DXGL r667 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r666‎ | r667 | r668 >
Date:00:25, 19 July 2016
Author:admin
Status:new
Tags:
Comment:
Overhaul profile configurations.
Overhaul install/uninstall.
Add option to delete profiles on uninstall.
Display install path of profiles in DXGLCfg.
Possibly fix a crash adding and deleting profiles; select new profile when added and select Global profile after deleting a profile.
Modified paths:
  • /Installer/dxgl.nsi (modified) (history)
  • /cfgmgr/cfgmgr.c (modified) (history)
  • /cfgmgr/cfgmgr.h (modified) (history)
  • /ddraw/common.h (modified) (history)
  • /dxglcfg/dxglcfg.c (modified) (history)
  • /dxglcfg/dxglcfg.rc (modified) (history)
  • /dxglcfg/resource.h (modified) (history)
  • /dxglcfg2/dxglcfg2.c (modified) (history)

Diff [purge]

Index: Installer/dxgl.nsi
@@ -82,7 +82,6 @@
8383 !define GetVersion "Kernel32::GetVersion() i"
8484 !define msvcr120_sha512 "729251371ED208898430040FE48CABD286A5671BD7F472A30E9021B68F73B2D49D85A0879920232426B139520F7E21321BA92646985216BF2F733C64E014A71D"
8585 !addplugindir "..\${SRCDIR}"
86 -Var SUBKEY
8786
8887 !ifdef _DEBUG
8988 Name "${PRODUCT_NAME} ${PRODUCT_VERSION} DEBUG BUILD"
@@ -124,72 +123,8 @@
125124 File "..\COPYING.txt"
126125 File "..\Help\dxgl.chm"
127126 CreateShortCut "$SMPROGRAMS\DXGL\DXGL Help.lnk" "$INSTDIR\dxgl.chm"
128 -
129 - StrCpy $8 0
130 - SetPluginUnload alwaysoff
131 - regloop:
132 - EnumRegKey $SUBKEY HKCU "Software\DXGL" $8
133 - StrCmp $SUBKEY "" regdone
134 - StrCpy $SUBKEY "Software\DXGL\$SUBKEY"
135 - IntOp $8 $8 + 1
136 - ;REG_MULTI_SZ reader based on code at http://nsis.sourceforge.net/REG_MULTI_SZ_Reader
137 - StrCpy $0 ""
138 - StrCpy $1 ""
139 - StrCpy $2 ""
140 - StrCpy $3 ""
141 - System::Call "${RegOpenKeyEx}(${ROOT_KEY},'$SUBKEY',0, \
142 - ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS},.r0) .r3"
143 - StrCmp $3 0 readvalue
144 - Goto regloop
145 - readvalue:
146 - System::Call "${RegQueryValueEx}(r0,'${INSTPATH}',0,.r1,0,.r2) .r3"
147 - StrCmp $3 0 checksz
148 - goto readdone
149 - checksz:
150 - StrCmp $1 ${REG_MULTI_SZ} checkempty
151 - Goto readdone
152 - checkempty:
153 - StrCmp $2 0 0 multiszalloc
154 - Goto readdone
155 - multiszalloc:
156 - System::Alloc $2
157 - Pop $1
158 - StrCmp $1 0 0 multiszget
159 - Goto readdone
160 - multiszget:
161 - System::Call "${RegQueryValueEx}(r0, '${INSTPATH}', 0, n, r1, r2) .r3"
162 - StrCmp $3 0 multiszprocess
163 - System::Free $1
164 - Goto readdone
165 - multiszprocess:
166 - StrCpy $4 $1
167 - IntOp $6 $4 + $2
168 - !ifdef NSIS_UNICODE
169 - IntOp $6 $6 - 2
170 - !else
171 - IntOp $6 $6 - 1
172 - !endif
173 - szloop:
174 - System::Call "*$4(&t${NSIS_MAX_STRLEN} .r3)"
175 - StrLen $5 $3
176 - IntOp $5 $5 + 1
177 - !ifdef NSIS_UNICODE
178 - IntOp $5 $5 + 2
179 - !endif
180 - IntOp $4 $4 + $5
181 - ;copy file here
182 - DetailPrint "Installing ddraw.dll to $3"
183 - CopyFiles $INSTDIR\ddraw.dll $3
184 - IntCmp IntCmp $4 $6 0 szloop
185 - System::Free $1
186 -
187 - readdone:
188 - StrCmp $0 0 regloop
189 - System::Call "${RegCloseKey}(r0)"
190 - goto regloop
191 - regdone:
192 - SetPluginUnload manual
193127 WriteRegStr HKLM "Software\DXGL" "InstallDir" "$INSTDIR"
 128+ ExecWait '"$INSTDIR\dxglcfg.exe" upgrade'
194129 ExecWait '"$INSTDIR\dxgltest.exe" install'
195130 SectionEnd
196131
@@ -317,6 +252,13 @@
318253 FunctionEnd
319254
320255 Section Uninstall
 256+ MessageBox MB_YESNO "Do you want to remove all application profiles?" IDYES wipeprofile IDNO nowipeprofile
 257+ wipeprofile:
 258+ ExecWait '"$INSTDIR\dxglcfg.exe" uninstall 1'
 259+ goto finishuninstall
 260+ nowipeprofile:
 261+ ExecWait '"$INSTDIR\dxglcfg.exe" uninstall 0'
 262+ finishuninstall:
321263 Delete "$INSTDIR\${PRODUCT_NAME}.url"
322264 Delete "$INSTDIR\uninst.exe"
323265 Delete "$INSTDIR\COPYING.txt"
@@ -337,71 +279,5 @@
338280 DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
339281 DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
340282 DeleteRegKey HKLM "Software\DXGL"
341 -
342 - StrCpy $8 0
343 - SetPluginUnload alwaysoff
344 - regloop:
345 - EnumRegKey $SUBKEY HKCU "Software\DXGL" $8
346 - StrCmp $SUBKEY "" regdone
347 - StrCpy $SUBKEY "Software\DXGL\$SUBKEY"
348 - IntOp $8 $8 + 1
349 - ;REG_MULTI_SZ reader based on code at http://nsis.sourceforge.net/REG_MULTI_SZ_Reader
350 - StrCpy $0 ""
351 - StrCpy $1 ""
352 - StrCpy $2 ""
353 - StrCpy $3 ""
354 - System::Call "${RegOpenKeyEx}(${ROOT_KEY},'$SUBKEY',0, \
355 - ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS},.r0) .r3"
356 - StrCmp $3 0 readvalue
357 - Goto regloop
358 - readvalue:
359 - System::Call "${RegQueryValueEx}(r0,'${INSTPATH}',0,.r1,0,.r2) .r3"
360 - StrCmp $3 0 checksz
361 - goto readdone
362 - checksz:
363 - StrCmp $1 ${REG_MULTI_SZ} checkempty
364 - Goto readdone
365 - checkempty:
366 - StrCmp $2 0 0 multiszalloc
367 - Goto readdone
368 - multiszalloc:
369 - System::Alloc $2
370 - Pop $1
371 - StrCmp $1 0 0 multiszget
372 - Goto readdone
373 - multiszget:
374 - System::Call "${RegQueryValueEx}(r0, '${INSTPATH}', 0, n, r1, r2) .r3"
375 - StrCmp $3 0 multiszprocess
376 - System::Free $1
377 - Goto readdone
378 - multiszprocess:
379 - StrCpy $4 $1
380 - IntOp $6 $4 + $2
381 - !ifdef NSIS_UNICODE
382 - IntOp $6 $6 - 2
383 - !else
384 - IntOp $6 $6 - 1
385 - !endif
386 - szloop:
387 - System::Call "*$4(&t${NSIS_MAX_STRLEN} .r3)"
388 - StrLen $5 $3
389 - IntOp $5 $5 + 1
390 - !ifdef NSIS_UNICODE
391 - IntOp $5 $5 * 2
392 - !endif
393 - IntOp $4 $4 + $5
394 - ;copy file here
395 - DetailPrint "Removing ddraw.dll from $3"
396 - Delete $3\ddraw.dll
397 - IntCmp IntCmp $4 $6 0 szloop
398 - System::Free $1
399 -
400 - readdone:
401 - StrCmp $0 0 regloop
402 - System::Call "${RegCloseKey}(r0)"
403 - goto regloop
404 - regdone:
405 - SetPluginUnload manual
406 -
407283 SetAutoClose true
408284 SectionEnd
\ No newline at end of file
Index: cfgmgr/cfgmgr.c
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2011-2015 William Feely
 3+// Copyright (C) 2011-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -34,9 +34,24 @@
3535
3636 TCHAR regkeyglobal[] = _T("Software\\DXGL\\Global");
3737 TCHAR regkeybase[] = _T("Software\\DXGL\\");
 38+TCHAR regkeydxgl[] = _T("Software\\DXGL");
3839
3940 DXGLCFG defaultmask;
4041
 42+/**
 43+* Gets the hexadecimal digit for a number; the number must be less than 16
 44+* or 0x10.
 45+* @param c
 46+* Number from 0 to 15 or 0x0 to 0xF
 47+* @return
 48+* A character representing a hexidecimal digit, letters are uppercase.
 49+*/
 50+static unsigned char hexdigit(unsigned char c)
 51+{
 52+ if (c < 10) return c + '0';
 53+ else return (c + 'A' - 10);
 54+}
 55+
4156 INT_PTR CALLBACK CompatDialogCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
4257 {
4358 switch (Msg)
@@ -436,7 +451,7 @@
437452 DXGLCFG *cfgmask;
438453 TCHAR path[MAX_PATH+1];
439454 LONG error;
440 - DWORD regmultisz = REG_MULTI_SZ;
 455+ DWORD regsz = REG_SZ;
441456 DWORD sizeout=4;
442457 if (mask) cfgmask = mask;
443458 else cfgmask = &defaultmask;
@@ -466,36 +481,14 @@
467482 cfg->aspect = ReadFloat(hKey, cfg->aspect, &cfgmask->aspect, _T("ScreenAspect"));
468483 if(!global && dll)
469484 {
470 - LPTSTR paths;
471485 sizeout = 0;
472486 if(!dir) GetModuleFileName(NULL,path,MAX_PATH);
473487 else _tcsncpy(path,dir,MAX_PATH+1);
474488 GetDirFromPath(path);
475 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,&regmultisz,NULL,&sizeout);
 489+ error = RegQueryValueEx(hKey,_T("InstallPath"),NULL,&regsz,NULL,&sizeout);
476490 if(error == ERROR_FILE_NOT_FOUND)
477 - {
478 - sizeout = (_tcslen(path)*2)+4;
479 - paths = (LPTSTR)malloc(sizeout*sizeof(TCHAR));
480 - if(!paths) return;
481 - ZeroMemory(paths,sizeout*sizeof(TCHAR));
482 - _tcscpy(paths,path);
483 - error = RegSetValueEx(hKey,_T("InstallPaths"),0,REG_MULTI_SZ,(LPBYTE)paths,sizeout);
484 - free(paths);
485 - }
486 - else
487 - {
488 - paths = (LPTSTR)malloc(sizeout+(MAX_PATH*2)+4);
489 - if(!paths) return;
490 - ZeroMemory(paths,sizeout+(MAX_PATH*2)+4);
491 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,&regmultisz,(LPBYTE)paths,&sizeout);
492 - if(!FindStringInMultiSz(paths,path))
493 - {
494 - AddStringToMultiSz(paths,path);
495 - sizeout += (MAX_PATH*2)+4;
496 - error = RegSetValueEx(hKey,_T("InstallPaths"),0,REG_MULTI_SZ,(LPBYTE)paths,sizeout);
497 - }
498 - free(paths);
499 - }
 491+ RegSetValueEx(hKey, _T("InstallPath"), 0, REG_MULTI_SZ,
 492+ (LPBYTE)path, _tcslen(path) * sizeof(TCHAR));
500493 }
501494 }
502495
@@ -558,33 +551,84 @@
559552 WriteFloat(hKey, cfg->aspect, cfgmask->aspect, _T("ScreenAspect"));
560553 }
561554
562 -TCHAR newregname[MAX_PATH+9];
 555+TCHAR newregname[MAX_PATH+65];
563556
 557+BOOL CheckProfileExists(LPTSTR path)
 558+{
 559+ Sha256Context sha_context;
 560+ SHA256_HASH sha256;
 561+ TCHAR sha256string[65];
 562+ TCHAR regkey[MAX_PATH + 80];
 563+ TCHAR filename[MAX_PATH + 1];
 564+ TCHAR pathlwr[MAX_PATH + 1];
 565+ HKEY hKey;
 566+ LONG error;
 567+ int i;
 568+ _tcscpy(regkey, regkeybase);
 569+ _tcscat(regkey, _T("Profiles\\"));
 570+ _tcscpy(filename, path);
 571+ for (i = _tcslen(filename); (i > 0) && (filename[i] != 92) && (filename[i] != 47); i--);
 572+ i++;
 573+ _tcscat(regkey, &filename[i]);
 574+ _tcscat(regkey, _T("-"));
 575+ i--;
 576+ filename[i] = 0;
 577+ _tcslwr(filename);
 578+ Sha256Initialise(&sha_context);
 579+ Sha256Update(&sha_context, filename, _tcslen(filename));
 580+ Sha256Finalise(&sha_context, &sha256);
 581+ for (i = 0; i < (256 / 8); i++)
 582+ {
 583+ sha256string[i * 2] = (TCHAR)hexdigit(sha256.bytes[i] >> 4);
 584+ sha256string[(i * 2) + 1] = (TCHAR)hexdigit(sha256.bytes[i] & 0xF);
 585+ }
 586+ sha256string[256 / 4] = 0;
 587+ _tcscat(regkey, sha256string);
 588+ error = RegOpenKeyEx(HKEY_CURRENT_USER, regkey, 0, KEY_READ, &hKey);
 589+ if (error = ERROR_SUCCESS)
 590+ {
 591+ RegCloseKey(hKey);
 592+ return TRUE;
 593+ }
 594+ else return FALSE;
 595+}
 596+
