示例#1
0
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;
}
示例#2
0
/*
 * 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;
}
示例#3
0
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 );
}
示例#4
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;
}
示例#5
0
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;
}
示例#6
0
文件: drive.c 项目: Cheesebaron/rufus
/*
 * 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;
}