[SETUPAPI]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 18 Dec 2009 04:37:15 +0000 (04:37 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 18 Dec 2009 04:37:15 +0000 (04:37 +0000)
- Implement SetupDiInstallDeviceInterfaces, SetupDiCreateDeviceInterfaceRegKeyW which are required to store device specific information

svn path=/trunk/; revision=44644

reactos/dll/win32/setupapi/devinst.c
reactos/dll/win32/setupapi/interface.c
reactos/dll/win32/setupapi/setupapi_private.h

index cb12d76..e589016 100644 (file)
@@ -2628,7 +2628,14 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
         HINF InfHandle,
         PCWSTR InfSectionName)
 {
+    HKEY hKey, hDevKey;
+    LPWSTR SymbolicLink;
+    DWORD Length, Index;
+    LONG rc;
+    WCHAR bracedGuidString[39];
+    struct DeviceInterface *DevItf;
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+
     TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
             samDesired, InfHandle, InfSectionName);
 
@@ -2650,11 +2657,79 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
         SetLastError(ERROR_INVALID_PARAMETER);
         return INVALID_HANDLE_VALUE;
     }
-    
-    FIXME("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
-            samDesired, InfHandle, InfSectionName);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return INVALID_HANDLE_VALUE;
+
+    hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, samDesired, DIOCR_INTERFACE, NULL, NULL);
+    if (hKey == INVALID_HANDLE_VALUE)
+    {
+        hKey = SetupDiOpenClassRegKeyExW(NULL, samDesired, DIOCR_INTERFACE, NULL, NULL);
+        if (hKey == INVALID_HANDLE_VALUE)
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return INVALID_HANDLE_VALUE;
+        }
+        SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid, bracedGuidString);
+
+        if (RegCreateKeyExW(hKey, bracedGuidString, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL) != ERROR_SUCCESS)
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return INVALID_HANDLE_VALUE;
+        }
+        RegCloseKey(hKey);
+        hKey = hDevKey;
+    }
+
+    DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
+
+    Length = (wcslen(DevItf->SymbolicLink)+1) * sizeof(WCHAR);
+    SymbolicLink = HeapAlloc(GetProcessHeap(), 0, Length);
+    if (!SymbolicLink)
+    {
+        RegCloseKey(hKey);
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    wcscpy(SymbolicLink, DevItf->SymbolicLink);
+
+    Index = 0;
+    while(SymbolicLink[Index])
+    {
+        if (SymbolicLink[Index] == L'\\')
+        {
+            SymbolicLink[Index] = L'#';
+        }
+        Index++;
+    }
+
+    rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL);
+
+    RegCloseKey(hKey);
+    HeapFree(GetProcessHeap(), 0, SymbolicLink);
+
+    if (rc == ERROR_SUCCESS)
+    {
+        if (InfHandle && InfSectionName)
+        {
+            if (!SetupInstallFromInfSection(NULL /*FIXME */,
+                                            InfHandle,
+                                            InfSectionName,
+                                            SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF,
+                                            hDevKey,
+                                            NULL,
+                                            0,
+                                            set->SelectedDevice->InstallParams.InstallMsgHandler,
+                                            set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
+                                            INVALID_HANDLE_VALUE,
+                                            NULL))
+            {
+                RegCloseKey(hDevKey);
+                return INVALID_HANDLE_VALUE;
+            }
+        }
+    }
+
+    SetLastError(rc);
+    return hDevKey;
 }
 
 /***********************************************************************
@@ -3611,6 +3686,7 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
             key = INVALID_HANDLE_VALUE;
         }
     }
+
     return key;
 }
 
index 172917b..fc9f890 100644 (file)
@@ -292,22 +292,118 @@ cleanup:
     return rc;
 }
 
+static LPWSTR
+CreateSymbolicLink(
+    IN LPGUID InterfaceGuid,
+    IN LPCWSTR ReferenceString,
+    IN struct DeviceInfo *devInfo)
+{
+    DWORD Length, Index, Offset;
+    LPWSTR Key;
+
+    Length = wcslen(devInfo->instanceId) + 4 /* prepend ##?# */ + 41 /* #{GUID} + */ + 1 /* zero byte */;
+
+    Key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR));
+    if (!Key)
+        return NULL;
+
+    wcscpy(Key, L"##?#");
+    wcscat(Key, devInfo->instanceId);
+
+    for(Index = 4; Index < Length; Index++)
+    {
+        if (Key[Index] == L'\\')
+        {
+            Key[Index] = L'#';
+        }
+    }
+
+    wcscat(Key, L"#");
+
+    Offset = wcslen(Key);
+    pSetupStringFromGuid(InterfaceGuid, Key + Offset, Length - Offset);
+
+    return Key;
+}
+
+
 static BOOL
 InstallOneInterface(
     IN LPGUID InterfaceGuid,
     IN LPCWSTR ReferenceString,
     IN LPCWSTR InterfaceSection,
-    IN UINT InterfaceFlags)
+    IN UINT InterfaceFlags,
+    IN HINF hInf,
+    IN HDEVINFO DeviceInfoSet,
+    IN struct DeviceInfo *devInfo)
 {
+    BOOL ret;
+    HKEY hKey, hRefKey;
+    LPWSTR Path;
+    SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
+    PLIST_ENTRY InterfaceListEntry;
+    struct DeviceInterface *DevItf = NULL;
+
     if (InterfaceFlags != 0)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    FIXME("Need to InstallOneInterface(%s %s %s %u)\n", debugstr_guid(InterfaceGuid),
-        debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags);
-    return TRUE;
+    TRACE("Need to InstallOneInterface(%s %s %s %u) hInf %p DeviceInfoSet %p devInfo %p instanceId %s\n", debugstr_guid(InterfaceGuid),
+        debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags, hInf, DeviceInfoSet, devInfo, debugstr_w(devInfo->instanceId));
+
+
+    Path = CreateSymbolicLink(InterfaceGuid, ReferenceString, devInfo);
+    if (!Path)
+        return FALSE;
+
+    CreateDeviceInterface(devInfo, Path, InterfaceGuid, &DevItf);
+    HeapFree(GetProcessHeap(), 0, Path);
+    if (!DevItf)
+    {
+        return FALSE;
+    }
+
+    InsertTailList(&devInfo->InterfaceListHead, &DevItf->ListEntry);
+
+    memcpy(&DeviceInterfaceData.InterfaceClassGuid, &DevItf->InterfaceClassGuid, sizeof(GUID));
+    DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+    DeviceInterfaceData.Flags = DevItf->Flags;
+    DeviceInterfaceData.Reserved = (ULONG_PTR)DevItf;
+
+    hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, NULL, 0);
+    HeapFree(GetProcessHeap(), 0, DevItf);
+    if (hKey == INVALID_HANDLE_VALUE)
+    {
+        return FALSE;
+    }
+
+    if (ReferenceString)
+    {
+        Path = HeapAlloc(GetProcessHeap(), 0, (wcslen(ReferenceString) + 2) * sizeof(WCHAR));
+        if (!Path)
+        {
+            RegCloseKey(hKey);
+            return FALSE;
+        }
+
+        wcscpy(Path, L"#");
+        wcscat(Path, ReferenceString);
+
+        if (RegCreateKeyExW(hKey, Path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
+        {
+            ERR("failed to create key %s %lx\n", debugstr_w(Path), GetLastError());
+            HeapFree(GetProcessHeap(), 0, Path);
+            return FALSE;
+        }
+
+        RegCloseKey(hKey);
+        hKey = hRefKey;
+        HeapFree(GetProcessHeap(), 0, Path);
+    }
+
+    return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hKey, NULL, 0, NULL, NULL, NULL, NULL);
 }
 
 /***********************************************************************
@@ -335,7 +431,8 @@ SetupDiInstallDeviceInterfaces(
         SetLastError(ERROR_INVALID_USER_BUFFER);
     else
     {
-        struct DriverInfoElement *SelectedDriver;
+        struct DeviceInfo *devInfo;
+        struct DriverInfoElement *SelectedDriver = NULL;
         SP_DEVINSTALL_PARAMS_W InstallParams;
         WCHAR SectionName[MAX_PATH];
         DWORD SectionNameLength = 0;
@@ -347,6 +444,8 @@ SetupDiInstallDeviceInterfaces(
         GUID InterfaceGuid;
         BOOL Result;
 
+        devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
         InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
         Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
         if (!Result)
@@ -402,11 +501,15 @@ SetupDiInstallDeviceInterfaces(
 
             ret = GetStringField(&ContextInterface, 3, &InterfaceSection);
             if (!ret)
-                goto cleanup;
+            {
+                /* ReferenceString is optional */
+                InterfaceSection = ReferenceString;
+                ReferenceString = NULL;
+            }
 
             ret = SetupGetIntField(
                 &ContextInterface,
-                4, /* Field index */
+                (ReferenceString ? 4 : 3), /* Field index */
                 &InterfaceFlags);
             if (!ret)
             {
@@ -421,11 +524,12 @@ SetupDiInstallDeviceInterfaces(
             }
 
             /* Install Interface */
-            ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags);
+            ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags, SelectedDriver->InfFileDetails->hInf, DeviceInfoSet, devInfo);
 
 cleanup:
             MyFree(InterfaceGuidString);
-            MyFree(ReferenceString);
+            if (ReferenceString)
+                MyFree(ReferenceString);
             MyFree(InterfaceSection);
             InterfaceGuidString = ReferenceString = InterfaceSection = NULL;
             Result = SetupFindNextMatchLineW(&ContextInterface, AddInterface, &ContextInterface);
index f527d7a..09630a6 100644 (file)
@@ -334,6 +334,10 @@ FreeFunctionPointer(
     IN HMODULE ModulePointer,
     IN PVOID FunctionPointer);
 
+DWORD
+WINAPI
+pSetupStringFromGuid(LPGUID lpGUID, PWSTR pString, DWORD dwStringLen);
+
 DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst);
 
 VOID WINAPI MyFree(LPVOID lpMem);