| 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;
|