Exemplo n.º 1
0
            /// <summary>
            /// Validate the header and CRC-32 of this structure.
            /// </summary>
            /// <returns>True if the structure is valid.</returns>
            /// <remarks></remarks>
            public bool Validate()
            {
                bool ValidateRet = default;
                var  mm          = new MemPtr();

                mm.FromStruct(this);
                mm.UIntAt(4L) = 0U;

                // validate the crc and the signature moniker
                ValidateRet = HeaderCRC32 == mm.CalculateCrc32() && Signature == 0x5452415020494645;
                mm.Free();
                return(ValidateRet);
            }
Exemplo n.º 2
0
        /// <summary>
        /// Retrieve the partition table of a GPT-layout disk, manually.
        /// Must be Administrator.
        /// </summary>
        /// <param name="inf">DiskDeviceInfo object to the physical disk to read.</param>
        /// <param name="gptInfo">Receives the drive layout information.</param>
        /// <returns>True if successful.</returns>
        /// <remarks></remarks>
        public static bool ReadRawGptDisk(string devicePath, ref RAW_GPT_DISK gptInfo)
        {
            // Demand Administrator for accessing a raw disk.
            AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
            // Dim principalPerm As New PrincipalPermission(Nothing, "Administrators")
            // principalPerm.Demand()


            var hfile = IO.CreateFile(devicePath, IO.GENERIC_READ | IO.GENERIC_WRITE, IO.FILE_SHARE_READ | IO.FILE_SHARE_WRITE, IntPtr.Zero, IO.OPEN_EXISTING, IO.FILE_FLAG_NO_BUFFERING | IO.FILE_FLAG_RANDOM_ACCESS, IntPtr.Zero);

            if (hfile == DevProp.INVALID_HANDLE_VALUE)
            {
                return(false);
            }
            DISK_GEOMETRY_EX geo = default;

            // get the disk geometry to retrieve the sector (LBA) size.
            if (!DiskGeometry(hfile, ref geo))
            {
                User32.CloseHandle(hfile);
                return(false);
            }

            // sector size (usually 512 bytes)
            uint bps = geo.Geometry.BytesPerSector;
            uint br  = 0U;
            long lp  = 0L;
            long lp2 = 0L;
            var  mm  = new MemPtr(bps * 2L);

            IO.SetFilePointerEx(hfile, 0L, ref lp, IO.FilePointerMoveMethod.Begin);
            IO.ReadFile(hfile, mm.Handle, bps * 2, ref br, IntPtr.Zero);
            var mbr = new RAW_MBR();
            var gpt = new RAW_GPT_HEADER();

            RAW_GPT_PARTITION[] gpp = null;

            // read the master boot record.
            mbr = mm.ToStructAt <RAW_MBR>(446L);

            // read the GPT structure header.
            gpt = mm.ToStructAt <RAW_GPT_HEADER>(bps);

            // check the partition header CRC.
            if (gpt.IsValid)
            {
                long lr = br;

                // seek to the LBA of the partition information.
                IO.SetFilePointerEx(hfile, (uint)(bps * gpt.PartitionEntryLBA), ref lr, IO.FilePointerMoveMethod.Begin);
                br = (uint)lr;

                // calculate the size of the partition table buffer.
                lp = gpt.NumberOfPartitions * gpt.PartitionEntryLength;

                // byte align to the sector size.
                if (lp % bps != 0L)
                {
                    lp += bps - lp % bps;
                }

                // bump up the memory pointer.
                mm.ReAlloc(lp);
                mm.ZeroMemory();

                // read the partition information into the pointer.
                IO.ReadFile(hfile, mm.Handle, (uint)lp, ref br, IntPtr.Zero);

                // check the partition table CRC.
                if (mm.CalculateCrc32() == gpt.PartitionArrayCRC32)
                {
                    // disk is valid.

                    lp = (uint)Marshal.SizeOf <RAW_GPT_PARTITION>();
                    br = 0U;
                    int i;
                    int c = (int)gpt.NumberOfPartitions;

                    gpp = new RAW_GPT_PARTITION[c + 1];

                    // populate the drive information.
                    for (i = 0; i < c; i++)
                    {
                        gpp[i] = mm.ToStructAt <RAW_GPT_PARTITION>(lp2);

                        // break on empty GUID, we are past the last partition.
                        if (gpp[i].PartitionTypeGuid == Guid.Empty)
                        {
                            break;
                        }
                        lp2 += lp;
                    }

                    // trim off excess records from the array.
                    if (i < c)
                    {
                        if (i == 0)
                        {
                            gpp = Array.Empty <RAW_GPT_PARTITION>();
                        }
                        else
                        {
                            Array.Resize(ref gpp, i);
                        }
                    }
                }
            }

            // free the resources.
            mm.Free();
            User32.CloseHandle(hfile);

            // if gpp is nothing then some error occurred somewhere and we did not succeed.
            if (gpp is null)
            {
                return(false);
            }

            // create a new RAW_GPT_DISK structure.
            gptInfo            = new RAW_GPT_DISK();
            gptInfo.Header     = gpt;
            gptInfo.Partitions = gpp;

            // we have succeeded.
            return(true);
        }