/* iterates over all fields of a certain key of a certain section */ static HRESULT iterate_section_fields(HINF hinf, PCWSTR section, PCWSTR key, iterate_fields_func callback, void *arg) { WCHAR static_buffer[200]; WCHAR *buffer = static_buffer; DWORD size = sizeof(static_buffer) / sizeof(WCHAR); INFCONTEXT context; HRESULT hr = E_FAIL; BOOL ok = SetupFindFirstLineW(hinf, section, key, &context); while (ok) { UINT i, count = SetupGetFieldCount(&context); for (i = 1; i <= count; i++) { if (!(buffer = get_field_string(&context, i, buffer, static_buffer, &size))) goto done; if ((hr = callback(hinf, buffer, arg)) != S_OK) goto done; } ok = SetupFindNextMatchLineW(&context, key, &context); } hr = S_OK; done: if (buffer != static_buffer) HeapFree(GetProcessHeap(), 0, buffer); return hr; }
BOOLEAN INF_GetData( IN PINFCONTEXT Context, OUT PWCHAR *Key, OUT PWCHAR *Data) { #ifdef __REACTOS__ return InfGetData(Context, Key, Data); #else static PWCHAR pLastCallData[4] = { NULL, NULL, NULL, NULL }; static DWORD currentIndex = 0; DWORD dwSize, i; BOOL ret; currentIndex ^= 2; if (Key) *Key = NULL; if (Data) *Data = NULL; if (SetupGetFieldCount(Context) != 1) return FALSE; for (i = 0; i <= 1; i++) { ret = SetupGetStringFieldW( Context, i, NULL, 0, &dwSize); if (!ret) return FALSE; HeapFree(GetProcessHeap(), 0, pLastCallData[i + currentIndex]); pLastCallData[i + currentIndex] = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR)); ret = SetupGetStringFieldW( Context, i, pLastCallData[i + currentIndex], dwSize, NULL); if (!ret) return FALSE; } if (Key) *Key = pLastCallData[0 + currentIndex]; if (Data) *Data = pLastCallData[1 + currentIndex]; return TRUE; #endif /* !__REACTOS__ */ }
static BOOL CreateShortcuts(HINF hinf, LPCWSTR szSection) { INFCONTEXT Context; WCHAR szPath[MAX_PATH]; WCHAR szFolder[MAX_PATH]; WCHAR szFolderSection[MAX_PATH]; INT csidl; CoInitialize(NULL); if (!SetupFindFirstLine(hinf, szSection, NULL, &Context)) return FALSE; do { if (SetupGetFieldCount(&Context) < 2) continue; if (!SetupGetStringFieldW(&Context, 0, szFolderSection, MAX_PATH, NULL)) continue; if (!SetupGetIntField(&Context, 1, &csidl)) continue; if (!SetupGetStringFieldW(&Context, 2, szFolder, MAX_PATH, NULL)) continue; if (FAILED(SHGetFolderPathAndSubDirW(NULL, csidl|CSIDL_FLAG_CREATE, (HANDLE)-1, SHGFP_TYPE_DEFAULT, szFolder, szPath))) continue; CreateShortcutsFromSection(hinf, szFolderSection, szPath); }while (SetupFindNextLine(&Context, &Context)); CoUninitialize(); return TRUE; }
static BOOL CreateShortcutsFromSection(HINF hinf, LPWSTR pszSection, LPCWSTR pszFolder) { INFCONTEXT Context; WCHAR szCommand[MAX_PATH]; WCHAR szName[MAX_PATH]; WCHAR szDescription[MAX_PATH]; INT iIconNr; if (!SetupFindFirstLine(hinf, pszSection, NULL, &Context)) return FALSE; do { if (SetupGetFieldCount(&Context) < 4) continue; if (!SetupGetStringFieldW(&Context, 1, szCommand, MAX_PATH, NULL)) continue; if (!SetupGetStringFieldW(&Context, 2, szName, MAX_PATH, NULL)) continue; if (!SetupGetStringFieldW(&Context, 3, szDescription, MAX_PATH, NULL)) continue; if (!SetupGetIntField(&Context, 4, &iIconNr)) continue; _tcscat(szName, L".lnk"); CreateShortcut(pszFolder, szName, szCommand, szDescription, iIconNr); }while (SetupFindNextLine(&Context, &Context)); return TRUE; }
static VOID InstallPrivileges(VOID) { HINF hSecurityInf = INVALID_HANDLE_VALUE; LSA_OBJECT_ATTRIBUTES ObjectAttributes; WCHAR szPrivilegeString[256]; WCHAR szSidString[256]; INFCONTEXT InfContext; DWORD i; PRIVILEGE_SET PrivilegeSet; PSID AccountSid; NTSTATUS Status; LSA_HANDLE PolicyHandle = NULL; LSA_HANDLE AccountHandle; DPRINT("InstallPrivileges()\n"); hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer, NULL, INF_STYLE_WIN4, NULL); if (hSecurityInf == INVALID_HANDLE_VALUE) { DPRINT1("SetupOpenInfFileW failed\n"); return; } memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT, &PolicyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); goto done; } if (!SetupFindFirstLineW(hSecurityInf, L"Privilege Rights", NULL, &InfContext)) { DPRINT1("SetupFindfirstLineW failed\n"); goto done; } PrivilegeSet.PrivilegeCount = 1; PrivilegeSet.Control = 0; do { /* Retrieve the privilege name */ if (!SetupGetStringFieldW(&InfContext, 0, szPrivilegeString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("Privilege: %S\n", szPrivilegeString); if (!LookupPrivilegeValueW(NULL, szPrivilegeString, &(PrivilegeSet.Privilege[0].Luid))) { DPRINT1("LookupPrivilegeNameW() failed\n"); goto done; } PrivilegeSet.Privilege[0].Attributes = 0; for (i = 0; i < SetupGetFieldCount(&InfContext); i++) { if (!SetupGetStringFieldW(&InfContext, i + 1, szSidString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("SID: %S\n", szSidString); ConvertStringSidToSid(szSidString, &AccountSid); Status = LsaOpenAccount(PolicyHandle, AccountSid, ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES, &AccountHandle); if (NT_SUCCESS(Status)) { Status = LsaAddPrivilegesToAccount(AccountHandle, &PrivilegeSet); if (!NT_SUCCESS(Status)) { DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status); } LsaClose(AccountHandle); } LocalFree(AccountSid); } } while (SetupFindNextLine(&InfContext, &InfContext)); done: if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (hSecurityInf != INVALID_HANDLE_VALUE) SetupCloseInfFile(hSecurityInf); }
/*********************************************************************** * do_reg_operation * * Perform an add/delete registry operation depending on the flags. */ static BOOLEAN do_reg_operation(HANDLE KeyHandle, PUNICODE_STRING ValueName, PINFCONTEXT Context, ULONG Flags) { WCHAR EmptyStr = (WCHAR)0; ULONG Type; ULONG Size; if (Flags & FLG_ADDREG_DELVAL) /* deletion */ { #if 0 if (ValueName) { RegDeleteValueW( KeyHandle, ValueName ); } else { RegDeleteKeyW( KeyHandle, NULL ); } #endif return TRUE; } if (Flags & FLG_ADDREG_KEYONLY) return TRUE; #if 0 if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) { BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL ); if (exists && (flags & FLG_ADDREG_NOCLOBBER)) return TRUE; if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) return TRUE; } #endif switch (Flags & FLG_ADDREG_TYPE_MASK) { case FLG_ADDREG_TYPE_SZ: Type = REG_SZ; break; case FLG_ADDREG_TYPE_MULTI_SZ: Type = REG_MULTI_SZ; break; case FLG_ADDREG_TYPE_EXPAND_SZ: Type = REG_EXPAND_SZ; break; case FLG_ADDREG_TYPE_BINARY: Type = REG_BINARY; break; case FLG_ADDREG_TYPE_DWORD: Type = REG_DWORD; break; case FLG_ADDREG_TYPE_NONE: Type = REG_NONE; break; default: Type = Flags >> 16; break; } if (!(Flags & FLG_ADDREG_BINVALUETYPE) || (Type == REG_DWORD && SetupGetFieldCount (Context) == 5)) { PWCHAR Str = NULL; if (Type == REG_MULTI_SZ) { if (!SetupGetMultiSzFieldW (Context, 5, NULL, 0, &Size)) Size = 0; if (Size) { Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); if (Str == NULL) return FALSE; SetupGetMultiSzFieldW (Context, 5, Str, Size, NULL); } if (Flags & FLG_ADDREG_APPEND) { if (Str == NULL) return TRUE; // append_multi_sz_value( hkey, value, str, size ); RtlFreeHeap (ProcessHeap, 0, Str); return TRUE; } /* else fall through to normal string handling */ } else { if (!SetupGetStringFieldW (Context, 5, NULL, 0, &Size)) Size = 0; if (Size) { Str = (WCHAR*) RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); if (Str == NULL) return FALSE; SetupGetStringFieldW (Context, 5, Str, Size, NULL); } } if (Type == REG_DWORD) { ULONG dw = Str ? wcstol (Str, NULL, 0) : 0; DPRINT("setting dword %wZ to %lx\n", ValueName, dw); #ifdef __ODYSSEY__ NtSetValueKey (KeyHandle, ValueName, 0, Type, (PVOID)&dw, sizeof(ULONG)); #else RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&dw, sizeof(ULONG)); #endif } else { DPRINT("setting value %wZ to %S\n", ValueName, Str); if (Str) { #ifdef __ODYSSEY__ NtSetValueKey (KeyHandle, ValueName, 0, Type, (PVOID)Str, Size * sizeof(WCHAR)); #else RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Str, Size * sizeof(WCHAR)); #endif } else { #ifdef __ODYSSEY__ NtSetValueKey (KeyHandle, ValueName, 0, Type, (PVOID)&EmptyStr, sizeof(WCHAR)); #else RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)&EmptyStr, sizeof(WCHAR)); #endif } } RtlFreeHeap (ProcessHeap, 0, Str); } else /* get the binary data */ { PUCHAR Data = NULL; if (!SetupGetBinaryField (Context, 5, NULL, 0, &Size)) Size = 0; if (Size) { Data = (unsigned char*) RtlAllocateHeap (ProcessHeap, 0, Size); if (Data == NULL) return FALSE; DPRINT("setting binary data %wZ len %lu\n", ValueName, Size); SetupGetBinaryField (Context, 5, Data, Size, NULL); } #ifdef __ODYSSEY__ NtSetValueKey (KeyHandle, ValueName, 0, Type, (PVOID)Data, Size); #else RegSetValueExW(KeyHandle, ValueName, 0, Type, (const UCHAR*)Data, Size); #endif RtlFreeHeap (ProcessHeap, 0, Data); } return TRUE; }