[idd] install: rework error handling for ensureKeyWithAce

Also avoid weird allocators like LocalAlloc in favour of malloc.
This commit is contained in:
Quantum
2025-09-13 05:07:50 -04:00
committed by Geoffrey McRae
parent e75c7cff46
commit 41d3e7a981

View File

@@ -50,69 +50,78 @@ void debugWinError(const wchar_t *desc, HRESULT status)
LocalFree(buffer); LocalFree(buffer);
} }
static DWORD resolveSidFromName(PCWSTR account, PSID* ppSid) static bool resolveSidFromName(PCWSTR account, PSID* ppSid)
{ {
*ppSid = NULL; *ppSid = NULL;
DWORD cbSid = 0, cchRefDom = 0; DWORD cbSid = 0, cchRefDom = 0, dwError;
SID_NAME_USE use; SID_NAME_USE use;
LookupAccountNameW(NULL, account, NULL, &cbSid, NULL, &cchRefDom, &use); LookupAccountNameW(NULL, account, NULL, &cbSid, NULL, &cchRefDom, &use);
dwError = GetLastError();
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) if (dwError != ERROR_INSUFFICIENT_BUFFER)
return GetLastError(); {
debugWinError(L"LookupAccountNameW buffer calculation", dwError);
return false;
}
PSID sid = (PSID)LocalAlloc(LMEM_FIXED, cbSid); PSID sid = malloc(cbSid);
if (!sid) if (!sid)
return ERROR_OUTOFMEMORY; {
fwprintf(stderr, L"out of memory\n");
return false;
}
PWSTR refDom = (PWSTR)LocalAlloc(LMEM_FIXED, cchRefDom * sizeof(WCHAR)); PWSTR refDom = malloc(cchRefDom * sizeof(WCHAR));
if (!refDom) if (!refDom)
{ {
LocalFree(sid); return ERROR_OUTOFMEMORY; fwprintf(stderr, L"out of memory\n");
free(sid);
return false;
} }
if (!LookupAccountNameW(NULL, account, sid, &cbSid, refDom, &cchRefDom, &use)) if (!LookupAccountNameW(NULL, account, sid, &cbSid, refDom, &cchRefDom, &use))
{ {
DWORD ec = GetLastError(); debugWinError(L"LookupAccountNameW", GetLastError());
LocalFree(refDom); free(refDom);
LocalFree(sid); free(sid);
return ec; return false;
} }
LocalFree(refDom); free(refDom);
*ppSid = sid; *ppSid = sid;
return ERROR_SUCCESS; return true;
} }
DWORD ensureKeyWithAce() bool ensureKeyWithAce()
{ {
bool result = false;
const PCWSTR accountName = L"NT AUTHORITY\\USER MODE DRIVERS"; const PCWSTR accountName = L"NT AUTHORITY\\USER MODE DRIVERS";
HKEY hKey = NULL; HKEY hKey = NULL;
DWORD disp = 0; DWORD disp = 0;
REGSAM sam = KEY_READ | KEY_WRITE | WRITE_DAC | READ_CONTROL | KEY_WOW64_64KEY; REGSAM sam = KEY_READ | KEY_WRITE | WRITE_DAC | READ_CONTROL | KEY_WOW64_64KEY;
PACL oldDacl = NULL;
PSECURITY_DESCRIPTOR psd = NULL;
PACL newDacl = NULL;
PSID sid = NULL;
DWORD ec = RegCreateKeyExW(HKEY_LOCAL_MACHINE, LGIDD_REGKEY, 0, NULL, 0, sam, NULL, &hKey, &disp); DWORD ec = RegCreateKeyExW(HKEY_LOCAL_MACHINE, LGIDD_REGKEY, 0, NULL, 0, sam, NULL, &hKey, &disp);
if (ec != ERROR_SUCCESS) if (ec != ERROR_SUCCESS)
return ec; {
debugWinError(L"RegCreateKeyExW", ec);
return false;
}
PACL oldDacl = NULL;
PSECURITY_DESCRIPTOR psd = NULL;
ec = GetSecurityInfo(hKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &oldDacl, NULL, &psd); ec = GetSecurityInfo(hKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &oldDacl, NULL, &psd);
if (ec != ERROR_SUCCESS) if (ec != ERROR_SUCCESS)
{ {
RegCloseKey(hKey); debugWinError(L"GetSecurityInfo", ec);
return ec; goto cleanup;
} }
PSID sid = NULL; if (!resolveSidFromName(accountName, &sid))
ec = resolveSidFromName(accountName, &sid); goto cleanup;
if (ec != ERROR_SUCCESS)
{
LocalFree(psd);
RegCloseKey(hKey);
return ec;
}
EXPLICIT_ACCESSW ea = {0}; EXPLICIT_ACCESSW ea = {0};
ea.grfAccessPermissions = KEY_ALL_ACCESS; ea.grfAccessPermissions = KEY_ALL_ACCESS;
@@ -121,26 +130,32 @@ DWORD ensureKeyWithAce()
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.ptstrName = (LPWSTR)sid; ea.Trustee.ptstrName = (LPWSTR)sid;
PACL newDacl = NULL;
ec = SetEntriesInAclW(1, &ea, oldDacl, &newDacl); ec = SetEntriesInAclW(1, &ea, oldDacl, &newDacl);
if (ec != ERROR_SUCCESS) if (ec != ERROR_SUCCESS)
{ {
LocalFree(sid); debugWinError(L"SetEntriesInAclW", ec);
LocalFree(psd); goto cleanup;
RegCloseKey(hKey);
return ec;
} }
ec = SetSecurityInfo(hKey, SE_REGISTRY_KEY, ec = SetSecurityInfo(hKey, SE_REGISTRY_KEY,
DACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION,
NULL, NULL, newDacl, NULL); NULL, NULL, newDacl, NULL);
if (ec != ERROR_SUCCESS)
{
debugWinError(L"SetSecurityInfo", ec);
goto cleanup;
}
result = true;
cleanup:
if (newDacl) LocalFree(newDacl); if (newDacl) LocalFree(newDacl);
if (sid) LocalFree(sid); if (sid) free(sid);
if (psd) LocalFree(psd); if (psd) LocalFree(psd);
RegCloseKey(hKey); RegCloseKey(hKey);
return ec; return result;
} }
DWORD deleteKeyTreeHKLM() DWORD deleteKeyTreeHKLM()
@@ -397,13 +412,9 @@ void install()
// fallthrough // fallthrough
case DEVICE_CREATED: case DEVICE_CREATED:
_putws("Preparing registry key..."); _putws(L"Preparing registry key...");
DWORD ec = ensureKeyWithAce(); if (!ensureKeyWithAce())
if (ec != ERROR_SUCCESS)
{
debugWinError(L"ensureKeyWithAce", ec);
exit(1); exit(1);
}
_putws(L"Installing INF..."); _putws(L"Installing INF...");
BOOL bNeedRestart; BOOL bNeedRestart;