X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fwin32-cfgmgr32.c;h=4acac2eef525868c042caba5add59e785fd24ce1;hb=06f9ecf36e529695feea35038e15233dffe37bb7;hp=4f40d1156a68de31e496b0d9b07d3c7a4b8a458d;hpb=1c2fb4a4f3eb5f9824e492f6b6c14e8cdf5072c4;p=pciutils.git diff --git a/lib/win32-cfgmgr32.c b/lib/win32-cfgmgr32.c index 4f40d11..4acac2e 100644 --- a/lib/win32-cfgmgr32.c +++ b/lib/win32-cfgmgr32.c @@ -403,9 +403,12 @@ get_driver_path_for_service(struct pci_access *a, LPCWSTR service_name, SC_HANDL SERVICE_STATUS service_status; SC_HANDLE service = NULL; char *driver_path = NULL; + int trim_system32 = 0; UINT systemroot_len; int driver_path_len; + UINT system32_len; HMODULE kernel32; + WCHAR *trim_ptr; DWORD error; service = OpenServiceW(manager, service_name, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS); @@ -466,36 +469,42 @@ retry_service_config: */ /* - * Old Windows versions return path to NT SystemRoot namespace via - * GetWindowsDirectoryW() function. New Windows versions via - * GetSystemWindowsDirectoryW(). GetSystemWindowsDirectoryW() is not - * provided in old Windows versions, so use GetProcAddress() for - * compatibility with all Windows versions. + * GetSystemWindowsDirectoryW() returns path to NT SystemRoot namespace. + * Alternativelly path to NT SystemRoot namespace can be constructed by + * GetSystemDirectoryW() by trimming "\\system32" from the end of path. + * GetSystemWindowsDirectoryW() is not provided in old Windows versions, + * so use GetProcAddress() for compatibility with all Windows versions. */ kernel32 = GetModuleHandleW(L"kernel32.dll"); if (kernel32) get_system_root_path = (void *)GetProcAddress(kernel32, "GetSystemWindowsDirectoryW"); - if (!get_system_root_path) - get_system_root_path = &GetWindowsDirectoryW; - - systemroot_len = get_system_root_path(NULL, 0); + else + { + get_system_root_path = &GetSystemDirectoryW; + trim_system32 = 1; + } if (!service_config->lpBinaryPathName || !service_config->lpBinaryPathName[0]) { - /* No ImagePath is specified, NT kernel assumes implicit kernel driver path by service name. */ - service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\System32\\drivers\\")-1 + wcslen(service_name) + sizeof(".sys")-1 + 1)); - systemroot_len = get_system_root_path(service_image_path, systemroot_len+1); - if (systemroot_len && service_image_path[systemroot_len-1] != L'\\') - service_image_path[systemroot_len++] = L'\\'; - wcscpy(service_image_path + systemroot_len, L"System32\\drivers\\"); - wcscpy(service_image_path + systemroot_len + sizeof("System32\\drivers\\")-1, service_name); - wcscpy(service_image_path + systemroot_len + sizeof("System32\\drivers\\")-1 + wcslen(service_name), L".sys"); + /* No ImagePath is specified, NT kernel assumes implicit kernel driver path by service name, which is relative to "\\system32\\drivers". */ + /* GetSystemDirectoryW() returns path to "\\system32" directory on all Windows versions. */ + system32_len = GetSystemDirectoryW(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */ + service_image_path = pci_malloc(a, sizeof(WCHAR) * (system32_len + sizeof("\\drivers\\")-1 + wcslen(service_name) + sizeof(".sys")-1)); + system32_len = GetSystemDirectoryW(service_image_path, system32_len); /* Now it returns number of WCHARs without nul-term. */ + if (system32_len && service_image_path[system32_len-1] != L'\\') + service_image_path[system32_len++] = L'\\'; + wcscpy(service_image_path + system32_len, L"drivers\\"); + wcscpy(service_image_path + system32_len + sizeof("drivers\\")-1, service_name); + wcscpy(service_image_path + system32_len + sizeof("drivers\\")-1 + wcslen(service_name), L".sys"); } else if (wcsncmp(service_config->lpBinaryPathName, L"\\SystemRoot\\", sizeof("\\SystemRoot\\")-1) == 0) { - /* ImagePath is in NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetWindowsDirectoryW(). */ + /* ImagePath is in NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetSystemDirectoryW(). */ + systemroot_len = get_system_root_path(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */ service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + wcslen(service_config->lpBinaryPathName) - (sizeof("\\SystemRoot")-1))); - systemroot_len = get_system_root_path(service_image_path, systemroot_len+1); + systemroot_len = get_system_root_path(service_image_path, systemroot_len); /* Now it returns number of WCHARs without nul-term. */ + if (trim_system32 && systemroot_len && (trim_ptr = wcsrchr(service_image_path, L'\\')) != NULL) + systemroot_len = trim_ptr - service_image_path; if (systemroot_len && service_image_path[systemroot_len-1] != L'\\') service_image_path[systemroot_len++] = L'\\'; wcscpy(service_image_path + systemroot_len, service_config->lpBinaryPathName + sizeof("\\SystemRoot\\")-1); @@ -525,9 +534,12 @@ retry_service_config: } else if (service_config->lpBinaryPathName[0] != L'\\') { - /* ImagePath is relative to the NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetWindowsDirectoryW(). */ - service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\") + wcslen(service_config->lpBinaryPathName))); - systemroot_len = get_system_root_path(service_image_path, systemroot_len+1); + /* ImagePath is relative to the NT SystemRoot namespace, convert to Win32 path via GetSystemWindowsDirectoryW()/GetSystemDirectoryW(). */ + systemroot_len = get_system_root_path(NULL, 0); /* Returns number of WCHARs plus 1 for nul-term. */ + service_image_path = pci_malloc(a, sizeof(WCHAR) * (systemroot_len + sizeof("\\")-1 + wcslen(service_config->lpBinaryPathName))); + systemroot_len = get_system_root_path(service_image_path, systemroot_len); /* Now it returns number of WCHARs without nul-term. */ + if (trim_system32 && systemroot_len && (trim_ptr = wcsrchr(service_image_path, L'\\')) != NULL) + systemroot_len = trim_ptr - service_image_path; if (systemroot_len && service_image_path[systemroot_len-1] != L'\\') service_image_path[systemroot_len++] = L'\\'; wcscpy(service_image_path + systemroot_len, service_config->lpBinaryPathName); @@ -714,7 +726,7 @@ retry_subname: { error = GetLastError(); if (error == 0) - a->warning("Cannot read driver %s key for PCI device %s: DevLoader key is stored as unknown type 0x%lx.", subname, devinst_id, unkn_reg_type); + a->warning("Cannot read driver %s key for PCI device %s: %s key is stored as unknown type 0x%lx.", subname, devinst_id, subname, unkn_reg_type); else if (error != ERROR_FILE_NOT_FOUND) a->warning("Cannot read driver %s key for PCI device %s: %s.", subname, devinst_id, win32_strerror(error)); else if (strcmp(subname, "minivdd") == 0) @@ -821,7 +833,7 @@ get_device_driver_path(struct pci_dev *d, SC_HANDLE manager, BOOL manager_suppor LPWSTR service_name = NULL; ULONG devinst_id_len = 0; char *driver_path = NULL; - DEVINST devinst = (DEVINST)d->aux; + DEVINST devinst = (DEVINST)d->backend_data; ULONG problem = 0; ULONG status = 0; HKEY key = NULL; @@ -1047,6 +1059,10 @@ fill_resources(struct pci_dev *d, DEVINST devinst, DEVINSTID_A devinst_id) prev_res_des = res_des; + /* Skip other resources early */ + if (res_id != ResType_IO && res_id != ResType_Mem && res_id != ResType_IRQ) + continue; + cr = CM_Get_Res_Des_Data_Size(&res_des_data_size, res_des, 0); if (cr != CR_SUCCESS) { @@ -1549,9 +1565,9 @@ scan_devinst_id(struct pci_access *a, DEVINSTID_A devinst_id) d = pci_get_dev(a, domain, bus, dev, func); pci_link_dev(a, d); - if (!d->access->aux) + if (!d->access->backend_data) d->no_config_access = 1; - d->aux = (void *)devinst; + d->backend_data = (void *)devinst; /* Parse device id part of devinst id and fill details into pci_dev. */ if (!a->buscentric) @@ -1565,7 +1581,7 @@ scan_devinst_id(struct pci_access *a, DEVINSTID_A devinst_id) fill_resources(d, devinst, devinst_id); /* - * Set parent field to cfgmgr32 parent devinst handle and aux field to current + * Set parent field to cfgmgr32 parent devinst handle and backend_data field to current * devinst handle. At later stage in win32_cfgmgr32_scan() when all pci_dev * devices are linked, change every devinst handle by pci_dev. */ @@ -1637,7 +1653,7 @@ win32_cfgmgr32_scan(struct pci_access *a) for (d1 = a->devices; d1; d1 = d1->next) { for (d2 = a->devices; d2; d2 = d2->next) - if ((DEVINST)d1->parent == (DEVINST)d2->aux) + if ((DEVINST)d1->parent == (DEVINST)d2->backend_data) break; d1->parent = d2; if (d1->parent) @@ -1645,9 +1661,9 @@ win32_cfgmgr32_scan(struct pci_access *a) } } - /* devinst stored in ->aux is not needed anymore, clear it. */ + /* devinst stored in ->backend_data is not needed anymore, clear it. */ for (d = a->devices; d; d = d->next) - d->aux = NULL; + d->backend_data = NULL; pci_mfree(devinst_id_list); } @@ -1697,7 +1713,7 @@ win32_cfgmgr32_fill_info(struct pci_dev *d, unsigned int flags) * All available flags were filled by win32_cfgmgr32_scan(). * Filling more flags is possible only from config space. */ - if (!d->access->aux) + if (!d->access->backend_data) return; pci_generic_fill_info(d, flags); @@ -1707,14 +1723,14 @@ static int win32_cfgmgr32_read(struct pci_dev *d, int pos, byte *buf, int len) { struct pci_access *a = d->access; - struct pci_access *acfg = a->aux; - struct pci_dev *dcfg = d->aux; + struct pci_access *acfg = a->backend_data; + struct pci_dev *dcfg = d->backend_data; if (!acfg) return pci_emulated_read(d, pos, buf, len); if (!dcfg) - d->aux = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func); + d->backend_data = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func); return pci_read_block(dcfg, pos, buf, len); } @@ -1723,14 +1739,14 @@ static int win32_cfgmgr32_write(struct pci_dev *d, int pos, byte *buf, int len) { struct pci_access *a = d->access; - struct pci_access *acfg = a->aux; - struct pci_dev *dcfg = d->aux; + struct pci_access *acfg = a->backend_data; + struct pci_dev *dcfg = d->backend_data; if (!acfg) return 0; if (!dcfg) - d->aux = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func); + d->backend_data = dcfg = pci_get_dev(acfg, d->domain, d->bus, d->dev, d->func); return pci_write_block(dcfg, pos, buf, len); } @@ -1738,7 +1754,7 @@ win32_cfgmgr32_write(struct pci_dev *d, int pos, byte *buf, int len) static void win32_cfgmgr32_cleanup_dev(struct pci_dev *d) { - struct pci_dev *dcfg = d->aux; + struct pci_dev *dcfg = d->backend_data; if (dcfg) pci_free_dev(dcfg); @@ -1782,13 +1798,13 @@ win32_cfgmgr32_init(struct pci_access *a) return; } - a->aux = acfg; + a->backend_data = acfg; } static void win32_cfgmgr32_cleanup(struct pci_access *a) { - struct pci_access *acfg = a->aux; + struct pci_access *acfg = a->backend_data; if (acfg) pci_cleanup(acfg);