DWORD LwSmRegistryEnumServices( HANDLE hReg, PWSTR** pppwszNames ) { DWORD dwError = 0; DWORD dwKeyCount = 0; DWORD dwMaxKeyLen = 0; DWORD dwKeyLen = 0; HKEY pRootKey = NULL; HKEY pParentKey = NULL; PWSTR* ppwszNames = NULL; PWSTR pwszParentPath = NULL; DWORD i = 0; static const PSTR pszServicesKeyName = "\\Services"; dwError = LwMbsToWc16s(pszServicesKeyName + 1, &pwszParentPath); dwError = RegOpenKeyExA( hReg, NULL, HKEY_THIS_MACHINE, 0, KEY_READ, &pRootKey); BAIL_ON_ERROR(dwError); dwError = RegOpenKeyExW(hReg, pRootKey, pwszParentPath, 0, KEY_READ, &pParentKey); BAIL_ON_ERROR(dwError); dwError = RegQueryInfoKeyW( hReg, pParentKey, NULL, NULL, NULL, &dwKeyCount, &dwMaxKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); BAIL_ON_ERROR(dwError); dwError = LwAllocateMemory( sizeof(*ppwszNames) * (dwKeyCount + 1), OUT_PPVOID(&ppwszNames)); BAIL_ON_ERROR(dwError); for (i = 0; i < dwKeyCount; i++) { dwKeyLen = dwMaxKeyLen + 1; dwError = LwAllocateMemory( sizeof(**ppwszNames) * dwKeyLen, OUT_PPVOID(&ppwszNames[i])); BAIL_ON_ERROR(dwError); dwError = RegEnumKeyExW(hReg, pParentKey, i, ppwszNames[i], &dwKeyLen, NULL, NULL, NULL, NULL); BAIL_ON_ERROR(dwError); } *pppwszNames = ppwszNames; cleanup: LW_SAFE_FREE_MEMORY(pwszParentPath); if (pParentKey) { RegCloseKey(hReg, pParentKey); } if (pRootKey) { RegCloseKey(hReg, pRootKey); } return dwError; error: *pppwszNames = NULL; if (ppwszNames) { LwSmFreeStringList(ppwszNames); } goto cleanup; }
DWORD LwSmPopulateTable( VOID ) { DWORD dwError = 0; HANDLE hReg = NULL; PWSTR* ppwszNames = NULL; PWSTR pwszName = NULL; PLW_SERVICE_INFO pInfo = NULL; PSM_TABLE_ENTRY pEntry = NULL; size_t i = 0; SM_LOG_VERBOSE("Populating service table"); dwError = RegOpenServer(&hReg); BAIL_ON_ERROR(dwError); dwError = LwSmRegistryEnumServices(hReg, &ppwszNames); switch (dwError) { case LWREG_ERROR_NO_SUCH_KEY_OR_VALUE: /* No services in registry */ dwError = 0; goto cleanup; } BAIL_ON_ERROR(dwError); for (i = 0; ppwszNames[i]; i++) { pwszName = ppwszNames[i]; LwSmCommonFreeServiceInfo(pInfo); pInfo = NULL; dwError = LwSmRegistryReadServiceInfo(hReg, pwszName, &pInfo); switch (dwError) { case LWREG_ERROR_NO_SUCH_KEY_OR_VALUE: dwError = 0; continue; default: break; } BAIL_ON_ERROR(dwError); dwError = LwSmTableGetEntry(pwszName, &pEntry); if (!dwError) { dwError = LwSmTableUpdateEntry(pEntry, pInfo, LW_SERVICE_INFO_MASK_ALL); BAIL_ON_ERROR(dwError); } else if (dwError == LW_ERROR_NO_SUCH_SERVICE) { dwError = LwSmTableAddEntry(pInfo, &pEntry); BAIL_ON_ERROR(dwError); } else { BAIL_ON_ERROR(dwError); } LwSmTableReleaseEntry(pEntry); pEntry = NULL; } cleanup: LwSmFreeStringList(ppwszNames); LwSmCommonFreeServiceInfo(pInfo); if (hReg) { RegCloseServer(hReg); } return dwError; error: goto cleanup; }
static DWORD LwSmRegistryReadStringList( HANDLE hReg, HKEY pRootKey, PCWSTR pwszParentKey, PCWSTR pwszValueName, PWSTR** pppwszValues ) { DWORD dwError = 0; PWSTR pwszValuesString = NULL; PWSTR pwszCursor = NULL; PWSTR pwszSpace = NULL; PWSTR* ppwszValues = NULL; size_t count = 0; size_t i = 0; dwError = LwSmRegistryReadString(hReg, pRootKey, pwszParentKey, pwszValueName, &pwszValuesString); BAIL_ON_ERROR(dwError); if (*pwszValuesString) { count = LwSmCountTokens(pwszValuesString); } else { count = 0; } dwError = LwAllocateMemory((count + 1) * sizeof(*ppwszValues), OUT_PPVOID(&ppwszValues)); BAIL_ON_ERROR(dwError); for (pwszCursor = pwszValuesString, i = 0; i < count; i++) { for (pwszSpace = pwszCursor; *pwszSpace && *pwszSpace != ' '; pwszSpace++); *pwszSpace = (WCHAR) '\0'; dwError = LwAllocateWc16String(&ppwszValues[i], pwszCursor); BAIL_ON_ERROR(dwError); for (pwszCursor = pwszSpace + 1; *pwszCursor == ' '; pwszCursor++); } *pppwszValues = ppwszValues; cleanup: LW_SAFE_FREE_MEMORY(pwszValuesString); return dwError; error: *pppwszValues = NULL; if (ppwszValues) { LwSmFreeStringList(ppwszValues); } goto cleanup; }
static DWORD LwSmAutostart( int argc, char** pArgv ) { DWORD dwError = 0; PWSTR *ppwszAllServices = NULL; LW_SERVICE_HANDLE hHandle = NULL; PLW_SERVICE_INFO pInfo = NULL; size_t i = 0; PWSTR *ppwszDependencies = NULL; LW_SERVICE_HANDLE hDepHandle = NULL; LW_SERVICE_STATUS status = {0}; PSTR pszTemp = NULL; size_t j = 0; dwError = LwSmEnumerateServices(&ppwszAllServices); BAIL_ON_ERROR(dwError); for (i = 0; ppwszAllServices[i]; i++) { dwError = LwSmAcquireServiceHandle(ppwszAllServices[i], &hHandle); BAIL_ON_ERROR(dwError); dwError = LwSmQueryServiceInfo(hHandle, &pInfo); BAIL_ON_ERROR(dwError); if (pInfo->bAutostart) { dwError = LwSmQueryServiceDependencyClosure( hHandle, &ppwszDependencies); BAIL_ON_ERROR(dwError); for (j = 0; ppwszDependencies[j]; j++) { dwError = LwSmAcquireServiceHandle( ppwszDependencies[j], &hDepHandle); BAIL_ON_ERROR(dwError); dwError = LwSmQueryServiceStatus(hDepHandle, &status); BAIL_ON_ERROR(dwError); if (status.state != LW_SERVICE_STATE_RUNNING) { if (!gState.bQuiet) { dwError = LwWc16sToMbs(ppwszDependencies[j], &pszTemp); BAIL_ON_ERROR(dwError); printf("Starting service dependency: %s\n", pszTemp); LW_SAFE_FREE_MEMORY(pszTemp); } dwError = LwSmStartService(hDepHandle); BAIL_ON_ERROR(dwError); } dwError = LwSmReleaseServiceHandle(hDepHandle); hDepHandle = NULL; BAIL_ON_ERROR(dwError); } if (ppwszDependencies) { LwSmFreeServiceNameList(ppwszDependencies); ppwszDependencies = NULL; } if (!gState.bQuiet) { dwError = LwWc16sToMbs(ppwszAllServices[i], &pszTemp); BAIL_ON_ERROR(dwError); printf("Starting service: %s\n", pszTemp); LW_SAFE_FREE_MEMORY(pszTemp); } dwError = LwSmStartService(hHandle); BAIL_ON_ERROR(dwError); } dwError = LwSmReleaseServiceHandle(hHandle); hHandle = NULL; BAIL_ON_ERROR(dwError); } cleanup: if (hHandle) { LwSmReleaseServiceHandle(hHandle); hHandle = NULL; } if (ppwszAllServices) { LwSmFreeStringList(ppwszAllServices); ppwszAllServices = NULL; } if (ppwszDependencies) { LwSmFreeServiceNameList(ppwszDependencies); ppwszDependencies = NULL; } if (hDepHandle) { LwSmReleaseServiceHandle(hDepHandle); hDepHandle = NULL; } LW_SAFE_FREE_MEMORY(pszTemp); return dwError; error: goto cleanup; }