Ejemplo n.º 1
0
        /// <summary>
        /// Helper method to construct an asyncResult object and use it to
        /// call NativeControl(). Called by BeginAsyncControl().
        /// </summary>
        private static DeviceAsyncResult <T> AsyncControl <T>(
            SafeFileHandle device,
            int controlCode,
            T outBuffer,
            AsyncCallback asyncCallback,
            object state
            )
        {
            SafePinnedObject outDeviceBuffer = null;

            if (outBuffer != null)
            {
                outDeviceBuffer = new SafePinnedObject(outBuffer);
            }

            // Create the async result object
            DeviceAsyncResult <T> asyncResult = new DeviceAsyncResult <T>(outDeviceBuffer,
                                                                          asyncCallback,
                                                                          state
                                                                          );

            unsafe
            {
                uint bytesReturned = 0;
                NativeAsyncControl(device,
                                   controlCode,
                                   outDeviceBuffer,
                                   ref bytesReturned,
                                   asyncResult.GetNativeOverlapped()
                                   );
            }

            return(asyncResult);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Helper method that actually sends the given IOCTL to the driver by
        /// calling the native DeviceIOControl() function. Called by AsyncControl().
        /// </summary>
        private static unsafe void NativeAsyncControl(
            SafeFileHandle device,
            int controlCode,
            SafePinnedObject outBuffer,
            ref uint bytesReturned,
            NativeOverlapped *nativeOverlapped
            )
        {
            bool succeeded = Kernel32Import.DeviceIoControl(device,
                                                            controlCode,
                                                            null,
                                                            0,
                                                            outBuffer,
                                                            outBuffer.Size,
                                                            ref bytesReturned,
                                                            nativeOverlapped
                                                            );

            // If DeviceIoControl returns TRUE, the operation completed
            // synchronously
            if (succeeded)
            {
                throw new InvalidOperationException($"Async call to DeviceIoControl completed synchronously.");
            }

            // DeviceIoControl is operating asynchronously; test the returned
            // error code to see if it is pending or not
            Int32       error           = Marshal.GetLastWin32Error();
            const Int32 cErrorIOPending = 997;  // system-defined code for pending I/O

            if (error == cErrorIOPending)
            {
                return;
            }

            // Throw an exception if DeviceIoControl fails altogether
            throw new InvalidOperationException($"Control failed with error {error}");
        }