mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[SDBINST] Add uninstall option
This commit is contained in:
parent
4e4328ac8a
commit
7fd004e50b
2 changed files with 218 additions and 40 deletions
|
@ -9,34 +9,47 @@
|
|||
|
||||
|
||||
|
||||
#define APPCOMPAT_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom\\"
|
||||
#define APPCOMPAT_CUSTOM_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom"
|
||||
#define APPCOMPAT_LAYERS_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"
|
||||
#define UNINSTALL_REG_PATH L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
|
||||
|
||||
HRESULT
|
||||
RegisterSdbEntry(
|
||||
_In_ PWCHAR sdbEntryName,
|
||||
_In_ LPCWSTR dbGuid,
|
||||
_In_ ULONGLONG time)
|
||||
_In_ ULONGLONG time,
|
||||
_In_ BOOL isInstall,
|
||||
_In_ BOOL isExe)
|
||||
{
|
||||
WCHAR regName[MAX_PATH] = {0};
|
||||
HKEY hKey;
|
||||
LSTATUS status;
|
||||
|
||||
HRESULT hres = StringCchPrintf(regName, sizeof(regName) / sizeof(WCHAR), L"%ls\\%ls", APPCOMPAT_REG_PATH, sdbEntryName);
|
||||
HRESULT hres = StringCchPrintf(regName, sizeof(regName) / sizeof(WCHAR), L"%ls\\%ls",
|
||||
isExe ? APPCOMPAT_CUSTOM_REG_PATH : APPCOMPAT_LAYERS_REG_PATH, sdbEntryName);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"StringCchPrintfW error: 0x%08X", hres);
|
||||
wprintf(L"StringCchPrintfW error: 0x%08X\n", hres);
|
||||
goto end;
|
||||
}
|
||||
|
||||
LSTATUS status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
regName,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,
|
||||
NULL,
|
||||
&hKey,
|
||||
NULL);
|
||||
// Remove key
|
||||
if (!isInstall)
|
||||
{
|
||||
status = RegDeleteKey(HKEY_LOCAL_MACHINE, regName);
|
||||
return HRESULT_FROM_WIN32(status);
|
||||
}
|
||||
|
||||
// Create main key
|
||||
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
regName,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,
|
||||
NULL,
|
||||
&hKey,
|
||||
NULL);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -45,6 +58,7 @@ RegisterSdbEntry(
|
|||
goto end;
|
||||
}
|
||||
|
||||
// Set instlled time
|
||||
status = RegSetValueEx(hKey,
|
||||
dbGuid,
|
||||
0,
|
||||
|
@ -80,12 +94,14 @@ AddUninstallKey(
|
|||
sdbinstPath[count] = L'\\';
|
||||
}
|
||||
|
||||
// Full path to sdbinst.exe
|
||||
hres = StringCchCat(sdbinstPath, sizeof(sdbinstPath) / sizeof(WCHAR), L"System32\\sdbinst.exe");
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"StringCchCat error: 0x%08X", hres);
|
||||
}
|
||||
|
||||
// Sdb guid reg key
|
||||
hres = StringCchPrintf(regName, sizeof(regName) / sizeof(WCHAR), L"%ls\\%ls", UNINSTALL_REG_PATH, guidDbStr);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
|
@ -96,6 +112,7 @@ AddUninstallKey(
|
|||
wprintf(L"%ls\n", sdbinstPath);
|
||||
wprintf(L"%ls\n", regName);
|
||||
|
||||
// Create main key
|
||||
LSTATUS status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
regName,
|
||||
0,
|
||||
|
@ -113,6 +130,7 @@ AddUninstallKey(
|
|||
goto end;
|
||||
}
|
||||
|
||||
// Set Display name
|
||||
DWORD length = wcslen(dbName) * sizeof(WCHAR);
|
||||
status = RegSetValueEx(hKey,
|
||||
L"DisplayName",
|
||||
|
@ -127,7 +145,7 @@ AddUninstallKey(
|
|||
goto end;
|
||||
}
|
||||
|
||||
// Uninst string
|
||||
// Uninstall full string
|
||||
hres = StringCchPrintf(uninstString, sizeof(uninstString) / sizeof(WCHAR), L"%ls -u \"%ls\"", sdbinstPath, sdbInstalledPath);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
|
@ -135,8 +153,7 @@ AddUninstallKey(
|
|||
goto end;
|
||||
}
|
||||
|
||||
//wprintf(L"%ls\n", uninstString);
|
||||
|
||||
// Set uninstall string
|
||||
length = wcslen(uninstString) * sizeof(WCHAR);
|
||||
status = RegSetValueEx(hKey,
|
||||
L"UninstallString",
|
||||
|
@ -188,15 +205,18 @@ HRESULT
|
|||
ProcessLayers(
|
||||
_In_ PDB pdb,
|
||||
_In_ TAGID tagDb,
|
||||
_In_ LPCWSTR guidDbStr,
|
||||
_In_ ULONGLONG time)
|
||||
_In_opt_ LPCWSTR guidDbStr,
|
||||
_In_opt_ ULONGLONG time,
|
||||
_In_ BOOL isInstall)
|
||||
{
|
||||
HRESULT res = ERROR_SUCCESS;
|
||||
TAGID tagLayerName;
|
||||
TAGID prevTagLayer = 0;
|
||||
|
||||
TAGID tagLayer = SdbFindFirstTag(pdb, tagDb, TAG_LAYER);
|
||||
|
||||
while (tagLayer)
|
||||
// Add all exe to registry (AppCompatFlags)
|
||||
while (tagLayer && (tagLayer != prevTagLayer))
|
||||
{
|
||||
tagLayerName = SdbFindFirstTag(pdb, tagLayer, TAG_NAME);
|
||||
if (!tagLayerName)
|
||||
|
@ -208,14 +228,15 @@ ProcessLayers(
|
|||
LPWSTR name = SdbGetStringTagPtr(pdb, tagLayerName);
|
||||
wprintf(L"Layer name %ls", name);
|
||||
|
||||
res = RegisterSdbEntry(name, guidDbStr, time);
|
||||
res = RegisterSdbEntry(name, guidDbStr, time, isInstall, FALSE);
|
||||
if (FAILED(res))
|
||||
{
|
||||
wprintf(L"Can't register layer\n");
|
||||
break;
|
||||
}
|
||||
|
||||
tagLayer = SdbFindNextTag(pdb, tagDb, TAG_LAYER);
|
||||
prevTagLayer = tagLayer;
|
||||
tagLayer = SdbFindNextTag(pdb, tagDb, tagLayer);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -225,16 +246,18 @@ HRESULT
|
|||
ProcessExe(
|
||||
_In_ PDB pdb,
|
||||
_In_ TAGID tagDb,
|
||||
_In_ LPCWSTR guidDbStr,
|
||||
_In_ ULONGLONG time
|
||||
)
|
||||
_In_opt_ LPCWSTR guidDbStr,
|
||||
_In_opt_ ULONGLONG time,
|
||||
_In_ BOOL isInstall)
|
||||
{
|
||||
HRESULT res = ERROR_SUCCESS;
|
||||
TAGID tagExeName;
|
||||
TAGID tagExePrev = 0;
|
||||
|
||||
TAGID tagExe = SdbFindFirstTag(pdb, tagDb, TAG_EXE);
|
||||
|
||||
while (tagExe)
|
||||
// Add all exe to registry (AppCompatFlags)
|
||||
while (tagExe != 0 && (tagExe != tagExePrev))
|
||||
{
|
||||
tagExeName = SdbFindFirstTag(pdb, tagExe, TAG_NAME);
|
||||
if (!tagExeName)
|
||||
|
@ -247,14 +270,15 @@ ProcessExe(
|
|||
LPWSTR name = SdbGetStringTagPtr(pdb, tagExeName);
|
||||
wprintf(L"Exe name %ls\n", name);
|
||||
|
||||
res = RegisterSdbEntry(name, guidDbStr, time);
|
||||
res = RegisterSdbEntry(name, guidDbStr, time, isInstall, TRUE);
|
||||
if (FAILED(res))
|
||||
{
|
||||
wprintf(L"Can't register exe\n");
|
||||
wprintf(L"Can't register exe 0x%08X\n", res);
|
||||
break;
|
||||
}
|
||||
|
||||
tagExe = SdbFindNextTag(pdb, tagDb, TAG_EXE);
|
||||
tagExePrev = tagExe;
|
||||
tagExe = SdbFindNextTag(pdb, tagDb, tagExe);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -276,6 +300,7 @@ CopySdbToAppPatch(
|
|||
goto end;
|
||||
}
|
||||
|
||||
// Get parent folder fo sdb file
|
||||
CopyMemory(sysdirPath, destSdbPath, destLen * sizeof(WCHAR));
|
||||
pTmpSysdir = sysdirPath + destLen;
|
||||
|
||||
|
@ -287,6 +312,7 @@ CopySdbToAppPatch(
|
|||
|
||||
wprintf(L"%ls\n", sysdirPath);
|
||||
|
||||
// Create directory if need
|
||||
if (!CreateDirectory(sysdirPath, NULL))
|
||||
{
|
||||
error = GetLastError();
|
||||
|
@ -298,6 +324,7 @@ CopySdbToAppPatch(
|
|||
error = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Copy file
|
||||
if (!CopyFile(sourceSdbPath, destSdbPath, TRUE))
|
||||
{
|
||||
error = GetLastError();
|
||||
|
@ -355,6 +382,7 @@ SdbInstall(
|
|||
currentTime.LowPart = systemTime.dwLowDateTime;
|
||||
currentTime.HighPart = systemTime.dwHighDateTime;
|
||||
|
||||
// Open db
|
||||
pdb = SdbOpenDatabase(sdbPath, DOS_PATH);
|
||||
if (pdb == NULL)
|
||||
{
|
||||
|
@ -369,7 +397,7 @@ SdbInstall(
|
|||
goto end;
|
||||
}
|
||||
|
||||
//
|
||||
// Get db guid
|
||||
if (!GetSdbGuid(pdb, tagDb, &dbGuid))
|
||||
{
|
||||
wprintf(L"GetSdbGuid error\n");
|
||||
|
@ -396,14 +424,16 @@ SdbInstall(
|
|||
LPWSTR dbName = SdbGetStringTagPtr(pdb, tagDbName);
|
||||
wprintf(L"Database name %ls\n", dbName);
|
||||
|
||||
hres = ProcessExe(pdb, tagDb, guidDbStr, currentTime.QuadPart);
|
||||
// Process exe tags
|
||||
hres = ProcessExe(pdb, tagDb, guidDbStr, currentTime.QuadPart, TRUE);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"Process exe failed. Status: 0x%08X", res);
|
||||
goto end;
|
||||
}
|
||||
|
||||
hres = ProcessLayers(pdb, tagDb, guidDbStr, currentTime.QuadPart);
|
||||
// Proess layer tags
|
||||
hres = ProcessLayers(pdb, tagDb, guidDbStr, currentTime.QuadPart, TRUE);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"Process layers failed. Status: 0x%08X", res);
|
||||
|
@ -413,6 +443,7 @@ SdbInstall(
|
|||
SIZE_T bufLen = MAX_PATH * 2;
|
||||
sysdirPatchPath = (PWCHAR)HeapAlloc(GetProcessHeap(), 0, bufLen * sizeof(WCHAR));
|
||||
|
||||
// Create full path tos db in system folder
|
||||
hres = BuildPathToSdb(&sysdirPatchPath, bufLen, guidDbStr);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
|
@ -431,6 +462,7 @@ SdbInstall(
|
|||
|
||||
AddUninstallKey(dbName, sysdirPatchPath, guidDbStr);
|
||||
|
||||
// Registration
|
||||
if (!SdbRegisterDatabaseEx(sysdirPatchPath, SDB_DATABASE_SHIM, ¤tTime.QuadPart))
|
||||
{
|
||||
wprintf(L"SdbRegisterDatabaseEx UNSUCCESS");
|
||||
|
@ -448,6 +480,117 @@ end:
|
|||
return res;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DeleteUninstallKey(
|
||||
_In_ LPCWSTR keyName)
|
||||
{
|
||||
HKEY hKey;
|
||||
HRESULT hres = HRESULT_FROM_WIN32(ERROR_SUCCESS);
|
||||
|
||||
LSTATUS status = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
UNINSTALL_REG_PATH,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,
|
||||
NULL,
|
||||
&hKey,
|
||||
NULL);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
hres = HRESULT_FROM_WIN32(status);
|
||||
goto end;
|
||||
}
|
||||
|
||||
status = RegDeleteKey(hKey, keyName);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
hres = HRESULT_FROM_WIN32(status);
|
||||
}
|
||||
|
||||
end:
|
||||
return hres;
|
||||
}
|
||||
|
||||
BOOL
|
||||
SdbUninstall(
|
||||
_In_ LPWSTR sdbPath)
|
||||
{
|
||||
BOOL res = FALSE;
|
||||
PWCHAR sdbName = NULL;
|
||||
PDB pdb;
|
||||
TAGID tagDb;
|
||||
GUID dbGuid;
|
||||
|
||||
SIZE_T sdbPathLen = wcslen(sdbPath);
|
||||
sdbName = sdbPath + sdbPathLen;
|
||||
|
||||
while (*sdbName != L'\\')
|
||||
{
|
||||
--sdbName;
|
||||
}
|
||||
sdbName++;
|
||||
|
||||
wprintf(L"uninstall name %ls\n", sdbName);
|
||||
|
||||
// open sdb
|
||||
pdb = SdbOpenDatabase(sdbPath, DOS_PATH);
|
||||
if (pdb == NULL)
|
||||
{
|
||||
wprintf(L"Can't open database %ls\n", sdbPath);
|
||||
goto end;
|
||||
}
|
||||
|
||||
tagDb = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE);
|
||||
if (!tagDb)
|
||||
{
|
||||
wprintf(L"Can't find database tag\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
//
|
||||
if (!GetSdbGuid(pdb, tagDb, &dbGuid))
|
||||
{
|
||||
wprintf(L"GetSdbGuid error\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
//remove regkey in appatch/custom
|
||||
HRESULT hres = ProcessExe(pdb, tagDb, NULL, 0, FALSE);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"Process exe fail\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
SdbCloseDatabase(pdb);
|
||||
|
||||
hres = DeleteUninstallKey(sdbName);
|
||||
if (FAILED(hres))
|
||||
{
|
||||
wprintf(L"Remove key fail\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SdbUnregisterDatabase(&dbGuid))
|
||||
{
|
||||
wprintf(L"SdbUnregisterDatabase\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!DeleteFile(sdbPath))
|
||||
{
|
||||
wprintf(L"Remove file fail 0x%08X\n", GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ShowHelp()
|
||||
{
|
||||
|
@ -459,24 +602,58 @@ ShowHelp()
|
|||
L"-n - \"name\" - file name (only uninstall)\n");
|
||||
}
|
||||
|
||||
int _tmain(int argc, LPCWSTR argv[])
|
||||
int _tmain(int argc, LPWSTR argv[])
|
||||
{
|
||||
LPCWSTR sdbPath = NULL;
|
||||
LPWSTR sdbPath = NULL;
|
||||
BOOL isInstall = TRUE;
|
||||
//LPWSTR guidSdbStr = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
ShowHelp();
|
||||
}
|
||||
|
||||
if (argv[1][0] == L'-' && argv[1][1] == L'?')
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
ShowHelp();
|
||||
return ERROR_SUCCESS;
|
||||
if (argv[i][0] != L'-')
|
||||
{
|
||||
sdbPath = argv[i];
|
||||
break;
|
||||
}
|
||||
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case L'?':
|
||||
ShowHelp();
|
||||
return ERROR_SUCCESS;
|
||||
break;
|
||||
|
||||
case L'u':
|
||||
isInstall = FALSE;
|
||||
break;
|
||||
|
||||
case L'g':
|
||||
++i;
|
||||
|
||||
if (i < argc)
|
||||
{
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//guidSdbStr = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sdbPath = argv[1];
|
||||
|
||||
SdbInstall(sdbPath);
|
||||
if (isInstall)
|
||||
{
|
||||
SdbInstall(sdbPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// call uninstall
|
||||
SdbUninstall(sdbPath);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ DWORD WINAPI SdbQueryDataExTagID(PDB pdb, TAGID tiExe, LPCWSTR lpszDataName, LPD
|
|||
BOOL WINAPI SdbGetDatabaseInformation(PDB pdb, PDB_INFORMATION information);
|
||||
VOID WINAPI SdbFreeDatabaseInformation(PDB_INFORMATION information);
|
||||
BOOL WINAPI SdbRegisterDatabaseEx(_In_ LPCWSTR pszDatabasePath, _In_ DWORD dwDatabaseType, _In_opt_ const PULONGLONG pTimeStamp);
|
||||
BOOL WINAPI SdbUnregisterDatabase(_In_ const GUID *pguidDB);
|
||||
|
||||
/* sdbread.c */
|
||||
BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num);
|
||||
|
|
Loading…
Reference in a new issue