564597 LPTSTR MakeNewConfig(LPTSTR path)
565598 {
 599+ Sha256Context sha_context;
 600+ SHA256_HASH sha256;
 601+ TCHAR sha256string[65];
 602+ TCHAR pathlwr[MAX_PATH + 1];
566603 HKEY hKey;
567604 DXGLCFG tmp;
568 - TCHAR crcstr[10];
569 - unsigned long crc;
570 - TCHAR regkey[MAX_PATH + 24];
 605+ TCHAR regkey[MAX_PATH + 80];
571606 int i;
572607 TCHAR filename[MAX_PATH + 1];
573 - FILE *file = _tfopen(path, _T("rb"));
574 - if(file != NULL) Crc32_ComputeFile(file,&crc);
575 - else crc = 0;
576 - _itot(crc,crcstr,16);
577 - if(file) fclose(file);
 608+ _tcsncpy(pathlwr, path, MAX_PATH);
 609+ for (i = _tcslen(pathlwr); (i > 0) && (pathlwr[i] != 92) && (pathlwr[i] != 47); i--);
 610+ pathlwr[i] = 0;
 611+ _tcslwr(pathlwr);
 612+ Sha256Initialise(&sha_context);
 613+ Sha256Update(&sha_context, pathlwr, _tcslen(pathlwr));
 614+ Sha256Finalise(&sha_context, &sha256);
 615+ for (i = 0; i < (256 / 8); i++)
 616+ {
 617+ sha256string[i * 2] = (TCHAR)hexdigit(sha256.bytes[i] >> 4);
 618+ sha256string[(i * 2) + 1] = (TCHAR)hexdigit(sha256.bytes[i] & 0xF);
 619+ }
 620+ sha256string[256 / 4] = 0;
578621 _tcscpy(regkey,regkeybase);
579622 _tcsncpy(filename,path,MAX_PATH);
580623 filename[MAX_PATH] = 0;
581624 for(i = _tcslen(filename); (i > 0) && (filename[i] != 92) && (filename[i] != 47); i--);
582625 i++;
 626+ _tcscat(regkey, _T("Profiles\\"));
583627 _tcscat(regkey,&filename[i]);
584628 _tcscat(regkey,_T("-"));
585 - _tcscat(regkey,crcstr);
 629+ _tcscat(regkey,sha256string);
586630 _tcscpy(newregname,&filename[i]);
587631 _tcscat(newregname,_T("-"));
588 - _tcscat(newregname,crcstr);
 632+ _tcscat(newregname,sha256string);
589633 RegCreateKeyEx(HKEY_CURRENT_USER,regkey,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,NULL);
590634 ReadSettings(hKey,&tmp,NULL,FALSE,TRUE,path);
591635 RegCloseKey(hKey);
@@ -591,61 +635,39 @@
592636 return newregname;
593637 }
594638
595 -BOOL IsInstalledDXGLTest(LPCTSTR path)
596 -{
597 - LRESULT err;
598 - TCHAR dir[MAX_PATH+1];
599 - TCHAR cmp[MAX_PATH+1];
600 - HKEY hKey;
601 - DWORD sizeout;
602 - _tcsncpy(dir, path, MAX_PATH);
603 - GetDirFromPath(dir);
604 - sizeout = MAX_PATH*sizeof(TCHAR);
605 - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\DXGL"),0,KEY_READ,&hKey) != ERROR_SUCCESS)
606 - return FALSE;
607 - err = RegQueryValueEx(hKey,_T("InstallDir"),NULL,NULL,(LPBYTE)cmp,&sizeout);
608 - if(err != ERROR_SUCCESS)
609 - {
610 - RegCloseKey(hKey);
611 - return FALSE;
612 - }
613 - RegCloseKey(hKey);
614 - if(!_tcsnicmp(dir,cmp,MAX_PATH)) return TRUE;
615 - else return FALSE;
616 -}
617 -
618639 void GetCurrentConfig(DXGLCFG *cfg, BOOL initial)
619640 {
620641 HKEY hKey;
621 - unsigned long crc;
622 - TCHAR regkey[MAX_PATH+24];
 642+ Sha256Context sha_context;
 643+ SHA256_HASH sha256;
 644+ TCHAR sha256string[65];
 645+ TCHAR regkey[MAX_PATH+80];
623646 FILE *file;
624647 TCHAR filename[MAX_PATH+1];
625 - TCHAR crcstr[10];
626648 int i;
627649 BOOL DPIAwarePM = FALSE;
628650 HMODULE hSHCore = NULL;
629651 HMODULE hUser32 = NULL;
630652 GetModuleFileName(NULL, filename, MAX_PATH);
631 - if(IsInstalledDXGLTest(filename))
 653+ _tcscpy(regkey, regkeybase);
 654+ _tcscat(regkey, _T("Profiles\\"));
 655+ for (i = _tcslen(filename); (i > 0) && (filename[i] != 92) && (filename[i] != 47); i--);
 656+ i++;
 657+ _tcscat(regkey, &filename[i]);
 658+ _tcscat(regkey, _T("-"));
 659+ i--;
 660+ filename[i] = 0;
 661+ _tcslwr(filename);
 662+ Sha256Initialise(&sha_context);
 663+ Sha256Update(&sha_context, filename, _tcslen(filename));
 664+ Sha256Finalise(&sha_context, &sha256);
 665+ for (i = 0; i < (256 / 8); i++)
632666 {
633 - _tcscpy(regkey,regkeybase);
634 - _tcscat(regkey,_T("DXGLTestApp"));
 667+ sha256string[i * 2] = (TCHAR)hexdigit(sha256.bytes[i] >> 4);
 668+ sha256string[(i * 2) + 1] = (TCHAR)hexdigit(sha256.bytes[i] & 0xF);
635669 }
636 - else
637 - {
638 - file = _tfopen(filename,_T("rb"));
639 - if(file != NULL) Crc32_ComputeFile(file,&crc);
640 - else crc = 0;
641 - _itot(crc,crcstr,16);
642 - if(file) fclose(file);
643 - _tcscpy(regkey, regkeybase);
644 - for(i = _tcslen(filename); (i > 0) && (filename[i] != 92) && (filename[i] != 47); i--);
645 - i++;
646 - _tcscat(regkey,&filename[i]);
647 - _tcscat(regkey,_T("-"));
648 - _tcscat(regkey,crcstr);
649 - }
 670+ sha256string[256 / 4] = 0;
 671+ _tcscat(regkey,sha256string);
650672 GetGlobalConfig(cfg, initial);
651673 if (initial) RegOpenKeyEx(HKEY_CURRENT_USER, regkey, 0, KEY_READ, &hKey);
652674 else RegCreateKeyEx(HKEY_CURRENT_USER,regkey,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,NULL);
@@ -714,8 +736,9 @@
715737 void GetConfig(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR name)
716738 {
717739 HKEY hKey;
718 - TCHAR regkey[MAX_PATH + 24];
 740+ TCHAR regkey[MAX_PATH + 80];
719741 _tcscpy(regkey,regkeybase);
 742+ _tcscat(regkey, _T("Profiles\\"));
720743 _tcsncat(regkey, name, MAX_PATH);
721744 ZeroMemory(cfg,sizeof(DXGLCFG));
722745 cfg->DPIScale = 1;
@@ -734,10 +757,305 @@
735758 void SetConfig(const DXGLCFG *cfg, const DXGLCFG *mask, LPCTSTR name)
736759 {
737760 HKEY hKey;
738 - TCHAR regkey[MAX_PATH + 24];
 761+ TCHAR regkey[MAX_PATH + 80];
739762 _tcscpy(regkey, regkeybase);
 763+ _tcscat(regkey, _T("Profiles\\"));
740764 _tcsncat(regkey, name, MAX_PATH);
741765 RegCreateKeyEx(HKEY_CURRENT_USER, regkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
742766 WriteSettings(hKey,cfg,mask,FALSE);
743767 RegCloseKey(hKey);
744768 }
 769+
 770+/**
 771+ * Checks the registry configuration version and if outdated upgrades to
 772+ * the latest version - currently version 1
 773+ * Alpha version configuration is assumed to be version 0.
 774+ */
 775+void UpgradeConfig()
 776+{
 777+ DWORD version = 0;
 778+ DWORD keyindex;
 779+ HKEY hKey;
 780+ HKEY hKeyProfile;
 781+ HKEY hKeyDest;
 782+ TCHAR regkey[MAX_PATH + 24];
 783+ TCHAR subkey[MAX_PATH];
 784+ TCHAR exepath[(MAX_PATH * 2) + 1];
 785+ FILE *file;
 786+ TCHAR crcstr[10];
 787+ unsigned long crc;
 788+ DWORD numoldconfig;
 789+ DWORD numvalue;
 790+ DWORD oldconfigcount;
 791+ DWORD olddirsize = 1024;
 792+ TCHAR *olddir = NULL;
 793+ DWORD oldvaluesize = 1024;
 794+ TCHAR *oldvalue = NULL;
 795+ TCHAR *ptr;
 796+ size_t length;
 797+ CFGREG *oldkeys = NULL;
 798+ DWORD regtype;
 799+ DWORD sizeout, sizeout2;
 800+ Sha256Context sha_context;
 801+ LONG error;
 802+ LONG error2;
 803+ int i;
 804+ // Check configuration version first
 805+ _tcscpy(regkey, regkeybase);
 806+ error = RegCreateKeyEx(HKEY_CURRENT_USER, regkey, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
 807+ if (error != ERROR_SUCCESS)
 808+ {
 809+ MessageBox(NULL, _T("Could not open registry key to upgrade DXGL"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 810+ ExitProcess(error);
 811+ }
 812+ sizeout = 4;
 813+ regtype = REG_DWORD;
 814+ error = RegQueryValueEx(hKey, _T("Configuration Version"), NULL, &regtype, &version, &sizeout);
 815+ if (error != ERROR_SUCCESS) version = 0; // Version is 0 if not set (alpha didn't have version)
 816+ if (regtype != REG_DWORD) version = 0; // Is the key the wrong type?
 817+ if (version >= 1) return; // If version is 1 no need to upgrade.
 818+ver0to1:
 819+ // Count profiles
 820+ keyindex = 0;
 821+ numoldconfig = 0;
 822+ olddir = malloc(olddirsize);
 823+ do
 824+ {
 825+ sizeout = MAX_PATH;
 826+ error = RegEnumKeyEx(hKey, keyindex, &subkey, &sizeout,
 827+ NULL, NULL, NULL, NULL);
 828+ keyindex++;
 829+ if (error == ERROR_SUCCESS)
 830+ {
 831+ error2 = RegOpenKeyEx(hKey, subkey, 0, KEY_READ, &hKeyProfile);
 832+ if (error2 == ERROR_SUCCESS)
 833+ {
 834+ regtype = REG_MULTI_SZ;
 835+ sizeout = olddirsize;
 836+ error2 = RegQueryValueEx(hKeyProfile, _T("InstallPaths"), NULL,
 837+ &regtype, olddir, &sizeout);
 838+ if (error2 == ERROR_MORE_DATA)
 839+ {
 840+ olddirsize = sizeout;
 841+ olddir = realloc(olddir, olddirsize);
 842+ if (!olddir)
 843+ {
 844+ MessageBox(NULL, _T("Out of memory updating registry"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 845+ ExitProcess(error);
 846+ }
 847+ sizeout = olddirsize;
 848+ error2 = RegQueryValueEx(hKeyProfile, _T("InstallPaths"), NULL,
 849+ &regtype, olddir, &sizeout);
 850+ }
 851+ if (error2 == ERROR_SUCCESS)
 852+ {
 853+ if (regtype == REG_MULTI_SZ)
 854+ {
 855+ // Parse MULTI_SZ and count install paths
 856+ ptr = olddir;
 857+ do
 858+ {
 859+ length = _tcslen(ptr);
 860+ if (length)
 861+ {
 862+ numoldconfig++;
 863+ ptr += length + 1;
 864+ }
 865+ } while (length > 0);
 866+ }
 867+ }
 868+ RegCloseKey(hKeyProfile);
 869+ }
 870+ }
 871+ } while (error == ERROR_SUCCESS);
 872+ // Read the old profiles into a list
 873+ // Just need the keys; will transfer the settings later
 874+ oldkeys = (CFGREG*)malloc(numoldconfig * sizeof(CFGREG));
 875+ if (!oldkeys)
 876+ {
 877+ free(olddir);
 878+ MessageBox(NULL, _T("Out of memory updating registry"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 879+ ExitProcess(ERROR_NOT_ENOUGH_MEMORY);
 880+ }
 881+ ZeroMemory(oldkeys, numoldconfig * sizeof(CFGREG));
 882+ oldconfigcount = 0;
 883+ keyindex = 0;
 884+ do
 885+ {
 886+ sizeout = MAX_PATH;
 887+ error = RegEnumKeyEx(hKey, keyindex, &subkey, &sizeout,
 888+ NULL, NULL, NULL, NULL);
 889+ keyindex++;
 890+ if (error == ERROR_SUCCESS)
 891+ {
 892+ error2 = RegOpenKeyEx(hKey, subkey, 0, KEY_READ, &hKeyProfile);
 893+ if (error2 == ERROR_SUCCESS)
 894+ {
 895+ regtype = REG_MULTI_SZ;
 896+ sizeout = olddirsize;
 897+ error2 = RegQueryValueEx(hKeyProfile, _T("InstallPaths"), NULL,
 898+ &regtype, olddir, &sizeout);
 899+ if (error2 == ERROR_MORE_DATA)
 900+ {
 901+ olddirsize = sizeout;
 902+ olddir = realloc(olddir, olddirsize);
 903+ if (!olddir)
 904+ {
 905+ free(olddir);
 906+ MessageBox(NULL, _T("Out of memory updating registry"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 907+ ExitProcess(error);
 908+ }
 909+ sizeout = olddirsize;
 910+ error2 = RegQueryValueEx(hKeyProfile, _T("InstallPaths"), NULL,
 911+ &regtype, olddir, &sizeout);
 912+ }
 913+ if (error2 == ERROR_SUCCESS)
 914+ {
 915+ if (regtype == REG_MULTI_SZ)
 916+ {
 917+ // Parse MULTI_SZ build profiles
 918+ ptr = olddir;
 919+ do
 920+ {
 921+ length = _tcslen(ptr);
 922+ if (length)
 923+ {
 924+ _tcsncpy(oldkeys[oldconfigcount].InstallPath, ptr, MAX_PATH);
 925+ _tcsncpy(oldkeys[oldconfigcount].InstallPathLowercase, ptr, MAX_PATH);
 926+ _tcslwr(oldkeys[oldconfigcount].InstallPathLowercase);
 927+ _tcsncpy(oldkeys[oldconfigcount].OldKey, subkey, MAX_PATH);
 928+ if (!_tcscmp(subkey, _T("DXGLTestApp")))
 929+ {
 930+ _tcscpy(oldkeys[oldconfigcount].EXEFile, _T("dxgltest.exe-0"));
 931+ oldkeys[oldconfigcount].nocrc = TRUE;
 932+ }
 933+ else
 934+ {
 935+ _tcsncpy(oldkeys[oldconfigcount].EXEFile, subkey, MAX_PATH);
 936+ oldkeys[oldconfigcount].nocrc = FALSE;
 937+ }
 938+ if (_tcsrchr(oldkeys[oldconfigcount].EXEFile, _T('-')))
 939+ {
 940+ _tcscpy(oldkeys[oldconfigcount].crc32, _tcsrchr(oldkeys[oldconfigcount].EXEFile, _T('-')) + 1);
 941+ *(_tcsrchr(oldkeys[oldconfigcount].EXEFile, _T('-'))) = 0;
 942+ }
 943+ else
 944+ {
 945+ _tcscpy(oldkeys[oldconfigcount].crc32, "0");
 946+ }
 947+ _tcscpy(exepath, oldkeys[oldconfigcount].InstallPath);
 948+ _tcscat(exepath, _T("\\"));
 949+ _tcscat(exepath, oldkeys[oldconfigcount].EXEFile);
 950+ if (!oldkeys[oldconfigcount].nocrc)
 951+ {
 952+ file = _tfopen(exepath, _T("rb"));
 953+ if (file != NULL) Crc32_ComputeFile(file, &crc);
 954+ else crc = 0;
 955+ _itot(crc, crcstr, 16);
 956+ if (file)
 957+ {
 958+ fclose(file);
 959+ if (!_tcsicmp(crcstr, oldkeys[oldconfigcount].crc32))
 960+ oldkeys[oldconfigcount].exe_found = TRUE;
 961+ else oldkeys[oldconfigcount].exe_found = FALSE;
 962+ }
 963+ else oldkeys[oldconfigcount].exe_found = FALSE;
 964+ }
 965+ else oldkeys[oldconfigcount].exe_found = TRUE;
 966+ Sha256Initialise(&sha_context);
 967+ Sha256Update(&sha_context, oldkeys[oldconfigcount].InstallPathLowercase, length);
 968+ Sha256Finalise(&sha_context, &oldkeys[oldconfigcount].PathHash);
 969+ for (i = 0; i < (256 / 8); i++)
 970+ {
 971+ oldkeys[oldconfigcount].PathHashString[i * 2] = (TCHAR)hexdigit(oldkeys[oldconfigcount].PathHash.bytes[i] >> 4);
 972+ oldkeys[oldconfigcount].PathHashString[(i * 2) + 1] = (TCHAR)hexdigit(oldkeys[oldconfigcount].PathHash.bytes[i] & 0xF);
 973+ }
 974+ oldkeys[oldconfigcount].PathHashString[256 / 4] = 0;
 975+ oldconfigcount++;
 976+ if (oldconfigcount > numoldconfig)
 977+ {
 978+ free(oldkeys);
 979+ goto ver0to1;
 980+ }
 981+ ptr += length + 1;
 982+ }
 983+ } while (length > 0);
 984+ }
 985+ }
 986+ RegCloseKey(hKeyProfile);
 987+ }
 988+ }
 989+ } while (error == ERROR_SUCCESS);
 990+ // Transfer matching profiles
 991+ oldvalue = malloc(oldvaluesize);
 992+ for (int i = 0; i < oldconfigcount; i++)
 993+ {
 994+ if (oldkeys[i].exe_found)
 995+ {
 996+ error = RegOpenKeyEx(hKey, oldkeys[i].OldKey, 0, KEY_READ, &hKeyProfile);
 997+ if (error == ERROR_SUCCESS)
 998+ {
 999+ _tcscpy(exepath, _T("Profiles\\"));
 1000+ _tcscat(exepath, oldkeys[i].EXEFile);
 1001+ _tcscat(exepath, _T("-"));
 1002+ _tcscat(exepath, oldkeys[i].PathHashString);
 1003+ error = RegCreateKeyEx(hKey, exepath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyDest, NULL);
 1004+ if (error == ERROR_SUCCESS)
 1005+ {
 1006+ numvalue = 0;
 1007+ do
 1008+ {
 1009+ sizeout = olddirsize;
 1010+ sizeout2 = oldvaluesize;
 1011+ error = RegEnumValue(hKeyProfile, numvalue, olddir, &sizeout, NULL, &regtype, oldvalue, &sizeout2);
 1012+ if (error == ERROR_MORE_DATA)
 1013+ {
 1014+ if (sizeout > olddirsize)
 1015+ {
 1016+ olddirsize = sizeout;
 1017+ olddir = realloc(olddir, olddirsize);
 1018+ if (!olddir)
 1019+ {
 1020+ MessageBox(NULL, _T("Out of memory updating registry"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 1021+ ExitProcess(error);
 1022+ }
 1023+ }
 1024+ if (sizeout2 > oldvaluesize)
 1025+ {
 1026+ oldvaluesize = sizeout2;
 1027+ oldvalue = realloc(oldvalue, oldvaluesize);
 1028+ if (!oldvalue)
 1029+ {
 1030+ MessageBox(NULL, _T("Out of memory updating registry"), _T("Fatal error"), MB_ICONSTOP | MB_OK);
 1031+ ExitProcess(error);
 1032+ }
 1033+ }
 1034+ sizeout = olddirsize;
 1035+ sizeout2 = oldvaluesize;
 1036+ error = RegEnumValue(hKeyProfile, numvalue, olddir, &sizeout, NULL, &regtype, oldvalue, &sizeout2);
 1037+ }
 1038+ if (error == ERROR_SUCCESS)
 1039+ {
 1040+ if (_tcsnicmp(olddir, _T("InstallPaths"), sizeout))
 1041+ RegSetValueEx(hKeyDest, olddir, 0, regtype, oldvalue, sizeout2);
 1042+ }
 1043+ numvalue++;
 1044+ } while (error == ERROR_SUCCESS);
 1045+ RegSetValueEx(hKeyDest, _T("InstallPath"), 0, REG_SZ, oldkeys[i].InstallPath,
 1046+ ((_tcslen(oldkeys[i].InstallPath) + 1) * sizeof(TCHAR)));
 1047+ RegCloseKey(hKeyDest);
 1048+ }
 1049+ RegCloseKey(hKeyProfile);
 1050+ }
 1051+ }
 1052+ }
 1053+ // Delete old registry keys
 1054+ for (int i = 0; i < oldconfigcount; i++)
 1055+ RegDeleteKey(hKey, oldkeys[i].OldKey);
 1056+ // Clean up and write registry version
 1057+ if(olddir) free(olddir);
 1058+ if(oldvalue) free(oldvalue);
 1059+ sizeout = 1;
 1060+ RegSetValueEx(hKey, _T("Configuration Version"), 0, REG_DWORD, &sizeout, 4);
 1061+ RegCloseKey(hKey);
 1062+}
\ No newline at end of file
Index: cfgmgr/cfgmgr.h
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2011-2012 William Feely
 3+// Copyright (C) 2011-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -49,6 +49,19 @@
5050 BOOL Windows8Detected;
5151 } DXGLCFG;
5252
 53+typedef struct
 54+{
 55+ TCHAR InstallPath[MAX_PATH + 1];
 56+ TCHAR InstallPathLowercase[MAX_PATH + 1];
 57+ TCHAR EXEFile[MAX_PATH + 1];
 58+ TCHAR OldKey[MAX_PATH + 1];
 59+ TCHAR crc32[9];
 60+ BOOL nocrc;
 61+ SHA256_HASH PathHash;
 62+ TCHAR PathHashString[65];
 63+ BOOL exe_found;
 64+} CFGREG;
 65+
5366 void ReadSettings(HKEY hKey, DXGLCFG *cfg, DXGLCFG *mask, BOOL global, BOOL dll, LPTSTR dir);
5467 void WriteSettings(HKEY hKey, const DXGLCFG *cfg, const DXGLCFG *mask, BOOL global);
5568 void GetCurrentConfig(DXGLCFG *cfg, BOOL initial);
@@ -57,6 +70,8 @@
5871 void GetConfig(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR name);
5972 void SetConfig(const DXGLCFG *cfg, const DXGLCFG *mask, LPCTSTR name);
6073 void GetDirFromPath(LPTSTR path);
 74+void UpgradeConfig();
 75+BOOL CheckProfileExists(LPTSTR path);
6176 LPTSTR MakeNewConfig(LPTSTR path);
6277
6378 #ifdef __cplusplus
Index: ddraw/common.h
@@ -119,5 +119,6 @@
120120 extern CRITICAL_SECTION dll_cs;
121121
122122 #include "trace.h"
 123+#include "../cfgmgr/LibSha256.h"
123124 #include "../cfgmgr/cfgmgr.h"
124125 #endif //_COMMON_H
Index: dxglcfg/dxglcfg.c
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2011-2014 William Feely
 3+// Copyright (C) 2011-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,7 @@
3131 #include <math.h>
3232 #include <io.h>
3333 #include "resource.h"
 34+#include "../cfgmgr/LibSha256.h"
3435 #include "../cfgmgr/cfgmgr.h"
3536 #include <gl/GL.h>
3637
@@ -65,6 +66,8 @@
6667 BOOL dirty;
6768 DXGLCFG cfg;
6869 DXGLCFG mask;
 70+ TCHAR path[MAX_PATH];
 71+ BOOL builtin;
6972 } app_setting;
7073
7174 TCHAR exe_filter[] = _T("Program Files\0*.exe\0All Files\0*.*\0\0");
@@ -223,6 +226,7 @@
224227 float fract;
225228 TCHAR denominator[5];
226229 int i;
 230+ if (_isnan(f)) f = 0; //Handle NAN condition
227231 if (f >= 1000.0f) // Clamp ridiculously wide aspects
228232 {
229233 _tcscpy(aspect, _T("1000:1"));
@@ -456,7 +460,6 @@
457461 LPTSTR keyname;
458462 LPTSTR regbuffer;
459463 DWORD regbuffersize;
460 - DWORD regbufferpos;
461464 DWORD buffersize;
462465 LONG error;
463466 TCHAR buffer[64];
@@ -481,6 +484,7 @@
482485 LPTSTR regpath;
483486 LPTSTR regkey;
484487 BOOL failed;
 488+ LPTSTR installpath;
485489 switch (Msg)
486490 {
487491 case WM_INITDIALOG:
@@ -491,6 +495,7 @@
492496 _tcscpy(apps[0].name,_T("Global"));
493497 apps[0].regkey = (TCHAR*)malloc(7 * sizeof(TCHAR));
494498 _tcscpy(apps[0].regkey,_T("Global"));
 499+ UpgradeConfig();
495500 GetGlobalConfig(&apps[0].cfg, FALSE);
496501 cfg = &apps[0].cfg;
497502 cfgmask = &apps[0].mask;
@@ -499,6 +504,7 @@
500505 apps[0].dirty = FALSE;
501506 apps[0].icon = LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_STAR));
502507 apps[0].icon_shared = TRUE;
 508+ apps[0].path[0] = 0;
503509 SetClassLong(hWnd,GCL_HICON,(LONG)LoadIcon(hinstance,(LPCTSTR)IDI_DXGL));
504510 SetClassLong(hWnd,GCL_HICONSM,(LONG)LoadIcon(hinstance,(LPCTSTR)IDI_DXGLSM));
505511 // create temporary gl context to get AA and AF settings.
@@ -740,119 +746,139 @@
741747 _tcscpy(buffer, _T("Windows AppCompat"));
742748 SendDlgItemMessage(hWnd,IDC_DPISCALE,CB_ADDSTRING,2,(LPARAM)buffer);
743749 SendDlgItemMessage(hWnd,IDC_DPISCALE,CB_SETCURSEL,cfg->DPIScale,0);
 750+ EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), FALSE);
 751+ EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), FALSE);
 752+ // Check install path
 753+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKey);
 754+ if (error == ERROR_SUCCESS)
 755+ {
 756+ if (RegQueryValueEx(hKey, _T("InstallDir"), NULL, NULL, NULL, &keysize) == ERROR_SUCCESS)
 757+ {
 758+ installpath = (LPTSTR)malloc(keysize);
 759+ error = RegQueryValueEx(hKey, _T("InstallDir"), NULL, NULL, installpath, &keysize);
 760+ if (error != ERROR_SUCCESS)
 761+ {
 762+ free(installpath);
 763+ installpath = NULL;
 764+ }
 765+ }
 766+ RegCloseKey(hKey);
 767+ }
 768+ hKey = NULL;
744769 // Add installed programs
745770 current_app = 1;
746771 appcount = 1;
747772 regbuffersize = 1024;
748 - regbuffer = (LPTSTR)malloc(regbuffersize*sizeof(TCHAR));
749 - RegCreateKeyEx(HKEY_CURRENT_USER,_T("Software\\DXGL"),0,NULL,0,KEY_READ,NULL,&hKeyBase,NULL);
750 - RegQueryInfoKey(hKeyBase,NULL,NULL,NULL,NULL,&keysize,NULL,NULL,NULL,NULL,NULL,NULL);
 773+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 774+ RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, NULL, 0, KEY_READ, NULL, &hKeyBase, NULL);
 775+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
751776 keysize++;
752 - keyname = (LPTSTR)malloc(keysize*sizeof(TCHAR));
 777+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
753778 keysize2 = keysize;
754779 i = 0;
755 - while(RegEnumKeyEx(hKeyBase,i,keyname,&keysize2,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
 780+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
756781 {
757782 keysize2 = keysize;
758783 i++;
759 - if(!_tcscmp(keyname,_T("Global"))) continue;
760784 appcount++;
761 - if(appcount > maxapps)
 785+ if (appcount > maxapps)
762786 {
763787 maxapps += 128;
764 - apps = (app_setting *)realloc(apps,maxapps*sizeof(app_setting));
 788+ apps = (app_setting *)realloc(apps, maxapps * sizeof(app_setting));
765789 }
766 - if(!_tcscmp(keyname,_T("DXGLTestApp"))) _tcscpy(subkey,_T("dxgltest.exe-0"));
767 - else _tcscpy(subkey,keyname);
 790+ _tcscpy(subkey, keyname);
768791 if (_tcsrchr(subkey, _T('-'))) *(_tcsrchr(subkey, _T('-'))) = 0;
769 - error = RegOpenKeyEx(hKeyBase,keyname,0,KEY_READ,&hKey);
 792+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
770793 buffersize = regbuffersize;
771 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
772 - if(buffersize > regbuffersize)
 794+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
 795+ if (buffersize > regbuffersize)
773796 {
774797 regbuffersize = buffersize;
775 - regbuffer = (LPTSTR)realloc(regbuffer,regbuffersize);
 798+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
776799 }
777800 buffersize = regbuffersize;
778 - regbuffer[0] = regbuffer[1] = 0;
779 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
780 - regbufferpos = 0;
781 - apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(keyname) + 1)*sizeof(TCHAR));
 801+ regbuffer[0] = 0;
 802+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 803+ apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(keyname) + 1) * sizeof(TCHAR));
782804 _tcscpy(apps[appcount - 1].regkey, keyname);
783 - GetConfig(&apps[appcount-1].cfg,&apps[appcount-1].mask,keyname);
784 - apps[appcount-1].dirty = FALSE;
785 - while(1)
 805+ GetConfig(&apps[appcount - 1].cfg, &apps[appcount - 1].mask, keyname);
 806+ apps[appcount - 1].dirty = FALSE;
 807+ if ((regbuffer[0] == 0) || error != ERROR_SUCCESS)
786808 {
787 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS)
 809+ // Default icon
 810+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 811+ apps[appcount - 1].icon_shared = TRUE;
 812+ apps[appcount - 1].name = (TCHAR*)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 813+ _tcscpy(apps[appcount - 1].name, subkey);
 814+ break;
 815+ }
 816+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + _tcslen(subkey) + 2)) * sizeof(TCHAR));
 817+ _tcscpy(path, regbuffer);
 818+ _tcscpy(apps[appcount - 1].path, path);
 819+ if (installpath)
 820+ {
 821+ if (!_tcsicmp(installpath, path)) apps[appcount - 1].builtin = TRUE;
 822+ else apps[appcount - 1].builtin = FALSE;
 823+ }
 824+ _tcscat(path, _T("\\"));
 825+ _tcscat(path, subkey);
 826+ if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
 827+ {
 828+ // Default icon
 829+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 830+ apps[appcount - 1].icon_shared = TRUE;
 831+ apps[appcount - 1].name = (TCHAR*)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 832+ _tcscpy(apps[appcount - 1].name, subkey);
 833+ break;
 834+ }
 835+ // Get exe attributes
 836+ error = SHGetFileInfo(path, 0, &fileinfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_ADDOVERLAYS);
 837+ apps[appcount - 1].icon = fileinfo.hIcon;
 838+ apps[appcount - 1].icon_shared = FALSE;
 839+ verinfosize = GetFileVersionInfoSize(path, NULL);
 840+ verinfo = malloc(verinfosize);
 841+ hasname = FALSE;
 842+ if (GetFileVersionInfo(path, 0, verinfosize, verinfo))
 843+ {
 844+ if (VerQueryValue(verinfo, _T("\\VarFileInfo\\Translation"), (LPVOID*)&outbuffer, &outlen))
788845 {
789 - // Default icon
790 - apps[appcount-1].icon = LoadIcon(NULL,IDI_APPLICATION);
791 - apps[appcount-1].icon_shared = TRUE;
792 - apps[appcount-1].name = (TCHAR*)malloc((_tcslen(subkey)+1)*sizeof(TCHAR));
793 - _tcscpy(apps[appcount-1].name,subkey);
794 - break;
795 - }
796 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
797 - _tcslen(subkey) + 2))*sizeof(TCHAR));
798 - _tcscpy(path, (LPTSTR)regbuffer + regbufferpos);
799 - _tcscat(path, _T("\\"));
800 - _tcscat(path, subkey);
801 - if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
802 - {
803 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
804 - free(path);
805 - continue;
806 - }
807 - // Get exe attributes
808 - error = SHGetFileInfo(path,0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SMALLICON|SHGFI_ADDOVERLAYS);
809 - apps[appcount-1].icon = fileinfo.hIcon;
810 - apps[appcount-1].icon_shared = FALSE;
811 - verinfosize = GetFileVersionInfoSize(path,NULL);
812 - verinfo = malloc(verinfosize);
813 - hasname = FALSE;
814 - if(GetFileVersionInfo(path,0,verinfosize,verinfo))
815 - {
816 - if(VerQueryValue(verinfo,_T("\\VarFileInfo\\Translation"),(LPVOID*)&outbuffer,&outlen))
 846+ memcpy(translation, outbuffer, 4);
 847+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\FileDescription"), translation[0], translation[1]);
 848+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
817849 {
818 - memcpy(translation,outbuffer,4);
819 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\FileDescription"),translation[0],translation[1]);
820 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 850+ hasname = TRUE;
 851+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
 852+ _tcscpy(apps[appcount - 1].name, outbuffer);
 853+ }
 854+ else
 855+ {
 856+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\ProductName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 857+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
821858 {
822859 hasname = TRUE;
823 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 860+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
824861 _tcscpy(apps[appcount - 1].name, outbuffer);
825862 }
826863 else
827864 {
828 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\ProductName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
829 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 865+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\InternalName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 866+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
830867 {
831868 hasname = TRUE;
832 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 869+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
833870 _tcscpy(apps[appcount - 1].name, outbuffer);
834871 }
835 - else
836 - {
837 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\InternalName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
838 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
839 - {
840 - hasname = TRUE;
841 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
842 - _tcscpy(apps[appcount - 1].name, outbuffer);
843 - }
844 - }
845872 }
846873 }
847874 }
848 - free(path);
849 - if (!hasname)
850 - {
851 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(subkey) + 1)*sizeof(TCHAR));
852 - _tcscpy(apps[appcount - 1].name, subkey);
853 - }
854 - free(verinfo);
855 - break;
856875 }
 876+ free(path);
 877+ if (!hasname)
 878+ {
 879+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 880+ _tcscpy(apps[appcount - 1].name, subkey);
 881+ }
 882+ free(verinfo);
857883 RegCloseKey(hKey);
858884 }
859885 RegCloseKey(hKeyBase);
@@ -956,10 +982,19 @@
957983 dirty = &apps[current_app].dirty;
958984 if(current_app)
959985 {
960 - if(!_tcscmp(apps[current_app].regkey,_T("DXGLTestApp"))) EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),FALSE);
961 - else EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),TRUE);
 986+ EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), TRUE);
 987+ EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), TRUE);
 988+ SetDlgItemText(hWnd, IDC_PROFILEPATH, apps[current_app].path);
 989+ if(apps[current_app].builtin) EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), FALSE);
 990+ else EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), TRUE);
962991 }
963 - else EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),FALSE);
 992+ else
 993+ {
 994+ EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), FALSE);
 995+ EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), FALSE);
 996+ SetDlgItemText(hWnd, IDC_PROFILEPATH, _T(""));
 997+ EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), FALSE);
 998+ }
964999 // Set 3-state status
9651000 if(current_app && !tristate)
9661001 {
@@ -1142,99 +1177,107 @@
11431178 break;
11441179 case IDC_ADD:
11451180 selectedfile[0] = 0;
1146 - ZeroMemory(&filename,OPENFILENAME_SIZE_VERSION_400);
 1181+ ZeroMemory(&filename, OPENFILENAME_SIZE_VERSION_400);
11471182 filename.lStructSize = OPENFILENAME_SIZE_VERSION_400;
11481183 filename.hwndOwner = hWnd;
11491184 filename.lpstrFilter = exe_filter;
11501185 filename.lpstrFile = selectedfile;
1151 - filename.nMaxFile = MAX_PATH+1;
 1186+ filename.nMaxFile = MAX_PATH + 1;
11521187 filename.lpstrInitialDir = _T("%ProgramFiles%");
11531188 filename.lpstrTitle = _T("Select program");
11541189 filename.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
1155 - if(GetOpenFileName(&filename))
 1190+ if (GetOpenFileName(&filename))
11561191 {
1157 - DWORD err = AddApp(filename.lpstrFile,TRUE,FALSE);
1158 - if(!err)
 1192+ if (CheckProfileExists(filename.lpstrFile))
11591193 {
 1194+ MessageBox(hWnd, _T("A profile already exists for this program."),
 1195+ _T("Profile already exists"), MB_OK | MB_ICONWARNING);
 1196+ break;
 1197+ }
 1198+ DWORD err = AddApp(filename.lpstrFile, TRUE, FALSE);
 1199+ if (!err)
 1200+ {
11601201 LPTSTR newkey = MakeNewConfig(filename.lpstrFile);
1161 - LPTSTR newkey2 = (LPTSTR)malloc((_tcslen(newkey) + 15)*sizeof(TCHAR));
1162 - _tcscpy(newkey2, _T("Software\\DXGL\\"));
1163 - _tcscat(newkey2,newkey);
 1202+ LPTSTR newkey2 = (LPTSTR)malloc((_tcslen(newkey) + 24) * sizeof(TCHAR));
 1203+ _tcscpy(newkey2, _T("Software\\DXGL\\Profiles\\"));
 1204+ _tcscat(newkey2, newkey);
11641205 appcount++;
1165 - if(appcount > maxapps)
 1206+ if (appcount > maxapps)
11661207 {
11671208 maxapps += 128;
1168 - apps = (app_setting *)realloc(apps,maxapps*sizeof(app_setting));
 1209+ apps = (app_setting *)realloc(apps, maxapps * sizeof(app_setting));
11691210 }
1170 - RegOpenKeyEx(HKEY_CURRENT_USER,newkey2,0,KEY_READ,&hKey);
1171 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
 1211+ RegOpenKeyEx(HKEY_CURRENT_USER, newkey2, 0, KEY_READ, &hKey);
 1212+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
11721213 regbuffer = (LPTSTR)malloc(buffersize);
1173 - regbuffer[0] = regbuffer[1] = 0;
1174 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
1175 - regbufferpos = 0;
1176 - apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
 1214+ regbuffer[0] = 0;
 1215+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1216+ apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
11771217 _tcscpy(apps[appcount - 1].regkey, newkey);
1178 - GetConfig(&apps[appcount-1].cfg,&apps[appcount-1].mask,newkey);
1179 - apps[appcount-1].dirty = FALSE;
 1218+ GetConfig(&apps[appcount - 1].cfg, &apps[appcount - 1].mask, newkey);
 1219+ apps[appcount - 1].dirty = FALSE;
11801220 free(newkey2);
1181 - while(1)
 1221+ if ((regbuffer[0] == 0) || error != ERROR_SUCCESS)
11821222 {
1183 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS)
1184 - {
1185 - // Default icon
1186 - apps[appcount-1].icon = LoadIcon(NULL,IDI_APPLICATION);
1187 - apps[appcount-1].icon_shared = TRUE;
1188 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
1189 - _tcscpy(apps[appcount - 1].name, newkey);
1190 - break;
1191 - }
1192 - if (_tcsrchr(newkey, _T('-'))) *(_tcsrchr(newkey, _T('-'))) = 0;
1193 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
1194 - _tcslen(newkey) + 2))*sizeof(TCHAR));
1195 - _tcscpy(path, (LPTSTR)regbuffer + regbufferpos);
1196 - _tcscat(path, _T("\\"));
1197 - _tcscat(path, newkey);
1198 - if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
1199 - {
1200 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1201 - free(path);
1202 - continue;
1203 - }
 1223+ // Default icon
 1224+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1225+ apps[appcount - 1].icon_shared = TRUE;
 1226+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
 1227+ _tcscpy(apps[appcount - 1].name, newkey);
 1228+ break;
 1229+ }
 1230+ if (_tcsrchr(newkey, _T('-'))) *(_tcsrchr(newkey, _T('-'))) = 0;
 1231+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + _tcslen(newkey) + 2)) * sizeof(TCHAR));
 1232+ _tcscpy(path, regbuffer);
 1233+ _tcscpy(apps[appcount - 1].path, path);
 1234+ _tcscat(path, _T("\\"));
 1235+ _tcscat(path, newkey);
 1236+ if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
 1237+ {
 1238+ // Default icon
 1239+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1240+ apps[appcount - 1].icon_shared = TRUE;
 1241+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
 1242+ _tcscpy(apps[appcount - 1].name, newkey);
 1243+ break;
 1244+ }
 1245+ else
 1246+ {
12041247 // Get exe attributes
1205 - error = SHGetFileInfo(path,0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SMALLICON|SHGFI_ADDOVERLAYS);
1206 - apps[appcount-1].icon = fileinfo.hIcon;
1207 - apps[appcount-1].icon_shared = FALSE;
1208 - verinfosize = GetFileVersionInfoSize(path,NULL);
 1248+ error = SHGetFileInfo(path, 0, &fileinfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_ADDOVERLAYS);
 1249+ apps[appcount - 1].icon = fileinfo.hIcon;
 1250+ apps[appcount - 1].icon_shared = FALSE;
 1251+ verinfosize = GetFileVersionInfoSize(path, NULL);
12091252 verinfo = malloc(verinfosize);
12101253 hasname = FALSE;
1211 - if(GetFileVersionInfo(path,0,verinfosize,verinfo))
 1254+ if (GetFileVersionInfo(path, 0, verinfosize, verinfo))
12121255 {
1213 - if(VerQueryValue(verinfo,_T("\\VarFileInfo\\Translation"),(LPVOID*)&outbuffer,&outlen))
 1256+ if (VerQueryValue(verinfo, _T("\\VarFileInfo\\Translation"), (LPVOID*)&outbuffer, &outlen))
12141257 {
1215 - memcpy(translation,outbuffer,4);
1216 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\FileDescription"),translation[0],translation[1]);
1217 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1258+ memcpy(translation, outbuffer, 4);
 1259+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\FileDescription"), translation[0], translation[1]);
 1260+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
12181261 {
12191262 hasname = TRUE;
1220 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1263+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
12211264 _tcscpy(apps[appcount - 1].name, outbuffer);
12221265 }
12231266 else
12241267 {
1225 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\ProductName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1226 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1268+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\ProductName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1269+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
12271270 {
12281271 hasname = TRUE;
1229 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1272+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
12301273 _tcscpy(apps[appcount - 1].name, outbuffer);
12311274 }
12321275 else
12331276 {
1234 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\InternalName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1235 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1277+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\InternalName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1278+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
12361279 {
12371280 hasname = TRUE;
1238 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1281+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
12391282 _tcscpy(apps[appcount - 1].name, outbuffer);
12401283 }
12411284 }
@@ -1243,53 +1286,43 @@
12441287 }
12451288 if (!hasname)
12461289 {
1247 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
 1290+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
12481291 _tcscpy(apps[appcount - 1].name, newkey);
12491292 }
12501293 free(verinfo);
12511294 free(path);
1252 - break;
12531295 }
1254 - SendDlgItemMessage(hWnd,IDC_APPS,LB_ADDSTRING,0,(LPARAM)apps[appcount-1].name);
 1296+ SendDlgItemMessage(hWnd, IDC_APPS, LB_SETCURSEL,
 1297+ SendDlgItemMessage(hWnd, IDC_APPS, LB_ADDSTRING, 0, (LPARAM)apps[appcount - 1].name), 0);
 1298+ SendMessage(hWnd, WM_COMMAND, IDC_APPS + 0x10000, 0);
12551299 RegCloseKey(hKey);
12561300 free(regbuffer);
12571301 }
12581302 }
1259 -
12601303 break;
12611304 case IDC_REMOVE:
12621305 if(MessageBox(hWnd,_T("Do you want to delete the selected application profile and remove DXGL from its installation folder(s)?"),
12631306 _T("Confirmation"),MB_YESNO|MB_ICONQUESTION) != IDYES) return FALSE;
12641307 regpath = (LPTSTR)malloc((_tcslen(apps[current_app].regkey) + 15)*sizeof(TCHAR));
1265 - _tcscpy(regpath, _T("Software\\DXGL\\"));
 1308+ _tcscpy(regpath, _T("Software\\DXGL\\Profiles\\"));
