From b83d70a068d0f16743e5626c606bc1bf8f8a826f Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sat, 13 Sep 2025 13:50:24 +1000 Subject: [PATCH] [idd] installer: create the IDD registry key for the driver The driver runs under the account `NT AUTHORITY\USER MODE DRIVERS` and as a result requires the key to be owned by this user so that it is able to write to it. --- idd/LGIddInstall/LGIddInstall.c | 129 ++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/idd/LGIddInstall/LGIddInstall.c b/idd/LGIddInstall/LGIddInstall.c index e7725bf5..daa71e5a 100644 --- a/idd/LGIddInstall/LGIddInstall.c +++ b/idd/LGIddInstall/LGIddInstall.c @@ -9,12 +9,15 @@ #include #include #include +#include +#include #define LGIDD_CLASS_GUID GUID_DEVCLASS_DISPLAY #define LGIDD_CLASS_NAME L"Display" #define LGIDD_HWID L"Root\\LGIdd" #define LGIDD_HWID_MULTI_SZ (LGIDD_HWID "\0") #define LGIDD_INF_NAME L"LGIdd.inf" +#define LGIDD_REGKEY L"Software\\LookingGlass\\IDD" void usage(wchar_t *program) { @@ -47,6 +50,111 @@ void debugWinError(const wchar_t *desc, HRESULT status) LocalFree(buffer); } +static DWORD resolveSidFromName(PCWSTR account, PSID* ppSid) +{ + *ppSid = NULL; + DWORD cbSid = 0, cchRefDom = 0; + SID_NAME_USE use; + + LookupAccountNameW(NULL, account, NULL, &cbSid, NULL, &cchRefDom, &use); + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return GetLastError(); + + PSID sid = (PSID)LocalAlloc(LMEM_FIXED, cbSid); + if (!sid) + return ERROR_OUTOFMEMORY; + + PWSTR refDom = (PWSTR)LocalAlloc(LMEM_FIXED, cchRefDom * sizeof(WCHAR)); + if (!refDom) + { + LocalFree(sid); return ERROR_OUTOFMEMORY; + } + + if (!LookupAccountNameW(NULL, account, sid, &cbSid, refDom, &cchRefDom, &use)) + { + DWORD ec = GetLastError(); + LocalFree(refDom); + LocalFree(sid); + return ec; + } + + LocalFree(refDom); + *ppSid = sid; + return ERROR_SUCCESS; +} + +DWORD ensureKeyWithAce() +{ + const PCWSTR accountName = L"NT AUTHORITY\\USER MODE DRIVERS"; + + HKEY hKey = NULL; + DWORD disp = 0; + REGSAM sam = KEY_READ | KEY_WRITE | WRITE_DAC | READ_CONTROL | KEY_WOW64_64KEY; + + DWORD ec = RegCreateKeyExW(HKEY_LOCAL_MACHINE, LGIDD_REGKEY, 0, NULL, 0, sam, NULL, &hKey, &disp); + if (ec != ERROR_SUCCESS) + return ec; + + PACL oldDacl = NULL; + PSECURITY_DESCRIPTOR psd = NULL; + ec = GetSecurityInfo(hKey, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &oldDacl, NULL, &psd); + if (ec != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return ec; + } + + PSID sid = NULL; + ec = resolveSidFromName(accountName, &sid); + if (ec != ERROR_SUCCESS) + { + LocalFree(psd); + RegCloseKey(hKey); + return ec; + } + + EXPLICIT_ACCESSW ea = {0}; + ea.grfAccessPermissions = KEY_ALL_ACCESS; + ea.grfAccessMode = GRANT_ACCESS; + ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; + ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea.Trustee.ptstrName = (LPWSTR)sid; + + PACL newDacl = NULL; + ec = SetEntriesInAclW(1, &ea, oldDacl, &newDacl); + if (ec != ERROR_SUCCESS) + { + LocalFree(sid); + LocalFree(psd); + RegCloseKey(hKey); + return ec; + } + + ec = SetSecurityInfo(hKey, SE_REGISTRY_KEY, + OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + sid, NULL, newDacl, NULL); + + if (newDacl) LocalFree(newDacl); + if (sid) LocalFree(sid); + if (psd) LocalFree(psd); + RegCloseKey(hKey); + + return ec; +} + +DWORD deleteKeyTreeHKLM() +{ + HKEY h; + DWORD ec = RegOpenKeyExW(HKEY_LOCAL_MACHINE, LGIDD_REGKEY, 0, KEY_WRITE | KEY_WOW64_64KEY, &h); + if (ec != ERROR_SUCCESS) + return ec; + + ec = RegDeleteTreeW(h, NULL); + RegCloseKey(h); + return ec; +} + typedef bool (*IDD_FOUND_PROC)(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfo, void *pContext); bool findIddDevice(IDD_FOUND_PROC procFound, void *pContext) @@ -142,6 +250,13 @@ enum DeviceCreated isIddDeviceCreated() bool createIddDevice(void) { + DWORD ec = ensureKeyWithAce(); + if (ec != ERROR_SUCCESS) + { + debugWinError(L"ensureKeyWithAce", ec); + return false; + } + HDEVINFO hDevInfo = SetupDiCreateDeviceInfoList(&LGIDD_CLASS_GUID, NULL); if (hDevInfo == INVALID_HANDLE_VALUE) { @@ -220,6 +335,13 @@ uninstall: debugWinError(L"DiUninstallDriverW", GetLastError()); } + DWORD ec = deleteKeyTreeHKLM(); + if (ec != ERROR_SUCCESS) + { + debugWinError(L"deleteKeyTreeHKLM failed", ec); + // this is non-fatal + } + return true; } @@ -262,6 +384,13 @@ bool installIddInf(PBOOL pbNeedRestart) if (!getIddInfPath(szInf)) return false; + DWORD ec = ensureKeyWithAce(); + if (ec != ERROR_SUCCESS) + { + debugWinError(L"ensureKeyWithAce", ec); + return false; + } + if (!DiInstallDriverW(NULL, szInf, DIIRFLAG_FORCE_INF, pbNeedRestart)) { debugWinError(L"DiInstallDriverW", GetLastError());