Author: janderwald
Date: Wed Mar 31 04:43:57 2010
New Revision: 46609
URL:
http://svn.reactos.org/svn/reactos?rev=46609&view=rev
Log:
[SETUPAPI]
- Implement SetupDiOpenDeviceInterfaceW
Modified:
trunk/reactos/dll/win32/setupapi/devinst.c
Modified: trunk/reactos/dll/win32/setupapi/devinst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/devinst…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/devinst.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/setupapi/devinst.c [iso-8859-1] Wed Mar 31 04:43:57 2010
@@ -3699,8 +3699,209 @@
DWORD OpenFlags,
PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
{
- FIXME("%p %s %08x %p\n",
+ struct DeviceInfoSet * list;
+ PCWSTR pEnd;
+ DWORD dwLength, dwError, dwIndex, dwKeyName, dwSubIndex;
+ CLSID ClassId;
+ WCHAR Buffer[MAX_PATH + 1];
+ WCHAR SymBuffer[MAX_PATH + 1];
+ WCHAR InstancePath[MAX_PATH + 1];
+ HKEY hKey, hDevKey, hSymKey;
+ struct DeviceInfo * deviceInfo;
+ struct DeviceInterface *deviceInterface;
+ BOOL Ret;
+ PLIST_ENTRY ItemList;
+ PLIST_ENTRY InterfaceListEntry;
+
+ TRACE("%p %s %08x %p\n",
DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
+
+
+ if (DeviceInterfaceData && DeviceInterfaceData->cbSize !=
sizeof(SP_DEVICE_INTERFACE_DATA))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (((struct DeviceInfoSet *)DeviceInfoSet)->magic !=
SETUP_DEVICE_INFO_SET_MAGIC)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ list = (struct DeviceInfoSet * )DeviceInfoSet;
+
+ dwLength = wcslen(DevicePath);
+ if (dwLength < 39)
+ {
+ /* path must be at least a guid length + L'\0' */
+ SetLastError(ERROR_BAD_PATHNAME);
+ return FALSE;
+ }
+
+ if (DevicePath[0] != L'\\' ||
+ DevicePath[1] != L'\\' ||
+ (DevicePath[2] != L'?' && DevicePath[2] != L'.') ||
+ DevicePath[3] != L'\\')
+ {
+ /* invalid formatted path */
+ SetLastError(ERROR_BAD_PATHNAME);
+ return FALSE;
+ }
+
+ /* check for reference strings */
+ pEnd = wcschr(&DevicePath[4], L'\\');
+ if (!pEnd)
+ {
+ /* no reference string */
+ pEnd = DevicePath + dwLength;
+ }
+
+ /* copy guid */
+ wcscpy(Buffer, pEnd - 37);
+ Buffer[36] = L'\0';
+
+ dwError = UuidFromStringW(Buffer, &ClassId);
+ if (dwError != NOERROR)
+ {
+ /* invalid formatted path */
+ SetLastError(ERROR_BAD_PATHNAME);
+ return FALSE;
+ }
+
+ hKey = SetupDiOpenClassRegKeyExW(&ClassId, KEY_READ, DIOCR_INTERFACE,
list->MachineName, NULL);
+
+ if (hKey == INVALID_HANDLE_VALUE)
+ {
+ /* invalid device class */
+ return FALSE;
+ }
+
+ ItemList = list->ListHead.Flink;
+ while (ItemList != &list->ListHead)
+ {
+ deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
+ InterfaceListEntry = deviceInfo->InterfaceListHead.Flink;
+ while (InterfaceListEntry != &deviceInfo->InterfaceListHead)
+ {
+ deviceInterface = CONTAINING_RECORD(InterfaceListEntry, struct
DeviceInterface, ListEntry);
+ if (!IsEqualIID(&deviceInterface->InterfaceClassGuid, &ClassId))
+ {
+ InterfaceListEntry = InterfaceListEntry->Flink;
+ continue;
+ }
+
+ if (!wcsicmp(deviceInterface->SymbolicLink, DevicePath))
+ {
+ if (DeviceInterfaceData)
+ {
+ DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
+ DeviceInterfaceData->Flags = deviceInterface->Flags;
+ CopyMemory(&DeviceInterfaceData->InterfaceClassGuid,
&ClassId, sizeof(GUID));
+ }
+
+ return TRUE;
+ }
+
+ }
+ }
+
+
+ dwIndex = 0;
+ do
+ {
+ Buffer[0] = 0;
+ dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
+ dwError = RegEnumKeyExW(hKey, dwIndex, Buffer, &dwKeyName, NULL, NULL, NULL,
NULL);
+
+ if (dwError != ERROR_SUCCESS)
+ break;
+
+ if (RegOpenKeyExW(hKey, Buffer, 0, KEY_READ, &hDevKey) != ERROR_SUCCESS)
+ break;
+
+ dwSubIndex = 0;
+ InstancePath[0] = 0;
+ dwKeyName = sizeof(InstancePath);
+
+ dwError = RegQueryValueExW(hDevKey, L"DeviceInstance", NULL, NULL,
(LPBYTE)InstancePath, &dwKeyName);
+
+ while(TRUE)
+ {
+ Buffer[0] = 0;
+ dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
+ dwError = RegEnumKeyExW(hDevKey, dwSubIndex, Buffer, &dwKeyName, NULL,
NULL, NULL, NULL);
+
+ if (dwError != ERROR_SUCCESS)
+ break;
+
+ dwError = RegOpenKeyExW(hDevKey, Buffer, 0, KEY_READ, &hSymKey);
+ if (dwError != ERROR_SUCCESS)
+ break;
+
+ /* query for symbolic link */
+ dwKeyName = sizeof(SymBuffer);
+ SymBuffer[0] = L'\0';
+ dwError = RegQueryValueExW(hSymKey, L"SymbolicLink", NULL, NULL,
(LPBYTE)SymBuffer, &dwKeyName);
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ RegCloseKey(hSymKey);
+ break;
+ }
+
+ if (!wcsicmp(SymBuffer, DevicePath))
+ {
+ Ret = CreateDeviceInfo(list, InstancePath, &ClassId,
&deviceInfo);
+ RegCloseKey(hSymKey);
+ RegCloseKey(hDevKey);
+ RegCloseKey(hKey);
+
+ if (Ret)
+ {
+ deviceInterface = HeapAlloc(GetProcessHeap(), 0, sizeof(struct
DeviceInterface) + (wcslen(SymBuffer) + 1) * sizeof(WCHAR));
+ if (deviceInterface)
+ {
+
+ CopyMemory(&deviceInterface->InterfaceClassGuid,
&ClassId, sizeof(GUID));
+ deviceInterface->DeviceInfo = deviceInfo;
+ deviceInterface->Flags = SPINT_ACTIVE; //FIXME
+
+ wcscpy(deviceInterface->SymbolicLink, SymBuffer);
+
+ InsertTailList(&deviceInfo->InterfaceListHead,
&deviceInterface->ListEntry);
+ InsertTailList(&list->ListHead,
&deviceInfo->ListEntry);
+
+
+ if (DeviceInterfaceData)
+ {
+ DeviceInterfaceData->Reserved =
(ULONG_PTR)deviceInterface;
+ DeviceInterfaceData->Flags = deviceInterface->Flags;
+ CopyMemory(&DeviceInterfaceData->InterfaceClassGuid,
&ClassId, sizeof(GUID));
+ }
+ else
+ {
+ Ret = FALSE;
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ }
+ }
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, deviceInfo);
+ Ret = FALSE;
+ }
+ return Ret;
+ }
+ RegCloseKey(hSymKey);
+ dwSubIndex++;
+ }
+
+ RegCloseKey(hDevKey);
+ dwIndex++;
+ }while(TRUE);
+
+ RegCloseKey(hKey);
return FALSE;
}