12661309 _tcscat(regpath, apps[current_app].regkey);
12671310 regkey = (LPTSTR)malloc(_tcslen(apps[current_app].regkey));
12681311 _tcscpy(regkey, apps[current_app].regkey);
12691312 RegOpenKeyEx(HKEY_CURRENT_USER,regpath,0,KEY_READ,&hKey);
1270 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
 1313+ RegQueryValueEx(hKey,_T("InstallPath"),NULL,NULL,NULL,&buffersize);
12711314 regbuffer = (LPTSTR)malloc(buffersize);
1272 - regbuffer[0] = regbuffer[1] = 0;
1273 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
1274 - regbufferpos = 0;
 1315+ regbuffer[0] = 0;
12751316 failed = FALSE;
1276 - while(1)
 1317+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1318+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + 12)) * sizeof(TCHAR));
 1319+ _tcscpy(path, regbuffer);
 1320+ _tcscat(path, _T("\\ddraw.dll"));
 1321+ if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
12771322 {
1278 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS) break;
1279 - if (_tcsrchr(regkey, _T('-'))) *(_tcsrchr(regkey, _T('-'))) = 0;
1280 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
1281 - 12))*sizeof(TCHAR));
1282 - _tcscpy(path, regbuffer + regbufferpos);
1283 - _tcscat(path, _T("\\ddraw.dll"));
1284 - if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
1285 - {
1286 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1287 - free(path);
1288 - continue;
1289 - }
1290 - if(DelApp(path,FALSE)) failed = TRUE;
1291 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1292 - free(path);
 1323+ if (DelApp(path, FALSE)) failed = TRUE;
