mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[togo] Add Windows To Go support - part 2
* Closes #126 * Only supported on Windows 8 or later for now * Also fix MinGW and WDK compilation issues
This commit is contained in:
		
							parent
							
								
									295650a8b4
								
							
						
					
					
						commit
						032d4413c8
					
				
					 17 changed files with 251 additions and 70 deletions
				
			
		|  | @ -259,9 +259,16 @@ t MSG_093 "IMPORTANT: THIS DRIVE CONTAINS MULTIPLE PARTITIONS!!\n\n" | |||
| 	"Should you wish to proceed, you are responsible for any data loss on these partitions." | ||||
| t MSG_094 "Multiple partitions detected" | ||||
| t MSG_095 "DD Image" | ||||
| t MSG_096 "Only FAT/FAT32 is supported for this type of ISO. Please select FAT/FAT32 as the File system." | ||||
| t MSG_097 "Only 'bootmgr' or 'WinPE' based ISO images can currently be used with NTFS." | ||||
| t MSG_098 "FAT/FAT32 can only be used for isolinux based ISO images or when the Target Type is UEFI." | ||||
| t MSG_096 "The file system currently selected can not be used with this type of ISO. " | ||||
| 	"Please select a different file system or use a different ISO." | ||||
| t MSG_097 "'Windows To Go' can only be applied if the file system is NTFS." | ||||
| t MSG_098 "IMPORTANT: You are trying to install 'Windows To Go', but your USB drive doesn't " | ||||
| 	"have the 'FIXED' attribute. Because of this Windows will most likely freeze during boot, " | ||||
| 	"as Microsoft hasn't designed it to work with drives that are 'REMOVABLE'.\n\n" | ||||
| 	"Do you still want to proceed?\n\n" | ||||
| 	"Note: the 'FIXED/REMOVABLE' attribute is a hardware property that can only be changed " | ||||
| 	"using custom tools from the drive manufacturer. However those tools are ALMOST NEVER " | ||||
| 	"provided to the public..." | ||||
| t MSG_099 "Filesystem limitation" | ||||
| t MSG_100 "This ISO image contains a file larger than 4GB, which is more than the " | ||||
| 	"maximum size allowed for a FAT or FAT32 file system." | ||||
|  | @ -364,6 +371,7 @@ t MSG_186 "Rufus does not install or run background services, therefore update c | |||
| t MSG_187 "Invalid image for selected boot option" | ||||
| t MSG_188 "The current image doesn't match the boot option selected. Please use a different image or choose a different boot option." | ||||
| t MSG_189 "This ISO image is not compatible with the selected filesystem" | ||||
| t MSG_190 "Incompatible drive detected" | ||||
| t MSG_191 "Write pass" | ||||
| t MSG_192 "Read pass" | ||||
| t MSG_193 "Downloaded %s" | ||||
|  |  | |||
							
								
								
									
										11
									
								
								res/togo/san_policy.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								res/togo/san_policy.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| <?xml version='1.0' encoding='utf-8' standalone='yes'?> | ||||
| <unattend xmlns="urn:schemas-microsoft-com:unattend"> | ||||
| 	<settings pass="offlineServicing"> | ||||
| 		<component name="Microsoft-Windows-PartitionManager" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
| 			<SanPolicy>4</SanPolicy> | ||||
| 		</component> | ||||
| 		<component name="Microsoft-Windows-PartitionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
| 			<SanPolicy>4</SanPolicy> | ||||
| 		</component> | ||||
| 	</settings> | ||||
| </unattend> | ||||
							
								
								
									
										11
									
								
								res/togo/unattend.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								res/togo/unattend.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <unattend xmlns="urn:schemas-microsoft-com:unattend"> | ||||
