Implement SetupDiGetSelectedDriverW/SetupDiSetSelectedDriverW
Define rank of a driver as in MSDN description
Fix comments in Flags/FlagsEx description
Factorise DeviceInfoElement structure creation in
CreateDeviceInfoElement().
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-09 16:08:00 UTC
(rev 17243)
+++ trunk/reactos/lib/setupapi/devinst.c 2005-08-09 16:13:50 UTC
(rev 17244)
@@ -152,6 +152,9 @@
/* If CreationFlags contains DICD_INHERIT_CLASSDRVS, this list is
invalid */
/* If the driver is not searched/detected, this list is empty */
LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */
+ /* Points into DriverListHead list. The pointer is NULL if no
driver is
+ * currently chosen. */
+ struct DriverInfoElement *SelectedDriver;
/* List of interfaces implemented by this device */
LIST_ENTRY InterfaceHead; /* List of struct DeviceInterface */
@@ -167,13 +170,9 @@
HKEY HKLM; /* Local or distant HKEY_LOCAL_MACHINE registry key */
/* Flags is a combination of:
- * - DI_FLAGSEX_DIDINFOLIST
* - DI_DIDCLASS
- * - DI_MULTMFGS
- * Set by SetupDiBuildDriverInfoList if drivers of
- * multiple manufacturers found
- * - DI_FLAGSEX_DIDCOMPATINFO
- * - DI_COMPAT_FROM_CLASS
+ * Set when the class driver list is created
+ * - DI_COMPAT_FROM_CLASS (FIXME: not supported)
* Forces SetupDiBuildDriverInfoList to build a class drivers
list
* FlagsEx is a combination of:
*/
@@ -182,6 +181,9 @@
/* If the driver is not searched/detected, this list is empty */
LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */
+ /* Points into DriverListHead list. The pointer is NULL if no
driver is
+ * currently chosen. */
+ struct DriverInfoElement *SelectedDriver;
LIST_ENTRY ListHead; /* List of struct DeviceInfoElement */
};
@@ -1156,6 +1158,39 @@
return ret;
}
+static BOOL
+CreateDeviceInfoElement(
+ IN LPCWSTR InstancePath,
+ LPCGUID pClassGuid,
+ OUT struct DeviceInfoElement **pDeviceInfo)
+{
+ struct DeviceInfoElement *deviceInfo;
+
+ *pDeviceInfo = NULL;
+
+ deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct
DeviceInfoElement) + (wcslen(InstancePath) + 1) * sizeof(WCHAR));
+ if (!deviceInfo)
+ {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return FALSE;
+ }
+ wcscpy(deviceInfo->Data, InstancePath);
+ deviceInfo->DeviceName = deviceInfo->Data;
+ deviceInfo->UniqueId = wcsrchr(deviceInfo->Data, '\\');
+ deviceInfo->DeviceDescription = NULL;
+ memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID));
+ deviceInfo->CreationFlags = 0;
+ deviceInfo->hwndParent = NULL;
+ deviceInfo->Flags = 0; /* FIXME */
+ deviceInfo->FlagsEx = 0; /* FIXME */
+ deviceInfo->SelectedDriver = NULL;
+ InitializeListHead(&deviceInfo->DriverListHead);
+ InitializeListHead(&deviceInfo->InterfaceHead);
+
+ *pDeviceInfo = deviceInfo;
+ return TRUE;
+}
+
static LONG SETUP_CreateDevListFromEnumerator(
struct DeviceInfoSet *list,
LPCGUID pClassGuid OPTIONAL,
@@ -1252,24 +1287,12 @@
}
/* Add the entry to the list */
- deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct
DeviceInfoElement) + (wcslen(InstancePath) + 1) * sizeof(WCHAR));
- if (!deviceInfo)
+ if (!CreateDeviceInfoElement(InstancePath, pClassGuid,
&deviceInfo))
{
RegCloseKey(hDeviceIdKey);
- return ERROR_NO_SYSTEM_RESOURCES;
+ return GetLastError();
}
TRACE("Adding '%S' to device info set %p\n", InstancePath,
list);
- wcscpy(deviceInfo->Data, InstancePath);
- deviceInfo->DeviceName = deviceInfo->Data;
- deviceInfo->UniqueId = &deviceInfo->Data[pEndOfInstancePath
- InstancePath + 1];
- deviceInfo->DeviceDescription = NULL;
- memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID));
- deviceInfo->CreationFlags = 0;
- deviceInfo->hwndParent = NULL;
- deviceInfo->Flags = 0; /* FIXME */
- deviceInfo->FlagsEx = 0; /* FIXME */
- InitializeListHead(&deviceInfo->DriverListHead);
- InitializeListHead(&deviceInfo->InterfaceHead);
InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
}
RegCloseKey(hDeviceIdKey);
@@ -2841,25 +2864,8 @@
{
struct DeviceInfoElement *deviceInfo;
- deviceInfo = HeapAlloc(GetProcessHeap(), 0,
sizeof(struct DeviceInfoElement) + (wcslen(DeviceName) + 1) *
sizeof(WCHAR));
- if (!deviceInfo)
+ if (CreateDeviceInfoElement(DeviceName, &GUID_NULL /*
FIXME */, &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)
@@ -2900,8 +2906,7 @@
IN LPCWSTR ManufacturerName,
FILETIME DriverDate,
DWORDLONG DriverVersion,
- IN DWORD Rank,
- IN DWORD SubRank)
+ IN DWORD Rank)
{
struct DriverInfoElement *driverInfo;
DWORD RequiredSize = 128; /* Initial buffer size */
@@ -2963,7 +2968,8 @@
return FALSE;
}
- TRACE("Adding driver '%S' [%S/%S]\n", DeviceDescription, InfFile,
InfInstallSection);
+ TRACE("Adding driver '%S' [%S/%S] (Rank 0x%lx)\n",
+ DeviceDescription, InfFile, InfInstallSection, Rank);
driverInfo->Info.DriverType = DriverType;
driverInfo->Info.Reserved = (ULONG_PTR)driverInfo;
@@ -3168,6 +3174,7 @@
if (Result)
{
LPCWSTR filename;
+
for (filename = (LPCWSTR)Buffer; *filename; filename +=
wcslen(filename) + 1)
{
INFCONTEXT ContextManufacturer, ContextDevice;
@@ -3259,7 +3266,7 @@
ProviderName,
ManufacturerName,
DriverDate, DriverVersion,
- 0, 0))
+ 0))
{
break;
}
@@ -3299,9 +3306,8 @@
HeapFree(GetProcessHeap(), 0,
DeviceId);
goto done;
}
- DriverRank = 0;
DriverAlreadyAdded = FALSE;
- for (currentId = (LPCWSTR)HardwareIDs;
!DriverAlreadyAdded && *currentId; currentId += wcslen(currentId) + 1,
DriverRank++)
+ for (DriverRank = 0, currentId =
(LPCWSTR)HardwareIDs; !DriverAlreadyAdded && *currentId; currentId +=
wcslen(currentId) + 1, DriverRank++)
{
if (wcscmp(DeviceId, currentId) ==
0)
{
@@ -3313,13 +3319,13 @@
ProviderName,
ManufacturerName,
DriverDate, DriverVersion,
- DriverRank, i);
+ DriverRank + (i == 2 ? 0 :
0x1000 + i - 3));
DriverAlreadyAdded = TRUE;
}
}
if (CompatibleIDs)
{
- for (currentId =
(LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId +=
wcslen(currentId) + 1, DriverRank++)
+ for (DriverRank = 0, currentId =
(LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId +=
wcslen(currentId) + 1, DriverRank++)
{
if (wcscmp(DeviceId, currentId)
== 0)
{
@@ -3331,7 +3337,7 @@
ProviderName,
ManufacturerName,
DriverDate,
DriverVersion,
- DriverRank, i);
+ DriverRank + (i == 2 ?
0x2000 : 0x3000 + i - 3));
DriverAlreadyAdded = TRUE;
}
}
@@ -3359,6 +3365,17 @@
}
done:
+ if (ret)
+ {
+ if (DeviceInfoData)
+ {
+ struct DeviceInfoElement *deviceInfo = (struct
DeviceInfoElement *)DeviceInfoData;
+ deviceInfo->Flags |= DI_DIDCOMPAT;
+ }
+ else
+ list->Flags |= DI_DIDCLASS;
+ }
+
HeapFree(GetProcessHeap(), 0, ProviderName);
HeapFree(GetProcessHeap(), 0, ManufacturerName);
HeapFree(GetProcessHeap(), 0, ManufacturerSection);
@@ -3367,6 +3384,7 @@
if (hInf != INVALID_HANDLE_VALUE)
SetupCloseInfFile(hInf);
HeapFree(GetProcessHeap(), 0, Buffer);
+
TRACE("Returning %d\n", ret);
return ret;
}
@@ -3522,25 +3540,11 @@
return FALSE;
}
- deviceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct
DeviceInfoElement) + (wcslen(DeviceInstanceId) + 1) * sizeof(WCHAR));
- if (!deviceInfo)
+ if (!CreateDeviceInfoElement(DeviceInstanceId, &GUID_NULL
/* FIXME */, &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);
@@ -3688,3 +3692,133 @@
TRACE("Returning %d\n", ret);
return ret;
}
+
+/**********************************************************************
*
+ * SetupDiGetSelectedDriverW (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiGetSelectedDriverW(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+ OUT PSP_DRVINFO_DATA_W DriverInfoData)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, 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 (DeviceInfoData && DeviceInfoData->cbSize !=
sizeof(SP_DEVINFO_DATA))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ 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 DriverInfoElement *driverInfo;
+
+ if (DeviceInfoData)
+ driverInfo = ((struct DeviceInfoElement
*)DeviceInfoData->Reserved)->SelectedDriver;
+ else
+ driverInfo = ((struct DeviceInfoSet
*)DeviceInfoSet)->SelectedDriver;
+
+ if (driverInfo == NULL)
+ SetLastError(ERROR_NO_DRIVER_SELECTED);
+ else
+ {
+ memcpy(
+ DriverInfoData,
+ &driverInfo->Info,
+ DriverInfoData->cbSize);
+ ret = TRUE;
+ }
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
+/**********************************************************************
*
+ * SetupDiSetSelectedDriverW (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiSetSelectedDriverW(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+ IN OUT PSP_DRVINFO_DATA_W DriverInfoData OPTIONAL)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DriverInfoData);
+
+ if (!DeviceInfoSet)
+ 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 (DeviceInfoData && DeviceInfoData->cbSize !=
sizeof(SP_DEVINFO_DATA))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if (DriverInfoData && DriverInfoData->cbSize !=
sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize !=
sizeof(SP_DRVINFO_DATA_V2_W))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else
+ {
+ struct DriverInfoElement **pDriverInfo;
+ PLIST_ENTRY ListHead, ItemList;
+
+ if (DeviceInfoData)
+ {
+ pDriverInfo = &((struct DeviceInfoElement
*)DeviceInfoData->Reserved)->SelectedDriver;
+ ListHead = &((struct DeviceInfoElement
*)DeviceInfoData->Reserved)->DriverListHead;
+ }
+ else
+ {
+ pDriverInfo = &((struct DeviceInfoSet
*)DeviceInfoSet)->SelectedDriver;
+ ListHead = &((struct DeviceInfoSet
*)DeviceInfoSet)->DriverListHead;
+ }
+
+ if (!DriverInfoData)
+ {
+ *pDriverInfo = NULL;
+ ret = TRUE;
+ }
+ else
+ {
+ /* Search selected driver in list */
+ ItemList = ListHead->Flink;
+ while (ItemList != ListHead)
+ {
+ if (DriverInfoData->Reserved != 0)
+ {
+ if (DriverInfoData->Reserved ==
(ULONG_PTR)ItemList)
+ break;
+ }
+ else
+ {
+ /* The caller wants to compare only DriverType,
Description and ProviderName fields */
+ struct DriverInfoElement *driverInfo = (struct
DriverInfoElement *)ItemList;
+ if (driverInfo->Info.DriverType ==
DriverInfoData->DriverType
+ && wcscmp(driverInfo->Info.Description,
DriverInfoData->Description) == 0
+ && wcscmp(driverInfo->Info.ProviderName,
DriverInfoData->ProviderName) == 0)
+ {
+ break;
+ }
+ }
+ }
+ if (ItemList == ListHead)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ *pDriverInfo = (struct DriverInfoElement *)ItemList;
+ DriverInfoData->Reserved = (ULONG_PTR)ItemList;
+ ret = TRUE;
+ }
+ }
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
_____
Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec 2005-08-09 16:08:00 UTC
(rev 17243)
+++ trunk/reactos/lib/setupapi/setupapi.spec 2005-08-09 16:13:50 UTC
(rev 17244)
@@ -290,7 +290,6 @@
@ stub SetupDiDeleteDevRegKey
@ stdcall SetupDiDeleteDeviceInfo(long ptr)
@ stub SetupDiDeleteDeviceInterfaceData
-@ stub SetupDiDeleteDeviceRegKey
@ stub SetupDiDestroyClassImageList
@ stdcall SetupDiDestroyDeviceInfoList(long)
@ stdcall SetupDiDestroyDriverInfoList(long ptr long)
@@ -345,7 +344,7 @@
@ stub SetupDiGetINFClassW
@ stub SetupDiGetSelectedDevice
@ stub SetupDiGetSelectedDriverA
-@ stub SetupDiGetSelectedDriverW
+@ stdcall SetupDiGetSelectedDriverW(ptr ptr ptr)
@ stub SetupDiGetWizardPage
@ stdcall SetupDiInstallClassA(long str long ptr)
@ stub SetupDiInstallClassExA
@@ -379,7 +378,7 @@
@ stub SetupDiSetDriverInstallParamsW
@ stub SetupDiSetSelectedDevice
@ stub SetupDiSetSelectedDriverA
-@ stub SetupDiSetSelectedDriverW
+@ stdcall SetupDiSetSelectedDriverW(ptr ptr ptr)
@ stub SetupDiUnremoveDevice
@ stub SetupDuplicateDiskSpaceListA
@ stub SetupDuplicateDiskSpaceListW