12931324 }
 1325+ free(path);
 1326+ free(regbuffer);
12941327 RegCloseKey(hKey);
12951328 if(!failed)
12961329 {
@@ -1304,6 +1337,8 @@
13051338 appcount--;
13061339 }
13071340 SendDlgItemMessage(hWnd,IDC_APPS,LB_DELETESTRING,current_app,0);
 1341+ SendDlgItemMessage(hWnd, IDC_APPS, LB_SETCURSEL, 0, 0);
 1342+ SendMessage(hWnd, WM_COMMAND, IDC_APPS + 0x10000, 0);
13081343 break;
13091344 }
13101345 break;
@@ -1311,8 +1346,195 @@
13121347 return FALSE;
13131348 }
13141349
1315 -int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
 1350+void UpgradeDXGL()
13161351 {
 1352+ UpgradeConfig();
 1353+ HKEY hKeyBase;
 1354+ HKEY hKey;
 1355+ DWORD keysize, keysize2;
 1356+ int i = 0;
 1357+ LONG error;
 1358+ LPTSTR keyname;
 1359+ DWORD sizeout;
 1360+ DWORD buffersize;
 1361+ DWORD regbuffersize;
 1362+ LPTSTR regbuffer;
 1363+ BOOL installed = FALSE;
 1364+ BOOL dxgl_installdir = FALSE;
 1365+ BOOL old_dxgl = FALSE;
 1366+ HKEY hKeyInstall;
 1367+ TCHAR installpath[MAX_PATH + 1];
 1368+ TCHAR srcpath[MAX_PATH + 1];
 1369+ TCHAR destpath[MAX_PATH + 1];
 1370+ regbuffersize = 1024;
 1371+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 1372+ RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, NULL, 0, KEY_READ, NULL, &hKeyBase, NULL);
 1373+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1374+ keysize++;
 1375+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
 1376+ keysize2 = keysize;
 1377+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
 1378+ if (error == ERROR_SUCCESS)
 1379+ {
 1380+ dxgl_installdir = TRUE;
 1381+ error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
 1382+ if (error == ERROR_SUCCESS) installed = TRUE;
 1383+ }
 1384+ if (hKeyInstall) RegCloseKey(hKeyInstall);
 1385+ if (!installed)
 1386+ {
 1387+ GetModuleFileName(NULL, installpath, MAX_PATH + 1);
 1388+ }
 1389+ if (dxgl_installdir) _tcscat(installpath, _T("\\"));
 1390+ else (_tcsrchr(installpath, _T('\\')))[1] = 0;
 1391+ _tcsncpy(srcpath, installpath, MAX_PATH + 1);
 1392+ _tcscat(srcpath, _T("ddraw.dll"));
 1393+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1394+ {
 1395+ keysize2 = keysize;
 1396+ i++;
 1397+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
 1398+ buffersize = regbuffersize;
 1399+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
 1400+ if (buffersize > regbuffersize)
 1401+ {
 1402+ regbuffersize = buffersize;
 1403+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
 1404+ }
 1405+ buffersize = regbuffersize;
 1406+ regbuffer[0] = 0;
 1407+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1408+ if (regbuffer[0] != 0)
 1409+ {
 1410+ _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
 1411+ _tcscat(destpath, _T("\\"));
 1412+ _tcscat(destpath, _T("ddraw.dll"));
 1413+ error = CopyFile(srcpath, destpath, TRUE);
 1414+ if (!error)
 1415+ {
 1416+ error = GetLastError();
 1417+ if (error == ERROR_FILE_EXISTS)
 1418+ {
 1419+ old_dxgl = FALSE;
 1420+ HMODULE hmod = LoadLibrary(destpath);
 1421+ if (hmod)
 1422+ {
 1423+ if (GetProcAddress(hmod, "IsDXGLDDraw")) old_dxgl = TRUE;
 1424+ FreeLibrary(hmod);
 1425+ }
 1426+ if (old_dxgl) CopyFile(srcpath, destpath, FALSE);
 1427+ }
 1428+ }
 1429+ }
 1430+ RegCloseKey(hKey);
 1431+ }
 1432+ free(regbuffer);
 1433+ free(keyname);
 1434+ RegCloseKey(hKeyBase);
 1435+}
 1436+
 1437+// '0' for keep, '1' for remove, personal settings
 1438+void UninstallDXGL(TCHAR uninstall)
 1439+{
 1440+ HKEY hKeyBase;
 1441+ HKEY hKey;
 1442+ DWORD keysize, keysize2;
 1443+ LONG error;
 1444+ LPTSTR keyname;
 1445+ DWORD sizeout;
 1446+ DWORD buffersize;
 1447+ DWORD regbuffersize;
 1448+ LPTSTR regbuffer;
 1449+ BOOL installed = FALSE;
 1450+ BOOL dxgl_installdir = FALSE;
 1451+ BOOL old_dxgl = FALSE;
 1452+ HKEY hKeyInstall;
 1453+ TCHAR installpath[MAX_PATH + 1];
 1454+ TCHAR srcpath[MAX_PATH + 1];
 1455+ TCHAR destpath[MAX_PATH + 1];
 1456+ int i = 0;
 1457+ UpgradeConfig(); // Just to make sure the registry format is correct
 1458+ regbuffersize = 1024;
 1459+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 1460+ error = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, KEY_ALL_ACCESS, &hKeyBase);
 1461+ if (error != ERROR_SUCCESS) return;
 1462+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1463+ keysize++;
 1464+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
 1465+ keysize2 = keysize;
 1466+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
 1467+ if (error == ERROR_SUCCESS)
 1468+ {
 1469+ dxgl_installdir = TRUE;
 1470+ error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
 1471+ if (error == ERROR_SUCCESS) installed = TRUE;
 1472+ }
 1473+ if (hKeyInstall) RegCloseKey(hKeyInstall);
 1474+ if (!installed)
 1475+ {
 1476+ GetModuleFileName(NULL, installpath, MAX_PATH + 1);
 1477+ }
 1478+ if (dxgl_installdir) _tcscat(installpath, _T("\\"));
 1479+ else (_tcsrchr(installpath, _T('\\')))[1] = 0;
 1480+ _tcsncpy(srcpath, installpath, MAX_PATH + 1);
 1481+ _tcscat(srcpath, _T("ddraw.dll"));
 1482+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1483+ {
 1484+ keysize2 = keysize;
 1485+ i++;
 1486+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
 1487+ buffersize = regbuffersize;
 1488+ if (buffersize > regbuffersize)
 1489+ {
 1490+ regbuffersize = buffersize;
 1491+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
 1492+ }
 1493+ buffersize = regbuffersize;
 1494+ regbuffer[0] = 0;
 1495+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1496+ if (regbuffer[0] != 0)
 1497+ {
 1498+ _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
 1499+ _tcscat(destpath, _T("\\"));
 1500+ _tcscat(destpath, _T("ddraw.dll"));
 1501+ if (GetFileAttributes(destpath) != INVALID_FILE_ATTRIBUTES)
 1502+ {
 1503+ old_dxgl = FALSE;
 1504+ HMODULE hmod = LoadLibrary(destpath);
 1505+ if (hmod)
 1506+ {
 1507+ if (GetProcAddress(hmod, "IsDXGLDDraw")) old_dxgl = TRUE;
 1508+ FreeLibrary(hmod);
 1509+ }
 1510+ if (_tcscmp(srcpath, destpath))
 1511+ {
 1512+ if (old_dxgl) DeleteFile(destpath);
 1513+ }
 1514+ }
 1515+ }
 1516+ RegCloseKey(hKey);
 1517+ }
 1518+ free(regbuffer);
 1519+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1520+ keysize++;
 1521+ if (uninstall == '1') // Delete user settings
 1522+ {
 1523+ while (RegEnumKeyEx(hKeyBase, 0, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1524+ {
 1525+ keysize2 = keysize;
 1526+ i++;
 1527+ RegDeleteKey(hKeyBase, keyname);
 1528+ }
 1529+ RegCloseKey(hKeyBase);
 1530+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"));
 1531+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL\\Global"));
 1532+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL"));
 1533+ }
 1534+ else RegCloseKey(hKeyBase);
 1535+}
 1536+
 1537+int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
 1538+{
13171539 INITCOMMONCONTROLSEX icc;
13181540 HMODULE comctl32;
13191541 BOOL(WINAPI *iccex)(LPINITCOMMONCONTROLSEX lpInitCtrls);
@@ -1319,6 +1541,16 @@
13201542 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
13211543 GetVersionEx(&osver);
13221544 CoInitialize(NULL);
 1545+ if (!_tcsnicmp(lpCmdLine, _T("upgrade"), 7))
 1546+ {
 1547+ UpgradeDXGL();
 1548+ return 0;
 1549+ }
 1550+ if (!_tcsnicmp(lpCmdLine, _T("uninstall "), 10))
 1551+ {
 1552+ UninstallDXGL(lpCmdLine[10]);
 1553+ return 0;
 1554+ }
13231555 if(!_tcsnicmp(lpCmdLine,_T("install "),8))
13241556 {
13251557 return AddApp(lpCmdLine+8,TRUE,TRUE);
@@ -1337,6 +1569,7 @@
13381570 GetModuleFileName(NULL,hlppath,MAX_PATH);
13391571 GetDirFromPath(hlppath);
13401572 _tcscat(hlppath,_T("\\dxgl.chm"));
 1573+ // Message for when transitioning to the new config UI
13411574 /*MessageBox(NULL, _T("This version of DXGL Config is deprecated and no longer supported. Some options may no longer work correctly."),
13421575 _T("Notice"), MB_OK | MB_ICONWARNING);*/
13431576 DialogBox(hInstance,MAKEINTRESOURCE(IDD_DXGLCFG),0,(DLGPROC)DXGLCfgCallback);
Index: dxglcfg/dxglcfg.rc
@@ -73,6 +73,8 @@
7474 COMBOBOX IDC_TEXTUREFORMAT, 195, 205, 102, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
7575 LTEXT "Texture access method", IDC_STATIC, 299, 195, 76, 8, SS_LEFT
7676 COMBOBOX IDC_TEXUPLOAD, 299, 205, 100, 30, CBS_DROPDOWNLIST | CBS_HASSTRINGS
 77+ EDITTEXT IDC_PROFILEPATH, 215, 227, 184, 14, NOT WS_BORDER | ES_AUTOHSCROLL | ES_READONLY, WS_EX_LEFT
 78+ LTEXT "Path:", IDC_PATHLABEL, 196, 227, 18, 9, SS_LEFT, WS_EX_LEFT
7779 }
7880
7981
Index: dxglcfg/resource.h
@@ -45,3 +45,5 @@
4646 #define IDC_TEXUPLOAD 1059
4747 #define IDC_ASPECT 1061
4848 #define IDC_DPISCALE 1063
 49+#define IDC_PATHLABEL 1064
 50+#define IDC_PROFILEPATH 1065
Index: dxglcfg2/dxglcfg2.c
@@ -1,5 +1,5 @@
22 // DXGL
3 -// Copyright (C) 2011-2015 William Feely
 3+// Copyright (C) 2011-2016 William Feely
44
55 // This library is free software; you can redistribute it and/or
66 // modify it under the terms of the GNU Lesser General Public
@@ -32,6 +32,7 @@
3333 #include <Uxtheme.h>
3434 #include <Vsstyle.h>
3535 #include "resource.h"
 36+#include "../cfgmgr/LibSha256.h"
3637 #include "../cfgmgr/cfgmgr.h"
3738 #include <gl/GL.h>
3839
@@ -74,6 +75,8 @@
7576 BOOL dirty;
7677 DXGLCFG cfg;
7778 DXGLCFG mask;
 79+ TCHAR path[MAX_PATH];
 80+ BOOL builtin;
7881 } app_setting;
7982
8083 TCHAR exe_filter[] = _T("Program Files\0*.exe\0All Files\0*.*\0\0");
@@ -630,7 +633,6 @@
631634 LPTSTR keyname;
632635 LPTSTR regbuffer;
633636 DWORD regbuffersize;
634 - DWORD regbufferpos;
635637 DWORD buffersize;
636638 LONG error;
637639 TCHAR buffer[64];
@@ -655,6 +657,7 @@
656658 LPTSTR regpath;
657659 LPTSTR regkey;
658660 BOOL failed;
 661+ LPTSTR installpath;
659662 RECT r;
660663 NMHDR *nm;
661664 int newtab;
@@ -677,6 +680,7 @@
678681 apps[0].dirty = FALSE;
679682 apps[0].icon = LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_STAR));
680683 apps[0].icon_shared = TRUE;
 684+ apps[0].path[0] = 0;
