mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
parent
372b89ba3a
commit
fd55a4ef0f
6 changed files with 276 additions and 31 deletions
|
@ -8,9 +8,10 @@
|
||||||
#define IDD_NOTIFICATION 104
|
#define IDD_NOTIFICATION 104
|
||||||
#define IDD_LICENSE 105
|
#define IDD_LICENSE 105
|
||||||
#define IDD_ISO_EXTRACT 106
|
#define IDD_ISO_EXTRACT 106
|
||||||
#define IDS_VERSION 107
|
#define IDD_LOG 107
|
||||||
#define IDI_UP 108
|
#define IDS_VERSION 108
|
||||||
#define IDI_DOWN 109
|
#define IDI_UP 109
|
||||||
|
#define IDI_DOWN 110
|
||||||
#define IDR_BR_MBR_BIN 200
|
#define IDR_BR_MBR_BIN 200
|
||||||
#define IDR_FD_COMMAND_COM 300
|
#define IDR_FD_COMMAND_COM 300
|
||||||
#define IDR_FD_KERNEL_SYS 301
|
#define IDR_FD_KERNEL_SYS 301
|
||||||
|
@ -77,6 +78,10 @@
|
||||||
#define IDC_NOTIFICATION_LINE 1042
|
#define IDC_NOTIFICATION_LINE 1042
|
||||||
#define IDC_ADVANCED 1043
|
#define IDC_ADVANCED 1043
|
||||||
#define IDC_ADVANCED_GROUP 1044
|
#define IDC_ADVANCED_GROUP 1044
|
||||||
|
#define IDC_LOG 1045
|
||||||
|
#define IDC_LOG_EDIT 1050
|
||||||
|
#define IDC_LOG_SAVE 1051
|
||||||
|
#define IDC_LOG_CLEAR 1052
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
@ -85,7 +90,7 @@
|
||||||
#define _APS_NO_MFC 1
|
#define _APS_NO_MFC 1
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 110
|
#define _APS_NEXT_RESOURCE_VALUE 110
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1045
|
#define _APS_NEXT_CONTROL_VALUE 1053
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
113
src/rufus.c
113
src/rufus.c
|
@ -87,6 +87,7 @@ static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes"
|
||||||
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
|
"1024 kilobytes","2048 kilobytes","4096 kilobytes","8192 kilobytes","16 megabytes","32 megabytes" };
|
||||||
static BOOL existing_key = FALSE; // For LGP set/restore
|
static BOOL existing_key = FALSE; // For LGP set/restore
|
||||||
static BOOL iso_size_check = TRUE;
|
static BOOL iso_size_check = TRUE;
|
||||||
|
static BOOL log_displayed = FALSE;
|
||||||
static int selection_default;
|
static int selection_default;
|
||||||
BOOL enable_fixed_disks = FALSE, advanced_mode = TRUE;
|
BOOL enable_fixed_disks = FALSE, advanced_mode = TRUE;
|
||||||
|
|
||||||
|
@ -95,12 +96,12 @@ BOOL enable_fixed_disks = FALSE, advanced_mode = TRUE;
|
||||||
*/
|
*/
|
||||||
HINSTANCE hMainInstance;
|
HINSTANCE hMainInstance;
|
||||||
HWND hMainDialog;
|
HWND hMainDialog;
|
||||||
char szFolderPath[MAX_PATH];
|
char szFolderPath[MAX_PATH], app_dir[MAX_PATH];
|
||||||
char* iso_path = NULL;
|
char* iso_path = NULL;
|
||||||
float fScale = 1.0f;
|
float fScale = 1.0f;
|
||||||
int default_fs;
|
int default_fs;
|
||||||
HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
|
HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog = NULL;
|
||||||
HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDiskID;
|
||||||
BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
|
||||||
int rufus_version[4];
|
int rufus_version[4];
|
||||||
extern char szStatusMessage[256];
|
extern char szStatusMessage[256];
|
||||||
|
@ -379,7 +380,7 @@ static BOOL GetDriveInfo(void)
|
||||||
nb_partitions++;
|
nb_partitions++;
|
||||||
uprintf("Partition %d:\n", i+1);
|
uprintf("Partition %d:\n", i+1);
|
||||||
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
|
part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
|
||||||
uprintf(" Type: %s (0x%02x)\n Size: %s\n Boot: %s\n Recognized: %s\n Hidden Sectors: %d\n",
|
uprintf(" Type: %s (0x%02x)\r\n Size: %s\r\n Boot: %s\r\n Recognized: %s\r\n Hidden Sectors: %d\n",
|
||||||
GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength),
|
GetPartitionType(part_type), part_type, size_to_hr(DriveLayout->PartitionEntry[i].PartitionLength),
|
||||||
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
|
DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
|
||||||
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No",
|
DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No",
|
||||||
|
@ -1078,6 +1079,67 @@ static void EnableControls(BOOL bEnable)
|
||||||
SetDlgItemTextA(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel");
|
SetDlgItemTextA(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for the log window */
|
||||||
|
BOOL CALLBACK LogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
HFONT hf;
|
||||||
|
long lfHeight;
|
||||||
|
DWORD log_size;
|
||||||
|
char *log_buffer, *filepath;
|
||||||
|
|
||||||
|
switch (message) {
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
hLog = GetDlgItem(hDlg, IDC_LOG_EDIT);
|
||||||
|
// Increase the size of our log textbox to MAX_LOG_SIZE (unsigned word)
|
||||||
|
PostMessage(hLog, EM_LIMITTEXT, MAX_LOG_SIZE , 0);
|
||||||
|
// Set the font to Unicode so that we can display anything
|
||||||
|
hdc = GetDC(NULL);
|
||||||
|
lfHeight = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
||||||
|
ReleaseDC(NULL, hdc);
|
||||||
|
hf = CreateFontA(lfHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||||
|
DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, 0, "Arial Unicode MS");
|
||||||
|
SendDlgItemMessageA(hDlg, IDC_LOG_EDIT, WM_SETFONT, (WPARAM)hf, TRUE);
|
||||||
|
return TRUE;
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch (LOWORD(wParam)) {
|
||||||
|
case IDCANCEL:
|
||||||
|
ShowWindow(hDlg, SW_HIDE);
|
||||||
|
log_displayed = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
case IDC_LOG_CLEAR:
|
||||||
|
SetWindowTextA(hLog, "");
|
||||||
|
return TRUE;
|
||||||
|
case IDC_LOG_SAVE:
|
||||||
|
log_size = GetWindowTextLengthU(hLog);
|
||||||
|
log_buffer = (char*)malloc(log_size);
|
||||||
|
if (log_buffer != NULL) {
|
||||||
|
log_size = GetDlgItemTextU(hDlg, IDC_LOG_EDIT, log_buffer, log_size);
|
||||||
|
if (log_size == 0) {
|
||||||
|
uprintf("Nothing to save.\n");
|
||||||
|
} else {
|
||||||
|
log_size--; // remove NULL terminator
|
||||||
|
filepath = FileDialog(TRUE, app_dir, "rufus.log", "log", "Rufus log");
|
||||||
|
if (filepath != NULL) {
|
||||||
|
FileIO(TRUE, filepath, &log_buffer, &log_size);
|
||||||
|
}
|
||||||
|
safe_free(filepath);
|
||||||
|
}
|
||||||
|
safe_free(log_buffer);
|
||||||
|
} else {
|
||||||
|
uprintf("Could not allocate buffer to save log\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_CLOSE:
|
||||||
|
ShowWindow(hDlg, SW_HIDE);
|
||||||
|
log_displayed = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timer in the right part of the status area
|
* Timer in the right part of the status area
|
||||||
*/
|
*/
|
||||||
|
@ -1171,7 +1233,7 @@ DWORD WINAPI ISOScanThread(LPVOID param)
|
||||||
safe_free(iso_path);
|
safe_free(iso_path);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
uprintf("ISO label: '%s'\n size: %lld bytes, 4GB:%c, bootmgr:%c, winpe:%c (/minint:%c), isolinux:%c, old vesa:%c\n",
|
uprintf("ISO label: '%s'\r\n size: %lld bytes, 4GB:%c, bootmgr:%c, winpe:%c (/minint:%c), isolinux:%c, old vesa:%c\n",
|
||||||
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?'Y':'N',
|
iso_report.label, iso_report.projected_size, iso_report.has_4GB_file?'Y':'N',
|
||||||
iso_report.has_bootmgr?'Y':'N', IS_WINPE(iso_report.winpe)?'Y':'N', (iso_report.uses_minint)?'Y':'N',
|
iso_report.has_bootmgr?'Y':'N', IS_WINPE(iso_report.winpe)?'Y':'N', (iso_report.uses_minint)?'Y':'N',
|
||||||
iso_report.has_isolinux?'Y':'N', iso_report.has_old_vesamenu?'Y':'N');
|
iso_report.has_isolinux?'Y':'N', iso_report.has_old_vesamenu?'Y':'N');
|
||||||
|
@ -1249,7 +1311,7 @@ void MoveControl(int nID, float vertical_shift)
|
||||||
// Toggle "advanced" mode
|
// Toggle "advanced" mode
|
||||||
void ToggleAdvanced(void)
|
void ToggleAdvanced(void)
|
||||||
{
|
{
|
||||||
float dialog_shift = 60.0f;
|
float dialog_shift = 59.0f;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
POINT point;
|
POINT point;
|
||||||
int toggle;
|
int toggle;
|
||||||
|
@ -1268,7 +1330,11 @@ void ToggleAdvanced(void)
|
||||||
MoveControl(IDC_START, dialog_shift);
|
MoveControl(IDC_START, dialog_shift);
|
||||||
MoveControl(IDC_PROGRESS, dialog_shift);
|
MoveControl(IDC_PROGRESS, dialog_shift);
|
||||||
MoveControl(IDC_ABOUT, dialog_shift);
|
MoveControl(IDC_ABOUT, dialog_shift);
|
||||||
|
MoveControl(IDC_LOG, dialog_shift);
|
||||||
MoveControl(IDCANCEL, dialog_shift);
|
MoveControl(IDCANCEL, dialog_shift);
|
||||||
|
#ifdef RUFUS_TEST
|
||||||
|
MoveControl(IDC_TEST, dialog_shift);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Hide or show the various advanced options
|
// Hide or show the various advanced options
|
||||||
toggle = advanced_mode?SW_SHOW:SW_HIDE;
|
toggle = advanced_mode?SW_SHOW:SW_HIDE;
|
||||||
|
@ -1421,10 +1487,13 @@ void InitDialog(HWND hDlg)
|
||||||
static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
DRAWITEMSTRUCT* pDI;
|
DRAWITEMSTRUCT* pDI;
|
||||||
int nDeviceIndex, fs, i;
|
POINT Point;
|
||||||
|
RECT DialogRect, DesktopRect;
|
||||||
|
int nDeviceIndex, fs, i, nWidth, nHeight;
|
||||||
static DWORD DeviceNum = 0;
|
static DWORD DeviceNum = 0;
|
||||||
wchar_t wtmp[128], wstr[MAX_PATH];
|
wchar_t wtmp[128], wstr[MAX_PATH];
|
||||||
static UINT uDOSChecked = BST_CHECKED;
|
static UINT uDOSChecked = BST_CHECKED;
|
||||||
|
static BOOL first_log_display = TRUE;
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
|
|
||||||
|
@ -1437,6 +1506,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_INITDIALOG:
|
case WM_INITDIALOG:
|
||||||
|
// Create the log window (hidden)
|
||||||
|
hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc);
|
||||||
InitDialog(hDlg);
|
InitDialog(hDlg);
|
||||||
GetUSBDevices(0);
|
GetUSBDevices(0);
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
|
@ -1451,7 +1522,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
switch(pDI->itemID) {
|
switch(pDI->itemID) {
|
||||||
case 0: // left part
|
case 0: // left part
|
||||||
DrawTextExU(pDI->hDC, szStatusMessage, -1, &pDI->rcItem,
|
DrawTextExU(pDI->hDC, szStatusMessage, -1, &pDI->rcItem,
|
||||||
DT_LEFT|DT_END_ELLIPSIS, NULL);
|
DT_LEFT|DT_END_ELLIPSIS|DT_PATH_ELLIPSIS, NULL);
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
case 1: // right part
|
case 1: // right part
|
||||||
SetTextColor(pDI->hDC, GetSysColor(COLOR_3DSHADOW));
|
SetTextColor(pDI->hDC, GetSysColor(COLOR_3DSHADOW));
|
||||||
|
@ -1497,6 +1568,27 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
case IDC_ABOUT:
|
case IDC_ABOUT:
|
||||||
CreateAboutBox();
|
CreateAboutBox();
|
||||||
break;
|
break;
|
||||||
|
case IDC_LOG:
|
||||||
|
// Place the log Window to the right of our dialog on first display
|
||||||
|
if (first_log_display) {
|
||||||
|
GetClientRect(GetDesktopWindow(), &DesktopRect);
|
||||||
|
GetWindowRect(hLogDlg, &DialogRect);
|
||||||
|
nWidth = DialogRect.right - DialogRect.left;
|
||||||
|
nHeight = DialogRect.bottom - DialogRect.top;
|
||||||
|
GetWindowRect(hDlg, &DialogRect);
|
||||||
|
// TODO: adjust for high DPI
|
||||||
|
Point.x = min(DialogRect.right + 10, DesktopRect.right - nWidth);
|
||||||
|
Point.y = max(DialogRect.top, DesktopRect.top - nHeight);
|
||||||
|
MoveWindow(hLogDlg, Point.x, Point.y, nWidth, nHeight, FALSE);
|
||||||
|
first_log_display = FALSE;
|
||||||
|
}
|
||||||
|
// Display the log Window
|
||||||
|
log_displayed = !log_displayed;
|
||||||
|
ShowWindow(hLogDlg, log_displayed?SW_SHOW:SW_HIDE);
|
||||||
|
// Set focus on the start button
|
||||||
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)FALSE, 0);
|
||||||
|
SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDC_START), TRUE);
|
||||||
|
break;
|
||||||
#ifdef RUFUS_TEST
|
#ifdef RUFUS_TEST
|
||||||
case IDC_TEST:
|
case IDC_TEST:
|
||||||
break;
|
break;
|
||||||
|
@ -1741,7 +1833,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
|
||||||
SetTaskbarProgressState(TASKBAR_ERROR);
|
SetTaskbarProgressState(TASKBAR_ERROR);
|
||||||
PrintStatus(0, FALSE, "FAILED");
|
PrintStatus(0, FALSE, "FAILED");
|
||||||
Notification(MSG_ERROR, "Error", "Error: %s.%s", StrError(FormatStatus),
|
Notification(MSG_ERROR, "Error", "Error: %s.%s", StrError(FormatStatus),
|
||||||
(strchr(StrError(FormatStatus), '\n') != NULL)?"":"\nFor more information, please try DebugView.");
|
(strchr(StrError(FormatStatus), '\n') != NULL)?"":"\nFor more information, please check the log.");
|
||||||
}
|
}
|
||||||
return (INT_PTR)TRUE;
|
return (INT_PTR)TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1775,6 +1867,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
// Initialize COM for folder selection
|
// Initialize COM for folder selection
|
||||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
// Retrieve the current application directory
|
||||||
|
GetCurrentDirectoryU(MAX_PATH, app_dir);
|
||||||
|
|
||||||
// Set the Windows version
|
// Set the Windows version
|
||||||
DetectWindowsVersion();
|
DetectWindowsVersion();
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#define MAX_DRIVES 16
|
#define MAX_DRIVES 16
|
||||||
#define MAX_TOOLTIPS 32
|
#define MAX_TOOLTIPS 32
|
||||||
#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround
|
#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround
|
||||||
|
#define MAX_LOG_SIZE 0x7FFFFFFE
|
||||||
#define PROPOSEDLABEL_TOLERANCE 0.10
|
#define PROPOSEDLABEL_TOLERANCE 0.10
|
||||||
#define FS_DEFAULT FS_FAT32
|
#define FS_DEFAULT FS_FAT32
|
||||||
#define WHITE RGB(255,255,255)
|
#define WHITE RGB(255,255,255)
|
||||||
|
@ -187,8 +188,8 @@ enum WindowsVersion {
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
extern HINSTANCE hMainInstance;
|
extern HINSTANCE hMainInstance;
|
||||||
extern HWND hMainDialog, hStatus, hDeviceList, hCapacity;
|
extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity;
|
||||||
extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses;
|
extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses, hLog;
|
||||||
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID;
|
extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName, hDiskID;
|
||||||
extern float fScale;
|
extern float fScale;
|
||||||
extern char szFolderPath[MAX_PATH];
|
extern char szFolderPath[MAX_PATH];
|
||||||
|
@ -233,6 +234,7 @@ extern BOOL UnmountDrive(HANDLE hDrive);
|
||||||
extern BOOL CreateProgress(void);
|
extern BOOL CreateProgress(void);
|
||||||
extern BOOL SetAutorun(const char* path);
|
extern BOOL SetAutorun(const char* path);
|
||||||
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);
|
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);
|
||||||
|
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
|
||||||
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
|
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
|
||||||
extern BOOL DownloadFile(const char* url, const char* file);
|
extern BOOL DownloadFile(const char* url, const char* file);
|
||||||
extern char* get_token_data(const char* filename, const char* token);
|
extern char* get_token_data(const char* filename, const char* token);
|
||||||
|
@ -278,7 +280,7 @@ static __inline HMODULE GetDLLHandle(char* szDLLName)
|
||||||
#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
|
#define PF_INIT(proc, dllname) pf##proc = (proc##_t) GetProcAddress(GetDLLHandle(#dllname), #proc)
|
||||||
#define PF_INIT_OR_OUT(proc, dllname) \
|
#define PF_INIT_OR_OUT(proc, dllname) \
|
||||||
PF_INIT(proc, dllname); if (pf##proc == NULL) { \
|
PF_INIT(proc, dllname); if (pf##proc == NULL) { \
|
||||||
uprintf("unable to access %s DLL: %s", #dllname, \
|
uprintf("Unable to access %s DLL: %s\n", #dllname, \
|
||||||
WindowsErrorString()); goto out; }
|
WindowsErrorString()); goto out; }
|
||||||
|
|
||||||
/* Clang/MinGW32 has an issue with intptr_t */
|
/* Clang/MinGW32 has an issue with intptr_t */
|
||||||
|
|
30
src/rufus.rc
30
src/rufus.rc
|
@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
IDD_DIALOG DIALOGEX 12, 12, 206, 316
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
EXSTYLE WS_EX_APPWINDOW
|
||||||
CAPTION "Rufus v1.2.0.178"
|
CAPTION "Rufus v1.2.0.179"
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
|
||||||
|
@ -56,13 +56,14 @@ BEGIN
|
||||||
COMBOBOX IDC_NBPASSES,119,159,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_NBPASSES,119,159,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_DOSTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_DOSTYPE,119,183,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
PUSHBUTTON "...",IDC_SELECT_ISO,171,182,22,14,BS_ICON
|
PUSHBUTTON "...",IDC_SELECT_ISO,171,182,22,14,BS_ICON
|
||||||
PUSHBUTTON "Test",IDC_TEST,62,278,20,14,NOT WS_VISIBLE
|
PUSHBUTTON "T",IDC_TEST,80,278,12,14,NOT WS_VISIBLE
|
||||||
CONTROL "Use Rufus MBR with BIOS ID:",IDC_RUFUS_MBR,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,13,222,106,10
|
CONTROL "Use Rufus MBR with BIOS ID:",IDC_RUFUS_MBR,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,13,222,106,10
|
||||||
PUSHBUTTON "",IDC_ADVANCED,63,148,14,10,BS_TOP | BS_FLAT
|
PUSHBUTTON "",IDC_ADVANCED,63,148,14,10,BS_TOP | BS_FLAT
|
||||||
GROUPBOX "Advanced Options",IDC_ADVANCED_GROUP,7,210,192,42,NOT WS_VISIBLE
|
GROUPBOX "Advanced Options",IDC_ADVANCED_GROUP,7,210,192,42,NOT WS_VISIBLE
|
||||||
COMBOBOX IDC_DISK_ID,119,220,73,30,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_DISK_ID,119,220,73,30,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
|
||||||
CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION,
|
CONTROL "Add fixes for old BIOSes (extra partition, align, etc.)",IDC_EXTRA_PARTITION,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,184,10
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,235,184,10
|
||||||
|
PUSHBUTTON "Log",IDC_LOG,62,278,18,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195
|
IDD_ABOUTBOX DIALOGEX 0, 0, 287, 195
|
||||||
|
@ -76,7 +77,7 @@ BEGIN
|
||||||
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
|
DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP
|
||||||
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
|
CONTROL "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",IDC_ABOUT_RUFUS_URL,
|
||||||
"SysLink",WS_TABSTOP,46,47,114,9
|
"SysLink",WS_TABSTOP,46,47,114,9
|
||||||
LTEXT "Version 1.2.0 (Build 178)",IDC_STATIC,46,19,78,8
|
LTEXT "Version 1.2.0 (Build 179)",IDC_STATIC,46,19,78,8
|
||||||
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
|
PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP
|
||||||
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
||||||
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
|
LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8
|
||||||
|
@ -116,6 +117,17 @@ BEGIN
|
||||||
EDITTEXT IDC_LICENSE_TEXT,7,7,321,176,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
EDITTEXT IDC_LICENSE_TEXT,7,7,321,176,ES_MULTILINE | ES_READONLY | WS_VSCROLL
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_LOG DIALOGEX 0, 0, 366, 280
|
||||||
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
|
||||||
|
CAPTION "Log"
|
||||||
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
|
BEGIN
|
||||||
|
EDITTEXT IDC_LOG_EDIT,0,0,366,252,ES_MULTILINE | ES_READONLY | NOT WS_BORDER | WS_VSCROLL,WS_EX_STATICEDGE
|
||||||
|
PUSHBUTTON "Clear Log",IDC_LOG_CLEAR,204,259,50,14
|
||||||
|
PUSHBUTTON "Save Log",IDC_LOG_SAVE,259,259,50,14
|
||||||
|
PUSHBUTTON "Close",IDCANCEL,314,259,50,14
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -211,6 +223,10 @@ BEGIN
|
||||||
IDD_LICENSE, DIALOG
|
IDD_LICENSE, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_LOG, DIALOG
|
||||||
|
BEGIN
|
||||||
|
END
|
||||||
END
|
END
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
@ -221,8 +237,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,2,0,178
|
FILEVERSION 1,2,0,179
|
||||||
PRODUCTVERSION 1,2,0,178
|
PRODUCTVERSION 1,2,0,179
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -239,13 +255,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "akeo.ie"
|
VALUE "CompanyName", "akeo.ie"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "1.2.0.178"
|
VALUE "FileVersion", "1.2.0.179"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011 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", "1.2.0.178"
|
VALUE "ProductVersion", "1.2.0.179"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -56,7 +57,11 @@ void _uprintf(const char *format, ...)
|
||||||
*p++ = '\n';
|
*p++ = '\n';
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
// Send output to Windows debug facility
|
||||||
OutputDebugStringA(buf);
|
OutputDebugStringA(buf);
|
||||||
|
// Send output to our log Window
|
||||||
|
Edit_SetSel(hLog, MAX_LOG_SIZE, MAX_LOG_SIZE);
|
||||||
|
Edit_ReplaceSelU(hLog, buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
138
src/stdlg.c
138
src/stdlg.c
|
@ -32,6 +32,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
|
#include <sddl.h>
|
||||||
|
|
||||||
#include "rufus.h"
|
#include "rufus.h"
|
||||||
#include "msapi_utf8.h"
|
#include "msapi_utf8.h"
|
||||||
|
@ -139,6 +140,57 @@ void StrArrayDestroy(StrArray* arr)
|
||||||
safe_free(arr->Table);
|
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
|
* 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.
|
* our path, else if what the user typed does match the selection, it is discarded.
|
||||||
|
@ -224,13 +276,13 @@ void BrowseForFolder(void) {
|
||||||
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC,
|
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC,
|
||||||
&IID_IFileOpenDialog, (LPVOID)&pfod);
|
&IID_IFileOpenDialog, (LPVOID)&pfod);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
uprintf("CoCreateInstance for FileOpenDialog failed: error %X", hr);
|
uprintf("CoCreateInstance for FileOpenDialog failed: error %X\n", hr);
|
||||||
pfod = NULL; // Just in case
|
pfod = NULL; // Just in case
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
hr = pfod->lpVtbl->SetOptions(pfod, FOS_PICKFOLDERS);
|
hr = pfod->lpVtbl->SetOptions(pfod, FOS_PICKFOLDERS);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
uprintf("Failed to set folder option for FileOpenDialog: error %X", hr);
|
uprintf("Failed to set folder option for FileOpenDialog: error %X\n", hr);
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
// Set the initial folder (if the path is invalid, will simply use last)
|
// Set the initial folder (if the path is invalid, will simply use last)
|
||||||
|
@ -266,17 +318,17 @@ void BrowseForFolder(void) {
|
||||||
tmp_path = wchar_to_utf8(wpath);
|
tmp_path = wchar_to_utf8(wpath);
|
||||||
CoTaskMemFree(wpath);
|
CoTaskMemFree(wpath);
|
||||||
if (tmp_path == NULL) {
|
if (tmp_path == NULL) {
|
||||||
uprintf("Could not convert path");
|
uprintf("Could not convert path\n");
|
||||||
} else {
|
} else {
|
||||||
safe_strcpy(szFolderPath, MAX_PATH, tmp_path);
|
safe_strcpy(szFolderPath, MAX_PATH, tmp_path);
|
||||||
safe_free(tmp_path);
|
safe_free(tmp_path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uprintf("Failed to set folder option for FileOpenDialog: error %X", hr);
|
uprintf("Failed to set folder option for FileOpenDialog: error %X\n", hr);
|
||||||
}
|
}
|
||||||
} else if ((hr & 0xFFFF) != ERROR_CANCELLED) {
|
} else if ((hr & 0xFFFF) != ERROR_CANCELLED) {
|
||||||
// If it's not a user cancel, assume the dialog didn't show and fallback
|
// If it's not a user cancel, assume the dialog didn't show and fallback
|
||||||
uprintf("could not show FileOpenDialog: error %X", hr);
|
uprintf("Could not show FileOpenDialog: error %X\n", hr);
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
pfod->lpVtbl->Release(pfod);
|
pfod->lpVtbl->Release(pfod);
|
||||||
|
@ -301,6 +353,76 @@ fallback:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* 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
|
* Will use the newer IFileOpenDialog if *compiled* for Vista or later
|
||||||
|
@ -385,7 +507,7 @@ char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_des
|
||||||
}
|
}
|
||||||
} else if ((hr & 0xFFFF) != ERROR_CANCELLED) {
|
} else if ((hr & 0xFFFF) != ERROR_CANCELLED) {
|
||||||
// If it's not a user cancel, assume the dialog didn't show and fallback
|
// If it's not a user cancel, assume the dialog didn't show and fallback
|
||||||
uprintf("could not show FileOpenDialog: error %X\n", hr);
|
uprintf("Could not show FileOpenDialog: error %X\n", hr);
|
||||||
goto fallback;
|
goto fallback;
|
||||||
}
|
}
|
||||||
pfd->lpVtbl->Release(pfd);
|
pfd->lpVtbl->Release(pfd);
|
||||||
|
@ -612,7 +734,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
|
||||||
CenterDialog(hDlg);
|
CenterDialog(hDlg);
|
||||||
// Change the default icon
|
// Change the default icon
|
||||||
if (Static_SetIcon(GetDlgItem(hDlg, IDC_NOTIFICATION_ICON), hMessageIcon) == 0) {
|
if (Static_SetIcon(GetDlgItem(hDlg, IDC_NOTIFICATION_ICON), hMessageIcon) == 0) {
|
||||||
uprintf("could not set dialog icon");
|
uprintf("Could not set dialog icon\n");
|
||||||
}
|
}
|
||||||
// Set the dialog title
|
// Set the dialog title
|
||||||
if (szMessageTitle != NULL) {
|
if (szMessageTitle != NULL) {
|
||||||
|
@ -918,7 +1040,7 @@ BOOL CreateTaskbarList(void)
|
||||||
// Create the taskbar icon progressbar
|
// Create the taskbar icon progressbar
|
||||||
hr = CoCreateInstance(&my_CLSID_TaskbarList, NULL, CLSCTX_ALL, &my_IID_ITaskbarList3, (LPVOID)&ptbl);
|
hr = CoCreateInstance(&my_CLSID_TaskbarList, NULL, CLSCTX_ALL, &my_IID_ITaskbarList3, (LPVOID)&ptbl);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
uprintf("CoCreateInstance for TaskbarList failed: error %X", hr);
|
uprintf("CoCreateInstance for TaskbarList failed: error %X\n", hr);
|
||||||
ptbl = NULL;
|
ptbl = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue