Honor DI_ENUMSINGLEINF flag in SetupDiBuildDriverInfoList
Implement SetupDiGetSelectedDevice/SetupDiSetSelectedDevice
Modified: trunk/reactos/lib/setupapi/devinst.c
Modified: trunk/reactos/lib/setupapi/setupapi.spec
Modified: trunk/reactos/lib/setupapi/setupapi_private.h

Modified: trunk/reactos/lib/setupapi/devinst.c
--- trunk/reactos/lib/setupapi/devinst.c	2005-12-19 17:58:17 UTC (rev 20273)
+++ trunk/reactos/lib/setupapi/devinst.c	2005-12-20 09:45:53 UTC (rev 20274)
@@ -5655,41 +5655,65 @@
                 goto done;
         }
 
-        /* Enumerate .inf files */
-        Result = FALSE;
-        RequiredSize = 32768; /* Initial buffer size */
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+        if (InstallParams.Flags & DI_ENUMSINGLEINF)
         {
-            HeapFree(GetProcessHeap(), 0, Buffer);
+            /* InstallParams.DriverPath contains the name of a .inf file */
+            RequiredSize = wcslen(InstallParams.DriverPath) + 2;
             Buffer = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
             if (!Buffer)
             {
-                Result = FALSE;
                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                break;
+                goto done;
             }
-            Result = SetupGetInfFileListW(
-                *InstallParams.DriverPath ? InstallParams.DriverPath : NULL,
-                INF_STYLE_WIN4,
-                Buffer, RequiredSize,
-                &RequiredSize);
+            wcscpy(Buffer, InstallParams.DriverPath);
+            ((LPWSTR)Buffer)[RequiredSize - 1] = 0;
+            Result = TRUE;
         }
-        if (!Result && GetLastError() == ERROR_FILE_NOT_FOUND)
+        else
         {
-            /* No .inf file in specified directory. So, we should
-             * success as we created an empty driver info list.
-             */
-            ret = TRUE;
-            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(
+                    *InstallParams.DriverPath ? InstallParams.DriverPath : NULL,
+                    INF_STYLE_WIN4,
+                    Buffer, RequiredSize,
+                    &RequiredSize);
+            }
+            if (!Result && GetLastError() == ERROR_FILE_NOT_FOUND)
+            {
+                /* No .inf file in specified directory. So, we should
+                 * success as we created an empty driver info list.
+                 */
+                ret = TRUE;
+                goto done;
+            }
         }
         if (Result)
         {
             LPCWSTR filename;
             LPWSTR pFullFilename;
 
-            if (*InstallParams.DriverPath)
+            if (InstallParams.Flags & DI_ENUMSINGLEINF)
             {
+                FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
+                if (!FullInfFileName)
+                    goto done;
+                pFullFilename = &FullInfFileName[0];
+            }
+            else if (*InstallParams.DriverPath)
+            {
                 DWORD len;
                 len = GetFullPathNameW(InstallParams.DriverPath, 0, NULL, NULL);
                 if (len == 0)
@@ -6324,6 +6348,44 @@
 
 
 /***********************************************************************
+ *		SetupDiGetSelectedDevice (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiGetSelectedDevice(
+    IN HDEVINFO DeviceInfoSet,
+    OUT PSP_DEVINFO_DATA DeviceInfoData)
+{
+    struct DeviceInfoSet *list;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p\n", DeviceInfoSet, 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 (list->SelectedDevice == NULL)
+        SetLastError(ERROR_NO_DEVICE_SELECTED);
+    else if (!DeviceInfoData)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else
+    {
+        memcpy(&DeviceInfoData->ClassGuid,
+            &list->SelectedDevice->ClassGuid,
+            sizeof(GUID));
+        DeviceInfoData->DevInst = list->SelectedDevice->dnDevInst;
+        DeviceInfoData->Reserved = (ULONG_PTR)list->SelectedDevice;
+        ret = TRUE;
+    }
+
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
+
+/***********************************************************************
  *		SetupDiGetSelectedDriverA (SETUPAPI.@)
  */
 BOOL WINAPI
@@ -6434,6 +6496,40 @@
 
 
 /***********************************************************************
+ *		SetupDiSetSelectedDevice (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiSetSelectedDevice(
+    IN HDEVINFO DeviceInfoSet,
+    IN PSP_DEVINFO_DATA DeviceInfoData)
+{
+    struct DeviceInfoSet *list;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p\n", DeviceInfoSet, 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 (!DeviceInfoData)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else if (DeviceInfoData->Reserved == 0)
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else
+    {
+        list->SelectedDevice = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
+        ret = TRUE;
+    }
+
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
+
+/***********************************************************************
  *		SetupDiSetSelectedDriverA (SETUPAPI.@)
  */
 BOOL WINAPI

Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec	2005-12-19 17:58:17 UTC (rev 20273)
+++ trunk/reactos/lib/setupapi/setupapi.spec	2005-12-20 09:45:53 UTC (rev 20274)
@@ -345,7 +345,7 @@
 @ stub SetupDiGetHwProfileListExW
 @ stdcall SetupDiGetINFClassA(str ptr ptr long ptr)
 @ stdcall SetupDiGetINFClassW(wstr ptr ptr long ptr)
-@ stub SetupDiGetSelectedDevice
+@ stdcall SetupDiGetSelectedDevice(ptr ptr)
 @ stdcall SetupDiGetSelectedDriverA(ptr ptr ptr)
 @ stdcall SetupDiGetSelectedDriverW(ptr ptr ptr)
 @ stub SetupDiGetWizardPage
@@ -382,7 +382,7 @@
 @ stdcall SetupDiSetDeviceRegistryPropertyW(ptr ptr long ptr long)
 @ stub SetupDiSetDriverInstallParamsA
 @ stub SetupDiSetDriverInstallParamsW
-@ stub SetupDiSetSelectedDevice
+@ stdcall SetupDiSetSelectedDevice(ptr ptr)
 @ stdcall SetupDiSetSelectedDriverA(ptr ptr ptr)
 @ stdcall SetupDiSetSelectedDriverW(ptr ptr ptr)
 @ stub SetupDiUnremoveDevice

Modified: trunk/reactos/lib/setupapi/setupapi_private.h
--- trunk/reactos/lib/setupapi/setupapi_private.h	2005-12-19 17:58:17 UTC (rev 20273)
+++ trunk/reactos/lib/setupapi/setupapi_private.h	2005-12-20 09:45:53 UTC (rev 20274)
@@ -156,6 +156,7 @@
     LIST_ENTRY DriverListHead; /* List of struct DriverInfoElement */
 
     LIST_ENTRY ListHead; /* List of struct DeviceInfoElement */
+    struct DeviceInfoElement *SelectedDevice;
 
     /* Used by SetupDiGetClassInstallParamsW/SetupDiSetClassInstallParamsW */
     struct ClassInstallParams ClassInstallParams;