681685 SetClassLong(hWnd,GCL_HICON,(LONG)LoadIcon(hinstance,(LPCTSTR)IDI_DXGL));
682686 SetClassLong(hWnd,GCL_HICONSM,(LONG)LoadIcon(hinstance,(LPCTSTR)IDI_DXGLSM));
683687 // create temporary gl context to get AA and AF settings.
@@ -981,119 +985,139 @@
982986 _tcscpy(buffer, _T("Windows AppCompat"));
983987 SendDlgItemMessage(hTabs[0],IDC_DPISCALE,CB_ADDSTRING,2,(LPARAM)buffer);
984988 SendDlgItemMessage(hTabs[0],IDC_DPISCALE,CB_SETCURSEL,cfg->DPIScale,0);
 989+ //EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), FALSE);
 990+ //EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), FALSE);
 991+ // Check install path
 992+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKey);
 993+ if (error == ERROR_SUCCESS)
 994+ {
 995+ if (RegQueryValueEx(hKey, _T("InstallDir"), NULL, NULL, NULL, &keysize) == ERROR_SUCCESS)
 996+ {
 997+ installpath = (LPTSTR)malloc(keysize);
 998+ error = RegQueryValueEx(hKey, _T("InstallDir"), NULL, NULL, installpath, &keysize);
 999+ if (error != ERROR_SUCCESS)
 1000+ {
 1001+ free(installpath);
 1002+ installpath = NULL;
 1003+ }
 1004+ }
 1005+ RegCloseKey(hKey);
 1006+ }
 1007+ hKey = NULL;
9851008 // Add installed programs
9861009 current_app = 1;
9871010 appcount = 1;
9881011 regbuffersize = 1024;
989 - regbuffer = (LPTSTR)malloc(regbuffersize*sizeof(TCHAR));
990 - RegCreateKeyEx(HKEY_CURRENT_USER,_T("Software\\DXGL"),0,NULL,0,KEY_READ,NULL,&hKeyBase,NULL);
991 - RegQueryInfoKey(hKeyBase,NULL,NULL,NULL,NULL,&keysize,NULL,NULL,NULL,NULL,NULL,NULL);
 1012+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 1013+ RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, NULL, 0, KEY_READ, NULL, &hKeyBase, NULL);
 1014+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
9921015 keysize++;
993 - keyname = (LPTSTR)malloc(keysize*sizeof(TCHAR));
 1016+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
9941017 keysize2 = keysize;
9951018 i = 0;
996 - while(RegEnumKeyEx(hKeyBase,i,keyname,&keysize2,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
 1019+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
9971020 {
9981021 keysize2 = keysize;
9991022 i++;
1000 - if(!_tcscmp(keyname,_T("Global"))) continue;
10011023 appcount++;
1002 - if(appcount > maxapps)
 1024+ if (appcount > maxapps)
10031025 {
10041026 maxapps += 128;
1005 - apps = (app_setting *)realloc(apps,maxapps*sizeof(app_setting));
 1027+ apps = (app_setting *)realloc(apps, maxapps * sizeof(app_setting));
10061028 }
1007 - if(!_tcscmp(keyname,_T("DXGLTestApp"))) _tcscpy(subkey,_T("dxgltest.exe-0"));
1008 - else _tcscpy(subkey,keyname);
 1029+ _tcscpy(subkey, keyname);
10091030 if (_tcsrchr(subkey, _T('-'))) *(_tcsrchr(subkey, _T('-'))) = 0;
1010 - error = RegOpenKeyEx(hKeyBase,keyname,0,KEY_READ,&hKey);
 1031+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
10111032 buffersize = regbuffersize;
1012 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
1013 - if(buffersize > regbuffersize)
 1033+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
 1034+ if (buffersize > regbuffersize)
10141035 {
10151036 regbuffersize = buffersize;
1016 - regbuffer = (LPTSTR)realloc(regbuffer,regbuffersize);
 1037+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
10171038 }
10181039 buffersize = regbuffersize;
1019 - regbuffer[0] = regbuffer[1] = 0;
1020 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
1021 - regbufferpos = 0;
1022 - apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(keyname) + 1)*sizeof(TCHAR));
 1040+ regbuffer[0] = 0;
 1041+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1042+ apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(keyname) + 1) * sizeof(TCHAR));
10231043 _tcscpy(apps[appcount - 1].regkey, keyname);
1024 - GetConfig(&apps[appcount-1].cfg,&apps[appcount-1].mask,keyname);
1025 - apps[appcount-1].dirty = FALSE;
1026 - while(1)
 1044+ GetConfig(&apps[appcount - 1].cfg, &apps[appcount - 1].mask, keyname);
 1045+ apps[appcount - 1].dirty = FALSE;
 1046+ if ((regbuffer[0] == 0) || error != ERROR_SUCCESS)
