BOOL DLL_EXPORT ResizeExtendPartition(BYTE btHardDisk, PPARTITION_ENTRY ppeParEntry, PINT pnError) { PARTITION_INFORMATION piNew; int nIndex; DRIVE_LAYOUT DriveLayout; DISK_GEOMETRY dg; btHardDisk &= 0x7f; if( GetDriveLayout(btHardDisk,&DriveLayout)) return FALSE; if( GetDiskGeometry(btHardDisk,&dg)) return FALSE; for( nIndex = 0 ; nIndex < 4 ; nIndex++ ) { if( GetPartitionType(&DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR ) break; } if( nIndex < 4 ) { //Get new information memset(&piNew,0,sizeof(PARTITION_INFORMATION)); piNew.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector * dg.BytesPerSector; piNew.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition * dg.BytesPerSector; piNew.PartitionType = ppeParEntry->SystemFlag; if( ResizePrimary(&DriveLayout, &piNew, &dg, nIndex)) { return FALSE; }else if ( SetDriveLayout( btHardDisk, &DriveLayout )) { return FALSE; }else return TRUE; }else return FALSE; }
/* * Fill the drive properties (size, FS, etc) * Returns TRUE if the drive has a partition that can be mounted in Windows, FALSE otherwise */ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize, BOOL bSilent) { // MBR partition types that can be mounted in Windows const uint8_t mbr_mountable[] = { 0x01, 0x04, 0x06, 0x07, 0x0b, 0x0c, 0x0e, 0xef }; BOOL r, ret = FALSE, isUefiNtfs = FALSE; HANDLE hPhysical; DWORD size; BYTE geometry[256] = {0}, layout[4096] = {0}, part_type; PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; char* volume_name; char tmp[256]; DWORD i, j; if (FileSystemName == NULL) return FALSE; SelectedDrive.nPartitions = 0; // Populate the filesystem data FileSystemName[0] = 0; volume_name = GetLogicalName(DriveIndex, TRUE, FALSE); if ((volume_name == NULL) || (!GetVolumeInformationA(volume_name, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize))) { suprintf("No volume information for drive 0x%02x\n", DriveIndex); } safe_free(volume_name); hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); if (hPhysical == INVALID_HANDLE_VALUE) return 0; r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, geometry, sizeof(geometry), &size, NULL); if (!r || size <= 0) { suprintf("Could not get geometry for drive 0x%02x: %s\n", DriveIndex, WindowsErrorString()); safe_closehandle(hPhysical); return 0; } if (DiskGeometry->Geometry.BytesPerSector < 512) { suprintf("Warning: Drive 0x%02x reports a sector size of %d - Correcting to 512 bytes.\n", DriveIndex, DiskGeometry->Geometry.BytesPerSector); DiskGeometry->Geometry.BytesPerSector = 512; } SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); suprintf("Disk type: %s, Sector Size: %d bytes\n", (DiskGeometry->Geometry.MediaType == FixedMedia)?"Fixed":"Removable", DiskGeometry->Geometry.BytesPerSector); suprintf("Cylinders: %" PRIi64 ", TracksPerCylinder: %d, SectorsPerTrack: %d\n", DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack); r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, layout, sizeof(layout), &size, NULL ); if (!r || size <= 0) { suprintf("Could not get layout for drive 0x%02x: %s\n", DriveIndex, WindowsErrorString()); safe_closehandle(hPhysical); return 0; } #if defined(__GNUC__) // GCC 4.9 bugs us about the fact that MS defined an expandable array as array[1] #pragma GCC diagnostic ignored "-Warray-bounds" #endif switch (DriveLayout->PartitionStyle) { case PARTITION_STYLE_MBR: SelectedDrive.PartitionType = PARTITION_STYLE_MBR; for (i=0; i<DriveLayout->PartitionCount; i++) { if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { SelectedDrive.nPartitions++; } } suprintf("Partition type: MBR, NB Partitions: %d\n", SelectedDrive.nPartitions); SelectedDrive.has_mbr_uefi_marker = (DriveLayout->Mbr.Signature == MBR_UEFI_MARKER); suprintf("Disk ID: 0x%08X %s\n", DriveLayout->Mbr.Signature, SelectedDrive.has_mbr_uefi_marker?"(UEFI target)":""); AnalyzeMBR(hPhysical, "Drive"); for (i=0; i<DriveLayout->PartitionCount; i++) { if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; isUefiNtfs = (i == 1) && (part_type == 0xef) && (DriveLayout->PartitionEntry[i].PartitionLength.QuadPart <= 1*MB); suprintf("Partition %d%s:\n", i+1, isUefiNtfs?" (UEFI:NTFS)":""); for (j=0; j<ARRAYSIZE(mbr_mountable); j++) { if (part_type == mbr_mountable[j]) { ret = TRUE; break; } } // NB: MinGW's gcc 4.9.2 broke "%lld" printout on XP so we use the inttypes.h "PRI##" qualifiers suprintf(" Type: %s (0x%02x)\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %d, Boot: %s, Recognized: %s\n", ((part_type==0x07)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); if ((part_type == RUFUS_EXTRA_PARTITION_TYPE) || (isUefiNtfs)) // This is a partition Rufus created => we can safely ignore it --SelectedDrive.nPartitions; if (part_type == 0xee) // Flag a protective MBR for non GPT platforms (XP) SelectedDrive.has_protective_mbr = TRUE; } } break; case PARTITION_STYLE_GPT: SelectedDrive.PartitionType = PARTITION_STYLE_GPT; suprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount); suprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId)); suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes\n", DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart); for (i=0; i<DriveLayout->PartitionCount; i++) { SelectedDrive.nPartitions++; tmp[0] = 0; wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp)); suprintf("Partition %d:\r\n Type: %s\r\n Name: '%s'\n", i+1, GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp); suprintf(" ID: %s\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %" PRIi64 ", Attributes: 0x%016" PRIX64 "\n", GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector, DriveLayout->PartitionEntry[i].Gpt.Attributes); // Don't register the partitions that we don't care about destroying if ( (strcmp(tmp, "UEFI:NTFS") == 0) || (CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_MSFT_RESERVED_GUID)) || (CompareGUID(&DriveLayout->PartitionEntry[i].Gpt.PartitionType, &PARTITION_SYSTEM_GUID)) ) --SelectedDrive.nPartitions; if ( (memcmp(&PARTITION_BASIC_DATA_GUID, &DriveLayout->PartitionEntry[i].Gpt.PartitionType, sizeof(GUID)) == 0) && (nWindowsVersion >= WINDOWS_VISTA) ) ret = TRUE; } break; default: SelectedDrive.PartitionType = PARTITION_STYLE_MBR; suprintf("Partition type: RAW\n"); break; } #if defined(__GNUC__) #pragma GCC diagnostic warning "-Warray-bounds" #endif safe_closehandle(hPhysical); return ret; }
BOOL DLL_EXPORT GetProtectSectors(BYTE btHardDisk, DWORD dwStartSector, CREATE_PAR_FLAG flags,//indicate is logical or primary DWORD dwFlag,//create flags PPARTITION_ENTRY ppeParEntry, PPROTECT_SECTOR pProtect,//[out] BOOL bWriteToDisk, int *pnError) { DISK_GEOMETRY dg; DRIVE_LAYOUT DriveLayout; int nErrorCode; int nIndex; LARGE_INTEGER lnStartByte; BOOL bDeleteSuccess; PARTITION_INFORMATION pi,piExtend; BYTE btPartitionType; BOOL bExistExtend,bNeedResize,bResizeSuccess; LARGE_INTEGER lnExtendStart,lnExtendEnd; //viriable need to get the protect sectors BOOL bIsDeleteLogical; BOOL bIsCreateLogical; DWORD dwExtOriginalHead,dwExtFinalHead; DWORD dwOriginalHead,dwOriginalEnd; DWORD dwFinalHead,dwFinalEnd; DWORD dwOriginalEmbr,dwFinalEmbr; //p//init protect logic viriables memset( pProtect, 0, sizeof(PROTECT_SECTOR)); bIsDeleteLogical = FALSE; bIsCreateLogical = FALSE; dwExtOriginalHead = 0; dwExtFinalHead = 0; dwOriginalHead = 0; dwOriginalEnd = 0; dwFinalHead = 0; dwFinalEnd = 0; dwOriginalEmbr = 0; dwFinalEmbr = 0; btHardDisk &= 0x7f; bDeleteSuccess = FALSE; // 102 indicate false *pnError = nErrorCode = ERR_PARMAN_PARAM; //Get disk geometry and layout information if ( GetDiskGeometry(btHardDisk,&dg)) return FALSE; if ( GetDriveLayout(btHardDisk, &DriveLayout)) return FALSE; /************************************************ Delete partition ************************************************/ //look for the partition lnStartByte.QuadPart = (__int64)dg.BytesPerSector * dwStartSector; for( nIndex = DriveLayout.dli.PartitionCount -1 ; nIndex >=0 ; nIndex-- ) { if(DriveLayout.dli.PartitionEntry[nIndex].StartingOffset.QuadPart == lnStartByte.QuadPart) break; } //usb disk if( ( DriveLayout.dli.PartitionCount == 1 ) && ( nIndex == 0 ) ) { //p//back up the partition information memcpy(&pi, &DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); //zero partition table memset( DriveLayout.dli.PartitionEntry, 0, 4*sizeof(PARTITION_INFORMATION) ); DriveLayout.dli.PartitionCount = 4; for( nIndex = 0 ; nIndex < 4 ; nIndex++ ) DriveLayout.dli.PartitionEntry[nIndex].RewritePartition = TRUE; bDeleteSuccess = TRUE; }else { //if found do delete if(nIndex >= 0) { switch( GetPartitionType(&DriveLayout, nIndex) ) { case DISKMAN_PAR_UNUSED: break; case DISKMAN_PAR_EXTENDED_MBR: if ( flags.Extended ) { //delete first logical nIndex = 4; //p//back up the partition information memcpy(&pi, &DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex); bIsDeleteLogical = TRUE; break; } //else consider as primary case DISKMAN_PAR_PRIMARY_MBR: //p//back up the partition information memcpy(&pi, &DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); bDeleteSuccess = !DeletePrimary(&DriveLayout,nIndex); break; case DISKMAN_PAR_EXTENDED_EMBR: nIndex +=3; case DISKMAN_PAR_LOGICAL_EMBR: //p//back up the partition information memcpy(&pi, &DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); bDeleteSuccess = !DeleteLogical(&DriveLayout,nIndex); bIsDeleteLogical = TRUE; break; } }//if nIndex >= 0; } //delete fail if( bDeleteSuccess ) { //p//pi now store the original start and end dwOriginalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector); dwOriginalEnd = dwOriginalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector); if( bIsDeleteLogical ) dwOriginalEmbr = dwOriginalHead - pi.HiddenSectors;//dwOriginalEmbr == embr }else { return FALSE; } /************************************************ Create partition ************************************************/ //check if usb sigle partition if((DriveLayout.dli.PartitionCount % 4) != 0 ) return FALSE; //translate to partition information memset(&pi,0,sizeof(PARTITION_INFORMATION)); //bootable? pi.BootIndicator = ppeParEntry->BootFlag ? 1:0; //file system pi.PartitionType = ppeParEntry->SystemFlag; //start pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector * dg.BytesPerSector; //length pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition * dg.BytesPerSector; //detect if exist extend partition bExistExtend = FALSE; for( nIndex = 0 ; nIndex < 4 ; nIndex++ ) { if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR ) { bExistExtend = TRUE; memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart; lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart; lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1; //p//Get extend original start dwExtOriginalHead = (DWORD)(lnExtendStart.QuadPart / dg.BytesPerSector); break; } } //do alignment if ( dwFlag == LOGICAL ) { LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR); }else LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR); bNeedResize = FALSE; bResizeSuccess = TRUE; if( dwFlag == LOGICAL ) { bIsCreateLogical = TRUE; if( bExistExtend ) { //beyond the extend low boundary if( pi.StartingOffset.QuadPart < lnExtendStart.QuadPart ) { //justify the extend head piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart; piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart - piExtend.StartingOffset.QuadPart + 1; bNeedResize = TRUE; } //beyond the extend high boundary if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart > lnExtendEnd.QuadPart + 1 ) { //justify the extend end //piExtend.StartingOffset has modified; piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart - piExtend.StartingOffset.QuadPart; bNeedResize = TRUE; } if ( bNeedResize ) { nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); bResizeSuccess = ! nErrorCode; } //resize success create logical if( bResizeSuccess ) { //p//get extend final head dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector); nErrorCode = CreateLogical(&DriveLayout,&pi,&dg); } }else { //no extend partition, should create one //Backup partition type; btPartitionType = pi.PartitionType; pi.PartitionType = PARTITION_EXTENDED; nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg); if( !nErrorCode ) { pi.PartitionType = btPartitionType; nErrorCode = CreateLogical(&DriveLayout,&pi,&dg); } } }else { // if primary overlap the extend then resize extend partition if( bExistExtend ) { if( IsOverlap(&piExtend,&pi)) { //try to resize extend partition forward piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart - lnExtendStart.QuadPart; //if length < 0 then length = 0 if( piExtend.PartitionLength.QuadPart < 0 ) piExtend.PartitionLength.QuadPart = 0; //resize forward nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); if( nErrorCode != 0 ) { //try to resize backward piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart; piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart - piExtend.StartingOffset.QuadPart + 1; nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); bResizeSuccess = ! nErrorCode; } } } if( bResizeSuccess ) { //p//get extend final head dwExtFinalHead = (DWORD)(piExtend.StartingOffset.QuadPart / dg.BytesPerSector); nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg); } } //get the protect sectors group if( !nErrorCode ) { //pi now store the partition information created dwFinalHead = (DWORD)(pi.StartingOffset.QuadPart / dg.BytesPerSector); dwFinalEnd = dwFinalHead + (DWORD)(pi.PartitionLength.QuadPart / dg.BytesPerSector); if( bIsCreateLogical ) { dwFinalEmbr = dwFinalHead;//dwFinalEmbr == embr dwFinalHead += dg.SectorsPerTrack; } if( dwExtOriginalHead >= dwFinalHead && dwExtOriginalHead <= dwFinalEnd - 1 ) { pProtect->bProtectReadOne = TRUE; pProtect->dwProtectReadOne = dwExtOriginalHead; } if( bIsCreateLogical ^ bIsDeleteLogical ) { //delete primary, create logical or //delete logical, create primary if( dwExtFinalHead >= dwOriginalHead && dwExtFinalHead <= dwOriginalEnd - 1 ) { pProtect->bProtectWriteOne = TRUE; pProtect->dwProtectWriteOne = dwExtFinalHead; } } if( bIsDeleteLogical ) { if( dwOriginalEmbr >= dwFinalHead && dwOriginalEmbr <= dwFinalEnd - 1 ) { pProtect->bProtectReadTwo = TRUE; pProtect->dwProtectReadTwo = dwOriginalEmbr; } if( bIsCreateLogical ) { //delete logical, create logical if( dwFinalEmbr >= dwOriginalHead && dwFinalEmbr <= dwOriginalEnd - 1 ) { pProtect->bProtectWriteTwo = TRUE; pProtect->dwProtectWriteTwo = dwFinalEmbr; } } } } //if write set drive layout if( !nErrorCode && bWriteToDisk ) nErrorCode = SetDriveLayout(btHardDisk, &DriveLayout, TRUE); //return *pnError = nErrorCode; return( nErrorCode == 0 ); }
BOOL DLL_EXPORT CreatePartition(PPARTITION_ENTRY ppeParEntry, BYTE btHardDisk, DWORD dwFlag, BOOL blIsFormat, PBYTE pLabel, HWND hWnd, PINT pnError) { int nErrorCode; PARTITION_INFORMATION pi,piExtend; DRIVE_LAYOUT DriveLayout; DISK_GEOMETRY dg; int nIndex; BYTE btPartitionType; BOOL bExistExtend; BOOL bNeedResize,bResizeSuccess; LARGE_INTEGER lnExtendStart,lnExtendEnd; char chDriveLetter; char szLabel[12]; // int nLogicalNumber; btHardDisk &= 0x7f; //Get disk geomtry and layout information *pnError = nErrorCode = ERR_PARMAN_PARAM; // 102 indicate false if ( GetDiskGeometry(btHardDisk,&dg)) return FALSE; if ( GetDriveLayout(btHardDisk, &DriveLayout)) return FALSE; //check if usb sigle partition if((DriveLayout.dli.PartitionCount % 4) != 0 ) return FALSE; //translate to partition information memset(&pi,0,sizeof(PARTITION_INFORMATION)); pi.StartingOffset.QuadPart = (__int64)ppeParEntry->StartSector * dg.BytesPerSector; pi.PartitionLength.QuadPart = (__int64)ppeParEntry->SectorsInPartition * dg.BytesPerSector; pi.BootIndicator = ppeParEntry->BootFlag ? 1:0; pi.PartitionType = ppeParEntry->SystemFlag; *pnError = ERR_PARMAN_PARAM; //stat logical drive numbers // nLogicalNumber = 0; // for( nIndex = 4 ; nIndex < DriveLayout.dli.PartitionCount ; nIndex +=4 ) // { // if ( GetPartitionType( &DriveLayout,nIndex) != DISKMAN_PAR_UNUSED ) // nLogicalNumber++; // } //detect if exist extend partition bExistExtend = FALSE; for( nIndex = 0 ; nIndex < 4 ; nIndex++ ) { if ( GetPartitionType( &DriveLayout,nIndex) == DISKMAN_PAR_EXTENDED_MBR ) { bExistExtend = TRUE; memcpy(&piExtend,&DriveLayout.dli.PartitionEntry[nIndex], sizeof(PARTITION_INFORMATION)); lnExtendStart.QuadPart = piExtend.StartingOffset.QuadPart; lnExtendEnd.QuadPart = piExtend.PartitionLength.QuadPart; lnExtendEnd.QuadPart += lnExtendStart.QuadPart - 1; break; } } //do alignment if ( dwFlag == LOGICAL ) { LegalizePartition(&pi,&dg,DISKMAN_PAR_LOGICAL_EMBR); }else LegalizePartition(&pi,&dg,DISKMAN_PAR_PRIMARY_MBR); //create partition bNeedResize = FALSE; bResizeSuccess = TRUE; if( dwFlag == LOGICAL ) { if( bExistExtend ) { //beyond the extend low boundary if( pi.StartingOffset.QuadPart < lnExtendStart.QuadPart ) { //justify the extend head piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart; piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart - piExtend.StartingOffset.QuadPart + 1; bNeedResize = TRUE; } //beyond the extend high boundary if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart > lnExtendEnd.QuadPart + 1 ) { //justify the extend end //piExtend.StartingOffset has modified; piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart - piExtend.StartingOffset.QuadPart; bNeedResize = TRUE; } //if there existing only one logical drive is required to //move to the free space acrross a primary partition, parman //should move the extend with the logical // if( nLogicalNumber == 1 ) // { // if( pi.StartingOffset.QuadPart // < // lnExtendStart.QuadPart ) // // if( pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart // > // lnExtendEnd.QuadPart + 1 ) // } if ( bNeedResize ) { nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); bResizeSuccess = ! nErrorCode; } //resize success create logical if( bResizeSuccess ) nErrorCode = CreateLogical(&DriveLayout,&pi,&dg); }else { //no extend partition, should create one //Backup partition type; btPartitionType = pi.PartitionType; pi.PartitionType = PARTITION_EXTENDED; nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg); if( !nErrorCode ) { pi.PartitionType = btPartitionType; nErrorCode = CreateLogical(&DriveLayout,&pi,&dg); } } }else { // if primary overlap the extend then resize extend partition if( bExistExtend ) { if( IsOverlap(&piExtend,&pi) ) { //try to resize extend partition forward piExtend.PartitionLength.QuadPart = pi.StartingOffset.QuadPart - lnExtendStart.QuadPart; //if length < 0 then length = 0 if( piExtend.PartitionLength.QuadPart < 0 ) piExtend.PartitionLength.QuadPart = 0; //resize forward nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); if( nErrorCode != 0 ) { //try to resize backward piExtend.StartingOffset.QuadPart = pi.StartingOffset.QuadPart + pi.PartitionLength.QuadPart; piExtend.PartitionLength.QuadPart = lnExtendEnd.QuadPart - piExtend.StartingOffset.QuadPart + 1; nErrorCode = ResizePrimary(&DriveLayout,&piExtend,&dg,nIndex); bResizeSuccess = ! nErrorCode; } } } if( bResizeSuccess ) nErrorCode = CreatePrimary(&DriveLayout,&pi,&dg); } //create success, write back if( !nErrorCode ) nErrorCode = SetDriveLayout(btHardDisk,&DriveLayout); //format partition if(( blIsFormat )&&( !nErrorCode )) { for( nIndex = 0; nIndex < 100 ; nIndex++ ) { Sleep(500); chDriveLetter = RetrieveDriveLttr(btHardDisk, dwFlag, (DWORD) (pi.StartingOffset.QuadPart / dg.BytesPerSector)); if( (BYTE)chDriveLetter != 0xff ) { chDriveLetter += 0x40; break; } } if ( chDriveLetter >= 'A' && chDriveLetter <= 'Z' ) { memcpy(szLabel,pLabel,11); szLabel[11] = '\0'; //if no name if( !memcmp(szLabel,"NO NAME",7)) szLabel[0] = '\0'; switch( pi.PartitionType & 0x0f) { case 0x01://fat12 FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd); break; case 0x04://fat16(old) case 0x06://fat16(big dos) case 0x0e://fat16(eint13) case 0x0f://fat16(int13) FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_16,hWnd) ||(nErrorCode=ERR_PARMAN_FORMATDRIVE); break; case 0x07://ntfs FormatDrive(chDriveLetter, szLabel,FORMAT_NTFS,hWnd) ||(nErrorCode=ERR_PARMAN_FORMATDRIVE); break; case 0x0b://fat32(int13) case 0x0c://fat32(eint13) FormatDrive(chDriveLetter, szLabel,FORMAT_FAT_32,hWnd) ||(nErrorCode=ERR_PARMAN_FORMATDRIVE); break; default: //unknow type break; } } } *pnError = nErrorCode; return !nErrorCode; }
BOOL DLL_EXPORT DeletePartition(DWORD dwStartSector, BYTE btHardDisk, CREATE_PAR_FLAG flags, PINT pnError) { int nErrorCode; int nIndex; LARGE_INTEGER lnStartByte; DISK_GEOMETRY dg; DRIVE_LAYOUT DriveLayout; BIOS_DRIVE_PARAM bdp; //standard mbr BYTE stdMBR[512] = {0x33,0xc0,0x8e,0xd0,0xbc,0x0 ,0x7c,0xfb,0x50,0x7 , 0x50,0x1f,0xfc,0xbe,0x1b,0x7c,0xbf,0x1b,0x6 ,0x50, 0x57,0xb9,0xe5,0x1 ,0xf3,0xa4,0xcb,0xbe,0xbe,0x7 , 0xb1,0x4 ,0x38,0x2c,0x7c,0x9 ,0x75,0x15,0x83,0xc6, 0x10,0xe2,0xf5,0xcd,0x18,0x8b,0x14,0x8b,0xee,0x83, 0xc6,0x10,0x49,0x74,0x16,0x38,0x2c,0x74,0xf6,0xbe, 0x10,0x7 ,0x4e,0xac,0x3c,0x0 ,0x74,0xfa,0xbb,0x7 , 0x0 ,0xb4,0xe ,0xcd,0x10,0xeb,0xf2,0x89,0x46,0x25, 0x96,0x8a,0x46,0x4 ,0xb4,0x6 ,0x3c,0xe ,0x74,0x11, 0xb4,0xb ,0x3c,0xc ,0x74,0x5 ,0x3a,0xc4,0x75,0x2b, 0x40,0xc6,0x46,0x25,0x6 ,0x75,0x24,0xbb,0xaa,0x55, 0x50,0xb4,0x41,0xcd,0x13,0x58,0x72,0x16,0x81,0xfb, 0x55,0xaa,0x75,0x10,0xf6,0xc1,0x1 ,0x74,0xb ,0x8a, 0xe0,0x88,0x56,0x24,0xc7,0x6 ,0xa1,0x6 ,0xeb,0x1e, 0x88,0x66,0x4 ,0xbf,0xa ,0x0 ,0xb8,0x1 ,0x2 ,0x8b, 0xdc,0x33,0xc9,0x83,0xff,0x5 ,0x7f,0x3 ,0x8b,0x4e, 0x25,0x3 ,0x4e,0x2 ,0xcd,0x13,0x72,0x29,0xbe,0x46, 0x7 ,0x81,0x3e,0xfe,0x7d,0x55,0xaa,0x74,0x5a,0x83, 0xef,0x5 ,0x7f,0xda,0x85,0xf6,0x75,0x83,0xbe,0x27, 0x7 ,0xeb,0x8a,0x98,0x91,0x52,0x99,0x3 ,0x46,0x8 , 0x13,0x56,0xa ,0xe8,0x12,0x0 ,0x5a,0xeb,0xd5,0x4f, 0x74,0xe4,0x33,0xc0,0xcd,0x13,0xeb,0xb8,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x56,0x33,0xf6,0x56,0x56,0x52, 0x50,0x6 ,0x53,0x51,0xbe,0x10,0x0 ,0x56,0x8b,0xf4, 0x50,0x52,0xb8,0x0 ,0x42,0x8a,0x56,0x24,0xcd,0x13, 0x5a,0x58,0x8d,0x64,0x10,0x72,0xa ,0x40,0x75,0x1 , 0x42,0x80,0xc7,0x2 ,0xe2,0xf7,0xf8,0x5e,0xc3,0xeb, 0x74,0x49,0x6e,0x76,0x61,0x6c,0x69,0x64,0x20,0x70, 0x61,0x72,0x74,0x69,0x74,0x69,0x6f,0x6e,0x20,0x74, 0x61,0x62,0x6c,0x65,0x0 ,0x45,0x72,0x72,0x6f,0x72, 0x20,0x6c,0x6f,0x61,0x64,0x69,0x6e,0x67,0x20,0x6f, 0x70,0x65,0x72,0x61,0x74,0x69,0x6e,0x67,0x20,0x73, 0x79,0x73,0x74,0x65,0x6d,0x0 ,0x4d,0x69,0x73,0x73, 0x69,0x6e,0x67,0x20,0x6f,0x70,0x65,0x72,0x61,0x74, 0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d, 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x8b,0xfc,0x1e, 0x57,0x8b,0xf5,0xcb,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 , 0x55,0xaa}; btHardDisk &= 0x7f; //Get disk geometry and layout information *pnError = nErrorCode = ERR_PARMAN_PARAM; // 102 indicate false if ( GetDiskGeometry(btHardDisk,&dg)) return FALSE; if ( GetDriveLayout(btHardDisk, &DriveLayout)) return FALSE; //found the partition lnStartByte.QuadPart = (__int64)dg.BytesPerSector * dwStartSector; for( nIndex = DriveLayout.dli.PartitionCount -1 ; nIndex >=0 ; nIndex-- ) { if(DriveLayout.dli.PartitionEntry[nIndex].StartingOffset.QuadPart == lnStartByte.QuadPart) break; } //usb disk if((DriveLayout.dli.PartitionCount == 1)&&(nIndex == 0)) { GetDriveParam(btHardDisk,&bdp); WriteSector(6,1,stdMBR,btHardDisk,&bdp); return WriteSector(0,1,stdMBR,btHardDisk,&bdp); } //if found do delete if(nIndex >= 0) { switch( GetPartitionType(&DriveLayout, nIndex) ) { case DISKMAN_PAR_UNUSED: nErrorCode = ERR_PARMAN_PARAM; break; case DISKMAN_PAR_EXTENDED_MBR: if ( flags.Extended ) { //delete first logical if( DeleteLogical(&DriveLayout,4) ) nErrorCode = ERR_PARMAN_PARAM; else nErrorCode = 0; break; }//else consider as primary case DISKMAN_PAR_PRIMARY_MBR: if( DeletePrimary(&DriveLayout,nIndex) ) nErrorCode = ERR_PARMAN_PARAM; else nErrorCode = 0; break; case DISKMAN_PAR_EXTENDED_EMBR: nIndex +=3; case DISKMAN_PAR_LOGICAL_EMBR: if( DeleteLogical(&DriveLayout,nIndex) ) nErrorCode = ERR_PARMAN_PARAM; else nErrorCode = 0; break; } //if success, nErrorCode == 0 //write the layout information back if( !nErrorCode ) nErrorCode = SetDriveLayout(btHardDisk, &DriveLayout); } *pnError = nErrorCode; // nErrorCode == 0, return TRUE; return !nErrorCode; }
/* * Fill the drive properties (size, FS, etc) */ int GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize) { BOOL r, hasRufusExtra = FALSE; HANDLE hPhysical; DWORD size; BYTE geometry[256], layout[4096], part_type; PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)(void*)geometry; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)(void*)layout; char* volume_name; char tmp[256]; DWORD i, nb_partitions = 0; // Populate the filesystem data FileSystemName[0] = 0; volume_name = GetLogicalName(DriveIndex, TRUE, FALSE); if ((volume_name == NULL) || (!GetVolumeInformationA(volume_name, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize))) { uprintf("No volume information for disk 0x%02x\n", DriveIndex); } safe_free(volume_name); hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE); if (hPhysical == INVALID_HANDLE_VALUE) return 0; r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, geometry, sizeof(geometry), &size, NULL); if (!r || size <= 0) { uprintf("Could not get geometry for drive 0x%02x: %s\n", DriveIndex, WindowsErrorString()); safe_closehandle(hPhysical); return 0; } SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); uprintf("Disk type: %s, Sector Size: %d bytes\n", (DiskGeometry->Geometry.MediaType == FixedMedia)?"Fixed":"Removable", DiskGeometry->Geometry.BytesPerSector); uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n", DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack); r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, layout, sizeof(layout), &size, NULL ); if (!r || size <= 0) { uprintf("Could not get layout for drive 0x%02x: %s\n", DriveIndex, WindowsErrorString()); safe_closehandle(hPhysical); return 0; } switch (DriveLayout->PartitionStyle) { case PARTITION_STYLE_MBR: SelectedDrive.PartitionType = PARTITION_STYLE_MBR; for (i=0; i<DriveLayout->PartitionCount; i++) { if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { nb_partitions++; } } uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions); SelectedDrive.has_mbr_uefi_marker = (DriveLayout->Mbr.Signature == MBR_UEFI_MARKER); uprintf("Disk ID: 0x%08X %s\n", DriveLayout->Mbr.Signature, SelectedDrive.has_mbr_uefi_marker?"(UEFI target)":""); AnalyzeMBR(hPhysical, "Drive"); for (i=0; i<DriveLayout->PartitionCount; i++) { if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { uprintf("Partition %d:\n", i+1); part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType; uprintf(" Type: %s (0x%02x)\r\n Size: %s (%lld bytes)\r\n Start Sector: %d, Boot: %s, Recognized: %s\n", ((part_type==0x07)&&(FileSystemName[0]!=0))?FileSystemName:GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors, DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No", DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No"); if (part_type == RUFUS_EXTRA_PARTITION_TYPE) // This is a partition Rufus created => we can safely ignore it hasRufusExtra = TRUE; if (part_type == 0xee) // Flag a protective MBR for non GPT platforms (XP) SelectedDrive.has_protective_mbr = TRUE; } } break; case PARTITION_STYLE_GPT: SelectedDrive.PartitionType = PARTITION_STYLE_GPT; uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount); uprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId)); uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n", DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart); for (i=0; i<DriveLayout->PartitionCount; i++) { nb_partitions++; tmp[0] = 0; wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp)); uprintf("Partition %d:\r\n Type: %s\r\n Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber, GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp); uprintf(" ID: %s\r\n Size: %s (%lld bytes)\r\n Start Sector: %lld, Attributes: 0x%016llX\n", GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE), DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector, DriveLayout->PartitionEntry[i].Gpt.Attributes); } break; default: SelectedDrive.PartitionType = PARTITION_STYLE_MBR; uprintf("Partition type: RAW\n"); break; } safe_closehandle(hPhysical); if (hasRufusExtra) nb_partitions--; return (int)nb_partitions; }