2

C++ プログラムを使用して、Windows サーバー 2008/2012 上の既存のディスクのプロパティでディスクを初期化しようとしています。

ディスク管理制御コードDeviceIoControl()のメソッドとIOCTL_DISK_CREATE_DISKコードIOCTL_DISK_SET_DRIVE_LAYOUT_EX, IOCTL_DISK_SET_PARTITION_INFO_EXを使用して、ディスクを使用できるようにします。

少し検索して、次のコードスニペットを取得しました

//To open the drive
hDevice = CreateFile( TEXT("\\\\.\\PhysicalDrive7"), 
                      GENERIC_READ | GENERIC_WRITE,       // no access to the drive 
                      FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode 
                      NULL,                               // default security attributes 
                      OPEN_EXISTING,                      // disposition 
                      0,                                  // file attributes 
                      NULL);                              // do not copy file attributes 


CREATE_DISK dsk; 
dsk.PartitionStyle = PARTITION_STYLE_MBR; //It can also be PARTITION_STYLE_GPT
dsk.Mbr.Signature = 1;

// Initialize disk
bResult = DeviceIoControl( hDevice,                 // device to be queried 
                           IOCTL_DISK_CREATE_DISK,  // operation to perform 
                           &dsk, sizeof(dsk),         
                           NULL, 0,                // no output buffer 
                           &junk,                  // # bytes returned 
                           NULL
                         ); 

LARGE_INTEGER lgPartitionSize;
lgPartitionSize.QuadPart = (1024 * 1024 * 1024);
DWORD dwDriverLayoutInfoExLen = sizeof (DRIVE_LAYOUT_INFORMATION_EX) + 3 * sizeof(PARTITION_INFORMATION_EX);
DRIVE_LAYOUT_INFORMATION_EX *pdg = (DRIVE_LAYOUT_INFORMATION_EX *)new BYTE[dwDriverLayoutInfoExLen];

SecureZeroMemory(pdg, dwDriverLayoutInfoExLen);

pdg->PartitionStyle = PARTITION_STYLE_MBR; 
pdg->PartitionCount = 1;
pdg->Mbr.Signature = 1;

pdg->PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;   
pdg->PartitionEntry[0].StartingOffset.QuadPart = 1048576;  
pdg->PartitionEntry[0].PartitionLength.QuadPart = lgPartitionSize.QuadPart * 200;   
pdg->PartitionEntry[0].PartitionNumber = 1;   
pdg->PartitionEntry[0].RewritePartition = TRUE;

pdg->PartitionEntry[0].Mbr.PartitionType = PARTITION_NTFT; // PARTITION_IFS (NTFS partition or logical drive)   
pdg->PartitionEntry[0].Mbr.BootIndicator = TRUE;
pdg->PartitionEntry[0].Mbr.RecognizedPartition = 1;   
pdg->PartitionEntry[0].Mbr.HiddenSectors = 32256 / 512;   

// Partition a disk
bResult = DeviceIoControl( hDevice,        // device to be queried 
                           IOCTL_DISK_SET_DRIVE_LAYOUT_EX,  // operation to perform 
                           pdg, sizeof DRIVE_LAYOUT_INFORMATION_EX, //output buffer
                           NULL, 0,                // no output buffer 
                           &junk,                    // # bytes returned 
                           NULL
                         ); 

bResult = DeviceIoControl(  hDevice, 
                            IOCTL_DISK_UPDATE_PROPERTIES, 
                            NULL, 0, NULL, 0, &junk, NULL);

PARTITION_INFORMATION_EX dskinfo; 
PARTITION_INFORMATION_MBR mbrinfo; 
mbrinfo.PartitionType = PARTITION_NTFT; 
mbrinfo.HiddenSectors = (32256 / 512);
mbrinfo.BootIndicator = 1;
mbrinfo.RecognizedPartition = 1;

dskinfo.PartitionStyle = PARTITION_STYLE_MBR; 
dskinfo.StartingOffset.QuadPart = 1048576;//0; 
dskinfo.PartitionLength.QuadPart = lgPartitionSize.QuadPart * 200; 
dskinfo.PartitionNumber = 1; 
dskinfo.RewritePartition = TRUE; 
dskinfo.Mbr = mbrinfo;


bResult = DeviceIoControl( hDevice,        // device to be queried 
                           IOCTL_DISK_SET_PARTITION_INFO_EX,  // operation to perform 
                           &dskinfo, sizeof(dskinfo),        // output buffer 
                           NULL, 0,                // no output buffer 
                           &junk,                    // # bytes returned   
                           NULL
                         ); 

へのすべての呼び出しは、エラー 1 のコード (つまり、関数が正しくない)DeviceIoControl()の最後の呼び出しを除いて成功しています。IOCTL_DISK_SET_PARTITION_INFO_EXこの理由は何でしょうか?

最後の呼び出しをコメントアウトすると、ディスクは raw ディスクとして初期化されますが、これは要件を満たしていません。

上記のサンプルは、MBR パーティション スタイル専用です。GPT、... スタイルのサンプルが見つかりませんでした。誰かが知っている場合はリンクを提供してください。

4

1 に答える 1

1

で間違った構造タイプを使用していますIOCTL_DISK_SET_PARTITION_INFO_EXSET_PARTITION_INFORMATION_EX構造ではなく、構造を取りますPARTITION_INFORMATION_EX

IOCTL_DISK_SET_PARTITION_INFO_EXですでに設定されているはずのパーティションタイプを設定するだけなので、おそらく使用する必要はありませんIOCTL_DISK_SET_DRIVE_LAYOUT_EX。残念ながら、これを使用して間違ったパーティション タイプを設定しました。NTFS パーティションのパーティション タイプはPARTITION_IFSです。

掛け算lgPartitionSize200ほぼ間違いなく間違っています。がセクター単位のサイズであると想定される場合lgPartitionSizeは、これにディスクのセクター サイズを掛ける必要があります。ハード ドライブのセクター サイズは常に 512 バイト (0x200バイト) でしたが、最近のドライブは 4096 バイトのセクター サイズを使用しています。

パーティション テーブルを正しく作成するのは簡単ではありません。また、あなたが行ったように他人のコードを無意識にコピーしてもうまくいきません。上記の問題を修正した後でも、他の問題が発生する可能性があります。パーティションのレイアウト方法に関するすべての制限を理解する必要があります。

diskpartC++ コードではなく、このコマンドを使用してプログラムでディスクを初期化することを検討してください。

于 2014-09-13T19:13:58.297 に答える