Recent

Author Topic: [SOLVED] Error Code 122 when retrieving GPT Partition Type GUID from offset 1024  (Read 10605 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Hi

I am trying to read the Partition TYPE GUID of GPT formatted disks. I don't mean the Disk GUID itself. I mean, quite specifically, the partition type GUID which is what identifies the partition as being created by a certain type of system. For example, the partition type GUID for Microsoft reserved partition is E3C9E316-0B5C-4DB8-817D-F92DF00215AE. For a basic data partition, it is EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (see full list in the table here : https://en.wikipedia.org/wiki/GUID_Partition_Table)

I have successfully incorporated some existing code from the fantastic  David Heffernan at StackOverflow (http://stackoverflow.com/a/17132506) which works for things like the Disk GUID. But I am having problem when calling DeviceIOControl and populating another aspect of his type set, 'TPartitionInformationGPT'. Basically, DeviceIOControl is returning false when I try to use it with a TPartitionInformationGPT record variable, but the handle to the disk is valid. The Last OS Error code is 122, which I gather means :

Quote
ERROR_INSUFFICIENT_BUFFER
The data area passed to a system call is too small.
Trouble is, I don't understand why. The relevant portions of code are supplied below. Most is in my GPTMBR unit file, and then I call the functions from my main unit.

Code: [Select]
unit GPTMBR;

interface

uses
  Windows, SysUtils, Dialogs;

type
  TDriveLayoutInformationGpt = record
    DiskId: TGuid;
    StartingUsableOffset: Int64;
    UsableLength: Int64;
    MaxPartitionCount: DWORD;
  end;

  TPartitionInformationGpt = record
    PartitionType: TGuid;
    PartitionId: TGuid;
    Attributes: Int64;
    Name: array [0..35] of WideChar;
  end;

...
function Get_GPT_PartitionType(SelectedDisk : widestring) : TGUID;
function Textify_GPT_PartitionType(GPTType : TGUID) : string;

implementation

// Get_GPT_PartitionType : Get the GPT partition type GUID, which is usually
// located at the third sector at offset 1024 (decimal) 0x400 (hex) and is 16 bytes long.
function Get_GPT_PartitionType(SelectedDisk : widestring) : TGUID;
const
  PARTITION_STYLE_MBR = 0;
  PARTITION_STYLE_GPT = 1;
  PARTITION_STYLE_RAW = 2;
  IOCTL_DISK_GET_DRIVE_LAYOUT_EX = $00070050;
var
  i: Integer;
  Drive: widestring;
  hDevice: THandle;
  GPT_PartitionGUID : TPartitionInformationGpt;
  BytesReturned: DWORD;
  GPTPartitionType : TGUID;

begin
  Drive := SelectedDisk;

  hDevice := CreateFileW(PWideChar(Drive),
                        0,
                        FILE_SHARE_READ or FILE_SHARE_WRITE,
                        nil,
                        OPEN_EXISTING,
                        0,
                        0);

  if hDevice <> INVALID_HANDLE_VALUE then
  begin
    if DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
        @GPT_PartitionGUID, SizeOf(GPT_PartitionGUID), BytesReturned, nil) then // returns FALSE, I assume because GPT_PartitionGUID is too small?
      begin
        // THIS IS NOT BEING EXECUTED
        ShowMessage(GPT_PartitionGUID.Name);
        GPTPartitionType := GPT_PartitionGUID.PartitionType;
        result := GPTPartitionType; // Return the GUID as TGUID for conversion to text next
      end
    else RaiseLastOSError; // Generates Error Code 122
  end;
  CloseHandle(hDevice);
end;

// Textify_GPT_PartitionType : Return a string representation of the type GUID
function Textify_GPT_PartitionType(GPTType : TGUID) : string;
begin
  result := GUIDToString(GPTType); // Convert the TGUID value to text
end;
...

Usage :

[code]
 // First, determine if it a MBR or GPT partitioned disk. Call GPTMBR unit...
      MBRorGPT := MBR_or_GPT(SelectedDisk);
// Now check if it's a GPT, lookup the partition type GUID for looking up against https://en.wikipedia.org/wiki/GUID_Partition_Table list
      if Pos('GPT', MBRorGPT) > 0 then
        begin
          ShowMessage(Textify_GPT_PartitionType(Get_GPT_PartitionType(SelectedDisk)));
        end;

If anyone has a GPT formatted disk (I create virtual disk VHD's using Windows 7 disk manager) and opens it in HxD or any disk software and they navigate to offset 1024, chances are they will see the 16 bytes type GUID I am referring to, in byte reversed order.

Can anyone see why Error Code 122 is being generated here? Thanks a lot
« Last Edit: January 02, 2016, 12:33:52 pm by Gizmo »

Cyrax

  • Hero Member
  • *****
  • Posts: 836
You are feeding wrong data structure to it. See this link for more info : https://msdn.microsoft.com/en-us/library/windows/desktop/aa364001(v=vs.85).aspx

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Yes, I see.

I need to lookup the value in DriveLayoutInfo.PartitionEntry instead. I didn't realise that it points to the TPartitionInformationGpt type, which in turn has the value PartitionType: TGuid. But how do I assign that to a TGUID variable?

Code: [Select]
TDriveLayoutInformationEx = record
    PartitionStyle: DWORD;
    PartitionCount: DWORD;
    DriveLayoutInformation: record
      case Integer of
      0: (Mbr: TDriveLayoutInformationMbr);
      1: (Gpt: TDriveLayoutInformationGpt);
    end;
    PartitionEntry: array [0..15] of TPartitionInformationGpt; // How to assign this to a TGUID variable? 

Code: [Select]
var
  GUIDType : TGUID;
...

if hDevice <> INVALID_HANDLE_VALUE then
    begin
      if DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
        @DriveLayoutInfo, SizeOf(DriveLayoutInfo), BytesReturned, nil) then
      begin
        if DriveLayoutInfo.PartitionStyle = 0 then result := 'MBR (sig: ' + IntToHex(SwapEndian(DriveLayoutInfo.DriveLayoutInformation.Mbr.Signature), 8) + ')';
        if DriveLayoutInfo.PartitionStyle = 1 then // A GTP partition is there
        begin
          result := 'GPT (Disk GUID: ' + GUIDToString(DriveLayoutInfo.DriveLayoutInformation.Gpt.DiskId) + ')';
          GUIDType := DriveLayoutInfo.PartitionEntry; // HOW DO I DO THIS LINE PROPERLY?
          result := GUIDToString(GUIDType);   

molly

  • Hero Member
  • *****
  • Posts: 2330
But how do I assign that to a TGUID variable?
Assuming you are talking about this structure, you copy the GUID bytes into TGUID record ?

Other functions that might perhaps be of help, here.


Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #4 on: November 23, 2015, 10:16:18 pm »
OK, please see attached project which is a stripped demo to simplify.

You should find that by default it returns a false GUID Type of zeroes.

Or, if you switch the if statement to use IOCTL_GET_DISK_DRIVE_LAYOUT_EX you should find it generates the 122 error.

Can anyone else confirm if they get this as well? Does it help people help me work out where the problem is?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #5 on: November 24, 2015, 12:19:02 am »
@Gizmo:
Yes i can confirm and yes you're doing it wrong  ;D

I haven't looked at your structures (i used those from jedi win), but you should understand that the DrivelayoutInformationEx structure only defines room for a single partition (even though your declared structure defined to be able to support more partitions). This seems to cause confusion (also for me), but it is mentioned on the IOCTL_DISK_GET_DRIVE_LAYOUT_EX msdn page

Quote
Community Additions

DRIVE_LAYOUT_INFORMATION_EX memory allocation

C99 Standard states that the last member of structure can be an array whose size is omitted.
DRIVE_LAYOUT_INFORMATION_EX is using this feathure, to call this control code correctly,
you cannot just declare a struct, should do something like this:

DWORD layout_size = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + MAX_NUM_PARTITION * sizeof(PARTITION_INFORMATION_EX);
DRIVE_LAYOUT_INFORMATION_EX *disk_layout = (DRIVE_LAYOUT_INFORMATION_EX*) new char[layout_size];

MAX_NUM_PARTITION , maximum number of partitions on that disk.

I've attached a small test program (not lazarus, fpc), which seem to work for me and at least gets rid of the error 122. Now for the GUID's, i'm leaving some room for you to experiment.

hope it helps.

PS: the remark in the source-code regarding not needing admin rights doesn't work for me (tested with xp).
« Last Edit: November 24, 2015, 12:40:40 am by molly »

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #6 on: November 26, 2015, 07:25:03 pm »
Thanks Molly.

The API either doesn't suit my requirments (because GPT disks can be initialised without ever even being formatted with an actual partition) or I'm just a totally stupid. Probably the latter but hey, I've tried to write my own instead.

So I have a type declaration and a function:
Code: [Select]
type
...
  TGPTHeader = packed record
      TypeID : array [0..15] of byte;
      NextVal : array [0..15] of byte;
      WHateverElseINeed : array [0..15] of byte;
end;
...

function ReadGPT(hDevice : THandle) : string;
var
  DiskStream : THandleStream;
  GPTHeader : TGPTHeader;
  GPTGUIDType : string;
  I : integer;
begin
  i := 0;
  DiskStream := THandleStream.Create(hDevice);
  DiskStream.Position := 0;
  // Seek and start the read from offset 1024 of the disk
  DiskStream.Seek(1023, soFromBeginning);
  // Read in the 32 bytes of data, 16 into TypeID and 16 to NextVal
  if DiskStream.Read(GPTHeader, SizeOf(GPTHeader)) > -1 then
    begin
      // And display it
      for i:= 0 to 15 do
      begin
        GPTGUIDType := GPTGuidType + IntToHex(GPTHeader.TypeID[i], 2);
      end;
      result := GPTGUIDType;
    end
  else RaiseLastOSError;
  DiskStream.Free;
end;                   

But, no matter what I do, I keep just getting the following hex string :  00000000910000000000000046000000

What gives? Why the hell does this not simply start at offset zero, move to offset 1024, read in 45 bytes of data or so and parse out the first 16 bytes as a valid hex string? The hex string, incidentally, should be : 16 E3 C9 E3 5C 0B B8 4D 81 7D F9 2D F0 02 15 AE
« Last Edit: November 26, 2015, 07:28:09 pm by Gizmo »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #7 on: November 26, 2015, 09:02:37 pm »
Hi gizmo,

i wouldn't dare say "you're a totally stupid", however and afaik some things do go wrong in your code.

In order to let your (previous attached) code work, please change the hard-coded array of 16 partitions, as it is wrong.

My code (hopefully) showed that increasing that buffer does get rid of the "122 error code".

I've experimented a little, and it seems that 32 entries for partitions does the trick (at least when i reserve enough memory for that my code still works).


But there's another 'problem' with the (previous) code you attached.

afaik the function DRIVE_LAYOUT_INFORMATION_EX, reads the whole drive layout, even when things are not formatted -> tested with mbr and seems to works like a charm as  it reports the partition being raw in that case.

So, there's no need to read in the partition tables manually, as a single DRIVE_LAYOUT_INFORMATION_EX fills out the entire DrivelayoutInformationEx structure.

My current 'read data from HD' procedure reads:

Code: [Select]
Procedure DoSomeAction;
var
  hDevice            : THandle;
  DriveLayoutInfo    : PDrivelayoutInformationEx;
  DriveLayoutSize    : DWORD;
  BytesReturned      : DWORD;
begin
  hDevice := jwawinbase.CreateFile
  (
    '\\.\PHYSICALDRIVE0', 
    GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
    nil, OPEN_EXISTING, 0, 0
  );

  if (hDevice <> INVALID_HANDLE_VALUE) then
  begin
    DriveLayoutSize := sizeof(DRIVE_LAYOUT_INFORMATION_EX) + MAX_NUM_PARTITIONS * sizeof(PARTITION_INFORMATION_EX);
    DrivelayoutInfo := AllocMem(DriveLayoutSize);

    if DeviceIoControl
    (
      hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
      DriveLayoutInfo, DriveLayoutSize, @BytesReturned, nil
    ) then
    begin
      WriteLn('DeviceIoControl() call succeeded');
      WriteLn(BytesReturned, ' bytes were returned');

      DumpInfo(DriveLayoutInfo);
    end
    else WriteLn('failed with error nr: ', GetLastError);

    FreeMem(DriveLayoutInfo);

    CloseHandle(hDevice);
  end
  else WriteLn('unable to access partition');
end;

And The DumpInfo routine simply prints out the data that was read.

Code: [Select]
Attempting to read partition
DeviceIoControl() call succeeded
2928 bytes were returned
Sign = MBR (sig: REMOVED FOR PRIVACY)
This drive has 5 Partitions
---
Partition[  0].PartitionStyle          = MBR
Partition[  0].StartingOffset          = 32256
Partition[  0].PartitionLength         = 38165266944 (36397 MB)
Partition[  0].PartitionNumber         = 1
Partition[  0].RewritePartition        = FALSE
mbr info: used
Partition[  0].mbr.PartitionType       = PARTITION_IFS (#7)
Partition[  0].mbr.BootIndicator       = TRUE
Partition[  0].mbr.RecognizedPartition = TRUE
Partition[  0].mbr.HiddenSectors       = 63
---
Partition[  4].PartitionStyle          = MBR
Partition[  4].StartingOffset          = 38165331456
Partition[  4].PartitionLength         = 150489690624 (143518 MB)
Partition[  4].PartitionNumber         = 2
Partition[  4].RewritePartition        = FALSE
mbr info: used
Partition[  4].mbr.PartitionType       = PARTITION_IFS (#7)
Partition[  4].mbr.BootIndicator       = FALSE
Partition[  4].mbr.RecognizedPartition = TRUE
Partition[  4].mbr.HiddenSectors       = 63
---
Partition[  8].PartitionStyle          = MBR
Partition[  8].StartingOffset          = 188655054336
Partition[  8].PartitionLength         = 150489690624 (143518 MB)
Partition[  8].PartitionNumber         = 3
Partition[  8].RewritePartition        = FALSE
mbr info: used
Partition[  8].mbr.PartitionType       = PARTITION_IFS (#7)
Partition[  8].mbr.BootIndicator       = FALSE
Partition[  8].mbr.RecognizedPartition = TRUE
Partition[  8].mbr.HiddenSectors       = 63
---
Partition[ 12].PartitionStyle          = MBR
Partition[ 12].StartingOffset          = 339144777216
Partition[ 12].PartitionLength         = 150489690624 (143518 MB)
Partition[ 12].PartitionNumber         = 4
Partition[ 12].RewritePartition        = FALSE
mbr info: used
Partition[ 12].mbr.PartitionType       = PARTITION_IFS (#7)
Partition[ 12].mbr.BootIndicator       = FALSE
Partition[ 12].mbr.RecognizedPartition = TRUE
Partition[ 12].mbr.HiddenSectors       = 63
---
Partition[ 16].PartitionStyle          = MBR
Partition[ 16].StartingOffset          = 489634500096
Partition[ 16].PartitionLength         = 150489690624 (143518 MB)
Partition[ 16].PartitionNumber         = 5
Partition[ 16].RewritePartition        = FALSE
mbr info: used
Partition[ 16].mbr.PartitionType       = PARTITION_IFS (#7)
Partition[ 16].mbr.BootIndicator       = FALSE
Partition[ 16].mbr.RecognizedPartition = TRUE
Partition[ 16].mbr.HiddenSectors       = 63

Nothing exciting going on in DumpInfo() routine, just interpreting the data from record DrivelayoutInformationEx and printing it to console.

Why don't you try telling what you want exactly instead of jumping left and right adjusting the question ?

The error 122 is fixed by simply increasing the array size to such extend that it can actually  contain all the partition data gathered by the windows DeviceIoControl() function.

Sorry, i haven't looked at your latest snippet as the error is fixed.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #8 on: November 26, 2015, 09:54:04 pm »
Code: [Select]
  DiskStream.Seek(1023, soFromBeginning);

But, no matter what I do, I keep just getting the following hex string :  00000000910000000000000046000000

What gives? Why the hell does this not simply start at offset zero, move to offset 1024, read in 45 bytes of data or so and parse out the first 16 bytes as a valid hex string? The hex string, incidentally, should be : 16 E3 C9 E3 5C 0B B8 4D 81 7D F9 2D F0 02 15 AE

From documentation:
Quote
Remark:
  • ThandleStream does not obtain a handle from the OS by itself, it just handles reading and writing to such a handle by wrapping the system calls for reading and writing; Descendent classes should obtain a handle from the OS by themselves and pass it on in the inherited constructor.
  • Contrary to Delphi, no seek is implemented for THandleStream, since pipes and sockets do not support this. The seek is implemented in descendent methods that support it.

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #9 on: November 26, 2015, 10:22:15 pm »
Hi Molly.

Thanks, as always, for your help and time.

Few observations....

I tried changing

Code: [Select]

  TDriveLayoutInformationEx = record
    PartitionStyle: DWORD;
    PartitionCount: DWORD;
    DriveLayoutInformation: record
      case Integer of
      0: (Mbr: TDriveLayoutInformationMbr);
      1: (Gpt: TDriveLayoutInformationGpt);
    end;
    PartitionEntry: array [0..15] of TPartitionInformationGpt;

to

Code: [Select]
  TDriveLayoutInformationEx = record
    PartitionStyle: DWORD;
    PartitionCount: DWORD;
    DriveLayoutInformation: record
      case Integer of
      0: (Mbr: TDriveLayoutInformationMbr);
      1: (Gpt: TDriveLayoutInformationGpt);
    end;
    PartitionEntry: array [0..31] of TPartitionInformationGpt;

Same error 122.

The entire reason I'm doing this is specifically for GPT data, and not just any parts of the GPT data. Just the 16 bytes that tell me what created the volume, that appear at offset 1024 of a GPT prepared disk. The implementation I have is inheritted from the example at Stackoverflow that gives me all the means to query a disks GPT properties, if its MBR or GPT, and if it is GPT, the values I need from it. Specifically, in TPartitionInformationGpt, is PartitionType: TGuid, which I can then convert to string using GUIDToString;

Using PDrivelayoutInformationEx does not give me those choices (as far as I can see), so I can't query things like DriveLayoutInfo.PartitionStyle and then PartitionInformationEx.Gpt.PartitionType. I did of course adjust my uses declaration so it compiled OK, but the structure doesn't seem to offer any properties. At least, if I can, I can't see how.

And you're not using the standard Windows API either I notice, which confused me further (whereas I have uses Windows) but rather the jwawinbase, jwawinnt, jwawinioctl uses. I'm not sure which is the recommended one, but I've generally assumed the Windows one. Is that not right?

You're correct that your sample does compile and run without error, except all it returns is the bytes read. I could use it if I could query the GPT structures individually (type, diskGUID etc) but I don't think I can?

Given that you seem to know what you're doing, is it not possible for you to look at the existing demo project I uploaded and tweak whatever (small, single?) value it is (the partition count by the sounds of it?) that prevents the 122 error and successfully returns the value? Because any changes I make do not work.

The entire thing is pretty much done, except it doesn't successfuly return the value. That's all I need. I can take it from there.

As for the seek issue - I did read that, but left it in from my last desperate attempt to get it run. Taking it out makes no difference. It still generates the same value.   
« Last Edit: November 26, 2015, 10:24:19 pm by Gizmo »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #10 on: November 26, 2015, 11:12:10 pm »
@gizmo:
thank you for the clarification

Quote
Same error 122.
In that case either windows increased that value with newer version (tested with xp pro here), which can happen (as 32 is also not minimum possible amount, it's more like 128 or even 256 entries), or something seems amiss with your declared structures (hence i used jedi's to make sure -> and i was lazy checking yours  :D ).

Quote
The entire reason I'm doing this is specifically for GPT data, and not just any parts of the GPT data. Just the 16 bytes that tell me what created the volume, that appear at offset 1024 of a GPT prepared disk.
Then my code i attached earlier is a good starting point. The only thing left for you todo is interpreting the data correctly.

Quote
Using PDrivelayoutInformationEx does not give me those choices (as far as I can see), so I can't query things like DriveLayoutInfo.PartitionStyle and then PartitionInformationEx.Gpt.PartitionType.
And that's where the real culprit lies ;-)

Ok, so you have difficulty traveling down the structures:

Quote
Given that you seem to know what you're doing, is it not possible for you to look at the existing demo project I uploaded and tweak whatever (small, single?) value it is (the partition count by the sounds of it?) that prevents the 122 error and successfully returns the value?
Too much credit, i have no idea how windows works  (i simply go along with what msdn writes and test in vm) :-[

Take my example, using jedi's structures. After reading the data into DrivelayoutInformationEx:

When
Quote
PDrivelayoutInformationEx^.PartitionStyle = PARTITION_STYLE_GPT
then
Quote
writeLine(GUIDToString(PDrivelayoutInformationEx^.Union.Gpt.DiskId));

then check for each valid x (array of entries = nr of partitions)
Code: Pascal  [Select][+][-]
  1.  PDrivelayoutInformationEx^.partitionEntry[x].PartitionStyle

if that partition style = PARTITION_STYLE_GPT then :
Code: Pascal  [Select][+][-]
  1.  
  2.  PDrivelayoutInformationEx^.partitionEntr[x].Gpt.PartitionType;
  3.  PDrivelayoutInformationEx^.partitionEntr[x].Gpt.PartitionId;
  4.  PDrivelayoutInformationEx^.partitionEntr[x].Gpt.Attributes;
  5.  PDrivelayoutInformationEx^.partitionEntr[x].Gpt.Name;

Does that make more sense ?

Sorry, i'm not in a habit writing code for someone else. There's got to be something left for you to learn  ;D

(and i do apologize in advance if i made a mistake somewhere along the line, because in my code uses with's, so it could be that i missed a dot or circumflex somewhere).

edit: ^^ and i did made a mistake, sorry for that: in the last code line samples i posted the union part must be removed, i have corrected this now.
« Last Edit: November 26, 2015, 11:48:03 pm by molly »

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #11 on: November 27, 2015, 12:03:49 am »
Reading the posts above, and reading:

The Last OS Error code is 122, which I gather means :

Quote
ERROR_INSUFFICIENT_BUFFER
The data area passed to a system call is too small.

then going directly to DeviceIoControl(..IOCTL_DISK_GET_DRIVE_LAYOUT_EX.. calls in your code and in molly's, I see you used SizeOf(GPTPartitionLayoutInfo) while Molly used DriveLayoutSize := sizeof(DRIVE_LAYOUT_INFORMATION_EX) + MAX_NUM_PARTITIONS * sizeof(PARTITION_INFORMATION_EX);

I marked the difference in red.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #12 on: November 27, 2015, 02:19:48 am »
You're absolutely correct there engkin,

.. and most probably this is Gizmo's (first) problem.

The (default declared) DrivelayoutInformationEx structure/record (ms$ and jedi) declares the structure/record to have room for only 1 single partition.

OP did declared a custom record structure to circumvent and increased the number of entries for the partition array, by (initially) making room for 16 entries.

I checked that value of 16, and allocating room for 16 entries failed for me with error 122, while allocating 32 entries worked for me (error went away).

The value of max. 16 partitions is mentioned somewhere in msdn documentation, but i believe this to be incorrect (or placed out of context).

According to Intel gpt white-paper the max. amount of partitions (per GPT disk) is 128.

But, since GPT could theoretically support 256 (??) partitions entries, i used that worsed case scenario for the example that i posted.

It might be that the value of MAX_NUM_PARTITIONS was increased over the years by m$ (i was unable to find the value for that constant), so that different versions of Windows might perhaps require another value for this variable.

Sorry to say that i was unable to locate the (official) specifications with regards to GPT, although i didn't searched very long (allocating memory for 256 partition entries simply works for me).

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #13 on: November 27, 2015, 06:29:38 pm »
Hi Gizmo,

I took some time to look at your definitions:
Quote
PartitionEntry: array [0..31] of TPartitionInformationGpt;

No idea where ^^ that ^^ came from, msdn writes:
Quote
PARTITION_INFORMATION_EX PartitionEntry[1];

That also explains why you seem to have a problem with reaching the information inside the structures/records, which you would like to obtain.

If you correct that inside your unit GPTMBR  + remove all code between begin end after you've read DiskGUID, then you should be good to go. In case you keep getting the 122 error then increase the PartitionEntry array so that it can contain 256 partition entries.

Which btw leaves you in the same situation as described in previous posts: you still need to interpret all the obtained data from the records.

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Error Code 122 when retrieving GPT Partition Type GUID from offset 1024
« Reply #14 on: January 02, 2016, 12:33:40 pm »
Hi all

Just for info, I wrote my own method for this in the end.

For anyone else wishing to benefit, the unit is here : https://github.com/tedsmith/yaffi/blob/master/uGPT.pas

Thanks to all, and to Molly in particular, for your time.

 

TinyPortal © 2005-2018