10271047 {
1028 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS)
 1048+ // Default icon
 1049+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1050+ apps[appcount - 1].icon_shared = TRUE;
 1051+ apps[appcount - 1].name = (TCHAR*)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 1052+ _tcscpy(apps[appcount - 1].name, subkey);
 1053+ break;
 1054+ }
 1055+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + _tcslen(subkey) + 2)) * sizeof(TCHAR));
 1056+ _tcscpy(path, regbuffer);
 1057+ _tcscpy(apps[appcount - 1].path, path);
 1058+ if (installpath)
 1059+ {
 1060+ if (!_tcsicmp(installpath, path)) apps[appcount - 1].builtin = TRUE;
 1061+ else apps[appcount - 1].builtin = FALSE;
 1062+ }
 1063+ _tcscat(path, _T("\\"));
 1064+ _tcscat(path, subkey);
 1065+ if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
 1066+ {
 1067+ // Default icon
 1068+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1069+ apps[appcount - 1].icon_shared = TRUE;
 1070+ apps[appcount - 1].name = (TCHAR*)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 1071+ _tcscpy(apps[appcount - 1].name, subkey);
 1072+ break;
 1073+ }
 1074+ // Get exe attributes
 1075+ error = SHGetFileInfo(path, 0, &fileinfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_ADDOVERLAYS);
 1076+ apps[appcount - 1].icon = fileinfo.hIcon;
 1077+ apps[appcount - 1].icon_shared = FALSE;
 1078+ verinfosize = GetFileVersionInfoSize(path, NULL);
 1079+ verinfo = malloc(verinfosize);
 1080+ hasname = FALSE;
 1081+ if (GetFileVersionInfo(path, 0, verinfosize, verinfo))
 1082+ {
 1083+ if (VerQueryValue(verinfo, _T("\\VarFileInfo\\Translation"), (LPVOID*)&outbuffer, &outlen))
10291084 {
1030 - // Default icon
1031 - apps[appcount-1].icon = LoadIcon(NULL,IDI_APPLICATION);
1032 - apps[appcount-1].icon_shared = TRUE;
1033 - apps[appcount-1].name = (TCHAR*)malloc((_tcslen(subkey)+1)*sizeof(TCHAR));
1034 - _tcscpy(apps[appcount-1].name,subkey);
1035 - break;
1036 - }
1037 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
1038 - _tcslen(subkey) + 2))*sizeof(TCHAR));
1039 - _tcscpy(path, (LPTSTR)regbuffer + regbufferpos);
1040 - _tcscat(path, _T("\\"));
1041 - _tcscat(path, subkey);
1042 - if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
1043 - {
1044 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1045 - free(path);
1046 - continue;
1047 - }
1048 - // Get exe attributes
1049 - error = SHGetFileInfo(path,0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SMALLICON|SHGFI_ADDOVERLAYS);
1050 - apps[appcount-1].icon = fileinfo.hIcon;
1051 - apps[appcount-1].icon_shared = FALSE;
1052 - verinfosize = GetFileVersionInfoSize(path,NULL);
1053 - verinfo = malloc(verinfosize);
1054 - hasname = FALSE;
1055 - if(GetFileVersionInfo(path,0,verinfosize,verinfo))
1056 - {
1057 - if(VerQueryValue(verinfo,_T("\\VarFileInfo\\Translation"),(LPVOID*)&outbuffer,&outlen))
 1085+ memcpy(translation, outbuffer, 4);
 1086+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\FileDescription"), translation[0], translation[1]);
 1087+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
10581088 {
1059 - memcpy(translation,outbuffer,4);
1060 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\FileDescription"),translation[0],translation[1]);
1061 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1089+ hasname = TRUE;
 1090+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
 1091+ _tcscpy(apps[appcount - 1].name, outbuffer);
 1092+ }
 1093+ else
 1094+ {
 1095+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\ProductName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1096+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
10621097 {
10631098 hasname = TRUE;
1064 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1099+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
10651100 _tcscpy(apps[appcount - 1].name, outbuffer);
10661101 }
10671102 else
10681103 {
1069 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\ProductName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1070 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1104+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\InternalName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1105+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
10711106 {
10721107 hasname = TRUE;
1073 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1108+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
10741109 _tcscpy(apps[appcount - 1].name, outbuffer);
10751110 }
1076 - else
1077 - {
1078 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\InternalName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1079 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
1080 - {
1081 - hasname = TRUE;
1082 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
1083 - _tcscpy(apps[appcount - 1].name, outbuffer);
1084 - }
1085 - }
10861111 }
10871112 }
10881113 }
1089 - free(path);
1090 - if (!hasname)
1091 - {
1092 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(subkey) + 1)*sizeof(TCHAR));
1093 - _tcscpy(apps[appcount - 1].name, subkey);
1094 - }
1095 - free(verinfo);
1096 - break;
10971114 }
 1115+ free(path);
 1116+ if (!hasname)
 1117+ {
 1118+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(subkey) + 1) * sizeof(TCHAR));
 1119+ _tcscpy(apps[appcount - 1].name, subkey);
 1120+ }
 1121+ free(verinfo);
10981122 RegCloseKey(hKey);
10991123 }
11001124 RegCloseKey(hKeyBase);
@@ -1215,13 +1239,21 @@
12161240 cfg = &apps[current_app].cfg;
12171241 cfgmask = &apps[current_app].mask;
12181242 dirty = &apps[current_app].dirty;
1219 - if(current_app)
 1243+ if (current_app)
12201244 {
1221 - if(!_tcscmp(apps[current_app].regkey,_T("DXGLTestApp"))) EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),FALSE);
1222 - else EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),TRUE);
 1245+// EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), TRUE);
 1246+// EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), TRUE);
 1247+// SetDlgItemText(hWnd, IDC_PROFILEPATH, apps[current_app].path);
 1248+ EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), TRUE);
12231249 }
1224 - else EnableWindow(GetDlgItem(hWnd,IDC_REMOVE),FALSE);
1225 -/* // Set 3-state status
 1250+ else
 1251+ {
 1252+// EnableWindow(GetDlgItem(hWnd, IDC_PATHLABEL), FALSE);
 1253+// EnableWindow(GetDlgItem(hWnd, IDC_PROFILEPATH), FALSE);
 1254+// SetDlgItemText(hWnd, IDC_PROFILEPATH, _T(""));
 1255+ EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), FALSE);
 1256+ }
 1257+ /* // Set 3-state status
12261258 if(current_app && !tristate)
12271259 {
12281260 tristate = TRUE;
@@ -1394,99 +1426,107 @@
13951427 break;*/
13961428 case IDC_ADD:
13971429 selectedfile[0] = 0;
1398 - ZeroMemory(&filename,OPENFILENAME_SIZE_VERSION_400);
 1430+ ZeroMemory(&filename, OPENFILENAME_SIZE_VERSION_400);
13991431 filename.lStructSize = OPENFILENAME_SIZE_VERSION_400;
14001432 filename.hwndOwner = hWnd;
14011433 filename.lpstrFilter = exe_filter;
14021434 filename.lpstrFile = selectedfile;
1403 - filename.nMaxFile = MAX_PATH+1;
 1435+ filename.nMaxFile = MAX_PATH + 1;
14041436 filename.lpstrInitialDir = _T("%ProgramFiles%");
14051437 filename.lpstrTitle = _T("Select program");
14061438 filename.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
1407 - if(GetOpenFileName(&filename))
 1439+ if (GetOpenFileName(&filename))
14081440 {
1409 - DWORD err = AddApp(filename.lpstrFile,TRUE,FALSE);
1410 - if(!err)
 1441+ if (CheckProfileExists(filename.lpstrFile))
14111442 {
 1443+ MessageBox(hWnd, _T("A profile already exists for this program."),
 1444+ _T("Profile already exists"), MB_OK | MB_ICONWARNING);
 1445+ break;
 1446+ }
 1447+ DWORD err = AddApp(filename.lpstrFile, TRUE, FALSE);
 1448+ if (!err)
 1449+ {
14121450 LPTSTR newkey = MakeNewConfig(filename.lpstrFile);
1413 - LPTSTR newkey2 = (LPTSTR)malloc((_tcslen(newkey) + 15)*sizeof(TCHAR));
1414 - _tcscpy(newkey2, _T("Software\\DXGL\\"));
1415 - _tcscat(newkey2,newkey);
 1451+ LPTSTR newkey2 = (LPTSTR)malloc((_tcslen(newkey) + 24) * sizeof(TCHAR));
 1452+ _tcscpy(newkey2, _T("Software\\DXGL\\Profiles\\"));
 1453+ _tcscat(newkey2, newkey);
14161454 appcount++;
1417 - if(appcount > maxapps)
 1455+ if (appcount > maxapps)
14181456 {
14191457 maxapps += 128;
1420 - apps = (app_setting *)realloc(apps,maxapps*sizeof(app_setting));
 1458+ apps = (app_setting *)realloc(apps, maxapps * sizeof(app_setting));
14211459 }
1422 - RegOpenKeyEx(HKEY_CURRENT_USER,newkey2,0,KEY_READ,&hKey);
1423 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
 1460+ RegOpenKeyEx(HKEY_CURRENT_USER, newkey2, 0, KEY_READ, &hKey);
 1461+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
14241462 regbuffer = (LPTSTR)malloc(buffersize);
1425 - regbuffer[0] = regbuffer[1] = 0;
1426 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
1427 - regbufferpos = 0;
1428 - apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
 1463+ regbuffer[0] = 0;
 1464+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1465+ apps[appcount - 1].regkey = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
14291466 _tcscpy(apps[appcount - 1].regkey, newkey);
1430 - GetConfig(&apps[appcount-1].cfg,&apps[appcount-1].mask,newkey);
1431 - apps[appcount-1].dirty = FALSE;
 1467+ GetConfig(&apps[appcount - 1].cfg, &apps[appcount - 1].mask, newkey);
 1468+ apps[appcount - 1].dirty = FALSE;
14321469 free(newkey2);
1433 - while(1)
 1470+ if ((regbuffer[0] == 0) || error != ERROR_SUCCESS)
14341471 {
1435 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS)
1436 - {
1437 - // Default icon
1438 - apps[appcount-1].icon = LoadIcon(NULL,IDI_APPLICATION);
1439 - apps[appcount-1].icon_shared = TRUE;
1440 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
1441 - _tcscpy(apps[appcount - 1].name, newkey);
1442 - break;
1443 - }
1444 - if (_tcsrchr(newkey, _T('-'))) *(_tcsrchr(newkey, _T('-'))) = 0;
1445 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
1446 - _tcslen(newkey) + 2))*sizeof(TCHAR));
1447 - _tcscpy(path, (LPTSTR)regbuffer + regbufferpos);
1448 - _tcscat(path, _T("\\"));
1449 - _tcscat(path, newkey);
1450 - if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
1451 - {
1452 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1453 - free(path);
1454 - continue;
1455 - }
 1472+ // Default icon
 1473+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1474+ apps[appcount - 1].icon_shared = TRUE;
 1475+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
 1476+ _tcscpy(apps[appcount - 1].name, newkey);
 1477+ break;
 1478+ }
 1479+ if (_tcsrchr(newkey, _T('-'))) *(_tcsrchr(newkey, _T('-'))) = 0;
 1480+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + _tcslen(newkey) + 2)) * sizeof(TCHAR));
 1481+ _tcscpy(path, regbuffer);
 1482+ _tcscpy(apps[appcount - 1].path, path);
 1483+ _tcscat(path, _T("\\"));
 1484+ _tcscat(path, newkey);
 1485+ if (GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
 1486+ {
 1487+ // Default icon
 1488+ apps[appcount - 1].icon = LoadIcon(NULL, IDI_APPLICATION);
 1489+ apps[appcount - 1].icon_shared = TRUE;
 1490+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
 1491+ _tcscpy(apps[appcount - 1].name, newkey);
 1492+ break;
 1493+ }
 1494+ else
 1495+ {
14561496 // Get exe attributes
1457 - error = SHGetFileInfo(path,0,&fileinfo,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SMALLICON|SHGFI_ADDOVERLAYS);
1458 - apps[appcount-1].icon = fileinfo.hIcon;
1459 - apps[appcount-1].icon_shared = FALSE;
1460 - verinfosize = GetFileVersionInfoSize(path,NULL);
 1497+ error = SHGetFileInfo(path, 0, &fileinfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_ADDOVERLAYS);
 1498+ apps[appcount - 1].icon = fileinfo.hIcon;
 1499+ apps[appcount - 1].icon_shared = FALSE;
 1500+ verinfosize = GetFileVersionInfoSize(path, NULL);
14611501 verinfo = malloc(verinfosize);
14621502 hasname = FALSE;
1463 - if(GetFileVersionInfo(path,0,verinfosize,verinfo))
 1503+ if (GetFileVersionInfo(path, 0, verinfosize, verinfo))
14641504 {
1465 - if(VerQueryValue(verinfo,_T("\\VarFileInfo\\Translation"),(LPVOID*)&outbuffer,&outlen))
 1505+ if (VerQueryValue(verinfo, _T("\\VarFileInfo\\Translation"), (LPVOID*)&outbuffer, &outlen))
14661506 {
1467 - memcpy(translation,outbuffer,4);
1468 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\FileDescription"),translation[0],translation[1]);
1469 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1507+ memcpy(translation, outbuffer, 4);
 1508+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\FileDescription"), translation[0], translation[1]);
 1509+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
14701510 {
14711511 hasname = TRUE;
1472 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1512+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
14731513 _tcscpy(apps[appcount - 1].name, outbuffer);
14741514 }
14751515 else
14761516 {
1477 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\ProductName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1478 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1517+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\ProductName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1518+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
14791519 {
14801520 hasname = TRUE;
1481 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1521+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
14821522 _tcscpy(apps[appcount - 1].name, outbuffer);
14831523 }
14841524 else
14851525 {
1486 - _sntprintf(verpath,64,_T("\\StringFileInfo\\%04x%04x\\InternalName"),((WORD*)outbuffer)[0],((WORD*)outbuffer)[1]);
1487 - if(VerQueryValue(verinfo,verpath,(LPVOID*)&outbuffer,&outlen))
 1526+ _sntprintf(verpath, 64, _T("\\StringFileInfo\\%04x%04x\\InternalName"), ((WORD*)outbuffer)[0], ((WORD*)outbuffer)[1]);
 1527+ if (VerQueryValue(verinfo, verpath, (LPVOID*)&outbuffer, &outlen))
14881528 {
14891529 hasname = TRUE;
1490 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1)*sizeof(TCHAR));
 1530+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(outbuffer) + 1) * sizeof(TCHAR));
14911531 _tcscpy(apps[appcount - 1].name, outbuffer);
14921532 }
14931533 }
@@ -1495,53 +1535,43 @@
14961536 }
14971537 if (!hasname)
14981538 {
1499 - apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1)*sizeof(TCHAR));
 1539+ apps[appcount - 1].name = (LPTSTR)malloc((_tcslen(newkey) + 1) * sizeof(TCHAR));
