Helder
Helder

Reputation: 11

IOCTL_DISK_GET_DRIVE_LAYOUT_EX Not working correctly

I have a hard disk that has 3 partitions on it. When i use IOCTL_DISK_GET_DRIVE_LAYOUT_EX, the object (in my code it's "pdg" object) only return an array 1 partition information even if it says found 4 partition. What am i missing so that the partitionEntry (must use debugger to the object pdg for partitionentry) displays all the 3 partitions. I have looked all over for some information and could not get it to work. Different forums, msdn ...

Below is my code

#define UNICODE 1
#define _UNICODE 1

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

#define wszDrive L"\\\\.\\PhysicalDrive3"

BOOL GetDrive(LPWSTR wszPath)
{
  HANDLE hDevice = INVALID_HANDLE_VALUE;  // handle to the drive to be examined 
  BOOL bResult   = FALSE;                 // results flag
  DWORD junk     = 0;                     // discard results
  DWORD hr;

  DWORD szNewLayout = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + sizeof(PARTITION_INFORMATION_EX) * 4 * 25 ;
  DRIVE_LAYOUT_INFORMATION_EX *pdg = (DRIVE_LAYOUT_INFORMATION_EX*) new BYTE[szNewLayout];

  hDevice = CreateFileW(wszPath,          // drive to open
                        GENERIC_READ|GENERIC_WRITE,                // no access to the drive
                        FILE_SHARE_READ | // share mode
                        FILE_SHARE_WRITE, 
                        NULL,             // default security attributes
                        OPEN_EXISTING,    // disposition
                        0,                // file attributes
                        0);            // do not copy file attributes

  if (hDevice == INVALID_HANDLE_VALUE)    // cannot open the drive
  {
    hr = GetLastError();
      return (FALSE);
  }

  bResult = DeviceIoControl(hDevice,                       // device to be queried
                            IOCTL_DISK_GET_DRIVE_LAYOUT_EX, // operation to perform
                            NULL, 0,                       // no input buffer
                            pdg, szNewLayout,// sizeof(*pdg)*2,            // output buffer
                            &junk,                         // # bytes returned
                            (LPOVERLAPPED) NULL);          // synchronous I/O
  if(!bResult)
  {    
     hr = GetLastError();

     LPTSTR errorText = NULL;
     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, NULL);
     wprintf(L"Error",   errorText);
  }
  CloseHandle(hDevice);

  return (bResult);
}


int wmain(int argc, wchar_t *argv[])
{

  BOOL bResult = FALSE;      // generic results flag

  bResult = GetDrive(wszDrive);

  system ("pause");

  return ((int)bResult);
}

Thanks

Upvotes: 1

Views: 3378

Answers (1)

lnmx
lnmx

Reputation: 11164

The other partition data is there, but not being displayed by the debugger.

DRIVE_LAYOUT_INFORMATION_EX.PartitionEntry is declared as an array of length 1, but is actually allocated dynamically to match the PartitionCount.

Set a breakpoint after DeviceIoControl, right-click pdg and select QuickWatch..., then update the expression to pdg->PartitionEntry[1], then [2], etc. to inspect the other partitions.

Or, add a loop to walk the PartitionEntry array an print the results out:

for( int i = 0; i < pdg->PartitionCount; i++ ) {
    printf( "partition %d: %d\n", i, pdg->PartitionEntry[i].PartitionStyle);
}

Upvotes: 2

Related Questions