Beispiel #1
0
        /// <summary>
        /// The ensure length.
        /// </summary>
        /// <param name="buffer">
        /// The buffer.
        /// </param>
        /// <param name="length">
        /// The length.
        /// </param>
        /// <param name="withRepeat">
        /// The with repeat.
        /// </param>
        /// <returns>
        /// The <see cref="IBuffer"/>.
        /// </returns>
        private static IBuffer EnsureLength(IBuffer buffer, int length, bool withRepeat)
        {
            if (buffer.Length == length)
            {
                return(buffer);
            }

            if (buffer.Length > length)
            {
                var array = new byte[length];
                buffer.CopyTo(0, array, 0, length);
                return(array.AsBuffer());
            }

            var longerArray = new byte[length];

            if (!withRepeat)
            {
                buffer.CopyTo(0, longerArray, 0, (int)buffer.Length);
                return(longerArray.AsBuffer());
            }

            var pos = 0;

            while (pos < length)
            {
                var toGo = length - pos;
                var pad  = toGo <= buffer.Length ? toGo : (int)buffer.Length;
                buffer.CopyTo(0, longerArray, pos, pad);
                pos += pad;
            }

            return(longerArray.AsBuffer());
        }
Beispiel #2
0
        private Task <uint> createSaveBufferTask(IBuffer buffer)
        {
            if (OnDataWriting != null)
            {
                var arg = new BufferWriteEventArgs(BufferActions.Write, _position, buffer.Length);
                OnDataWriting(this, ref arg);

                if (!arg.IsAllowed)
                {
                    return(new Task <uint>(() => { return buffer.Length; }));
                }
            }

            return(new Task <uint>(() =>
            {
                uint len = buffer.Length;
                var data = new byte[len];
                buffer.CopyTo(data);

                try
                {
                    doSend(data);
                    if (_position + len > _streamSize)
                    {
                        _streamSize = _position + len;
                    }
                    return len;
                }
                catch
                {
                    DataSendingFailed?.Invoke(this, new EventArgs());
                    return 0;
                }
            }));
        }
        /// <summary>
        /// Encrypt value using password.
        /// </summary>
        /// <param name="value">Value to encrypt.</param>
        /// <param name="key">Key that is used for encryption.</param>
        /// <returns>A buffer with the encrypted data is returned.</returns>
        public IBuffer Encrypt(string value, string key)
        {
            // Create a Sha256 from key.
            var     passwordBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
            var     hashProvider   = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
            IBuffer keyMaterial    = hashProvider.HashData(passwordBuffer);

            // Create an Aes256 with CBC and Pkcs7
            var aesProvider         = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
            CryptographicKey aesKey = aesProvider.CreateSymmetricKey(keyMaterial);

            // Create a random IV so the password can be used more than once.
            IBuffer iv = CryptographicBuffer.GenerateRandom(aesProvider.BlockLength);

            // Encrypt value.
            var     data      = CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8);
            IBuffer encrypted = CryptographicEngine.Encrypt(aesKey, data, iv);

            // Insert random generated IV before encrypted message because it will be needed at decryption.
            IBuffer result = CryptographicBuffer.CreateFromByteArray(new byte[iv.Length + encrypted.Length]);

            iv.CopyTo(0, result, 0, iv.Length);
            encrypted.CopyTo(0, result, iv.Length, encrypted.Length);

            return(result);
        }
Beispiel #4
0
        public static byte[] ToArray(this IBuffer source, uint sourceIndex, int count)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (source.Capacity <= sourceIndex)
            {
                throw new ArgumentException(SR.Argument_BufferIndexExceedsCapacity);
            }
            if (source.Capacity - sourceIndex < count)
            {
                throw new ArgumentException(SR.Argument_InsufficientSpaceInSourceBuffer);
            }

            if (count == 0)
            {
                return(Array.Empty <byte>());
            }

            byte[] destination = new byte[count];
            source.CopyTo(sourceIndex, destination, 0, count);
            return(destination);
        }
Beispiel #5
0
        /// <summary>
        /// Derives the base key used by <see cref="HmacBlockHandler"/> given
        /// a database's master seed and the user's composite key.
        ///
        /// The derived key is a SHA-512 hash of the result of concatenating
        /// these values together, with the byte 0x1 appended at the end.
        /// </summary>
        /// <param name="compositeKey">The user's composite key.</param>
        /// <param name="masterSeed">The database's master seed.</param>
        /// <returns>A buffer to use for an HMAC block key.</returns>
        public static IBuffer DeriveHmacKey(IBuffer compositeKey, IBuffer masterSeed)
        {
            if (compositeKey == null)
            {
                throw new ArgumentNullException(nameof(compositeKey));
            }

            if (masterSeed == null)
            {
                throw new ArgumentNullException(nameof(masterSeed));
            }

            if (compositeKey.Length != 32)
            {
                throw new ArgumentException("Composite key should be 32 bytes", nameof(compositeKey));
            }

            if (masterSeed.Length != 32)
            {
                throw new ArgumentException("Master seed should be 32 bytes", nameof(masterSeed));
            }

            byte[] buffer = new byte[compositeKey.Length + masterSeed.Length + 1];

            masterSeed.CopyTo(buffer);
            compositeKey.CopyTo(0, buffer, (int)masterSeed.Length, (int)compositeKey.Length);
            buffer[buffer.Length - 1] = 1;

            HashAlgorithmProvider sha512 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512);
            CryptographicHash     hash   = sha512.CreateHash();

            hash.Append(buffer.AsBuffer());
            return(hash.GetValueAndReset());
        }
        public void TestWrite()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                IBuffer res = BufferFactory.NewBuffer <int>()
                              .WithUsage(ResourceUsage.Write)
                              .WithLength(100)
                              .Create();

                IBuffer copyDest = (res as Buffer <int>).Clone()
                                   .WithUsage(ResourceUsage.StagingRead)
                                   .WithPermittedBindings(GPUBindings.None)
                                   .Create();

                // Set up context


                // Execute
                Assert.IsTrue(res.CanWrite);
                res.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 10U);
                res.CopyTo(copyDest);

                // Assert outcome
                byte[] readData = copyDest.Read();
                for (int i = 10; i < 20; ++i)
                {
                    Assert.AreEqual(i - 9, readData[i]);
                }

                res.Dispose();
                copyDest.Dispose();
            });
        }
        public static byte[] ToArray(this IBuffer source, uint sourceIndex, int count)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (source.Length < sourceIndex)
            {
                throw new ArgumentException("The specified buffer index is not within the buffer length.");
            }
            if (source.Length - sourceIndex < count)
            {
                throw new ArgumentException(global::Windows.Storage.Streams.SR.Argument_InsufficientSpaceInSourceBuffer);
            }

            if (count == 0)
            {
                return(Array.Empty <byte>());
            }

            byte[] destination = new byte[count];
            source.CopyTo(sourceIndex, destination, 0, count);
            return(destination);
        }
        public static Byte[] ToArray(this IBuffer source, UInt32 sourceIndex, Int32 count)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }
            if (sourceIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(sourceIndex));
            }
            if (source.Capacity <= sourceIndex)
            {
                throw new ArgumentException(SR.Argument_BufferIndexExceedsCapacity);
            }
            if (source.Capacity - sourceIndex < count)
            {
                throw new ArgumentException(SR.Argument_InsufficientSpaceInSourceBuffer);
            }
            Contract.EndContractBlock();

            if (count == 0)
            {
                return(Array.Empty <Byte>());
            }

            Byte[] destination = new Byte[count];
            source.CopyTo(sourceIndex, destination, 0, count);
            return(destination);
        }
