ReactOS  0.4.15-dev-2972-gda2a567
sdbinst.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS sdbinst
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Application compatibility database installer
5  * COPYRIGHT: Copyright 2020 Max Korostil (mrmks04@yandex.ru)
6  */
7 
8 #include <tchar.h>
9 
10 #include <windef.h>
11 #include <winbase.h>
12 #include <winreg.h>
13 #include <strsafe.h>
14 #include <objbase.h>
15 #include <apphelp.h>
16 #include <shlwapi.h>
17 
18 #define APPCOMPAT_CUSTOM_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom"
19 #define APPCOMPAT_LAYERS_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom\\Layers"
20 #define APPCOMPAT_INSTALLEDSDB_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\InstalledSDB"
21 #define UNINSTALL_REG_PATH L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
22 #define DBPATH_KEY_NAME L"DatabasePath"
23 #define SDB_EXT L".sdb"
24 #define GUID_STR_LENGTH 38
25 #define GUID_SBD_NAME_LENGTH (GUID_STR_LENGTH + ARRAYSIZE(SDB_EXT))
26 
28 
29 HRESULT
31  _In_ PWCHAR sdbEntryName,
32  _In_ LPCWSTR dbGuid,
34  _In_ BOOL isInstall,
35  _In_ BOOL isExe)
36 {
37  WCHAR regName[MAX_PATH];
38  HKEY hKey = NULL;
40  HRESULT hres;
41 
42  hres = StringCchPrintfW(regName, MAX_PATH, L"%ls\\%ls",
44  sdbEntryName);
45  if (FAILED(hres))
46  {
47  wprintf(L"StringCchPrintfW error: 0x%08X\n", hres);
48  goto end;
49  }
50 
51  // Remove key
52  if (!isInstall)
53  {
56  {
58  }
59 
60  return HRESULT_FROM_WIN32(status);
61  }
62 
63  // Create main key
65  regName,
66  0,
67  NULL,
70  NULL,
71  &hKey,
72  NULL);
73  if (status != ERROR_SUCCESS)
74  {
75  wprintf(L"RegKeyCreateEx error: 0x%08X", status);
77  goto end;
78  }
79 
80  // Set installed time
82  dbGuid,
83  0,
84  REG_QWORD,
85  (PBYTE)&time,
86  sizeof(time));
87  if (status != ERROR_SUCCESS)
88  {
89  wprintf(L"RegSetValueExW error: 0x%08X", status);
91  goto end;
92  }
93 
94 end:
95  if (hKey)
96  {
98  }
99 
100  return hres;
101 }
102 
103 HRESULT
105  _In_ LPCWSTR dbName,
106  _In_ LPCWSTR sdbInstalledPath,
107  _In_ LPCWSTR guidDbStr)
108 {
109  WCHAR sdbinstPath[MAX_PATH];
110  WCHAR regName[MAX_PATH];
111  WCHAR uninstString[MAX_PATH];
112  HKEY hKey = NULL;
113  HRESULT hres;
114 
115  UINT count = GetSystemWindowsDirectory(sdbinstPath, MAX_PATH);
116  if (sdbinstPath[count - 1] != L'\\')
117  {
118  hres = StringCchCatW(sdbinstPath, MAX_PATH, L"\\");
119  if (FAILED(hres))
120  {
121  wprintf(L"StringCchCatW error: 0x%08X", hres);
122  goto end;
123  }
124  }
125 
126  // Full path to sdbinst.exe
127  hres = StringCchCatW(sdbinstPath, MAX_PATH, L"System32\\sdbinst.exe");
128  if (FAILED(hres))
129  {
130  wprintf(L"StringCchCatW error: 0x%08X", hres);
131  goto end;
132  }
133 
134  // Sdb GUID registry key
135  hres = StringCchPrintfW(regName, MAX_PATH, L"%ls\\%ls", UNINSTALL_REG_PATH, guidDbStr);
136  if (FAILED(hres))
137  {
138  wprintf(L"StringCchPrintfW error: 0x%08X", hres);
139  goto end;
140  }
141 
142  // Create main key
144  regName,
145  0,
146  NULL,
149  NULL,
150  &hKey,
151  NULL);
152 
153  if (status != ERROR_SUCCESS)
154  {
155  wprintf(L"RegKeyCreateEx error: 0x%08X", status);
157  goto end;
158  }
159 
160  // Set Display name
161  DWORD length = wcslen(dbName) * sizeof(WCHAR);
163  L"DisplayName",
164  0,
165  REG_SZ,
166  (PBYTE)dbName,
167  length + sizeof(WCHAR));
168  if (status != ERROR_SUCCESS)
169  {
170  wprintf(L"RegSetValueExW error: 0x%08X", status);
172  goto end;
173  }
174 
175  // Uninstall full string
176  hres = StringCchPrintfW(uninstString, MAX_PATH, L"%ls -u \"%ls\"", sdbinstPath, sdbInstalledPath);
177  if (FAILED(hres))
178  {
179  wprintf(L"StringCchPrintfW error: 0x%08X", hres);
180  goto end;
181  }
182 
183  // Set uninstall string
184  length = wcslen(uninstString) * sizeof(WCHAR);
186  L"UninstallString",
187  0,
188  REG_SZ,
189  (PBYTE)uninstString,
190  length + sizeof(WCHAR));
191  if (status != ERROR_SUCCESS)
192  {
193  wprintf(L"RegSetValueExW error: 0x%08X", status);
195  goto end;
196  }
197 
198 end:
199  if (hKey)
200  {
201  RegCloseKey(hKey);
202  }
203 
204  return hres;
205 }
206 
207 //
208 // Get database GUID id
209 //
210 BOOL
212  _In_ PDB pdb,
213  _In_ TAGID tagDb,
214  _Out_ GUID* guid)
215 {
216  TAGID tagDbId;
217 
218  tagDbId = SdbFindFirstTag(pdb, tagDb, TAG_DATABASE_ID);
219  if (!tagDbId)
220  {
221  wprintf(L"Can't find database id tag");
222  return FALSE;
223  }
224 
225  if (!SdbReadBinaryTag(pdb, tagDbId, (PBYTE)guid, sizeof(GUID)))
226  {
227  wprintf(L"Can't read database id");
228  return FALSE;
229  }
230 
231  return TRUE;
232 }
233 
234 HRESULT
236  _In_ PDB pdb,
237  _In_ TAGID tagDb,
238  _In_opt_ LPCWSTR guidDbStr,
240  _In_ BOOL isInstall)
241 {
243  TAGID tagLayerName;
244  TAGID prevTagLayer = 0;
245 
246  TAGID tagLayer = SdbFindFirstTag(pdb, tagDb, TAG_LAYER);
247 
248  // Add all layers to registry (AppCompatFlags)
249  while (tagLayer && (tagLayer != prevTagLayer))
250  {
251  tagLayerName = SdbFindFirstTag(pdb, tagLayer, TAG_NAME);
252  if (!tagLayerName)
253  {
255  break;
256  }
257 
258  LPWSTR name = SdbGetStringTagPtr(pdb, tagLayerName);
259 
260  res = RegisterSdbEntry(name, guidDbStr, time, isInstall, FALSE);
261  if (FAILED(res))
262  {
263  wprintf(L"Can't register layer\n");
264  break;
265  }
266 
267  prevTagLayer = tagLayer;
268  tagLayer = SdbFindNextTag(pdb, tagDb, tagLayer);
269  }
270 
271  return res;
272 }
273 
274 HRESULT
276  _In_ PDB pdb,
277  _In_ TAGID tagDb,
278  _In_opt_ LPCWSTR guidDbStr,
280  _In_ BOOL isInstall)
281 {
283  TAGID tagExeName;
284  TAGID tagExePrev = 0;
285 
286  TAGID tagExe = SdbFindFirstTag(pdb, tagDb, TAG_EXE);
287 
288  // Add all exe to registry (AppCompatFlags)
289  while (tagExe != 0 && (tagExe != tagExePrev))
290  {
291  tagExeName = SdbFindFirstTag(pdb, tagExe, TAG_NAME);
292  if (!tagExeName)
293  {
294  wprintf(L"Can't find exe tag\n");
296  break;
297  }
298 
299  LPWSTR name = SdbGetStringTagPtr(pdb, tagExeName);
300 
301  res = RegisterSdbEntry(name, guidDbStr, time, isInstall, TRUE);
302  if (FAILED(res))
303  {
304  wprintf(L"Can't register exe 0x%08X\n", res);
305  break;
306  }
307 
308  tagExePrev = tagExe;
309  tagExe = SdbFindNextTag(pdb, tagDb, tagExe);
310  }
311 
312  return res;
313 }
314 
315 HRESULT
317  _In_ LPCWSTR sourceSdbPath,
318  _In_ LPCWSTR destSdbPath)
319 {
321  PWCHAR pTmpSysdir = NULL;
322  SIZE_T destLen = wcslen(destSdbPath);
323  PWCHAR sysdirPath = (PWCHAR)HeapAlloc(GetProcessHeap(), 0, destLen * sizeof(WCHAR));
324 
325  if (sysdirPath == NULL)
326  {
328  goto end;
329  }
330 
331  // Get parent folder fo sdb file
332  CopyMemory(sysdirPath, destSdbPath, destLen * sizeof(WCHAR));
333  pTmpSysdir = StrRChrW(sysdirPath, sysdirPath + destLen, L'\\');
334  if (pTmpSysdir == NULL)
335  {
336  wprintf(L"Can't find directory separator\n");
337  goto end;
338  }
339  else
340  {
341  *pTmpSysdir = UNICODE_NULL;
342  }
343 
344  // Create directory if need
345  if (!CreateDirectory(sysdirPath, NULL))
346  {
347  error = GetLastError();
349  {
350  wprintf(L"Can't create folder %ls\n Error: 0x%08X\n", sysdirPath, error);
351  goto end;
352  }
354  }
355 
356  // Copy file
357  if (!CopyFile(sourceSdbPath, destSdbPath, TRUE))
358  {
359  error = GetLastError();
360  wprintf(L"Can't copy sdb file");
361  }
362 
363 end:
364  if (sysdirPath)
365  {
366  HeapFree(GetProcessHeap(), 0, sysdirPath);
367  }
368 
369  return HRESULT_FROM_WIN32(error);
370 }
371 
372 HRESULT
375  _In_ SIZE_T bufLen,
376  _In_ LPCWSTR guidDbStr)
377 {
378  ZeroMemory(buffer, bufLen * sizeof(WCHAR));
379 
380  // Can't use here SdbGetAppPatchDir, because Windows XP haven't this function
381  UINT count = GetSystemWindowsDirectory(buffer, bufLen);
382  if (buffer[count - 1] != L'\\')
383  {
384  buffer[count] = L'\\';
385  }
386 
387  HRESULT res = StringCchCatW(buffer, bufLen, L"AppPatch\\Custom\\");
388  if (FAILED(res))
389  {
390  goto end;
391  }
392 
393  res = StringCchCatW(buffer, bufLen, guidDbStr);
394 
395 end:
396  return res;
397 }
398 
399 BOOL
401  _In_ LPCWSTR sdbPath)
402 {
403  BOOL res = FALSE;
404  PDB pdb = NULL;
405  TAGID tagDb;
406  TAGID tagDbName;
407  GUID dbGuid = {0};
408  FILETIME systemTime = {0};
409  ULARGE_INTEGER currentTime = {0};
410  WCHAR sysdirPatchPath[MAX_PATH];
411  WCHAR guidDbStr[GUID_SBD_NAME_LENGTH];
412 
413  GetSystemTimeAsFileTime(&systemTime);
414  currentTime.LowPart = systemTime.dwLowDateTime;
415  currentTime.HighPart = systemTime.dwHighDateTime;
416 
417  // Open database
418  pdb = SdbOpenDatabase(sdbPath, DOS_PATH);
419  if (pdb == NULL)
420  {
421  wprintf(L"Can't open database %ls\n", sdbPath);
422  goto end;
423  }
424 
426  if (!tagDb)
427  {
428  wprintf(L"Can't find database tag\n");
429  goto end;
430  }
431 
432  // Get database GUID
433  if (!GetSdbGuid(pdb, tagDb, &dbGuid))
434  {
435  wprintf(L"GetSdbGuid error\n");
436  goto end;
437  }
438 
439  StringFromGUID2(&dbGuid, guidDbStr, GUID_SBD_NAME_LENGTH);
441  if (FAILED(hres))
442  {
443  wprintf(L"StringCchCatW error 0x%08X\n", hres);
444  goto end;
445  }
446 
447  wprintf(L"Database guid %ls\n", guidDbStr);
448 
449  tagDbName = SdbFindFirstTag(pdb, tagDb, TAG_NAME);
450  if (!tagDbName)
451  {
452  wprintf(L"Can't get tag name\n");
453  goto end;
454  }
455 
456  LPWSTR dbName = SdbGetStringTagPtr(pdb, tagDbName);
457  wprintf(L"Database name %ls\n", dbName);
458 
459  // Process exe tags
460  hres = ProcessExe(pdb, tagDb, guidDbStr, currentTime.QuadPart, TRUE);
461  if (FAILED(hres))
462  {
463  wprintf(L"Process exe failed. Status: 0x%08X", res);
464  goto end;
465  }
466 
467  // Proess layer tags
468  hres = ProcessLayers(pdb, tagDb, guidDbStr, currentTime.QuadPart, TRUE);
469  if (FAILED(hres))
470  {
471  wprintf(L"Process layers failed. Status: 0x%08X", res);
472  goto end;
473  }
474 
475  // Create full path to sdb in system folder
476  hres = BuildPathToSdb(sysdirPatchPath, ARRAYSIZE(sysdirPatchPath), guidDbStr);
477  if (FAILED(hres))
478  {
479  wprintf(L"Build path error\n");
480  goto end;
481  }
482 
483  wprintf(L"file path %ls\n", sysdirPatchPath);
484 
485  res = CopySdbToAppPatch(sdbPath, sysdirPatchPath);
486  if (FAILED(res))
487  {
488  wprintf(L"Copy sdb error. Status: 0x%08X\n", res);
489  goto end;
490  }
491 
492  AddUninstallKey(dbName, sysdirPatchPath, guidDbStr);
493 
494  // Registration
495  if (!SdbRegisterDatabaseEx(sysdirPatchPath, SDB_DATABASE_SHIM, &currentTime.QuadPart))
496  {
497  wprintf(L"SdbRegisterDatabaseEx failed");
498  goto end;
499  }
500 
501  res = TRUE;
502 
503 end:
504  if (pdb)
505  {
507  }
508 
509  return res;
510 }
511 
512 HRESULT
514  _In_ LPCWSTR keyName)
515 {
516  HKEY hKey = NULL;
518 
521  0,
522  NULL,
525  NULL,
526  &hKey,
527  NULL);
528 
529  if (status != ERROR_SUCCESS)
530  {
532  goto end;
533  }
534 
535  status = RegDeleteKeyW(hKey, keyName);
536  if (status != ERROR_SUCCESS)
537  {
539  }
540 
541 end:
542  if (hKey)
543  {
544  RegCloseKey(hKey);
545  }
546 
547  return hres;
548 }
549 
550 BOOL
552  _In_ LPWSTR sdbPath)
553 {
554  BOOL res = FALSE;
555  PWCHAR sdbName = NULL;
556  PDB pdb;
557  TAGID tagDb;
558  GUID dbGuid = {0};
559  WCHAR guidDbStr[GUID_SBD_NAME_LENGTH];
560 
561  SIZE_T sdbPathLen = wcslen(sdbPath);
562  sdbName = sdbPath + sdbPathLen;
563 
564  wprintf(L"uninstall path %ls\n", sdbPath);
565  sdbName = StrRChrW(sdbPath, sdbPath + sdbPathLen, L'\\');
566  if (sdbName == NULL)
567  {
568  sdbName = sdbPath;
569  }
570  else
571  {
572  sdbName++;
573  }
574 
575  wprintf(L"uninstall name %ls\n", sdbName);
576 
577  // open sdb
578  pdb = SdbOpenDatabase(sdbPath, DOS_PATH);
579  if (pdb == NULL)
580  {
581  wprintf(L"Can't open database %ls\n", sdbPath);
582  return FALSE;
583  }
584 
586  if (!tagDb)
587  {
588  wprintf(L"Can't find database tag\n");
589  goto end;
590  }
591 
592  if (!GetSdbGuid(pdb, tagDb, &dbGuid))
593  {
594  wprintf(L"GetSdbGuid error\n");
595  goto end;
596  }
597 
598  // Database name must be GUID string
599  if (wcslen(sdbName) + 1 != GUID_SBD_NAME_LENGTH)
600  {
601  StringFromGUID2(&dbGuid, guidDbStr, GUID_SBD_NAME_LENGTH);
603  return SdbUninstallByGuid(guidDbStr);
604  }
605 
606  //remove regkey in appatch/custom
607  HRESULT hres = ProcessExe(pdb, tagDb, NULL, 0, FALSE);
608  if (FAILED(hres))
609  {
610  wprintf(L"Process exe fail\n");
611  goto end;
612  }
613 
614  hres = ProcessLayers(pdb, tagDb, NULL, 0, FALSE);
615  if (FAILED(hres))
616  {
617  wprintf(L"Process layers fail\n");
618  goto end;
619  }
620 
622  pdb = NULL;
623 
624  hres = DeleteUninstallKey(sdbName);
625  if (FAILED(hres))
626  {
627  wprintf(L"Remove uninstall key fail\n");
628  }
629 
630  if (!SdbUnregisterDatabase(&dbGuid))
631  {
632  wprintf(L"SdbUnregisterDatabase\n");
633  return FALSE;
634  }
635 
637  if (!DeleteFileW(sdbPath))
638  {
639  wprintf(L"Remove file fail 0x%08X\n", GetLastError());
640  return FALSE;
641  }
642 
643  res = TRUE;
644 
645 end:
646  if (pdb)
648  return res;
649 }
650 
651 BOOL
654 {
656 
657  if (length == GUID_STR_LENGTH &&
658  guidStr[0] == L'{' &&
659  guidStr[GUID_STR_LENGTH - 1] == L'}' &&
660  guidStr[9] == L'-' &&
661  guidStr[14] == L'-' &&
662  guidStr[19] == L'-' &&
663  guidStr[24] == L'-')
664  {
665  return TRUE;
666  }
667 
668  return FALSE;
669 }
670 
671 BOOL
673  _In_ LPWSTR guidSdbStr)
674 {
675  BOOL res = FALSE;
676  HKEY hKey = NULL;
677  HKEY guidKey = NULL;
678  LSTATUS status;
679  WCHAR dbPath[MAX_PATH];
680  DWORD keyValSize = sizeof(dbPath);
681 
682  if (!ValidateGuidString(guidSdbStr))
683  {
684  wprintf(L"Invalid GUID: %ls\n", guidSdbStr);
685  return res;
686  }
687 
689 
690  if (status != ERROR_SUCCESS)
691  {
692  wprintf(L"RegOpenKeyW error: 0x%08X", status);
693  goto end;
694  }
695 
696  status = RegOpenKeyExW(hKey, guidSdbStr, 0, KEY_READ | KEY_QUERY_VALUE, &guidKey);
697 
698  if (status != ERROR_SUCCESS)
699  {
700  wprintf(L"Cant open key: 0x%08X %ls\n", status, guidSdbStr);
701  goto end;
702  }
703 
704  status = RegQueryValueExW(guidKey, DBPATH_KEY_NAME, NULL, NULL, (LPBYTE)dbPath, &keyValSize);
705  if (status != ERROR_SUCCESS)
706  {
707  wprintf(L"RegQueryValueExW: 0x%08X\n", status);
708  goto end;
709  }
710 
711  res = SdbUninstall(dbPath);
712 
713 end:
714  if (hKey)
715  {
716  RegCloseKey(hKey);
717  }
718 
719  if (guidKey)
720  {
721  RegCloseKey(guidKey);
722  }
723 
724  return res;
725 }
726 
727 BOOL
729  _In_ LPWSTR nameSdbStr)
730 {
731  BOOL res = FALSE;
732  LSTATUS status;
733  HKEY hKey = NULL;
734  HKEY subKey = NULL;
735  DWORD index = 0;
736  WCHAR keyName[MAX_PATH];
737  DWORD keyNameLen = ARRAYSIZE(keyName);
738  DWORD keyValSize;
739  WCHAR dbDescript[MAX_PATH];
740  WCHAR dbPath[MAX_PATH];
741 
743 
744  if (status != ERROR_SUCCESS)
745  {
746  wprintf(L"RegOpenKeyW error: 0x%08X", status);
747  goto end;
748  }
749 
750  status = RegEnumKeyEx(hKey, index, keyName, &keyNameLen, NULL, NULL, NULL, NULL);
751  wprintf(L"0x%08X %d %ls \n", status, keyNameLen, keyName);
752 
753  // Search database GUID by name
754  while (status == ERROR_SUCCESS)
755  {
756  status = RegOpenKeyExW(hKey, keyName, 0, KEY_READ | KEY_QUERY_VALUE, &subKey);
757  if (status != ERROR_SUCCESS)
758  {
759  break;
760  }
761 
762  keyValSize = sizeof(dbDescript);
763  status = RegQueryValueExW(subKey, L"DatabaseDescription", NULL, NULL, (LPBYTE)dbDescript, &keyValSize);
764  if (status != ERROR_SUCCESS)
765  {
766  break;
767  }
768 
769  wprintf(L"dbdescript: %ls \n", dbDescript);
770 
771  if (_wcsnicmp(dbDescript, nameSdbStr, keyNameLen) == 0)
772  {
773  // Take db full path
774  keyValSize = sizeof(dbPath);
775  status = RegQueryValueExW(subKey, DBPATH_KEY_NAME, NULL, NULL, (LPBYTE)dbPath, &keyValSize);
776  if (status != ERROR_SUCCESS)
777  {
778  dbPath[0] = UNICODE_NULL;
779  break;
780  }
781 
782  wprintf(L"dbpath: 0x%08X %ls \n", status, dbPath);
783  RegCloseKey(subKey);
784  break;
785  }
786 
787  RegCloseKey(subKey);
788 
789  keyName[0] = UNICODE_NULL;
790 
791  ++index;
792  keyNameLen = ARRAYSIZE(keyName);
793  status = RegEnumKeyExW(hKey, index, keyName, &keyNameLen, NULL, NULL, NULL, NULL);
794  }
795 
796  RegCloseKey(hKey);
797 
798  if (dbPath[0] != UNICODE_NULL)
799  {
800  res = SdbUninstall(dbPath);
801  }
802 
803 end:
804  return res;
805 }
806 
807 
808 void
810 {
811  /* FIXME: to be localized */
812  wprintf(L"Using: sdbinst [-?][-q][-u][-g][-n] foo.sdb | {guid} | \"name\" \n"
813  L"-? - show help\n"
814  L"-u - uninstall\n"
815  L"-g - {guid} file GUID (only uninstall)\n"
816  L"-n - \"name\" - file name (only uninstall)\n");
817 }
818 
819 int _tmain(int argc, LPWSTR argv[])
820 {
821  LPWSTR sdbPath = NULL;
822  BOOL isInstall = TRUE;
823  BOOL isUninstByGuid = FALSE;
824  BOOL isUninstByName = FALSE;
825  BOOL success = FALSE;
826  LPWSTR guidSdbStr = NULL;
827  LPWSTR nameSdbStr = NULL;
828 
829  if (argc < 2)
830  {
831  ShowHelp();
832  }
833 
834  for (int i = 1; i < argc; ++i)
835  {
836  if (argv[i][0] != L'-')
837  {
838  sdbPath = argv[i];
839  break;
840  }
841 
842  switch (argv[i][1])
843  {
844  case L'?':
845  ShowHelp();
846  return ERROR_SUCCESS;
847  break;
848 
849  case L'u':
850  isInstall = FALSE;
851  break;
852 
853  case L'g':
854  ++i;
855 
856  if (i >= argc)
857  {
859  }
860 
861  guidSdbStr = argv[i];
862  wprintf(L"guidSdbStr %ls\n", guidSdbStr);
863 
864  isUninstByGuid = TRUE;
865  isInstall = FALSE;
866  break;
867 
868  case L'n':
869  ++i;
870 
871  if (i >= argc)
872  {
874  }
875 
876  nameSdbStr = argv[i];
877  wprintf(L"nameSdbStr %ls\n", nameSdbStr);
878 
879  isUninstByName = TRUE;
880  isInstall = FALSE;
881  break;
882  }
883  }
884 
885  if (isInstall)
886  {
887  wprintf(L"install\n");
888  success = SdbInstall(sdbPath);
889  }
890  else if (isUninstByGuid)
891  {
892  wprintf(L"uninstall by GUID\n");
893  success = SdbUninstallByGuid(guidSdbStr);
894  }
895  else if (isUninstByName)
896  {
897  wprintf(L"uninstall by name\n");
898  success = SdbUninstallByName(nameSdbStr);
899  }
900  else
901  {
902  wprintf(L"uninstall\n");
903  success = SdbUninstall(sdbPath);
904  }
905 
906  if (!success)
907  {
908  wprintf(isInstall ? L"Sdb install failed\n" : L"Sdb uninstall failed\n");
909  return -1;
910  }
911 
912  return ERROR_SUCCESS;
913 }
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
#define SDB_EXT
Definition: sdbinst.c:23
#define APPCOMPAT_INSTALLEDSDB_REG_PATH
Definition: sdbinst.c:20
#define GUID_SBD_NAME_LENGTH
Definition: sdbinst.c:25
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static int argc
Definition: ServiceArgs.c:12
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define TAG_NAME
Definition: vfat.h:553
static PDB pdb
Definition: db.cpp:172
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define _In_opt_
Definition: ms_sal.h:309
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL GetSdbGuid(_In_ PDB pdb, _In_ TAGID tagDb, _Out_ GUID *guid)
Definition: sdbinst.c:211
#define error(str)
Definition: mkdosfs.c:1605
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define _Out_
Definition: ms_sal.h:345
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define TAG_DATABASE
Definition: db.cpp:85
GLuint GLuint GLsizei count
Definition: gl.h:1545
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid)
Definition: sdbread.c:375
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1664
$ULONG LowPart
Definition: ntbasedef.h:569
GLuint buffer
Definition: glext.h:5915
uint16_t * PWCHAR
Definition: typedefs.h:56
#define DBPATH_KEY_NAME
Definition: sdbinst.c:22
__u16 time
Definition: mkdosfs.c:366
#define wprintf(...)
Definition: whoami.c:18
#define argv
Definition: mplay32.c:18
BOOL SdbInstall(_In_ LPCWSTR sdbPath)
Definition: sdbinst.c:400
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
#define TAG_EXE
Definition: db.cpp:87
DWORD dwHighDateTime
Definition: mapidefs.h:66
const GUID * guid
static WCHAR guidStr[]
Definition: asn.c:531
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define APPCOMPAT_LAYERS_REG_PATH
Definition: sdbinst.c:19
#define SDB_DATABASE_SHIM
Definition: apphelp.h:28
#define _In_
Definition: ms_sal.h:308
HRESULT RegisterSdbEntry(_In_ PWCHAR sdbEntryName, _In_ LPCWSTR dbGuid, _In_ ULONGLONG time, _In_ BOOL isInstall, _In_ BOOL isExe)
Definition: sdbinst.c:30
HRESULT ProcessLayers(_In_ PDB pdb, _In_ TAGID tagDb, _In_opt_ LPCWSTR guidDbStr, _In_opt_ ULONGLONG time, _In_ BOOL isInstall)
Definition: sdbinst.c:235
GLuint index
Definition: glext.h:6031
BOOL SdbUninstallByName(_In_ LPWSTR nameSdbStr)
Definition: sdbinst.c:728
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
void ShowHelp()
Definition: sdbinst.c:809
TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:231
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
$ULONG HighPart
Definition: ntbasedef.h:570
HRESULT hres
Definition: protocol.c:465
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
uint64_t ULONGLONG
Definition: typedefs.h:67
#define GUID_STR_LENGTH
Definition: sdbinst.c:24
#define MAX_PATH
Definition: compat.h:34
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define CopyMemory
Definition: winbase.h:1662
HRESULT ProcessExe(_In_ PDB pdb, _In_ TAGID tagDb, _In_opt_ LPCWSTR guidDbStr, _In_opt_ ULONGLONG time, _In_ BOOL isInstall)
Definition: sdbinst.c:275
unsigned long DWORD
Definition: ntddk_ex.h:95
#define success(from, fromstr, to, tostr)
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
BOOL WINAPI SdbRegisterDatabaseEx(_In_ LPCWSTR pszDatabasePath, _In_ DWORD dwDatabaseType, _In_opt_ const PULONGLONG pTimeStamp)
Definition: apphelp.c:261
TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag)
Definition: sdbread.c:208
GLuint GLuint end
Definition: gl.h:1545
void WINAPI SdbCloseDatabase(PDB)
Definition: sdbapi.c:373
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CopyFile
Definition: winbase.h:3597
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
#define RegEnumKeyEx
Definition: winreg.h:510
#define UNINSTALL_REG_PATH
Definition: sdbinst.c:21
BOOL SdbUninstallByGuid(_In_ LPWSTR guidSdbStr)
Definition: sdbinst.c:672
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int _tmain(int argc, LPWSTR argv[])
Definition: sdbinst.c:819
HRESULT CopySdbToAppPatch(_In_ LPCWSTR sourceSdbPath, _In_ LPCWSTR destSdbPath)
Definition: sdbinst.c:316
HRESULT BuildPathToSdb(_In_ PWCHAR buffer, _In_ SIZE_T bufLen, _In_ LPCWSTR guidDbStr)
Definition: sdbinst.c:373
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxAutoRegKey hKey
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define APPCOMPAT_CUSTOM_REG_PATH
Definition: sdbinst.c:18
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define TAG_LAYER
Definition: db.cpp:90
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define TAGID_ROOT
Definition: db.cpp:39
#define ERROR_NOT_FOUND
Definition: winerror.h:690
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BOOL WINAPI SdbUnregisterDatabase(_In_ const GUID *pguidDB)
Definition: apphelp.c:406
Definition: name.c:38
GLuint res
Definition: glext.h:9613
#define REG_QWORD
Definition: sdbapi.c:597
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define TAG_DATABASE_ID
Definition: db.cpp:122
BOOL SdbUninstall(_In_ LPWSTR sdbPath)
Definition: sdbinst.c:551
BOOL WINAPI SdbReadBinaryTag(PDB pdb, TAGID tagid, PBYTE buffer, DWORD size)
Definition: sdbread.c:338
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
DWORD TAGID
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:556
static SERVICE_STATUS status
Definition: service.c:31
HRESULT AddUninstallKey(_In_ LPCWSTR dbName, _In_ LPCWSTR sdbInstalledPath, _In_ LPCWSTR guidDbStr)
Definition: sdbinst.c:104
BYTE * PBYTE
Definition: pedump.c:66
BOOL ValidateGuidString(_In_ PWCHAR guidStr)
Definition: sdbinst.c:652
HRESULT DeleteUninstallKey(_In_ LPCWSTR keyName)
Definition: sdbinst.c:513
#define HeapFree(x, y, z)
Definition: compat.h:594
DWORD dwLowDateTime
Definition: mapidefs.h:65
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
PDB WINAPI SdbOpenDatabase(LPCWSTR path, PATH_TYPE type)
Definition: sdbapi.c:329
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97