Beispiel #1
0
        /// <summary>
        /// CheckTrim Checks for trim descriptor
        /// </summary>
        /// <param name="DiskIndex">Physical disk index</param>
        /// <returns>
        /// true if trim is enabled else false.
        /// </returns>
        private static bool CheckTrim(int DiskIndex)
        {
            DEVICE_TRIM_DESCRIPTOR TrimDesc     = new DEVICE_TRIM_DESCRIPTOR();
            STORAGE_PROPERTY_QUERY StorageQuery = new STORAGE_PROPERTY_QUERY();
            uint BytesReturned = 0;

            StorageQuery.PropertyId = STORAGE_PROPERTY_ID.StorageDeviceTrimProperty;
            StorageQuery.QueryType  = STORAGE_QUERY_TYPE.PropertyStandardQuery;

            IntPtr StorageQueryPtr = Marshal.AllocHGlobal(Marshal.SizeOf(StorageQuery));
            IntPtr TrimDescPtr     = Marshal.AllocHGlobal(Marshal.SizeOf(TrimDesc));

            Marshal.StructureToPtr(StorageQuery, StorageQueryPtr, false);
            Marshal.StructureToPtr(TrimDesc, TrimDescPtr, false);

            SafeFileHandle physicalDisk = DeviceIO.CreateFile(
                "\\\\.\\PhysicalDrive" + DiskIndex,
                GENERIC_READ,
                FILE_SHARE_READ,
                IntPtr.Zero,
                OPEN_EXISTING,
                FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
                IntPtr.Zero);

            bool rs = DeviceIoControl(physicalDisk, IOCTL_STORAGE_QUERY_PROPERTY, StorageQueryPtr,
                                      (uint)Marshal.SizeOf(StorageQuery), TrimDescPtr, (uint)Marshal.SizeOf(TrimDesc),
                                      ref BytesReturned, IntPtr.Zero);

            if (rs == false)
            {
                throw new Exception();
            }
            TrimDesc = (DEVICE_TRIM_DESCRIPTOR)Marshal.PtrToStructure(TrimDescPtr, typeof(DEVICE_TRIM_DESCRIPTOR));
            return(TrimDesc.TrimEnabled);
        }
        //
        public ulong SeekU(ulong offset, SeekOrigin origin)
        {
            ulong n = 0;

            if (!DeviceIO.SetFilePointerEx(this.fileHandle, offset, out n, (uint)origin))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
            return(n);
        }
 /// <summary>
 /// Close Opened File Handles for current object
 /// </summary>
 public override void Close()
 {
     if (this.fileHandle != null)
     {
         DeviceIO.CloseHandle(this.fileHandle);
         this.fileHandle.SetHandleAsInvalid();
         this.fileHandle = null;
     }
     base.Close();
 }
        /// <summary>
        ///  Function to Write Data Pattern that is in buffer to disk sectors
        /// </summary>
        /// <param name="writeBuffer">The buffer that has the pattern of data to write</param>
        /// <param name="writeOffset">The byte offset in writeBuffer from which to begin copying bytes to the stream</param>
        /// <param name="writeCount">The maximum number of bytes to write</param>
        /// <returns></returns>
        public unsafe void Write(byte[] writeBuffer, uint writeOffset, uint writeCount)
        {
            uint   BytesWritten = 0;
            UInt64 newFilePtr   = 0;
            long   sectorStart  = -1;
            long   sectorEnd    = -1;

            while (true)
            {
                Console.WriteLine("Enter start sector to overwrite from : ");
                Wipe.sectorStart = Convert.ToUInt64(Console.ReadLine());
                Console.WriteLine("\nEnter end sector to write till : ");
                Wipe.sectorEnd = Convert.ToUInt64(Console.ReadLine());
                if (sectorStart < sectorEnd)
                {
                    break;
                }
                else
                {
                    Console.WriteLine("\nStart sector cannot be greater than end Sector.....Try again!!!\n");
                }
            }
            long  sectorDiff     = sectorEnd - sectorStart;
            int   size           = Wipe.sectorWriteSize;// ((sectorDiff > 32) ? ((sectorDiff > 1024) ? (512 * 2 * 64) : (512 * 2 * 4)) : 512); //512 * 2 * 1024;
            ulong distanceToMove = (ulong)(sectorStart * size);

            Console.WriteLine("\nWriting entered pattern to disk\n");

            try
            {
                fixed(byte *writeBufferPointer = writeBuffer)
                {
                    DeviceIO.SetFilePointerEx(this.fileHandle, distanceToMove, out newFilePtr, DeviceIO.FILE_BEGIN);

                    for (long i = sectorStart; i <= sectorEnd; i += (size / 512))
                    {
                        if (!DeviceIO.WriteFile(this.fileHandle, writeBufferPointer + writeOffset, (uint)size, &BytesWritten, IntPtr.Zero))
                        {
                            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                        }

                        //sectorStart += (size / 512);
                        if (i % 100 == 0)
                        {
                            drawTextProgressBar((int)i, (int)sectorEnd);
                        }
                    }
                    Console.WriteLine("After WriteFile");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
 /// <summary>
 /// Function to Lock Volumes
 /// </summary>
 /// <param name="drive">Volume label</param>
 /// <returns>
 /// true on successful lock of the volumes,else false
 /// </returns>
 public bool LockVolume(string drive)
 {
     try
     {
         uint bytesWritten = 0;
         bool locked       = DeviceIO.DeviceIoControl(this.fileHandle, DeviceIO.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesWritten, IntPtr.Zero);
         if (locked == false)
         {
             Console.WriteLine("\nCoudln't lock  volume\n");
         }
         return(locked);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
         return(false);
     }
 }
 /// <summary>
 /// Function to Unmount Volumes
 /// </summary>
 /// <param name="drive">Volume label</param>
 /// <returns>
 /// true on successfull unmount of the volume, else false
 /// </returns>
 public bool UnmountVolume(string drive)
 {
     try
     {
         uint BytesWritten = 0;
         Console.WriteLine("\nAttempting to Unmount volume : " + drive + "\n");
         bool unmounted = DeviceIO.DeviceIoControl(this.fileHandle, DeviceIO.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, ref BytesWritten, IntPtr.Zero);
         if (unmounted == false)
         {
             Console.WriteLine("\nCoudln't Dismount  volume\n");
         }
         return(unmounted);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
         return(false);
     }
 }
        /// <summary>
        /// Opens file handle for the required drive.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="desiredAccess"></param>
        /// <returns>
        /// Pointer to the drive
        /// </returns>
        private SafeFileHandle OpenFile(string id, FileAccess desiredAccess)
        {
            uint access;

            switch (desiredAccess)
            {
            case FileAccess.Read:
                access = DeviceIO.GENERIC_READ;
                break;

            case FileAccess.Write:
                access = DeviceIO.GENERIC_WRITE;
                break;

            case FileAccess.ReadWrite:
                access = DeviceIO.GENERIC_READ | DeviceIO.GENERIC_WRITE;
                break;

            default:
                access = DeviceIO.GENERIC_READ;
                break;
            }

            SafeFileHandle ptr = DeviceIO.CreateFile(
                id,
                access,
                DeviceIO.FILE_SHARE_READ,
                IntPtr.Zero,
                DeviceIO.OPEN_EXISTING,
                DeviceIO.FILE_FLAG_NO_BUFFERING | DeviceIO.FILE_FLAG_WRITE_THROUGH,
                IntPtr.Zero);

            if (ptr.IsInvalid)
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            return(ptr);
        }
        /// <summary>
        /// Function to Read Data into the Buffer from disk
        /// </summary>
        /// <param name="readBuffer">bytes read from the current disk.</param>
        /// <param name="readOffset"> byte offset in readBuffer at which to begin storing the data read from the current stream.</param>
        /// <param name="readCount">The maximum number of bytes to be read from the current stream.</param>
        /// <returns>
        /// Number of bytes read into the buffer.
        /// </returns>
        public unsafe uint Read(byte[] readBuffer, uint readOffset, uint readCount)
        {
            uint   BytesRead      = 0;
            UInt64 newFilePtr     = 0;
            uint   size           = 512;// ((sectorDiff > 32) ? ((sectorDiff > 1024) ? (512 * 2 * 64 ) : (512 * 2 * 4)) : 512);
            ulong  distanceToMove = (ulong)(Wipe.sectorStart * size);

            Console.WriteLine("\nVerifying Write Pattern....\n");

            fixed(byte *readBufferPointer = readBuffer)
            {
                DeviceIO.SetFilePointerEx(this.fileHandle, distanceToMove, out newFilePtr, DeviceIO.FILE_BEGIN);

                for (ulong i = Wipe.sectorStart; i <= Wipe.sectorEnd; i += ((ulong)size / 512))
                {
                    if (!DeviceIO.ReadFile(this.fileHandle, readBufferPointer + readOffset, size, &BytesRead, IntPtr.Zero))
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }

                    if (!readBuffer.SequenceEqual(toWrite))
                    {
                        Wipe.sectorErrorCount++;
                    }

                    /*else
                     * {
                     *  Console.WriteLine("Could not verify");
                     * }*/
                    //Wipe.sectorStart += ((ulong)size / 512);
                }

                Console.WriteLine("Verification Complete.....");
                return(BytesRead);
            }
        }
Beispiel #9
0
        /// <summary>
        /// The Main method, chooses on Trim or overwritting and executes accordingly.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("***************************\n" +
                              "*\t\t\t  *\n*\tWipe Demo\t  *\n*\t\t\t  *\n" +
                              "***************************\n");
            Console.Write("Reading Drive Information");
            int i = 0;

            while (i++ < 4)
            {
                Console.Write(".");
                Thread.Sleep(500);
            }
            RetrieveDiskInfo();
            DisplayDiskVolInfo();
            //BeginErase

            /* {
             *  //while(diskIndices in List<Drives>)
             *  {
             *      //CheckTrim();
             *      //GetOffsets();
             *      //UnmountVolumes();
             *      //ExecuteTrim();
             *      //ExecuteOverwrite();
             *   }
             * }
             */
            Console.WriteLine("Beginning Erase Procedure....Are you sure you want to continue Y/N ??");
            char input = (char)Console.Read();

            if (input == 'n' || input == 'N')
            {
                Environment.Exit(-1);
            }

            Console.WriteLine("Enter value to write within 0-255");
            int val = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Enter how many sectors to write at a time");
            sectorOffset = Convert.ToInt32(Console.ReadLine());

            writeBuffer = Enumerable.Repeat((byte)val, writeBuffer.Length).ToArray();

            foreach (Dictionary <String, Object> disk in PhysicalDriveInfo.Values)
            {
                bool doTrim = bool.Parse(disk["TrimSupported"].ToString());
                BytesPerSector  = int.Parse(disk["BytesPerSector"].ToString());
                sectorWriteSize = BytesPerSector * sectorOffset;
                writeBuffer     = new byte[sectorWriteSize];
                readBuffer      = new byte[sectorReadSize];
                uint     DiskIndex = (uint)disk["Index"];
                DeviceIO diskObj   = new DeviceIO();
                List <Dictionary <String, Object> > volumes = VolumesInfo[(int)DiskIndex];

                diskObj.OpenFileObject(DiskIndex, FileAccess.ReadWrite);

                foreach (Dictionary <String, Object> volumeInfo in volumes)
                {
                    Regex  regex        = new Regex(@"\((.*?)\)");
                    Match  tmpDriveName = regex.Match(volumeInfo["Name"].ToString());
                    String driveLetter  = tmpDriveName.Value.Replace("(", "").Replace(")", "").Trim();
                    int    volumeIndex  = -1;
                    Console.WriteLine("Partition letter : " + driveLetter);
                    if (driveLetter.Equals(""))
                    {
                        volumeIndex = (int)volumeInfo["Index"];
                    }
                    if (bool.Parse(volumeInfo["Erasable"].ToString()) == true)
                    {
                        sectorStart = Convert.ToUInt64(volumeInfo["StartingOffset"]) / 512;
                        // startingOffsets.Add(Convert.ToString(volumeInfo["Name"]), sectorStart);

                        UInt64 sectorStartInBytes = Convert.ToUInt64(volumeInfo["StartingOffset"]);
                        UInt64 totalSpace         = Convert.ToUInt64(volumeInfo["Size"]);
                        UInt64 sectorEndInBytes   = sectorStartInBytes + totalSpace;
                        sectorEnd = (sectorStartInBytes + totalSpace) / 512;

                        // UInt64 sectorDiff = sectorEnd - sectorStart;
                        //writeBuffer = new Byte[1048576];
                        //writeBuffer = Enumerable.Repeat((byte)val, writeBuffer.Length).ToArray();
                        //readBuffer = new byte[1048576];
                        //endingOffsets.Add(Convert.ToString(volumeInfo["Name"]), sectorEnd);

                        diskObj.LockVolume(driveLetter);
                        diskObj.UnmountVolume(driveLetter);
                        if (doTrim)
                        {
                            PerformTrim(driveLetter);
                        }
                    }
                    diskObj.Write(writeBuffer, 0, writeBuffer.Length);
                    diskObj.Read(readBuffer, 0, readBuffer.Length);
                }
            }
        }