2014-09-11 16 views
1

C++ 프로그램을 통해 Windows 서버 2008/2012에서 기존 디스크의 속성으로 디스크를 초기화하려고합니다.C++ 프로그램을 통해 Windows 서버 2008/2012에서 디스크를 초기화하는 방법

DeviceIoControl() 방법과 IOCTL_DISK_CREATE_DISK, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, IOCTL_DISK_SET_PARTITION_INFO_EX 코드를 Disk management control codes에서 사용하고 있습니다.

조금에게 DeviceIoControl()

//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 IOCTL_DISK_SET_PARTITION_INFO_EX 코드로 마지막을 제외하고 성공 얻고있다. 이것에 대한 이유는 무엇일까요?

마지막 호출을 주석 처리하면 디스크가 원시 디스크로 초기화되지만이 요구 사항을 충족하지 못합니다.

위의 샘플은 MBR 파티션 스타일에만 해당됩니다. GPT, ... 스타일에 대한 샘플을 찾을 수 없습니다. 누군가가 그것을 알고 있다면 링크를주십시오.

답변

1

IOCTL_DISK_SET_PARTITION_INFO_EX과 함께 잘못된 구조 유형을 사용하고 있습니다. PARTITION_INFORMATION_EX 구조가 아닌 SET_PARTITION_INFORMATION_EX 구조체를 사용합니다.

IOCTL_DISK_SET_DRIVE_LAYOUT_EX으로 이미 설정된 파티션 유형을 설정하기 때문에 IOCTL_DISK_SET_PARTITION_INFO_EX을 사용할 필요가 없을 것입니다. 안타깝게도 잘못된 파티션 유형을 설정하는 데 사용했습니다. NTFS 파티션의 파티션 유형은 PARTITION_IFS입니다.

lgPartitionSize에 의해 200 곱하기는 거의 틀림 없습니다. lgPartitionSize이 섹터의 ​​크기라고 가정하면 디스크의 섹터 크기를 곱해야합니다. 하드 드라이브의 섹터 크기는 항상 512 바이트 (0x200 바이트) 였지만 최신 드라이브는 4096 바이트 섹터 크기를 사용합니다.

파티션 테이블을 올바르게 작성하는 것은 쉽지 않으며, 다른 사람의 코드를 실수로 복사하는 것은 효과가 없습니다. 위에서 언급 한 문제를 해결 한 후에도 여전히 다른 문제가 발생할 가능성이 있습니다. 파티션을 배치하는 방법에 대한 모든 제한 사항을 이해해야합니다.

diskpart 명령을 사용하여 C++ 코드 대신 디스크를 프로그래밍 방식으로 초기화하는 것이 좋습니다.