| 	<settings pass="oobeSystem"> | ||||
| 		<component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
| 			<UninstallWindowsRE>true</UninstallWindowsRE> | ||||
| 		</component> | ||||
| 		<component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
| 			<UninstallWindowsRE>true</UninstallWindowsRE> | ||||
| 		</component> | ||||
| 	</settings> | ||||
| </unattend> | ||||
|  | @ -223,7 +223,6 @@ | |||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <None Include="..\..\res\down.ico" /> | ||||
|     <None Include="..\..\res\localization\rufus.loc" /> | ||||
|     <None Include="..\..\res\rufus.ico" /> | ||||
|     <None Include="..\..\res\up.ico" /> | ||||
|   </ItemGroup> | ||||
|  |  | |||
|  | @ -139,9 +139,6 @@ | |||
|     <None Include="..\..\res\down.ico"> | ||||
|       <Filter>Resource Files</Filter> | ||||
|     </None> | ||||
|     <None Include="..\..\res\localization\rufus.loc"> | ||||
|       <Filter>Resource Files</Filter> | ||||
|     </None> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Manifest Include="..\common_controls_and_elevation.manifest"> | ||||
|  |  | |||
|  | @ -187,6 +187,11 @@ static inline ssize_t full_read(int fd, void *buf, size_t count) { | |||
| 	return rb; | ||||
| } | ||||
| 
 | ||||