15001540 _tcscpy(apps[appcount - 1].name, newkey);
15011541 }
15021542 free(verinfo);
15031543 free(path);
1504 - break;
15051544 }
1506 - SendDlgItemMessage(hWnd,IDC_APPS,LB_ADDSTRING,0,(LPARAM)apps[appcount-1].name);
 1545+ SendDlgItemMessage(hWnd, IDC_APPS, LB_SETCURSEL,
 1546+ SendDlgItemMessage(hWnd, IDC_APPS, LB_ADDSTRING, 0, (LPARAM)apps[appcount - 1].name), 0);
 1547+ SendMessage(hWnd, WM_COMMAND, IDC_APPS + 0x10000, 0);
15071548 RegCloseKey(hKey);
15081549 free(regbuffer);
15091550 }
15101551 }
1511 -
15121552 break;
15131553 case IDC_REMOVE:
15141554 if(MessageBox(hWnd,_T("Do you want to delete the selected application profile and remove DXGL from its installation folder(s)?"),
15151555 _T("Confirmation"),MB_YESNO|MB_ICONQUESTION) != IDYES) return FALSE;
15161556 regpath = (LPTSTR)malloc((_tcslen(apps[current_app].regkey) + 15)*sizeof(TCHAR));
1517 - _tcscpy(regpath, _T("Software\\DXGL\\"));
 1557+ _tcscpy(regpath, _T("Software\\DXGL\\Profiles\\"));
15181558 _tcscat(regpath, apps[current_app].regkey);
15191559 regkey = (LPTSTR)malloc(_tcslen(apps[current_app].regkey));
15201560 _tcscpy(regkey, apps[current_app].regkey);
15211561 RegOpenKeyEx(HKEY_CURRENT_USER,regpath,0,KEY_READ,&hKey);
1522 - RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,NULL,&buffersize);
 1562+ RegQueryValueEx(hKey,_T("InstallPath"),NULL,NULL,NULL,&buffersize);
15231563 regbuffer = (LPTSTR)malloc(buffersize);
1524 - regbuffer[0] = regbuffer[1] = 0;
1525 - error = RegQueryValueEx(hKey,_T("InstallPaths"),NULL,NULL,(LPBYTE)regbuffer,&buffersize);
1526 - regbufferpos = 0;
 1564+ regbuffer[0] = 0;
15271565 failed = FALSE;
1528 - while(1)
 1566+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1567+ path = (LPTSTR)malloc(((_tcslen(regbuffer) + 12)) * sizeof(TCHAR));
 1568+ _tcscpy(path, regbuffer);
 1569+ _tcscat(path, _T("\\ddraw.dll"));
 1570+ if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
15291571 {
1530 - if((regbuffer[regbufferpos] == 0) || error != ERROR_SUCCESS) break;
1531 - if (_tcsrchr(regkey, _T('-'))) *(_tcsrchr(regkey, _T('-'))) = 0;
1532 - path = (LPTSTR)malloc(((_tcslen((LPTSTR)regbuffer + regbufferpos) +
1533 - 12))*sizeof(TCHAR));
1534 - _tcscpy(path, regbuffer + regbufferpos);
1535 - _tcscat(path, _T("\\ddraw.dll"));
1536 - if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES)
1537 - {
1538 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1539 - free(path);
1540 - continue;
1541 - }
1542 - if(DelApp(path,FALSE)) failed = TRUE;
1543 - regbufferpos += (_tcslen(regbuffer+regbufferpos)+1);
1544 - free(path);
 1572+ if (DelApp(path, FALSE)) failed = TRUE;
15451573 }
 1574+ free(path);
 1575+ free(regbuffer);
15461576 RegCloseKey(hKey);
15471577 if(!failed)
15481578 {
@@ -1556,6 +1586,8 @@
15571587 appcount--;
15581588 }
15591589 SendDlgItemMessage(hWnd,IDC_APPS,LB_DELETESTRING,current_app,0);
 1590+ SendDlgItemMessage(hWnd, IDC_APPS, LB_SETCURSEL, 0, 0);
 1591+ SendMessage(hWnd, WM_COMMAND, IDC_APPS + 0x10000, 0);
15601592 break;
15611593 }
15621594 break;
@@ -1563,6 +1595,193 @@
15641596 return FALSE;
15651597 }
15661598
 1599+void UpgradeDXGL()
 1600+{
 1601+ UpgradeConfig();
 1602+ HKEY hKeyBase;
 1603+ HKEY hKey;
 1604+ DWORD keysize, keysize2;
 1605+ int i = 0;
 1606+ LONG error;
 1607+ LPTSTR keyname;
 1608+ DWORD sizeout;
 1609+ DWORD buffersize;
 1610+ DWORD regbuffersize;
 1611+ LPTSTR regbuffer;
 1612+ BOOL installed = FALSE;
 1613+ BOOL dxgl_installdir = FALSE;
 1614+ BOOL old_dxgl = FALSE;
 1615+ HKEY hKeyInstall;
 1616+ TCHAR installpath[MAX_PATH + 1];
 1617+ TCHAR srcpath[MAX_PATH + 1];
 1618+ TCHAR destpath[MAX_PATH + 1];
 1619+ regbuffersize = 1024;
 1620+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 1621+ RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, NULL, 0, KEY_READ, NULL, &hKeyBase, NULL);
 1622+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1623+ keysize++;
 1624+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
 1625+ keysize2 = keysize;
 1626+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
 1627+ if (error == ERROR_SUCCESS)
 1628+ {
 1629+ dxgl_installdir = TRUE;
 1630+ error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
 1631+ if (error == ERROR_SUCCESS) installed = TRUE;
 1632+ }
 1633+ if (hKeyInstall) RegCloseKey(hKeyInstall);
 1634+ if (!installed)
 1635+ {
 1636+ GetModuleFileName(NULL, installpath, MAX_PATH + 1);
 1637+ }
 1638+ if (dxgl_installdir) _tcscat(installpath, _T("\\"));
 1639+ else (_tcsrchr(installpath, _T('\\')))[1] = 0;
 1640+ _tcsncpy(srcpath, installpath, MAX_PATH + 1);
 1641+ _tcscat(srcpath, _T("ddraw.dll"));
 1642+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1643+ {
 1644+ keysize2 = keysize;
 1645+ i++;
 1646+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
 1647+ buffersize = regbuffersize;
 1648+ RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, NULL, &buffersize);
 1649+ if (buffersize > regbuffersize)
 1650+ {
 1651+ regbuffersize = buffersize;
 1652+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
 1653+ }
 1654+ buffersize = regbuffersize;
 1655+ regbuffer[0] = 0;
 1656+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1657+ if (regbuffer[0] != 0)
 1658+ {
 1659+ _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
 1660+ _tcscat(destpath, _T("\\"));
 1661+ _tcscat(destpath, _T("ddraw.dll"));
 1662+ error = CopyFile(srcpath, destpath, TRUE);
 1663+ if (!error)
 1664+ {
 1665+ error = GetLastError();
 1666+ if (error == ERROR_FILE_EXISTS)
 1667+ {
 1668+ old_dxgl = FALSE;
 1669+ HMODULE hmod = LoadLibrary(destpath);
 1670+ if (hmod)
 1671+ {
 1672+ if (GetProcAddress(hmod, "IsDXGLDDraw")) old_dxgl = TRUE;
 1673+ FreeLibrary(hmod);
 1674+ }
 1675+ if (old_dxgl) CopyFile(srcpath, destpath, FALSE);
 1676+ }
 1677+ }
 1678+ }
 1679+ RegCloseKey(hKey);
 1680+ }
 1681+ free(regbuffer);
 1682+ free(keyname);
 1683+ RegCloseKey(hKeyBase);
 1684+}
 1685+
 1686+// '0' for keep, '1' for remove, personal settings
 1687+void UninstallDXGL(TCHAR uninstall)
 1688+{
 1689+ HKEY hKeyBase;
 1690+ HKEY hKey;
 1691+ DWORD keysize, keysize2;
 1692+ LONG error;
 1693+ LPTSTR keyname;
 1694+ DWORD sizeout;
 1695+ DWORD buffersize;
 1696+ DWORD regbuffersize;
 1697+ LPTSTR regbuffer;
 1698+ BOOL installed = FALSE;
 1699+ BOOL dxgl_installdir = FALSE;
 1700+ BOOL old_dxgl = FALSE;
 1701+ HKEY hKeyInstall;
 1702+ TCHAR installpath[MAX_PATH + 1];
 1703+ TCHAR srcpath[MAX_PATH + 1];
 1704+ TCHAR destpath[MAX_PATH + 1];
 1705+ int i = 0;
 1706+ UpgradeConfig(); // Just to make sure the registry format is correct
 1707+ regbuffersize = 1024;
 1708+ regbuffer = (LPTSTR)malloc(regbuffersize * sizeof(TCHAR));
 1709+ error = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"), 0, KEY_ALL_ACCESS, &hKeyBase);
 1710+ if (error != ERROR_SUCCESS) return;
 1711+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1712+ keysize++;
 1713+ keyname = (LPTSTR)malloc(keysize * sizeof(TCHAR));
 1714+ keysize2 = keysize;
 1715+ error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
 1716+ if (error == ERROR_SUCCESS)
 1717+ {
 1718+ dxgl_installdir = TRUE;
 1719+ error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
 1720+ if (error == ERROR_SUCCESS) installed = TRUE;
 1721+ }
 1722+ if (hKeyInstall) RegCloseKey(hKeyInstall);
 1723+ if (!installed)
 1724+ {
 1725+ GetModuleFileName(NULL, installpath, MAX_PATH + 1);
 1726+ }
 1727+ if (dxgl_installdir) _tcscat(installpath, _T("\\"));
 1728+ else (_tcsrchr(installpath, _T('\\')))[1] = 0;
 1729+ _tcsncpy(srcpath, installpath, MAX_PATH + 1);
 1730+ _tcscat(srcpath, _T("ddraw.dll"));
 1731+ while (RegEnumKeyEx(hKeyBase, i, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1732+ {
 1733+ keysize2 = keysize;
 1734+ i++;
 1735+ error = RegOpenKeyEx(hKeyBase, keyname, 0, KEY_READ, &hKey);
 1736+ buffersize = regbuffersize;
 1737+ if (buffersize > regbuffersize)
 1738+ {
 1739+ regbuffersize = buffersize;
 1740+ regbuffer = (LPTSTR)realloc(regbuffer, regbuffersize);
 1741+ }
 1742+ buffersize = regbuffersize;
 1743+ regbuffer[0] = 0;
 1744+ error = RegQueryValueEx(hKey, _T("InstallPath"), NULL, NULL, (LPBYTE)regbuffer, &buffersize);
 1745+ if (regbuffer[0] != 0)
 1746+ {
 1747+ _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
 1748+ _tcscat(destpath, _T("\\"));
 1749+ _tcscat(destpath, _T("ddraw.dll"));
 1750+ if (GetFileAttributes(destpath) != INVALID_FILE_ATTRIBUTES)
 1751+ {
 1752+ old_dxgl = FALSE;
 1753+ HMODULE hmod = LoadLibrary(destpath);
 1754+ if (hmod)
 1755+ {
 1756+ if (GetProcAddress(hmod, "IsDXGLDDraw")) old_dxgl = TRUE;
 1757+ FreeLibrary(hmod);
 1758+ }
 1759+ if (_tcscmp(srcpath, destpath))
 1760+ {
 1761+ if (old_dxgl) DeleteFile(destpath);
 1762+ }
 1763+ }
 1764+ }
 1765+ RegCloseKey(hKey);
 1766+ }
 1767+ free(regbuffer);
 1768+ RegQueryInfoKey(hKeyBase, NULL, NULL, NULL, NULL, &keysize, NULL, NULL, NULL, NULL, NULL, NULL);
 1769+ keysize++;
 1770+ if (uninstall == '1') // Delete user settings
 1771+ {
 1772+ while (RegEnumKeyEx(hKeyBase, 0, keyname, &keysize2, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
 1773+ {
 1774+ keysize2 = keysize;
 1775+ i++;
 1776+ RegDeleteKey(hKeyBase, keyname);
 1777+ }
 1778+ RegCloseKey(hKeyBase);
 1779+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL\\Profiles"));
 1780+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL\\Global"));
 1781+ RegDeleteKey(HKEY_CURRENT_USER, _T("Software\\DXGL"));
 1782+ }
 1783+ else RegCloseKey(hKeyBase);
 1784+}
 1785+
15671786 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
15681787 {
15691788 INITCOMMONCONTROLSEX icc;
@@ -1571,6 +1790,16 @@
15721791 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
15731792 GetVersionEx(&osver);
15741793 CoInitialize(NULL);
 1794+ if (!_tcsnicmp(lpCmdLine, _T("upgrade"), 7))
 1795+ {
 1796+ UpgradeDXGL();
 1797+ return 0;
 1798+ }
 1799+ if (!_tcsnicmp(lpCmdLine, _T("uninstall"), 9))
 1800+ {
 1801+ UninstallDXGL(lpCmdLine[10]);
 1802+ return 0;
 1803+ }
15751804 if(!_tcsnicmp(lpCmdLine,_T("install "),8))
15761805 {
15771806 return AddApp(lpCmdLine+8,TRUE,TRUE);