Beispiel #9
0
        /// <summary>
        /// Asynchronously transforms the user's 32-byte key using ECB AES.
        ///
        /// Since Rijndael works on 16-byte blocks, the k is split in half and
        /// each half is encrypted separately the same number of times.
        /// </summary>
        /// <param name="rawKey">The key to transform.</param>
        /// <param name="token">Token used to cancel the transform task.</param>
        /// <returns>The transformed key.</returns>
        public async Task <IBuffer> TransformKeyAsync(IBuffer rawKey, CancellationToken token)
        {
            if (rawKey == null)
            {
                throw new ArgumentNullException(nameof(rawKey));
            }

            if (rawKey.Length != 32)
            {
                throw new ArgumentException("Key must be 32 bytes", nameof(rawKey));
            }

            // Split the k buffer in half
            byte[]  rawKeyBytes = rawKey.ToArray();
            IBuffer lowerBuffer = WindowsRuntimeBuffer.Create(rawKeyBytes, 0, 16, 16);
            IBuffer upperBuffer = WindowsRuntimeBuffer.Create(rawKeyBytes, 16, 16, 16);

            // Set up the encryption parameters
            var aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcb);
            CryptographicKey key = aes.CreateSymmetricKey(this.algoParams.Seed);
            IBuffer          iv  = null;

            // Run the encryption rounds in two threads (upper and lower)
            ConditionChecker checkForCancel = () => token.IsCancellationRequested;
            Task <bool>      lowerTask      = Task.Run(() =>
            {
                lowerBuffer = KeePassHelper.TransformKey(this.algoParams.Rounds, this.algoParams.Seed, iv, lowerBuffer, checkForCancel);
                return(!checkForCancel());
            }
                                                       );
            Task <bool> upperTask = Task.Run(() =>
            {
                upperBuffer = KeePassHelper.TransformKey(this.algoParams.Rounds, this.algoParams.Seed, iv, upperBuffer, checkForCancel);
                return(!checkForCancel());
            }
                                             );

            // Verify the work was completed successfully
            await Task.WhenAll(lowerTask, upperTask);

            if (!(lowerTask.Result && upperTask.Result))
            {
                return(null);
            }

            // Copy the units of work back into one buffer, hash it, and return.
            IBuffer transformedKey = (new byte[32]).AsBuffer();

            lowerBuffer.CopyTo(0, transformedKey, 0, 16);
            upperBuffer.CopyTo(0, transformedKey, 16, 16);

            var sha256             = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
            CryptographicHash hash = sha256.CreateHash();

            hash.Append(transformedKey);

            return(hash.GetValueAndReset());
        }
Beispiel #10
0
        /// <summary>
        /// Ends an asynchronous Receive
        /// </summary>
        /// <param name="ar">AsyncResult obtained from BeginReive</param>
        /// <param name="Error">Indicates an error occured while receiving data</param>
        /// <returns>Received Data</returns>
        public byte[] EndReceive(IAsyncResult ar, out bool Error)
        {
            Error = false;
            int bytesRead = 0;

            try
            {
                lock (syncSocket)
                {
                    bytesRead = socket.EndReceive(ar);
                }
            }
            catch (ObjectDisposedException ex)
            {
                if (!isClosing)
                {
                    Diags.LogSocketException(ex);
                }
                Error = true;
            }
            catch (Exception ex)
            {
                Diags.LogSocketException(ex);
                Error = true;
            }

            byte[] readData;
            if (Error || bytesRead < 0)
            {
                readData = new byte[0];
            }
            else
            {
                readData = new byte[bytesRead];
            }


            if (recvBuffer != null && !recvBuffer.IsDisposed)
            {
                if (!Error && bytesRead > 0)
                {
                    recvBuffer.CopyTo(readData, 0, bytesRead);
                }

                //Dispose buffer if it's greater than a specified threshold
                if (recvBuffer.Size > BufferRenewalSizeThreshold)
                {
                    recvBuffer.Dispose();
                }
            }

            return(readData);
        }
Beispiel #11
0
        /// <summary>
        /// Loads the byte data from a StorageFile
        /// </summary>
        /// <param name="file">The file to read</param>
        public async Task <byte[]> ReadFile(StorageFile file)
        {
            using (IRandomAccessStreamWithContentType stream = await file.OpenReadAsync())
            {
                stream.Seek((ulong)0);
                byte[]  fileBytes = new byte[stream.Size];
                var     buffer    = CryptographicBuffer.CreateFromByteArray(fileBytes);
                IBuffer rd        = await stream.ReadAsync(buffer, (uint)fileBytes.Length, InputStreamOptions.None);

                rd.CopyTo(fileBytes);
                return(fileBytes);
            }
        }