| static inline struct tm *localtime_r(const time_t *timep, struct tm *result) { | ||||
| 	result = localtime(timep); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| #define full_write _write | ||||
| #define safe_read full_read | ||||
| #define lstat stat | ||||
|  | @ -197,11 +202,6 @@ static inline ssize_t full_read(int fd, void *buf, size_t count) { | |||
| #define mkdir(x, y) _mkdirU(x) | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
| static inline struct tm *localtime_r(const time_t *timep, struct tm *result) { | ||||
| 	result = localtime(timep); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| #define _S_IFBLK 0x3000 | ||||
| 
 | ||||
| #define S_IFMT   _S_IFMT | ||||
|  |  | |||
|  | @ -751,7 +751,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys | |||
| 			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", DriveLayout->PartitionEntry[i].PartitionNumber, | ||||
| 			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 (%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), | ||||
|  |  | |||
							
								
								
									
										109
									
								
								src/format.c
									
										
									
									
									
								
							
							
						
						
									
										109
									
								
								src/format.c
									
										
									
									
									
								
							|  | @ -1225,6 +1225,79 @@ out: | |||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| // http://technet.microsoft.com/en-ie/library/jj721578.aspx
 | ||||
| static BOOL SetupWinToGo(const char* drive_name) | ||||
| { | ||||
| 	char san_policy_path[] = "?:\\san_policy.xml", unattend_path[] = "?:\\Windows\\System32\\sysprep\\unattend.xml"; | ||||
| 	char *mounted_iso, image[128], cmd[128]; | ||||
| 	unsigned char *buffer; | ||||
| 	DWORD bufsize; | ||||
| 	FILE* fd; | ||||
| 
 | ||||
| 	uprintf("Windows To Go mode selected"); | ||||
| 
 | ||||
| 	// First, we need to access the install.wim image, that resides on the ISO
 | ||||
| 	mounted_iso = MountISO(image_path); | ||||
| 	if (mounted_iso == NULL) { | ||||
| 		uprintf("Could not mount ISO for Windows To Go installation"); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	uprintf("Mounted ISO as '%s'", mounted_iso); | ||||
| 
 | ||||
| 	// Now we use the WIM API to apply that image
 | ||||
| 	static_sprintf(image, "%s\\sources\\install.wim", mounted_iso); | ||||
| 	if (!WimApplyImage(image, 1, drive_name)) { | ||||
| 		uprintf("Failed to apply Windows To Go image"); | ||||
| 		if (!IS_ERROR(FormatStatus)) | ||||
| 			FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 		UnMountISO(); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	UnMountISO(); | ||||
| 
 | ||||
| 	uprintf("Setting up boot for Windows To Go..."); | ||||
| 	static_sprintf(cmd, "%C:\\Windows\\System32\\bcdboot.exe %C:\\Windows /f ALL /s %C:", | ||||
| 		drive_name[0], drive_name[0], drive_name[0]); | ||||
| 	if (RunCommand(cmd, NULL, TRUE) != 0) { | ||||
| 		// Fatal, as the UFD is unlikely to boot then
 | ||||
| 		uprintf("Command '%s' failed to run", cmd); | ||||
| 		FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 		return FALSE; | ||||
| 	} | ||||
| 	UpdateProgress(OP_DOS, 99.0f); | ||||
| 
 | ||||
| 	// The following are non fatal if they fail
 | ||||
| 	buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_TOGO_SAN_POLICY_XML), | ||||
| 		_RT_RCDATA, "san_policy.xml", &bufsize, FALSE); | ||||
| 	san_policy_path[0] = drive_name[0]; | ||||
| 	uprintf("Applying san_policy.xml..."); | ||||
| 	fd = fopenU(san_policy_path, "wb"); | ||||
| 	if ((fd == NULL) || (fwrite(buffer, 1, bufsize, fd) != bufsize)) { | ||||
| 		uprintf("Could not write '%s'\n", san_policy_path); | ||||
| 		if (fd) | ||||
| 			fclose(fd); | ||||
| 	} else { | ||||
| 		fclose(fd); | ||||
| 		static_sprintf(cmd, "dism /Image:%C:\\ /Apply-Unattend:%s", drive_name[0], san_policy_path); | ||||
| 		if (RunCommand(cmd, NULL, TRUE) != 0) | ||||
| 			uprintf("Command '%s' failed to run"); | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("Copying 'unattend.xml'"); | ||||
| 	buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDR_TOGO_UNATTEND_XML), | ||||
| 		_RT_RCDATA, "unattend.xml", &bufsize, FALSE); | ||||
| 	unattend_path[0] = drive_name[0]; | ||||
| 	fd = fopenU(unattend_path, "wb"); | ||||
| 	if ((fd == NULL) || (fwrite(buffer, 1, bufsize, fd) != bufsize)) { | ||||
| 		uprintf("Could not write '%s'\n", unattend_path); | ||||
| 	} | ||||
| 	fclose(fd); | ||||
| 	UpdateProgress(OP_DOS, 100.0f); | ||||
| 
 | ||||
| 	return TRUE; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Detect if a Windows Format prompt is active, by enumerating the | ||||
|  * whole Windows tree and looking for the relevant popup | ||||
|  | @ -1305,10 +1378,10 @@ DWORD WINAPI FormatThread(void* param) | |||
| 	LARGE_INTEGER li; | ||||
| 	uint64_t wb; | ||||
| 	uint8_t *buffer = NULL, *aligned_buffer; | ||||
| 	char *bb_msg, *guid_volume = NULL, *mounted_iso; | ||||
| 	char *bb_msg, *guid_volume = NULL; | ||||
| 	char drive_name[] = "?:\\"; | ||||
| 	char drive_letters[27]; | ||||
| 	char logfile[MAX_PATH], image[128], *userdir; | ||||
| 	char logfile[MAX_PATH], *userdir; | ||||
| 	char wim_image[] = "?:\\sources\\install.wim"; | ||||
| 	char efi_dst[] = "?:\\efi\\boot\\bootx64.efi"; | ||||
| 	char kolibri_dst[] = "?:\\MTLD_F32"; | ||||
|  | @ -1693,28 +1766,24 @@ DWORD WINAPI FormatThread(void* param) | |||
| 				UpdateProgress(OP_DOS, 0.0f); | ||||
| 				PrintInfoDebug(0, MSG_231); | ||||
| 				drive_name[2] = 0; | ||||
| 				// TODO: Check that we have apply-wim support
 | ||||
| 				if (HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED)) { | ||||
| 					uprintf("Windows To Go mode selected"); | ||||
| 					mounted_iso = MountISO(image_path); | ||||
| 					if (mounted_iso == NULL) { | ||||
| 						uprintf("Could not mount ISO for Windows To Go installation"); | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 					} else { | ||||
| 						uprintf("Mounted ISO as '%s'", mounted_iso); | ||||
| 						static_sprintf(image, "%s\\sources\\install.wim", mounted_iso); | ||||
| 						if (!WimApplyImage(image, 1, drive_name)) { | ||||
| 							uprintf("Failed to setup Windows To Go"); | ||||
| 							if (!IS_ERROR(FormatStatus)) | ||||
| 								FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_EXTRACT); | ||||
| 						} | ||||
| 						UnMountISO(); | ||||
| 					} | ||||
| 					if (IS_ERROR(FormatStatus)) | ||||
| 					// Sanity checks
 | ||||
| 					if (fs != FS_NTFS) { | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS); | ||||
| 						goto out; | ||||
| 					} | ||||
| 					if ((nWindowsVersion < WINDOWS_8) || ((WimExtractCheck() & 4) == 0)) { | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_NOT_SUPPORTED; | ||||
| 						goto out; | ||||
| 					} | ||||
| 					if (!SetupWinToGo(drive_name)) { | ||||
| 						if (!IS_ERROR(FormatStatus)) | ||||
| 							FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ISO_EXTRACT; | ||||
| 						goto out; | ||||
| 					} | ||||
| 				} else if (!ExtractISO(image_path, drive_name, FALSE)) { | ||||
| 					if (!IS_ERROR(FormatStatus)) | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANNOT_COPY; | ||||
| 						FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_ISO_EXTRACT; | ||||
| 					goto out; | ||||
| 				} | ||||
| 				if (iso_report.has_kolibrios) { | ||||
|  |  | |||
|  | @ -925,8 +925,8 @@ out: | |||
| /*
 | ||||
|  * The following is used for native ISO mounting in Windows 8 or later | ||||
|  */ | ||||
| const GUID VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT = | ||||
| 	{ 0xEC984AECL, 0xA0F9, 0x47e9, { 0x90, 0x1F, 0x71, 0x41, 0x5A, 0x66, 0x34, 0x5B } }; | ||||
| #define VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT \ | ||||
| 	{ 0xEC984AECL, 0xA0F9, 0x47e9, { 0x90, 0x1F, 0x71, 0x41, 0x5A, 0x66, 0x34, 0x5B } } | ||||
| 
 | ||||
| typedef enum _VIRTUAL_DISK_ACCESS_MASK { | ||||
| 	VIRTUAL_DISK_ACCESS_NONE = 0x00000000, | ||||
|  | @ -1015,7 +1015,7 @@ static HANDLE mounted_handle = INVALID_HANDLE_VALUE; | |||
| char* MountISO(const char* path) | ||||
| { | ||||
| 	VIRTUAL_STORAGE_TYPE vtype = { 1, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT }; | ||||
| 	ATTACH_VIRTUAL_DISK_PARAMETERS vparams = { ATTACH_VIRTUAL_DISK_VERSION_1, 0 }; | ||||
| 	ATTACH_VIRTUAL_DISK_PARAMETERS vparams = {0}; | ||||
| 	DWORD r; | ||||
| 	wchar_t wtmp[128]; | ||||
| 	ULONG size = ARRAYSIZE(wtmp); | ||||
|  | @ -1037,6 +1037,7 @@ char* MountISO(const char* path) | |||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	vparams.Version = ATTACH_VIRTUAL_DISK_VERSION_1; | ||||
| 	r = pfAttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | | ||||
| 		ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, &vparams, NULL); | ||||
| 	if (r != ERROR_SUCCESS) { | ||||
|  |  | |||
|  | @ -407,11 +407,11 @@ char* lmprintf(int msg_id, ...) | |||
| #define MSG_INFO     1 | ||||
| #define MSG_LOW_PRI  0 | ||||
| #define MSG_HIGH_PRI 1 | ||||
| char szMessage[2][2][MSG_LEN] = { 0 }; | ||||
| char szMessage[2][2][MSG_LEN] = { {"", ""}, {"", ""} }; | ||||
| char* szStatusMessage = szMessage[MSG_STATUS][MSG_HIGH_PRI]; | ||||
| static BOOL bStatusTimerArmed = FALSE; | ||||
| 
 | ||||
| static __inline OutputMessage(BOOL info, char* msg) | ||||
| static void __inline OutputMessage(BOOL info, char* msg) | ||||
| { | ||||
| 	if (info) | ||||
| 		SetWindowTextU(hInfo, msg); | ||||
|  |  | |||
|  | @ -506,9 +506,9 @@ static __inline int SHDeleteDirectoryExU(HWND hwnd, const char* pszPath, FILEOP_ | |||
| 	// which is always expected to be larger than our UTF-16 one, and add 2 chars for good measure.
 | ||||
| 	size_t wpszPath_len = strlen(pszPath) + 2; | ||||
| 	wchar_t* wpszPath = (wchar_t*)calloc(wpszPath_len, sizeof(wchar_t)); | ||||
| 	SHFILEOPSTRUCTW shfo = { hwnd, FO_DELETE, wpszPath, NULL, fFlags, FALSE, NULL, NULL }; | ||||
| 	utf8_to_wchar_no_alloc(pszPath, wpszPath, wpszPath_len); | ||||
| 	// FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION,
 | ||||
| 	SHFILEOPSTRUCTW shfo = { hwnd, FO_DELETE, wpszPath, NULL, fFlags, FALSE, NULL, NULL }; | ||||
| 	ret = SHFileOperationW(&shfo); | ||||
| 	wfree(pszPath); | ||||
| 	return ret; | ||||
|  |  | |||
|  | @ -70,6 +70,8 @@ | |||
| #define IDR_LC_RUFUS_LOC                500 | ||||
| #define IDR_XT_HOGGER                   501 | ||||
| #define IDR_UEFI_TOGO                   502 | ||||
| #define IDR_TOGO_SAN_POLICY_XML         503 | ||||
| #define IDR_TOGO_UNATTEND_XML           504 | ||||
| #define IDC_DEVICE                      1001 | ||||
| #define IDC_FILESYSTEM                  1002 | ||||
| #define IDC_START                       1003 | ||||
|  | @ -411,7 +413,7 @@ | |||
| #ifdef APSTUDIO_INVOKED | ||||
| #ifndef APSTUDIO_READONLY_SYMBOLS | ||||
| #define _APS_NO_MFC                     1 | ||||
| #define _APS_NEXT_RESOURCE_VALUE        502 | ||||
| #define _APS_NEXT_RESOURCE_VALUE        505 | ||||
| #define _APS_NEXT_COMMAND_VALUE         40001 | ||||
| #define _APS_NEXT_CONTROL_VALUE         1071 | ||||
| #define _APS_NEXT_SYMED_VALUE           4000 | ||||
|  |  | |||
							
								
								
									
										42
									
								
								src/rufus.c
									
										
									
									
									
								
							
							
						
						
									
										42
									
								
								src/rufus.c
									
										
									
									
									
								
							|  | @ -933,6 +933,9 @@ static void DisplayISOProps(void) | |||
| 	uprintf("  Uses ReactOS: %s", YesNo(IS_REACTOS(iso_report))); | ||||
| 	uprintf("  Uses WinPE: %s%s", YesNo(IS_WINPE(iso_report.winpe)), (iso_report.uses_minint) ? " (with /minint)" : ""); | ||||
| 
 | ||||
| 	// We don't support ToGo on Windows 7 or earlier, for lack of ISO mount capabilities
 | ||||
| 	// TODO: add install.wim extraction workaround for Windows 7
 | ||||
| 	if (nWindowsVersion >= WINDOWS_8) | ||||
| 		if ( ((!togo_mode) && (HAS_TOGO(iso_report))) || ((togo_mode) && (!HAS_TOGO(iso_report))) ) | ||||
| 			ToggleToGo(); | ||||
| } | ||||
|  | @ -1186,7 +1189,18 @@ static BOOL BootCheck(void) | |||
| 		} | ||||
| 		fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); | ||||
| 		bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); | ||||
| 		if (bt == BT_UEFI) { | ||||
| 		if ((togo_mode) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED)) { | ||||
| 			if (fs != FS_NTFS) { | ||||
| 				// Windows To Go only works for NTFS
 | ||||
| 				MessageBoxU(hMainDialog, lmprintf(MSG_097), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
| 				return FALSE; | ||||
| 			} else if (SelectedDrive.Geometry.MediaType != FixedMedia) { | ||||
| 				// I never had any success with drives that have the REMOVABLE attribute set, no matter the
 | ||||
| 				// method or tool I tried. If you manage to get this working, I'd like to hear from you!
 | ||||
| 				if (MessageBoxU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_190), MB_YESNO|MB_ICONWARNING|MB_IS_RTL) != IDYES) | ||||
| 					return FALSE; | ||||
| 			} | ||||
| 		} else if (bt == BT_UEFI) { | ||||
| 			if (!iso_report.has_efi) { | ||||
| 				// Unsupported ISO
 | ||||
| 				MessageBoxU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
|  | @ -1198,24 +1212,16 @@ static BOOL BootCheck(void) | |||
| 					ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL); | ||||
| 				return FALSE; | ||||
| 			} | ||||
| 		} else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe)) && (!IS_GRUB(iso_report))) { | ||||
| 			if (HAS_SYSLINUX(iso_report)) { | ||||
| 				// Only FAT/FAT32 is supported for this type of ISO
 | ||||
| 		} else if ( ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe)) && (!IS_GRUB(iso_report))) | ||||
| 				 || (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!HAS_SYSLINUX(iso_report)) && (!allow_dual_uefi_bios) && | ||||
| 					 (!IS_REACTOS(iso_report)) && (!iso_report.has_kolibrios) && (!IS_GRUB(iso_report))) ) { | ||||
| 			// Incompatible FS and ISO
 | ||||
| 			MessageBoxU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
| 			} else { | ||||
| 				// Only 'bootmgr' or 'WinPE' based ISO images can currently be used with NTFS
 | ||||
| 				MessageBoxU(hMainDialog, lmprintf(MSG_097), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
| 			} | ||||
| 			return FALSE; | ||||
| 		} else if ((fs == FS_FAT16) && (iso_report.has_kolibrios)) { | ||||
| 			// KolibriOS doesn't support FAT16
 | ||||
| 			MessageBoxU(hMainDialog, lmprintf(MSG_189), lmprintf(MSG_099), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
| 			return FALSE; | ||||
| 		} else if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!HAS_SYSLINUX(iso_report)) && (!allow_dual_uefi_bios) && | ||||
| 			(!IS_REACTOS(iso_report)) && (!iso_report.has_kolibrios) && (!IS_GRUB(iso_report))) { | ||||
| 			// FAT/FAT32 can only be used for isolinux based ISO images or when the Target Type is UEFI
 | ||||
| 			MessageBoxU(hMainDialog, lmprintf(MSG_098), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL); | ||||
| 			return FALSE; | ||||
| 		} | ||||
| 		if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (iso_report.has_4GB_file)) { | ||||
| 			// This ISO image contains a file larger than 4GB file (FAT32)
 | ||||
|  | @ -2153,6 +2159,16 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA | |||
| 				FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); | ||||
| 			} | ||||
| 			break; | ||||
| 		case IDC_WINDOWS_TO_GO: | ||||
| 			if (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED) { | ||||
| 				for (i=0; i<ComboBox_GetCount(hFileSystem); i++) { | ||||
| 					if (ComboBox_GetItemData(hFileSystem, i) == FS_NTFS) { | ||||
| 						IGNORE_RETVAL(ComboBox_SetCurSel(hFileSystem, i)); | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		case IDC_RUFUS_MBR: | ||||
| 			if ((HIWORD(wParam)) == BN_CLICKED) | ||||
| 				mbr_selected_by_user = IsChecked(IDC_RUFUS_MBR); | ||||
|  |  | |||
|  | @ -395,6 +395,7 @@ extern char* FileDialog(BOOL save, char* path, const ext_t* ext, DWORD options); | |||
| extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size); | ||||
| extern unsigned char* GetResource(HMODULE module, char* name, char* type, const char* desc, DWORD* len, BOOL duplicate); | ||||
| extern DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc); | ||||
| extern DWORD RunCommand(const char* cmdline, const char* dir, BOOL log); | ||||
| extern BOOL GetUSBDevices(DWORD devnum); | ||||
| extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue); | ||||
| extern LONG GetEntryWidth(HWND hDropDown, const char* entry); | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | |||
| 
 | ||||
