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."
|
"Should you wish to proceed, you are responsible for any data loss on these partitions."
|
||||||
t MSG_094 "Multiple partitions detected"
|
t MSG_094 "Multiple partitions detected"
|
||||||
t MSG_095 "DD Image"
|
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_096 "The file system currently selected can not be used with this type of ISO. "
|
||||||
t MSG_097 "Only 'bootmgr' or 'WinPE' based ISO images can currently be used with NTFS."
|
"Please select a different file system or use a different ISO."
|
||||||
t MSG_098 "FAT/FAT32 can only be used for isolinux based ISO images or when the Target Type is UEFI."
|
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_099 "Filesystem limitation"
|
||||||
t MSG_100 "This ISO image contains a file larger than 4GB, which is more than the "
|
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."
|
"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_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_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_189 "This ISO image is not compatible with the selected filesystem"
|
||||||
|
t MSG_190 "Incompatible drive detected"
|
||||||
t MSG_191 "Write pass"
|
t MSG_191 "Write pass"
|
||||||
t MSG_192 "Read pass"
|
t MSG_192 "Read pass"
|
||||||
t MSG_193 "Downloaded %s"
|
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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\res\down.ico" />
|
<None Include="..\..\res\down.ico" />
|
||||||
<None Include="..\..\res\localization\rufus.loc" />
|
|
||||||
<None Include="..\..\res\rufus.ico" />
|
<None Include="..\..\res\rufus.ico" />
|
||||||
<None Include="..\..\res\up.ico" />
|
<None Include="..\..\res\up.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -139,9 +139,6 @@
|
||||||
<None Include="..\..\res\down.ico">
|
<None Include="..\..\res\down.ico">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\..\res\localization\rufus.loc">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Manifest Include="..\common_controls_and_elevation.manifest">
|
<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;
|
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 full_write _write
|
||||||
#define safe_read full_read
|
#define safe_read full_read
|
||||||
#define lstat stat
|
#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)
|
#define mkdir(x, y) _mkdirU(x)
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#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_IFBLK 0x3000
|
||||||
|
|
||||||
#define S_IFMT _S_IFMT
|
#define S_IFMT _S_IFMT
|
||||||
|
|
|
@ -751,7 +751,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
SelectedDrive.nPartitions++;
|
SelectedDrive.nPartitions++;
|
||||||
tmp[0] = 0;
|
tmp[0] = 0;
|
||||||
wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp));
|
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);
|
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",
|
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),
|
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;
|
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
|
* Detect if a Windows Format prompt is active, by enumerating the
|
||||||
* whole Windows tree and looking for the relevant popup
|
* whole Windows tree and looking for the relevant popup
|
||||||
|
@ -1305,10 +1378,10 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
uint64_t wb;
|
uint64_t wb;
|
||||||
uint8_t *buffer = NULL, *aligned_buffer;
|
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_name[] = "?:\\";
|
||||||
char drive_letters[27];
|
char drive_letters[27];
|
||||||
char logfile[MAX_PATH], image[128], *userdir;
|
char logfile[MAX_PATH], *userdir;
|
||||||
char wim_image[] = "?:\\sources\\install.wim";
|
char wim_image[] = "?:\\sources\\install.wim";
|
||||||
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
char efi_dst[] = "?:\\efi\\boot\\bootx64.efi";
|
||||||
char kolibri_dst[] = "?:\\MTLD_F32";
|
char kolibri_dst[] = "?:\\MTLD_F32";
|
||||||
|
@ -1693,28 +1766,24 @@ DWORD WINAPI FormatThread(void* param)
|
||||||
UpdateProgress(OP_DOS, 0.0f);
|
UpdateProgress(OP_DOS, 0.0f);
|
||||||
PrintInfoDebug(0, MSG_231);
|
PrintInfoDebug(0, MSG_231);
|
||||||
drive_name[2] = 0;
|
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)) {
|
if (HAS_TOGO(iso_report) && (Button_GetCheck(GetDlgItem(hMainDialog, IDC_WINDOWS_TO_GO)) == BST_CHECKED)) {
|
||||||
uprintf("Windows To Go mode selected");
|
// Sanity checks
|
||||||
mounted_iso = MountISO(image_path);
|
if (fs != FS_NTFS) {
|
||||||
if (mounted_iso == NULL) {
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_INCOMPATIBLE_FS);
|
||||||
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))
|
|
||||||
goto out;
|
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)) {
|
} else if (!ExtractISO(image_path, drive_name, FALSE)) {
|
||||||
if (!IS_ERROR(FormatStatus))
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
if (iso_report.has_kolibrios) {
|
if (iso_report.has_kolibrios) {
|
||||||
|
|
|
@ -925,8 +925,8 @@ out:
|
||||||
/*
|
/*
|
||||||
* The following is used for native ISO mounting in Windows 8 or later
|
* The following is used for native ISO mounting in Windows 8 or later
|
||||||
*/
|
*/
|
||||||
const GUID VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT =
|
#define VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT \
|
||||||
{ 0xEC984AECL, 0xA0F9, 0x47e9, { 0x90, 0x1F, 0x71, 0x41, 0x5A, 0x66, 0x34, 0x5B } };
|
{ 0xEC984AECL, 0xA0F9, 0x47e9, { 0x90, 0x1F, 0x71, 0x41, 0x5A, 0x66, 0x34, 0x5B } }
|
||||||
|
|
||||||
typedef enum _VIRTUAL_DISK_ACCESS_MASK {
|
typedef enum _VIRTUAL_DISK_ACCESS_MASK {
|
||||||
VIRTUAL_DISK_ACCESS_NONE = 0x00000000,
|
VIRTUAL_DISK_ACCESS_NONE = 0x00000000,
|
||||||
|
@ -1015,7 +1015,7 @@ static HANDLE mounted_handle = INVALID_HANDLE_VALUE;
|
||||||
char* MountISO(const char* path)
|
char* MountISO(const char* path)
|
||||||
{
|
{
|
||||||
VIRTUAL_STORAGE_TYPE vtype = { 1, VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT };
|
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;
|
DWORD r;
|
||||||
wchar_t wtmp[128];
|
wchar_t wtmp[128];
|
||||||
ULONG size = ARRAYSIZE(wtmp);
|
ULONG size = ARRAYSIZE(wtmp);
|
||||||
|
@ -1037,6 +1037,7 @@ char* MountISO(const char* path)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vparams.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
|
||||||
r = pfAttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY |
|
r = pfAttachVirtualDisk(mounted_handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY |
|
||||||
ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, &vparams, NULL);
|
ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, &vparams, NULL);
|
||||||
if (r != ERROR_SUCCESS) {
|
if (r != ERROR_SUCCESS) {
|
||||||
|
|
|
@ -407,11 +407,11 @@ char* lmprintf(int msg_id, ...)
|
||||||
#define MSG_INFO 1
|
#define MSG_INFO 1
|
||||||
#define MSG_LOW_PRI 0
|
#define MSG_LOW_PRI 0
|
||||||
#define MSG_HIGH_PRI 1
|
#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];
|
char* szStatusMessage = szMessage[MSG_STATUS][MSG_HIGH_PRI];
|
||||||
static BOOL bStatusTimerArmed = FALSE;
|
static BOOL bStatusTimerArmed = FALSE;
|
||||||
|
|
||||||
static __inline OutputMessage(BOOL info, char* msg)
|
static void __inline OutputMessage(BOOL info, char* msg)
|
||||||
{
|
{
|
||||||
if (info)
|
if (info)
|
||||||
SetWindowTextU(hInfo, msg);
|
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.
|
// 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;
|
size_t wpszPath_len = strlen(pszPath) + 2;
|
||||||
wchar_t* wpszPath = (wchar_t*)calloc(wpszPath_len, sizeof(wchar_t));
|
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);
|
utf8_to_wchar_no_alloc(pszPath, wpszPath, wpszPath_len);
|
||||||
// FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION,
|
// FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMATION,
|
||||||
SHFILEOPSTRUCTW shfo = { hwnd, FO_DELETE, wpszPath, NULL, fFlags, FALSE, NULL, NULL };
|
|
||||||
ret = SHFileOperationW(&shfo);
|
ret = SHFileOperationW(&shfo);
|
||||||
wfree(pszPath);
|
wfree(pszPath);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -70,6 +70,8 @@
|
||||||
#define IDR_LC_RUFUS_LOC 500
|
#define IDR_LC_RUFUS_LOC 500
|
||||||
#define IDR_XT_HOGGER 501
|
#define IDR_XT_HOGGER 501
|
||||||
#define IDR_UEFI_TOGO 502
|
#define IDR_UEFI_TOGO 502
|
||||||
|
#define IDR_TOGO_SAN_POLICY_XML 503
|
||||||
|
#define IDR_TOGO_UNATTEND_XML 504
|
||||||
#define IDC_DEVICE 1001
|
#define IDC_DEVICE 1001
|
||||||
#define IDC_FILESYSTEM 1002
|
#define IDC_FILESYSTEM 1002
|
||||||
#define IDC_START 1003
|
#define IDC_START 1003
|
||||||
|
@ -411,7 +413,7 @@
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NO_MFC 1
|
#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_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1071
|
#define _APS_NEXT_CONTROL_VALUE 1071
|
||||||
#define _APS_NEXT_SYMED_VALUE 4000
|
#define _APS_NEXT_SYMED_VALUE 4000
|
||||||
|
|
48
src/rufus.c
48
src/rufus.c
|
@ -933,8 +933,11 @@ static void DisplayISOProps(void)
|
||||||
uprintf(" Uses ReactOS: %s", YesNo(IS_REACTOS(iso_report)));
|
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)" : "");
|
uprintf(" Uses WinPE: %s%s", YesNo(IS_WINPE(iso_report.winpe)), (iso_report.uses_minint) ? " (with /minint)" : "");
|
||||||
|
|
||||||
if ( ((!togo_mode) && (HAS_TOGO(iso_report))) || ((togo_mode) && (!HAS_TOGO(iso_report))) )
|
// We don't support ToGo on Windows 7 or earlier, for lack of ISO mount capabilities
|
||||||
ToggleToGo();
|
// 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The scanning process can be blocking for message processing => use a thread
|
// The scanning process can be blocking for message processing => use a thread
|
||||||
|
@ -1186,7 +1189,18 @@ static BOOL BootCheck(void)
|
||||||
}
|
}
|
||||||
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem));
|
||||||
bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme)));
|
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) {
|
if (!iso_report.has_efi) {
|
||||||
// Unsupported ISO
|
// Unsupported ISO
|
||||||
MessageBoxU(hMainDialog, lmprintf(MSG_091), lmprintf(MSG_090), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
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);
|
ShellExecuteA(hMainDialog, "open", SEVENZIP_URL, NULL, NULL, SW_SHOWNORMAL);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
} else if ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe)) && (!IS_GRUB(iso_report))) {
|
} else if ( ((fs == FS_NTFS) && (!iso_report.has_bootmgr) && (!IS_WINPE(iso_report.winpe)) && (!IS_GRUB(iso_report)))
|
||||||
if (HAS_SYSLINUX(iso_report)) {
|
|| (((fs == FS_FAT16)||(fs == FS_FAT32)) && (!HAS_SYSLINUX(iso_report)) && (!allow_dual_uefi_bios) &&
|
||||||
// Only FAT/FAT32 is supported for this type of ISO
|
(!IS_REACTOS(iso_report)) && (!iso_report.has_kolibrios) && (!IS_GRUB(iso_report))) ) {
|
||||||
MessageBoxU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
// Incompatible FS and ISO
|
||||||
} else {
|
MessageBoxU(hMainDialog, lmprintf(MSG_096), lmprintf(MSG_092), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
||||||
// 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;
|
return FALSE;
|
||||||
} else if ((fs == FS_FAT16) && (iso_report.has_kolibrios)) {
|
} else if ((fs == FS_FAT16) && (iso_report.has_kolibrios)) {
|
||||||
// KolibriOS doesn't support FAT16
|
// KolibriOS doesn't support FAT16
|
||||||
MessageBoxU(hMainDialog, lmprintf(MSG_189), lmprintf(MSG_099), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
MessageBoxU(hMainDialog, lmprintf(MSG_189), lmprintf(MSG_099), MB_OK|MB_ICONERROR|MB_IS_RTL);
|
||||||
return FALSE;
|
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)) {
|
if (((fs == FS_FAT16)||(fs == FS_FAT32)) && (iso_report.has_4GB_file)) {
|
||||||
// This ISO image contains a file larger than 4GB file (FAT32)
|
// 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);
|
FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case IDC_RUFUS_MBR:
|
||||||
if ((HIWORD(wParam)) == BN_CLICKED)
|
if ((HIWORD(wParam)) == BN_CLICKED)
|
||||||
mbr_selected_by_user = IsChecked(IDC_RUFUS_MBR);
|
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 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 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 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 GetUSBDevices(DWORD devnum);
|
||||||
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
|
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
|
||||||
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
|
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
|
IDD_DIALOG DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
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
|
FONT 8, "Segoe UI", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
||||||
|
@ -157,7 +157,7 @@ END
|
||||||
|
|
||||||
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
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
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
||||||
|
@ -283,7 +283,7 @@ END
|
||||||
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
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
|
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
|
FONT 8, "Segoe UI", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
||||||
|
@ -415,7 +415,7 @@ END
|
||||||
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
|
IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
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
|
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
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,127,339,50,14
|
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_FD_EGA18_CPX RCDATA ""../res/freedos/ega18.cpx""\r\n"
|
||||||
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
|
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
|
||||||
"IDR_UEFI_TOGO RCDATA ""../res/uefi/uefi-togo.img""\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"
|
"\r\n"
|
||||||
"// Must reference a manifest for visual styles and elevation\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"
|
"// Oh, and it must happen at the end, or MinGW will ignore it!\r\n"
|
||||||
|
@ -669,8 +671,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 2,0,0,574
|
FILEVERSION 2,0,0,575
|
||||||
PRODUCTVERSION 2,0,0,574
|
PRODUCTVERSION 2,0,0,575
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -687,13 +689,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "2.0.0.574"
|
VALUE "FileVersion", "2.0.0.575"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
|
||||||
VALUE "OriginalFilename", "rufus.exe"
|
VALUE "OriginalFilename", "rufus.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "2.0.0.574"
|
VALUE "ProductVersion", "2.0.0.575"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
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_FD_EGA18_CPX RCDATA "../res/freedos/ega18.cpx"
|
||||||
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
|
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
|
||||||
IDR_UEFI_TOGO RCDATA "../res/uefi/uefi-togo.img"
|
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
|
// Must reference a manifest for visual styles and elevation
|
||||||
// Oh, and it must happen at the end, or MinGW will ignore it!
|
// 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;
|
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
|
* 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;
|
tmpdst[i] = 0;
|
||||||
|
|
||||||
|
// TODO: use RunCommand
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\%s", image, index, src);
|
safe_sprintf(cmdline, sizeof(cmdline), "7z -y e \"%s\" %d\\%s", image, index, src);
|
||||||
uprintf("Extracting: %s (From %s)", dst, src);
|
uprintf("Extracting: %s (From %s)", dst, src);
|
||||||
|
@ -509,12 +510,11 @@ DWORD WINAPI WimProgressCallback(DWORD dwMsgId, WPARAM wParam, LPARAM lParam, PV
|
||||||
switch (dwMsgId) {
|
switch (dwMsgId) {
|
||||||
case WIM_MSG_PROGRESS:
|
case WIM_MSG_PROGRESS:
|
||||||
uprintf(" %d%% completed", (DWORD)wParam);
|
uprintf(" %d%% completed", (DWORD)wParam);
|
||||||
UpdateProgress(OP_DOS, 1.0f*(DWORD)wParam);
|
UpdateProgress(OP_DOS, 0.98f*(DWORD)wParam);
|
||||||
break;
|
break;
|
||||||
case WIM_MSG_PROCESS:
|
case WIM_MSG_PROCESS:
|
||||||
// The amount of files processed is a bit overwhelming, and displaying it all slows us down
|
// The amount of files processed is a bit overwhelming, and displaying it all slows us down
|
||||||
//#define WIM_DISPLAY_INDIVIDUAL_FILES
|
#if 0
|
||||||
#if WIM_DISPLAY_INDIVIDUAL_FILES
|
|
||||||
str = wchar_to_utf8((PWSTR)wParam);
|
str = wchar_to_utf8((PWSTR)wParam);
|
||||||
uprintf("Applying: '%s'", str);
|
uprintf("Applying: '%s'", str);
|
||||||
PrintStatus(0, MSG_000, str); // MSG_000 is "%s"
|
PrintStatus(0, MSG_000, str); // MSG_000 is "%s"
|
||||||
|
@ -595,7 +595,7 @@ static DWORD WINAPI WimApplyImageThread(LPVOID param)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uprintf("Applying image...");
|
uprintf("Applying Windows image...");
|
||||||
if (!pfWIMApplyImage(hImage, wdst, 0)) {
|
if (!pfWIMApplyImage(hImage, wdst, 0)) {
|
||||||
uprintf(" Could not apply image: %s", WindowsErrorString());
|
uprintf(" Could not apply image: %s", WindowsErrorString());
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -618,11 +618,11 @@ out:
|
||||||
|
|
||||||
BOOL WimApplyImage(const char* image, int index, const char* dst)
|
BOOL WimApplyImage(const char* image, int index, const char* dst)
|
||||||
{
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
DWORD dw = 0;
|
||||||
_image = image;
|
_image = image;
|
||||||
_index = index;
|
_index = index;
|
||||||
_dst = dst;
|
_dst = dst;
|
||||||
HANDLE handle;
|
|
||||||
DWORD dw = 0;
|
|
||||||
|
|
||||||
handle = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL);
|
handle = CreateThread(NULL, 0, WimApplyImageThread, NULL, 0, NULL);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
|
|
Loading…
Reference in a new issue