Index: cfgmgr/cfgmgr.c |
— | — | @@ -1372,4 +1372,80 @@ |
1373 | 1373 | sizeout = 1;
|
1374 | 1374 | RegSetValueEx(hKey, _T("Configuration Version"), 0, REG_DWORD, &sizeout, 4);
|
1375 | 1375 | RegCloseKey(hKey);
|
| 1376 | +}
|
| 1377 | +
|
| 1378 | +int ReadINIOptionsCallback(app_ini_options *options, const char *section, const char *name,
|
| 1379 | + const char *value)
|
| 1380 | +{
|
| 1381 | + if (!stricmp(section, "system"))
|
| 1382 | + {
|
| 1383 | + if (!stricmp(name, "NoOverwrite")) options->NoOverwrite = INIBoolValue(value);
|
| 1384 | + if (!stricmp(name, "BundledDDrawSHA256"))
|
| 1385 | + {
|
| 1386 | + strncpy(options->sha256comp, value, 65);
|
| 1387 | + options->sha256comp[64] = 0;
|
| 1388 | + if (options->sha256comp[63] == 0) options->sha256comp[0] = 0;
|
| 1389 | + }
|
| 1390 | + if (!stricmp(name, "NoUninstall")) options->NoUninstall = INIBoolValue(value);
|
| 1391 | + }
|
| 1392 | + return 1;
|
| 1393 | +}
|
| 1394 | +
|
| 1395 | +void ReadAppINIOptions(LPCTSTR path, app_ini_options *options)
|
| 1396 | +{
|
| 1397 | + int i;
|
| 1398 | + Sha256Context sha_context;
|
| 1399 | + SHA256_HASH sha256;
|
| 1400 | + TCHAR sha256string[65];
|
| 1401 | + FILE *file;
|
| 1402 | + HANDLE file2;
|
| 1403 | + char buffer[512];
|
| 1404 | + DWORD bytesread;
|
| 1405 | + TCHAR path2[MAX_PATH + 1];
|
| 1406 | + ZeroMemory(options->sha256, 65*sizeof(char));
|
| 1407 | + ZeroMemory(options->sha256comp, 65*sizeof(char));
|
| 1408 | + _tcsncpy(path2, path, MAX_PATH + 1);
|
| 1409 | + _tcscat(path2, _T("dxgl.ini"));
|
| 1410 | + // Check for INI file and read it.
|
| 1411 | + file = _tfopen(path2, _T("r"));
|
| 1412 | + if (file)
|
| 1413 | + {
|
| 1414 | + ini_parse_file(file, ReadINIOptionsCallback, options);
|
| 1415 | + fclose(file);
|
| 1416 | + }
|
| 1417 | + else
|
| 1418 | + {
|
| 1419 | + options->NoOverwrite = FALSE;
|
| 1420 | + options->NoUninstall = FALSE;
|
| 1421 | + }
|
| 1422 | + // Check for existing ddraw.dll and get SHA256 sum
|
| 1423 | + if ((options->sha256comp[0] != 0) && !options->NoOverwrite)
|
| 1424 | + {
|
| 1425 | + _tcsncpy(path2, path, MAX_PATH + 1);
|
| 1426 | + _tcscat(path2, _T("ddraw.dll"));
|
| 1427 | + Sha256Initialise(&sha_context);
|
| 1428 | + file2 = CreateFile(path2, GENERIC_READ, FILE_SHARE_READ, NULL,
|
| 1429 | + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| 1430 | + if(!file2)
|
| 1431 | + {
|
| 1432 | + options->sha256[0] = 0;
|
| 1433 | + }
|
| 1434 | + else
|
| 1435 | + {
|
| 1436 | + while (1)
|
| 1437 | + {
|
| 1438 | + ReadFile(file, buffer, 512, &bytesread, NULL);
|
| 1439 | + if (!bytesread) break;
|
| 1440 | + Sha256Update(&sha_context, buffer, bytesread);
|
| 1441 | + if (bytesread < 512) break;
|
| 1442 | + }
|
| 1443 | + Sha256Finalise(&sha_context, &sha256);
|
| 1444 | + CloseHandle(file2);
|
| 1445 | + for (i = 0; i < (256 / 8); i++)
|
| 1446 | + {
|
| 1447 | + options->sha256[i * 2] = hexdigit(sha256.bytes[i] >> 4);
|
| 1448 | + options->sha256[(i * 2) + 1] = hexdigit(sha256.bytes[i] & 0xF);
|
| 1449 | + }
|
| 1450 | + }
|
| 1451 | + }
|
1376 | 1452 | } |
\ No newline at end of file |
Index: cfgmgr/cfgmgr.h |
— | — | @@ -76,6 +76,14 @@ |
77 | 77 |
|
78 | 78 | typedef struct
|
79 | 79 | {
|
| 80 | + BOOL NoOverwrite;
|
| 81 | + char sha256[65];
|
| 82 | + char sha256comp[65];
|
| 83 | + BOOL NoUninstall;
|
| 84 | +} app_ini_options;
|
| 85 | +
|
| 86 | +typedef struct
|
| 87 | +{
|
80 | 88 | TCHAR InstallPath[MAX_PATH + 1];
|
81 | 89 | TCHAR InstallPathLowercase[MAX_PATH + 1];
|
82 | 90 | TCHAR EXEFile[MAX_PATH + 1];
|
— | — | @@ -96,6 +104,7 @@ |
97 | 105 | void SetConfig(const DXGLCFG *cfg, const DXGLCFG *mask, LPCTSTR name);
|
98 | 106 | void GetDirFromPath(LPTSTR path);
|
99 | 107 | void UpgradeConfig();
|
| 108 | +void ReadAppINIOptions(LPCTSTR path, app_ini_options *options);
|
100 | 109 | BOOL CheckProfileExists(LPTSTR path);
|
101 | 110 | LPTSTR MakeNewConfig(LPTSTR path);
|
102 | 111 |
|
Index: dxglcfg/dxglcfg.c |
— | — | @@ -80,62 +80,126 @@ |
81 | 81 | BOOL tristate;
|
82 | 82 | TCHAR strdefault[] = _T("(global default)");
|
83 | 83 |
|
84 | | -DWORD AddApp(LPCTSTR path, BOOL copyfile, BOOL admin)
|
| 84 | +DWORD AddApp(LPCTSTR path, BOOL copyfile, BOOL admin, BOOL force, HWND hwnd)
|
85 | 85 | {
|
86 | 86 | BOOL installed = FALSE;
|
87 | 87 | BOOL dxgl_installdir = FALSE;
|
88 | | - BOOL old_dxgl = FALSE;
|
89 | | - TCHAR command[MAX_PATH+32];
|
| 88 | + BOOL old_dxgl = TRUE;
|
| 89 | + TCHAR command[MAX_PATH + 37];
|
90 | 90 | SHELLEXECUTEINFO shex;
|
91 | 91 | DWORD exitcode;
|
| 92 | + app_ini_options inioptions;
|
92 | 93 | if (copyfile)
|
93 | 94 | {
|
94 | | - DWORD sizeout = (MAX_PATH+1)*sizeof(TCHAR);
|
95 | | - TCHAR installpath[MAX_PATH+1];
|
96 | | - TCHAR srcpath[MAX_PATH+1];
|
97 | | - TCHAR destpath[MAX_PATH+1];
|
| 95 | + DWORD sizeout = (MAX_PATH + 1) * sizeof(TCHAR);
|
| 96 | + TCHAR installpath[MAX_PATH + 1];
|
| 97 | + TCHAR srcpath[MAX_PATH + 1];
|
| 98 | + TCHAR inipath[MAX_PATH + 1];
|
| 99 | + TCHAR backuppath[MAX_PATH + 1];
|
| 100 | + TCHAR destpath[MAX_PATH + 1];
|
98 | 101 | HKEY hKeyInstall;
|
99 | | - LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\DXGL"),0,KEY_READ,&hKeyInstall);
|
100 | | - if(error == ERROR_SUCCESS)
|
| 102 | + LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
|
| 103 | + if (error == ERROR_SUCCESS)
|
101 | 104 | {
|
102 | 105 | dxgl_installdir = TRUE;
|
103 | | - error = RegQueryValueEx(hKeyInstall,_T("InstallDir"),NULL,NULL,(LPBYTE)installpath,&sizeout);
|
104 | | - if(error == ERROR_SUCCESS) installed = TRUE;
|
| 106 | + error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
|
| 107 | + if (error == ERROR_SUCCESS) installed = TRUE;
|
105 | 108 | }
|
106 | | - if(hKeyInstall) RegCloseKey(hKeyInstall);
|
107 | | - if(!installed)
|
| 109 | + if (hKeyInstall) RegCloseKey(hKeyInstall);
|
| 110 | + if (!installed)
|
108 | 111 | {
|
109 | | - GetModuleFileName(NULL,installpath,MAX_PATH+1);
|
| 112 | + GetModuleFileName(NULL, installpath, MAX_PATH + 1);
|
110 | 113 | }
|
111 | | - if(dxgl_installdir) _tcscat(installpath,_T("\\"));
|
112 | | - else (_tcsrchr(installpath,_T('\\')))[1] = 0;
|
113 | | - _tcsncpy(srcpath,installpath,MAX_PATH+1);
|
114 | | - _tcscat(srcpath,_T("ddraw.dll"));
|
115 | | - _tcsncpy(destpath,path,MAX_PATH+1);
|
116 | | - (_tcsrchr(destpath,_T('\\')))[1] = 0;
|
117 | | - _tcscat(destpath,_T("ddraw.dll"));
|
118 | | - error = CopyFile(srcpath,destpath,TRUE);
|
119 | | - error_loop:
|
120 | | - if(!error)
|
| 114 | + if (dxgl_installdir) _tcscat(installpath, _T("\\"));
|
| 115 | + else (_tcsrchr(installpath, _T('\\')))[1] = 0;
|
| 116 | + _tcsncpy(srcpath, installpath, MAX_PATH + 1);
|
| 117 | + _tcscat(srcpath, _T("ddraw.dll"));
|
| 118 | + _tcsncpy(destpath, path, MAX_PATH + 1);
|
| 119 | + (_tcsrchr(destpath, _T('\\')))[1] = 0;
|
| 120 | + _tcscat(destpath, _T("ddraw.dll"));
|
| 121 | + _tcsncpy(backuppath, path, MAX_PATH + 1);
|
| 122 | + (_tcsrchr(backuppath, _T('\\')))[1] = 0;
|
| 123 | + _tcscat(backuppath, _T("ddraw.dll.dxgl-backup"));
|
| 124 | + _tcsncpy(inipath, path, MAX_PATH + 1);
|
| 125 | + (_tcsrchr(inipath, _T('\\')))[1] = 0;
|
| 126 | + // Check for DXGL ini file and existing ddraw.dll
|
| 127 | + ReadAppINIOptions(inipath, &inioptions);
|
| 128 | + error = CopyFile(srcpath, destpath, TRUE);
|
| 129 | + error_loop:
|
| 130 | + if (!error)
|
121 | 131 | {
|
122 | 132 | error = GetLastError();
|
123 | | - if(error == ERROR_FILE_EXISTS)
|
| 133 | + if (error == ERROR_FILE_EXISTS)
|
124 | 134 | {
|
| 135 | + if (inioptions.NoOverwrite)
|
| 136 | + {
|
| 137 | + MessageBox(hwnd, _T("Cannot install DXGL. An INI file has \
|
| 138 | +been found in your game folder prohibiting overwriting the existing DirectDraw \
|
| 139 | +library.\r\n\r\nIf you want to install DXGL, edit the dxgl.ini file in your game \
|
| 140 | +folder and set the NoOverwite value to false.\r\n\r\n\
|
| 141 | +A profile will still be created for your game but may not be compatible with the \
|
| 142 | +DirectDraw library in your game folder."), _T("Error"), MB_OK | MB_ICONERROR);
|
| 143 | + return 0; // Continue to install registry key anyway
|
| 144 | + }
|
| 145 | + if (!memcmp(inioptions.sha256, inioptions.sha256comp, 64))
|
| 146 | + // Detected original ddraw matches INI hash
|
| 147 | + {
|
| 148 | + error = CopyFile(srcpath, backuppath, FALSE);
|
| 149 | + if (!error)
|
| 150 | + {
|
| 151 | + error = GetLastError();
|
| 152 | + if ((error == ERROR_ACCESS_DENIED) && !admin)
|
| 153 | + {
|
| 154 | + _tcscpy(command, _T(" install "));
|
| 155 | + _tcscat(command, path);
|
| 156 | + ZeroMemory(&shex, sizeof(SHELLEXECUTEINFO));
|
| 157 | + shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
| 158 | + shex.lpVerb = _T("runas");
|
| 159 | + shex.fMask = SEE_MASK_NOCLOSEPROCESS;
|
| 160 | + _tcscat(installpath, _T("\\dxglcfg.exe"));
|
| 161 | + shex.lpFile = installpath;
|
| 162 | + shex.lpParameters = command;
|
| 163 | + ShellExecuteEx(&shex);
|
| 164 | + WaitForSingleObject(shex.hProcess, INFINITE);
|
| 165 | + GetExitCodeProcess(shex.hProcess, &exitcode);
|
| 166 | + return exitcode;
|
| 167 | + }
|
| 168 | + }
|
| 169 | + }
|
125 | 170 | HMODULE hmod = LoadLibrary(destpath);
|
126 | 171 | if(hmod)
|
127 | 172 | {
|
128 | | - if(GetProcAddress(hmod,"IsDXGLDDraw")) old_dxgl = TRUE;
|
| 173 | + if(GetProcAddress(hmod,"IsDXGLDDraw") || force) old_dxgl = TRUE;
|
| 174 | + else old_dxgl = FALSE;
|
129 | 175 | FreeLibrary(hmod);
|
130 | 176 | }
|
| 177 | + else
|
| 178 | + {
|
| 179 | + if (force) old_dxgl = TRUE;
|
| 180 | + else old_dxgl = FALSE;
|
| 181 | + }
|
131 | 182 | if(old_dxgl)
|
132 | 183 | {
|
133 | 184 | error = CopyFile(srcpath,destpath,FALSE);
|
134 | 185 | goto error_loop;
|
135 | 186 | }
|
| 187 | + else
|
| 188 | + {
|
| 189 | + // Prompt to overwrite
|
| 190 | + if (MessageBox(hwnd, _T("A custom DirectDraw library has been detected in \
|
| 191 | +your game folder. Would you like to replace it with DXGL?\r\n\r\n\
|
| 192 | +Warning: Installing DXGL will remove any customizations that the existing custom DirectDraw \
|
| 193 | +library may have."), _T("DXGL Config"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)
|
| 194 | + {
|
| 195 | + error = CopyFile(srcpath, destpath, FALSE);
|
| 196 | + goto error_loop;
|
| 197 | + }
|
| 198 | + }
|
136 | 199 | }
|
137 | 200 | if((error == ERROR_ACCESS_DENIED) && !admin)
|
138 | 201 | {
|
139 | | - _tcscpy(command,_T(" install "));
|
| 202 | + if(old_dxgl) _tcscpy(command,_T(" install "));
|
| 203 | + else _tcscpy(command, _T(" forceinstall "));
|
140 | 204 | _tcscat(command,path);
|
141 | 205 | ZeroMemory(&shex,sizeof(SHELLEXECUTEINFO));
|
142 | 206 | shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
— | — | @@ -155,7 +219,7 @@ |
156 | 220 | return 0;
|
157 | 221 | }
|
158 | 222 |
|
159 | | -DWORD DelApp(LPCTSTR path, BOOL admin)
|
| 223 | +DWORD DelApp(LPCTSTR path, BOOL admin, HWND hwnd)
|
160 | 224 | {
|
161 | 225 | BOOL installed = FALSE;
|
162 | 226 | TCHAR command[MAX_PATH + 32];
|
— | — | @@ -162,10 +226,14 @@ |
163 | 227 | BOOL old_dxgl = TRUE;
|
164 | 228 | DWORD sizeout = (MAX_PATH+1)*sizeof(TCHAR);
|
165 | 229 | TCHAR installpath[MAX_PATH+1];
|
| 230 | + TCHAR inipath[MAX_PATH + 1];
|
| 231 | + TCHAR backuppath[MAX_PATH + 1];
|
166 | 232 | HKEY hKeyInstall;
|
167 | 233 | HMODULE hmod;
|
168 | 234 | SHELLEXECUTEINFO shex;
|
169 | 235 | DWORD exitcode;
|
| 236 | + HANDLE exists;
|
| 237 | + app_ini_options inioptions;
|
170 | 238 | LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
|
171 | 239 | if(error == ERROR_SUCCESS)
|
172 | 240 | {
|
— | — | @@ -177,6 +245,24 @@ |
178 | 246 | {
|
179 | 247 | GetModuleFileName(NULL,installpath,MAX_PATH+1);
|
180 | 248 | }
|
| 249 | + _tcsncpy(inipath, path, MAX_PATH + 1);
|
| 250 | + (_tcsrchr(inipath, _T('\\')))[1] = 0;
|
| 251 | + _tcsncpy(backuppath, path, MAX_PATH + 1);
|
| 252 | + (_tcsrchr(backuppath, _T('\\')))[1] = 0;
|
| 253 | + _tcscat(backuppath, _T("ddraw.dll.dxgl-backup"));
|
| 254 | + // Check for DXGL ini file and existing ddraw.dll
|
| 255 | + ReadAppINIOptions(inipath, &inioptions);
|
| 256 | + if (inioptions.NoOverwrite || inioptions.NoUninstall)
|
| 257 | + {
|
| 258 | + MessageBox(hwnd,_T("DXGL has not been removed from your game folder. \
|
| 259 | +An INI file has been found in your game folder prohibiting the DirectDraw \
|
| 260 | +library in your game folder from being deleted.\r\n\r\n\
|
| 261 | +If this is in error, you will have to manually delete ddraw.dll from your \
|
| 262 | +game folder. If your game was distributed by Steam or a similar service \
|
| 263 | +please verify your game files after removing the file, in case the game \
|
| 264 | +shipped with a custom DirectDraw library."), _T("Warning"), MB_OK | MB_ICONWARNING);
|
| 265 | + return 0; // Continue to delete registry profile.
|
| 266 | + }
|
181 | 267 | hmod = LoadLibrary(path);
|
182 | 268 | if(hmod)
|
183 | 269 | {
|
— | — | @@ -183,11 +269,11 @@ |
184 | 270 | if(!GetProcAddress(hmod,"IsDXGLDDraw")) old_dxgl = FALSE;
|
185 | 271 | FreeLibrary(hmod);
|
186 | 272 | }
|
| 273 | + else old_dxgl = FALSE;
|
187 | 274 | if(!old_dxgl) return 0;
|
188 | 275 | if(!DeleteFile(path))
|
189 | 276 | {
|
190 | 277 | error = GetLastError();
|
191 | | - if(error == ERROR_FILE_NOT_FOUND) return 0;
|
192 | 278 | if((error == ERROR_ACCESS_DENIED) && !admin)
|
193 | 279 | {
|
194 | 280 | _tcscpy(command,_T(" remove "));
|
— | — | @@ -204,8 +290,37 @@ |
205 | 291 | GetExitCodeProcess(shex.hProcess,&exitcode);
|
206 | 292 | return exitcode;
|
207 | 293 | }
|
208 | | - return error;
|
| 294 | + else if (error != ERROR_FILE_NOT_FOUND) return error;
|
209 | 295 | }
|
| 296 | + exists = CreateFile(backuppath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
| 297 | + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| 298 | + if (exists == INVALID_HANDLE_VALUE) return 0;
|
| 299 | + else
|
| 300 | + {
|
| 301 | + CloseHandle(exists);
|
| 302 | + error = MoveFile(backuppath, path);
|
| 303 | + if (!error)
|
| 304 | + {
|
| 305 | + error = GetLastError();
|
| 306 | + if ((error == ERROR_ACCESS_DENIED) && !admin)
|
| 307 | + {
|
| 308 | + _tcscpy(command, _T(" remove "));
|
| 309 | + _tcscat(command, path);
|
| 310 | + ZeroMemory(&shex, sizeof(SHELLEXECUTEINFO));
|
| 311 | + shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
| 312 | + shex.lpVerb = _T("runas");
|
| 313 | + shex.fMask = SEE_MASK_NOCLOSEPROCESS;
|
| 314 | + _tcscat(installpath, _T("\\dxglcfg.exe"));
|
| 315 | + shex.lpFile = installpath;
|
| 316 | + shex.lpParameters = command;
|
| 317 | + ShellExecuteEx(&shex);
|
| 318 | + WaitForSingleObject(shex.hProcess, INFINITE);
|
| 319 | + GetExitCodeProcess(shex.hProcess, &exitcode);
|
| 320 | + return exitcode;
|
| 321 | + }
|
| 322 | + else return error;
|
| 323 | + }
|
| 324 | + }
|
210 | 325 | return 0;
|
211 | 326 | }
|
212 | 327 |
|
— | — | @@ -1340,7 +1455,7 @@ |
1341 | 1456 | _T("Profile already exists"), MB_OK | MB_ICONWARNING);
|
1342 | 1457 | break;
|
1343 | 1458 | }
|
1344 | | - err = AddApp(filename.lpstrFile, TRUE, FALSE);
|
| 1459 | + err = AddApp(filename.lpstrFile, TRUE, FALSE, FALSE, hWnd);
|
1345 | 1460 | if (!err)
|
1346 | 1461 | {
|
1347 | 1462 | LPTSTR newkey = MakeNewConfig(filename.lpstrFile);
|
— | — | @@ -1465,7 +1580,7 @@ |
1466 | 1581 | _tcscat(path, _T("\\ddraw.dll"));
|
1467 | 1582 | if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
|
1468 | 1583 | {
|
1469 | | - if (DelApp(path, FALSE)) failed = TRUE;
|
| 1584 | + if (DelApp(path, FALSE, hWnd)) failed = TRUE;
|
1470 | 1585 | }
|
1471 | 1586 | free(path);
|
1472 | 1587 | free(regbuffer);
|
— | — | @@ -1511,6 +1626,9 @@ |
1512 | 1627 | TCHAR installpath[MAX_PATH + 1];
|
1513 | 1628 | TCHAR srcpath[MAX_PATH + 1];
|
1514 | 1629 | TCHAR destpath[MAX_PATH + 1];
|
| 1630 | + TCHAR inipath[MAX_PATH + 1];
|
| 1631 | + TCHAR backuppath[MAX_PATH + 1];
|
| 1632 | + app_ini_options inioptions;
|
1515 | 1633 | HMODULE hmod;
|
1516 | 1634 | UpgradeConfig();
|
1517 | 1635 | regbuffersize = 1024;
|
— | — | @@ -1555,8 +1673,12 @@ |
1556 | 1674 | if (regbuffer[0] != 0)
|
1557 | 1675 | {
|
1558 | 1676 | _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
|
1559 | | - _tcscat(destpath, _T("\\"));
|
1560 | | - _tcscat(destpath, _T("ddraw.dll"));
|
| 1677 | + _tcscat(destpath, _T("\\ddraw.dll"));
|
| 1678 | + _tcsncpy(inipath, regbuffer, MAX_PATH + 1);
|
| 1679 | + _tcscat(inipath, _T("\\dxgl.ini"));
|
| 1680 | + _tcsncpy(backuppath, regbuffer, MAX_PATH + 1);
|
| 1681 | + _tcscat(backuppath, _T("\\ddraw.dll.dxgl-backup"));
|
| 1682 | + ReadAppINIOptions(inipath, &inioptions);
|
1561 | 1683 | error = CopyFile(srcpath, destpath, TRUE);
|
1562 | 1684 | if (!error)
|
1563 | 1685 | {
|
— | — | @@ -1563,6 +1685,10 @@ |
1564 | 1686 | error = GetLastError();
|
1565 | 1687 | if (error == ERROR_FILE_EXISTS)
|
1566 | 1688 | {
|
| 1689 | + if (inioptions.NoOverwrite) continue;
|
| 1690 | + if (!memcmp(inioptions.sha256, inioptions.sha256comp, 64))
|
| 1691 | + // Detected original ddraw matches INI hash
|
| 1692 | + CopyFile(srcpath, backuppath, FALSE);
|
1567 | 1693 | old_dxgl = FALSE;
|
1568 | 1694 | hmod = LoadLibrary(destpath);
|
1569 | 1695 | if (hmod)
|
— | — | @@ -1600,6 +1726,10 @@ |
1601 | 1727 | TCHAR installpath[MAX_PATH + 1];
|
1602 | 1728 | TCHAR srcpath[MAX_PATH + 1];
|
1603 | 1729 | TCHAR destpath[MAX_PATH + 1];
|
| 1730 | + TCHAR inipath[MAX_PATH + 1];
|
| 1731 | + TCHAR backuppath[MAX_PATH + 1];
|
| 1732 | + HANDLE exists;
|
| 1733 | + app_ini_options inioptions;
|
1604 | 1734 | HMODULE hmod;
|
1605 | 1735 | int i = 0;
|
1606 | 1736 | UpgradeConfig(); // Just to make sure the registry format is correct
|
— | — | @@ -1645,8 +1775,13 @@ |
1646 | 1776 | if (regbuffer[0] != 0)
|
1647 | 1777 | {
|
1648 | 1778 | _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
|
1649 | | - _tcscat(destpath, _T("\\"));
|
1650 | | - _tcscat(destpath, _T("ddraw.dll"));
|
| 1779 | + _tcscat(destpath, _T("\\ddraw.dll"));
|
| 1780 | + _tcsncpy(inipath, regbuffer, MAX_PATH + 1);
|
| 1781 | + _tcscat(inipath, _T("\\dxgl.ini"));
|
| 1782 | + _tcsncpy(backuppath, regbuffer, MAX_PATH + 1);
|
| 1783 | + _tcscat(backuppath, _T("\\ddraw.dll.dxgl-backup"));
|
| 1784 | + ReadAppINIOptions(inipath, &inioptions);
|
| 1785 | + if (inioptions.NoOverwrite || inioptions.NoUninstall) continue;
|
1651 | 1786 | if (GetFileAttributes(destpath) != INVALID_FILE_ATTRIBUTES)
|
1652 | 1787 | {
|
1653 | 1788 | old_dxgl = FALSE;
|
— | — | @@ -1658,7 +1793,18 @@ |
1659 | 1794 | }
|
1660 | 1795 | if (_tcscmp(srcpath, destpath))
|
1661 | 1796 | {
|
1662 | | - if (old_dxgl) DeleteFile(destpath);
|
| 1797 | + if (old_dxgl)
|
| 1798 | + {
|
| 1799 | + DeleteFile(destpath);
|
| 1800 | + exists = CreateFile(backuppath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
| 1801 | + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| 1802 | + if (exists == INVALID_HANDLE_VALUE) continue;
|
| 1803 | + else
|
| 1804 | + {
|
| 1805 | + CloseHandle(exists);
|
| 1806 | + MoveFile(backuppath, destpath);
|
| 1807 | + }
|
| 1808 | + }
|
1663 | 1809 | }
|
1664 | 1810 | }
|
1665 | 1811 | }
|
— | — | @@ -1705,11 +1851,15 @@ |
1706 | 1852 | }
|
1707 | 1853 | if(!_tcsnicmp(lpCmdLine,_T("install "),8))
|
1708 | 1854 | {
|
1709 | | - return AddApp(lpCmdLine+8,TRUE,TRUE);
|
| 1855 | + return AddApp(lpCmdLine+8,TRUE,TRUE,FALSE,NULL);
|
1710 | 1856 | }
|
| 1857 | + if(!_tcsnicmp(lpCmdLine,_T("forceinstall "),13))
|
| 1858 | + {
|
| 1859 | + return AddApp(lpCmdLine+8,TRUE,TRUE,TRUE,NULL);
|
| 1860 | + }
|
1711 | 1861 | if(!_tcsnicmp(lpCmdLine,_T("remove "),7))
|
1712 | 1862 | {
|
1713 | | - return DelApp(lpCmdLine+7,TRUE);
|
| 1863 | + return DelApp(lpCmdLine+7,TRUE,NULL);
|
1714 | 1864 | }
|
1715 | 1865 | icc.dwSize = sizeof(icc);
|
1716 | 1866 | icc.dwICC = ICC_WIN95_CLASSES;
|
Index: dxglcfg2/dxglcfg2.c |
— | — | @@ -128,62 +128,126 @@ |
129 | 129 | _T("8/15/16/24/32-bit")
|
130 | 130 | };
|
131 | 131 |
|
132 | | -DWORD AddApp(LPCTSTR path, BOOL copyfile, BOOL admin)
|
| 132 | +DWORD AddApp(LPCTSTR path, BOOL copyfile, BOOL admin, BOOL force, HWND hwnd)
|
133 | 133 | {
|
134 | 134 | BOOL installed = FALSE;
|
135 | 135 | BOOL dxgl_installdir = FALSE;
|
136 | | - BOOL old_dxgl = FALSE;
|
137 | | - TCHAR command[MAX_PATH+32];
|
| 136 | + BOOL old_dxgl = TRUE;
|
| 137 | + TCHAR command[MAX_PATH + 37];
|
138 | 138 | SHELLEXECUTEINFO shex;
|
139 | 139 | DWORD exitcode;
|
| 140 | + app_ini_options inioptions;
|
140 | 141 | if (copyfile)
|
141 | 142 | {
|
142 | | - DWORD sizeout = (MAX_PATH+1)*sizeof(TCHAR);
|
143 | | - TCHAR installpath[MAX_PATH+1];
|
144 | | - TCHAR srcpath[MAX_PATH+1];
|
145 | | - TCHAR destpath[MAX_PATH+1];
|
| 143 | + DWORD sizeout = (MAX_PATH + 1) * sizeof(TCHAR);
|
| 144 | + TCHAR installpath[MAX_PATH + 1];
|
| 145 | + TCHAR srcpath[MAX_PATH + 1];
|
| 146 | + TCHAR inipath[MAX_PATH + 1];
|
| 147 | + TCHAR backuppath[MAX_PATH + 1];
|
| 148 | + TCHAR destpath[MAX_PATH + 1];
|
146 | 149 | HKEY hKeyInstall;
|
147 | | - LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\DXGL"),0,KEY_READ,&hKeyInstall);
|
148 | | - if(error == ERROR_SUCCESS)
|
| 150 | + LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
|
| 151 | + if (error == ERROR_SUCCESS)
|
149 | 152 | {
|
150 | 153 | dxgl_installdir = TRUE;
|
151 | | - error = RegQueryValueEx(hKeyInstall,_T("InstallDir"),NULL,NULL,(LPBYTE)installpath,&sizeout);
|
152 | | - if(error == ERROR_SUCCESS) installed = TRUE;
|
| 154 | + error = RegQueryValueEx(hKeyInstall, _T("InstallDir"), NULL, NULL, (LPBYTE)installpath, &sizeout);
|
| 155 | + if (error == ERROR_SUCCESS) installed = TRUE;
|
153 | 156 | }
|
154 | | - if(hKeyInstall) RegCloseKey(hKeyInstall);
|
155 | | - if(!installed)
|
| 157 | + if (hKeyInstall) RegCloseKey(hKeyInstall);
|
| 158 | + if (!installed)
|
156 | 159 | {
|
157 | | - GetModuleFileName(NULL,installpath,MAX_PATH+1);
|
| 160 | + GetModuleFileName(NULL, installpath, MAX_PATH + 1);
|
158 | 161 | }
|
159 | | - if(dxgl_installdir) _tcscat(installpath,_T("\\"));
|
160 | | - else (_tcsrchr(installpath,_T('\\')))[1] = 0;
|
161 | | - _tcsncpy(srcpath,installpath,MAX_PATH+1);
|
162 | | - _tcscat(srcpath,_T("ddraw.dll"));
|
163 | | - _tcsncpy(destpath,path,MAX_PATH+1);
|
164 | | - (_tcsrchr(destpath,_T('\\')))[1] = 0;
|
165 | | - _tcscat(destpath,_T("ddraw.dll"));
|
166 | | - error = CopyFile(srcpath,destpath,TRUE);
|
167 | | - error_loop:
|
168 | | - if(!error)
|
| 162 | + if (dxgl_installdir) _tcscat(installpath, _T("\\"));
|
| 163 | + else (_tcsrchr(installpath, _T('\\')))[1] = 0;
|
| 164 | + _tcsncpy(srcpath, installpath, MAX_PATH + 1);
|
| 165 | + _tcscat(srcpath, _T("ddraw.dll"));
|
| 166 | + _tcsncpy(destpath, path, MAX_PATH + 1);
|
| 167 | + (_tcsrchr(destpath, _T('\\')))[1] = 0;
|
| 168 | + _tcscat(destpath, _T("ddraw.dll"));
|
| 169 | + _tcsncpy(backuppath, path, MAX_PATH + 1);
|
| 170 | + (_tcsrchr(backuppath, _T('\\')))[1] = 0;
|
| 171 | + _tcscat(backuppath, _T("ddraw.dll.dxgl-backup"));
|
| 172 | + _tcsncpy(inipath, path, MAX_PATH + 1);
|
| 173 | + (_tcsrchr(inipath, _T('\\')))[1] = 0;
|
| 174 | + // Check for DXGL ini file and existing ddraw.dll
|
| 175 | + ReadAppINIOptions(inipath, &inioptions);
|
| 176 | + error = CopyFile(srcpath, destpath, TRUE);
|
| 177 | + error_loop:
|
| 178 | + if (!error)
|
169 | 179 | {
|
170 | 180 | error = GetLastError();
|
171 | | - if(error == ERROR_FILE_EXISTS)
|
| 181 | + if (error == ERROR_FILE_EXISTS)
|
172 | 182 | {
|
| 183 | + if (inioptions.NoOverwrite)
|
| 184 | + {
|
| 185 | + MessageBox(hwnd, _T("Cannot install DXGL. An INI file has \
|
| 186 | +been placed in your game folder prohibiting overwriting the existing DirectDraw \
|
| 187 | +library.\r\n\r\nIf you want to install DXGL, edit the dxgl.ini file in your game \
|
| 188 | +folder and set the NoOverwite value to false.\r\n\r\n\
|
| 189 | +A profile will still be created for your game but may not be compatible with the \
|
| 190 | +DirectDraw library in your game folder."), _T("Error"), MB_OK | MB_ICONERROR);
|
| 191 | + return 0; // Continue to install registry key anyway
|
| 192 | + }
|
| 193 | + if (!memcmp(inioptions.sha256, inioptions.sha256comp, 64))
|
| 194 | + // Detected original ddraw matches INI hash
|
| 195 | + {
|
| 196 | + error = CopyFile(srcpath, backuppath, FALSE);
|
| 197 | + if (!error)
|
| 198 | + {
|
| 199 | + error = GetLastError();
|
| 200 | + if ((error == ERROR_ACCESS_DENIED) && !admin)
|
| 201 | + {
|
| 202 | + _tcscpy(command, _T(" install "));
|
| 203 | + _tcscat(command, path);
|
| 204 | + ZeroMemory(&shex, sizeof(SHELLEXECUTEINFO));
|
| 205 | + shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
| 206 | + shex.lpVerb = _T("runas");
|
| 207 | + shex.fMask = SEE_MASK_NOCLOSEPROCESS;
|
| 208 | + _tcscat(installpath, _T("\\dxglcfg.exe"));
|
| 209 | + shex.lpFile = installpath;
|
| 210 | + shex.lpParameters = command;
|
| 211 | + ShellExecuteEx(&shex);
|
| 212 | + WaitForSingleObject(shex.hProcess, INFINITE);
|
| 213 | + GetExitCodeProcess(shex.hProcess, &exitcode);
|
| 214 | + return exitcode;
|
| 215 | + }
|
| 216 | + }
|
| 217 | + }
|
173 | 218 | HMODULE hmod = LoadLibrary(destpath);
|
174 | 219 | if(hmod)
|
175 | 220 | {
|
176 | | - if(GetProcAddress(hmod,"IsDXGLDDraw")) old_dxgl = TRUE;
|
| 221 | + if(GetProcAddress(hmod,"IsDXGLDDraw") || force) old_dxgl = TRUE;
|
| 222 | + else old_dxgl = FALSE;
|
177 | 223 | FreeLibrary(hmod);
|
178 | 224 | }
|
| 225 | + else
|
| 226 | + {
|
| 227 | + if (force) old_dxgl = TRUE;
|
| 228 | + else old_dxgl = FALSE;
|
| 229 | + }
|
179 | 230 | if(old_dxgl)
|
180 | 231 | {
|
181 | 232 | error = CopyFile(srcpath,destpath,FALSE);
|
182 | 233 | goto error_loop;
|
183 | 234 | }
|
| 235 | + else
|
| 236 | + {
|
| 237 | + // Prompt to overwrite
|
| 238 | + if (MessageBox(hwnd, _T("A custom DirectDraw library has been detected in \
|
| 239 | +your game folder. Would you like to replace it with DXGL?\r\n\r\n\
|
| 240 | +Warning: Installing DXGL will remove any customizations that the existing custom DirectDraw \
|
| 241 | +library may have."), _T("DXGL Config"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)
|
| 242 | + {
|
| 243 | + error = CopyFile(srcpath, destpath, FALSE);
|
| 244 | + goto error_loop;
|
| 245 | + }
|
| 246 | + }
|
184 | 247 | }
|
185 | 248 | if((error == ERROR_ACCESS_DENIED) && !admin)
|
186 | 249 | {
|
187 | | - _tcscpy(command,_T(" install "));
|
| 250 | + if(old_dxgl) _tcscpy(command,_T(" install "));
|
| 251 | + else _tcscpy(command, _T(" forceinstall "));
|
188 | 252 | _tcscat(command,path);
|
189 | 253 | ZeroMemory(&shex,sizeof(SHELLEXECUTEINFO));
|
190 | 254 | shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
— | — | @@ -203,7 +267,7 @@ |
204 | 268 | return 0;
|
205 | 269 | }
|
206 | 270 |
|
207 | | -DWORD DelApp(LPCTSTR path, BOOL admin)
|
| 271 | +DWORD DelApp(LPCTSTR path, BOOL admin, HWND hwnd)
|
208 | 272 | {
|
209 | 273 | BOOL installed = FALSE;
|
210 | 274 | TCHAR command[MAX_PATH + 32];
|
— | — | @@ -210,10 +274,14 @@ |
211 | 275 | BOOL old_dxgl = TRUE;
|
212 | 276 | DWORD sizeout = (MAX_PATH+1)*sizeof(TCHAR);
|
213 | 277 | TCHAR installpath[MAX_PATH+1];
|
| 278 | + TCHAR inipath[MAX_PATH + 1];
|
| 279 | + TCHAR backuppath[MAX_PATH + 1];
|
214 | 280 | HKEY hKeyInstall;
|
215 | 281 | HMODULE hmod;
|
216 | 282 | SHELLEXECUTEINFO shex;
|
217 | 283 | DWORD exitcode;
|
| 284 | + HANDLE exists;
|
| 285 | + app_ini_options inioptions;
|
218 | 286 | LONG error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\DXGL"), 0, KEY_READ, &hKeyInstall);
|
219 | 287 | if(error == ERROR_SUCCESS)
|
220 | 288 | {
|
— | — | @@ -225,6 +293,24 @@ |
226 | 294 | {
|
227 | 295 | GetModuleFileName(NULL,installpath,MAX_PATH+1);
|
228 | 296 | }
|
| 297 | + _tcsncpy(inipath, path, MAX_PATH + 1);
|
| 298 | + (_tcsrchr(inipath, _T('\\')))[1] = 0;
|
| 299 | + _tcsncpy(backuppath, path, MAX_PATH + 1);
|
| 300 | + (_tcsrchr(backuppath, _T('\\')))[1] = 0;
|
| 301 | + _tcscat(backuppath, _T("ddraw.dll.dxgl-backup"));
|
| 302 | + // Check for DXGL ini file and existing ddraw.dll
|
| 303 | + ReadAppINIOptions(inipath, &inioptions);
|
| 304 | + if (inioptions.NoOverwrite || inioptions.NoUninstall)
|
| 305 | + {
|
| 306 | + MessageBox(hwnd,_T("DXGL has not been removed from your game folder. \
|
| 307 | +An INI file has been found in your game folder prohibiting the DirectDraw \
|
| 308 | +library in your game folder from being deleted.\r\n\r\n\
|
| 309 | +If this is in error, you will have to manually delete ddraw.dll from your \
|
| 310 | +game folder. If your game was distributed by Steam or a similar service \
|
| 311 | +please verify your game files after removing the file, in case the game \
|
| 312 | +shipped with a custom DirectDraw library."), _T("Warning"), MB_OK | MB_ICONWARNING);
|
| 313 | + return 0; // Continue to delete registry profile.
|
| 314 | + }
|
229 | 315 | hmod = LoadLibrary(path);
|
230 | 316 | if(hmod)
|
231 | 317 | {
|
— | — | @@ -231,11 +317,11 @@ |
232 | 318 | if(!GetProcAddress(hmod,"IsDXGLDDraw")) old_dxgl = FALSE;
|
233 | 319 | FreeLibrary(hmod);
|
234 | 320 | }
|
| 321 | + else old_dxgl = FALSE;
|
235 | 322 | if(!old_dxgl) return 0;
|
236 | 323 | if(!DeleteFile(path))
|
237 | 324 | {
|
238 | 325 | error = GetLastError();
|
239 | | - if(error == ERROR_FILE_NOT_FOUND) return 0;
|
240 | 326 | if((error == ERROR_ACCESS_DENIED) && !admin)
|
241 | 327 | {
|
242 | 328 | _tcscpy(command,_T(" remove "));
|
— | — | @@ -252,8 +338,37 @@ |
253 | 339 | GetExitCodeProcess(shex.hProcess,&exitcode);
|
254 | 340 | return exitcode;
|
255 | 341 | }
|
256 | | - return error;
|
| 342 | + else if (error != ERROR_FILE_NOT_FOUND) return error;
|
257 | 343 | }
|
| 344 | + exists = CreateFile(backuppath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
| 345 | + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| 346 | + if (exists == INVALID_HANDLE_VALUE) return 0;
|
| 347 | + else
|
| 348 | + {
|
| 349 | + CloseHandle(exists);
|
| 350 | + error = MoveFile(backuppath, path);
|
| 351 | + if (!error)
|
| 352 | + {
|
| 353 | + error = GetLastError();
|
| 354 | + if ((error == ERROR_ACCESS_DENIED) && !admin)
|
| 355 | + {
|
| 356 | + _tcscpy(command, _T(" remove "));
|
| 357 | + _tcscat(command, path);
|
| 358 | + ZeroMemory(&shex, sizeof(SHELLEXECUTEINFO));
|
| 359 | + shex.cbSize = sizeof(SHELLEXECUTEINFO);
|
| 360 | + shex.lpVerb = _T("runas");
|
| 361 | + shex.fMask = SEE_MASK_NOCLOSEPROCESS;
|
| 362 | + _tcscat(installpath, _T("\\dxglcfg.exe"));
|
| 363 | + shex.lpFile = installpath;
|
| 364 | + shex.lpParameters = command;
|
| 365 | + ShellExecuteEx(&shex);
|
| 366 | + WaitForSingleObject(shex.hProcess, INFINITE);
|
| 367 | + GetExitCodeProcess(shex.hProcess, &exitcode);
|
| 368 | + return exitcode;
|
| 369 | + }
|
| 370 | + else return error;
|
| 371 | + }
|
| 372 | + }
|
258 | 373 | return 0;
|
259 | 374 | }
|
260 | 375 |
|
— | — | @@ -1617,7 +1732,7 @@ |
1618 | 1733 | _T("Profile already exists"), MB_OK | MB_ICONWARNING);
|
1619 | 1734 | break;
|
1620 | 1735 | }
|
1621 | | - err = AddApp(filename.lpstrFile, TRUE, FALSE);
|
| 1736 | + err = AddApp(filename.lpstrFile, TRUE, FALSE, FALSE, hWnd);
|
1622 | 1737 | if (!err)
|
1623 | 1738 | {
|
1624 | 1739 | LPTSTR newkey = MakeNewConfig(filename.lpstrFile);
|
— | — | @@ -1742,7 +1857,7 @@ |
1743 | 1858 | _tcscat(path, _T("\\ddraw.dll"));
|
1744 | 1859 | if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
|
1745 | 1860 | {
|
1746 | | - if (DelApp(path, FALSE)) failed = TRUE;
|
| 1861 | + if (DelApp(path, FALSE, hWnd)) failed = TRUE;
|
1747 | 1862 | }
|
1748 | 1863 | free(path);
|
1749 | 1864 | free(regbuffer);
|
— | — | @@ -1877,6 +1992,10 @@ |
1878 | 1993 | TCHAR installpath[MAX_PATH + 1];
|
1879 | 1994 | TCHAR srcpath[MAX_PATH + 1];
|
1880 | 1995 | TCHAR destpath[MAX_PATH + 1];
|
| 1996 | + TCHAR inipath[MAX_PATH + 1];
|
| 1997 | + TCHAR backuppath[MAX_PATH + 1];
|
| 1998 | + HANDLE exists;
|
| 1999 | + app_ini_options inioptions;
|
1881 | 2000 | HMODULE hmod;
|
1882 | 2001 | int i = 0;
|
1883 | 2002 | UpgradeConfig(); // Just to make sure the registry format is correct
|
— | — | @@ -1922,8 +2041,13 @@ |
1923 | 2042 | if (regbuffer[0] != 0)
|
1924 | 2043 | {
|
1925 | 2044 | _tcsncpy(destpath, regbuffer, MAX_PATH + 1);
|
1926 | | - _tcscat(destpath, _T("\\"));
|
1927 | | - _tcscat(destpath, _T("ddraw.dll"));
|
| 2045 | + _tcscat(destpath, _T("\\ddraw.dll"));
|
| 2046 | + _tcsncpy(inipath, regbuffer, MAX_PATH + 1);
|
| 2047 | + _tcscat(inipath, _T("\\dxgl.ini"));
|
| 2048 | + _tcsncpy(backuppath, regbuffer, MAX_PATH + 1);
|
| 2049 | + _tcscat(backuppath, _T("\\ddraw.dll.dxgl-backup"));
|
| 2050 | + ReadAppINIOptions(inipath, &inioptions);
|
| 2051 | + if (inioptions.NoOverwrite || inioptions.NoUninstall) continue;
|
1928 | 2052 | if (GetFileAttributes(destpath) != INVALID_FILE_ATTRIBUTES)
|
1929 | 2053 | {
|
1930 | 2054 | old_dxgl = FALSE;
|
— | — | @@ -1935,7 +2059,18 @@ |
1936 | 2060 | }
|
1937 | 2061 | if (_tcscmp(srcpath, destpath))
|
1938 | 2062 | {
|
1939 | | - if (old_dxgl) DeleteFile(destpath);
|
| 2063 | + if (old_dxgl)
|
| 2064 | + {
|
| 2065 | + DeleteFile(destpath);
|
| 2066 | + exists = CreateFile(backuppath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
| 2067 | + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
| 2068 | + if (exists == INVALID_HANDLE_VALUE) continue;
|
| 2069 | + else
|
| 2070 | + {
|
| 2071 | + CloseHandle(exists);
|
| 2072 | + MoveFile(backuppath, destpath);
|
| 2073 | + }
|
| 2074 | + }
|
1940 | 2075 | }
|
1941 | 2076 | }
|
1942 | 2077 | }
|
— | — | @@ -1982,11 +2117,15 @@ |
1983 | 2118 | }
|
1984 | 2119 | if(!_tcsnicmp(lpCmdLine,_T("install "),8))
|
1985 | 2120 | {
|
1986 | | - return AddApp(lpCmdLine+8,TRUE,TRUE);
|
| 2121 | + return AddApp(lpCmdLine+8,TRUE,TRUE,FALSE,NULL);
|
1987 | 2122 | }
|
| 2123 | + if(!_tcsnicmp(lpCmdLine,_T("forceinstall "),13))
|
| 2124 | + {
|
| 2125 | + return AddApp(lpCmdLine+8,TRUE,TRUE,TRUE,NULL);
|
| 2126 | + }
|
1988 | 2127 | if(!_tcsnicmp(lpCmdLine,_T("remove "),7))
|
1989 | 2128 | {
|
1990 | | - return DelApp(lpCmdLine+7,TRUE);
|
| 2129 | + return DelApp(lpCmdLine+7,TRUE,NULL);
|
1991 | 2130 | }
|
1992 | 2131 | icc.dwSize = sizeof(icc);
|
1993 | 2132 | icc.dwICC = ICC_WIN95_CLASSES;
|