| IDD_DIALOG DIALOGEX 12, 12, 242, 376 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| CAPTION "Rufus 2.0.0.574" | ||||
| CAPTION "Rufus 2.0.0.575" | ||||
| FONT 8, "Segoe UI", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,127,339,50,14 | ||||
|  | @ -157,7 +157,7 @@ END | |||
| 
 | ||||
| IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| CAPTION "Rufus 2.0.0.574" | ||||
| CAPTION "Rufus 2.0.0.575" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,127,339,50,14 | ||||
|  | @ -283,7 +283,7 @@ END | |||
| IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | ||||
| CAPTION "Rufus 2.0.0.574" | ||||
| CAPTION "Rufus 2.0.0.575" | ||||
| FONT 8, "Segoe UI", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,127,339,50,14 | ||||
|  | @ -415,7 +415,7 @@ END | |||
| IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 | ||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||
| EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | ||||
| CAPTION "Rufus 2.0.0.574" | ||||
| CAPTION "Rufus 2.0.0.575" | ||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||
| BEGIN | ||||
|     DEFPUSHBUTTON   "Start",IDC_START,127,339,50,14 | ||||
|  | @ -612,6 +612,8 @@ BEGIN | |||
|     "IDR_FD_EGA18_CPX        RCDATA                  ""../res/freedos/ega18.cpx""\r\n" | ||||
|     "IDR_XT_HOGGER           RCDATA                  ""../res/hogger/hogger.exe""\r\n" | ||||
|     "IDR_UEFI_TOGO           RCDATA                  ""../res/uefi/uefi-togo.img""\r\n" | ||||
|     "IDR_TOGO_SAN_POLICY_XML RCDATA                  ""../res/togo/san_policy.xml""\r\n" | ||||
|     "IDR_TOGO_UNATTEND_XML   RCDATA                  ""../res/togo/unattend.xml""\r\n" | ||||
|     "\r\n" | ||||
|     "// Must reference a manifest for visual styles and elevation\r\n" | ||||
|     "// Oh, and it must happen at the end, or MinGW will ignore it!\r\n" | ||||
|  | @ -669,8 +671,8 @@ END | |||
| // | ||||
| 
 | ||||
