ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

interface.c
Go to the documentation of this file.
00001 /*
00002  * SetupAPI interface-related functions
00003  *
00004  * Copyright 2000 Andreas Mohr for CodeWeavers
00005  *           2005-2006 Hervé Poussineau (hpoussin@reactos.org)
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include "setupapi_private.h"
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
00025 
00026 /* Unicode constants */
00027 static const WCHAR AddInterface[]  = {'A','d','d','I','n','t','e','r','f','a','c','e',0};
00028 static const WCHAR ClassGUID[]  = {'C','l','a','s','s','G','U','I','D',0};
00029 static const WCHAR Control[]  = {'C','o','n','t','r','o','l',0};
00030 static const WCHAR DeviceInstance[]  = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
00031 static const WCHAR DotInterfaces[]  = {'.','I','n','t','e','r','f','a','c','e','s',0};
00032 static const WCHAR Linked[]  = {'L','i','n','k','e','d',0};
00033 static const WCHAR SymbolicLink[]  = {'S','y','m','b','o','l','i','c','L','i','n','k',0};
00034 
00035 static BOOL
00036 CreateDeviceInterface(
00037     IN struct DeviceInfo* deviceInfo,
00038     IN LPCWSTR SymbolicLink,
00039     IN LPCGUID pInterfaceGuid,
00040     OUT struct DeviceInterface **pDeviceInterface)
00041 {
00042     struct DeviceInterface *deviceInterface;
00043 
00044     *pDeviceInterface = NULL;
00045 
00046     deviceInterface = HeapAlloc(GetProcessHeap(), 0,
00047         FIELD_OFFSET(struct DeviceInterface, SymbolicLink) + (strlenW(SymbolicLink) + 1) * sizeof(WCHAR));
00048     if (!deviceInterface)
00049     {
00050         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00051         return FALSE;
00052     }
00053     deviceInterface->DeviceInfo = deviceInfo;
00054     strcpyW(deviceInterface->SymbolicLink, SymbolicLink);
00055     deviceInterface->Flags = 0; /* Flags will be updated later */
00056     memcpy(&deviceInterface->InterfaceClassGuid, pInterfaceGuid, sizeof(GUID));
00057 
00058     *pDeviceInterface = deviceInterface;
00059     return TRUE;
00060 }
00061 
00062 BOOL
00063 DestroyDeviceInterface(
00064     struct DeviceInterface* deviceInterface)
00065 {
00066     return HeapFree(GetProcessHeap(), 0, deviceInterface);
00067 }
00068 
00069 LONG
00070 SETUP_CreateInterfaceList(
00071     struct DeviceInfoSet *list,
00072     PCWSTR MachineName,
00073     CONST GUID *InterfaceGuid,
00074     PCWSTR DeviceInstanceW /* OPTIONAL */,
00075     BOOL OnlyPresentInterfaces)
00076 {
00077     HKEY hInterfaceKey;      /* HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
00078     HKEY hDeviceInstanceKey; /* HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID}\##?#{InstancePath} */
00079     HKEY hReferenceKey;      /* HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID}\##?#{InstancePath}\#{ReferenceString} */
00080     HKEY hControlKey;        /* HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID}\##?#{InstancePath}\#{ReferenceString}\Control */
00081     HKEY hEnumKey;           /* HKLM\SYSTEM\CurrentControlSet\Enum */
00082     HKEY hKey;               /* HKLM\SYSTEM\CurrentControlSet\Enum\{Instance\Path} */
00083     LONG rc;
00084     WCHAR KeyBuffer[max(MAX_PATH, MAX_GUID_STRING_LEN) + 1];
00085     PWSTR pSymbolicLink = NULL;
00086     PWSTR InstancePath = NULL;
00087     DWORD i, j;
00088     DWORD dwLength, dwInstancePathLength;
00089     DWORD dwRegType;
00090     DWORD LinkedValue;
00091     GUID ClassGuid;
00092     struct DeviceInfo *deviceInfo;
00093 
00094     hInterfaceKey = INVALID_HANDLE_VALUE;
00095     hDeviceInstanceKey = NULL;
00096     hReferenceKey = NULL;
00097 
00098     /* Open registry key related to this interface */
00099     hInterfaceKey = SetupDiOpenClassRegKeyExW(InterfaceGuid, KEY_ENUMERATE_SUB_KEYS, DIOCR_INTERFACE, MachineName, NULL);
00100     if (hInterfaceKey == INVALID_HANDLE_VALUE)
00101     {
00102         rc = GetLastError();
00103         goto cleanup;
00104     }
00105 
00106     /* Enumerate sub keys of hInterfaceKey */
00107     i = 0;
00108     while (TRUE)
00109     {
00110         dwLength = sizeof(KeyBuffer) / sizeof(KeyBuffer[0]);
00111         rc = RegEnumKeyExW(hInterfaceKey, i, KeyBuffer, &dwLength, NULL, NULL, NULL, NULL);
00112         if (rc == ERROR_NO_MORE_ITEMS)
00113             break;
00114         if (rc != ERROR_SUCCESS)
00115             goto cleanup;
00116         i++;
00117 
00118         /* Open sub key */
00119         if (hDeviceInstanceKey != NULL)
00120             RegCloseKey(hDeviceInstanceKey);
00121         rc = RegOpenKeyExW(hInterfaceKey, KeyBuffer, 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hDeviceInstanceKey);
00122         if (rc != ERROR_SUCCESS)
00123             goto cleanup;
00124 
00125         /* Read DeviceInstance */
00126         rc = RegQueryValueExW(hDeviceInstanceKey, DeviceInstance, NULL, &dwRegType, NULL, &dwInstancePathLength);
00127         if (rc != ERROR_SUCCESS)
00128             goto cleanup;
00129         if (dwRegType != REG_SZ)
00130         {
00131             rc = ERROR_GEN_FAILURE;
00132             goto cleanup;
00133         }
00134         HeapFree(GetProcessHeap(), 0, InstancePath);
00135         InstancePath = HeapAlloc(GetProcessHeap(), 0, dwInstancePathLength + sizeof(WCHAR));
00136         if (!InstancePath)
00137         {
00138             rc = ERROR_NOT_ENOUGH_MEMORY;
00139             goto cleanup;
00140         }
00141         rc = RegQueryValueExW(hDeviceInstanceKey, DeviceInstance, NULL, NULL, (LPBYTE)InstancePath, &dwInstancePathLength);
00142         if (rc != ERROR_SUCCESS)
00143             goto cleanup;
00144         InstancePath[dwInstancePathLength / sizeof(WCHAR)] = '\0';
00145         TRACE("DeviceInstance %s\n", debugstr_w(InstancePath));
00146 
00147         if (DeviceInstanceW)
00148         {
00149             /* Check if device enumerator is not the right one */
00150             if (strcmpW(DeviceInstanceW, InstancePath) != 0)
00151                 continue;
00152         }
00153 
00154         /* Find class GUID associated to the device instance */
00155         rc = RegOpenKeyExW(
00156             list->HKLM,
00157             REGSTR_PATH_SYSTEMENUM,
00158             0, /* Options */
00159             0,
00160             &hEnumKey);
00161         if (rc != ERROR_SUCCESS)
00162             goto cleanup;
00163         rc = RegOpenKeyExW(
00164             hEnumKey,
00165             InstancePath,
00166             0, /* Options */
00167             KEY_QUERY_VALUE,
00168             &hKey);
00169         RegCloseKey(hEnumKey);
00170         if (rc != ERROR_SUCCESS)
00171             goto cleanup;
00172         dwLength = sizeof(KeyBuffer) - sizeof(WCHAR);
00173         rc = RegQueryValueExW(hKey, ClassGUID, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
00174         RegCloseKey(hKey);
00175         if (rc != ERROR_SUCCESS)
00176             goto cleanup;
00177         KeyBuffer[dwLength / sizeof(WCHAR)] = '\0';
00178         KeyBuffer[37] = '\0'; /* Replace the } by a NULL character */
00179         if (UuidFromStringW(&KeyBuffer[1], &ClassGuid) != RPC_S_OK)
00180         {
00181             rc = ERROR_GEN_FAILURE;
00182             goto cleanup;
00183         }
00184         TRACE("ClassGUID %s\n", debugstr_guid(&ClassGuid));
00185 
00186         /* If current device doesn't match the list GUID (if any), skip this entry */
00187         if (!IsEqualIID(&list->ClassGuid, &GUID_NULL) && !IsEqualIID(&list->ClassGuid, &ClassGuid))
00188             continue;
00189 
00190         /* Enumerate subkeys of hDeviceInstanceKey (ie "#ReferenceString" in IoRegisterDeviceInterface). Skip entries that don't start with '#' */
00191         j = 0;
00192         while (TRUE)
00193         {
00194             struct DeviceInterface *interfaceInfo;
00195 
00196             dwLength = sizeof(KeyBuffer) / sizeof(KeyBuffer[0]);
00197             rc = RegEnumKeyExW(hDeviceInstanceKey, j, KeyBuffer, &dwLength, NULL, NULL, NULL, NULL);
00198             if (rc == ERROR_NO_MORE_ITEMS)
00199                 break;
00200             if (rc != ERROR_SUCCESS)
00201                 goto cleanup;
00202             j++;
00203             if (KeyBuffer[0] != '#')
00204                 /* This entry doesn't represent an interesting entry */
00205                 continue;
00206 
00207             /* Open sub key */
00208             if (hReferenceKey != NULL)
00209                 RegCloseKey(hReferenceKey);
00210             rc = RegOpenKeyExW(hDeviceInstanceKey, KeyBuffer, 0, KEY_QUERY_VALUE, &hReferenceKey);
00211             if (rc != ERROR_SUCCESS)
00212                 goto cleanup;
00213 
00214             /* Read SymbolicLink value */
00215             rc = RegQueryValueExW(hReferenceKey, SymbolicLink, NULL, &dwRegType, NULL, &dwLength);
00216             if (rc != ERROR_SUCCESS )
00217                 goto cleanup;
00218             if (dwRegType != REG_SZ)
00219             {
00220                 rc = ERROR_GEN_FAILURE;
00221                 goto cleanup;
00222             }
00223 
00224             /* We have found a device */
00225             /* Step 1. Create a device info element */
00226             if (!CreateDeviceInfo(list, InstancePath, &ClassGuid, &deviceInfo))
00227             {
00228                 rc = GetLastError();
00229                 goto cleanup;
00230             }
00231             TRACE("Adding device %s to list\n", debugstr_w(InstancePath));
00232             InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
00233 
00234             /* Step 2. Create an interface list for this element */
00235             HeapFree(GetProcessHeap(), 0, pSymbolicLink);
00236             pSymbolicLink = HeapAlloc(GetProcessHeap(), 0, (dwLength + 1) * sizeof(WCHAR));
00237             if (!pSymbolicLink)
00238             {
00239                 rc = ERROR_NOT_ENOUGH_MEMORY;
00240                 goto cleanup;
00241             }
00242             rc = RegQueryValueExW(hReferenceKey, SymbolicLink, NULL, NULL, (LPBYTE)pSymbolicLink, &dwLength);
00243             pSymbolicLink[dwLength / sizeof(WCHAR)] = '\0';
00244             if (rc != ERROR_SUCCESS)
00245                 goto cleanup;
00246             if (!CreateDeviceInterface(deviceInfo, pSymbolicLink, InterfaceGuid, &interfaceInfo))
00247             {
00248                 rc = GetLastError();
00249                 goto cleanup;
00250             }
00251 
00252             /* Step 3. Update flags */
00253             if (KeyBuffer[1] == '\0')
00254                 interfaceInfo->Flags |= SPINT_DEFAULT;
00255             rc = RegOpenKeyExW(hReferenceKey, Control, 0, KEY_QUERY_VALUE, &hControlKey);
00256             if (rc != ERROR_SUCCESS)
00257             {
00258 #if 0
00259                 if (OnlyPresentInterfaces)
00260                 {
00261                     DestroyDeviceInterface(interfaceInfo);
00262                     continue;
00263                 }
00264                 else
00265                     interfaceInfo->Flags |= SPINT_REMOVED;
00266 #endif
00267             }
00268             else
00269             {
00270                 dwLength = sizeof(DWORD);
00271                 if (RegQueryValueExW(hControlKey, Linked, NULL, &dwRegType, (LPBYTE)&LinkedValue, &dwLength) == ERROR_SUCCESS
00272                     && dwRegType == REG_DWORD && LinkedValue)
00273                     interfaceInfo->Flags |= SPINT_ACTIVE;
00274                 RegCloseKey(hControlKey);
00275             }
00276 
00277             TRACE("Adding interface %s to list\n", debugstr_w(pSymbolicLink));
00278             InsertTailList(&deviceInfo->InterfaceListHead, &interfaceInfo->ListEntry);
00279         }
00280     }
00281     rc = ERROR_SUCCESS;
00282 
00283 cleanup:
00284     if (hReferenceKey != NULL)
00285         RegCloseKey(hReferenceKey);
00286     if (hDeviceInstanceKey != NULL)
00287         RegCloseKey(hDeviceInstanceKey);
00288     if (hInterfaceKey != INVALID_HANDLE_VALUE)
00289         RegCloseKey(hInterfaceKey);
00290     HeapFree(GetProcessHeap(), 0, InstancePath);
00291     HeapFree(GetProcessHeap(), 0, pSymbolicLink);
00292     return rc;
00293 }
00294 
00295 static LPWSTR
00296 CreateSymbolicLink(
00297     IN LPGUID InterfaceGuid,
00298     IN LPCWSTR ReferenceString,
00299     IN struct DeviceInfo *devInfo)
00300 {
00301     DWORD Length, Index, Offset;
00302     LPWSTR Key;
00303 
00304     Length = wcslen(devInfo->instanceId) + 4 /* prepend ##?# */ + 41 /* #{GUID} + */ + 1 /* zero byte */;
00305 
00306     Key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR));
00307     if (!Key)
00308         return NULL;
00309 
00310     wcscpy(Key, L"##?#");
00311     wcscat(Key, devInfo->instanceId);
00312 
00313     for(Index = 4; Index < Length; Index++)
00314     {
00315         if (Key[Index] == L'\\')
00316         {
00317             Key[Index] = L'#';
00318         }
00319     }
00320 
00321     wcscat(Key, L"#");
00322 
00323     Offset = wcslen(Key);
00324     pSetupStringFromGuid(InterfaceGuid, Key + Offset, Length - Offset);
00325 
00326     return Key;
00327 }
00328 
00329 
00330 static BOOL
00331 InstallOneInterface(
00332     IN LPGUID InterfaceGuid,
00333     IN LPCWSTR ReferenceString,
00334     IN LPCWSTR InterfaceSection,
00335     IN UINT InterfaceFlags,
00336     IN HINF hInf,
00337     IN HDEVINFO DeviceInfoSet,
00338     IN struct DeviceInfo *devInfo)
00339 {
00340     HKEY hKey, hRefKey;
00341     LPWSTR Path;
00342     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
00343     struct DeviceInterface *DevItf = NULL;
00344 
00345     if (InterfaceFlags != 0)
00346     {
00347         SetLastError(ERROR_INVALID_PARAMETER);
00348         return FALSE;
00349     }
00350 
00351     TRACE("Need to InstallOneInterface(%s %s %s %u) hInf %p DeviceInfoSet %p devInfo %p instanceId %s\n", debugstr_guid(InterfaceGuid),
00352         debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags, hInf, DeviceInfoSet, devInfo, debugstr_w(devInfo->instanceId));
00353 
00354 
00355     Path = CreateSymbolicLink(InterfaceGuid, ReferenceString, devInfo);
00356     if (!Path)
00357         return FALSE;
00358 
00359     CreateDeviceInterface(devInfo, Path, InterfaceGuid, &DevItf);
00360     HeapFree(GetProcessHeap(), 0, Path);
00361     if (!DevItf)
00362     {
00363         return FALSE;
00364     }
00365 
00366     memcpy(&DeviceInterfaceData.InterfaceClassGuid, &DevItf->InterfaceClassGuid, sizeof(GUID));
00367     DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
00368     DeviceInterfaceData.Flags = DevItf->Flags;
00369     DeviceInterfaceData.Reserved = (ULONG_PTR)DevItf;
00370 
00371     hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, NULL, 0);
00372     HeapFree(GetProcessHeap(), 0, DevItf);
00373     if (hKey == INVALID_HANDLE_VALUE)
00374     {
00375         return FALSE;
00376     }
00377 
00378     if (ReferenceString)
00379     {
00380         Path = HeapAlloc(GetProcessHeap(), 0, (wcslen(ReferenceString) + 2) * sizeof(WCHAR));
00381         if (!Path)
00382         {
00383             RegCloseKey(hKey);
00384             return FALSE;
00385         }
00386 
00387         wcscpy(Path, L"#");
00388         wcscat(Path, ReferenceString);
00389 
00390         if (RegCreateKeyExW(hKey, Path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
00391         {
00392             ERR("failed to create key %s %lx\n", debugstr_w(Path), GetLastError());
00393             HeapFree(GetProcessHeap(), 0, Path);
00394             return FALSE;
00395         }
00396 
00397         RegCloseKey(hKey);
00398         hKey = hRefKey;
00399         HeapFree(GetProcessHeap(), 0, Path);
00400     }
00401 
00402     if (RegCreateKeyExW(hKey, L"Device Parameters", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
00403     {
00404         RegCloseKey(hKey);
00405         return FALSE;
00406     }
00407 
00408     return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hRefKey, NULL, 0, NULL, NULL, NULL, NULL);
00409 }
00410 
00411 /***********************************************************************
00412  *      SetupDiInstallDeviceInterfaces (SETUPAPI.@)
00413  */
00414 BOOL WINAPI
00415 SetupDiInstallDeviceInterfaces(
00416     IN HDEVINFO DeviceInfoSet,
00417     IN PSP_DEVINFO_DATA DeviceInfoData)
00418 {
00419     struct DeviceInfoSet *list = NULL;
00420     BOOL ret = FALSE;
00421 
00422     TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
00423 
00424     if (!DeviceInfoSet)
00425         SetLastError(ERROR_INVALID_PARAMETER);
00426     else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
00427         SetLastError(ERROR_INVALID_HANDLE);
00428     else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
00429         SetLastError(ERROR_INVALID_HANDLE);
00430     else if (!DeviceInfoData)
00431         SetLastError(ERROR_INVALID_PARAMETER);
00432     else if (DeviceInfoData && DeviceInfoData->Reserved == 0)
00433         SetLastError(ERROR_INVALID_USER_BUFFER);
00434     else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
00435         SetLastError(ERROR_INVALID_USER_BUFFER);
00436     else
00437     {
00438         struct DeviceInfo *devInfo;
00439         struct DriverInfoElement *SelectedDriver = NULL;
00440         SP_DEVINSTALL_PARAMS_W InstallParams;
00441         WCHAR SectionName[MAX_PATH];
00442         DWORD SectionNameLength = 0;
00443         INFCONTEXT ContextInterface;
00444         LPWSTR InterfaceGuidString = NULL;
00445         LPWSTR ReferenceString = NULL;
00446         LPWSTR InterfaceSection = NULL;
00447         INT InterfaceFlags;
00448         GUID InterfaceGuid;
00449         BOOL Result;
00450 
00451         devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
00452 
00453         InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
00454         Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
00455         if (!Result)
00456             goto cleanup;
00457 
00458         SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
00459         if (SelectedDriver == NULL)
00460         {
00461             SetLastError(ERROR_NO_DRIVER_SELECTED);
00462             ret = FALSE;
00463             goto cleanup;
00464         }
00465 
00466         /* Get .Interfaces section name */
00467         Result = SetupDiGetActualSectionToInstallW(
00468             SelectedDriver->InfFileDetails->hInf,
00469             SelectedDriver->Details.SectionName,
00470             SectionName, MAX_PATH, &SectionNameLength, NULL);
00471         if (!Result || SectionNameLength > MAX_PATH - strlenW(DotInterfaces) - 1)
00472             goto cleanup;
00473         strcatW(SectionName, DotInterfaces);
00474 
00475         ret = TRUE;
00476         Result = SetupFindFirstLineW(
00477             SelectedDriver->InfFileDetails->hInf,
00478             SectionName,
00479             AddInterface,
00480             &ContextInterface);
00481         while (ret && Result)
00482         {
00483             ret = GetStringField(&ContextInterface, 1, &InterfaceGuidString);
00484             if (!ret)
00485                 goto cleanup;
00486             else if (strlenW(InterfaceGuidString) != MAX_GUID_STRING_LEN - 1)
00487             {
00488                 SetLastError(ERROR_INVALID_PARAMETER);
00489                 ret = FALSE;
00490                 goto cleanup;
00491             }
00492 
00493             InterfaceGuidString[MAX_GUID_STRING_LEN - 2] = '\0'; /* Replace the } by a NULL character */
00494             if (UuidFromStringW(&InterfaceGuidString[1], &InterfaceGuid) != RPC_S_OK)
00495             {
00496                 /* Bad GUID, skip the entry */
00497                 SetLastError(ERROR_INVALID_PARAMETER);
00498                 ret = FALSE;
00499                 goto cleanup;
00500             }
00501 
00502             ret = GetStringField(&ContextInterface, 2, &ReferenceString);
00503             if (!ret)
00504                 goto cleanup;
00505 
00506             ret = GetStringField(&ContextInterface, 3, &InterfaceSection);
00507             if (!ret)
00508             {
00509                 /* ReferenceString is optional */
00510                 InterfaceSection = ReferenceString;
00511                 ReferenceString = NULL;
00512             }
00513 
00514             ret = SetupGetIntField(
00515                 &ContextInterface,
00516                 (ReferenceString ? 4 : 3), /* Field index */
00517                 &InterfaceFlags);
00518             if (!ret)
00519             {
00520                 if (GetLastError() == ERROR_INVALID_PARAMETER)
00521                 {
00522                     /* The field may be empty. Ignore the error */
00523                     InterfaceFlags = 0;
00524                     ret = TRUE;
00525                 }
00526                 else
00527                     goto cleanup;
00528             }
00529 
00530             /* Install Interface */
00531             ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags, SelectedDriver->InfFileDetails->hInf, DeviceInfoSet, devInfo);
00532 
00533 cleanup:
00534             MyFree(InterfaceGuidString);
00535             if (ReferenceString)
00536                 MyFree(ReferenceString);
00537             MyFree(InterfaceSection);
00538             InterfaceGuidString = ReferenceString = InterfaceSection = NULL;
00539             Result = SetupFindNextMatchLineW(&ContextInterface, AddInterface, &ContextInterface);
00540         }
00541     }
00542 
00543     TRACE("Returning %d\n", ret);
00544     return ret;
00545 }
00546 
00547 HKEY WINAPI
00548 SetupDiOpenDeviceInterfaceRegKey(
00549     IN HDEVINFO  DeviceInfoSet, IN PSP_DEVICE_INTERFACE_DATA  DeviceInterfaceData, IN DWORD  Reserved, IN REGSAM  samDesired)
00550 {
00551     HKEY hKey = INVALID_HANDLE_VALUE, hDevKey;
00552     struct DeviceInfoSet * list;
00553 
00554     TRACE("%p %p %p 0x%08x 0x%08x)\n", DeviceInfoSet, DeviceInterfaceData, Reserved, samDesired);
00555 
00556     if (!DeviceInfoSet)
00557         SetLastError(ERROR_INVALID_PARAMETER);
00558     else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
00559         SetLastError(ERROR_INVALID_HANDLE);
00560     else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
00561         SetLastError(ERROR_INVALID_HANDLE);
00562     else if (!DeviceInterfaceData)
00563         SetLastError(ERROR_INVALID_PARAMETER);
00564     else if (DeviceInterfaceData && DeviceInterfaceData->Reserved == 0)
00565         SetLastError(ERROR_INVALID_USER_BUFFER);
00566     else if (DeviceInterfaceData && DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
00567         SetLastError(ERROR_INVALID_USER_BUFFER);
00568     else
00569     {
00570         struct DeviceInterface *DevItf;
00571         LPWSTR Path, Guid, Slash;
00572         DWORD Length;
00573         DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
00574 
00575         Length = wcslen(DevItf->SymbolicLink);
00576 
00577         Path = HeapAlloc(GetProcessHeap(), 0, (Length+2) * sizeof(WCHAR));
00578         if (!Path)
00579         {
00580             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00581             return INVALID_HANDLE_VALUE;
00582         }
00583 
00584         wcscpy(Path, DevItf->SymbolicLink);
00585 
00586         Guid = wcsrchr(Path, '}');
00587         Slash = wcsrchr(Path, '\\');
00588         if (!Guid || !Slash)
00589         {
00590             SetLastError(ERROR_INVALID_PARAMETER);
00591             return INVALID_HANDLE_VALUE;
00592         }
00593 
00594         if ((ULONG_PTR)Slash > (ULONG_PTR)Guid)
00595         {
00596             /* Create an extra slash */
00597             memmove(Slash+1, Slash, (wcslen(Slash) + 1) * sizeof(WCHAR));
00598             Slash[1] = L'#';
00599         }
00600 
00601         Guid = Path;
00602         while((ULONG_PTR)Guid < (ULONG_PTR)Slash)
00603         {
00604             if (*Guid == L'\\')
00605                 *Guid = L'#';
00606 
00607             Guid++;
00608         }
00609 
00610         hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, samDesired, DIOCR_INTERFACE, NULL, NULL);
00611         if (hKey != INVALID_HANDLE_VALUE)
00612         {
00613             if (RegOpenKeyExW(hKey, Path, 0, samDesired, &hDevKey) == ERROR_SUCCESS)
00614             {
00615                 RegCloseKey(hKey);
00616                 hKey = hDevKey;
00617             }
00618             else
00619             {
00620                 RegCloseKey(hKey);
00621                 hKey = INVALID_HANDLE_VALUE;
00622             }
00623         }
00624 
00625         HeapFree(GetProcessHeap(), 0, Path);
00626     }
00627 
00628     return hKey;
00629 }

Generated on Sat May 26 2012 04:24:49 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.