Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninterface.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
1.7.6.1
|