| VS_VERSION_INFO VERSIONINFO | ||||
|  FILEVERSION 2,0,0,574 | ||||
|  PRODUCTVERSION 2,0,0,574 | ||||
|  FILEVERSION 2,0,0,575 | ||||
|  PRODUCTVERSION 2,0,0,575 | ||||
|  FILEFLAGSMASK 0x3fL | ||||
| #ifdef _DEBUG | ||||
|  FILEFLAGS 0x1L | ||||
|  | @ -687,13 +689,13 @@ BEGIN | |||
|         BEGIN | ||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||
|             VALUE "FileDescription", "Rufus" | ||||
|             VALUE "FileVersion", "2.0.0.574" | ||||
|             VALUE "FileVersion", "2.0.0.575" | ||||
|             VALUE "InternalName", "Rufus" | ||||
|             VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" | ||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||
|             VALUE "OriginalFilename", "rufus.exe" | ||||
|             VALUE "ProductName", "Rufus" | ||||
|             VALUE "ProductVersion", "2.0.0.574" | ||||
|             VALUE "ProductVersion", "2.0.0.575" | ||||
|         END | ||||
|     END | ||||
|     BLOCK "VarFileInfo" | ||||
|  | @ -765,6 +767,8 @@ IDR_FD_EGA17_CPX        RCDATA                  "../res/freedos/ega17.cpx" | |||
| IDR_FD_EGA18_CPX        RCDATA                  "../res/freedos/ega18.cpx" | ||||
| IDR_XT_HOGGER           RCDATA                  "../res/hogger/hogger.exe" | ||||
| IDR_UEFI_TOGO           RCDATA                  "../res/uefi/uefi-togo.img" | ||||
| IDR_TOGO_SAN_POLICY_XML RCDATA                  "../res/togo/san_policy.xml" | ||||
| IDR_TOGO_UNATTEND_XML   RCDATA                  "../res/togo/unattend.xml" | ||||
| 
 | ||||
