From bba1772940b30b15345390002c7933ecb9c6f7ea Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 24 Jan 2013 21:30:11 +0000 Subject: [PATCH] [misc] refactoring and cleanup - part 1 * add stdfn.c and move the relevant standard calls there * move most of GetDriveInfo() to drive.c * rename IDC_DOS/hDos to IDC_BOOT/hBoot --- src/.msvc/rufus.vcxproj | 1 + src/.msvc/rufus.vcxproj.filters | 3 + src/.msvc/rufus_sources | 1 + src/Makefile.am | 2 +- src/Makefile.in | 14 +- src/dos.c | 2 +- src/drive.c | 97 +++++++++ src/format.c | 12 +- src/resource.h | 4 +- src/rufus.c | 321 +++++----------------------- src/rufus.h | 4 +- src/rufus.rc | 14 +- src/stdfn.c | 364 ++++++++++++++++++++++++++++++++ src/stdio.c | 5 +- src/stdlg.c | 205 ------------------ src/syslinux.c | 2 +- 16 files changed, 555 insertions(+), 496 deletions(-) create mode 100644 src/stdfn.c diff --git a/src/.msvc/rufus.vcxproj b/src/.msvc/rufus.vcxproj index b9027638..fbfbf063 100644 --- a/src/.msvc/rufus.vcxproj +++ b/src/.msvc/rufus.vcxproj @@ -172,6 +172,7 @@ + diff --git a/src/.msvc/rufus.vcxproj.filters b/src/.msvc/rufus.vcxproj.filters index 068f5682..e77ebd51 100644 --- a/src/.msvc/rufus.vcxproj.filters +++ b/src/.msvc/rufus.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + diff --git a/src/.msvc/rufus_sources b/src/.msvc/rufus_sources index 59dbaf1a..df001208 100644 --- a/src/.msvc/rufus_sources +++ b/src/.msvc/rufus_sources @@ -31,6 +31,7 @@ SXS_APPLICATION_MANIFEST=..\common_controls_and_elevation.manifest SOURCES=rufus.c \ format.c \ stdio.c \ + stdfn.c \ stdlg.c \ icon.c \ parser.c \ diff --git a/src/Makefile.am b/src/Makefile.am index 1aa6f424..decd2f84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ pkg_v_rc_0 = @echo " RC $@"; %_rc.o: %.rc $(pkg_v_rc)$(WINDRES) $(AM_RCFLAGS) -i $< -o $@ -rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdlg.c rufus.c +rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS) rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ diff --git a/src/Makefile.in b/src/Makefile.in index 87a9faaa..04bef641 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -48,8 +48,8 @@ am_rufus_OBJECTS = rufus-drive.$(OBJEXT) rufus-icon.$(OBJEXT) \ rufus-dos.$(OBJEXT) rufus-dos_locale.$(OBJEXT) \ rufus-badblocks.$(OBJEXT) rufus-syslinux.$(OBJEXT) \ rufus-vhd.$(OBJEXT) rufus-format.$(OBJEXT) \ - rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \ - rufus-rufus.$(OBJEXT) + rufus-stdio.$(OBJEXT) rufus-stdfn.$(OBJEXT) \ + rufus-stdlg.$(OBJEXT) rufus-rufus.$(OBJEXT) rufus_OBJECTS = $(am_rufus_OBJECTS) rufus_DEPENDENCIES = rufus_rc.o ms-sys/libmssys.a \ syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ @@ -184,7 +184,7 @@ SUBDIRS = ms-sys syslinux/libfat syslinux/libinstaller libcdio/iso9660 libcdio/u pkg_v_rc = $(pkg_v_rc_$(V)) pkg_v_rc_ = $(pkg_v_rc_$(AM_DEFAULT_VERBOSITY)) pkg_v_rc_0 = @echo " RC $@"; -rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdlg.c rufus.c +rufus_SOURCES = drive.c icon.c parser.c iso.c net.c dos.c dos_locale.c badblocks.c syslinux.c vhd.c format.c stdio.c stdfn.c stdlg.c rufus.c rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./libcdio $(AM_CFLAGS) rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows rufus_LDADD = rufus_rc.o ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \ @@ -341,6 +341,14 @@ rufus-stdio.obj: stdio.c $(AM_V_CC) @AM_BACKSLASH@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdio.obj `if test -f 'stdio.c'; then $(CYGPATH_W) 'stdio.c'; else $(CYGPATH_W) '$(srcdir)/stdio.c'; fi` +rufus-stdfn.o: stdfn.c + $(AM_V_CC) @AM_BACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.o `test -f 'stdfn.c' || echo '$(srcdir)/'`stdfn.c + +rufus-stdfn.obj: stdfn.c + $(AM_V_CC) @AM_BACKSLASH@ + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdfn.obj `if test -f 'stdfn.c'; then $(CYGPATH_W) 'stdfn.c'; else $(CYGPATH_W) '$(srcdir)/stdfn.c'; fi` + rufus-stdlg.o: stdlg.c $(AM_V_CC) @AM_BACKSLASH@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-stdlg.o `test -f 'stdlg.c' || echo '$(srcdir)/'`stdlg.c diff --git a/src/dos.c b/src/dos.c index a9889a8c..6d73fbc0 100644 --- a/src/dos.c +++ b/src/dos.c @@ -451,7 +451,7 @@ BOOL ExtractFreeDOS(const char* path) BOOL ExtractDOS(const char* path) { - switch(ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType))) { + switch(ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType))) { case DT_WINME: return ExtractMSDOS(path); case DT_FREEDOS: diff --git a/src/drive.c b/src/drive.c index 60c7a4ba..ba6ea381 100644 --- a/src/drive.c +++ b/src/drive.c @@ -190,6 +190,103 @@ BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label) return TRUE; } +/* + * Fill the drive properties (size, FS, etc) + */ +BOOL GetDrivePartitionData(DWORD DeviceNumber, char* FileSystemName, DWORD FileSystemNameSize) +{ + BOOL r; + HANDLE hDrive; + DWORD size; + BYTE geometry[128], layout[1024], part_type; + void* disk_geometry = (void*)geometry; + void* drive_layout = (void*)layout; + PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; + PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; + char DrivePath[] = "#:\\", tmp[256]; + DWORD i, nb_partitions = 0; + + hDrive = GetDriveHandle(DeviceNumber, DrivePath, FALSE, FALSE); + if (hDrive == INVALID_HANDLE_VALUE) + return FALSE; + + r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, + NULL, 0, geometry, sizeof(geometry), &size, NULL); + if (!r || size <= 0) { + uprintf("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX failed for drive %c: %s\n", DrivePath[0], WindowsErrorString()); + safe_closehandle(hDrive); + return FALSE; + } + SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; + memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); + uprintf("Sector Size: %d bytes\n", DiskGeometry->Geometry.BytesPerSector); + uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n", + DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack); + + r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, + NULL, 0, layout, sizeof(layout), &size, NULL ); + if (!r || size <= 0) { + uprintf("IOCTL_DISK_GET_DRIVE_LAYOUT_EX failed for drive %c: %s\n", DrivePath[0], WindowsErrorString()); + return FALSE; + } + + switch (DriveLayout->PartitionStyle) { + case PARTITION_STYLE_MBR: + SelectedDrive.PartitionType = PARTITION_STYLE_MBR; + for (i=0; iPartitionCount; i++) { + if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { + nb_partitions++; + } + } + uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions); + uprintf("Disk ID: 0x%08X\n", DriveLayout->Mbr.Signature); + for (i=0; iPartitionCount; i++) { + if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { + uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber); + 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", + GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength), + 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 == 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; iPartitionCount; 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), + 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(hDrive); + + // Populate the filesystem data + if (!GetVolumeInformationA(DrivePath, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize)) { + FileSystemName[0] = 0; + } + + return TRUE; +} + BOOL UnmountDrive(HANDLE hDrive) { DWORD size; diff --git a/src/format.c b/src/format.c index 7324b4d4..14a33a45 100644 --- a/src/format.c +++ b/src/format.c @@ -849,7 +849,7 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive) buf[0x1c2] = 0x0c; break; } - if (IsChecked(IDC_DOS)) { + if (IsChecked(IDC_BOOT)) { // Set first partition bootable - masquerade as per the DiskID selected buf[0x1be] = (IsChecked(IDC_RUFUS_MBR))?(BYTE)ComboBox_GetItemData(hDiskID, ComboBox_GetCurSel(hDiskID)):0x80; uprintf("Set bootable USB partition as 0x%02X\n", buf[0x1be]); @@ -864,7 +864,7 @@ static BOOL WriteMBR(HANDLE hPhysicalDrive) fake_fd._ptr = (char*)hPhysicalDrive; fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); - dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); if ( (dt == DT_SYSLINUX) || ((dt == DT_ISO) && ((fs == FS_FAT16) || (fs == FS_FAT32))) ) { r = write_syslinux_mbr(&fake_fd); } else { @@ -889,7 +889,7 @@ static BOOL WritePBR(HANDLE hLogicalVolume) { int i; FILE fake_fd = { 0 }; - BOOL bFreeDOS = (ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)) == DT_FREEDOS); + BOOL bFreeDOS = (ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)) == DT_FREEDOS); fake_fd._ptr = (char*)hLogicalVolume; fake_fd._bufsiz = SelectedDrive.Geometry.BytesPerSector; @@ -1123,7 +1123,7 @@ DWORD WINAPI FormatThread(LPVOID param) FILE* log_fd; fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); - dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); pt = GETPARTTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); bt = GETBIOSTYPE((int)ComboBox_GetItemData(hPartitionScheme, ComboBox_GetCurSel(hPartitionScheme))); @@ -1250,7 +1250,7 @@ DWORD WINAPI FormatThread(LPVOID param) UpdateProgress(OP_FIX_MBR, -1.0f); } - if (IsChecked(IDC_DOS)) { + if (IsChecked(IDC_BOOT)) { if (bt == BT_UEFI) { // For once, no need to do anything - just check our sanity if ( (dt != DT_ISO) || (!IS_EFI(iso_report)) || (fs > FS_FAT32) ) { @@ -1294,7 +1294,7 @@ DWORD WINAPI FormatThread(LPVOID param) if (!RemountVolume(drive_name[0])) goto out; - if (IsChecked(IDC_DOS)) { + if (IsChecked(IDC_BOOT)) { if ((dt == DT_WINME) || (dt == DT_FREEDOS)) { UpdateProgress(OP_DOS, -1.0f); PrintStatus(0, TRUE, "Copying DOS files..."); diff --git a/src/resource.h b/src/resource.h index 2b3ed6df..a6cc439a 100644 --- a/src/resource.h +++ b/src/resource.h @@ -54,10 +54,10 @@ #define IDC_ABOUT 1007 #define IDC_LABEL 1008 #define IDC_QUICKFORMAT 1009 -#define IDC_DOS 1010 +#define IDC_BOOT 1010 #define IDC_BADBLOCKS 1011 #define IDC_PROGRESS 1012 -#define IDC_DOSTYPE 1013 +#define IDC_BOOTTYPE 1013 #define IDC_NBPASSES 1014 #define IDC_TEST 1015 #define IDC_SELECT_ISO 1016 diff --git a/src/rufus.c b/src/rufus.c index c37b7403..f737db35 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -102,7 +102,7 @@ char szFolderPath[MAX_PATH], app_dir[MAX_PATH]; char* iso_path = NULL; float fScale = 1.0f; int default_fs; -HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL; +HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog = NULL; HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID; BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE; BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE; @@ -112,7 +112,7 @@ RUFUS_UPDATE update = { {0,0,0,0}, {0,0}, NULL, NULL}; extern char szStatusMessage[256]; static HANDLE format_thid = NULL; -static HWND hProgress = NULL, hDOS = NULL, hSelectISO = NULL; +static HWND hProgress = NULL, hBoot = NULL, hSelectISO = NULL; static HICON hIconDisc, hIconDown, hIconUp; static StrArray DriveID, DriveLabel; static char szTimer[12] = "00:00:00"; @@ -319,101 +319,23 @@ static BOOL SetClusterSizes(int FSType) */ static BOOL GetDriveInfo(int ComboIndex) { - BOOL r; - HANDLE hDrive; - DWORD size; - BYTE geometry[128], layout[1024], part_type; - void* disk_geometry = (void*)geometry; - void* drive_layout = (void*)layout; - PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry; - PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout; - char DrivePath[] = "#:\\", tmp[256], fs_type[32]; - DWORD i, nb_partitions = 0; + DWORD i; + char fs_type[32]; memset(&SelectedDrive, 0, sizeof(SelectedDrive)); SelectedDrive.DeviceNumber = (DWORD)ComboBox_GetItemData(hDeviceList, ComboIndex); - hDrive = GetDriveHandle(SelectedDrive.DeviceNumber, DrivePath, FALSE, FALSE); - if (hDrive == INVALID_HANDLE_VALUE) + if (!GetDrivePartitionData(SelectedDrive.DeviceNumber, fs_type, sizeof(fs_type))) return FALSE; - r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, - NULL, 0, geometry, sizeof(geometry), &size, NULL); - if (!r || size <= 0) { - uprintf("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX failed for drive %c: %s\n", DrivePath[0], WindowsErrorString()); - safe_closehandle(hDrive); - return FALSE; - } - SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart; - memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY)); - uprintf("Sector Size: %d bytes\n", DiskGeometry->Geometry.BytesPerSector); - uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n", - DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack); - - r = DeviceIoControl(hDrive, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, - NULL, 0, layout, sizeof(layout), &size, NULL ); - if (!r || size <= 0) { - uprintf("IOCTL_DISK_GET_DRIVE_LAYOUT_EX failed for drive %c: %s\n", DrivePath[0], WindowsErrorString()); - } else { - switch (DriveLayout->PartitionStyle) { - case PARTITION_STYLE_MBR: - SelectedDrive.PartitionType = PARTITION_STYLE_MBR; - for (i=0; iPartitionCount; i++) { - if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { - nb_partitions++; - } - } - uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions); - uprintf("Disk ID: 0x%08X\n", DriveLayout->Mbr.Signature); - for (i=0; iPartitionCount; i++) { - if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) { - uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber); - 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", - GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength), - 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 == 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; iPartitionCount; 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), - 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(hDrive); - if (!DefineClusterSizes()) { uprintf("no file system is selectable for this drive\n"); return FALSE; } // re-select existing FS if it's one we know - if (GetVolumeInformationA(DrivePath, NULL, 0, NULL, NULL, NULL, - fs_type, sizeof(fs_type))) { + SelectedDrive.FSType = FS_UNKNOWN; + if (safe_strlen(fs_type) != 0) { for (SelectedDrive.FSType=FS_MAX-1; SelectedDrive.FSType>=0; SelectedDrive.FSType--) { if (safe_strcmp(fs_type, FileSystemLabel[SelectedDrive.FSType]) == 0) { break; @@ -488,7 +410,7 @@ static void SetFSFromISO(void) void SetMBRProps(void) { int fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); - int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + int dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); BOOL needs_masquerading = (IS_WINPE(iso_report.winpe) && (!iso_report.uses_minint)); if ((!mbr_selected_by_user) && ((iso_path == NULL) || (dt != DT_ISO) || (fs != FS_NTFS))) { @@ -504,8 +426,8 @@ void SetMBRProps(void) void EnableBootOptions(BOOL enable) { - EnableWindow(hDOS, enable); - EnableWindow(hDOSType, enable); + EnableWindow(hBoot, enable); + EnableWindow(hBootType, enable); EnableWindow(hSelectISO, enable); EnableWindow(GetDlgItem(hMainDialog, IDC_RUFUS_MBR), enable); EnableWindow(hDiskID, enable); @@ -746,7 +668,7 @@ static void InitProgress(void) float last_end = 0.0f, slots_discrete = 0.0f, slots_analog = 0.0f; fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); - dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); memset(&nb_slots, 0, sizeof(nb_slots)); memset(&slot_end, 0, sizeof(slot_end)); previous_end = 0.0f; @@ -759,7 +681,7 @@ static void InitProgress(void) if (IsChecked(IDC_BADBLOCKS)) { nb_slots[OP_BADBLOCKS] = -1; } - if (IsChecked(IDC_DOS)) { + if (IsChecked(IDC_BOOT)) { // 1 extra slot for PBR writing switch (dt) { case DT_WINME: @@ -855,138 +777,6 @@ void UpdateProgress(int op, float percent) SetTaskbarProgressValue(pos, MAX_PROGRESS); } -/* - * Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy - */ -#pragma push_macro("INTERFACE") -#undef INTERFACE -#define INTERFACE IGroupPolicyObject -#define REGISTRY_EXTENSION_GUID { 0x35378EAC, 0x683F, 0x11D2, {0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2} } -#define GPO_OPEN_LOAD_REGISTRY 1 -#define GPO_SECTION_MACHINE 2 -typedef enum _GROUP_POLICY_OBJECT_TYPE { - GPOTypeLocal = 0, GPOTypeRemote, GPOTypeDS -} GROUP_POLICY_OBJECT_TYPE, *PGROUP_POLICY_OBJECT_TYPE; -DECLARE_INTERFACE_(IGroupPolicyObject, IUnknown) { - STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG, AddRef) (THIS) PURE; - STDMETHOD_(ULONG, Release) (THIS) PURE; - STDMETHOD(New) (THIS_ LPOLESTR pszDomainName, LPOLESTR pszDisplayName, DWORD dwFlags) PURE; - STDMETHOD(OpenDSGPO) (THIS_ LPOLESTR pszPath, DWORD dwFlags) PURE; - STDMETHOD(OpenLocalMachineGPO) (THIS_ DWORD dwFlags) PURE; - STDMETHOD(OpenRemoteMachineGPO) (THIS_ LPOLESTR pszComputerName, DWORD dwFlags) PURE; - STDMETHOD(Save) (THIS_ BOOL bMachine, BOOL bAdd,GUID *pGuidExtension, GUID *pGuid) PURE; - STDMETHOD(Delete) (THIS) PURE; - STDMETHOD(GetName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; - STDMETHOD(GetDisplayName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; - STDMETHOD(SetDisplayName) (THIS_ LPOLESTR pszName) PURE; - STDMETHOD(GetPath) (THIS_ LPOLESTR pszPath, int cchMaxPath) PURE; - STDMETHOD(GetDSPath) (THIS_ DWORD dwSection, LPOLESTR pszPath ,int cchMaxPath) PURE; - STDMETHOD(GetFileSysPath) (THIS_ DWORD dwSection, LPOLESTR pszPath, int cchMaxPath) PURE; - STDMETHOD(GetRegistryKey) (THIS_ DWORD dwSection, HKEY *hKey) PURE; - STDMETHOD(GetOptions) (THIS_ DWORD *dwOptions) PURE; - STDMETHOD(SetOptions) (THIS_ DWORD dwOptions, DWORD dwMask) PURE; - STDMETHOD(GetType) (THIS_ GROUP_POLICY_OBJECT_TYPE *gpoType) PURE; - STDMETHOD(GetMachineName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; - STDMETHOD(GetPropertySheetPages) (THIS_ HPROPSHEETPAGE **hPages, UINT *uPageCount) PURE; -}; -typedef IGroupPolicyObject *LPGROUPPOLICYOBJECT; - -BOOL SetLGP(BOOL bRestore, const char* szPath, const char* szPolicy, DWORD dwValue) -{ - LONG r; - DWORD disp, regtype, val=0, val_size=sizeof(DWORD); - HRESULT hr; - IGroupPolicyObject* pLGPO; - // Along with global 'existing_key', this static value is used to restore initial state - static DWORD original_val; - HKEY path_key = NULL, policy_key = NULL; - // MSVC is finicky about these ones => redefine them - const IID my_IID_IGroupPolicyObject = - { 0xea502723, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } }; - const IID my_CLSID_GroupPolicyObject = - { 0xea502722, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } }; - GUID ext_guid = REGISTRY_EXTENSION_GUID; - // Can be anything really - GUID snap_guid = { 0x3D271CFC, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} }; - - // We need an IGroupPolicyObject instance to set a Local Group Policy - hr = CoCreateInstance(&my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER, &my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO); - if (FAILED(hr)) { - uprintf("SetLGP: CoCreateInstance failed; hr = %x\n", hr); - goto error; - } - - hr = pLGPO->lpVtbl->OpenLocalMachineGPO(pLGPO, GPO_OPEN_LOAD_REGISTRY); - if (FAILED(hr)) { - uprintf("SetLGP: OpenLocalMachineGPO failed - error %x\n", hr); - goto error; - } - - hr = pLGPO->lpVtbl->GetRegistryKey(pLGPO, GPO_SECTION_MACHINE, &path_key); - if (FAILED(hr)) { - uprintf("SetLGP: GetRegistryKey failed - error %x\n", hr); - goto error; - } - - // The DisableSystemRestore is set in Software\Policies\Microsoft\Windows\DeviceInstall\Settings - r = RegCreateKeyExA(path_key, szPath, 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, - NULL, &policy_key, &disp); - if (r != ERROR_SUCCESS) { - uprintf("SetLGP: Failed to open LGPO path %s - error %x\n", szPath, hr); - goto error; - } - - if ((disp == REG_OPENED_EXISTING_KEY) && (!bRestore) && (!existing_key)) { - // backup existing value for restore - existing_key = TRUE; - regtype = REG_DWORD; - r = RegQueryValueExA(policy_key, szPolicy, NULL, ®type, (LPBYTE)&original_val, &val_size); - if (r == ERROR_FILE_NOT_FOUND) { - // The Key exists but not its value, which is OK - existing_key = FALSE; - } else if (r != ERROR_SUCCESS) { - uprintf("SetLGP: Failed to read original %s policy value - error %x\n", szPolicy, r); - } - } - - if ((!bRestore) || (existing_key)) { - val = (bRestore)?original_val:dwValue; - r = RegSetValueExA(policy_key, szPolicy, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); - } else { - r = RegDeleteValueA(policy_key, szPolicy); - } - if (r != ERROR_SUCCESS) { - uprintf("SetLGP: RegSetValueEx / RegDeleteValue failed - error %x\n", r); - } - RegCloseKey(policy_key); - policy_key = NULL; - - // Apply policy - hr = pLGPO->lpVtbl->Save(pLGPO, TRUE, (bRestore)?FALSE:TRUE, &ext_guid, &snap_guid); - if (r != S_OK) { - uprintf("SetLGP: Unable to apply %s policy - error %x\n", szPolicy, hr); - goto error; - } else { - if ((!bRestore) || (existing_key)) { - uprintf("SetLGP: Successfully %s %s policy to 0x%08X\n", (bRestore)?"restored":"set", szPolicy, val); - } else { - uprintf("SetLGP: Successfully removed %s policy key\n", szPolicy); - } - } - - RegCloseKey(path_key); - pLGPO->lpVtbl->Release(pLGPO); - return TRUE; - -error: - if (path_key != NULL) RegCloseKey(path_key); - if (policy_key != NULL) RegCloseKey(policy_key); - if (pLGPO != NULL) pLGPO->lpVtbl->Release(pLGPO); - return FALSE; -} -#pragma pop_macro("INTERFACE") - /* * Toggle controls according to operation */ @@ -1002,14 +792,14 @@ static void EnableControls(BOOL bEnable) EnableWindow(GetDlgItem(hMainDialog, IDC_QUICKFORMAT), bEnable); if (bEnable) { fs = (int)ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem)); - EnableWindow(hDOS, (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); - EnableWindow(hDOSType, (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); + EnableWindow(hBoot, (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); + EnableWindow(hBootType, (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); EnableWindow(hDiskID, (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); EnableWindow(GetDlgItem(hMainDialog, IDC_RUFUS_MBR), (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); EnableWindow(GetDlgItem(hMainDialog, IDC_EXTRA_PARTITION), (fs == FS_FAT16) || (fs == FS_FAT32) || (fs == FS_NTFS)); } else { - EnableWindow(hDOS, FALSE); - EnableWindow(hDOSType, FALSE); + EnableWindow(hBoot, FALSE); + EnableWindow(hBootType, FALSE); EnableWindow(hDiskID, FALSE); EnableWindow(GetDlgItem(hMainDialog, IDC_RUFUS_MBR), FALSE); EnableWindow(GetDlgItem(hMainDialog, IDC_EXTRA_PARTITION), FALSE); @@ -1234,7 +1024,7 @@ DWORD WINAPI ISOScanThread(LPVOID param) } // Enable DOS, set DOS Type to ISO (last item) and set FS accordingly - CheckDlgButton(hMainDialog, IDC_DOS, BST_CHECKED); + CheckDlgButton(hMainDialog, IDC_BOOT, BST_CHECKED); SetFSFromISO(); SetMBRProps(); for (i=(int)safe_strlen(iso_path); (i>0)&&(iso_path[i]!='\\'); i--); @@ -1255,7 +1045,6 @@ out: ExitThread(0); } - void MoveControl(int nID, float vertical_shift) { RECT rect; @@ -1330,8 +1119,8 @@ void InitDialog(HWND hDlg) hClusterSize = GetDlgItem(hDlg, IDC_CLUSTERSIZE); hLabel = GetDlgItem(hDlg, IDC_LABEL); hProgress = GetDlgItem(hDlg, IDC_PROGRESS); - hDOS = GetDlgItem(hDlg, IDC_DOS); - hDOSType = GetDlgItem(hDlg, IDC_DOSTYPE); + hBoot = GetDlgItem(hDlg, IDC_BOOT); + hBootType = GetDlgItem(hDlg, IDC_BOOTTYPE); hSelectISO = GetDlgItem(hDlg, IDC_SELECT_ISO); hNBPasses = GetDlgItem(hDlg, IDC_NBPASSES); hDiskID = GetDlgItem(hDlg, IDC_DISK_ID); @@ -1379,10 +1168,10 @@ void InitDialog(HWND hDlg) IGNORE_RETVAL(ComboBox_SetCurSel(hNBPasses, 1)); CreateTooltip(hNBPasses, "Pattern: 0x55, 0xAA", -1); // Fill up the DOS type dropdown - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME)); - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS)); - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO)); - IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, selection_default)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), DT_WINME)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), DT_FREEDOS)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "ISO Image"), DT_ISO)); + IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, selection_default)); // Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody") IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, "0x80 (default)"), 0x80)); for (i=1; i<=7; i++) { @@ -1396,7 +1185,7 @@ void InitDialog(HWND hDlg) StrArrayCreate(&DriveLabel, MAX_DRIVES); // Set various checkboxes CheckDlgButton(hDlg, IDC_QUICKFORMAT, BST_CHECKED); - CheckDlgButton(hDlg, IDC_DOS, BST_CHECKED); + CheckDlgButton(hDlg, IDC_BOOT, BST_CHECKED); CheckDlgButton(hDlg, IDC_SET_ICON, BST_CHECKED); // Load system icons (NB: Use the excellent http://www.nirsoft.net/utils/iconsext.html to find icon IDs) @@ -1437,8 +1226,8 @@ void InitDialog(HWND hDlg) CreateTooltip(GetDlgItem(hDlg, IDC_ADVANCED), "Toggle advanced options", -1); CreateTooltip(GetDlgItem(hDlg, IDC_BADBLOCKS), "Test the device for bad blocks using a byte pattern", -1); CreateTooltip(GetDlgItem(hDlg, IDC_QUICKFORMAT), "Unchek this box to use the \"slow\" format method", -1); - CreateTooltip(hDOS, "Check this box to make the USB drive bootable", -1); - CreateTooltip(hDOSType, "Boot method", -1); + CreateTooltip(hBoot, "Check this box to make the USB drive bootable", -1); + CreateTooltip(hBootType, "Boot method", -1); CreateTooltip(hSelectISO, "Click to select an ISO...", -1); CreateTooltip(GetDlgItem(hDlg, IDC_SET_ICON), "Check this box to allow the display of international labels " "and set a device icon (creates an autorun.inf)", 10000); @@ -1630,57 +1419,57 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA EnableBootOptions(TRUE); SetMBRProps(); // Remove the SysLinux option if exists - if (ComboBox_GetItemData(hDOSType, ComboBox_GetCount(hDOSType)-1) == DT_SYSLINUX) { - IGNORE_RETVAL(ComboBox_DeleteString(hDOSType, ComboBox_GetCount(hDOSType)-1)); - IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 1)); + if (ComboBox_GetItemData(hBootType, ComboBox_GetCount(hBootType)-1) == DT_SYSLINUX) { + IGNORE_RETVAL(ComboBox_DeleteString(hBootType, ComboBox_GetCount(hBootType)-1)); + IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, 1)); } break; } if (fs == FS_EXFAT) { - if (IsWindowEnabled(hDOS)) { + if (IsWindowEnabled(hBoot)) { // unlikely to be supported by BIOSes => don't bother - IGNORE_RETVAL(ComboBox_SetCurSel(hDOSType, 0)); - uDOSChecked = IsDlgButtonChecked(hMainDialog, IDC_DOS); - CheckDlgButton(hDlg, IDC_DOS, BST_UNCHECKED); + IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, 0)); + uDOSChecked = IsDlgButtonChecked(hMainDialog, IDC_BOOT); + CheckDlgButton(hDlg, IDC_BOOT, BST_UNCHECKED); EnableBootOptions(FALSE); } SetMBRProps(); break; } - IGNORE_RETVAL(ComboBox_ResetContent(hDOSType)); + IGNORE_RETVAL(ComboBox_ResetContent(hBootType)); if ((bt == BT_BIOS) && ((fs == FS_FAT16) || (fs == FS_FAT32))) { - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "MS-DOS"), DT_WINME)); - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "FreeDOS"), DT_FREEDOS)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), DT_WINME)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), DT_FREEDOS)); } - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "ISO Image"), DT_ISO)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "ISO Image"), DT_ISO)); // If needed (advanced mode) also append a Syslinux option if ( (bt == BT_BIOS) && (((fs == FS_FAT16) || (fs == FS_FAT32)) && (advanced_mode)) ) - IGNORE_RETVAL(ComboBox_SetItemData(hDOSType, ComboBox_AddStringU(hDOSType, "SysLinux"), DT_SYSLINUX)); + IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "SysLinux"), DT_SYSLINUX)); if ( ((!advanced_mode) && (selection_default == DT_SYSLINUX)) ) { selection_default = DT_FREEDOS; CheckDlgButton(hDlg, IDC_DISK_ID, BST_UNCHECKED); } - for (i=0; i + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifdef _CRTDBG_MAP_ALLOC +#include +#include +#endif + +#include +#include + +#include "msapi_utf8.h" +#include "rufus.h" + +enum WindowsVersion nWindowsVersion = WINDOWS_UNDEFINED; + +/* + * Detect Windows version + */ +enum WindowsVersion DetectWindowsVersion(void) +{ + OSVERSIONINFO OSVersion; + + memset(&OSVersion, 0, sizeof(OSVERSIONINFO)); + OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&OSVersion) == 0) + return WINDOWS_UNDEFINED; + if (OSVersion.dwPlatformId != VER_PLATFORM_WIN32_NT) + return WINDOWS_UNSUPPORTED; + // See the Remarks section from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833.aspx + if ((OSVersion.dwMajorVersion < 5) || ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 0))) + return WINDOWS_UNSUPPORTED; // Win2k or earlier + if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 1)) + return WINDOWS_XP; + if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 2)) + return WINDOWS_2003; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 0)) + return WINDOWS_VISTA; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 1)) + return WINDOWS_7; + if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 2)) + return WINDOWS_8; + if ((OSVersion.dwMajorVersion > 6) || ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion >= 3))) + return WINDOWS_9; + return WINDOWS_UNSUPPORTED; +} + +/* + * String array manipulation + */ +void StrArrayCreate(StrArray* arr, size_t initial_size) +{ + if (arr == NULL) return; + arr->Max = initial_size; arr->Index = 0; + arr->Table = (char**)calloc(arr->Max, sizeof(char*)); + if (arr->Table == NULL) + uprintf("Could not allocate string array\n"); +} + +void StrArrayAdd(StrArray* arr, const char* str) +{ + char** old_table; + if ((arr == NULL) || (arr->Table == NULL)) + return; + if (arr->Index == arr->Max) { + arr->Max *= 2; + old_table = arr->Table; + arr->Table = (char**)realloc(arr->Table, arr->Max*sizeof(char*)); + if (arr->Table == NULL) { + free(old_table); + uprintf("Could not reallocate string array\n"); + return; + } + } + arr->Table[arr->Index] = safe_strdup(str); + if (arr->Table[arr->Index++] == NULL) { + uprintf("Could not store string in array\n"); + } +} + +void StrArrayClear(StrArray* arr) +{ + size_t i; + if ((arr == NULL) || (arr->Table == NULL)) + return; + for (i=0; iIndex; i++) { + safe_free(arr->Table[i]); + } + arr->Index = 0; +} + +void StrArrayDestroy(StrArray* arr) +{ + StrArrayClear(arr); + if (arr != NULL) + safe_free(arr->Table); +} + +/* + * Retrieve the SID of the current user. The returned PSID must be freed by the caller using LocalFree() + */ +static PSID GetSID(void) { + TOKEN_USER* tu = NULL; + DWORD len; + HANDLE token; + PSID ret = NULL; + char* psid_string = NULL; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { + uprintf("OpenProcessToken failed: %s\n", WindowsErrorString()); + return NULL; + } + + if (!GetTokenInformation(token, TokenUser, tu, 0, &len)) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + uprintf("GetTokenInformation (pre) failed: %s\n", WindowsErrorString()); + return NULL; + } + tu = (TOKEN_USER*)calloc(1, len); + } + if (tu == NULL) { + return NULL; + } + + if (GetTokenInformation(token, TokenUser, tu, len, &len)) { + /* + * now of course, the interesting thing is that if you return tu->User.Sid + * but free tu, the PSID pointer becomes invalid after a while. + * The workaround? Convert to string then back to PSID + */ + if (!ConvertSidToStringSidA(tu->User.Sid, &psid_string)) { + uprintf("Unable to convert SID to string: %s\n", WindowsErrorString()); + ret = NULL; + } else { + if (!ConvertStringSidToSidA(psid_string, &ret)) { + uprintf("Unable to convert string back to SID: %s\n", WindowsErrorString()); + ret = NULL; + } + // MUST use LocalFree() + LocalFree(psid_string); + } + } else { + ret = NULL; + uprintf("GetTokenInformation (real) failed: %s\n", WindowsErrorString()); + } + free(tu); + return ret; +} + +/* + * read or write I/O to a file + * buffer is allocated by the procedure. path is UTF-8 + */ +BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size) +{ + SECURITY_ATTRIBUTES s_attr, *ps = NULL; + SECURITY_DESCRIPTOR s_desc; + PSID sid = NULL; + HANDLE handle; + BOOL r; + BOOL ret = FALSE; + + // Change the owner from admin to regular user + sid = GetSID(); + if ( (sid != NULL) + && InitializeSecurityDescriptor(&s_desc, SECURITY_DESCRIPTOR_REVISION) + && SetSecurityDescriptorOwner(&s_desc, sid, FALSE) ) { + s_attr.nLength = sizeof(SECURITY_ATTRIBUTES); + s_attr.bInheritHandle = FALSE; + s_attr.lpSecurityDescriptor = &s_desc; + ps = &s_attr; + } else { + uprintf("Could not set security descriptor: %s\n", WindowsErrorString()); + } + + if (!save) { + *buffer = NULL; + } + handle = CreateFileU(path, save?GENERIC_WRITE:GENERIC_READ, FILE_SHARE_READ, + ps, save?CREATE_ALWAYS:OPEN_EXISTING, 0, NULL); + + if (handle == INVALID_HANDLE_VALUE) { + uprintf("Could not %s file '%s'\n", save?"create":"open", path); + goto out; + } + + if (save) { + r = WriteFile(handle, *buffer, *size, size, NULL); + } else { + *size = GetFileSize(handle, NULL); + *buffer = (char*)malloc(*size); + if (*buffer == NULL) { + uprintf("Could not allocate buffer for reading file\n"); + goto out; + } + r = ReadFile(handle, *buffer, *size, size, NULL); + } + + if (!r) { + uprintf("I/O Error: %s\n", WindowsErrorString()); + goto out; + } + + PrintStatus(0, TRUE, "%s '%s'", save?"Saved":"Opened", path); + ret = TRUE; + +out: + CloseHandle(handle); + if (!ret) { + // Only leave a buffer allocated if successful + *size = 0; + if (!save) { + safe_free(*buffer); + } + } + return ret; +} + +/* + * Set or restore a Local Group Policy DWORD key indexed by szPath/SzPolicy + */ +#pragma push_macro("INTERFACE") +#undef INTERFACE +#define INTERFACE IGroupPolicyObject +#define REGISTRY_EXTENSION_GUID { 0x35378EAC, 0x683F, 0x11D2, {0xA8, 0x9A, 0x00, 0xC0, 0x4F, 0xBB, 0xCF, 0xA2} } +#define GPO_OPEN_LOAD_REGISTRY 1 +#define GPO_SECTION_MACHINE 2 +typedef enum _GROUP_POLICY_OBJECT_TYPE { + GPOTypeLocal = 0, GPOTypeRemote, GPOTypeDS +} GROUP_POLICY_OBJECT_TYPE, *PGROUP_POLICY_OBJECT_TYPE; +DECLARE_INTERFACE_(IGroupPolicyObject, IUnknown) { + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + STDMETHOD(New) (THIS_ LPOLESTR pszDomainName, LPOLESTR pszDisplayName, DWORD dwFlags) PURE; + STDMETHOD(OpenDSGPO) (THIS_ LPOLESTR pszPath, DWORD dwFlags) PURE; + STDMETHOD(OpenLocalMachineGPO) (THIS_ DWORD dwFlags) PURE; + STDMETHOD(OpenRemoteMachineGPO) (THIS_ LPOLESTR pszComputerName, DWORD dwFlags) PURE; + STDMETHOD(Save) (THIS_ BOOL bMachine, BOOL bAdd,GUID *pGuidExtension, GUID *pGuid) PURE; + STDMETHOD(Delete) (THIS) PURE; + STDMETHOD(GetName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; + STDMETHOD(GetDisplayName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; + STDMETHOD(SetDisplayName) (THIS_ LPOLESTR pszName) PURE; + STDMETHOD(GetPath) (THIS_ LPOLESTR pszPath, int cchMaxPath) PURE; + STDMETHOD(GetDSPath) (THIS_ DWORD dwSection, LPOLESTR pszPath ,int cchMaxPath) PURE; + STDMETHOD(GetFileSysPath) (THIS_ DWORD dwSection, LPOLESTR pszPath, int cchMaxPath) PURE; + STDMETHOD(GetRegistryKey) (THIS_ DWORD dwSection, HKEY *hKey) PURE; + STDMETHOD(GetOptions) (THIS_ DWORD *dwOptions) PURE; + STDMETHOD(SetOptions) (THIS_ DWORD dwOptions, DWORD dwMask) PURE; + STDMETHOD(GetType) (THIS_ GROUP_POLICY_OBJECT_TYPE *gpoType) PURE; + STDMETHOD(GetMachineName) (THIS_ LPOLESTR pszName, int cchMaxLength) PURE; + STDMETHOD(GetPropertySheetPages) (THIS_ HPROPSHEETPAGE **hPages, UINT *uPageCount) PURE; +}; +typedef IGroupPolicyObject *LPGROUPPOLICYOBJECT; + +BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue) +{ + LONG r; + DWORD disp, regtype, val=0, val_size=sizeof(DWORD); + HRESULT hr; + IGroupPolicyObject* pLGPO; + // Along with global 'existing_key', this static value is used to restore initial state + static DWORD original_val; + HKEY path_key = NULL, policy_key = NULL; + // MSVC is finicky about these ones => redefine them + const IID my_IID_IGroupPolicyObject = + { 0xea502723, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } }; + const IID my_CLSID_GroupPolicyObject = + { 0xea502722, 0xa23d, 0x11d1, { 0xa7, 0xd3, 0x0, 0x0, 0xf8, 0x75, 0x71, 0xe3 } }; + GUID ext_guid = REGISTRY_EXTENSION_GUID; + // Can be anything really + GUID snap_guid = { 0x3D271CFC, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} }; + + // We need an IGroupPolicyObject instance to set a Local Group Policy + hr = CoCreateInstance(&my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER, &my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO); + if (FAILED(hr)) { + uprintf("SetLGP: CoCreateInstance failed; hr = %x\n", hr); + goto error; + } + + hr = pLGPO->lpVtbl->OpenLocalMachineGPO(pLGPO, GPO_OPEN_LOAD_REGISTRY); + if (FAILED(hr)) { + uprintf("SetLGP: OpenLocalMachineGPO failed - error %x\n", hr); + goto error; + } + + hr = pLGPO->lpVtbl->GetRegistryKey(pLGPO, GPO_SECTION_MACHINE, &path_key); + if (FAILED(hr)) { + uprintf("SetLGP: GetRegistryKey failed - error %x\n", hr); + goto error; + } + + // The DisableSystemRestore is set in Software\Policies\Microsoft\Windows\DeviceInstall\Settings + r = RegCreateKeyExA(path_key, szPath, 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, + NULL, &policy_key, &disp); + if (r != ERROR_SUCCESS) { + uprintf("SetLGP: Failed to open LGPO path %s - error %x\n", szPath, hr); + goto error; + } + + if ((disp == REG_OPENED_EXISTING_KEY) && (!bRestore) && (!(*bExistingKey))) { + // backup existing value for restore + *bExistingKey = TRUE; + regtype = REG_DWORD; + r = RegQueryValueExA(policy_key, szPolicy, NULL, ®type, (LPBYTE)&original_val, &val_size); + if (r == ERROR_FILE_NOT_FOUND) { + // The Key exists but not its value, which is OK + *bExistingKey = FALSE; + } else if (r != ERROR_SUCCESS) { + uprintf("SetLGP: Failed to read original %s policy value - error %x\n", szPolicy, r); + } + } + + if ((!bRestore) || (*bExistingKey)) { + val = (bRestore)?original_val:dwValue; + r = RegSetValueExA(policy_key, szPolicy, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); + } else { + r = RegDeleteValueA(policy_key, szPolicy); + } + if (r != ERROR_SUCCESS) { + uprintf("SetLGP: RegSetValueEx / RegDeleteValue failed - error %x\n", r); + } + RegCloseKey(policy_key); + policy_key = NULL; + + // Apply policy + hr = pLGPO->lpVtbl->Save(pLGPO, TRUE, (bRestore)?FALSE:TRUE, &ext_guid, &snap_guid); + if (r != S_OK) { + uprintf("SetLGP: Unable to apply %s policy - error %x\n", szPolicy, hr); + goto error; + } else { + if ((!bRestore) || (*bExistingKey)) { + uprintf("SetLGP: Successfully %s %s policy to 0x%08X\n", (bRestore)?"restored":"set", szPolicy, val); + } else { + uprintf("SetLGP: Successfully removed %s policy key\n", szPolicy); + } + } + + RegCloseKey(path_key); + pLGPO->lpVtbl->Release(pLGPO); + return TRUE; + +error: + if (path_key != NULL) RegCloseKey(path_key); + if (policy_key != NULL) RegCloseKey(policy_key); + if (pLGPO != NULL) pLGPO->lpVtbl->Release(pLGPO); + return FALSE; +} +#pragma pop_macro("INTERFACE") diff --git a/src/stdio.c b/src/stdio.c index 1808ceaf..1e287202 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Standard I/O Routines (logging, status, etc.) + * Standard User I/O Routines (logging, status, etc.) * Copyright (c) 2011-2013 Pete Batard * * This program is free software: you can redistribute it and/or modify @@ -132,8 +132,7 @@ static char err_string[256] = {0}; /* * Display a message on the status bar. If duration is non zero, ensures that message - * is displayed for at least duration ms regardless, regardless of any other incoming - * message + * is displayed for at least duration ms, regardless of any other incoming message */ static BOOL bStatusTimerArmed = FALSE; char szStatusMessage[256] = { 0 }; diff --git a/src/stdlg.c b/src/stdlg.c index 49313672..bf9831d3 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "rufus.h" @@ -61,7 +60,6 @@ static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPath)(PCWSTR pszPath) = NULL; static HICON hMessageIcon = (HICON)INVALID_HANDLE_VALUE; static char* szMessageText = NULL; static char* szMessageTitle = NULL; -enum WindowsVersion nWindowsVersion = WINDOWS_UNDEFINED; static HWND hBrowseEdit; static WNDPROC pOrgBrowseWndproc; static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8}; @@ -69,139 +67,6 @@ static BOOL notification_is_question; static const notification_info* notification_more_info; static BOOL reg_commcheck = FALSE; -/* - * Detect Windows version - */ -enum WindowsVersion DetectWindowsVersion(void) -{ - OSVERSIONINFO OSVersion; - - memset(&OSVersion, 0, sizeof(OSVERSIONINFO)); - OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&OSVersion) == 0) - return WINDOWS_UNDEFINED; - if (OSVersion.dwPlatformId != VER_PLATFORM_WIN32_NT) - return WINDOWS_UNSUPPORTED; - // See the Remarks section from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833.aspx - if ((OSVersion.dwMajorVersion < 5) || ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 0))) - return WINDOWS_UNSUPPORTED; // Win2k or earlier - if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 1)) - return WINDOWS_XP; - if ((OSVersion.dwMajorVersion == 5) && (OSVersion.dwMinorVersion == 2)) - return WINDOWS_2003; - if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 0)) - return WINDOWS_VISTA; - if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 1)) - return WINDOWS_7; - if ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion == 2)) - return WINDOWS_8; - if ((OSVersion.dwMajorVersion > 6) || ((OSVersion.dwMajorVersion == 6) && (OSVersion.dwMinorVersion >= 3))) - return WINDOWS_9; - return WINDOWS_UNSUPPORTED; -} - -/* - * String array manipulation - */ -void StrArrayCreate(StrArray* arr, size_t initial_size) -{ - if (arr == NULL) return; - arr->Max = initial_size; arr->Index = 0; - arr->Table = (char**)calloc(arr->Max, sizeof(char*)); - if (arr->Table == NULL) - uprintf("Could not allocate string array\n"); -} - -void StrArrayAdd(StrArray* arr, const char* str) -{ - char** old_table; - if ((arr == NULL) || (arr->Table == NULL)) - return; - if (arr->Index == arr->Max) { - arr->Max *= 2; - old_table = arr->Table; - arr->Table = (char**)realloc(arr->Table, arr->Max*sizeof(char*)); - if (arr->Table == NULL) { - free(old_table); - uprintf("Could not reallocate string array\n"); - return; - } - } - arr->Table[arr->Index] = safe_strdup(str); - if (arr->Table[arr->Index++] == NULL) { - uprintf("Could not store string in array\n"); - } -} - -void StrArrayClear(StrArray* arr) -{ - size_t i; - if ((arr == NULL) || (arr->Table == NULL)) - return; - for (i=0; iIndex; i++) { - safe_free(arr->Table[i]); - } - arr->Index = 0; -} - -void StrArrayDestroy(StrArray* arr) -{ - StrArrayClear(arr); - if (arr != NULL) - safe_free(arr->Table); -} - -/* - * Retrieve the SID of the current user. The returned PSID must be freed by the caller using LocalFree() - */ -static PSID GetSID(void) { - TOKEN_USER* tu = NULL; - DWORD len; - HANDLE token; - PSID ret = NULL; - char* psid_string = NULL; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { - uprintf("OpenProcessToken failed: %s\n", WindowsErrorString()); - return NULL; - } - - if (!GetTokenInformation(token, TokenUser, tu, 0, &len)) { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - uprintf("GetTokenInformation (pre) failed: %s\n", WindowsErrorString()); - return NULL; - } - tu = (TOKEN_USER*)calloc(1, len); - } - if (tu == NULL) { - return NULL; - } - - if (GetTokenInformation(token, TokenUser, tu, len, &len)) { - /* - * now of course, the interesting thing is that if you return tu->User.Sid - * but free tu, the PSID pointer becomes invalid after a while. - * The workaround? Convert to string then back to PSID - */ - if (!ConvertSidToStringSidA(tu->User.Sid, &psid_string)) { - uprintf("Unable to convert SID to string: %s\n", WindowsErrorString()); - ret = NULL; - } else { - if (!ConvertStringSidToSidA(psid_string, &ret)) { - uprintf("Unable to convert string back to SID: %s\n", WindowsErrorString()); - ret = NULL; - } - // MUST use LocalFree() - LocalFree(psid_string); - } - } else { - ret = NULL; - uprintf("GetTokenInformation (real) failed: %s\n", WindowsErrorString()); - } - free(tu); - return ret; -} - /* * We need a sub-callback to read the content of the edit box on exit and update * our path, else if what the user typed does match the selection, it is discarded. @@ -369,76 +234,6 @@ fallback: dialog_showing--; } -/* - * read or write I/O to a file - * buffer is allocated by the procedure. path is UTF-8 - */ -BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size) -{ - SECURITY_ATTRIBUTES s_attr, *ps = NULL; - SECURITY_DESCRIPTOR s_desc; - PSID sid = NULL; - HANDLE handle; - BOOL r; - BOOL ret = FALSE; - - // Change the owner from admin to regular user - sid = GetSID(); - if ( (sid != NULL) - && InitializeSecurityDescriptor(&s_desc, SECURITY_DESCRIPTOR_REVISION) - && SetSecurityDescriptorOwner(&s_desc, sid, FALSE) ) { - s_attr.nLength = sizeof(SECURITY_ATTRIBUTES); - s_attr.bInheritHandle = FALSE; - s_attr.lpSecurityDescriptor = &s_desc; - ps = &s_attr; - } else { - uprintf("Could not set security descriptor: %s\n", WindowsErrorString()); - } - - if (!save) { - *buffer = NULL; - } - handle = CreateFileU(path, save?GENERIC_WRITE:GENERIC_READ, FILE_SHARE_READ, - ps, save?CREATE_ALWAYS:OPEN_EXISTING, 0, NULL); - - if (handle == INVALID_HANDLE_VALUE) { - uprintf("Could not %s file '%s'\n", save?"create":"open", path); - goto out; - } - - if (save) { - r = WriteFile(handle, *buffer, *size, size, NULL); - } else { - *size = GetFileSize(handle, NULL); - *buffer = (char*)malloc(*size); - if (*buffer == NULL) { - uprintf("Could not allocate buffer for reading file\n"); - goto out; - } - r = ReadFile(handle, *buffer, *size, size, NULL); - } - - if (!r) { - uprintf("I/O Error: %s\n", WindowsErrorString()); - goto out; - } - - PrintStatus(0, TRUE, "%s '%s'", save?"Saved":"Opened", path); - ret = TRUE; - -out: - CloseHandle(handle); - if (!ret) { - // Only leave a buffer allocated if successful - *size = 0; - if (!save) { - safe_free(*buffer); - } - } - return ret; -} - - /* * Return the UTF8 path of a file selected through a load or save dialog * Will use the newer IFileOpenDialog if *compiled* for Vista or later diff --git a/src/syslinux.c b/src/syslinux.c index 7bfcd120..404fec89 100644 --- a/src/syslinux.c +++ b/src/syslinux.c @@ -84,7 +84,7 @@ BOOL InstallSyslinux(DWORD num, const char* drive_name) int ldlinux_sectors; uint32_t ldlinux_cluster; int nsectors; - int dt = (int)ComboBox_GetItemData(hDOSType, ComboBox_GetCurSel(hDOSType)); + int dt = (int)ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)); ldlinux_name[0] = drive_name[0];