Ejemplo n.º 1
0
 public static GuestServiceInterfaceComponent GetGuestServiceInterfaceComponent(ComputerSystem ComputerSystem)
 {
     return
         (SystemDevice.GetInstances()
          .Cast <SystemDevice>()
          .Where((sd) =>
                 string.Compare(sd.GroupComponent.Path, ComputerSystem.Path.Path, true, CultureInfo.InvariantCulture) == 0 &&
                 string.Compare(sd.PartComponent.ClassName, $"Msvm_{nameof(GuestServiceInterfaceComponent)}", true, CultureInfo.InvariantCulture) == 0)
          .Select((sds) => new GuestServiceInterfaceComponent(sds.PartComponent))
          .ToList()
          .First());
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Function will query device for unique device number and set it on <see cref="SystemDevice"/> object
        /// </summary>
        /// <param name="device">The device.</param>
        /// <param name="token">The token.</param>
        protected void SetDeviceNumber(SystemDevice device, CancellationToken token)
        {
            STORAGE_DEVICE_NUMBER devNumber;

            if (DeviceIoControl <int> .IsAccessible(device) == false)
            {
                // Device is not ready
                return;
            }

            token.ThrowIfCancellationRequested();

            devNumber = base.GetDeviceNumber(device);

            token.ThrowIfCancellationRequested();

            device.DeviceNumber = devNumber.DeviceNumber;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Sets the size of disk the device.
        /// </summary>
        /// <param name="device">The device to query</param>
        /// <param name="token">The cancellation token.</param>
        protected void SetDeviceSize(SystemDevice device, CancellationToken token)
        {
            DISK_GEOMETRY_EX diskGeometry;

            if (DeviceIoControl <int> .IsAccessible(device) == false)
            {
                // Device is not ready
                return;
            }

            token.ThrowIfCancellationRequested();

            diskGeometry = base.GetDriveGeometry(device);

            token.ThrowIfCancellationRequested();

            device.DiskSize       = diskGeometry.DiskSize;
            device.BytesPerSector = diskGeometry.Geometry.BytesPerSector;
            device.SectorsCount   = diskGeometry.Geometry.SectorsCount;
        }
Ejemplo n.º 4
0
        public Task <long> ExtractDiskAsync(SystemDevice device, string outputFile, IProgress <double> progress, CancellationToken token)
        {
            if (deviceBuilder.IfUserAdmin() == false)
            {
                throw new System.Security.SecurityException("User must be administrator to access the hardware. Please re-login");
            }

            //
            // If bufferSize will be tooo small (like: 512 bytes) the iteration of ReadFile will fail with E_FAIL or some SEH exception :(
            int sectorsReadAtOnce = Convert.ToInt32(device.SectorsCount / 100) + 1; // in 'sectors' not bytes !
            int bufferSize        = sectorsReadAtOnce * device.BytesPerSector;

            //

            // Align to 512 exactly
            //while (bufferSize % device.BytesPerSector != 0)
            //    bufferSize--;

            byte[]           buffer              = new byte[bufferSize];
            long             bytesRead           = 0;
            uint             lpNumberOfBytesRead = 0;
            bool             functionResult      = false;
            int              win32err            = 0;
            NativeOverlapped nativeOverlapped    = new NativeOverlapped();

            SystemDevice device2  = new SystemDevice("\\\\.\\PhysicalDrive" + device.DeviceNumber);
            GCHandle     gcHandle = new GCHandle();

            return(Task.Factory.StartNew <long>(() => {
                try
                {
                    IntPtr deviceHandle = device2.OpenDeviceHandle();
                    gcHandle = GCHandle.Alloc(deviceHandle);        // So it won't be collected by GC while I'm doing PInvoke

                    BinaryWriter writer = GetOutputStream(outputFile);

                    while (true)
                    {
                        functionResult = UnsafeNativeMethods.ReadFile(deviceHandle, buffer, Convert.ToUInt32(buffer.Length), ref lpNumberOfBytesRead, ref nativeOverlapped);
                        win32err = Marshal.GetLastWin32Error();

                        if (functionResult)
                        {
                            bytesRead += lpNumberOfBytesRead;

                            writer.Write(buffer, 0, buffer.Length);
                        }
                        else
                        {
                            if (win32err == UnsafeNativeMethods.ERROR_SECTOR_NOT_FOUND)
                            {
                                // This is a device black-hole
                                // try to squeeze as much as I can
                                if (bufferSize == device.BytesPerSector)
                                {
                                    // That's the last one
                                    break;
                                }
                                else
                                {
                                    bufferSize = device.BytesPerSector;
                                    buffer = new byte[bufferSize];
                                }
                            }
                            else
                            {
                                throw new System.ComponentModel.Win32Exception(win32err);
                            }
                        }

                        if (progress != null)
                        {
                            progress.Report(Math.Round((double)((bytesRead * 100) / device.DiskSize.Value)));
                        }

                        // Must not (!) increase position - everything will be read to NULL
                        //deviceStream.Position = iCounter;

                        if (bytesRead + bufferSize > device.DiskSize.Value)
                        {
                            if (device.DiskSize.Value == bytesRead)
                            {
                                // all done
                                break;
                            }
                            else
                            {
                                // Collect leftovers
                                buffer = new byte[(bytesRead + bufferSize) - device.DiskSize.Value];
                            }
                        }

                        GC.KeepAlive(deviceHandle);
                    }

                    writer.Flush();

                    gcHandle.Free();

                    device.CloseDeviceHandle();

                    return bytesRead;
                }
                catch (SEHException seh)
                {
                    gcHandle.Free();
                    System.Diagnostics.Trace.WriteLine("[]--- SEHException in ExtractDiskAsync(): " + seh.ToString());
                    return 0;
                }
                catch (Exception exp_gen)
                {
                    gcHandle.Free();

                    if (win32err == 0)
                    {
                        win32err = Marshal.GetLastWin32Error();
                    }

                    var zz = new System.ComponentModel.Win32Exception(win32err);
                    System.Diagnostics.Trace.WriteLine("[]--- Exception in ExtractDiskAsync(): " + exp_gen.ToString());
                    System.Diagnostics.Trace.WriteLine("[]--- Exception in ExtractDiskAsync() (native) : " + zz.ToString());
                    return 0;
                }
            }
                                                , token));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Extracts the disk to provided file
 /// </summary>
 /// <param name="device">The device to extract from</param>
 /// <param name="outputFileName">Name of the output file including path</param>
 /// <param name="progressCallback">The progress callback.</param>
 /// <param name="token">The cancellation token.</param>
 /// <returns>Task that execute the process and return total number of bytes read from device</returns>
 internal Task <long> ExtractDisk(SystemDevice device, string outputFileName, IProgress <double> progressCallback, CancellationToken token)
 {
     return(engine.ExtractDiskAsync(device, outputFileName, progressCallback, token));
 }