2013-08-21 79 views
0

我有一個硬盤上有3個分區。當我使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX時,對象(在我的代碼中它是「pdg」對象)僅返回數組1分區信息,即使它表示發現了4分區。我錯過了什麼,因此partitionEntry(必須使用調試器訪問partitionentry的對象pdg)才能顯示所有3個分區。 我已經遍尋了一些信息,並不能得到它的工作。不同的論壇,MSDN ...IOCTL_DISK_GET_DRIVE_LAYOUT_EX不能正常工作

下面是我的代碼

#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); 
} 

感謝

+0

你是不是對什麼是在返回的數據,讓你想返回只有一個分區非常清晰。 3個額外的分區是否輸入爲「PARTITION_ENTRY_UNUSED」? –

+0

我敢打賭,IOCTL_DISK_GET_DRIVE_LAYOUT_EX其實工作不正常 –

+0

我沒有看到任何PARTITION_ENTRY_UNUSED – Helder

回答

1

其他分區的數據是存在的,但沒有被調試器顯示。

DRIVE_LAYOUT_INFORMATION_EX.PartitionEntry被聲明爲長度爲1的陣列,但實際上是動態地分配給匹配PartitionCount。

DeviceIoControl之後設置一個斷點,右鍵單擊pdg並選擇QuickWatch ...,然後更新表達式到pdg->PartitionEntry[1],然後[2]等檢查其他分區。

或者,添加一個循環來遍歷數組PartitionEntry的打印結果出來:

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

你的寫,謝謝很多 – Helder

+0

我有1最後一個懸而未決的問題。如果我在1分區的驅動器上嘗試相同的代碼,它將返回分區計數爲4.它應該是1.這裏的問題是什麼? – Helder

+0

[MSDN](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364001(v = vs.85).aspx)表示PartitionCount將是MBR磁盤的4倍數,但額外的分區將在'Mbr.PartitionType'字段中有'PARTITION_ENTRY_UNUSED'。 – lnmx