VOID ParseSetupInf(VOID) { INFCONTEXT InfContext; WCHAR szBuffer[30]; if (!SetupFindFirstLineW(hSetupInf, L"Unattend", L"LocaleID", &InfContext)) { SetupCloseInfFile(hSetupInf); DPRINT1("SetupFindFirstLine failed\n"); return; } if (!SetupGetStringFieldW(&InfContext, 1, szBuffer, sizeof(szBuffer) / sizeof(WCHAR), NULL)) { SetupCloseInfFile(hSetupInf); DPRINT1("SetupGetStringField failed\n"); return; } UnattendLCID = wcstoul(szBuffer, NULL, 16); IsUnattendedSetupEnabled = 1; SetupCloseInfFile(hSetupInf); }
/* 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; }
/* parses the destination directory parameters from pszSection * the parameters are of the form: root,key,value,unknown,fallback * we first read the reg value root\\key\\value and if that fails, * use fallback as the destination directory */ static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dwSize) { INFCONTEXT context; WCHAR key[MAX_PATH], value[MAX_PATH]; WCHAR prefix[PREFIX_LEN]; HKEY root, subkey; DWORD size; static const WCHAR hklm[] = {'H','K','L','M',0}; static const WCHAR hkcu[] = {'H','K','C','U',0}; /* load the destination parameters */ SetupFindFirstLineW(hInf, pszSection, NULL, &context); SetupGetStringFieldW(&context, 1, prefix, PREFIX_LEN, &size); SetupGetStringFieldW(&context, 2, key, MAX_PATH, &size); SetupGetStringFieldW(&context, 3, value, MAX_PATH, &size); if (!lstrcmpW(prefix, hklm)) root = HKEY_LOCAL_MACHINE; else if (!lstrcmpW(prefix, hkcu)) root = HKEY_CURRENT_USER; else root = NULL; size = dwSize * sizeof(WCHAR); /* fallback to the default destination dir if reg fails */ if (RegOpenKeyW(root, key, &subkey) || RegQueryValueExW(subkey, value, NULL, NULL, (LPBYTE)pszBuffer, &size)) { SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, NULL); } RegCloseKey(subkey); }
static BOOL InstallSysSetupInfDevices(VOID) { INFCONTEXT InfContext; WCHAR szLineBuffer[256]; DWORD dwLineLength; if (!SetupFindFirstLineW(hSysSetupInf, L"DeviceInfsToInstall", NULL, &InfContext)) { return FALSE; } do { if (!SetupGetStringFieldW(&InfContext, 0, szLineBuffer, sizeof(szLineBuffer)/sizeof(szLineBuffer[0]), &dwLineLength)) { return FALSE; } if (!SetupDiInstallClassW(NULL, szLineBuffer, DI_QUIETINSTALL, NULL)) { return FALSE; } } while (SetupFindNextLine(&InfContext, &InfContext)); return TRUE; }
BOOL WINAPI SetupGetSourceInfoW( HINF hinf, UINT source_id, UINT info, PWSTR buffer, DWORD buffer_size, LPDWORD required_size ) { WCHAR Section[MAX_PATH]; INFCONTEXT ctx; WCHAR source_id_str[11]; static const WCHAR fmt[] = {'%','d',0}; DWORD index; TRACE("%p, %d, %d, %p, %d, %p\n", hinf, source_id, info, buffer, buffer_size, required_size); sprintfW( source_id_str, fmt, source_id ); if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL)) return FALSE; if (!SetupFindFirstLineW( hinf, Section, source_id_str, &ctx ) && !SetupFindFirstLineW( hinf, source_disks_names, source_id_str, &ctx )) return FALSE; switch (info) { case SRCINFO_PATH: index = 4; break; case SRCINFO_TAGFILE: index = 2; break; case SRCINFO_DESCRIPTION: index = 1; break; default: WARN("unknown info level: %d\n", info); return FALSE; } if (SetupGetStringFieldW( &ctx, index, buffer, buffer_size, required_size )) return TRUE; if (required_size) *required_size = 1; if (buffer) { if (buffer_size >= 1) buffer[0] = 0; else { SetLastError( ERROR_INSUFFICIENT_BUFFER ); return FALSE; } } return TRUE; }
BOOL WINAPI SetupGetTargetPathW( HINF hinf, PINFCONTEXT context, PCWSTR section, PWSTR buffer, DWORD buffer_size, PDWORD required_size ) { static const WCHAR destination_dirs[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0}; static const WCHAR default_dest_dir[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0}; INFCONTEXT ctx; WCHAR *dir, systemdir[MAX_PATH]; unsigned int size; BOOL ret = FALSE; TRACE("%p, %p, %s, %p, 0x%08x, %p\n", hinf, context, debugstr_w(section), buffer, buffer_size, required_size); if (context) ret = SetupFindFirstLineW( hinf, destination_dirs, NULL, context ); else if (section) { if (!(ret = SetupFindFirstLineW( hinf, destination_dirs, section, &ctx ))) ret = SetupFindFirstLineW( hinf, destination_dirs, default_dest_dir, &ctx ); } if (!ret || !(dir = PARSER_get_dest_dir( context ? context : &ctx ))) { GetSystemDirectoryW( systemdir, MAX_PATH ); dir = systemdir; } size = strlenW( dir ) + 1; if (required_size) *required_size = size; if (buffer) { if (buffer_size >= size) lstrcpyW( buffer, dir ); else { SetLastError( ERROR_INSUFFICIENT_BUFFER ); if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir ); return FALSE; } } if (dir != systemdir) HeapFree( GetProcessHeap(), 0, dir ); return TRUE; }
static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, PINFCONTEXT pCtx) { if (!SetupFindFirstLineW(hInf, lpszSection, lpszKey, pCtx)) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%d) for Section(%S), Key(%S)\n", dwErr, lpszSection, lpszKey)); return HRESULT_FROM_WIN32(dwErr); } return S_OK; }
static LPWSTR get_source_id( HINF hinf, PINFCONTEXT context, PCWSTR filename ) { WCHAR Section[MAX_PATH]; DWORD size; LPWSTR source_id; if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_files, Section, MAX_PATH, NULL, NULL)) return NULL; if (!SetupFindFirstLineW( hinf, Section, filename, context ) && !SetupFindFirstLineW( hinf, source_disks_files, filename, context )) return NULL; if (!SetupGetStringFieldW( context, 1, NULL, 0, &size )) return NULL; if (!(source_id = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return NULL; if (!SetupGetStringFieldW( context, 1, source_id, size, NULL )) { HeapFree( GetProcessHeap(), 0, source_id ); return NULL; } if (!SetupDiGetActualSectionToInstallW(hinf, source_disks_names, Section, MAX_PATH, NULL, NULL)) { HeapFree( GetProcessHeap(), 0, source_id ); return NULL; } if (!SetupFindFirstLineW( hinf, Section, source_id, context ) && !SetupFindFirstLineW( hinf, source_disks_names, source_id, context )) { HeapFree( GetProcessHeap(), 0, source_id ); return NULL; } return source_id; }
PGENERIC_LIST CreateKeyboardDriverList( HINF InfFile) { CHAR Buffer[128]; PGENERIC_LIST List; INFCONTEXT Context; PWCHAR KeyName; PWCHAR KeyValue; PWCHAR UserData; List = CreateGenericList(); if (List == NULL) return NULL; if (!SetupFindFirstLineW (InfFile, L"Keyboard", NULL, &Context)) { DestroyGenericList(List, FALSE); return NULL; } do { if (!INF_GetData (&Context, &KeyName, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetData() failed\n"); break; } UserData = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, (wcslen(KeyName) + 1) * sizeof(WCHAR)); if (UserData == NULL) { /* FIXME: Handle error! */ } wcscpy(UserData, KeyName); sprintf(Buffer, "%S", KeyValue); AppendGenericListEntry(List, Buffer, UserData, FALSE); } while (SetupFindNextLine(&Context, &Context)); return List; }
static HRESULT check_admin_rights(const ADVInfo *info) { INT check; INFCONTEXT context; HRESULT hr = S_OK; if (!SetupFindFirstLineW(info->hinf, info->install_sec, CheckAdminRights, &context)) return S_OK; if (!SetupGetIntField(&context, 1, &check)) return S_OK; if (check == 1) hr = IsNTAdmin(0, NULL) ? S_OK : E_FAIL; return hr; }
static HRESULT per_user_install_callback(HINF hinf, PCWSTR field, const void *arg) { PERUSERSECTIONW per_user; INFCONTEXT context; DWORD size; static const WCHAR disp_name[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; static const WCHAR version[] = {'V','e','r','s','i','o','n',0}; static const WCHAR is_installed[] = {'I','s','I','n','s','t','a','l','l','e','d',0}; static const WCHAR comp_id[] = {'C','o','m','p','o','n','e','n','t','I','D',0}; static const WCHAR guid[] = {'G','U','I','D',0}; static const WCHAR locale[] = {'L','o','c','a','l','e',0}; static const WCHAR stub_path[] = {'S','t','u','b','P','a','t','h',0}; per_user.bRollback = FALSE; per_user.dwIsInstalled = 0; SetupGetLineTextW(NULL, hinf, field, disp_name, per_user.szDispName, sizeof(per_user.szDispName) / sizeof(WCHAR), &size); SetupGetLineTextW(NULL, hinf, field, version, per_user.szVersion, sizeof(per_user.szVersion) / sizeof(WCHAR), &size); if (SetupFindFirstLineW(hinf, field, is_installed, &context)) { SetupGetIntField(&context, 1, (PINT)&per_user.dwIsInstalled); } SetupGetLineTextW(NULL, hinf, field, comp_id, per_user.szCompID, sizeof(per_user.szCompID) / sizeof(WCHAR), &size); SetupGetLineTextW(NULL, hinf, field, guid, per_user.szGUID, sizeof(per_user.szGUID) / sizeof(WCHAR), &size); SetupGetLineTextW(NULL, hinf, field, locale, per_user.szLocale, sizeof(per_user.szLocale) / sizeof(WCHAR), &size); SetupGetLineTextW(NULL, hinf, field, stub_path, per_user.szStub, sizeof(per_user.szStub) / sizeof(WCHAR), &size); return SetPerUserSecValuesW(&per_user); }
/* Advanced INF callbacks */ static HRESULT del_dirs_callback(HINF hinf, PCWSTR field, const void *arg) { INFCONTEXT context; HRESULT hr = S_OK; DWORD size; BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context); for (; ok; ok = SetupFindNextLine(&context, &context)) { WCHAR directory[MAX_INF_STRING_LENGTH]; if (!SetupGetLineTextW(&context, NULL, NULL, NULL, directory, MAX_INF_STRING_LENGTH, &size)) continue; if (DelNodeW(directory, ADN_DEL_IF_EMPTY) != S_OK) hr = E_FAIL; } return hr; }
static HRESULT run_setup_commands_callback(HINF hinf, PCWSTR field, const void *arg) { const ADVInfo *info = (const ADVInfo *)arg; INFCONTEXT context; HRESULT hr = S_OK; DWORD size; BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context); for (; ok; ok = SetupFindNextLine(&context, &context)) { WCHAR buffer[MAX_INF_STRING_LENGTH]; if (!SetupGetLineTextW(&context, NULL, NULL, NULL, buffer, MAX_INF_STRING_LENGTH, &size)) continue; if (launch_exe(buffer, info->working_dir, NULL) != S_OK) hr = E_FAIL; } return hr; }
static HRESULT register_ocxs_callback(HINF hinf, PCWSTR field, const void *arg) { HMODULE hm; INFCONTEXT context; HRESULT hr = S_OK; BOOL ok = SetupFindFirstLineW(hinf, field, NULL, &context); for (; ok; ok = SetupFindNextLine(&context, &context)) { WCHAR buffer[MAX_INF_STRING_LENGTH]; /* get OCX filename */ if (!SetupGetStringFieldW(&context, 1, buffer, sizeof(buffer) / sizeof(WCHAR), NULL)) continue; hm = LoadLibraryExW(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (hm) { if (do_ocx_reg(hm, TRUE, NULL, NULL) != S_OK) hr = E_FAIL; FreeLibrary(hm); } else hr = E_FAIL; if (FAILED(hr)) { /* FIXME: display a message box */ break; } } return hr; }
static PBOOTRECORD ReadFreeldrSection(HINF hInf, WCHAR *szSectionName) { PBOOTRECORD pRecord; INFCONTEXT InfContext; WCHAR szName[MAX_PATH]; WCHAR szValue[MAX_PATH]; DWORD LineLength; if (!SetupFindFirstLineW(hInf, szSectionName, NULL, &InfContext)) { /* Failed to find section */ return NULL; } pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD)); if (pRecord == NULL) { return NULL; } wcscpy(pRecord->szSectionName, szSectionName); do { if (!SetupGetStringFieldW(&InfContext, 0, szName, sizeof(szName) / sizeof(WCHAR), &LineLength)) { break; } if (!SetupGetStringFieldW(&InfContext, 1, szValue, sizeof(szValue) / sizeof(WCHAR), &LineLength)) { break; } if (!_wcsnicmp(szName, L"BootType", 8)) { if (!_wcsnicmp(szValue, L"ReactOS", 7)) { // FIXME: Store as enum pRecord->BootType = 1; } else { pRecord->BootType = 0; } } else if (!_wcsnicmp(szName, L"SystemPath", 10)) { wcscpy(pRecord->szBootPath, szValue); } else if (!_wcsnicmp(szName, L"Options", 7)) { // FIXME: Store flags as values wcscpy(pRecord->szOptions, szValue); } } while (SetupFindNextLine(&InfContext, &InfContext)); return pRecord; }
/*********************************************************************** * registry_callback * * Called once for each AddReg and DelReg entry in a given section. */ static BOOLEAN registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete) { OBJECT_ATTRIBUTES ObjectAttributes; WCHAR Buffer[MAX_INF_STRING_LENGTH]; UNICODE_STRING Name; UNICODE_STRING Value; PUNICODE_STRING ValuePtr; NTSTATUS Status; UINT Flags; ULONG Length; INFCONTEXT Context; HANDLE KeyHandle; BOOLEAN Ok; Ok = SetupFindFirstLineW (hInf, Section, NULL, &Context); if (Ok) { for (;Ok; Ok = SetupFindNextLine (&Context, &Context)) { /* get root */ if (!SetupGetStringFieldW (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL)) continue; if (!GetRootKey (Buffer)) continue; /* get key */ Length = wcslen (Buffer); if (!SetupGetStringFieldW (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL)) *Buffer = 0; DPRINT("KeyName: <%S>\n", Buffer); /* get flags */ if (!SetupGetIntField (&Context, 4, (PINT)&Flags)) Flags = 0; DPRINT("Flags: %lx\n", Flags); #ifdef __ODYSSEY__ RtlInitUnicodeString (&Name, Buffer); InitializeObjectAttributes (&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) { Status = NtOpenKey (&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status); continue; /* ignore if it doesn't exist */ } } else { Status = CreateNestedKey (&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status); continue; } } #else if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) { LONG rc = RegOpenKeyW(NULL, Buffer, &KeyHandle); if (rc != ERROR_SUCCESS) { DPRINT("RegOpenKeyW(%S) failed (error %lu)\n", Buffer, rc); continue; /* ignore if it doesn't exist */ } } else { LONG rc = RegCreateKeyW(NULL, Buffer, &KeyHandle); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyW(%S) failed (error %lu)\n", Buffer, rc); continue; } } #endif /* get value name */ if (SetupGetStringFieldW (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL)) { RtlInitUnicodeString (&Value, Buffer); ValuePtr = &Value; } else { ValuePtr = NULL; } /* and now do it */ if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags)) { NtClose (KeyHandle); return FALSE; } #ifdef __ODYSSEY__ NtClose (KeyHandle); #endif } } return TRUE; }
PGENERIC_LIST CreateKeyboardLayoutList(HINF InfFile, WCHAR * DefaultKBLayout) { CHAR Buffer[128]; PGENERIC_LIST List; INFCONTEXT Context; PWCHAR KeyName; PWCHAR KeyValue; PWCHAR UserData; const MUI_LAYOUTS * LayoutsList; ULONG uIndex = 0; BOOL KeyboardLayoutsFound = FALSE; /* Get default layout id */ if (!SetupFindFirstLineW (InfFile, L"NLS", L"DefaultLayout", &Context)) return NULL; if (!INF_GetData (&Context, NULL, &KeyValue)) return NULL; wcscpy(DefaultKBLayout, KeyValue); List = CreateGenericList(); if (List == NULL) return NULL; LayoutsList = MUIGetLayoutsList(); do { if (!SetupFindFirstLineW(InfFile, L"KeyboardLayout", NULL, &Context)) { DestroyGenericList(List, FALSE); return NULL; } do { if (!INF_GetData (&Context, &KeyName, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetData() failed\n"); DestroyGenericList(List, FALSE); return NULL; } if (_wcsicmp(LayoutsList[uIndex].LayoutID, KeyName) == 0) { UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, (wcslen(KeyName) + 1) * sizeof(WCHAR)); if (UserData == NULL) { /* FIXME: Handle error! */ DPRINT("RtlAllocateHeap() failed\n"); DestroyGenericList(List, FALSE); return NULL; } wcscpy(UserData, KeyName); sprintf(Buffer, "%S", KeyValue); AppendGenericListEntry(List, Buffer, UserData, _wcsicmp(KeyName, DefaultKBLayout) ? FALSE : TRUE); KeyboardLayoutsFound = TRUE; } } while (SetupFindNextLine(&Context, &Context)); uIndex++; } while (LayoutsList[uIndex].LangID != NULL); /* FIXME: Handle this case */ if (!KeyboardLayoutsFound) { DPRINT1("No keyboard layouts have been found\n"); DestroyGenericList(List, FALSE); return NULL; } return List; }
static INT LoadFreeldrSettings(HINF hInf, HWND hwndDlg) { INFCONTEXT InfContext; PBOOTRECORD pRecord; WCHAR szDefaultOs[MAX_PATH]; WCHAR szName[MAX_PATH]; WCHAR szValue[MAX_PATH]; DWORD LineLength; DWORD TimeOut; LRESULT lResult; if (!SetupFindFirstLineW(hInf, L"FREELOADER", L"DefaultOS", &InfContext)) { /* Failed to find default os */ return FALSE; } if (!SetupGetStringFieldW(&InfContext, 1, szDefaultOs, sizeof(szDefaultOs) / sizeof(WCHAR), &LineLength)) { /* No key */ return FALSE; } if (!SetupFindFirstLineW(hInf, L"FREELOADER", L"TimeOut", &InfContext)) { /* Expected to find timeout value */ return FALSE; } if (!SetupGetIntField(&InfContext, 1, (PINT)&TimeOut)) { /* Failed to retrieve timeout */ return FALSE; } if (!SetupFindFirstLineW(hInf, L"Operating Systems", NULL, &InfContext)) { /* Expected list of operating systems */ return FALSE; } do { if (!SetupGetStringFieldW(&InfContext, 0, szName, sizeof(szName) / sizeof(WCHAR), &LineLength)) { /* The ini file is messed up */ return FALSE; } if (!SetupGetStringFieldW(&InfContext, 1, szValue, sizeof(szValue) / sizeof(WCHAR), &LineLength)) { /* The ini file is messed up */ return FALSE; } pRecord = ReadFreeldrSection(hInf, szName); if (pRecord) { lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue); if (lResult != CB_ERR) { SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord); if (!wcscmp(szDefaultOs, szName)) { /* We store the friendly name as key */ wcscpy(szDefaultOs, szValue); } } else { HeapFree(GetProcessHeap(), 0, pRecord); } } } while (SetupFindNextLine(&InfContext, &InfContext)); /* Find default os in list */ lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szDefaultOs); if (lResult != CB_ERR) { /* Set cur sel */ SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0); } if(TimeOut) { SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); } SetTimeout(hwndDlg, TimeOut); return TRUE; }
BOOLEAN ProcessDisplayRegistry(HINF InfFile, PGENERIC_LIST List) { PGENERIC_LIST_ENTRY Entry; INFCONTEXT Context; PWCHAR ServiceName; ULONG StartValue; NTSTATUS Status; WCHAR RegPath [255]; PWCHAR Buffer; ULONG Width, Height, Bpp; DPRINT("ProcessDisplayRegistry() called\n"); Entry = GetCurrentListEntry(List); if (Entry == NULL) { DPRINT("GetCurrentListEntry() failed\n"); return FALSE; } if (!SetupFindFirstLineW(InfFile, L"Display", (WCHAR*)GetListEntryUserData(Entry), &Context)) { DPRINT("SetupFindFirstLineW() failed\n"); return FALSE; } /* Enable the right driver */ if (!INF_GetDataField(&Context, 3, &ServiceName)) { DPRINT("INF_GetDataField() failed\n"); return FALSE; } ASSERT(wcslen(ServiceName) < 10); DPRINT("Service name: %S\n", ServiceName); StartValue = 1; Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, ServiceName, L"Start", REG_DWORD, &StartValue, sizeof(ULONG)); if (!NT_SUCCESS(Status)) { DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status); return FALSE; } /* Set the resolution */ swprintf(RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\%s\\Device0", ServiceName); if (!INF_GetDataField(&Context, 4, &Buffer)) { DPRINT("INF_GetDataField() failed\n"); return FALSE; } Width = wcstoul(Buffer, NULL, 10); Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, RegPath, L"DefaultSettings.XResolution", REG_DWORD, &Width, sizeof(ULONG)); if (!NT_SUCCESS(Status)) { DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status); return FALSE; } if (!INF_GetDataField(&Context, 5, &Buffer)) { DPRINT("INF_GetDataField() failed\n"); return FALSE; } Height = wcstoul(Buffer, 0, 0); Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, RegPath, L"DefaultSettings.YResolution", REG_DWORD, &Height, sizeof(ULONG)); if (!NT_SUCCESS(Status)) { DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status); return FALSE; } if (!INF_GetDataField(&Context, 6, &Buffer)) { DPRINT("INF_GetDataField() failed\n"); return FALSE; } Bpp = wcstoul(Buffer, 0, 0); Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, RegPath, L"DefaultSettings.BitsPerPel", REG_DWORD, &Bpp, sizeof(ULONG)); if (!NT_SUCCESS(Status)) { DPRINT("RtlWriteRegistryValue() failed (Status %lx)\n", Status); return FALSE; } DPRINT("ProcessDisplayRegistry() done\n"); return TRUE; }
PGENERIC_LIST CreateLanguageList(HINF InfFile, WCHAR * DefaultLanguage) { CHAR Buffer[128]; PGENERIC_LIST List; INFCONTEXT Context; PWCHAR KeyName; PWCHAR KeyValue; PWCHAR UserData = NULL; ULONG uIndex = 0; /* Get default language id */ if (!SetupFindFirstLineW (InfFile, L"NLS", L"DefaultLanguage", &Context)) return NULL; if (!INF_GetData (&Context, NULL, &KeyValue)) return NULL; wcscpy(DefaultLanguage, KeyValue); SelectedLanguageId = KeyValue; List = CreateGenericList(); if (List == NULL) return NULL; if (!SetupFindFirstLineW (InfFile, L"Language", NULL, &Context)) { DestroyGenericList(List, FALSE); return NULL; } do { if (!INF_GetData (&Context, &KeyName, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetData() failed\n"); break; } if (IsLanguageAvailable(KeyName)) { UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, (wcslen(KeyName) + 1) * sizeof(WCHAR)); if (UserData == NULL) { /* FIXME: Handle error! */ } wcscpy(UserData, KeyName); if (!_wcsicmp(KeyName, DefaultLanguage)) DefaultLanguageIndex = uIndex; sprintf(Buffer, "%S", KeyValue); AppendGenericListEntry(List, Buffer, UserData, FALSE); uIndex++; } } while (SetupFindNextLine(&Context, &Context)); /* Only one language available, make it the default one */ if(uIndex == 1 && UserData != NULL) { DefaultLanguageIndex = 0; wcscpy(DefaultLanguage, UserData); } return List; }
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); }
PGENERIC_LIST CreateDisplayDriverList(HINF InfFile) { CHAR Buffer[128]; PGENERIC_LIST List; INFCONTEXT Context; PWCHAR KeyName; PWCHAR KeyValue; PWCHAR UserData; WCHAR DisplayIdentifier[128]; WCHAR DisplayKey[32]; /* Get the display identification */ if (!GetDisplayIdentifier(DisplayIdentifier, 128)) { DisplayIdentifier[0] = 0; } DPRINT("Display identifier: '%S'\n", DisplayIdentifier); /* Search for matching device identifier */ if (!SetupFindFirstLineW(InfFile, L"Map.Display", NULL, &Context)) { /* FIXME: error message */ return NULL; } do { if (!INF_GetDataField(&Context, 1, &KeyValue)) { /* FIXME: Handle error! */ DPRINT("INF_GetDataField() failed\n"); return NULL; } DPRINT("KeyValue: %S\n", KeyValue); if (wcsstr(DisplayIdentifier, KeyValue)) { if (!INF_GetDataField(&Context, 0, &KeyName)) { /* FIXME: Handle error! */ DPRINT("INF_GetDataField() failed\n"); return NULL; } DPRINT("Display key: %S\n", KeyName); wcscpy(DisplayKey, KeyName); } } while (SetupFindNextLine(&Context, &Context)); List = CreateGenericList(); if (List == NULL) return NULL; if (!SetupFindFirstLineW (InfFile, L"Display", NULL, &Context)) { DestroyGenericList(List, FALSE); return NULL; } do { if (!INF_GetDataField(&Context, 0, &KeyName)) { DPRINT1("INF_GetDataField() failed\n"); break; } if (!INF_GetDataField(&Context, 1, &KeyValue)) { DPRINT1("INF_GetDataField() failed\n"); break; } UserData = (WCHAR*) RtlAllocateHeap(ProcessHeap, 0, (wcslen(KeyName) + 1) * sizeof(WCHAR)); if (UserData == NULL) { DPRINT1("RtlAllocateHeap() failed\n"); DestroyGenericList(List, TRUE); return NULL; } wcscpy(UserData, KeyName); sprintf(Buffer, "%S", KeyValue); AppendGenericListEntry(List, Buffer, UserData, _wcsicmp(KeyName, DisplayKey) ? FALSE : TRUE); } while (SetupFindNextLine(&Context, &Context)); #if 0 AppendGenericListEntry(List, "Other display driver", NULL, TRUE); #endif return List; }
static INT LoadBootSettings(HINF hInf, HWND hwndDlg) { INFCONTEXT InfContext; WCHAR szName[MAX_PATH]; WCHAR szValue[MAX_PATH]; DWORD LineLength; DWORD TimeOut = 0; WCHAR szDefaultOS[MAX_PATH]; WCHAR szOptions[MAX_PATH]; PBOOTRECORD pRecord; LRESULT lResult; if(!SetupFindFirstLineW(hInf, L"boot loader", NULL, &InfContext)) { return FALSE; } do { if (!SetupGetStringFieldW(&InfContext, 0, szName, sizeof(szName) / sizeof(WCHAR), &LineLength)) { return FALSE; } if (!SetupGetStringFieldW(&InfContext, 1, szValue, sizeof(szValue) / sizeof(WCHAR), &LineLength)) { return FALSE; } if (!_wcsnicmp(szName, L"timeout", 7)) { TimeOut = _wtoi(szValue); } if (!_wcsnicmp(szName, L"default", 7)) { wcscpy(szDefaultOS, szValue); } } while (SetupFindNextLine(&InfContext, &InfContext)); if (!SetupFindFirstLineW(hInf, L"operating systems", NULL, &InfContext)) { /* Failed to find operating systems section */ return FALSE; } do { if (!SetupGetStringFieldW(&InfContext, 0, szName, sizeof(szName) / sizeof(WCHAR), &LineLength)) { return FALSE; } if (!SetupGetStringFieldW(&InfContext, 1, szValue, sizeof(szValue) / sizeof(WCHAR), &LineLength)) { return FALSE; } SetupGetStringFieldW(&InfContext, 2, szOptions, sizeof(szOptions) / sizeof(WCHAR), &LineLength); pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD)); if (pRecord) { pRecord->BootType = 0; wcscpy(pRecord->szBootPath, szName); wcscpy(pRecord->szSectionName, szValue); wcscpy(pRecord->szOptions, szOptions); if (!wcscmp(szName, szDefaultOS)) { /* ms boot ini stores the path not the friendly name */ wcscpy(szDefaultOS, szValue); } lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue); if (lResult != CB_ERR) { SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord); } else { HeapFree(GetProcessHeap(), 0, pRecord); } } } while (SetupFindNextLine(&InfContext, &InfContext)); /* Find default os in list */ lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0, (LPARAM)szDefaultOS); if (lResult != CB_ERR) { /* Set cur sel */ SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0); } if(TimeOut) { SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); } SetTimeout(hwndDlg, TimeOut); return TRUE; }
static BOOL InstallSysSetupInfComponents(VOID) { INFCONTEXT InfContext; WCHAR szNameBuffer[256]; WCHAR szSectionBuffer[256]; HINF hComponentInf = INVALID_HANDLE_VALUE; if (!SetupFindFirstLineW(hSysSetupInf, L"Infs.Always", NULL, &InfContext)) { DPRINT("No Inf.Always section found\n"); } else { do { if (!SetupGetStringFieldW(&InfContext, 1, // Get the component name szNameBuffer, sizeof(szNameBuffer)/sizeof(szNameBuffer[0]), NULL)) { FatalError("Error while trying to get component name \n"); return FALSE; } if (!SetupGetStringFieldW(&InfContext, 2, // Get the component install section szSectionBuffer, sizeof(szSectionBuffer)/sizeof(szSectionBuffer[0]), NULL)) { FatalError("Error while trying to get component install section \n"); return FALSE; } DPRINT("Trying to execute install section '%S' from '%S' \n", szSectionBuffer, szNameBuffer); hComponentInf = SetupOpenInfFileW(szNameBuffer, NULL, INF_STYLE_WIN4, NULL); if (hComponentInf == INVALID_HANDLE_VALUE) { FatalError("SetupOpenInfFileW() failed to open '%S' (Error: %lu)\n", szNameBuffer, GetLastError()); return FALSE; } if (!SetupInstallFromInfSectionW(NULL, hComponentInf, szSectionBuffer, SPINST_ALL, NULL, NULL, SP_COPY_NEWER, SetupDefaultQueueCallbackW, NULL, NULL, NULL)) { FatalError("Error while trying to install : %S (Error: %lu)\n", szNameBuffer, GetLastError()); SetupCloseInfFile(hComponentInf); return FALSE; } SetupCloseInfFile(hComponentInf); } while (SetupFindNextLine(&InfContext, &InfContext)); } return TRUE; }
BOOLEAN InstallDriver( IN HINF hInf, IN HANDLE hServices, IN HANDLE hDeviceKey, IN LPCWSTR DeviceId, IN LPCWSTR HardwareId) { UNICODE_STRING PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\"); UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service"); UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl"); UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath"); UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start"); UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type"); UNICODE_STRING StringU; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hService; INFCONTEXT Context; LPWSTR Driver, ClassGuid, ImagePath, FullImagePath; ULONG dwValue; ULONG Disposition; NTSTATUS Status; BOOLEAN deviceInstalled = FALSE; UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters"); LPWSTR keyboardClass = L"kbdclass\0"; /* Check if we know the hardware */ if (!SetupFindFirstLineW(hInf, L"HardwareIdsDatabase", HardwareId, &Context)) return FALSE; if (!INF_GetDataField(&Context, 1, &Driver)) return FALSE; /* Get associated class GUID (if any) */ if (!INF_GetDataField(&Context, 2, &ClassGuid)) ClassGuid = NULL; /* Find associated driver name */ /* FIXME: check in other sections too! */ if (!SetupFindFirstLineW(hInf, L"BootBusExtenders.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"BusExtenders.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"SCSI.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"InputDevicesSupport.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"Keyboard.Load", Driver, &Context)) { return FALSE; } if (!INF_GetDataField(&Context, 1, &ImagePath)) return FALSE; /* Prepare full driver path */ dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR); FullImagePath = (LPWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue); if (!FullImagePath) { DPRINT1("RtlAllocateHeap() failed\n"); return FALSE; } RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength); wcscat(FullImagePath, ImagePath); DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId); /* Create service key */ RtlInitUnicodeString(&StringU, Driver); InitializeObjectAttributes(&ObjectAttributes, &StringU, 0, hServices, NULL); Status = NtCreateKey(&hService, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status); RtlFreeHeap(ProcessHeap, 0, FullImagePath); return FALSE; } /* Fill service key */ if (Disposition == REG_CREATED_NEW_KEY) { dwValue = 0; NtSetValueKey( hService, &ErrorControlU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = 0; NtSetValueKey( hService, &StartU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = SERVICE_KERNEL_DRIVER; NtSetValueKey( hService, &TypeU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); } /* HACK: don't put any path in registry */ NtSetValueKey( hService, &ImagePathU, 0, REG_SZ, ImagePath, (wcslen(ImagePath) + 1) * sizeof(WCHAR)); if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0) { DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId); NtSetValueKey(hDeviceKey, &UpperFiltersU, 0, REG_MULTI_SZ, keyboardClass, (wcslen(keyboardClass) + 2) * sizeof(WCHAR)); } /* Associate device with the service we just filled */ Status = NtSetValueKey( hDeviceKey, &ServiceU, 0, REG_SZ, Driver, (wcslen(Driver) + 1) * sizeof(WCHAR)); if (NT_SUCCESS(Status)) { /* Restart the device, so it will use the driver we registered */ deviceInstalled = ResetDevice(DeviceId); } /* HACK: Update driver path */ NtSetValueKey( hService, &ImagePathU, 0, REG_SZ, FullImagePath, (wcslen(FullImagePath) + 1) * sizeof(WCHAR)); RtlFreeHeap(ProcessHeap, 0, FullImagePath); NtClose(hService); return deviceInstalled; }
DWORD WINAPI NetClassInstaller( IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) { SP_DRVINFO_DATA_W DriverInfoData; SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail; WCHAR SectionName[LINE_LEN]; HINF hInf = INVALID_HANDLE_VALUE; INFCONTEXT InfContext; UINT ErrorLine; INT CharacteristicsInt; DWORD Characteristics; LPWSTR BusType = NULL; RPC_STATUS RpcStatus; UUID Uuid; LPWSTR UuidRpcString = NULL; LPWSTR UuidString = NULL; LONG rc; DWORD dwLength; if (InstallFunction != DIF_INSTALLDEVICE) return ERROR_DI_DO_DEFAULT; DPRINT("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData); /* Get driver info details */ DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W); if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData)) { rc = GetLastError(); DPRINT("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc); goto cleanup; } DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { rc = GetLastError(); DPRINT("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc); goto cleanup; } hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine); if (hInf == INVALID_HANDLE_VALUE) { rc = GetLastError(); DPRINT("SetupOpenInfFileW() failed with error 0x%lx\n", rc); goto cleanup; } if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL)) { rc = GetLastError(); DPRINT("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc); goto cleanup; } /* Get Characteristics and BusType (optional) from .inf file */ if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext)) { rc = GetLastError(); DPRINT("Unable to find key %S in section %S of file %S (error 0x%lx)\n", L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc); goto cleanup; } if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt)) { rc = GetLastError(); DPRINT("SetupGetIntField() failed with error 0x%lx\n", rc); goto cleanup; } Characteristics = (DWORD)CharacteristicsInt; if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) { if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext)) { if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength)) { rc = GetLastError(); DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc); goto cleanup; } BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); if (!BusType) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL)) { rc = GetLastError(); DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc); goto cleanup; } } } /* Create a new UUID */ RpcStatus = UuidCreate(&Uuid); if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) { DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); rc = ERROR_GEN_FAILURE; goto cleanup; } RpcStatus = UuidToStringW(&Uuid, &UuidRpcString); if (RpcStatus != RPC_S_OK) { DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); rc = ERROR_GEN_FAILURE; goto cleanup; } /* Add curly braces around Uuid */ UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); if (!UuidString) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } wcscpy(UuidString, L"{"); wcscat(UuidString, UuidRpcString); wcscat(UuidString, L"}"); if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType); else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT)) rc = InstallNetClient(); else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE)) rc = InstallNetService(); else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS)) rc = InstallNetTransport(); else { DPRINT("Invalid class guid\n"); rc = ERROR_GEN_FAILURE; } cleanup: if (hInf != INVALID_HANDLE_VALUE) SetupCloseInfFile(hInf); if (UuidRpcString != NULL) RpcStringFreeW(&UuidRpcString); HeapFree(GetProcessHeap(), 0, BusType); HeapFree(GetProcessHeap(), 0, UuidString); if (rc == ERROR_SUCCESS) rc = ERROR_DI_DO_DEFAULT; DPRINT("Returning 0x%lx\n", rc); return rc; }
/* loads the LDIDs specified in the install section of an INF */ void set_ldids(HINF hInf, LPCWSTR pszInstallSection, LPCWSTR pszWorkingDir) { WCHAR field[MAX_FIELD_LENGTH]; WCHAR line[MAX_FIELD_LENGTH]; WCHAR dest[MAX_PATH]; INFCONTEXT context; DWORD size; int ldid; static const WCHAR source_dir[] = {'S','o','u','r','c','e','D','i','r',0}; static const WCHAR custDestW[] = { 'C','u','s','t','o','m','D','e','s','t','i','n','a','t','i','o','n',0 }; if (!SetupGetLineTextW(NULL, hInf, pszInstallSection, custDestW, field, MAX_FIELD_LENGTH, &size)) return; if (!SetupFindFirstLineW(hInf, field, NULL, &context)) return; do { LPWSTR value, ptr, key, key_copy = NULL; DWORD flags = 0; SetupGetLineTextW(&context, NULL, NULL, NULL, line, MAX_FIELD_LENGTH, &size); /* SetupGetLineTextW returns the value if there is only one key, but * returns the whole line if there is more than one key */ if (!(value = strchrW(line, '='))) { SetupGetStringFieldW(&context, 0, NULL, 0, &size); key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); key_copy = key; SetupGetStringFieldW(&context, 0, key, size, &size); value = line; } else { key = line; *(value++) = '\0'; } /* remove leading whitespace from the value */ while (*value == ' ') value++; /* Extract the flags */ ptr = strchrW(value, ','); if (ptr) { *ptr = '\0'; flags = atolW(ptr+1); } /* set dest to pszWorkingDir if key is SourceDir */ if (pszWorkingDir && !lstrcmpiW(value, source_dir)) lstrcpynW(dest, pszWorkingDir, MAX_PATH); else get_dest_dir(hInf, value, dest, MAX_PATH); /* If prompting required, provide dialog to request path */ if (flags & 0x04) FIXME("Need to support changing paths - default will be used\n"); /* set all ldids to dest */ while ((ptr = get_parameter(&key, ',', FALSE))) { ldid = atolW(ptr); SetupSetDirectoryIdW(hInf, ldid, dest); } HeapFree(GetProcessHeap(), 0, key_copy); } while (SetupFindNextLine(&context, &context)); }