return hDevInfo;
}
+static DWORD
+GetErrorCodeFromCrCode(const IN CONFIGRET cr)
+{
+ switch (cr)
+ {
+ case CR_INVALID_MACHINENAME: return ERROR_INVALID_COMPUTERNAME;
+ case CR_OUT_OF_MEMORY: return ERROR_NOT_ENOUGH_MEMORY;
+ case CR_SUCCESS: return ERROR_SUCCESS;
+ default:
+ /* FIXME */
+ return ERROR_GEN_FAILURE;
+ }
+
+ /* Does not happen */
+}
+
/***********************************************************************
* SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
*/
TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
debugstr_w(MachineName), Reserved);
- size = sizeof(struct DeviceInfoSet);
+ size = FIELD_OFFSET(struct DeviceInfoSet, szData);
if (MachineName)
size += (wcslen(MachineName) + 3) * sizeof(WCHAR);
list = HeapAlloc(GetProcessHeap(), 0, size);
cr = CM_Connect_MachineW(UNCServerName, &list->hMachine);
if (cr != CR_SUCCESS)
{
- switch (cr)
- {
- case CR_OUT_OF_MEMORY: rc = ERROR_NOT_ENOUGH_MEMORY; break;
- case CR_INVALID_MACHINENAME: rc = ERROR_INVALID_COMPUTERNAME; break;
- default: rc = ERROR_GEN_FAILURE; break;
- }
- SetLastError(rc);
+ SetLastError(GetErrorCodeFromCrCode(cr));
goto cleanup;
}
#endif
memcpy(&DeviceInfoData->ClassGuid,
&DevInfo->ClassGuid,
sizeof(GUID));
- DeviceInfoData->DevInst = (DWORD)list->hMachine;
+ DeviceInfoData->DevInst = DevInfo->dnDevInst;
DeviceInfoData->Reserved = (ULONG_PTR)DevInfo;
ret = TRUE;
}
static BOOL
CreateDeviceInfoElement(
+ IN struct DeviceInfoSet *list,
IN LPCWSTR InstancePath,
IN LPCGUID pClassGuid,
OUT struct DeviceInfoElement **pDeviceInfo)
{
DWORD size;
+ CONFIGRET cr;
struct DeviceInfoElement *deviceInfo;
*pDeviceInfo = NULL;
- size = sizeof(struct DeviceInfoElement) + (wcslen(InstancePath) + 1) * sizeof(WCHAR);
+ size = FIELD_OFFSET(struct DeviceInfoElement, Data) + (wcslen(InstancePath) + 1) * sizeof(WCHAR);
deviceInfo = HeapAlloc(GetProcessHeap(), 0, size);
if (!deviceInfo)
{
return FALSE;
}
memset(deviceInfo, 0, size);
+
+ cr = CM_Locate_DevNode_ExW(&deviceInfo->dnDevInst, (DEVINSTID_W)InstancePath, CM_LOCATE_DEVNODE_PHANTOM, list->hMachine);
+ if (cr != CR_SUCCESS)
+ {
+ SetLastError(GetErrorCodeFromCrCode(cr));
+ return FALSE;
+ }
+
deviceInfo->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
wcscpy(deviceInfo->Data, InstancePath);
deviceInfo->DeviceName = deviceInfo->Data;
}
/* Add the entry to the list */
- if (!CreateDeviceInfoElement(InstancePath, &KeyGuid, &deviceInfo))
+ if (!CreateDeviceInfoElement(list, InstancePath, &KeyGuid, &deviceInfo))
{
RegCloseKey(hDeviceIdKey);
return GetLastError();
struct DeviceInterface *interfaceInfo;
TRACE("Adding %s to list\n", debugstr_w(ptr));
/* Step 1. Create a device info element */
- if (!CreateDeviceInfoElement(ptr, &GUID_SERENUM_BUS_ENUMERATOR, &deviceInfo))
+ if (!CreateDeviceInfoElement(list, ptr, &GUID_SERENUM_BUS_ENUMERATOR, &deviceInfo))
{
if (devices != buf)
HeapFree(GetProcessHeap(), 0, devices);
/* We have found a device */
/* Step 1. Create a device info element */
- if (!CreateDeviceInfoElement(InstancePath, &ClassGuid, &deviceInfo))
+ if (!CreateDeviceInfoElement(list, InstancePath, &ClassGuid, &deviceInfo))
{
RegCloseKey(hReferenceKey);
RegCloseKey(hDeviceInstanceKey);
}
}
+/***********************************************************************
+ * SetupDiGetClassImageIndex (SETUPAPI.@)
+ */
+
+static BOOL GetIconIndex(
+ IN HKEY hClassKey,
+ OUT PINT ImageIndex)
+{
+ LPWSTR Buffer = NULL;
+ DWORD dwRegType, dwLength;
+ LONG rc;
+ BOOL ret = FALSE;
+
+ /* Read "Icon" registry key */
+ rc = RegQueryValueExW(hClassKey, L"Icon", NULL, &dwRegType, NULL, &dwLength);
+ if (rc != ERROR_SUCCESS)
+ {
+ SetLastError(rc);
+ goto cleanup;
+ } else if (dwRegType != REG_SZ)
+ {
+ SetLastError(ERROR_INVALID_INDEX);
+ goto cleanup;
+ }
+ Buffer = MyMalloc(dwLength + sizeof(WCHAR));
+ if (!Buffer)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ Buffer[dwLength / sizeof(WCHAR)] = 0;
+ rc = RegQueryValueExW(hClassKey, L"Icon", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+ if (rc != ERROR_SUCCESS)
+ {
+ SetLastError(rc);
+ goto cleanup;
+ }
+
+ /* Transform "Icon" value to a INT */
+ *ImageIndex = atoiW(Buffer);
+ ret = TRUE;
+
+cleanup:
+ MyFree(Buffer);
+ return ret;
+}
+
+BOOL WINAPI SetupDiGetClassImageIndex(
+ IN PSP_CLASSIMAGELIST_DATA ClassImageListData,
+ IN CONST GUID *ClassGuid,
+ OUT PINT ImageIndex)
+{
+ struct ClassImageList *list;
+ BOOL ret = FALSE;
+
+ TRACE("%p %s %p\n", ClassImageListData, debugstr_guid(ClassGuid), ImageIndex);
+
+ if (!ClassImageListData || !ClassGuid || !ImageIndex)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (ClassImageListData->cbSize != sizeof(SP_CLASSIMAGELIST_DATA))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if ((list = (struct ClassImageList *)ClassImageListData->Reserved) == NULL)
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if (list->magic != SETUP_CLASS_IMAGE_LIST_MAGIC)
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if (!ImageIndex)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ HKEY hKey = INVALID_HANDLE_VALUE;
+ INT iconIndex;
+
+ /* Read Icon registry entry into Buffer */
+ hKey = SetupDiOpenClassRegKeyExW(ClassGuid, KEY_QUERY_VALUE, DIOCR_INTERFACE, list->MachineName, NULL);
+ if (hKey == INVALID_HANDLE_VALUE)
+ goto cleanup;
+ if (!GetIconIndex(hKey, &iconIndex))
+ goto cleanup;
+
+ if (iconIndex >= 0)
+ {
+ SetLastError(ERROR_INVALID_INDEX);
+ goto cleanup;
+ }
+
+ *ImageIndex = -iconIndex;
+ ret = TRUE;
+
+cleanup:
+ if (hKey != INVALID_HANDLE_VALUE)
+ RegCloseKey(hKey);
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
+/***********************************************************************
+ * SetupDiGetClassImageList(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetClassImageList(
+ OUT PSP_CLASSIMAGELIST_DATA ClassImageListData)
+{
+ return SetupDiGetClassImageListExW(ClassImageListData, NULL, NULL);
+}
+
+/***********************************************************************
+ * SetupDiGetClassImageListExA(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetClassImageListExA(
+ OUT PSP_CLASSIMAGELIST_DATA ClassImageListData,
+ IN PCSTR MachineName OPTIONAL,
+ IN PVOID Reserved)
+{
+ PWSTR MachineNameW = NULL;
+ BOOL ret;
+
+ if (MachineName)
+ {
+ MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
+ if (MachineNameW == NULL)
+ return FALSE;
+ }
+
+ ret = SetupDiGetClassImageListExW(ClassImageListData, MachineNameW, Reserved);
+
+ if (MachineNameW)
+ MyFree(MachineNameW);
+
+ return ret;
+}
+
+/***********************************************************************
+ * SetupDiGetClassImageListExW(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetClassImageListExW(
+ OUT PSP_CLASSIMAGELIST_DATA ClassImageListData,
+ IN PCWSTR MachineName OPTIONAL,
+ IN PVOID Reserved)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p %p %p\n", ClassImageListData, debugstr_w(MachineName), Reserved);
+
+ if (!ClassImageListData)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (ClassImageListData->cbSize != sizeof(SP_CLASSIMAGELIST_DATA))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if (Reserved)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ struct ClassImageList *list = NULL;
+ DWORD size;
+
+ size = FIELD_OFFSET(struct ClassImageList, szData);
+ if (MachineName)
+ size += (wcslen(MachineName) + 3) * sizeof(WCHAR);
+ list = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!list)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ list->magic = SETUP_CLASS_IMAGE_LIST_MAGIC;
+ if (MachineName)
+ {
+ list->szData[0] = list->szData[1] = '\\';
+ strcpyW(list->szData + 2, MachineName);
+ list->MachineName = list->szData;
+ }
+ else
+ {
+ list->MachineName = NULL;
+ }
+
+ ClassImageListData->Reserved = (DWORD)list; /* FIXME: 64 bit portability issue */
+ ret = TRUE;
+
+cleanup:
+ if (!ret)
+ MyFree(list);
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
+/***********************************************************************
+ * SetupDiLoadClassIcon(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiLoadClassIcon(
+ IN CONST GUID *ClassGuid,
+ OUT HICON *LargeIcon OPTIONAL,
+ OUT PINT MiniIconIndex OPTIONAL)
+{
+ BOOL ret = FALSE;
+
+ if (!ClassGuid)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ LPWSTR Buffer = NULL;
+ LPCWSTR DllName;
+ INT iconIndex;
+ HKEY hKey = INVALID_HANDLE_VALUE;
+
+ hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE);
+ if (hKey == INVALID_HANDLE_VALUE)
+ goto cleanup;
+
+ if (!GetIconIndex(hKey, &iconIndex))
+ goto cleanup;
+
+ if (iconIndex > 0)
+ {
+ /* Look up icon in dll specified by Installer32 or EnumPropPages32 key */
+ PWCHAR Comma;
+ LONG rc;
+ DWORD dwRegType, dwLength;
+ rc = RegQueryValueExW(hKey, L"Installer32", NULL, &dwRegType, NULL, &dwLength);
+ if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
+ {
+ Buffer = MyMalloc(dwLength);
+ if (Buffer == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ rc = RegQueryValueExW(hKey, L"Installer32", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+ if (rc != ERROR_SUCCESS)
+ {
+ SetLastError(rc);
+ goto cleanup;
+ }
+ }
+ else if
+ (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, &dwRegType, NULL, &dwLength))
+ && dwRegType == REG_SZ)
+ {
+ Buffer = MyMalloc(dwLength);
+ if (Buffer == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+ if (rc != ERROR_SUCCESS)
+ {
+ SetLastError(rc);
+ goto cleanup;
+ }
+ }
+ else
+ {
+ /* Unable to find where to load the icon */
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ goto cleanup;
+ }
+ Comma = strchrW(Buffer, ',');
+ if (!Comma)
+ {
+ SetLastError(ERROR_GEN_FAILURE);
+ goto cleanup;
+ }
+ *Comma = '\0';
+ }
+ else
+ {
+ /* Look up icon in setupapi.dll */
+ DllName = L"setupapi.dll";
+ iconIndex = -iconIndex;
+ }
+
+ TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(DllName));
+ if (LargeIcon)
+ {
+ if (1 != ExtractIconEx(DllName, iconIndex, LargeIcon, NULL, 1))
+ {
+ SetLastError(ERROR_INVALID_INDEX);
+ goto cleanup;
+ }
+ }
+ if (MiniIconIndex)
+ *MiniIconIndex = iconIndex;
+ ret = TRUE;
+
+cleanup:
+ if (hKey != INVALID_HANDLE_VALUE)
+ RegCloseKey(hKey);
+ MyFree(Buffer);
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
/***********************************************************************
* SetupDiEnumDeviceInterfaces (SETUPAPI.@)
*/
PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData)
{
- struct DeviceInfoSet *list;
BOOL ret = FALSE;
TRACE("%p %p %p %lu %p %p\n", DeviceInfoSet,
SetLastError(ERROR_INVALID_PARAMETER);
else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+ else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
SetLastError(ERROR_INVALID_HANDLE);
else if (DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
SetLastError(ERROR_INVALID_USER_BUFFER);
memcpy(&DeviceInfoData->ClassGuid,
&deviceInterface->DeviceInfo->ClassGuid,
sizeof(GUID));
- DeviceInfoData->DevInst = (DWORD)list->hMachine;
+ DeviceInfoData->DevInst = deviceInterface->DeviceInfo->dnDevInst;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
}
ret = TRUE;
* SetupDiOpenClassRegKeyExA (SETUPAPI.@)
*/
HKEY WINAPI SetupDiOpenClassRegKeyExA(
- const GUID* ClassGuid,
+ const GUID* ClassGuid OPTIONAL,
REGSAM samDesired,
DWORD Flags,
- PCSTR MachineName,
+ PCSTR MachineName OPTIONAL,
PVOID Reserved)
{
PWSTR MachineNameW = NULL;
* SetupDiOpenClassRegKeyExW (SETUPAPI.@)
*/
HKEY WINAPI SetupDiOpenClassRegKeyExW(
- const GUID* ClassGuid,
+ const GUID* ClassGuid OPTIONAL,
REGSAM samDesired,
DWORD Flags,
- PCWSTR MachineName,
+ PCWSTR MachineName OPTIONAL,
PVOID Reserved)
{
LPWSTR lpGuidString;
return FALSE;
}
+/***********************************************************************
+ * SetupDiSetClassInstallParamsW (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiSetClassInstallParamsW(
+ HDEVINFO DeviceInfoSet,
+ PSP_DEVINFO_DATA DeviceInfoData,
+ PSP_CLASSINSTALL_HEADER ClassInstallParams,
+ DWORD ClassInstallParamsSize)
+{
+ FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
+ ClassInstallParams->InstallFunction, ClassInstallParamsSize);
+ return FALSE;
+}
+
static DWORD
GetFunctionPointer(
IN PWSTR InstallerName,
rc = GetFunctionPointer(PropPageProvider, &hModule, (PVOID*)&pPropPageProvider);
if (rc != ERROR_SUCCESS)
{
- SetLastError(rc);
+ SetLastError(ERROR_INVALID_PROPPAGE_PROVIDER);
goto cleanup;
}
if (CreationFlags & DICD_GENERATE_ID)
{
/* Generate a new unique ID for this device */
- SetLastError(ERROR_GEN_FAILURE);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
FIXME("not implemented\n");
}
else
{
struct DeviceInfoElement *deviceInfo;
- if (CreateDeviceInfoElement(DeviceName, ClassGuid, &deviceInfo))
+ if (CreateDeviceInfoElement(list, DeviceName, ClassGuid, &deviceInfo))
{
InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
else
{
memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = (DWORD)list->hMachine;
+ DeviceInfoData->DevInst = deviceInfo->dnDevInst;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
ret = TRUE;
}
TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
FIXME("not implemented\n");
- SetLastError(ERROR_GEN_FAILURE);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/* FIXME: try to get ClassGUID from registry, instead of
* sending GUID_NULL to CreateDeviceInfoElement
*/
- if (!CreateDeviceInfoElement(DeviceInstanceId, &GUID_NULL, &deviceInfo))
+ if (!CreateDeviceInfoElement(list, DeviceInstanceId, &GUID_NULL, &deviceInfo))
{
RegCloseKey(hKey);
return FALSE;
if (ret && deviceInfo && DeviceInfoData)
{
memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = (DWORD)list->hMachine;
+ DeviceInfoData->DevInst = deviceInfo->dnDevInst;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
}
}