| // Must reference a manifest for visual styles and elevation | ||||
| // Oh, and it must happen at the end, or MinGW will ignore it! | ||||
|  |  | |||
							
								
								
									
										62
									
								
								src/stdfn.c
									
										
									
									
									
								
							
							
						
						
									
										62
									
								
								src/stdfn.c
									
										
									
									
									
								
							|  | @ -528,6 +528,68 @@ DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc) | |||
| 	return (GetResource(module, name, type, desc, &len, FALSE) == NULL)?0:len; | ||||
| } | ||||
| 
 | ||||
| // Run a console command, with optional redirection of stdout and stderr to our log
 | ||||
| DWORD RunCommand(const char* cmd, const char* dir, BOOL log) | ||||
| { | ||||
| 	DWORD ret, dwRead, dwAvail, dwMsg; | ||||
| 	STARTUPINFOA si = {0}; | ||||
| 	PROCESS_INFORMATION pi = {0}; | ||||
| 	HANDLE hOutputRead = INVALID_HANDLE_VALUE, hOutputWrite = INVALID_HANDLE_VALUE; | ||||
| 	HANDLE hDupOutputWrite = INVALID_HANDLE_VALUE; | ||||
| 	char output[1024]; | ||||
| 
 | ||||
| 	si.cb = sizeof(si); | ||||
| 	if (log) { | ||||
| 		if (!CreatePipe(&hOutputRead, &hOutputWrite, NULL, sizeof(output)-1)) { | ||||
| 			ret = GetLastError(); | ||||
| 			uprintf("Could not set commandline pipe: %s", WindowsErrorString()); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		// We need an inheritable pipe endpoint handle
 | ||||
| 		DuplicateHandle(GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hDupOutputWrite,  | ||||
| 			0L, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); | ||||
| 		si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; | ||||
| 		si.wShowWindow = SW_HIDE; | ||||
| 		si.hStdOutput = hDupOutputWrite; | ||||
| 		si.hStdError = hDupOutputWrite; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!CreateProcessU(NULL, cmd, NULL, NULL, TRUE, | ||||
| 		NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, dir, &si, &pi)) { | ||||
| 		ret = GetLastError(); | ||||
| 		uprintf("Unable to launch command '%s': %s", WindowsErrorString()); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (log) { | ||||
| 		while (1) { | ||||
| 			if (PeekNamedPipe(hOutputRead, output, sizeof(output)-1, &dwRead, &dwAvail, &dwMsg)) { | ||||
| 				// Don't care about possible multiple reads being needed
 | ||||
| 				if ((dwAvail != 0) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) { | ||||
| 					// This seems to be needed. Won't overflow since we set our max sizes to sizeof(output)-1
 | ||||
| 					output[dwAvail] = 0; | ||||
| 					uprintf(output); | ||||
| 				} | ||||
| 			} | ||||
| 			if (WaitForSingleObject(pi.hProcess, 0) == WAIT_OBJECT_0) | ||||
| 				break; | ||||
| 			Sleep(100); | ||||
| 		}; | ||||
| 	} else { | ||||
| 		WaitForSingleObject(pi.hProcess, INFINITE); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!GetExitCodeProcess(pi.hProcess, &ret)) | ||||
| 		ret = GetLastError(); | ||||
| 	CloseHandle(pi.hProcess); | ||||
| 	CloseHandle(pi.hThread); | ||||
| 
 | ||||
| out: | ||||
| 	safe_closehandle(hDupOutputWrite); | ||||
| 	safe_closehandle(hOutputRead); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy | ||||
|  */ | ||||
|  |  | |||
							
								
								
									
										12
									
								
								src/vhd.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/vhd.c
									
										
									
									
									
								
							|  | @ -430,6 +430,7 @@ static BOOL WimExtractFile_7z(const char* image, int index, const char* src, con | |||
| 	} | ||||
| 	tmpdst[i] = 0; | ||||
| 
 | ||||
| 	// TODO: use RunCommand
 | ||||
| 	si.cb = sizeof(si); | ||||
| 	safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\%s", image, index, src); | ||||
| 	uprintf("Extracting: %s (From %s)", dst, src); | ||||
|  | @ -509,12 +510,11 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV | |||
| 	switch (dwMsgId) { | ||||
| 	case WIM_MSG_PROGRESS: | ||||
| 		uprintf("  %d%% completed", (DWORD)wParam); | ||||
| 		UpdateProgress(OP_DOS, 1.0f*(DWORD)wParam); | ||||
| 		UpdateProgress(OP_DOS, 0.98f*(DWORD)wParam); | ||||
| 		break; | ||||
| 	case WIM_MSG_PROCESS: | ||||
| 		// The amount of files processed is a bit overwhelming, and displaying it all slows us down
 | ||||
| //#define WIM_DISPLAY_INDIVIDUAL_FILES
 | ||||
| #if WIM_DISPLAY_INDIVIDUAL_FILES | ||||
| #if 0 | ||||
| 		str = wchar_to_utf8((PWSTR)wParam); | ||||
| 		uprintf("Applying: '%s'", str); | ||||
| 		PrintStatus(0, MSG_000, str);	// MSG_000 is "%s"
 | ||||
|  | @ -595,7 +595,7 @@ static DWORD WINAPI WimApplyImageThread(LPVOID param) | |||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	uprintf("Applying image..."); | ||||
| 	uprintf("Applying Windows image..."); | ||||
| 	if (!pfWIMApplyImage(hImage, wdst, 0)) { | ||||
| 		uprintf("  Could not apply image: %s", WindowsErrorString()); | ||||
| 		goto out; | ||||
|  | @ -618,11 +618,11 @@ out: | |||
| 
 | ||||
| BOOL WimApplyImage(const char* image, int index, const char* dst) | ||||
| { | ||||
| 	HANDLE handle; | ||||
| 	DWORD dw = 0; | ||||
| 	_image = image; | ||||
| 	_index = index; | ||||
| 	_dst = dst; | ||||
| 	HANDLE handle; | ||||
| 	DWORD dw = 0; | ||||
| 
 | ||||
| 	handle = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL); | ||||
| 	if (handle == NULL) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue