Implement SetupDiBuildDriverInfoList, SetupDiOpenDeviceInfoA/W, SetupDiEnumDriverInfoA/W, SetupDiCreateDeviceInfoW Add stubs for SetupDiDeleteDeviceInfo, SetupDiDestroyDriverInfoList Modified: trunk/reactos/lib/setupapi/devinst.c Modified: trunk/reactos/lib/setupapi/setupapi.spec _____
Modified: trunk/reactos/lib/setupapi/devinst.c --- trunk/reactos/lib/setupapi/devinst.c 2005-08-08 16:08:30 UTC (rev 17211) +++ trunk/reactos/lib/setupapi/devinst.c 2005-08-08 16:09:48 UTC (rev 17212) @@ -2787,8 +2787,904 @@
DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData) { - FIXME("%p %s %s %s %p %lx %p\n", DeviceInfoSet, debugstr_w(DeviceName), - debugstr_guid(ClassGuid), debugstr_w(DeviceDescription), hwndParent, - CreationFlags, DeviceInfoData); + struct DeviceInfoSet *list; + BOOL ret = FALSE; + + TRACE("%p %S %s %S %p %lx %p\n", DeviceInfoSet, DeviceName, + debugstr_guid(ClassGuid), DeviceDescription, + hwndParent, CreationFlags, DeviceInfoData); + + if (!DeviceInfoSet) + SetLastError(ERROR_INVALID_HANDLE); + else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (!ClassGuid) + SetLastError(ERROR_INVALID_PARAMETER); + else if (!IsEqualIID(&list->ClassGuid, &GUID_NULL) && !IsEqualIID(&list->ClassGuid, ClassGuid)) + SetLastError(ERROR_CLASS_MISMATCH); + else if (CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS)) + { + TRACE("Unknown flags: 0x%08lx\n", CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS)); + SetLastError(ERROR_INVALID_PARAMETER); + } + else + { + SP_DEVINFO_DATA DevInfo; + + if (CreationFlags & DICD_GENERATE_ID) + { + /* Generate a new unique ID for this device */ + SetLastError(ERROR_GEN_FAILURE); + FIXME("not implemented\n"); + } + else + { + /* Device name is fully qualified. Try to open it */ + BOOL rc; + + DevInfo.cbSize = sizeof(SP_DEVINFO_DATA); + rc = SetupDiOpenDeviceInfoW( + DeviceInfoSet, + DeviceName, + NULL, /* hwndParent */ + CreationFlags & DICD_INHERIT_CLASSDRVS ? DIOD_INHERIT_CLASSDRVS : 0, + &DevInfo); + + if (rc) + { + /* SetupDiOpenDeviceInfoW has already added + * the device info to the device info set + */ + SetLastError(ERROR_DEVINST_ALREADY_EXISTS); + } + else if (GetLastError() == ERROR_FILE_NOT_FOUND) + { + struct DeviceInfoElement *deviceInfo; + + deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfoElement) + (wcslen(DeviceName) + 1) * sizeof(WCHAR)); + if (!deviceInfo) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } + else + { + /* Fill members of the new structure */ + wcscpy(deviceInfo->Data, DeviceName); + deviceInfo->DeviceName = deviceInfo->Data; + deviceInfo->UniqueId = wcsrchr(deviceInfo->Data, '\'); + deviceInfo->DeviceDescription = NULL; + //FIXME memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID)); + deviceInfo->CreationFlags = 0; + deviceInfo->hwndParent = hwndParent; + deviceInfo->Flags = 0; /* FIXME */ + deviceInfo->FlagsEx = 0; /* FIXME */ + InitializeListHead(&deviceInfo->DriverListHead); + InitializeListHead(&deviceInfo->InterfaceHead); + InsertTailList(&list->ListHead, &deviceInfo->ListEntry); + + if (!DeviceInfoData) + ret = TRUE; + else + { + if (DeviceInfoData->cbSize != sizeof(PSP_DEVINFO_DATA)) + { + SetLastError(ERROR_INVALID_USER_BUFFER); + } + else + { + memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID)); + DeviceInfoData->DevInst = 0; /* FIXME */ + DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo; + ret = TRUE; + } + } + } + } + } + } + + TRACE("Returning %d\n", ret); + return ret; +} + +/********************************************************************** * + * Helper functions for SetupDiBuildDriverInfoList + */ +static BOOL +AddDriverToList( + IN PLIST_ENTRY DriverListHead, + IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */ + IN INFCONTEXT ContextDevice, + IN LPCWSTR InfFile, + IN LPCWSTR ProviderName, + IN LPCWSTR ManufacturerName, + FILETIME DriverDate, + DWORDLONG DriverVersion, + IN DWORD Rank, + IN DWORD SubRank) +{ + struct DriverInfoElement *driverInfo; + DWORD RequiredSize = 128; /* Initial buffer size */ + BOOL Result = FALSE; + LPWSTR DeviceDescription = NULL; + LPWSTR InfInstallSection = NULL; + + driverInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DriverInfoElement)); + if (!driverInfo) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, DeviceDescription); + DeviceDescription = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!DeviceDescription) + return FALSE; + Result = SetupGetStringFieldW( + &ContextDevice, + 0, /* Field index */ + DeviceDescription, RequiredSize, + &RequiredSize); + } + if (!Result) + { + HeapFree(GetProcessHeap(), 0, driverInfo); + HeapFree(GetProcessHeap(), 0, DeviceDescription); + return FALSE; + } + + Result = FALSE; + RequiredSize = 128; /* Initial buffer size */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, InfInstallSection); + InfInstallSection = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!InfInstallSection) + { + HeapFree(GetProcessHeap(), 0, driverInfo); + HeapFree(GetProcessHeap(), 0, DeviceDescription); + return FALSE; + } + Result = SetupGetStringFieldW( + &ContextDevice, + 1, /* Field index */ + InfInstallSection, RequiredSize, + &RequiredSize); + } + if (!Result) + { + HeapFree(GetProcessHeap(), 0, driverInfo); + HeapFree(GetProcessHeap(), 0, DeviceDescription); + HeapFree(GetProcessHeap(), 0, InfInstallSection); + return FALSE; + } + + TRACE("Adding driver '%S' [%S/%S]\n", DeviceDescription, InfFile, InfInstallSection); + + driverInfo->Info.DriverType = DriverType; + driverInfo->Info.Reserved = (ULONG_PTR)driverInfo; + wcsncpy(driverInfo->Info.Description, DeviceDescription, LINE_LEN - 1); + driverInfo->Info.Description[LINE_LEN - 1] = '\0'; + wcsncpy(driverInfo->Info.MfgName, ManufacturerName, LINE_LEN - 1); + driverInfo->Info.MfgName[LINE_LEN - 1] = '\0'; + if (ProviderName) + { + wcsncpy(driverInfo->Info.ProviderName, ProviderName, LINE_LEN - 1); + driverInfo->Info.ProviderName[LINE_LEN - 1] = '\0'; + } + else + driverInfo->Info.ProviderName[0] = '\0'; + driverInfo->Info.DriverDate = DriverDate; + driverInfo->Info.DriverVersion = DriverVersion; + InsertTailList(DriverListHead, &driverInfo->ListEntry); + + HeapFree(GetProcessHeap(), 0, DeviceDescription); + HeapFree(GetProcessHeap(), 0, InfInstallSection); + return TRUE; +} + +static BOOL +GetVersionInformationFromInfFile( + IN HINF hInf, + OUT LPGUID ClassGuid, + OUT LPWSTR* pProviderName, + OUT FILETIME* DriverDate, + OUT DWORDLONG* DriverVersion) +{ + DWORD RequiredSize; + WCHAR guidW[MAX_GUID_STRING_LEN + 1]; + LPWSTR ProviderName = NULL; + BOOL Result; + + if (!SetupGetLineTextW( + NULL, /* Context */ + hInf, + L"Version", L"ClassGUID", + guidW, sizeof(guidW), + NULL /* Required size */)) + { + return FALSE; + } + + /* Get Provider name, driver date, and driver version */ + + guidW[37] = '\0'; /* Replace the } by a NULL character */ + if (UuidFromStringW(&guidW[1], ClassGuid) != RPC_S_OK) + { + return FALSE; + } + Result = SetupGetLineTextW( + NULL, /* Context */ + hInf, L"Version", L"Provider", + NULL, 0, + &RequiredSize); + if (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + ProviderName = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!ProviderName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + Result = SetupGetLineTextW( + NULL, /* Context */ + hInf, L"Version", L"Provider", + ProviderName, RequiredSize, + &RequiredSize); + } + //FIXME: DriverDate = Version.DriverVer => invalid date = 00/00/00 + //FIXME: DriverVersion = Version.DriverVer => invalid = 0 + + *pProviderName = ProviderName; + return TRUE; +} + +/********************************************************************** * + * SetupDiBuildDriverInfoList (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiBuildDriverInfoList( + IN HDEVINFO DeviceInfoSet, + IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, + IN DWORD DriverType) +{ + struct DeviceInfoSet *list; + PVOID Buffer = NULL; + HINF hInf = INVALID_HANDLE_VALUE; + LPWSTR ProviderName = NULL; + LPWSTR ManufacturerName = NULL; + LPWSTR ManufacturerSection = NULL; + LPWSTR HardwareIDs = NULL; + LPWSTR CompatibleIDs = NULL; + FILETIME DriverDate; + DWORDLONG DriverVersion; + DWORD RequiredSize; + BOOL ret = FALSE; + + TRACE("%p %p %ld\n", DeviceInfoSet, DeviceInfoData, DriverType); + + if (!DeviceInfoSet) + SetLastError(ERROR_INVALID_HANDLE); + else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (list->HKLM != HKEY_LOCAL_MACHINE) + SetLastError(ERROR_INVALID_HANDLE); + else if (DriverType != SPDIT_CLASSDRIVER && DriverType != SPDIT_COMPATDRIVER) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverType == SPDIT_CLASSDRIVER && DeviceInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverType == SPDIT_COMPATDRIVER && !DeviceInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + BOOL Result = FALSE; + + if (DriverType == SPDIT_COMPATDRIVER) + { + /* Get hardware IDs list */ + Result = FALSE; + RequiredSize = 512; /* Initial buffer size */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, HardwareIDs); + HardwareIDs = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!HardwareIDs) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + Result = SetupDiGetDeviceRegistryPropertyW( + DeviceInfoSet, + DeviceInfoData, + SPDRP_HARDWAREID, + NULL, + (PBYTE)HardwareIDs, + RequiredSize, + &RequiredSize); + } + if (!Result) + goto done; + + /* Get compatible IDs list */ + Result = FALSE; + RequiredSize = 512; /* Initial buffer size */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, CompatibleIDs); + CompatibleIDs = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!CompatibleIDs) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + Result = SetupDiGetDeviceRegistryPropertyW( + DeviceInfoSet, + DeviceInfoData, + SPDRP_COMPATIBLEIDS, + NULL, + (PBYTE)CompatibleIDs, + RequiredSize, + &RequiredSize); + if (!Result && GetLastError() == ERROR_FILE_NOT_FOUND) + { + /* No compatible ID for this device */ + HeapFree(GetProcessHeap(), 0, CompatibleIDs); + CompatibleIDs = NULL; + Result = TRUE; + } + } + if (!Result) + goto done; + } + + /* Enumerate .inf files */ + Result = FALSE; + RequiredSize = 32768; /* Initial buffer size */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, Buffer); + Buffer = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!Buffer) + { + Result = FALSE; + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + break; + } + Result = SetupGetInfFileListW( + NULL, /* Directory path */ + INF_STYLE_WIN4, + Buffer, RequiredSize, + &RequiredSize); + } + if (Result) + { + LPCWSTR filename; + for (filename = (LPCWSTR)Buffer; *filename; filename += wcslen(filename) + 1) + { + INFCONTEXT ContextManufacturer, ContextDevice; + GUID ClassGuid; + TRACE("Opening file %S\n", filename); + + hInf = SetupOpenInfFileW(filename, NULL, INF_STYLE_WIN4, NULL); + if (hInf == INVALID_HANDLE_VALUE) + continue; + + if (!GetVersionInformationFromInfFile( + hInf, + &ClassGuid, + &ProviderName, + &DriverDate, + &DriverVersion)) + { + SetupCloseInfFile(hInf); + hInf = INVALID_HANDLE_VALUE; + continue; + } + + if (DriverType == SPDIT_CLASSDRIVER) + { + /* Check if the ClassGuid in this .inf file is corresponding with our needs */ + if (!IsEqualIID(&list->ClassGuid, &GUID_NULL) && !IsEqualIID(&list->ClassGuid, &ClassGuid)) + { + SetupCloseInfFile(hInf); + hInf = INVALID_HANDLE_VALUE; + continue; + } + } + + /* Get the manufacturers list */ + Result = SetupFindFirstLineW(hInf, L"Manufacturer", NULL, &ContextManufacturer); + while (Result) + { + Result = SetupGetStringFieldW( + &ContextManufacturer, + 0, /* Field index */ + NULL, 0, + &RequiredSize); + if (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + ManufacturerName = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!ManufacturerName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + Result = SetupGetStringFieldW( + &ContextManufacturer, + 0, /* Field index */ + ManufacturerName, RequiredSize, + &RequiredSize); + } + Result = SetupGetStringFieldW( + &ContextManufacturer, + 1, /* Field index */ + NULL, 0, + &RequiredSize); + if (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + ManufacturerSection = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!ManufacturerSection) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + Result = SetupGetStringFieldW( + &ContextManufacturer, + 1, /* Field index */ + ManufacturerSection, RequiredSize, + &RequiredSize); + } + + TRACE("Enumerating devices in manufacturer %S\n", ManufacturerSection); + Result = SetupFindFirstLineW(hInf, ManufacturerSection, NULL, &ContextDevice); + while (Result) + { + if (DriverType == SPDIT_CLASSDRIVER) + { + /* FIXME: read [ControlFlags] / ExcludeFromSelect */ + if (!AddDriverToList( + &list->DriverListHead, + DriverType, + ContextDevice, + filename, + ProviderName, + ManufacturerName, + DriverDate, DriverVersion, + 0, 0)) + { + break; + } + } + else /* DriverType = SPDIT_COMPATDRIVER */ + { + /* 1. Get all fields */ + DWORD FieldCount = SetupGetFieldCount(&ContextDevice); + DWORD DriverRank; + DWORD i; + LPCWSTR currentId; + BOOL DriverAlreadyAdded; + + for (i = 2; i <= FieldCount; i++) + { + LPWSTR DeviceId = NULL; + Result = FALSE; + RequiredSize = 128; /* Initial buffer size */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + HeapFree(GetProcessHeap(), 0, DeviceId); + DeviceId = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR)); + if (!DeviceId) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto done; + } + Result = SetupGetStringFieldW( + &ContextDevice, + i, + DeviceId, RequiredSize, + &RequiredSize); + } + if (!Result) + { + HeapFree(GetProcessHeap(), 0, DeviceId); + goto done; + } + DriverRank = 0; + DriverAlreadyAdded = FALSE; + for (currentId = (LPCWSTR)HardwareIDs; !DriverAlreadyAdded && *currentId; currentId += wcslen(currentId) + 1, DriverRank++) + { + if (wcscmp(DeviceId, currentId) == 0) + { + AddDriverToList( + &((struct DeviceInfoElement *)DeviceInfoData->Reserved)->DriverListHead, + DriverType, + ContextDevice, + filename, + ProviderName, + ManufacturerName, + DriverDate, DriverVersion, + DriverRank, i); + DriverAlreadyAdded = TRUE; + } + } + if (CompatibleIDs) + { + for (currentId = (LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId += wcslen(currentId) + 1, DriverRank++) + { + if (wcscmp(DeviceId, currentId) == 0) + { + AddDriverToList( + &((struct DeviceInfoElement *)DeviceInfoData->Reserved)->DriverListHead, + DriverType, + ContextDevice, + filename, + ProviderName, + ManufacturerName, + DriverDate, DriverVersion, + DriverRank, i); + DriverAlreadyAdded = TRUE; + } + } + } + HeapFree(GetProcessHeap(), 0, DeviceId); + } + } + Result = SetupFindNextLine(&ContextDevice, &ContextDevice); + } + + HeapFree(GetProcessHeap(), 0, ManufacturerName); + HeapFree(GetProcessHeap(), 0, ManufacturerSection); + ManufacturerName = ManufacturerSection = NULL; + Result = SetupFindNextLine(&ContextManufacturer, &ContextManufacturer); + } + HeapFree(GetProcessHeap(), 0, ProviderName); + ProviderName = NULL; + ret = TRUE; + + SetupCloseInfFile(hInf); + hInf = INVALID_HANDLE_VALUE; + } + ret = TRUE; + } + } + +done: + HeapFree(GetProcessHeap(), 0, ProviderName); + HeapFree(GetProcessHeap(), 0, ManufacturerName); + HeapFree(GetProcessHeap(), 0, ManufacturerSection); + HeapFree(GetProcessHeap(), 0, HardwareIDs); + HeapFree(GetProcessHeap(), 0, CompatibleIDs); + if (hInf != INVALID_HANDLE_VALUE) + SetupCloseInfFile(hInf); + HeapFree(GetProcessHeap(), 0, Buffer); + TRACE("Returning %d\n", ret); + return ret; +} + +/********************************************************************** * + * SetupDiDeleteDeviceInfo (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiDeleteDeviceInfo( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData) +{ + TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData); + + FIXME("not implemented\n"); + SetLastError(ERROR_GEN_FAILURE); return FALSE; } + + +/********************************************************************** * + * SetupDiDestroyDriverInfoList (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiDestroyDriverInfoList( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData, + IN DWORD DriverType) +{ + TRACE("%p %p 0x%lx\n", DeviceInfoSet, DeviceInfoData, DriverType); + + FIXME("not implemented\n"); + SetLastError(ERROR_GEN_FAILURE); + return FALSE; +} + + +/********************************************************************** * + * SetupDiOpenDeviceInfoA (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiOpenDeviceInfoA( + IN HDEVINFO DeviceInfoSet, + IN PCSTR DeviceInstanceId, + IN HWND hwndParent OPTIONAL, + IN DWORD OpenFlags, + OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + LPWSTR DeviceInstanceIdW = NULL; + BOOL bResult; + + TRACE("%p %s %p %lx %p\n", DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData); + + DeviceInstanceIdW = MultiByteToUnicode(DeviceInstanceId, CP_ACP); + if (DeviceInstanceIdW == NULL) + return FALSE; + + bResult = SetupDiOpenDeviceInfoW(DeviceInfoSet, + DeviceInstanceIdW, hwndParent, OpenFlags, DeviceInfoData); + + MyFree(DeviceInstanceIdW); + + return bResult; +} + + +/********************************************************************** * + * SetupDiOpenDeviceInfoW (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiOpenDeviceInfoW( + IN HDEVINFO DeviceInfoSet, + IN PCWSTR DeviceInstanceId, + IN HWND hwndParent OPTIONAL, + IN DWORD OpenFlags, + OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) +{ + struct DeviceInfoSet *list; + HKEY hEnumKey, hKey; + DWORD rc; + BOOL ret = FALSE; + + TRACE("%p %S %p %lx %p\n", DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData); + + if (OpenFlags & DIOD_CANCEL_REMOVE) + FIXME("DIOD_CANCEL_REMOVE flag not implemented\n"); + + if (!DeviceInfoSet) + SetLastError(ERROR_INVALID_HANDLE); + else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (!DeviceInstanceId) + SetLastError(ERROR_INVALID_PARAMETER); + else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS)) + { + TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS)); + SetLastError(ERROR_INVALID_PARAMETER); + } + else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + struct DeviceInfoElement *deviceInfo = NULL; + /* Search if device already exists in DeviceInfoSet. + * If yes, return the existing element + * If no, create a new element using informations in registry + */ + PLIST_ENTRY ItemList = list->ListHead.Flink; + while (ItemList != &list->ListHead) + { + // TODO + //if (good one) + // break; + FIXME("not implemented\n"); + ItemList = ItemList->Flink; + } + + if (deviceInfo) + { + // good one found + if (DeviceInfoData) + { + memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID)); + DeviceInfoData->DevInst = 0; /* FIXME */ + DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo; + } + ret = TRUE; + } + else + { + /* Open supposed registry key */ + rc = RegOpenKeyExW( + list->HKLM, + EnumKeyName, + 0, /* Options */ + KEY_ENUMERATE_SUB_KEYS, + &hEnumKey); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + return FALSE; + } + rc = RegOpenKeyExW( + hEnumKey, + DeviceInstanceId, + 0, /* Options */ + KEY_QUERY_VALUE, + &hKey); + RegCloseKey(hEnumKey); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + return FALSE; + } + + deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfoElement) + (wcslen(DeviceInstanceId) + 1) * sizeof(WCHAR)); + if (!deviceInfo) + { + RegCloseKey(hKey); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + wcscpy(deviceInfo->Data, DeviceInstanceId); + deviceInfo->DeviceName = deviceInfo->Data; + //FIXME deviceInfo->UniqueId = &deviceInfo->Data[pEndOfInstancePath - InstancePath + 1]; + deviceInfo->DeviceDescription = NULL; + //FIXME memcpy(&deviceInfo->ClassGuid, FIXME, sizeof(GUID)); + deviceInfo->CreationFlags = 0; + deviceInfo->hwndParent = hwndParent; + deviceInfo->Flags = 0; /* FIXME */ + deviceInfo->FlagsEx = 0; /* FIXME */ + InitializeListHead(&deviceInfo->DriverListHead); + InitializeListHead(&deviceInfo->InterfaceHead); + InsertTailList(&list->ListHead, &deviceInfo->ListEntry); + + RegCloseKey(hKey); + ret = TRUE; + } + + if (ret && deviceInfo && DeviceInfoData) + { + memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID)); + DeviceInfoData->DevInst = 0; /* FIXME */ + DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo; + } + } + + return ret; +} + + +/********************************************************************** * + * SetupDiEnumDriverInfoA (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiEnumDriverInfoA( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, + IN DWORD DriverType, + IN DWORD MemberIndex, + OUT PSP_DRVINFO_DATA_A DriverInfoData) +{ + SP_DRVINFO_DATA_V2_W driverInfoData2W; + BOOL ret = FALSE; + + TRACE("%p %p 0x%lx %ld %p\n", DeviceInfoSet, DeviceInfoData, + DriverType, MemberIndex, DriverInfoData); + + if (DriverInfoData == NULL) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_A)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + driverInfoData2W.cbSize = sizeof(SP_DRVINFO_DATA_V2_W); + ret = SetupDiEnumDriverInfoW(DeviceInfoSet, DeviceInfoData, + DriverType, MemberIndex, &driverInfoData2W); + + if (ret) + { + /* Do W->A conversion */ + DriverInfoData->DriverType = driverInfoData2W.DriverType; + DriverInfoData->Reserved = driverInfoData2W.Reserved; + if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.Description, -1, + DriverInfoData->Description, LINE_LEN, NULL, NULL) == 0) + { + DriverInfoData->Description[0] = '\0'; + ret = FALSE; + } + if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.MfgName, -1, + DriverInfoData->MfgName, LINE_LEN, NULL, NULL) == 0) + { + DriverInfoData->MfgName[0] = '\0'; + ret = FALSE; + } + if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.ProviderName, -1, + DriverInfoData->ProviderName, LINE_LEN, NULL, NULL) == 0) + { + DriverInfoData->ProviderName[0] = '\0'; + ret = FALSE; + } + if (DriverInfoData->cbSize == sizeof(SP_DRVINFO_DATA_V2_A)) + { + /* Copy more fields */ + DriverInfoData->DriverDate = driverInfoData2W.DriverDate; + DriverInfoData->DriverVersion = driverInfoData2W.DriverVersion; + } + } + } + + TRACE("Returning %d\n", ret); + return ret; +} + + +/********************************************************************** * + * SetupDiEnumDriverInfoW (SETUPAPI.@) + */ +BOOL WINAPI +SetupDiEnumDriverInfoW( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, + IN DWORD DriverType, + IN DWORD MemberIndex, + OUT PSP_DRVINFO_DATA_W DriverInfoData) +{ + PLIST_ENTRY ListHead; + BOOL ret = FALSE; + + TRACE("%p %p 0x%lx %ld %p\n", DeviceInfoSet, DeviceInfoData, + DriverType, MemberIndex, DriverInfoData); + + if (!DeviceInfoSet || !DriverInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE) + SetLastError(ERROR_INVALID_HANDLE); + else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC) + SetLastError(ERROR_INVALID_HANDLE); + else if (DriverType != SPDIT_CLASSDRIVER && DriverType != SPDIT_COMPATDRIVER) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverType == SPDIT_CLASSDRIVER && DeviceInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverType == SPDIT_COMPATDRIVER && !DeviceInfoData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + struct DeviceInfoElement *devInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved; + PLIST_ENTRY ItemList; + if (DriverType == SPDIT_CLASSDRIVER || + devInfo->CreationFlags & DICD_INHERIT_CLASSDRVS) + { + ListHead = &((struct DeviceInfoSet *)DeviceInfoSet)->DriverListHead; + } + else + { + ListHead = &devInfo->DriverListHead; + } + + ItemList = ListHead->Flink; + while (ItemList != ListHead && MemberIndex-- > 0) + ItemList = ItemList->Flink; + if (ItemList == ListHead) + SetLastError(ERROR_NO_MORE_ITEMS); + else + { + struct DriverInfoElement *DrvInfo = (struct DriverInfoElement *)ItemList; + + memcpy( + DriverInfoData, + &DrvInfo->Info, + DriverInfoData->cbSize); + ret = TRUE; + } + } + + TRACE("Returning %d\n", ret); + return ret; +} _____
Modified: trunk/reactos/lib/setupapi/setupapi.spec --- trunk/reactos/lib/setupapi/setupapi.spec 2005-08-08 16:08:30 UTC (rev 17211) +++ trunk/reactos/lib/setupapi/setupapi.spec 2005-08-08 16:09:48 UTC (rev 17212) @@ -268,7 +268,7 @@
@ stdcall SetupDiBuildClassInfoList(long ptr long ptr) @ stdcall SetupDiBuildClassInfoListExA(long ptr long ptr str ptr) @ stdcall SetupDiBuildClassInfoListExW(long ptr long ptr wstr ptr) -@ stub SetupDiBuildDriverInfoList +@ stdcall SetupDiBuildDriverInfoList(long ptr long) @ stdcall SetupDiCallClassInstaller(long ptr ptr) @ stub SetupDiCancelDriverInfoSearch @ stub SetupDiChangeState @@ -293,12 +293,12 @@ @ stub SetupDiDeleteDeviceRegKey @ stub SetupDiDestroyClassImageList @ stdcall SetupDiDestroyDeviceInfoList(long) -@ stub SetupDiDestroyDriverInfoList +@ stdcall SetupDiDestroyDriverInfoList(long ptr long) @ stub SetupDiDrawMiniIcon @ stdcall SetupDiEnumDeviceInfo(long long ptr) @ stdcall SetupDiEnumDeviceInterfaces(long ptr ptr long ptr) -@ stub SetupDiEnumDriverInfoA -@ stub SetupDiEnumDriverInfoW +@ stdcall SetupDiEnumDriverInfoA(long ptr long long ptr) +@ stdcall SetupDiEnumDriverInfoW(long ptr long long ptr) @ stdcall SetupDiGetActualSectionToInstallA(long str str long ptr ptr) @ stdcall SetupDiGetActualSectionToInstallW(long wstr wstr long ptr ptr) @ stub SetupDiGetClassBitmapIndex @@ -359,8 +359,8 @@ @ stdcall SetupDiOpenClassRegKeyExA(ptr long long str ptr) @ stdcall SetupDiOpenClassRegKeyExW(ptr long long wstr ptr) @ stdcall SetupDiOpenDevRegKey(ptr ptr long long long long) -@ stub SetupDiOpenDeviceInfoA -@ stub SetupDiOpenDeviceInfoW +@ stdcall SetupDiOpenDeviceInfoA(ptr str long long ptr) +@ stdcall SetupDiOpenDeviceInfoW(ptr wstr long long ptr) @ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr) @ stub SetupDiOpenDeviceInterfaceRegKey @ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr)