diff --git a/.msvc/rufus_2010.vcxproj b/.msvc/rufus_2010.vcxproj index 811d6af4..95b8c38e 100644 --- a/.msvc/rufus_2010.vcxproj +++ b/.msvc/rufus_2010.vcxproj @@ -73,7 +73,7 @@ - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) + _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) MultiThreadedDebug Level3 @@ -92,7 +92,7 @@ ..\..\msvc;..\..\libwdi;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) + _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;ISOLATION_AWARE_ENABLED;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase diff --git a/rufus.c b/rufus.c index ef627667..dc450324 100644 --- a/rufus.c +++ b/rufus.c @@ -19,6 +19,12 @@ * along with this program. If not, see . */ +/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */ +#ifdef _CRTDBG_MAP_ALLOC +#include +#include +#endif + #include #include #include @@ -42,8 +48,6 @@ const GUID GUID_DEVINTERFACE_DISK = { 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b} }; #endif -extern char *WindowsErrorString(void); - /* * Globals */ @@ -54,7 +58,7 @@ HWND hStatus; float fScale = 1.0f; static HWND hDeviceList, hCapacity, hFileSystem; - +static StrArray DriveID; #ifdef RUFUS_DEBUG void _uprintf(const char *format, ...) @@ -366,6 +370,7 @@ static BOOL GetUSBDevices(void) const char* usbstor_name = "USBSTOR"; IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); + StrArrayClear(&DriveID); dev_info = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (dev_info == INVALID_HANDLE_VALUE) { @@ -391,6 +396,7 @@ static BOOL GetUSBDevices(void) continue; } uprintf("found drive '%s'\n", buffer); + StrArrayAdd(&DriveID, buffer); devint_data.cbSize = sizeof(devint_data); hDrive = INVALID_HANDLE_VALUE; @@ -459,6 +465,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA { HDC hDC; DRAWITEMSTRUCT* pDI; + int nDeviceIndex; switch (message) { @@ -479,6 +486,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA CreateStatusBar(); // Display the version in the right area of the status bar SendMessageA(GetDlgItem(hDlg, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)APP_VERSION); + StrArrayCreate(&DriveID, 16); GetUSBDevices(); return (INT_PTR)TRUE; @@ -497,19 +505,26 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA case WM_COMMAND: switch(LOWORD(wParam)) { + case IDOK: // close application + case IDCANCEL: + PostQuitMessage(0); + StrArrayDestroy(&DriveID); + EndDialog(hDlg, 0); + break; case IDC_ABOUT: CreateAboutBox(); break; case IDC_DEVICE: // dropdown: device description switch (HIWORD(wParam)) { case CBN_SELCHANGE: - PopulateProperties(ComboBox_GetCurSel(hDeviceList)); + nDeviceIndex = ComboBox_GetCurSel(hDeviceList); + if (nDeviceIndex != CB_ERR) { + PopulateProperties(ComboBox_GetCurSel(hDeviceList)); + SetDlgItemTextU(hMainDialog, IDC_STATUS, DriveID.Table[nDeviceIndex]); + } break; } break; - case IDC_CLOSE: - PostQuitMessage(0); - break; default: return (INT_PTR)FALSE; } @@ -570,5 +585,9 @@ out: CloseHandle(mutex); uprintf("*** RUFUS EXIT ***\n"); +#ifdef _CRTDBG_MAP_ALLOC + _CrtDumpMemoryLeaks(); +#endif + return 0; } diff --git a/rufus.h b/rufus.h index f9ebf40b..b0455412 100644 --- a/rufus.h +++ b/rufus.h @@ -64,10 +64,23 @@ extern char szFolderPath[MAX_PATH]; /* * Shared prototypes */ +extern char *WindowsErrorString(void); extern void CenterDialog(HWND hDlg); extern void CreateStatusBar(void); extern INT_PTR CreateAboutBox(void); +/* Basic String Array */ +typedef struct { + char** Table; + size_t Size; + size_t Index; + size_t Max; +} StrArray; +extern void StrArrayCreate(StrArray* arr, size_t initial_size); +extern void StrArrayAdd(StrArray* arr, const char* str); +extern void StrArrayClear(StrArray* arr); +extern void StrArrayDestroy(StrArray* arr); + #ifdef RUFUS_DEBUG extern void _uprintf(const char *format, ...); #define uprintf(...) _uprintf(__VA_ARGS__) diff --git a/rufus.rc b/rufus.rc index 4904fcea..ff69d917 100644 --- a/rufus.rc +++ b/rufus.rc @@ -34,7 +34,7 @@ CAPTION "Rufus" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,102,223,50,14 - PUSHBUTTON "Close",IDC_CLOSE,156,223,50,14 + PUSHBUTTON "Close",IDCANCEL,156,223,50,14 COMBOBOX IDC_DEVICE,16,20,190,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Device",IDC_STATIC,17,8,22,8 COMBOBOX IDC_FILESYSTEM,16,80,190,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP diff --git a/stdlg.c b/stdlg.c index 26581cb3..f93f29ca 100644 --- a/stdlg.c +++ b/stdlg.c @@ -19,6 +19,12 @@ * along with this program. If not, see . */ +/* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */ +#ifdef _CRTDBG_MAP_ALLOC +#include +#include +#endif + #include #include #include @@ -127,6 +133,54 @@ void DetectWindowsVersion(void) } } + +/* + * 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) +{ + if ((arr == NULL) || (arr->Table == NULL)) + return; + if (arr->Index == arr->Max) { + arr->Max *= 2; + arr->Table = (char**)realloc(arr->Table, arr->Max*sizeof(char*)); + if (arr->Table == NULL) { + 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); + safe_free(arr->Table); +} + /* * 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.