Beispiel #12
0
 protected override void SendToRemote(byte[] e)
 {
     if (remoteConnected)
     {
         try
         {
             r.Send(e);
         }
         catch (Exception)
         {
             Debug.WriteLine("Cannot send to remote");
             Dispose();
             return;
         }
         LogData("Sent to remote ", e);
         // Send header first, followed by local buffer
         if (localbuf != null)
         {
             IBuffer newLocalbuf;
             lock (localbuf)
             {
                 if (localbuf != null && localbuf.Length > 0)
                 {
                     newLocalbuf = WindowsRuntimeBuffer.Create((int)localbuf.Length);
                     localbuf.CopyTo(newLocalbuf);
                     newLocalbuf.Length = localbuf.Length;
                     //LogData("Sending local buffer ", newLocalbuf.ToArray());
                     localbuf = null;
                 }
                 else
                 {
                     localbuf = null;
                     return;
                 }
             }
             r.Send(newLocalbuf.ToArray());
             Debug.WriteLine("Buffer sent");
             //await r.OutputStream.WriteAsync(outData.Take((int)len).ToArray().AsBuffer());
         }
         return;
     }
     else
     {
         lock (localbuf)
         {
             e.CopyTo(0, localbuf, localbuf.Length, e.Length);
             localbuf.Length += (uint)e.Length;
         }
         return;
     }
 }
Beispiel #13
0
        internal static void EnsureResultsInUserBuffer(IBuffer userBuffer, IBuffer resultBuffer)
        {
            // Results buffer may be different from user specified buffer. If so - copy data to the user.

            Debug.Assert(userBuffer != null);
            Debug.Assert(resultBuffer != null);

            if (resultBuffer.IsSameData(userBuffer))
            {
                return;
            }

            resultBuffer.CopyTo(userBuffer);
            userBuffer.Length = resultBuffer.Length;
        }
        /// <summary>
        /// Decrypt buffer using password.
        /// </summary>
        /// <param name="data">Data buffer to decrypt.</param>
        /// <param name="key">Key that is used for decryption.</param>
        /// <returns>Returns the decrypted value as string.</returns>
        public string Decrypt(IBuffer data, string key)
        {
            // Create a Sha256 from key.
            var     passwordBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
            var     hashProvider   = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
            IBuffer keyMaterial    = hashProvider.HashData(passwordBuffer);

            // Create am Aes256 with CBC and Pkcs7.
            var aesProvider         = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
            CryptographicKey aesKey = aesProvider.CreateSymmetricKey(keyMaterial);

            // Split data into IV and encrypted data.
            IBuffer iv        = CryptographicBuffer.CreateFromByteArray(new byte[aesProvider.BlockLength]);
            IBuffer encrypted = CryptographicBuffer.CreateFromByteArray(new byte[data.Length - iv.Length]);

            data.CopyTo(0, iv, 0, iv.Length);
            data.CopyTo(iv.Length, encrypted, 0, encrypted.Length);

            // Decrypt data.
            IBuffer decrypted = CryptographicEngine.Decrypt(aesKey, encrypted, iv);
            string  value     = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decrypted);

            return(value);
        }
        unsafe int DecryptBuffer(IBuffer buf, Span <byte> outBuf)
        {
            var len = (int)buf.Length;

            if (len == 0)
            {
                return(0);
            }

            if (buf != recvDataBuffer)
            {
                buf.CopyTo(0, recvDataBuffer, 0, (uint)len);
            }
            return((int)Decrypt(recvData.AsSpan(0, len), outBuf.Slice(0, len)));
        }
Beispiel #16
0
        /// <summary>
        /// Given a stream past the header, asynchronously fetches encrypted ciphertext
        /// from the file as a single buffer.
        /// </summary>
        /// <remarks>
        /// For KDBX3.1, this is just the rest of the stream. For KDBX4, it involves
        /// pulling out HMAC blocks from the stream.
        /// </remarks>
        /// <param name="dataStream">The stream representing the remainder of the database file.</param>
        /// <returns>A buffer representing the encrypted database.</returns>
        private async Task <IBuffer> GetCipherText(IRandomAccessStream dataStream, HmacBlockHandler macHandler)
        {
            uint streamRemaining = (uint)(dataStream.Size - dataStream.Position);

            DebugHelper.Trace("Stream has {0} bytes remaining.", streamRemaining);

            IBuffer fileRemainder;

            using (DataReader reader = GetReaderForStream(dataStream))
            {
                if (this.parameters.UseHmacBlocks)
                {
                    // KDBX 4: HMAC block content
                    int bytesLeft = (int)streamRemaining;
                    DebugHelper.Assert(bytesLeft > 0);

                    fileRemainder = WindowsRuntimeBuffer.Create(bytesLeft);

                    for (ulong index = 0; bytesLeft > 0; index++)
                    {
                        IBuffer block = await macHandler.ReadCipherBlockAsync(reader, index);

                        if (block == null || block.Length == 0)
                        {
                            break;
                        }

                        DebugHelper.Assert((int)block.Length > 0);
                        bytesLeft -= (int)block.Length + 4 + 32;

                        block.CopyTo(0, fileRemainder, fileRemainder.Length, block.Length);
                        fileRemainder.Length += block.Length;
                    }
                }
                else
                {
                    // KDBX 3.1: Rest of file as-is
                    DebugHelper.Assert(reader.UnconsumedBufferLength == 0);
                    await reader.LoadAsync(streamRemaining).AsTask().ConfigureAwait(false);

                    fileRemainder = reader.ReadBuffer(streamRemaining);
                }

                reader.DetachStream();
                return(fileRemainder);
            }
        }
Beispiel #17
0
        private async void OnPreviewFrameAvailable(IImageSize imageSize)
        {
            if (!_isRendering)
            {
                _isRendering = true;
                await _writeableBitmapRenderer.RenderAsync();

                await
                CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
                    CoreDispatcherPriority.High,
                    () =>
                {
                    int bufferSize = _writeableBitmap.PixelWidth *_writeableBitmap.PixelHeight * 4;
                    if (_buffer == null || _buffer.Length != bufferSize)
                    {
                        _buffer = new byte[bufferSize];
                    }
                    IBuffer pixelBuffer = _writeableBitmap.PixelBuffer;
                    pixelBuffer.CopyTo(_buffer);

                    GCHandle handle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
                    using (
                        Mat m = new Mat(_writeableBitmap.PixelHeight, _writeableBitmap.PixelWidth,
                                        DepthType.Cv8U, 4,
                                        handle.AddrOfPinnedObject(), _writeableBitmap.PixelWidth * 4))
                        using (Mat gray = new Mat())
                            using (Mat canny = new Mat())
                            {
                                CvInvoke.CvtColor(m, gray, ColorConversion.Bgr2Gray);
                                CvInvoke.Canny(gray, canny, 40, 60);

                                CvInvoke.CvtColor(canny, m, ColorConversion.Gray2Bgra);
                            }
                    handle.Free();

                    using (Stream s = pixelBuffer.AsStream())
                    {
                        s.Write(_buffer, 0, _buffer.Length);
                    }

                    _writeableBitmap.Invalidate();
                });

                _isRendering = false;
            }
        }
Beispiel #18
0
        // Implements sending of video/audio data to the service.
        // The message is encoded the following way:
        // 4 bytes - position in MP4 file where data shall be put.
        // n bytes - video/audio data.
        public IAsyncOperationWithProgress <uint, uint> WriteAsync(IBuffer buffer)
        {
            Task <uint> aTask = new Task <uint>(() =>
            {
                uint aVideoDataLength = buffer.Length;
                byte[] aMessage       = new byte[aVideoDataLength + 4];

                // Put position within MP4 file to the message.
                byte[] aPosition = BitConverter.GetBytes((int)this.Position);
                Array.Copy(aPosition, aMessage, aPosition.Length);

                // Put video/audio data to the message.
                buffer.CopyTo(0, aMessage, 4, (int)aVideoDataLength);



                uint aTransferedSize = 0;
                try
                {
                    // Send the message to the service.
                    // myOutputChannel.SendMessage(aMessage);
                    this.pushStream.Write(aMessage);

                    memoryBuffer.WriteAsync(buffer);
                    aTransferedSize = (uint)aVideoDataLength;
                }
                catch
                {
                    // If sending fails then the connection is broken.
                    if (ConnectionBroken != null)
                    {
                        ConnectionBroken(this, new EventArgs());
                    }
                }

                return(aTransferedSize);
            });

            aTask.RunSynchronously();

            Func <CancellationToken, IProgress <uint>, Task <uint> > aTaskProvider =
                (token, progress) => aTask;

            return(AsyncInfo.Run <uint, uint>(aTaskProvider));
        }
Beispiel #19
0
        /// <summary>
        /// Generates the HMAC-SHA-256 value for a given block.
        /// The actual hashed value is i || n (block size) || C.
        /// </summary>
        /// <param name="i">The block index.</param>
        /// <param name="cipherText">Encrypted block value.</param>
        /// <param name="offset">Offset into <paramref name="cipherText"/>.</param>
        /// <param name="length">Number of bytes of <paramref name="cipherText"/> to use.</param>
        /// <returns>The HMAC value of the block.</returns>
        public IBuffer GetMacForBlock(ulong i, IBuffer cipherText, uint offset, uint length)
        {
            if (cipherText == null)
            {
                throw new ArgumentNullException(nameof(cipherText));
            }

            if (offset > cipherText.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            length = (offset + length > cipherText.Length ? cipherText.Length - offset : length);

            DebugHelper.Assert(length <= int.MaxValue);

            // Construct the HMAC buffer: i || n || C
            byte[] buffer = new byte[8 + 4 + length];

            ByteHelper.GetLittleEndianBytes(i, buffer);
            ByteHelper.GetLittleEndianBytes(length, buffer, 8);
            if (length > 0)
            {
                // Necessary because buffers don't play nice if they're empty...
                cipherText.CopyTo(offset, buffer, 12, (int)length);
            }

            CryptographicHash hash = this.hmacAlgo.CreateHash(GetKeyForBlock(i));

            hash.Append(buffer.AsBuffer());
            IBuffer macValue = hash.GetValueAndReset();

            DebugHelper.Trace($"Generating MAC value for block #{i}, data length {length}");
            if (length > 0)
            {
                DebugHelper.Trace($"data[0]: { buffer[12]}, data[n]: { buffer[buffer.Length - 1]}");
            }
            DebugHelper.Trace($"MAC[0]: {macValue.GetByte(0)}, MAC[31]: {macValue.GetByte(31)}");
            return(macValue);
        }
Beispiel #20
0
        private async void Sck_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            //[email protected]("Message received " + args);

            if (args.MessageType == SocketMessageType.Utf8)
            {
                Windows.Storage.Streams.DataReader messageReader = args.GetDataReader();
                messageReader.UnicodeEncoding = UnicodeEncoding.Utf8;
                string messageString = messageReader.ReadString(messageReader.UnconsumedBufferLength);
                com.codename1.io.websocket.WebSocket.messageReceived(id, messageString);
            }
            else
            {
                Windows.Storage.Streams.IInputStream readStream = args.GetDataStream();
                byte[] readBuffer = new byte[4096];
                try
                {
                    while (true)
                    {
                        if (sender != sck)
                        {
                            return;
                        }

                        IBuffer res = await readStream.ReadAsync(readBuffer.AsBuffer(), (uint)readBuffer.Length, 0);

                        if (res.Length == 0)
                        {
                            return;
                        }
                        byte[] resArr = new byte[res.Length];
                        res.CopyTo(resArr);
                        com.codename1.io.websocket.WebSocket.messageReceived(1, resArr);
                    }
                } catch (Exception ex)
                {
                    com.codename1.io.websocket.WebSocket.errorReceived(id, ex.Message, ex.HResult);
                }
            }
        }
Beispiel #21
0
        private async Task RestoreBitmapAsync(int width, int height)
        {
            _bitmap = new WriteableBitmap(width, height);
            var folder = ApplicationData.Current.LocalFolder;
            var file   = await folder.GetFileAsync(c_filename);

            using (var stream = await file.OpenAsync(FileAccessMode.Read))
            {
                using (var input = stream.GetInputStreamAt(0))
                {
                    using (var reader = new DataReader(input))
                    {
                        var size = await reader.LoadAsync((uint)stream.Size);

                        IBuffer pixels = reader.ReadBuffer(size);
                        pixels.CopyTo(_bitmap.PixelBuffer);
                        Photo.Source = _bitmap;
                        _bitmap.Invalidate();
                    }
                }
            }
        }
Beispiel #22
0
        private void OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
        {
            // GetDataReader() throws an exception when either:
            // (1) The underlying TCP connection is closed prematurely (e.g., FIN/RST received without sending/receiving a WebSocket Close frame).
            // (2) The server sends invalid data (e.g., corrupt HTTP headers or a message exceeding the MaxMessageSize).
            //
            // In both cases, the appropriate thing to do is to close the socket, as we have reached an unexpected state in
            // the WebSocket protocol.
            try
            {
                using (DataReader reader = args.GetDataReader())
                {
                    uint dataAvailable;
                    while ((dataAvailable = reader.UnconsumedBufferLength) > 0)
                    {
                        ArraySegment <byte> buffer;
                        try
                        {
                            buffer = _receiveAsyncBufferTcs.Task.GetAwaiter().GetResult();
                        }
                        catch (OperationCanceledException) // Caused by Abort call on WebSocket
                        {
                            return;
                        }

                        _receiveAsyncBufferTcs = new TaskCompletionSource <ArraySegment <byte> >();
                        WebSocketMessageType messageType;
                        if (args.MessageType == SocketMessageType.Binary)
                        {
                            messageType = WebSocketMessageType.Binary;
                        }
                        else
                        {
                            messageType = WebSocketMessageType.Text;
                        }

                        bool endOfMessage = false;
                        uint readCount    = Math.Min(dataAvailable, (uint)buffer.Count);

                        if (readCount > 0)
                        {
                            IBuffer dataBuffer = reader.ReadBuffer(readCount);

                            // Safe to cast readCount to int as the maximum value that readCount can be is buffer.Count.
                            dataBuffer.CopyTo(0, buffer.Array, buffer.Offset, (int)readCount);
                        }

                        if (dataAvailable == readCount)
                        {
                            endOfMessage = !IsPartialMessageEvent(args);
                        }

                        WebSocketReceiveResult recvResult = new WebSocketReceiveResult((int)readCount, messageType,
                                                                                       endOfMessage);
                        _webSocketReceiveResultTcs.TrySetResult(recvResult);
                    }
                }
            }
            catch (Exception exc)
            {
                // WinRT WebSockets always throw exceptions of type System.Exception. However, we can determine whether
                // or not we're dealing with a known error by using WinRT's WebSocketError.GetStatus method.
                WebErrorStatus status      = RTWebSocketError.GetStatus(exc.HResult);
                WebSocketError actualError = WebSocketError.Faulted;
                switch (status)
                {
                case WebErrorStatus.ConnectionAborted:
                case WebErrorStatus.ConnectionReset:
                case WebErrorStatus.Disconnected:
                    actualError = WebSocketError.ConnectionClosedPrematurely;
                    break;
                }

                // Propagate a custom exception to any pending ReceiveAsync/CloseAsync operations and close the socket.
                WebSocketException customException = new WebSocketException(actualError, exc);
                AbortInternal(customException);
            }
        }
Beispiel #23
0
        private static void DoTestRead(Func <IInputStream> createStreamFunc, InputStreamOptions inputStreamOptions, bool mustInvokeProgressHandler, bool completesSynchronously)
        {
            IInputStream stream = createStreamFunc();
            IBuffer      buffer = WindowsRuntimeBuffer.Create(TestStreamProvider.ModelStreamLength);

            IAsyncOperationWithProgress <IBuffer, uint> readOp = stream.ReadAsync(buffer, (uint)TestStreamProvider.ModelStreamLength, inputStreamOptions);

            if (completesSynchronously)
            {
                // New readOp for a stream where we know that reading is sycnhronous must have Status = Completed
                Assert.Equal(AsyncStatus.Completed, readOp.Status);
            }
            else
            {
                // Note the race. By the tie we get here, the status of the op may be started or already completed.
                AsyncStatus readOpStatus = readOp.Status;
                Assert.True(readOpStatus == AsyncStatus.Completed || readOpStatus == AsyncStatus.Started, "New readOp must have Status = Started or Completed (race)");
            }

            bool progressCallbackInvoked  = false;
            bool completedCallbackInvoked = false;

            uint            readOpId   = readOp.Id;
            EventWaitHandle waitHandle = new ManualResetEvent(false);

            readOp.Progress = (asyncReadOp, bytesCompleted) =>
            {
                progressCallbackInvoked = true;

                // asyncReadOp.Id in a progress callback must match the ID of the asyncReadOp to which the callback was assigned
                Assert.Equal(readOpId, asyncReadOp.Id);

                // asyncReadOp.Status must be 'Started' for an asyncReadOp in progress
                Assert.Equal(AsyncStatus.Started, asyncReadOp.Status);

                // bytesCompleted must be in range [0, maxBytesToRead] asyncReadOp in progress
                Assert.InRange(bytesCompleted, 0u, (uint)TestStreamProvider.ModelStreamLength);
            };

            readOp.Completed = (asyncReadOp, passedStatus) =>
            {
                try
                {
                    completedCallbackInvoked = true;

                    // asyncReadOp.Id in a completion callback must match the ID of the asyncReadOp to which the callback was assigned
                    Assert.Equal(readOpId, asyncReadOp.Id);

                    // asyncReadOp.Status must match passedStatus for a completed asyncReadOp
                    Assert.Equal(passedStatus, asyncReadOp.Status);

                    // asyncReadOp.Status must be 'Completed' for a completed asyncReadOp
                    Assert.Equal(AsyncStatus.Completed, asyncReadOp.Status);

                    IBuffer resultBuffer = asyncReadOp.GetResults();

                    // asyncReadOp.GetResults() must not return null for a completed asyncReadOp
                    Assert.NotNull(resultBuffer);

                    AssertExtensions.GreaterThan(resultBuffer.Capacity, 0u, "resultBuffer.Capacity should be more than zero in completed callback");
                    AssertExtensions.GreaterThan(resultBuffer.Length, 0u, "resultBuffer.Length should be more than zero in completed callback");
                    AssertExtensions.LessThanOrEqualTo(resultBuffer.Length, resultBuffer.Capacity, "resultBuffer.Length should be <= Capacity in completed callback");

                    if (inputStreamOptions == InputStreamOptions.None)
                    {
                        // resultBuffer.Length must be equal to requested number of bytes when an asyncReadOp with
                        // InputStreamOptions.None completes successfully
                        Assert.Equal(resultBuffer.Length, (uint)TestStreamProvider.ModelStreamLength);
                    }

                    if (inputStreamOptions == InputStreamOptions.Partial)
                    {
                        AssertExtensions.LessThanOrEqualTo(resultBuffer.Length, (uint)TestStreamProvider.ModelStreamLength,
                                                           "resultBuffer.Length must be <= requested number of bytes with InputStreamOptions.Partial in completed callback");
                    }
                    buffer = resultBuffer;
                }
                finally
                {
                    waitHandle.Set();
                }
            };

            // Now, let's block until the read op is complete.
            // We speculate that it will complete within 3500 msec, although under high load it may not be.
            // If the test fails we should use a better way to determine if callback is really not invoked, or if it's just too slow.
            waitHandle.WaitOne(500);
            waitHandle.WaitOne(1000);
            waitHandle.WaitOne(2000);

            if (mustInvokeProgressHandler)
            {
                Assert.True(progressCallbackInvoked,
                            "Progress callback specified to ReadAsync callback must be invoked when reading from this kind of stream");
            }

            Assert.True(completedCallbackInvoked,
                        "Completion callback specified to ReadAsync callback must be invoked");

            // readOp.Status must be 'Completed' for a completed async readOp
            Assert.Equal(AsyncStatus.Completed, readOp.Status);

            AssertExtensions.GreaterThan(buffer.Capacity, 0u, "buffer.Capacity should be greater than zero bytes");
            AssertExtensions.GreaterThan(buffer.Length, 0u, "buffer.Length should be greater than zero bytes");
            AssertExtensions.LessThanOrEqualTo(buffer.Length, buffer.Capacity, "buffer.Length <= buffer.Capacity is required for a completed async readOp");

            if (inputStreamOptions == InputStreamOptions.None)
            {
                // buffer.Length must be equal to requested number of bytes when an async readOp with
                //  InputStreamOptions.None completes successfully
                Assert.Equal((uint)TestStreamProvider.ModelStreamLength, buffer.Length);
            }

            if (inputStreamOptions == InputStreamOptions.Partial)
            {
                AssertExtensions.LessThanOrEqualTo(buffer.Length, (uint)TestStreamProvider.ModelStreamLength,
                                                   "resultBuffer.Length must be <= requested number of bytes with InputStreamOptions.Partial");
            }

            byte[] results = new byte[buffer.Length];
            buffer.CopyTo(0, results, 0, (int)buffer.Length);

            Assert.True(TestStreamProvider.CheckContent(results, 0, (int)buffer.Length),
                        "Result data returned from AsyncRead must be the same as expected from the test data source");
        }