+++ /dev/null
-/*
- * SetupAPI device installer
- *
- * Copyright 2000 Andreas Mohr for CodeWeavers
- * 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "setupapi_private.h"
-
-/* Unicode constants */
-static const WCHAR BackSlash[] = {'\\',0};
-static const WCHAR DateFormat[] = {'%','u','-','%','u','-','%','u',0};
-static const WCHAR DotCoInstallers[] = {'.','C','o','I','n','s','t','a','l','l','e','r','s',0};
-static const WCHAR DotHW[] = {'.','H','W',0};
-static const WCHAR DotServices[] = {'.','S','e','r','v','i','c','e','s',0};
-static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
-static const WCHAR InstanceKeyFormat[] = {'%','0','4','l','u',0};
-static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
-static const WCHAR VersionFormat[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
-
-static const WCHAR REGSTR_DRIVER_DATE[] = {'D','r','i','v','e','r','D','a','t','e',0};
-static const WCHAR REGSTR_DRIVER_DATE_DATA[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
-static const WCHAR REGSTR_DRIVER_VERSION[] = {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
-static const WCHAR REGSTR_SECURITY[] = {'S','e','c','u','r','i','t','y',0};
-static const WCHAR REGSTR_UI_NUMBER_DESC_FORMAT[] = {'U','I','N','u','m','b','e','r','D','e','s','c','F','o','r','m','a','t',0};
-
-typedef DWORD
-(CALLBACK* CLASS_INSTALL_PROC) (
- IN DI_FUNCTION InstallFunction,
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL);
-typedef BOOL
-(WINAPI* DEFAULT_CLASS_INSTALL_PROC) (
- IN HDEVINFO DeviceInfoSet,
- IN OUT PSP_DEVINFO_DATA DeviceInfoData);
-typedef DWORD
-(CALLBACK* COINSTALLER_PROC) (
- IN DI_FUNCTION InstallFunction,
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
- IN OUT PCOINSTALLER_CONTEXT_DATA Context);
-
-struct CoInstallerElement
-{
- LIST_ENTRY ListEntry;
-
- HMODULE Module;
- COINSTALLER_PROC Function;
- BOOL DoPostProcessing;
- PVOID PrivateData;
-};
-
-struct GetSectionCallbackInfo
-{
- PSP_ALTPLATFORM_INFO PlatformInfo;
- BYTE ProductType;
- WORD SuiteMask;
- DWORD PrefixLength;
- WCHAR BestSection[LINE_LEN + 1];
- DWORD BestScore1, BestScore2, BestScore3, BestScore4, BestScore5;
-};
-
-
-
-static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
-{
- static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
- '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
- 'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
- '0','2','X','}',0};
-
- sprintfW(guidStr, fmt, guid->Data1, guid->Data2, guid->Data3,
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
-}
-
-static DWORD
-GetErrorCodeFromCrCode(const IN CONFIGRET cr)
-{
- switch (cr)
- {
- case CR_ACCESS_DENIED: return ERROR_ACCESS_DENIED;
- case CR_BUFFER_SMALL: return ERROR_INSUFFICIENT_BUFFER;
- case CR_CALL_NOT_IMPLEMENTED: return ERROR_CALL_NOT_IMPLEMENTED;
- case CR_FAILURE: return ERROR_GEN_FAILURE;
- case CR_INVALID_DATA: return ERROR_INVALID_USER_BUFFER;
- case CR_INVALID_DEVICE_ID: return ERROR_INVALID_PARAMETER;
- case CR_INVALID_MACHINENAME: return ERROR_INVALID_COMPUTERNAME;
- case CR_INVALID_DEVNODE: return ERROR_INVALID_PARAMETER;
- case CR_INVALID_FLAG: return ERROR_INVALID_FLAGS;
- case CR_INVALID_POINTER: return ERROR_INVALID_PARAMETER;
- case CR_INVALID_PROPERTY: return ERROR_INVALID_PARAMETER;
- case CR_NO_SUCH_DEVNODE: return ERROR_FILE_NOT_FOUND;
- case CR_NO_SUCH_REGISTRY_KEY: return ERROR_FILE_NOT_FOUND;
- case CR_NO_SUCH_VALUE: return ERROR_FILE_NOT_FOUND;
- case CR_OUT_OF_MEMORY: return ERROR_NOT_ENOUGH_MEMORY;
- case CR_REGISTRY_ERROR: return ERROR_GEN_FAILURE;
- case CR_ALREADY_SUCH_DEVINST: return ERROR_DEVINST_ALREADY_EXISTS;
- case CR_SUCCESS: return ERROR_SUCCESS;
- default: return ERROR_GEN_FAILURE;
- }
-
- /* Does not happen */
-}
-
-/* Lower scores are best ones */
-static BOOL
-CheckSectionValid(
- IN LPCWSTR SectionName,
- IN PSP_ALTPLATFORM_INFO PlatformInfo,
- IN BYTE ProductType,
- IN WORD SuiteMask,
- OUT PDWORD ScorePlatform,
- OUT PDWORD ScoreMajorVersion,
- OUT PDWORD ScoreMinorVersion,
- OUT PDWORD ScoreProductType,
- OUT PDWORD ScoreSuiteMask)
-{
- LPWSTR Section = NULL;
- //LPCWSTR pExtensionPlatform;
- LPCWSTR pExtensionArchitecture;
- LPWSTR Fields[6];
- DWORD i;
- BOOL ret = FALSE;
-
- //static const WCHAR ExtensionPlatformNone[] = {'.',0};
- static const WCHAR ExtensionPlatformNT[] = {'.','N','T',0};
- static const WCHAR ExtensionPlatformWindows[] = {'.','W','i','n',0};
-
- static const WCHAR ExtensionArchitectureNone[] = {0};
- static const WCHAR ExtensionArchitecturealpha[] = {'a','l','p','h','a',0};
- static const WCHAR ExtensionArchitectureamd64[] = {'A','M','D','6','4',0};
- static const WCHAR ExtensionArchitectureia64[] = {'I','A','6','4',0};
- static const WCHAR ExtensionArchitecturemips[] = {'m','i','p','s',0};
- static const WCHAR ExtensionArchitectureppc[] = {'p','p','c',0};
- static const WCHAR ExtensionArchitecturex86[] = {'x','8','6',0};
-
- TRACE("%s %p 0x%x 0x%x\n",
- debugstr_w(SectionName), PlatformInfo, ProductType, SuiteMask);
-
- *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = 0;
-
- Section = pSetupDuplicateString(SectionName);
- if (!Section)
- {
- TRACE("pSetupDuplicateString() failed\n");
- goto cleanup;
- }
-
- /* Set various extensions values */
- switch (PlatformInfo->Platform)
- {
- case VER_PLATFORM_WIN32_WINDOWS:
- //pExtensionPlatform = ExtensionPlatformWindows;
- break;
- case VER_PLATFORM_WIN32_NT:
- //pExtensionPlatform = ExtensionPlatformNT;
- break;
- default:
- ERR("Unknown platform 0x%lx\n", PlatformInfo->Platform);
- //pExtensionPlatform = ExtensionPlatformNone;
- break;
- }
- switch (PlatformInfo->ProcessorArchitecture)
- {
- case PROCESSOR_ARCHITECTURE_ALPHA:
- pExtensionArchitecture = ExtensionArchitecturealpha;
- break;
- case PROCESSOR_ARCHITECTURE_AMD64:
- pExtensionArchitecture = ExtensionArchitectureamd64;
- break;
- case PROCESSOR_ARCHITECTURE_IA64:
- pExtensionArchitecture = ExtensionArchitectureia64;
- break;
- case PROCESSOR_ARCHITECTURE_INTEL:
- pExtensionArchitecture = ExtensionArchitecturex86;
- break;
- case PROCESSOR_ARCHITECTURE_MIPS:
- pExtensionArchitecture = ExtensionArchitecturemips;
- break;
- case PROCESSOR_ARCHITECTURE_PPC:
- pExtensionArchitecture = ExtensionArchitectureppc;
- break;
- default:
- ERR("Unknown processor architecture 0x%x\n", PlatformInfo->ProcessorArchitecture);
- case PROCESSOR_ARCHITECTURE_UNKNOWN:
- pExtensionArchitecture = ExtensionArchitectureNone;
- break;
- }
-
- /*
- * Field[0] Platform
- * Field[1] Architecture
- * Field[2] Major version
- * Field[3] Minor version
- * Field[4] Product type
- * Field[5] Suite mask
- * Remark: these fields may be NULL if the information is not provided
- */
- Fields[0] = Section;
- if (Fields[0] == NULL)
- {
- TRACE("No extension found\n");
- *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = ULONG_MAX;
- ret = TRUE;
- goto cleanup;
- }
- Fields[1] = Fields[0] + 1;
- Fields[2] = Fields[3] = Fields[4] = Fields[5] = NULL;
- for (i = 2; Fields[i - 1] != NULL && i < 6; i++)
- {
- Fields[i] = wcschr(Fields[i - 1], '.');
- if (Fields[i])
- {
- Fields[i]++;
- *(Fields[i] - 1) = UNICODE_NULL;
- }
- }
- /* Take care of first 2 fields */
- if (strncmpiW(Fields[0], ExtensionPlatformWindows, strlenW(ExtensionPlatformWindows)) == 0)
- {
- if (PlatformInfo->Platform != VER_PLATFORM_WIN32_WINDOWS)
- {
- TRACE("Mismatch on platform field\n");
- goto cleanup;
- }
- Fields[1] += wcslen(ExtensionPlatformWindows) - 1;
- }
- else if (strncmpiW(Fields[0], ExtensionPlatformNT, strlenW(ExtensionPlatformNT)) == 0)
- {
- if (PlatformInfo->Platform != VER_PLATFORM_WIN32_NT)
- {
- TRACE("Mismatch on platform field\n");
- goto cleanup;
- }
- Fields[1] += wcslen(ExtensionPlatformNT) - 1;
- }
- else
- {
- /* No platform specified */
- *ScorePlatform |= 0x02;
- }
- if (strcmpiW(Fields[1], ExtensionArchitectureNone) == 0)
- {
- /* No architecture specified */
- *ScorePlatform |= 0x01;
- }
- else if (strcmpiW(Fields[1], pExtensionArchitecture) != 0)
- {
- TRACE("Mismatch on architecture field ('%s' and '%s')\n",
- debugstr_w(Fields[1]), debugstr_w(pExtensionArchitecture));
- goto cleanup;
- }
-
- /* Check if informations are matching */
- if (Fields[2] && *Fields[2])
- {
- DWORD MajorVersion, MinorVersion = 0;
- MajorVersion = strtoulW(Fields[2], NULL, 0);
- if ((MajorVersion == 0 || MajorVersion == ULONG_MAX) &&
- (errno == ERANGE || errno == EINVAL))
- {
- TRACE("Wrong MajorVersion ('%s')\n", debugstr_w(Fields[2]));
- goto cleanup;
- }
- if (Fields[3] && *Fields[3])
- {
- MinorVersion = strtoulW(Fields[3], NULL, 0);
- if ((MinorVersion == 0 || MinorVersion == ULONG_MAX) &&
- (errno == ERANGE || errno == EINVAL))
- {
- TRACE("Wrong MinorVersion ('%s')\n", debugstr_w(Fields[3]));
- goto cleanup;
- }
- }
- if (PlatformInfo->MajorVersion < MajorVersion ||
- (PlatformInfo->MajorVersion == MajorVersion && PlatformInfo->MinorVersion < MinorVersion))
- {
- TRACE("Mismatch on version field (%lu.%lu and %lu.%lu)\n",
- MajorVersion, MinorVersion, PlatformInfo->MajorVersion, PlatformInfo->MinorVersion);
- goto cleanup;
- }
- *ScoreMajorVersion = MajorVersion - PlatformInfo->MajorVersion;
- if (MajorVersion == PlatformInfo->MajorVersion)
- *ScoreMinorVersion = MinorVersion - PlatformInfo->MinorVersion;
- else
- *ScoreMinorVersion = MinorVersion;
- }
- else if (Fields[3] && *Fields[3])
- {
- TRACE("Minor version found without major version\n");
- goto cleanup;
- }
- else
- {
- *ScoreMajorVersion = PlatformInfo->MajorVersion;
- *ScoreMinorVersion = PlatformInfo->MinorVersion;
- }
-
- if (Fields[4] && *Fields[4])
- {
- DWORD CurrentProductType;
- CurrentProductType = strtoulW(Fields[4], NULL, 0);
- if ((CurrentProductType == 0 || CurrentProductType == ULONG_MAX) &&
- (errno == ERANGE || errno == EINVAL))
- {
- TRACE("Wrong Product type ('%s')\n", debugstr_w(Fields[4]));
- goto cleanup;
- }
- if (CurrentProductType != ProductType)
- {
- TRACE("Mismatch on product type (0x%08lx and 0x%08x)\n",
- CurrentProductType, ProductType);
- goto cleanup;
- }
- }
- else
- *ScoreProductType = 1;
-
- if (Fields[5] && *Fields[5])
- {
- DWORD CurrentSuiteMask;
- CurrentSuiteMask = strtoulW(Fields[5], NULL, 0);
- if ((CurrentSuiteMask == 0 || CurrentSuiteMask == ULONG_MAX) &&
- (errno == ERANGE || errno == EINVAL))
- {
- TRACE("Wrong Suite mask ('%s')\n", debugstr_w(Fields[5]));
- goto cleanup;
- }
- if ((CurrentSuiteMask & ~SuiteMask) != 0)
- {
- TRACE("Mismatch on suite mask (0x%08lx and 0x%08x)\n",
- CurrentSuiteMask, SuiteMask);
- goto cleanup;
- }
- *ScoreSuiteMask = SuiteMask & ~CurrentSuiteMask;
- }
- else
- *ScoreSuiteMask = SuiteMask;
-
- ret = TRUE;
-
-cleanup:
- MyFree(Section);
- return ret;
-}
-
-static BOOL
-GetSectionCallback(
- IN LPCWSTR SectionName,
- IN PVOID Context)
-{
- struct GetSectionCallbackInfo *info = Context;
- DWORD Score1, Score2, Score3, Score4, Score5;
- BOOL ret;
-
- if (SectionName[info->PrefixLength] != '.')
- return TRUE;
-
- ret = CheckSectionValid(
- &SectionName[info->PrefixLength],
- info->PlatformInfo,
- info->ProductType,
- info->SuiteMask,
- &Score1, &Score2, &Score3, &Score4, &Score5);
- if (!ret)
- {
- TRACE("Section %s not compatible\n", debugstr_w(SectionName));
- return TRUE;
- }
- if (Score1 > info->BestScore1) goto done;
- if (Score1 < info->BestScore1) goto bettersection;
- if (Score2 > info->BestScore2) goto done;
- if (Score2 < info->BestScore2) goto bettersection;
- if (Score3 > info->BestScore3) goto done;
- if (Score3 < info->BestScore3) goto bettersection;
- if (Score4 > info->BestScore4) goto done;
- if (Score4 < info->BestScore4) goto bettersection;
- if (Score5 > info->BestScore5) goto done;
- if (Score5 < info->BestScore5) goto bettersection;
- goto done;
-
-bettersection:
- strcpyW(info->BestSection, SectionName);
- info->BestScore1 = Score1;
- info->BestScore2 = Score2;
- info->BestScore3 = Score3;
- info->BestScore4 = Score4;
- info->BestScore5 = Score5;
-
-done:
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiGetActualSectionToInstallExW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetActualSectionToInstallExW(
- IN HINF InfHandle,
- IN PCWSTR InfSectionName,
- IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
- OUT PWSTR InfSectionWithExt OPTIONAL,
- IN DWORD InfSectionWithExtSize,
- OUT PDWORD RequiredSize OPTIONAL,
- OUT PWSTR* Extension OPTIONAL,
- IN PVOID Reserved)
-{
- BOOL ret = FALSE;
-
- TRACE("%p %s %p %p %lu %p %p %p\n", InfHandle, debugstr_w(InfSectionName),
- AlternatePlatformInfo, InfSectionWithExt, InfSectionWithExtSize,
- RequiredSize, Extension, Reserved);
-
- if (!InfHandle || InfHandle == (HINF)INVALID_HANDLE_VALUE)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (!InfSectionName)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (AlternatePlatformInfo && AlternatePlatformInfo->cbSize != sizeof(SP_ALTPLATFORM_INFO))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (Reserved != NULL)
- SetLastError(ERROR_INVALID_PARAMETER);
- else
- {
- static SP_ALTPLATFORM_INFO CurrentPlatform = { 0, };
- static BYTE CurrentProductType = 0;
- static WORD CurrentSuiteMask = 0;
- PSP_ALTPLATFORM_INFO pPlatformInfo = &CurrentPlatform;
- struct GetSectionCallbackInfo CallbackInfo;
- DWORD dwFullLength;
- BYTE ProductType;
- WORD SuiteMask;
-
- /* Fill platform info if needed */
- if (AlternatePlatformInfo)
- {
- pPlatformInfo = AlternatePlatformInfo;
- ProductType = 0;
- SuiteMask = 0;
- }
- else
- {
- if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
- {
- /* That's the first time we go here. We need to fill in the structure */
- SYSTEM_INFO SystemInfo;
- GetSystemInfo(&SystemInfo);
- CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
- CurrentPlatform.Platform = OsVersionInfo.dwPlatformId;
- CurrentPlatform.MajorVersion = OsVersionInfo.dwMajorVersion;
- CurrentPlatform.MinorVersion = OsVersionInfo.dwMinorVersion;
- CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
- CurrentPlatform.Reserved = 0;
- CurrentProductType = OsVersionInfo.wProductType;
- CurrentSuiteMask = OsVersionInfo.wSuiteMask;
- }
- ProductType = CurrentProductType;
- SuiteMask = CurrentSuiteMask;
- }
-
- CallbackInfo.PlatformInfo = pPlatformInfo;
- CallbackInfo.ProductType = ProductType;
- CallbackInfo.SuiteMask = SuiteMask;
- CallbackInfo.PrefixLength = strlenW(InfSectionName);
- CallbackInfo.BestScore1 = ULONG_MAX;
- CallbackInfo.BestScore2 = ULONG_MAX;
- CallbackInfo.BestScore3 = ULONG_MAX;
- CallbackInfo.BestScore4 = ULONG_MAX;
- CallbackInfo.BestScore5 = ULONG_MAX;
- strcpyW(CallbackInfo.BestSection, InfSectionName);
- TRACE("EnumerateSectionsStartingWith(InfSectionName = %S)\n", InfSectionName);
- if (!EnumerateSectionsStartingWith(
- InfHandle,
- InfSectionName,
- GetSectionCallback,
- &CallbackInfo))
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto done;
- }
- TRACE("CallbackInfo.BestSection = %S\n", CallbackInfo.BestSection);
-
- dwFullLength = lstrlenW(CallbackInfo.BestSection);
- if (RequiredSize != NULL)
- *RequiredSize = dwFullLength + 1;
-
- if (InfSectionWithExtSize > 0)
- {
- if (InfSectionWithExtSize < dwFullLength + 1)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- goto done;
- }
- strcpyW(InfSectionWithExt, CallbackInfo.BestSection);
- if (Extension)
- {
- DWORD dwLength = lstrlenW(InfSectionName);
- *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
- }
- }
-
- ret = TRUE;
- }
-
-done:
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-
-BOOL
-CreateDeviceInfo(
- IN struct DeviceInfoSet *list,
- IN LPCWSTR InstancePath,
- IN LPCGUID pClassGuid,
- OUT struct DeviceInfo **pDeviceInfo)
-{
- DWORD size;
- CONFIGRET cr;
- struct DeviceInfo *deviceInfo;
-
- *pDeviceInfo = NULL;
-
- size = FIELD_OFFSET(struct DeviceInfo, Data) + (strlenW(InstancePath) + 1) * sizeof(WCHAR);
- deviceInfo = HeapAlloc(GetProcessHeap(), 0, size);
- if (!deviceInfo)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ZeroMemory(deviceInfo, 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->set = list;
- deviceInfo->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- strcpyW(deviceInfo->Data, InstancePath);
- deviceInfo->instanceId = deviceInfo->Data;
- deviceInfo->UniqueId = strrchrW(deviceInfo->Data, '\\');
- deviceInfo->DeviceDescription = NULL;
- memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID));
- deviceInfo->CreationFlags = 0;
- InitializeListHead(&deviceInfo->DriverListHead);
- InitializeListHead(&deviceInfo->InterfaceListHead);
-
- *pDeviceInfo = deviceInfo;
- return TRUE;
-}
-
-
-static BOOL
-DestroyClassInstallParams(struct ClassInstallParams* installParams)
-{
- HeapFree(GetProcessHeap(), 0, installParams->PropChangeParams);
- HeapFree(GetProcessHeap(), 0, installParams->AddPropertyPageData);
- return TRUE;
-}
-
-static BOOL
-DestroyDeviceInfo(struct DeviceInfo *deviceInfo)
-{
- PLIST_ENTRY ListEntry;
- struct DriverInfoElement *driverInfo;
- struct DeviceInterface *deviceInterface;
-
- while (!IsListEmpty(&deviceInfo->DriverListHead))
- {
- ListEntry = RemoveHeadList(&deviceInfo->DriverListHead);
- driverInfo = CONTAINING_RECORD(ListEntry, struct DriverInfoElement, ListEntry);
- if (!DestroyDriverInfoElement(driverInfo))
- return FALSE;
- }
- while (!IsListEmpty(&deviceInfo->InterfaceListHead))
- {
- ListEntry = RemoveHeadList(&deviceInfo->InterfaceListHead);
- deviceInterface = CONTAINING_RECORD(ListEntry, struct DeviceInterface, ListEntry);
- if (!DestroyDeviceInterface(deviceInterface))
- return FALSE;
- }
- DestroyClassInstallParams(&deviceInfo->ClassInstallParams);
- if (deviceInfo->hmodDevicePropPageProvider)
- FreeLibrary(deviceInfo->hmodDevicePropPageProvider);
- return HeapFree(GetProcessHeap(), 0, deviceInfo);
-}
-
-static BOOL
-DestroyDeviceInfoSet(struct DeviceInfoSet* list)
-{
- PLIST_ENTRY ListEntry;
- struct DeviceInfo *deviceInfo;
-
- while (!IsListEmpty(&list->ListHead))
- {
- ListEntry = RemoveHeadList(&list->ListHead);
- deviceInfo = CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry);
- if (!DestroyDeviceInfo(deviceInfo))
- return FALSE;
- }
- if (list->HKLM != HKEY_LOCAL_MACHINE)
- RegCloseKey(list->HKLM);
- CM_Disconnect_Machine(list->hMachine);
- DestroyClassInstallParams(&list->ClassInstallParams);
- if (list->hmodClassPropPageProvider)
- FreeLibrary(list->hmodClassPropPageProvider);
- return HeapFree(GetProcessHeap(), 0, list);
-}
-
-/***********************************************************************
- * SetupDiBuildClassInfoList (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local machine.
- *
- * PARAMS
- * Flags [I] control exclusion of classes from the list.
- * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- *
- * RETURNS
- * Success: TRUE.
- * Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoList(
- DWORD Flags,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize)
-{
- TRACE("\n");
- return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
- ClassGuidListSize, RequiredSize,
- NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiBuildClassInfoListExA (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote machine.
- *
- * PARAMS
- * Flags [I] control exclusion of classes from the list.
- * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- * MachineName [I] name of a remote machine.
- * Reserved [I] must be NULL.
- *
- * RETURNS
- * Success: TRUE.
- * Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoListExA(
- DWORD Flags,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize,
- LPCSTR MachineName,
- PVOID Reserved)
-{
- LPWSTR MachineNameW = NULL;
- BOOL bResult;
-
- TRACE("0x%lx %p %lu %p %s %p\n", Flags, ClassGuidList,
- ClassGuidListSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
- if (MachineName)
- {
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- if (MachineNameW == NULL) return FALSE;
- }
-
- bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
- ClassGuidListSize, RequiredSize,
- MachineNameW, Reserved);
-
- MyFree(MachineNameW);
-
- return bResult;
-}
-
-/***********************************************************************
- * SetupDiBuildClassInfoListExW (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote machine.
- *
- * PARAMS
- * Flags [I] control exclusion of classes from the list.
- * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- * MachineName [I] name of a remote machine.
- * Reserved [I] must be NULL.
- *
- * RETURNS
- * Success: TRUE.
- * Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoListExW(
- DWORD Flags,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize,
- LPCWSTR MachineName,
- PVOID Reserved)
-{
- WCHAR szKeyName[40];
- HKEY hClassesKey = INVALID_HANDLE_VALUE;
- HKEY hClassKey;
- DWORD dwLength;
- DWORD dwIndex;
- LONG lError;
- DWORD dwGuidListIndex = 0;
-
- TRACE("0x%lx %p %lu %p %s %p\n", Flags, ClassGuidList,
- ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
- if (!RequiredSize)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- else if (!ClassGuidList && ClassGuidListSize > 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
- KEY_ENUMERATE_SUB_KEYS,
- DIOCR_INSTALLER,
- MachineName,
- Reserved);
- if (hClassesKey == INVALID_HANDLE_VALUE)
- {
- return FALSE;
- }
-
- for (dwIndex = 0; ; dwIndex++)
- {
- dwLength = 40;
- lError = RegEnumKeyExW(hClassesKey,
- dwIndex,
- szKeyName,
- &dwLength,
- NULL,
- NULL,
- NULL,
- NULL);
- TRACE("RegEnumKeyExW() returns %d\n", lError);
- if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
- {
- TRACE("Key name: %s\n", debugstr_w(szKeyName));
-
- if (RegOpenKeyExW(hClassesKey,
- szKeyName,
- 0,
- KEY_QUERY_VALUE,
- &hClassKey))
- {
- RegCloseKey(hClassesKey);
- return FALSE;
- }
-
- if (!RegQueryValueExW(hClassKey,
- REGSTR_VAL_NOUSECLASS,
- NULL,
- NULL,
- NULL,
- NULL))
- {
- TRACE("'NoUseClass' value found!\n");
- RegCloseKey(hClassKey);
- continue;
- }
-
- if ((Flags & DIBCI_NOINSTALLCLASS) &&
- (!RegQueryValueExW(hClassKey,
- REGSTR_VAL_NOINSTALLCLASS,
- NULL,
- NULL,
- NULL,
- NULL)))
- {
- TRACE("'NoInstallClass' value found!\n");
- RegCloseKey(hClassKey);
- continue;
- }
-
- if ((Flags & DIBCI_NODISPLAYCLASS) &&
- (!RegQueryValueExW(hClassKey,
- REGSTR_VAL_NODISPLAYCLASS,
- NULL,
- NULL,
- NULL,
- NULL)))
- {
- TRACE("'NoDisplayClass' value found!\n");
- RegCloseKey(hClassKey);
- continue;
- }
-
- RegCloseKey(hClassKey);
-
- TRACE("Guid: %s\n", debugstr_w(szKeyName));
- if (dwGuidListIndex < ClassGuidListSize)
- {
- if (szKeyName[0] == '{' && szKeyName[37] == '}')
- {
- szKeyName[37] = 0;
- }
- TRACE("Guid: %p\n", &szKeyName[1]);
-
- UuidFromStringW(&szKeyName[1],
- &ClassGuidList[dwGuidListIndex]);
- }
-
- dwGuidListIndex++;
- }
-
- if (lError != ERROR_SUCCESS)
- break;
- }
-
- RegCloseKey(hClassesKey);
-
- if (RequiredSize != NULL)
- *RequiredSize = dwGuidListIndex;
-
- if (ClassGuidListSize < dwGuidListIndex)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiClassGuidsFromNameA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameA(
- LPCSTR ClassName,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize)
-{
- return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
- ClassGuidListSize, RequiredSize,
- NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiClassGuidsFromNameW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameW(
- LPCWSTR ClassName,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize)
-{
- return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
- ClassGuidListSize, RequiredSize,
- NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExA(
- LPCSTR ClassName,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize,
- LPCSTR MachineName,
- PVOID Reserved)
-{
- LPWSTR ClassNameW = NULL;
- LPWSTR MachineNameW = NULL;
- BOOL bResult;
-
- TRACE("%s %p %lu %p %s %p\n", debugstr_a(ClassName), ClassGuidList,
- ClassGuidListSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
- if (!ClassName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- ClassNameW = pSetupMultiByteToUnicode(ClassName, CP_ACP);
- if (ClassNameW == NULL)
- return FALSE;
-
- if (MachineName)
- {
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- if (MachineNameW == NULL)
- {
- MyFree(ClassNameW);
- return FALSE;
- }
- }
-
- bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
- ClassGuidListSize, RequiredSize,
- MachineNameW, Reserved);
-
- MyFree(MachineNameW);
- MyFree(ClassNameW);
-
- return bResult;
-}
-
-/***********************************************************************
- * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExW(
- LPCWSTR ClassName,
- LPGUID ClassGuidList,
- DWORD ClassGuidListSize,
- PDWORD RequiredSize,
- LPCWSTR MachineName,
- PVOID Reserved)
-{
- WCHAR szKeyName[40];
- WCHAR szClassName[MAX_CLASS_NAME_LEN];
- HKEY hClassesKey;
- HKEY hClassKey;
- DWORD dwLength;
- DWORD dwIndex;
- LONG lError;
- DWORD dwGuidListIndex = 0;
-
- TRACE("%s %p %lu %p %s %p\n", debugstr_w(ClassName), ClassGuidList,
- ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
- if (!ClassName || !RequiredSize)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (!ClassGuidList && ClassGuidListSize > 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- *RequiredSize = 0;
-
- hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
- KEY_ENUMERATE_SUB_KEYS,
- DIOCR_INSTALLER,
- MachineName,
- Reserved);
- if (hClassesKey == INVALID_HANDLE_VALUE)
- {
- return FALSE;
- }
-
- for (dwIndex = 0; ; dwIndex++)
- {
- dwLength = 40;
- lError = RegEnumKeyExW(hClassesKey,
- dwIndex,
- szKeyName,
- &dwLength,
- NULL,
- NULL,
- NULL,
- NULL);
- TRACE("RegEnumKeyExW() returns %d\n", lError);
- if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
- {
- TRACE("Key name: %p\n", szKeyName);
-
- if (RegOpenKeyExW(hClassesKey,
- szKeyName,
- 0,
- KEY_QUERY_VALUE,
- &hClassKey))
- {
- RegCloseKey(hClassesKey);
- return FALSE;
- }
-
- dwLength = MAX_CLASS_NAME_LEN * sizeof(WCHAR);
- if (!RegQueryValueExW(hClassKey,
- REGSTR_VAL_CLASS,
- NULL,
- NULL,
- (LPBYTE)szClassName,
- &dwLength))
- {
- TRACE("Class name: %p\n", szClassName);
-
- if (strcmpiW(szClassName, ClassName) == 0)
- {
- TRACE("Found matching class name\n");
-
- TRACE("Guid: %p\n", szKeyName);
- if (dwGuidListIndex < ClassGuidListSize)
- {
- if (szKeyName[0] == '{' && szKeyName[37] == '}')
- {
- szKeyName[37] = 0;
- }
- TRACE("Guid: %p\n", &szKeyName[1]);
-
- UuidFromStringW(&szKeyName[1],
- &ClassGuidList[dwGuidListIndex]);
- }
-
- dwGuidListIndex++;
- }
- }
-
- RegCloseKey(hClassKey);
- }
-
- if (lError != ERROR_SUCCESS)
- break;
- }
-
- RegCloseKey(hClassesKey);
-
- if (RequiredSize != NULL)
- *RequiredSize = dwGuidListIndex;
-
- if (ClassGuidListSize < dwGuidListIndex)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiClassNameFromGuidA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidA(
- const GUID* ClassGuid,
- PSTR ClassName,
- DWORD ClassNameSize,
- PDWORD RequiredSize)
-{
- return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
- ClassNameSize, RequiredSize,
- NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiClassNameFromGuidW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidW(
- const GUID* ClassGuid,
- PWSTR ClassName,
- DWORD ClassNameSize,
- PDWORD RequiredSize)
-{
- return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
- ClassNameSize, RequiredSize,
- NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiClassNameFromGuidExA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExA(
- const GUID* ClassGuid,
- PSTR ClassName,
- DWORD ClassNameSize,
- PDWORD RequiredSize,
- PCSTR MachineName,
- PVOID Reserved)
-{
- WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
- LPWSTR MachineNameW = NULL;
- BOOL ret;
-
- if (MachineName)
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
- RequiredSize, MachineNameW, Reserved);
- if (ret)
- {
- int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
- ClassNameSize, NULL, NULL);
- if (len == 0 || len > ClassNameSize)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- ret = FALSE;
- }
- }
- MyFree(MachineNameW);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiClassNameFromGuidExW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExW(
- const GUID* ClassGuid,
- PWSTR ClassName,
- DWORD ClassNameSize,
- PDWORD RequiredSize,
- PCWSTR MachineName,
- PVOID Reserved)
-{
- HKEY hKey;
- DWORD dwLength;
- DWORD dwRegType;
- LONG rc;
- PWSTR Buffer;
-
- TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassName,
- ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
- /* Make sure there's a GUID */
- if (ClassGuid == NULL)
- {
- SetLastError(ERROR_INVALID_CLASS); /* On Vista: ERROR_INVALID_USER_BUFFER */
- return FALSE;
- }
-
- /* Make sure there's a real buffer when there's a size */
- if ((ClassNameSize > 0) && (ClassName == NULL))
- {
- SetLastError(ERROR_INVALID_PARAMETER); /* On Vista: ERROR_INVALID_USER_BUFFER */
- return FALSE;
- }
-
- /* Open the key for the GUID */
- hKey = SetupDiOpenClassRegKeyExW(ClassGuid, KEY_QUERY_VALUE, DIOCR_INSTALLER, MachineName, Reserved);
-
- if (hKey == INVALID_HANDLE_VALUE)
- return FALSE;
-
- /* Retrieve the class name data and close the key */
- rc = QueryRegistryValue(hKey, REGSTR_VAL_CLASS, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
- RegCloseKey(hKey);
-
- /* Make sure we got the data */
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- return FALSE;
- }
-
- /* Make sure the data is a string */
- if (dwRegType != REG_SZ)
- {
- MyFree(Buffer);
- SetLastError(ERROR_GEN_FAILURE);
- return FALSE;
- }
-
- /* Determine the length of the class name */
- dwLength /= sizeof(WCHAR);
-
- if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
- /* Count the null-terminator */
- dwLength++;
-
- /* Inform the caller about the class name */
- if ((ClassName != NULL) && (dwLength <= ClassNameSize))
- {
- memcpy(ClassName, Buffer, (dwLength - 1) * sizeof(WCHAR));
- ClassName[dwLength - 1] = UNICODE_NULL;
- }
-
- /* Inform the caller about the required size */
- if (RequiredSize != NULL)
- *RequiredSize = dwLength;
-
- /* Clean up the buffer */
- MyFree(Buffer);
-
- /* Make sure the buffer was large enough */
- if ((ClassName == NULL) || (dwLength > ClassNameSize))
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInfoList (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
- HWND hwndParent)
-{
- return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
- HWND hwndParent,
- PCSTR MachineName,
- PVOID Reserved)
-{
- LPWSTR MachineNameW = NULL;
- HDEVINFO hDevInfo;
-
- TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
- debugstr_a(MachineName), Reserved);
-
- if (MachineName)
- {
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- if (MachineNameW == NULL)
- return INVALID_HANDLE_VALUE;
- }
-
- hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
- MachineNameW, Reserved);
-
- MyFree(MachineNameW);
-
- return hDevInfo;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
- *
- * Create an empty DeviceInfoSet list.
- *
- * PARAMS
- * ClassGuid [I] if not NULL only devices with GUID ClassGuid are associated
- * with this list.
- * hwndParent [I] hwnd needed for interface related actions.
- * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
- * local registry will be used.
- * Reserved [I] must be NULL
- *
- * RETURNS
- * Success: empty list.
- * Failure: INVALID_HANDLE_VALUE.
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
- HWND hwndParent,
- PCWSTR MachineName,
- PVOID Reserved)
-{
- struct DeviceInfoSet *list = NULL;
- DWORD size = FIELD_OFFSET(struct DeviceInfoSet, szData);
- DWORD rc;
- CONFIGRET cr;
- HDEVINFO ret = INVALID_HANDLE_VALUE;
-
- TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
- debugstr_w(MachineName), Reserved);
-
- if (MachineName != NULL)
- {
- SIZE_T len = strlenW(MachineName);
- if (len >= SP_MAX_MACHINENAME_LENGTH - 4)
- {
- SetLastError(ERROR_INVALID_MACHINENAME);
- goto cleanup;
- }
- if(len > 0)
- size += (len + 3) * sizeof(WCHAR);
- else
- MachineName = NULL;
- }
-
- if (Reserved != NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
-
- list = MyMalloc(size);
- if (!list)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- ZeroMemory(list, FIELD_OFFSET(struct DeviceInfoSet, szData));
-
- list->magic = SETUP_DEVICE_INFO_SET_MAGIC;
- memcpy(&list->ClassGuid,
- ClassGuid ? ClassGuid : &GUID_NULL,
- sizeof(list->ClassGuid));
- list->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- list->InstallParams.Flags |= DI_CLASSINSTALLPARAMS;
- list->InstallParams.hwndParent = hwndParent;
- if (MachineName)
- {
- rc = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &list->HKLM);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(ERROR_INVALID_MACHINENAME);
- goto cleanup;
- }
-
- list->szData[0] = list->szData[1] = '\\';
- strcpyW(list->szData + 2, MachineName);
- list->MachineName = list->szData;
- }
- else
- {
- list->HKLM = HKEY_LOCAL_MACHINE;
- list->MachineName = NULL;
- }
- cr = CM_Connect_MachineW(list->MachineName, &list->hMachine);
- if (cr != CR_SUCCESS)
- {
- SetLastError(GetErrorCodeFromCrCode(cr));
- goto cleanup;
- }
- InitializeListHead(&list->DriverListHead);
- InitializeListHead(&list->ListHead);
-
- return (HDEVINFO)list;
-
-cleanup:
- if (ret == INVALID_HANDLE_VALUE)
- {
- if (list)
- {
- if (list->HKLM != NULL && list->HKLM != HKEY_LOCAL_MACHINE)
- RegCloseKey(list->HKLM);
- MyFree(list);
- }
- }
- return ret;
-}
-
-/***********************************************************************
- * SetupDiCreateDevRegKeyA (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDevRegKeyA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Scope,
- DWORD HwProfile,
- DWORD KeyType,
- HINF InfHandle,
- PCSTR InfSectionName)
-{
- PWSTR InfSectionNameW = NULL;
- HKEY key;
-
- TRACE("%p %p %d %d %d %p %s\n", DeviceInfoSet, DeviceInfoData, Scope,
- HwProfile, KeyType, InfHandle, debugstr_a(InfSectionName));
-
- if (InfHandle)
- {
- if (!InfSectionName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- else
- {
- InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
- if (InfSectionNameW == NULL) return INVALID_HANDLE_VALUE;
- }
- }
- key = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, Scope,
- HwProfile, KeyType, InfHandle, InfSectionNameW);
- MyFree(InfSectionNameW);
- return key;
-}
-
-static HKEY
-OpenHardwareProfileKey(
- IN HKEY HKLM,
- IN DWORD HwProfile,
- IN DWORD samDesired);
-
-/***********************************************************************
- * SetupDiCreateDevRegKeyW (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDevRegKeyW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Scope,
- DWORD HwProfile,
- DWORD KeyType,
- HINF InfHandle,
- PCWSTR InfSectionName)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- HKEY key = INVALID_HANDLE_VALUE;
- LPWSTR lpGuidString = NULL;
- LPWSTR DriverKey = NULL; /* {GUID}\Index */
- LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
- DWORD Index; /* Index used in the DriverKey name */
- DWORD dwSize;
- DWORD Disposition;
- DWORD rc;
- HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
- HKEY hEnumKey = NULL;
- HKEY hClassKey = NULL;
- HKEY hDeviceKey = INVALID_HANDLE_VALUE;
- HKEY hKey = NULL;
- HKEY RootKey;
-
- TRACE("%p %p %lu %lu %lu %p %s\n", DeviceInfoSet, DeviceInfoData, Scope,
- HwProfile, KeyType, InfHandle, debugstr_w(InfSectionName));
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return INVALID_HANDLE_VALUE;
- }
- if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return INVALID_HANDLE_VALUE;
- }
- if (InfHandle && !InfSectionName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- if (!InfHandle && InfSectionName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
-
- if (Scope == DICS_FLAG_GLOBAL)
- RootKey = set->HKLM;
- else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
- {
- hHWProfileKey = OpenHardwareProfileKey(set->HKLM, HwProfile, KEY_CREATE_SUB_KEY);
- if (hHWProfileKey == INVALID_HANDLE_VALUE)
- goto cleanup;
- RootKey = hHWProfileKey;
- }
-
- if (KeyType == DIREG_DEV)
- {
- struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-
- rc = RegCreateKeyExW(
- RootKey,
- REGSTR_PATH_SYSTEMENUM,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_CREATE_SUB_KEY,
- NULL,
- &hEnumKey,
- NULL);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- rc = RegCreateKeyExW(
- hEnumKey,
- deviceInfo->instanceId,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
-#if _WIN32_WINNT >= 0x502
- KEY_READ | KEY_WRITE,
-#else
- KEY_ALL_ACCESS,
-#endif
- NULL,
- &hKey,
- NULL);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- }
- else /* KeyType == DIREG_DRV */
- {
- /* Open device key, to read Driver value */
- hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
- if (hDeviceKey == INVALID_HANDLE_VALUE)
- goto cleanup;
-
- rc = RegOpenKeyExW(RootKey, REGSTR_PATH_CLASS_NT, 0, KEY_CREATE_SUB_KEY, &hClassKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, NULL, &dwSize);
- if (rc != ERROR_SUCCESS)
- {
- /* Create a new driver key */
-
- if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
- goto cleanup;
-
- /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
- DriverKey = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
- if (!DriverKey)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
-
- DriverKey[0] = '{';
- strcpyW(&DriverKey[1], lpGuidString);
- pDeviceInstance = &DriverKey[strlenW(DriverKey)];
- *pDeviceInstance++ = '}';
- *pDeviceInstance++ = '\\';
-
- /* Try all values for Index between 0 and 9999 */
- Index = 0;
- while (Index <= 9999)
- {
- sprintfW(pDeviceInstance, InstanceKeyFormat, Index);
- rc = RegCreateKeyExW(hClassKey,
- DriverKey,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
-#if _WIN32_WINNT >= 0x502
- KEY_READ | KEY_WRITE,
-#else
- KEY_ALL_ACCESS,
-#endif
- NULL,
- &hKey,
- &Disposition);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- if (Disposition == REG_CREATED_NEW_KEY)
- break;
- RegCloseKey(hKey);
- hKey = NULL;
- Index++;
- }
-
- if (Index > 9999)
- {
- /* Unable to create more than 9999 devices within the same class */
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- /* Write the new Driver value */
- rc = RegSetValueExW(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (strlenW(DriverKey) + 1) * sizeof(WCHAR));
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- }
- else
- {
- /* Open the existing driver key */
-
- DriverKey = HeapAlloc(GetProcessHeap(), 0, dwSize);
- if (!DriverKey)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
-
- rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, (LPBYTE)DriverKey, &dwSize);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- rc = RegCreateKeyExW(hClassKey,
- DriverKey,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
-#if _WIN32_WINNT >= 0x502
- KEY_READ | KEY_WRITE,
-#else
- KEY_ALL_ACCESS,
-#endif
- NULL,
- &hKey,
- &Disposition);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- }
- }
-
- /* Do installation of the specified section */
- if (InfHandle)
- {
- FIXME("Need to install section %s in file %p\n",
- debugstr_w(InfSectionName), InfHandle);
- }
- key = hKey;
-
-cleanup:
- if (lpGuidString)
- RpcStringFreeW(&lpGuidString);
- HeapFree(GetProcessHeap(), 0, DriverKey);
- if (hHWProfileKey != INVALID_HANDLE_VALUE)
- RegCloseKey(hHWProfileKey);
- if (hEnumKey != NULL)
- RegCloseKey(hEnumKey);
- if (hClassKey != NULL)
- RegCloseKey(hClassKey);
- if (hDeviceKey != INVALID_HANDLE_VALUE)
- RegCloseKey(hDeviceKey);
- if (hKey != NULL && hKey != key)
- RegCloseKey(hKey);
-
- TRACE("Returning 0x%p\n", key);
- return key;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInfoA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInfoA(
- HDEVINFO DeviceInfoSet,
- PCSTR DeviceName,
- CONST GUID *ClassGuid,
- PCSTR DeviceDescription,
- HWND hwndParent,
- DWORD CreationFlags,
- PSP_DEVINFO_DATA DeviceInfoData)
-{
- BOOL ret;
- LPWSTR DeviceNameW = NULL;
- LPWSTR DeviceDescriptionW = NULL;
-
- TRACE("\n");
-
- if (DeviceName)
- {
- DeviceNameW = pSetupMultiByteToUnicode(DeviceName, CP_ACP);
- if (DeviceNameW == NULL) return FALSE;
- }
- if (DeviceDescription)
- {
- DeviceDescriptionW = pSetupMultiByteToUnicode(DeviceDescription, CP_ACP);
- if (DeviceDescriptionW == NULL)
- {
- MyFree(DeviceNameW);
- return FALSE;
- }
- }
-
- ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW,
- hwndParent, CreationFlags, DeviceInfoData);
-
- MyFree(DeviceNameW);
- MyFree(DeviceDescriptionW);
-
- return ret;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInfoW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInfoW(
- HDEVINFO DeviceInfoSet,
- PCWSTR DeviceName,
- CONST GUID *ClassGuid,
- PCWSTR DeviceDescription,
- HWND hwndParent,
- DWORD CreationFlags,
- PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- struct DeviceInfo *deviceInfo = NULL;
- BOOL ret = FALSE;
- CONFIGRET cr;
- DEVINST RootDevInst;
- DEVINST DevInst;
- WCHAR GenInstanceId[MAX_DEVICE_ID_LEN];
-
- TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName),
- debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
- hwndParent, CreationFlags, DeviceInfoData);
-
- if (!DeviceName)
- {
- SetLastError(ERROR_INVALID_DEVINST_NAME);
- return FALSE;
- }
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!ClassGuid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) &&
- !IsEqualGUID(ClassGuid, &set->ClassGuid))
- {
- SetLastError(ERROR_CLASS_MISMATCH);
- return FALSE;
- }
- if (CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS))
- {
- TRACE("Unknown flags: 0x%08lx\n", CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS));
- SetLastError(ERROR_INVALID_FLAGS);
- return FALSE;
- }
-
- /* Get the root device instance */
- cr = CM_Locate_DevInst_ExW(&RootDevInst,
- NULL,
- CM_LOCATE_DEVINST_NORMAL,
- set->hMachine);
- if (cr != CR_SUCCESS)
- {
- SetLastError(ERROR_INVALID_DATA);
- return FALSE;
- }
-
- /* Create the new device instance */
- cr = CM_Create_DevInst_ExW(&DevInst,
- (DEVINSTID)DeviceName,
- RootDevInst,
- (CreationFlags & DICD_GENERATE_ID) ?
- CM_CREATE_DEVINST_GENERATE_ID : 0,
- set->hMachine);
- if (cr != CR_SUCCESS)
- {
- SetLastError(GetErrorCodeFromCrCode(cr));
- return FALSE;
- }
-
- if (CreationFlags & DICD_GENERATE_ID)
- {
- /* Grab the actual instance ID that was created */
- cr = CM_Get_Device_ID_Ex(DevInst,
- GenInstanceId,
- MAX_DEVICE_ID_LEN,
- 0,
- set->hMachine);
- if (cr != CR_SUCCESS)
- {
- SetLastError(GetErrorCodeFromCrCode(cr));
- return FALSE;
- }
-
- DeviceName = GenInstanceId;
- TRACE("Using generated instance ID: %s\n", debugstr_w(DeviceName));
- }
-
- if (CreateDeviceInfo(set, DeviceName, ClassGuid, &deviceInfo))
- {
- InsertTailList(&set->ListHead, &deviceInfo->ListEntry);
-
- if (!DeviceInfoData)
- ret = TRUE;
- else
- {
- if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- }
- else
- {
- memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = deviceInfo->dnDevInst;
- DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
- ret = TRUE;
- }
- }
- }
-
- if (ret == FALSE)
- {
- if (deviceInfo != NULL)
- {
- /* Remove deviceInfo from List */
- RemoveEntryList(&deviceInfo->ListEntry);
-
- /* Destroy deviceInfo */
- DestroyDeviceInfo(deviceInfo);
- }
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiRegisterDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiRegisterDeviceInfo(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Flags,
- PSP_DETSIG_CMPPROC CompareProc,
- PVOID CompareContext,
- PSP_DEVINFO_DATA DupDeviceInfoData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- WCHAR DevInstId[MAX_DEVICE_ID_LEN];
- DEVINST ParentDevInst;
- CONFIGRET cr;
- DWORD dwError = ERROR_SUCCESS;
-
- TRACE("%p %p %08x %p %p %p\n", DeviceInfoSet, DeviceInfoData, Flags,
- CompareProc, CompareContext, DupDeviceInfoData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if (Flags & ~SPRDI_FIND_DUPS)
- {
- TRACE("Unknown flags: 0x%08lx\n", Flags & ~SPRDI_FIND_DUPS);
- SetLastError(ERROR_INVALID_FLAGS);
- return FALSE;
- }
-
- if (Flags & SPRDI_FIND_DUPS)
- {
- FIXME("Unimplemented codepath!\n");
- }
-
- CM_Get_Device_ID_Ex(DeviceInfoData->DevInst,
- DevInstId,
- MAX_DEVICE_ID_LEN,
- 0,
- set->hMachine);
-
- CM_Get_Parent_Ex(&ParentDevInst,
- DeviceInfoData->DevInst,
- 0,
- set->hMachine);
-
- cr = CM_Create_DevInst_Ex(&DeviceInfoData->DevInst,
- DevInstId,
- ParentDevInst,
- CM_CREATE_DEVINST_NORMAL | CM_CREATE_DEVINST_DO_NOT_INSTALL,
- set->hMachine);
- if (cr != CR_SUCCESS &&
- cr != CR_ALREADY_SUCH_DEVINST)
- {
- dwError = ERROR_NO_SUCH_DEVINST;
- }
-
- SetLastError(dwError);
-
- return (dwError == ERROR_SUCCESS);
-}
-
-/***********************************************************************
- * SetupDiEnumDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiEnumDeviceInfo(
- HDEVINFO devinfo,
- DWORD index,
- PSP_DEVINFO_DATA info)
-{
- BOOL ret = FALSE;
-
- TRACE("%p %d %p\n", devinfo, index, info);
-
- if(info==NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (devinfo && devinfo != INVALID_HANDLE_VALUE)
- {
- struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
- if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
- {
- if (info->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- PLIST_ENTRY ItemList = list->ListHead.Flink;
- while (ItemList != &list->ListHead && index-- > 0)
- ItemList = ItemList->Flink;
- if (ItemList == &list->ListHead)
- SetLastError(ERROR_NO_MORE_ITEMS);
- else
- {
- struct DeviceInfo *DevInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
- memcpy(&info->ClassGuid,
- &DevInfo->ClassGuid,
- sizeof(GUID));
- info->DevInst = DevInfo->dnDevInst;
- info->Reserved = (ULONG_PTR)DevInfo;
- ret = TRUE;
- }
- }
- }
- else
- SetLastError(ERROR_INVALID_HANDLE);
- }
- else
- SetLastError(ERROR_INVALID_HANDLE);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInstanceIdA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstanceIdA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- PSTR DeviceInstanceId,
- DWORD DeviceInstanceIdSize,
- PDWORD RequiredSize)
-{
- BOOL ret = FALSE;
- DWORD size;
- PWSTR instanceId;
-
- TRACE("%p %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
- DeviceInstanceIdSize, RequiredSize);
-
- if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- ret = SetupDiGetDeviceInstanceIdW(DeviceInfoSet,
- DeviceInfoData,
- NULL,
- 0,
- &size);
- if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- return FALSE;
- instanceId = MyMalloc(size * sizeof(WCHAR));
- if (instanceId)
- {
- ret = SetupDiGetDeviceInstanceIdW(DeviceInfoSet,
- DeviceInfoData,
- instanceId,
- size,
- &size);
- if (ret)
- {
- int len = WideCharToMultiByte(CP_ACP, 0, instanceId, -1,
- DeviceInstanceId,
- DeviceInstanceIdSize, NULL, NULL);
-
- if (!len)
- ret = FALSE;
- else
- {
- if (len > DeviceInstanceIdSize)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- ret = FALSE;
- }
- if (RequiredSize)
- *RequiredSize = len;
- }
- }
- MyFree(instanceId);
- }
- else
- {
- if (RequiredSize)
- *RequiredSize = size;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- ret = FALSE;
- }
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInstanceIdW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstanceIdW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- PWSTR DeviceInstanceId,
- DWORD DeviceInstanceIdSize,
- PDWORD RequiredSize)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- struct DeviceInfo *devInfo;
-
- TRACE("%p %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
- DeviceInstanceIdSize, RequiredSize);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (DeviceInstanceId && DeviceInstanceIdSize == 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- TRACE("instance ID: %s\n", debugstr_w(devInfo->instanceId));
- if (DeviceInstanceIdSize < lstrlenW(devInfo->instanceId) + 1)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- if (RequiredSize)
- *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
- return FALSE;
- }
- lstrcpyW(DeviceInstanceId, devInfo->instanceId);
- if (RequiredSize)
- *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallA(
- HINF InfHandle,
- PCSTR InfSectionName,
- PSTR InfSectionWithExt,
- DWORD InfSectionWithExtSize,
- PDWORD RequiredSize,
- PSTR *Extension)
-{
- return SetupDiGetActualSectionToInstallExA(InfHandle, InfSectionName,
- NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
- Extension, NULL);
-}
-
-/***********************************************************************
- * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallW(
- HINF InfHandle,
- PCWSTR InfSectionName,
- PWSTR InfSectionWithExt,
- DWORD InfSectionWithExtSize,
- PDWORD RequiredSize,
- PWSTR *Extension)
-{
- return SetupDiGetActualSectionToInstallExW(InfHandle, InfSectionName,
- NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
- Extension, NULL);
-}
-
-/***********************************************************************
- * SetupDiGetActualSectionToInstallExA (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetActualSectionToInstallExA(
- IN HINF InfHandle,
- IN PCSTR InfSectionName,
- IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
- OUT PSTR InfSectionWithExt OPTIONAL,
- IN DWORD InfSectionWithExtSize,
- OUT PDWORD RequiredSize OPTIONAL,
- OUT PSTR* Extension OPTIONAL,
- IN PVOID Reserved)
-{
- LPWSTR InfSectionNameW = NULL;
- LPWSTR InfSectionWithExtW = NULL;
- PWSTR ExtensionW;
- BOOL bResult = FALSE;
-
- TRACE("\n");
-
- if (InfSectionName)
- {
- InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
- if (InfSectionNameW == NULL)
- goto cleanup;
- }
- if (InfSectionWithExt)
- {
- InfSectionWithExtW = MyMalloc(InfSectionWithExtSize * sizeof(WCHAR));
- if (InfSectionWithExtW == NULL)
- goto cleanup;
- }
-
- bResult = SetupDiGetActualSectionToInstallExW(
- InfHandle, InfSectionNameW, AlternatePlatformInfo,
- InfSectionWithExt ? InfSectionWithExtW : NULL,
- InfSectionWithExtSize,
- RequiredSize,
- Extension ? &ExtensionW : NULL,
- Reserved);
-
- if (bResult && InfSectionWithExt)
- {
- bResult = WideCharToMultiByte(CP_ACP, 0, InfSectionWithExtW, -1, InfSectionWithExt,
- InfSectionWithExtSize, NULL, NULL) != 0;
- }
- if (bResult && Extension)
- {
- if (ExtensionW == NULL)
- *Extension = NULL;
- else
- *Extension = &InfSectionWithExt[ExtensionW - InfSectionWithExtW];
- }
-
-cleanup:
- MyFree(InfSectionNameW);
- MyFree(InfSectionWithExtW);
-
- return bResult;
-}
-
-/***********************************************************************
- * SetupDiGetClassDescriptionA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionA(
- const GUID* ClassGuid,
- PSTR ClassDescription,
- DWORD ClassDescriptionSize,
- PDWORD RequiredSize)
-{
- return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
- ClassDescriptionSize,
- RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiGetClassDescriptionW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionW(
- const GUID* ClassGuid,
- PWSTR ClassDescription,
- DWORD ClassDescriptionSize,
- PDWORD RequiredSize)
-{
- return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
- ClassDescriptionSize,
- RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiGetClassDescriptionExA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExA(
- const GUID* ClassGuid,
- PSTR ClassDescription,
- DWORD ClassDescriptionSize,
- PDWORD RequiredSize,
- PCSTR MachineName,
- PVOID Reserved)
-{
- PWCHAR ClassDescriptionW = NULL;
- LPWSTR MachineNameW = NULL;
- BOOL ret = FALSE;
-
- TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
- ClassDescriptionSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
- if (ClassDescriptionSize > 0)
- {
- ClassDescriptionW = MyMalloc(ClassDescriptionSize * sizeof(WCHAR));
- if (!ClassDescriptionW)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
- }
-
- if (MachineName)
- {
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- if (!MachineNameW)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
- }
-
- ret = SetupDiGetClassDescriptionExW(ClassGuid, ClassDescriptionW,
- ClassDescriptionSize * sizeof(WCHAR), RequiredSize, MachineNameW, Reserved);
- if (ret)
- {
- DWORD len = (DWORD)WideCharToMultiByte(CP_ACP, 0, ClassDescriptionW, -1, ClassDescription,
- ClassDescriptionSize, NULL, NULL);
- if (len == 0 || len > ClassDescriptionSize)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- ret = FALSE;
- }
- }
-
-cleanup:
- MyFree(ClassDescriptionW);
- MyFree(MachineNameW);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetClassDescriptionExW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExW(
- const GUID* ClassGuid,
- PWSTR ClassDescription,
- DWORD ClassDescriptionSize,
- PDWORD RequiredSize,
- PCWSTR MachineName,
- PVOID Reserved)
-{
- HKEY hKey;
- DWORD dwLength;
- DWORD dwRegType;
- LONG rc;
- PWSTR Buffer;
-
- TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
- ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
- /* Make sure there's a GUID */
- if (!ClassGuid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- /* Make sure there's a real buffer when there's a size */
- if (!ClassDescription && ClassDescriptionSize > 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- /* Open the key for the GUID */
- hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
- KEY_QUERY_VALUE,
- DIOCR_INSTALLER,
- MachineName,
- Reserved);
- if (hKey == INVALID_HANDLE_VALUE)
- return FALSE;
-
- /* Retrieve the class description data and close the key */
- rc = QueryRegistryValue(hKey, NULL, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
- RegCloseKey(hKey);
-
- /* Make sure we got the data */
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- return FALSE;
- }
-
- /* Make sure the data is a string */
- if (dwRegType != REG_SZ)
- {
- MyFree(Buffer);
- SetLastError(ERROR_GEN_FAILURE);
- return FALSE;
- }
-
- /* Determine the length of the class description */
- dwLength /= sizeof(WCHAR);
-
- /* Count the null-terminator if none is present */
- if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
- dwLength++;
-
- /* Inform the caller about the class description */
- if ((ClassDescription != NULL) && (dwLength <= ClassDescriptionSize))
- {
- memcpy(ClassDescription, Buffer, (dwLength - 1) * sizeof(WCHAR));
- ClassDescription[dwLength - 1] = UNICODE_NULL;
- }
-
- /* Inform the caller about the required size */
- if (RequiredSize != NULL)
- *RequiredSize = dwLength;
-
- /* Clean up the buffer */
- MyFree(Buffer);
-
- /* Make sure the buffer was large enough */
- if ((ClassDescription == NULL) || (dwLength > ClassDescriptionSize))
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiGetClassDevsA (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsA(
- CONST GUID *class,
- LPCSTR enumstr,
- HWND parent,
- DWORD flags)
-{
- return SetupDiGetClassDevsExA(class, enumstr, parent,
- flags, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiGetClassDevsExA (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExA(
- const GUID *class,
- PCSTR enumstr,
- HWND parent,
- DWORD flags,
- HDEVINFO deviceset,
- PCSTR machine,
- PVOID reserved)
-{
- HDEVINFO ret;
- LPWSTR enumstrW = NULL, machineW = NULL;
-
- if (enumstr)
- {
- enumstrW = pSetupMultiByteToUnicode(enumstr, CP_ACP);
- if (!enumstrW)
- {
- ret = INVALID_HANDLE_VALUE;
- goto end;
- }
- }
- if (machine)
- {
- machineW = pSetupMultiByteToUnicode(machine, CP_ACP);
- if (!machineW)
- {
- MyFree(enumstrW);
- ret = INVALID_HANDLE_VALUE;
- goto end;
- }
- }
- ret = SetupDiGetClassDevsExW(class, enumstrW, parent, flags, deviceset,
- machineW, reserved);
- MyFree(enumstrW);
- MyFree(machineW);
-
-end:
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetClassDevsW (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsW(
- CONST GUID *class,
- LPCWSTR enumstr,
- HWND parent,
- DWORD flags)
-{
- return SetupDiGetClassDevsExW(class, enumstr, parent, flags, NULL, NULL,
- NULL);
-}
-
-/***********************************************************************
- * SetupDiGetClassDevsExW (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExW(
- CONST GUID *class,
- PCWSTR enumstr,
- HWND parent,
- DWORD flags,
- HDEVINFO deviceset,
- PCWSTR machine,
- PVOID reserved)
-{
- HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
- struct DeviceInfoSet *list;
- CONST GUID *pClassGuid;
- LONG rc;
- HDEVINFO set = INVALID_HANDLE_VALUE;
-
- TRACE("%s %s %p 0x%08x %p %s %p\n", debugstr_guid(class),
- debugstr_w(enumstr), parent, flags, deviceset, debugstr_w(machine),
- reserved);
-
- if (!(flags & DIGCF_ALLCLASSES) && !class)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
-
- /* Create the deviceset if not set */
- if (deviceset)
- {
- list = (struct DeviceInfoSet *)deviceset;
- if (list->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- goto cleanup;
- }
- hDeviceInfo = deviceset;
- }
- else
- {
- hDeviceInfo = SetupDiCreateDeviceInfoListExW(
- flags & (DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES) ? NULL : class,
- NULL, machine, NULL);
- if (hDeviceInfo == INVALID_HANDLE_VALUE)
- goto cleanup;
- list = (struct DeviceInfoSet *)hDeviceInfo;
- }
-
- if (flags & DIGCF_PROFILE)
- FIXME(": flag DIGCF_PROFILE ignored\n");
-
- if (flags & DIGCF_DEVICEINTERFACE)
- {
- if (!class)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
- rc = SETUP_CreateInterfaceList(list, machine, class, enumstr, flags & DIGCF_PRESENT);
- }
- else
- {
- /* Determine which class(es) should be included in the deviceset */
- if (flags & DIGCF_ALLCLASSES)
- {
- /* The caller wants all classes. Check if
- * the deviceset limits us to one class */
- if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
- pClassGuid = NULL;
- else
- pClassGuid = &list->ClassGuid;
- }
- else if (class)
- {
- /* The caller wants one class. Check if it matches deviceset class */
- if (IsEqualIID(&list->ClassGuid, class)
- || IsEqualIID(&list->ClassGuid, &GUID_NULL))
- {
- pClassGuid = class;
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
- }
- else if (!IsEqualIID(&list->ClassGuid, &GUID_NULL))
- {
- /* No class specified. Try to use the one of the deviceset */
- if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
- pClassGuid = &list->ClassGuid;
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
- rc = SETUP_CreateDevicesList(list, machine, pClassGuid, enumstr);
- }
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- set = hDeviceInfo;
-
-cleanup:
- if (!deviceset && hDeviceInfo != INVALID_HANDLE_VALUE && hDeviceInfo != set)
- SetupDiDestroyDeviceInfoList(hDeviceInfo);
- return set;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInfoListDetailA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_LIST_DETAIL_DATA_A DevInfoData )
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
- TRACE("%p %p\n", DeviceInfoSet, DevInfoData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DevInfoData ||
- DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_A))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
- DevInfoData->RemoteMachineHandle = set->hMachine;
- if (set->MachineName)
- {
- FIXME("Stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- }
- else
- DevInfoData->RemoteMachineName[0] = 0;
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInfoListDetailW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_LIST_DETAIL_DATA_W DevInfoData )
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
- TRACE("%p %p\n", DeviceInfoSet, DevInfoData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DevInfoData ||
- DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_W))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
- DevInfoData->RemoteMachineHandle = set->hMachine;
- if (set->MachineName)
- strcpyW(DevInfoData->RemoteMachineName, set->MachineName + 2);
- else
- DevInfoData->RemoteMachineName[0] = 0;
-
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInterfaceA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInterfaceA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- const GUID *InterfaceClassGuid,
- PCSTR ReferenceString,
- DWORD CreationFlags,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
- BOOL ret;
- LPWSTR ReferenceStringW = NULL;
-
- TRACE("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
- debugstr_guid(InterfaceClassGuid), debugstr_a(ReferenceString),
- CreationFlags, DeviceInterfaceData);
-
- if (ReferenceString)
- {
- ReferenceStringW = pSetupMultiByteToUnicode(ReferenceString, CP_ACP);
- if (ReferenceStringW == NULL) return FALSE;
- }
-
- ret = SetupDiCreateDeviceInterfaceW(DeviceInfoSet, DeviceInfoData,
- InterfaceClassGuid, ReferenceStringW, CreationFlags,
- DeviceInterfaceData);
-
- MyFree(ReferenceStringW);
-
- return ret;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInterfaceW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInterfaceW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- const GUID *InterfaceClassGuid,
- PCWSTR ReferenceString,
- DWORD CreationFlags,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- TRACE("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
- debugstr_guid(InterfaceClassGuid), debugstr_w(ReferenceString),
- CreationFlags, DeviceInterfaceData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (!InterfaceClassGuid)
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
-
- FIXME("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
- debugstr_guid(InterfaceClassGuid), debugstr_w(ReferenceString),
- CreationFlags, DeviceInterfaceData);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInterfaceRegKeyA (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- DWORD Reserved,
- REGSAM samDesired,
- HINF InfHandle,
- PCSTR InfSectionName)
-{
- HKEY key;
- PWSTR InfSectionNameW = NULL;
-
- TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
- samDesired, InfHandle, InfSectionName);
- if (InfHandle)
- {
- if (!InfSectionName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
- if (!InfSectionNameW)
- return INVALID_HANDLE_VALUE;
- }
- key = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet,
- DeviceInterfaceData, Reserved, samDesired, InfHandle,
- InfSectionNameW);
- MyFree(InfSectionNameW);
- return key;
-}
-
-/***********************************************************************
- * SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- DWORD Reserved,
- REGSAM samDesired,
- 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);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
- set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
- !DeviceInterfaceData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- if (InfHandle && !InfSectionName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- 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;
-}
-
-/***********************************************************************
- * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- DWORD Reserved)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- BOOL ret = FALSE;
-
- TRACE("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
- set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
- !DeviceInterfaceData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- FIXME("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
- *
- * PARAMS
- * DeviceInfoSet [I] Set of devices from which to enumerate
- * interfaces
- * DeviceInfoData [I] (Optional) If specified, a specific device
- * instance from which to enumerate interfaces.
- * If it isn't specified, all interfaces for all
- * devices in the set are enumerated.
- * InterfaceClassGuid [I] The interface class to enumerate.
- * MemberIndex [I] An index of the interface instance to enumerate.
- * A caller should start with MemberIndex set to 0,
- * and continue until the function fails with
- * ERROR_NO_MORE_ITEMS.
- * DeviceInterfaceData [I/O] Returns an enumerated interface. Its cbSize
- * member must be set to
- * sizeof(SP_DEVICE_INTERFACE_DATA).
- *
- * RETURNS
- * Success: non-zero value.
- * Failure: FALSE. Call GetLastError() for more info.
- */
-BOOL WINAPI SetupDiEnumDeviceInterfaces(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- CONST GUID * InterfaceClassGuid,
- DWORD MemberIndex,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- BOOL ret = FALSE;
-
- TRACE("%p, %p, %s, %d, %p\n", DeviceInfoSet, DeviceInfoData,
- debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
- set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (DeviceInfoData && (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) ||
- !DeviceInfoData->Reserved))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (DeviceInfoData)
- {
- struct DeviceInfo *devInfo =
- (struct DeviceInfo *)DeviceInfoData->Reserved;
- BOOL found = FALSE;
- PLIST_ENTRY InterfaceListEntry = devInfo->InterfaceListHead.Flink;
- while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
- {
- struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
- if (!IsEqualIID(&DevItf->InterfaceClassGuid, InterfaceClassGuid))
- {
- InterfaceListEntry = InterfaceListEntry->Flink;
- continue;
- }
- if (MemberIndex-- == 0)
- {
- /* return this item */
- memcpy(&DeviceInterfaceData->InterfaceClassGuid,
- &DevItf->InterfaceClassGuid,
- sizeof(GUID));
- DeviceInterfaceData->Flags = DevItf->Flags;
- DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
- found = TRUE;
- ret = TRUE;
- }
- InterfaceListEntry = InterfaceListEntry->Flink;
- }
- if (!found)
- SetLastError(ERROR_NO_MORE_ITEMS);
- }
- else
- {
- BOOL found = FALSE;
- PLIST_ENTRY ItemList = set->ListHead.Flink;
- while (ItemList != &set->ListHead && !found)
- {
- PLIST_ENTRY InterfaceListEntry;
- struct DeviceInfo *devInfo =
- CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
- InterfaceListEntry = devInfo->InterfaceListHead.Flink;
- while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
- {
- struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
- if (!IsEqualIID(&DevItf->InterfaceClassGuid, InterfaceClassGuid))
- {
- InterfaceListEntry = InterfaceListEntry->Flink;
- continue;
- }
- if (MemberIndex-- == 0)
- {
- /* return this item */
- memcpy(&DeviceInterfaceData->InterfaceClassGuid,
- &DevItf->InterfaceClassGuid,
- sizeof(GUID));
- DeviceInterfaceData->Flags = DevItf->Flags;
- DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
- found = TRUE;
- ret = TRUE;
- }
- InterfaceListEntry = InterfaceListEntry->Flink;
- }
- ItemList = ItemList->Flink;
-
- }
- if (!found)
- SetLastError(ERROR_NO_MORE_ITEMS);
- }
- return ret;
-}
-
-/***********************************************************************
- * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
- *
- * Destroy a DeviceInfoList and free all used memory of the list.
- *
- * PARAMS
- * devinfo [I] DeviceInfoList pointer to list to destroy
- *
- * RETURNS
- * Success: non zero value.
- * Failure: zero value.
- */
-BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
-{
- BOOL ret = FALSE;
-
- TRACE("%p\n", devinfo);
- if (devinfo && devinfo != INVALID_HANDLE_VALUE)
- {
- struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
-
- if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
- {
- ret = DestroyDeviceInfoSet(list);
- }
- }
-
- if (ret == FALSE)
- SetLastError(ERROR_INVALID_HANDLE);
-
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
- DWORD DeviceInterfaceDetailDataSize,
- PDWORD RequiredSize,
- PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
- DWORD sizeW = 0, bytesNeeded;
- BOOL ret = FALSE;
-
- TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
- DeviceInterfaceData, DeviceInterfaceDetailData,
- DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
- set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
- !DeviceInterfaceData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
-
- if((DeviceInterfaceDetailDataSize != 0) &&
- (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(CHAR))))
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
-
- if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
-
-
- if (DeviceInterfaceDetailData != NULL)
- {
- sizeW = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)
- + (DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath)) * sizeof(WCHAR);
- DeviceInterfaceDetailDataW = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)MyMalloc(sizeW);
- if (!DeviceInterfaceDetailDataW)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- }
- DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
- }
- if (!DeviceInterfaceDetailData || (DeviceInterfaceDetailData && DeviceInterfaceDetailDataW))
- {
- ret = SetupDiGetDeviceInterfaceDetailW(
- DeviceInfoSet,
- DeviceInterfaceData,
- DeviceInterfaceDetailDataW,
- sizeW,
- &sizeW,
- DeviceInfoData);
- bytesNeeded = (sizeW - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) / sizeof(WCHAR)
- + FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath);
- if (RequiredSize)
- *RequiredSize = bytesNeeded;
- if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize >= bytesNeeded)
- {
- if (!WideCharToMultiByte(
- CP_ACP, 0,
- DeviceInterfaceDetailDataW->DevicePath, -1,
- DeviceInterfaceDetailData->DevicePath, DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath),
- NULL, NULL))
- {
- ret = FALSE;
- }
- }
- }
- MyFree(DeviceInterfaceDetailDataW);
-
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
- PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
- DWORD DeviceInterfaceDetailDataSize,
- PDWORD RequiredSize,
- PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- BOOL ret = FALSE;
-
- TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
- DeviceInterfaceData, DeviceInterfaceDetailData,
- DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
- set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInterfaceData ||
- DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
- !DeviceInterfaceData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (DeviceInterfaceDetailData && DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W))
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
- if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
- {
- SetLastError(ERROR_INVALID_USER_BUFFER);
- return FALSE;
- }
- if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if ((DeviceInterfaceDetailData != NULL)
- && (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) + sizeof(WCHAR)))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- else
- {
- struct DeviceInterface *deviceInterface = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
- LPCWSTR devName = deviceInterface->SymbolicLink;
- DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) +
- (lstrlenW(devName) + 1) * sizeof(WCHAR);
-
- if (sizeRequired > DeviceInterfaceDetailDataSize)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- if (RequiredSize)
- *RequiredSize = sizeRequired;
- }
- else
- {
- strcpyW(DeviceInterfaceDetailData->DevicePath, devName);
- TRACE("DevicePath is %s\n", debugstr_w(DeviceInterfaceDetailData->DevicePath));
- if (DeviceInfoData)
- {
- memcpy(&DeviceInfoData->ClassGuid,
- &deviceInterface->DeviceInfo->ClassGuid,
- sizeof(GUID));
- DeviceInfoData->DevInst = deviceInterface->DeviceInfo->dnDevInst;
- DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
- }
- ret = TRUE;
- }
- }
- return ret;
-}
-
-struct PropertyMapEntry
-{
- DWORD regType;
- LPCSTR nameA;
- LPCWSTR nameW;
-};
-
-static struct PropertyMapEntry PropertyMap[] = {
- { REG_SZ, "DeviceDesc", REGSTR_VAL_DEVDESC },
- { REG_MULTI_SZ, "HardwareId", REGSTR_VAL_HARDWAREID },
- { REG_MULTI_SZ, "CompatibleIDs", REGSTR_VAL_COMPATIBLEIDS },
- { 0, NULL, NULL }, /* SPDRP_UNUSED0 */
- { REG_SZ, "Service", REGSTR_VAL_SERVICE },
- { 0, NULL, NULL }, /* SPDRP_UNUSED1 */
- { 0, NULL, NULL }, /* SPDRP_UNUSED2 */
- { REG_SZ, "Class", REGSTR_VAL_CLASS },
- { REG_SZ, "ClassGUID", REGSTR_VAL_CLASSGUID },
- { REG_SZ, "Driver", REGSTR_VAL_DRIVER },
- { REG_DWORD, "ConfigFlags", REGSTR_VAL_CONFIGFLAGS },
- { REG_SZ, "Mfg", REGSTR_VAL_MFG },
- { REG_SZ, "FriendlyName", REGSTR_VAL_FRIENDLYNAME },
- { REG_SZ, "LocationInformation", REGSTR_VAL_LOCATION_INFORMATION },
- { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */
- { REG_DWORD, "Capabilities", REGSTR_VAL_CAPABILITIES },
- { REG_DWORD, "UINumber", REGSTR_VAL_UI_NUMBER },
- { REG_MULTI_SZ, "UpperFilters", REGSTR_VAL_UPPERFILTERS },
- { REG_MULTI_SZ, "LowerFilters", REGSTR_VAL_LOWERFILTERS },
- { 0, NULL, NULL }, /* SPDRP_BUSTYPEGUID */
- { 0, NULL, NULL }, /* SPDRP_LEGACYBUSTYPE */
- { 0, NULL, NULL }, /* SPDRP_BUSNUMBER */
- { 0, NULL, NULL }, /* SPDRP_ENUMERATOR_NAME */
- { REG_BINARY, "Security", REGSTR_SECURITY },
- { 0, NULL, NULL }, /* SPDRP_SECURITY_SDS */
- { 0, NULL, NULL }, /* SPDRP_DEVTYPE */
- { 0, NULL, NULL }, /* SPDRP_EXCLUSIVE */
- { 0, NULL, NULL }, /* SPDRP_CHARACTERISTICS */
- { 0, NULL, NULL }, /* SPDRP_ADDRESS */
- { REG_SZ, "UINumberDescFormat", REGSTR_UI_NUMBER_DESC_FORMAT },
- { 0, NULL, NULL }, /* SPDRP_DEVICE_POWER_DATA */
- { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY */
- { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_HW_DEFAULT */
- { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_OVERRIDE */
- { 0, NULL, NULL }, /* SPDRP_INSTALL_STATE */
-};
-
-/***********************************************************************
- * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Property,
- PDWORD PropertyRegDataType,
- PBYTE PropertyBuffer,
- DWORD PropertyBufferSize,
- PDWORD RequiredSize)
-{
- BOOL ret;
- BOOL bIsStringProperty;
- DWORD RegType;
- DWORD RequiredSizeA, RequiredSizeW;
- DWORD PropertyBufferSizeW = 0;
- PBYTE PropertyBufferW = NULL;
-
- TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData,
- Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
- RequiredSize);
-
- if (PropertyBufferSize != 0)
- {
- PropertyBufferSizeW = PropertyBufferSize * 2;
- PropertyBufferW = HeapAlloc(GetProcessHeap(), 0, PropertyBufferSizeW);
- if (!PropertyBufferW)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- }
-
- ret = SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
- DeviceInfoData,
- Property,
- &RegType,
- PropertyBufferW,
- PropertyBufferSizeW,
- &RequiredSizeW);
-
- if (ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- bIsStringProperty = (RegType == REG_SZ || RegType == REG_MULTI_SZ || RegType == REG_EXPAND_SZ);
-
- if (bIsStringProperty)
- RequiredSizeA = RequiredSizeW / sizeof(WCHAR);
- else
- RequiredSizeA = RequiredSizeW;
- if (RequiredSize)
- *RequiredSize = RequiredSizeA;
- if (PropertyRegDataType)
- *PropertyRegDataType = RegType;
- }
-
- if (!ret)
- {
- HeapFree(GetProcessHeap(), 0, PropertyBufferW);
- return ret;
- }
-
- if (RequiredSizeA <= PropertyBufferSize)
- {
- if (bIsStringProperty && PropertyBufferSize > 0)
- {
- if (WideCharToMultiByte(CP_ACP, 0, (LPWSTR)PropertyBufferW, RequiredSizeW / sizeof(WCHAR), (LPSTR)PropertyBuffer, PropertyBufferSize, NULL, NULL) == 0)
- {
- /* Last error is already set by WideCharToMultiByte */
- ret = FALSE;
- }
- }
- else
- memcpy(PropertyBuffer, PropertyBufferW, RequiredSizeA);
- }
- else
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- ret = FALSE;
- }
-
- HeapFree(GetProcessHeap(), 0, PropertyBufferW);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceRegistryPropertyW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Property,
- PDWORD PropertyRegDataType,
- PBYTE PropertyBuffer,
- DWORD PropertyBufferSize,
- PDWORD RequiredSize)
-{
- BOOL ret = FALSE;
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- struct DeviceInfo *devInfo;
-
- TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData,
- Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
- RequiredSize);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
- && PropertyMap[Property].nameW)
- {
- DWORD size = PropertyBufferSize;
- HKEY hKey;
- LONG l;
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
- if (hKey == INVALID_HANDLE_VALUE)
- return FALSE;
- l = RegQueryValueExW(hKey, PropertyMap[Property].nameW,
- NULL, PropertyRegDataType, PropertyBuffer, &size);
- RegCloseKey(hKey);
-
- if (RequiredSize)
- *RequiredSize = size;
- switch(l) {
- case ERROR_SUCCESS:
- if (PropertyBuffer != NULL || size == 0)
- ret = TRUE;
- else
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- break;
- case ERROR_MORE_DATA:
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- break;
- default:
- SetLastError(l);
- }
- }
- else if (Property == SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)
- {
- DWORD required = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
-
- if (PropertyRegDataType)
- *PropertyRegDataType = REG_SZ;
- if (RequiredSize)
- *RequiredSize = required;
- if (PropertyBufferSize >= required)
- {
- strcpyW((LPWSTR)PropertyBuffer, devInfo->Data);
- ret = TRUE;
- }
- else
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- }
- else
- {
- ERR("Property 0x%lx not implemented\n", Property);
- SetLastError(ERROR_NOT_SUPPORTED);
- }
- return ret;
-}
-
-/***********************************************************************
- * SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Property,
- const BYTE *PropertyBuffer,
- DWORD PropertyBufferSize)
-{
- BOOL ret = FALSE;
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
- TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
- PropertyBuffer, PropertyBufferSize);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- FIXME("%p %p 0x%lx %p 0x%lx\n", DeviceInfoSet, DeviceInfoData,
- Property, PropertyBuffer, PropertyBufferSize);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Property,
- const BYTE *PropertyBuffer,
- DWORD PropertyBufferSize)
-{
- BOOL ret = FALSE;
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
- TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
- PropertyBuffer, PropertyBufferSize);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
- && PropertyMap[Property].nameW)
- {
- HKEY hKey;
- LONG l;
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
- if (hKey == INVALID_HANDLE_VALUE)
- return FALSE;
- /* Write new data */
- l = RegSetValueExW(
- hKey, PropertyMap[Property].nameW, 0,
- PropertyMap[Property].regType, PropertyBuffer,
- PropertyBufferSize);
- if (!l)
- ret = TRUE;
- else
- SetLastError(l);
- RegCloseKey(hKey);
- }
- else
- {
- ERR("Property 0x%lx not implemented\n", Property);
- SetLastError(ERROR_NOT_SUPPORTED);
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiInstallClassA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassA(
- HWND hwndParent,
- PCSTR InfFileName,
- DWORD Flags,
- HSPFILEQ FileQueue)
-{
- return SetupDiInstallClassExA(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiInstallClassExA (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiInstallClassExA(
- IN HWND hwndParent OPTIONAL,
- IN PCSTR InfFileName OPTIONAL,
- IN DWORD Flags,
- IN HSPFILEQ FileQueue OPTIONAL,
- IN CONST GUID *InterfaceClassGuid OPTIONAL,
- IN PVOID Reserved1,
- IN PVOID Reserved2)
-{
- PWSTR InfFileNameW = NULL;
- BOOL Result;
-
- if (!InfFileName)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- else
- {
- InfFileNameW = pSetupMultiByteToUnicode(InfFileName, CP_ACP);
- if (InfFileNameW == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- }
-
- Result = SetupDiInstallClassExW(hwndParent, InfFileNameW, Flags,
- FileQueue, InterfaceClassGuid, Reserved1, Reserved2);
-
- MyFree(InfFileNameW);
-
- return Result;
-}
-
-HKEY SETUP_CreateClassKey(HINF hInf)
-{
- WCHAR FullBuffer[MAX_PATH];
- WCHAR Buffer[MAX_PATH];
- DWORD RequiredSize;
- HKEY hClassKey;
- DWORD Disposition;
-
- /* Obtain the Class GUID for this class */
- if (!SetupGetLineTextW(NULL,
- hInf,
- Version,
- REGSTR_VAL_CLASSGUID,
- Buffer,
- sizeof(Buffer) / sizeof(WCHAR),
- &RequiredSize))
- {
- return INVALID_HANDLE_VALUE;
- }
-
- /* Build the corresponding registry key name */
- lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
- lstrcatW(FullBuffer, BackSlash);
- lstrcatW(FullBuffer, Buffer);
-
- /* Obtain the Class name for this class */
- if (!SetupGetLineTextW(NULL,
- hInf,
- Version,
- REGSTR_VAL_CLASS,
- Buffer,
- sizeof(Buffer) / sizeof(WCHAR),
- &RequiredSize))
- {
- return INVALID_HANDLE_VALUE;
- }
-
- /* Try to open or create the registry key */
- TRACE("Opening class key %s\n", debugstr_w(FullBuffer));
-#if 0 // I keep this for reference...
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
- FullBuffer,
- 0,
- KEY_SET_VALUE,
- &hClassKey))
- {
- /* Use RegCreateKeyExW */
- }
-#endif
- if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
- FullBuffer,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_SET_VALUE,
- NULL,
- &hClassKey,
- &Disposition))
- {
- ERR("RegCreateKeyExW(%s) failed\n", debugstr_w(FullBuffer));
- return INVALID_HANDLE_VALUE;
- }
- if (Disposition == REG_CREATED_NEW_KEY)
- TRACE("The class key %s was successfully created\n", debugstr_w(FullBuffer));
- else
- TRACE("The class key %s was successfully opened\n", debugstr_w(FullBuffer));
-
- TRACE( "setting value %s to %s\n", debugstr_w(REGSTR_VAL_CLASS), debugstr_w(Buffer) );
- if (RegSetValueExW(hClassKey,
- REGSTR_VAL_CLASS,
- 0,
- REG_SZ,
- (LPBYTE)Buffer,
- RequiredSize * sizeof(WCHAR)))
- {
- RegCloseKey(hClassKey);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE,
- FullBuffer);
- return INVALID_HANDLE_VALUE;
- }
-
- return hClassKey;
-}
-
-/***********************************************************************
- * SetupDiInstallClassW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassW(
- HWND hwndParent,
- PCWSTR InfFileName,
- DWORD Flags,
- HSPFILEQ FileQueue)
-{
- return SetupDiInstallClassExW(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
-}
-
-
-/***********************************************************************
- * SetupDiOpenClassRegKey (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKey(
- const GUID* ClassGuid,
- REGSAM samDesired)
-{
- return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
- DIOCR_INSTALLER, NULL, NULL);
-}
-
-
-/***********************************************************************
- * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExA(
- const GUID* ClassGuid,
- REGSAM samDesired,
- DWORD Flags,
- PCSTR MachineName,
- PVOID Reserved)
-{
- PWSTR MachineNameW = NULL;
- HKEY hKey;
-
- TRACE("%s 0x%lx 0x%lx %s %p\n", debugstr_guid(ClassGuid), samDesired,
- Flags, debugstr_a(MachineName), Reserved);
-
- if (MachineName)
- {
- MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
- if (MachineNameW == NULL)
- return INVALID_HANDLE_VALUE;
- }
-
- hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
- Flags, MachineNameW, Reserved);
-
- MyFree(MachineNameW);
-
- return hKey;
-}
-
-
-/***********************************************************************
- * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExW(
- const GUID* ClassGuid,
- REGSAM samDesired,
- DWORD Flags,
- PCWSTR MachineName,
- PVOID Reserved)
-{
- HKEY HKLM;
- HKEY hClassesKey;
- HKEY key;
- LPCWSTR lpKeyName;
- LONG l;
-
- TRACE("%s 0x%lx 0x%lx %s %p\n", debugstr_guid(ClassGuid), samDesired,
- Flags, debugstr_w(MachineName), Reserved);
-
- if (MachineName != NULL)
- {
- l = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &HKLM);
- if (l != ERROR_SUCCESS)
- {
- SetLastError(l);
- return INVALID_HANDLE_VALUE;
- }
- }
- else
- HKLM = HKEY_LOCAL_MACHINE;
-
- if (Flags == DIOCR_INSTALLER)
- {
- lpKeyName = REGSTR_PATH_CLASS_NT;
- }
- else if (Flags == DIOCR_INTERFACE)
- {
- lpKeyName = REGSTR_PATH_DEVICE_CLASSES;
- }
- else
- {
- ERR("Invalid Flags parameter!\n");
- SetLastError(ERROR_INVALID_FLAGS);
- if (MachineName != NULL) RegCloseKey(HKLM);
- return INVALID_HANDLE_VALUE;
- }
-
- if (!ClassGuid)
- {
- if ((l = RegOpenKeyExW(HKLM,
- lpKeyName,
- 0,
- samDesired,
- &hClassesKey)))
- {
- SetLastError(ERROR_INVALID_CLASS);
- hClassesKey = INVALID_HANDLE_VALUE;
- }
- if (MachineName != NULL)
- RegCloseKey(HKLM);
- key = hClassesKey;
- }
- else
- {
- WCHAR bracedGuidString[39];
-
- SETUPDI_GuidToString(ClassGuid, bracedGuidString);
-
- if (!(l = RegOpenKeyExW(HKLM,
- lpKeyName,
- 0,
- samDesired,
- &hClassesKey)))
- {
- if (MachineName != NULL)
- RegCloseKey(HKLM);
-
- if ((l = RegOpenKeyExW(hClassesKey,
- bracedGuidString,
- 0,
- samDesired,
- &key)))
- {
- SetLastError(l);
- key = INVALID_HANDLE_VALUE;
- }
- RegCloseKey(hClassesKey);
- }
- else
- {
- if (MachineName != NULL) RegCloseKey(HKLM);
- SetLastError(l);
- key = INVALID_HANDLE_VALUE;
- }
- }
-
- return key;
-}
-
-/***********************************************************************
- * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceW(
- HDEVINFO DeviceInfoSet,
- PCWSTR DevicePath,
- DWORD OpenFlags,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
- 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;
-}
-
-/***********************************************************************
- * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceA(
- HDEVINFO DeviceInfoSet,
- PCSTR DevicePath,
- DWORD OpenFlags,
- PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
- LPWSTR DevicePathW = NULL;
- BOOL bResult;
-
- TRACE("%p %s %08lx %p\n", DeviceInfoSet, debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
-
- DevicePathW = pSetupMultiByteToUnicode(DevicePath, CP_ACP);
- if (DevicePathW == NULL)
- return FALSE;
-
- bResult = SetupDiOpenDeviceInterfaceW(DeviceInfoSet,
- DevicePathW, OpenFlags, DeviceInterfaceData);
-
- MyFree(DevicePathW);
-
- return bResult;
-}
-
-/***********************************************************************
- * SetupDiSetClassInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetClassInstallParamsA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- PSP_CLASSINSTALL_HEADER ClassInstallParams,
- DWORD ClassInstallParamsSize)
-{
- FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
- ClassInstallParams->InstallFunction, ClassInstallParamsSize);
- return FALSE;
-}
-
-static BOOL WINAPI
-IntSetupDiRegisterDeviceInfo(
- IN HDEVINFO DeviceInfoSet,
- IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
- return SetupDiRegisterDeviceInfo(DeviceInfoSet, DeviceInfoData, 0, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- * SetupDiCallClassInstaller (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCallClassInstaller(
- DI_FUNCTION InstallFunction,
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData)
-{
- BOOL ret = FALSE;
-
- TRACE("%u %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (((struct DeviceInfoSet *)DeviceInfoSet)->HKLM != HKEY_LOCAL_MACHINE)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- SP_DEVINSTALL_PARAMS_W InstallParams;
-#define CLASS_COINSTALLER 0x1
-#define DEVICE_COINSTALLER 0x2
-#define CLASS_INSTALLER 0x4
- UCHAR CanHandle = 0;
- DEFAULT_CLASS_INSTALL_PROC DefaultHandler = NULL;
-
- switch (InstallFunction)
- {
- case DIF_ADDPROPERTYPAGE_ADVANCED:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_ADDREMOTEPROPERTYPAGE_ADVANCED:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_ALLOW_INSTALL:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_DETECT:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_DESTROYPRIVATEDATA:
- CanHandle = CLASS_INSTALLER;
- break;
- case DIF_INSTALLDEVICE:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiInstallDevice;
- break;
- case DIF_INSTALLDEVICEFILES:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiInstallDriverFiles;
- break;
- case DIF_INSTALLINTERFACES:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiInstallDeviceInterfaces;
- break;
- case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_NEWDEVICEWIZARD_POSTANALYZE:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_NEWDEVICEWIZARD_PREANALYZE:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_NEWDEVICEWIZARD_PRESELECT:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_NEWDEVICEWIZARD_SELECT:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_POWERMESSAGEWAKE:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_PROPERTYCHANGE:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiChangeState;
- break;
- case DIF_REGISTER_COINSTALLERS:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiRegisterCoDeviceInstallers;
- break;
- case DIF_REGISTERDEVICE:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = IntSetupDiRegisterDeviceInfo;
- break;
- case DIF_REMOVE:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiRemoveDevice;
- break;
- case DIF_SELECTBESTCOMPATDRV:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiSelectBestCompatDrv;
- break;
- case DIF_SELECTDEVICE:
- CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiSelectDevice;
- break;
- case DIF_TROUBLESHOOTER:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- break;
- case DIF_UNREMOVE:
- CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
- DefaultHandler = SetupDiUnremoveDevice;
- break;
- default:
- ERR("Install function %u not supported\n", InstallFunction);
- SetLastError(ERROR_NOT_SUPPORTED);
- }
-
- InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams))
- /* Don't process this call, as a parameter is invalid */
- CanHandle = 0;
-
- if (CanHandle != 0)
- {
- LIST_ENTRY ClassCoInstallersListHead;
- LIST_ENTRY DeviceCoInstallersListHead;
- HMODULE ClassInstallerLibrary = NULL;
- CLASS_INSTALL_PROC ClassInstaller = NULL;
- COINSTALLER_CONTEXT_DATA Context;
- PLIST_ENTRY ListEntry;
- HKEY hKey;
- DWORD dwRegType, dwLength;
- DWORD rc = NO_ERROR;
-
- InitializeListHead(&ClassCoInstallersListHead);
- InitializeListHead(&DeviceCoInstallersListHead);
-
- if (CanHandle & DEVICE_COINSTALLER)
- {
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
- if (hKey != INVALID_HANDLE_VALUE)
- {
- rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, &dwRegType, NULL, &dwLength);
- if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
- {
- LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
- if (KeyBuffer != NULL)
- {
- rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
- if (rc == ERROR_SUCCESS)
- {
- LPWSTR ptr;
- for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
- {
- /* Add coinstaller to DeviceCoInstallersListHead list */
- struct CoInstallerElement *coinstaller;
- TRACE("Got device coinstaller '%s'\n", debugstr_w(ptr));
- coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
- if (!coinstaller)
- continue;
- ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
- if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
- InsertTailList(&DeviceCoInstallersListHead, &coinstaller->ListEntry);
- else
- HeapFree(GetProcessHeap(), 0, coinstaller);
- }
- }
- HeapFree(GetProcessHeap(), 0, KeyBuffer);
- }
- }
- RegCloseKey(hKey);
- }
- }
- if (CanHandle & CLASS_COINSTALLER)
- {
- rc = RegOpenKeyExW(
- HKEY_LOCAL_MACHINE,
- REGSTR_PATH_CODEVICEINSTALLERS,
- 0, /* Options */
- KEY_QUERY_VALUE,
- &hKey);
- if (rc == ERROR_SUCCESS)
- {
- LPWSTR lpGuidString;
- if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) == RPC_S_OK)
- {
- rc = RegQueryValueExW(hKey, lpGuidString, NULL, &dwRegType, NULL, &dwLength);
- if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
- {
- LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
- if (KeyBuffer != NULL)
- {
- rc = RegQueryValueExW(hKey, lpGuidString, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
- if (rc == ERROR_SUCCESS)
- {
- LPWSTR ptr;
- for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
- {
- /* Add coinstaller to ClassCoInstallersListHead list */
- struct CoInstallerElement *coinstaller;
- TRACE("Got class coinstaller '%s'\n", debugstr_w(ptr));
- coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
- if (!coinstaller)
- continue;
- ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
- if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
- InsertTailList(&ClassCoInstallersListHead, &coinstaller->ListEntry);
- else
- HeapFree(GetProcessHeap(), 0, coinstaller);
- }
- }
- HeapFree(GetProcessHeap(), 0, KeyBuffer);
- }
- }
- RpcStringFreeW(&lpGuidString);
- }
- RegCloseKey(hKey);
- }
- }
- if ((CanHandle & CLASS_INSTALLER) && !(InstallParams.FlagsEx & DI_FLAGSEX_CI_FAILED))
- {
- hKey = SetupDiOpenClassRegKey(&DeviceInfoData->ClassGuid, KEY_QUERY_VALUE);
- if (hKey != INVALID_HANDLE_VALUE)
- {
- rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
- if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
- {
- LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
- if (KeyBuffer != NULL)
- {
- rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
- if (rc == ERROR_SUCCESS)
- {
- /* Get ClassInstaller function pointer */
- TRACE("Got class installer '%s'\n", debugstr_w(KeyBuffer));
- if (GetFunctionPointer(KeyBuffer, &ClassInstallerLibrary, (PVOID*)&ClassInstaller) != ERROR_SUCCESS)
- {
- InstallParams.FlagsEx |= DI_FLAGSEX_CI_FAILED;
- SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
- }
- }
- HeapFree(GetProcessHeap(), 0, KeyBuffer);
- }
- }
- RegCloseKey(hKey);
- }
- }
-
- /* Call Class co-installers */
- Context.PostProcessing = FALSE;
- rc = NO_ERROR;
- ListEntry = ClassCoInstallersListHead.Flink;
- while (rc == NO_ERROR && ListEntry != &ClassCoInstallersListHead)
- {
- struct CoInstallerElement *coinstaller;
- coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
- rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
- coinstaller->PrivateData = Context.PrivateData;
- if (rc == ERROR_DI_POSTPROCESSING_REQUIRED)
- {
- coinstaller->DoPostProcessing = TRUE;
- rc = NO_ERROR;
- }
- ListEntry = ListEntry->Flink;
- }
-
- /* Call Device co-installers */
- ListEntry = DeviceCoInstallersListHead.Flink;
- while (rc == NO_ERROR && ListEntry != &DeviceCoInstallersListHead)
- {
- struct CoInstallerElement *coinstaller;
- coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
- rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
- coinstaller->PrivateData = Context.PrivateData;
- if (rc == ERROR_DI_POSTPROCESSING_REQUIRED)
- {
- coinstaller->DoPostProcessing = TRUE;
- rc = NO_ERROR;
- }
- ListEntry = ListEntry->Flink;
- }
-
- /* Call Class installer */
- if (ClassInstaller)
- {
- rc = (*ClassInstaller)(InstallFunction, DeviceInfoSet, DeviceInfoData);
- FreeFunctionPointer(ClassInstallerLibrary, ClassInstaller);
- }
- else
- rc = ERROR_DI_DO_DEFAULT;
-
- /* Call default handler */
- if (rc == ERROR_DI_DO_DEFAULT)
- {
- if (DefaultHandler && !(InstallParams.Flags & DI_NODI_DEFAULTACTION))
- {
- if ((*DefaultHandler)(DeviceInfoSet, DeviceInfoData))
- rc = NO_ERROR;
- else
- rc = GetLastError();
- }
- else
- rc = NO_ERROR;
- }
-
- /* Call Class co-installers that required postprocessing */
- Context.PostProcessing = TRUE;
- ListEntry = ClassCoInstallersListHead.Flink;
- while (ListEntry != &ClassCoInstallersListHead)
- {
- struct CoInstallerElement *coinstaller;
- coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
- if (coinstaller->DoPostProcessing)
- {
- Context.InstallResult = rc;
- Context.PrivateData = coinstaller->PrivateData;
- rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
- }
- FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
- ListEntry = ListEntry->Flink;
- }
-
- /* Call Device co-installers that required postprocessing */
- ListEntry = DeviceCoInstallersListHead.Flink;
- while (ListEntry != &DeviceCoInstallersListHead)
- {
- struct CoInstallerElement *coinstaller;
- coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
- if (coinstaller->DoPostProcessing)
- {
- Context.InstallResult = rc;
- Context.PrivateData = coinstaller->PrivateData;
- rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
- }
- FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
- ListEntry = ListEntry->Flink;
- }
-
- /* Free allocated memory */
- while (!IsListEmpty(&ClassCoInstallersListHead))
- {
- ListEntry = RemoveHeadList(&ClassCoInstallersListHead);
- HeapFree(GetProcessHeap(), 0, CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry));
- }
- while (!IsListEmpty(&DeviceCoInstallersListHead))
- {
- ListEntry = RemoveHeadList(&DeviceCoInstallersListHead);
- HeapFree(GetProcessHeap(), 0, CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry));
- }
-
- ret = (rc == NO_ERROR);
- }
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstallParamsA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
-{
- SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
- BOOL ret = FALSE;
-
- TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
- if (DeviceInstallParams == NULL)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- ret = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &deviceInstallParamsW);
-
- if (ret)
- {
- /* Do W->A conversion */
- memcpy(
- DeviceInstallParams,
- &deviceInstallParamsW,
- FIELD_OFFSET(SP_DEVINSTALL_PARAMS_W, DriverPath));
- if (WideCharToMultiByte(CP_ACP, 0, deviceInstallParamsW.DriverPath, -1,
- DeviceInstallParams->DriverPath, MAX_PATH, NULL, NULL) == 0)
- {
- DeviceInstallParams->DriverPath[0] = '\0';
- ret = FALSE;
- }
- }
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInfoListClass (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetDeviceInfoListClass(
- IN HDEVINFO DeviceInfoSet,
- OUT LPGUID ClassGuid)
-{
- struct DeviceInfoSet *list;
- BOOL ret = FALSE;
-
- TRACE("%p %p\n", DeviceInfoSet, ClassGuid);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
- SetLastError(ERROR_NO_ASSOCIATED_CLASS);
- else
- {
- memcpy(&ClassGuid, &list->ClassGuid, sizeof(GUID));
-
- ret = TRUE;
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiGetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetDeviceInstallParamsW(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
- OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
- struct DeviceInfoSet *list;
- BOOL ret = FALSE;
-
- TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (!DeviceInstallParams)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- PSP_DEVINSTALL_PARAMS_W Source;
-
- if (DeviceInfoData)
- Source = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
- else
- Source = &list->InstallParams;
-
- ret = TRUE;
-
- _SEH2_TRY
- {
- memcpy(DeviceInstallParams, Source, Source->cbSize);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastError(RtlNtStatusToDosError(_SEH2_GetExceptionCode()));
- ret = FALSE;
- }
- _SEH2_END;
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-static BOOL
-CheckDeviceInstallParameters(
- IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
- DWORD SupportedFlags =
- DI_NOVCP | /* 0x00000008 */
- DI_DIDCOMPAT | /* 0x00000010 */
- DI_DIDCLASS | /* 0x00000020 */
- DI_NEEDRESTART | /* 0x00000080 */
- DI_NEEDREBOOT | /* 0x00000100 */
- DI_RESOURCEPAGE_ADDED | /* 0x00002000 */
- DI_PROPERTIES_CHANGE | /* 0x00004000 */
- DI_ENUMSINGLEINF | /* 0x00010000 */
- DI_DONOTCALLCONFIGMG | /* 0x00020000 */
- DI_CLASSINSTALLPARAMS | /* 0x00100000 */
- DI_NODI_DEFAULTACTION | /* 0x00200000 */
- DI_QUIETINSTALL | /* 0x00800000 */
- DI_NOFILECOPY | /* 0x01000000 */
- DI_DRIVERPAGE_ADDED; /* 0x04000000 */
- DWORD SupportedFlagsEx =
- DI_FLAGSEX_CI_FAILED | /* 0x00000004 */
- DI_FLAGSEX_DIDINFOLIST | /* 0x00000010 */
- DI_FLAGSEX_DIDCOMPATINFO | /* 0x00000020 */
- DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
- DI_FLAGSEX_NO_DRVREG_MODIFY | /* 0x00008000 */
- DI_FLAGSEX_INSTALLEDDRIVER; /* 0x04000000 */
- BOOL ret = FALSE;
-
- /* FIXME: add support for more flags */
-
- /* FIXME: DI_CLASSINSTALLPARAMS flag is not correctly used.
- * It should be checked before accessing to other values
- * of the SP_DEVINSTALL_PARAMS structure */
-
- if (DeviceInstallParams->Flags & ~SupportedFlags)
- {
- FIXME("Unknown Flags: 0x%08lx\n", DeviceInstallParams->Flags & ~SupportedFlags);
- SetLastError(ERROR_INVALID_FLAGS);
- }
- else if (DeviceInstallParams->FlagsEx & ~SupportedFlagsEx)
- {
- FIXME("Unknown FlagsEx: 0x%08lx\n", DeviceInstallParams->FlagsEx & ~SupportedFlagsEx);
- SetLastError(ERROR_INVALID_FLAGS);
- }
- else if ((DeviceInstallParams->Flags & DI_NOVCP)
- && (DeviceInstallParams->FileQueue == NULL || DeviceInstallParams->FileQueue == (HSPFILEQ)INVALID_HANDLE_VALUE))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- /* FIXME: check Reserved field */
- ret = TRUE;
- }
-
- return ret;
-}
-
-/***********************************************************************
- * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetDeviceInstallParamsW(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
- IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
- struct DeviceInfoSet *list;
- BOOL ret = FALSE;
-
- TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (!DeviceInstallParams)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (CheckDeviceInstallParameters(DeviceInstallParams))
- {
- PSP_DEVINSTALL_PARAMS_W Destination;
-
- if (DeviceInfoData)
- Destination = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
- else
- Destination = &list->InstallParams;
- memcpy(Destination, DeviceInstallParams, DeviceInstallParams->cbSize);
- ret = TRUE;
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetDeviceInstallParamsA(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
-{
- SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
- int len = 0;
- BOOL ret = FALSE;
-
- TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
- if (DeviceInstallParams == NULL)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInstallParams->cbSize < sizeof(SP_DEVINSTALL_PARAMS_A))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- memcpy(&deviceInstallParamsW, DeviceInstallParams, FIELD_OFFSET(SP_DEVINSTALL_PARAMS_A, DriverPath));
- deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- len = MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, NULL, 0);
- if (!len)
- {
- ERR("DrivePath is NULL\n");
- ret = FALSE;
- }
- else
- {
- MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, deviceInstallParamsW.DriverPath, len);
- ret = SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &deviceInstallParamsW);
- }
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-static HKEY
-OpenHardwareProfileKey(
- IN HKEY HKLM,
- IN DWORD HwProfile,
- IN DWORD samDesired)
-{
- HKEY hHWProfilesKey = NULL;
- HKEY hHWProfileKey = NULL;
- HKEY ret = INVALID_HANDLE_VALUE;
- LONG rc;
-
- rc = RegOpenKeyExW(HKLM,
- REGSTR_PATH_HWPROFILES,
- 0,
- READ_CONTROL,
- &hHWProfilesKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- if (HwProfile == 0)
- {
- rc = RegOpenKeyExW(hHWProfilesKey,
- REGSTR_KEY_CURRENT,
- 0,
- KEY_CREATE_SUB_KEY,
- &hHWProfileKey);
- }
- else
- {
- WCHAR subKey[5];
- snprintfW(subKey, 4, InstanceKeyFormat, HwProfile);
- subKey[4] = '\0';
- rc = RegOpenKeyExW(hHWProfilesKey,
- subKey,
- 0,
- KEY_CREATE_SUB_KEY,
- &hHWProfileKey);
- }
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- ret = hHWProfileKey;
-
-cleanup:
- if (hHWProfilesKey != NULL)
- RegCloseKey(hHWProfilesKey);
- if (hHWProfileKey != NULL && hHWProfileKey != ret)
- RegCloseKey(hHWProfileKey);
- return ret;
-}
-
-static BOOL
-IsDeviceInfoInDeviceInfoSet(
- struct DeviceInfoSet *deviceInfoSet,
- struct DeviceInfo *deviceInfo)
-{
- PLIST_ENTRY ListEntry;
-
- ListEntry = deviceInfoSet->ListHead.Flink;
- while (ListEntry != &deviceInfoSet->ListHead)
- {
- if (deviceInfo == CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry))
- return TRUE;
-
- ListEntry = ListEntry->Flink;
- }
-
- return FALSE;
-}
-
-/***********************************************************************
- * SetupDiDeleteDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiDeleteDeviceInfo(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *deviceInfoSet;
- struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData;
- BOOL ret = FALSE;
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((deviceInfoSet = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (!IsDeviceInfoInDeviceInfoSet(deviceInfoSet, deviceInfo))
- SetLastError(ERROR_INVALID_PARAMETER);
- else
- {
- RemoveEntryList(&deviceInfo->ListEntry);
- DestroyDeviceInfo(deviceInfo);
- ret = TRUE;
- }
-
- return ret;
-}
-
-
-/***********************************************************************
- * SetupDiOpenDeviceInfoA (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiOpenDeviceInfoA(
- IN HDEVINFO DeviceInfoSet,
- IN PCSTR DeviceInstanceId,
- IN HWND hwndParent OPTIONAL,
- IN DWORD OpenFlags,
- OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
-{
- LPWSTR DeviceInstanceIdW = NULL;
- BOOL bResult;
-
- TRACE("%p %s %p %lx %p\n", DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData);
-
- DeviceInstanceIdW = pSetupMultiByteToUnicode(DeviceInstanceId, CP_ACP);
- if (DeviceInstanceIdW == NULL)
- return FALSE;
-
- bResult = SetupDiOpenDeviceInfoW(DeviceInfoSet,
- DeviceInstanceIdW, hwndParent, OpenFlags, DeviceInfoData);
-
- MyFree(DeviceInstanceIdW);
-
- return bResult;
-}
-
-
-/***********************************************************************
- * SetupDiOpenDeviceInfoW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiOpenDeviceInfoW(
- IN HDEVINFO DeviceInfoSet,
- IN PCWSTR DeviceInstanceId,
- IN HWND hwndParent OPTIONAL,
- IN DWORD OpenFlags,
- OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
-{
- struct DeviceInfoSet *list;
- HKEY hEnumKey, hKey = NULL;
- DWORD rc, dwSize;
- BOOL ret = FALSE;
-
- TRACE("%p %s %p %lx %p\n",
- DeviceInfoSet, debugstr_w(DeviceInstanceId),
- hwndParent, OpenFlags, DeviceInfoData);
-
- if (OpenFlags & DIOD_CANCEL_REMOVE)
- FIXME("DIOD_CANCEL_REMOVE flag not implemented\n");
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (!DeviceInstanceId)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS))
- {
- TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS));
- SetLastError(ERROR_INVALID_FLAGS);
- }
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- struct DeviceInfo *deviceInfo = NULL;
- /* Search if device already exists in DeviceInfoSet.
- * If yes, return the existing element
- * If no, create a new element using information in registry
- */
- PLIST_ENTRY ItemList = list->ListHead.Flink;
- while (ItemList != &list->ListHead)
- {
- deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
- if (!wcscmp(deviceInfo->instanceId, DeviceInstanceId))
- break;
- deviceInfo = NULL;
- ItemList = ItemList->Flink;
- }
-
- if (deviceInfo)
- {
- /* good one found */
- ret = TRUE;
- }
- else
- {
- GUID ClassGUID;
- WCHAR szClassGuid[MAX_GUID_STRING_LEN];
-
- /* Open supposed registry key */
- rc = RegOpenKeyExW(
- list->HKLM,
- REGSTR_PATH_SYSTEMENUM,
- 0, /* Options */
- READ_CONTROL,
- &hEnumKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- rc = RegOpenKeyExW(
- hEnumKey,
- DeviceInstanceId,
- 0, /* Options */
- KEY_QUERY_VALUE,
- &hKey);
- RegCloseKey(hEnumKey);
- if (rc != ERROR_SUCCESS)
- {
- if (rc == ERROR_FILE_NOT_FOUND)
- rc = ERROR_NO_SUCH_DEVINST;
- SetLastError(rc);
- goto cleanup;
- }
-
- ClassGUID = GUID_NULL;
- dwSize = MAX_GUID_STRING_LEN * sizeof(WCHAR);
-
- if (RegQueryValueExW(hKey,
- REGSTR_VAL_CLASSGUID,
- NULL,
- NULL,
- (LPBYTE)szClassGuid,
- &dwSize) == ERROR_SUCCESS)
- {
- szClassGuid[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
-
- /* Convert a string to a ClassGuid */
- UuidFromStringW(&szClassGuid[1], &ClassGUID);
- }
-
- if (!CreateDeviceInfo(list, DeviceInstanceId, &ClassGUID, &deviceInfo))
- goto cleanup;
-
- InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
-
- ret = TRUE;
- }
-
- if (ret && deviceInfo && DeviceInfoData)
- {
- memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = deviceInfo->dnDevInst;
- DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
- }
- }
-
-cleanup:
- if (hKey != NULL)
- RegCloseKey(hKey);
- return ret;
-}
-
-
-/***********************************************************************
- * SetupDiGetSelectedDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetSelectedDevice(
- IN HDEVINFO DeviceInfoSet,
- OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *list;
- BOOL ret = FALSE;
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (list->SelectedDevice == NULL)
- SetLastError(ERROR_NO_DEVICE_SELECTED);
- else if (!DeviceInfoData)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- memcpy(&DeviceInfoData->ClassGuid,
- &list->SelectedDevice->ClassGuid,
- sizeof(GUID));
- DeviceInfoData->DevInst = list->SelectedDevice->dnDevInst;
- DeviceInfoData->Reserved = (ULONG_PTR)list->SelectedDevice;
- ret = TRUE;
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-
-/***********************************************************************
- * SetupDiSetSelectedDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetSelectedDevice(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData)
-{
- struct DeviceInfoSet *list;
- BOOL ret = FALSE;
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_HANDLE);
- else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (!DeviceInfoData)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (DeviceInfoData->Reserved == 0)
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- list->SelectedDevice = (struct DeviceInfo *)DeviceInfoData->Reserved;
- ret = TRUE;
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-
-/* Return the current hardware profile id, or -1 if error */
-static DWORD
-SETUPAPI_GetCurrentHwProfile(
- IN HDEVINFO DeviceInfoSet)
-{
- HKEY hKey = NULL;
- DWORD dwRegType, dwLength;
- DWORD hwProfile;
- LONG rc;
- DWORD ret = (DWORD)-1;
-
- rc = RegOpenKeyExW(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
- REGSTR_PATH_IDCONFIGDB,
- 0, /* Options */
- KEY_QUERY_VALUE,
- &hKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- dwLength = sizeof(DWORD);
- rc = RegQueryValueExW(hKey,
- REGSTR_VAL_CURRENTCONFIG,
- NULL,
- &dwRegType,
- (LPBYTE)&hwProfile, &dwLength);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- ret = hwProfile;
-
-cleanup:
- if (hKey != NULL)
- RegCloseKey(hKey);
-
- return ret;
-}
-
-static BOOL
-ResetDevice(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData)
-{
-#ifndef __WINESRC__
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- CONFIGRET cr;
-
- cr = CM_Enable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
- if (cr != CR_SUCCESS)
- {
- SetLastError(GetErrorCodeFromCrCode(cr));
- return FALSE;
- }
-
- return TRUE;
-#else
- FIXME("Stub: ResetDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
- return TRUE;
-#endif
-}
-
-static BOOL StopDevice(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData)
-{
- FIXME("Stub: StopDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiChangeState (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiChangeState(
- IN HDEVINFO DeviceInfoSet,
- IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
- PSP_PROPCHANGE_PARAMS PropChange;
- HKEY hKey = INVALID_HANDLE_VALUE;
- LPCWSTR RegistryValueName;
- DWORD dwConfigFlags, dwLength, dwRegType;
- LONG rc;
- BOOL ret = FALSE;
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoData)
- PropChange = ((struct DeviceInfoSet *)DeviceInfoSet)->ClassInstallParams.PropChangeParams;
- else
- PropChange = ((struct DeviceInfo *)DeviceInfoData->Reserved)->ClassInstallParams.PropChangeParams;
- if (!PropChange)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto cleanup;
- }
-
- if (PropChange->Scope == DICS_FLAG_GLOBAL)
- RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
- else
- RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
-
- switch (PropChange->StateChange)
- {
- case DICS_ENABLE:
- case DICS_DISABLE:
- {
- /* Enable/disable device in registry */
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
- if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
- hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, NULL, NULL);
- if (hKey == INVALID_HANDLE_VALUE)
- break;
- dwLength = sizeof(DWORD);
- rc = RegQueryValueExW(
- hKey,
- RegistryValueName,
- NULL,
- &dwRegType,
- (LPBYTE)&dwConfigFlags, &dwLength);
- if (rc == ERROR_FILE_NOT_FOUND)
- dwConfigFlags = 0;
- else if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
- if (PropChange->StateChange == DICS_ENABLE)
- dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
- else
- dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
- rc = RegSetValueExW(
- hKey,
- RegistryValueName,
- 0,
- REG_DWORD,
- (LPBYTE)&dwConfigFlags, sizeof(DWORD));
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- /* Enable/disable device if needed */
- if (PropChange->Scope == DICS_FLAG_GLOBAL
- || PropChange->HwProfile == 0
- || PropChange->HwProfile == SETUPAPI_GetCurrentHwProfile(DeviceInfoSet))
- {
- if (PropChange->StateChange == DICS_ENABLE)
- ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
- else
- ret = StopDevice(DeviceInfoSet, DeviceInfoData);
- }
- else
- ret = TRUE;
- break;
- }
- case DICS_PROPCHANGE:
- {
- ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
- break;
- }
- default:
- {
- ERR("Unknown StateChange 0x%lx\n", PropChange->StateChange);
- SetLastError(ERROR_NOT_SUPPORTED);
- }
- }
-
-cleanup:
- if (hKey != INVALID_HANDLE_VALUE)
- RegCloseKey(hKey);
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-/***********************************************************************
- * SetupDiSelectDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSelectDevice(
- IN HDEVINFO DeviceInfoSet,
- IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
-{
- FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-
-/***********************************************************************
- * SetupDiRegisterCoDeviceInstallers (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiRegisterCoDeviceInstallers(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData)
-{
- BOOL ret = FALSE; /* Return value */
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (!DeviceInfoData)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- {
- SP_DEVINSTALL_PARAMS_W InstallParams;
- struct DriverInfoElement *SelectedDriver;
- BOOL Result;
- DWORD DoAction;
- WCHAR SectionName[MAX_PATH];
- DWORD SectionNameLength = 0;
- HKEY hKey = INVALID_HANDLE_VALUE;
- PVOID Context = NULL;
-
- InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
- if (!Result)
- goto cleanup;
-
- SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
- if (SelectedDriver == NULL)
- {
- SetLastError(ERROR_NO_DRIVER_SELECTED);
- goto cleanup;
- }
-
- /* Get .CoInstallers section name */
- Result = SetupDiGetActualSectionToInstallW(
- SelectedDriver->InfFileDetails->hInf,
- SelectedDriver->Details.SectionName,
- SectionName, MAX_PATH, &SectionNameLength, NULL);
- if (!Result || SectionNameLength > MAX_PATH - strlenW(DotCoInstallers) - 1)
- goto cleanup;
- lstrcatW(SectionName, DotCoInstallers);
-
- /* Open/Create driver key information */
-#if _WIN32_WINNT >= 0x502
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
-#else
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
-#endif
- if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
- hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
- if (hKey == INVALID_HANDLE_VALUE)
- goto cleanup;
-
- /* Install .CoInstallers section */
- DoAction = SPINST_REGISTRY;
- if (!(InstallParams.Flags & DI_NOFILECOPY))
- {
- DoAction |= SPINST_FILES;
- Context = SetupInitDefaultQueueCallback(InstallParams.hwndParent);
- if (!Context)
- goto cleanup;
- }
- Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
- SelectedDriver->InfFileDetails->hInf, SectionName,
- DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
- SetupDefaultQueueCallbackW, Context,
- DeviceInfoSet, DeviceInfoData);
- if (!Result)
- goto cleanup;
-
- ret = TRUE;
-
-cleanup:
- if (Context)
- SetupTermDefaultQueueCallback(Context);
- if (hKey != INVALID_HANDLE_VALUE)
- RegCloseKey(hKey);
- }
-
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-static BOOL
-InfIsFromOEMLocation(
- IN PCWSTR FullName,
- OUT LPBOOL IsOEMLocation)
-{
- PWCHAR last;
-
- last = strrchrW(FullName, '\\');
- if (!last)
- {
- /* No directory specified */
- *IsOEMLocation = FALSE;
- }
- else
- {
- LPWSTR Windir;
- UINT ret;
-
- Windir = MyMalloc((MAX_PATH + 1 + strlenW(InfDirectory)) * sizeof(WCHAR));
- if (!Windir)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- ret = GetSystemWindowsDirectoryW(Windir, MAX_PATH);
- if (ret == 0 || ret > MAX_PATH)
- {
- MyFree(Windir);
- SetLastError(ERROR_GEN_FAILURE);
- return FALSE;
- }
- if (*Windir && Windir[strlenW(Windir) - 1] != '\\')
- strcatW(Windir, BackSlash);
- strcatW(Windir, InfDirectory);
-
- if (strncmpiW(FullName, Windir, last - FullName) == 0)
- {
- /* The path is %SYSTEMROOT%\Inf */
- *IsOEMLocation = FALSE;
- }
- else
- {
- /* The file is in another place */
- *IsOEMLocation = TRUE;
- }
- MyFree(Windir);
- }
- return TRUE;
-}
-
-/***********************************************************************
- * SetupDiInstallDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiInstallDevice(
- IN HDEVINFO DeviceInfoSet,
- IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
- SP_DEVINSTALL_PARAMS_W InstallParams;
- struct DriverInfoElement *SelectedDriver;
- SYSTEMTIME DriverDate;
- WCHAR SectionName[MAX_PATH];
- WCHAR Buffer[32];
- DWORD SectionNameLength = 0;
- BOOL Result = FALSE;
- ULONG DoAction;
- DWORD RequiredSize;
- LPWSTR pSectionName = NULL;
- WCHAR ClassName[MAX_CLASS_NAME_LEN];
- GUID ClassGuid;
- LPWSTR lpGuidString = NULL, lpFullGuidString = NULL;
- BOOL RebootRequired = FALSE;
- HKEY hKey = INVALID_HANDLE_VALUE;
- BOOL NeedtoCopyFile;
- LARGE_INTEGER fullVersion;
- LONG rc;
- PVOID Context = NULL;
- BOOL ret = FALSE; /* Return value */
-
- TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
- if (!DeviceInfoSet)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- SetLastError(ERROR_INVALID_HANDLE);
- else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
- SetLastError(ERROR_INVALID_USER_BUFFER);
- else
- Result = TRUE;
-
- if (!Result)
- {
- /* One parameter is bad */
- goto cleanup;
- }
-
- InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
- Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
- if (!Result)
- goto cleanup;
-
- if (InstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL)
- {
- /* Set FAILEDINSTALL in ConfigFlags registry value */
- DWORD ConfigFlags, regType;
- Result = SetupDiGetDeviceRegistryPropertyW(
- DeviceInfoSet,
- DeviceInfoData,
- SPDRP_CONFIGFLAGS,
- ®Type,
- (PBYTE)&ConfigFlags,
- sizeof(ConfigFlags),
- NULL);
- if (!Result || regType != REG_DWORD)
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
- ConfigFlags |= DNF_DISABLED;
- Result = SetupDiSetDeviceRegistryPropertyW(
- DeviceInfoSet,
- DeviceInfoData,
- SPDRP_CONFIGFLAGS,
- (PBYTE)&ConfigFlags,
- sizeof(ConfigFlags));
- if (!Result)
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
-
- ret = TRUE;
- goto cleanup;
- }
-
- SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
- if (SelectedDriver == NULL)
- {
- SetLastError(ERROR_NO_DRIVER_SELECTED);
- goto cleanup;
- }
-
- FileTimeToSystemTime(&SelectedDriver->Info.DriverDate, &DriverDate);
-
- Result = SetupDiGetActualSectionToInstallW(
- SelectedDriver->InfFileDetails->hInf,
- SelectedDriver->Details.SectionName,
- SectionName, MAX_PATH, &SectionNameLength, NULL);
- if (!Result || SectionNameLength > MAX_PATH - strlenW(DotServices))
- goto cleanup;
- pSectionName = &SectionName[strlenW(SectionName)];
-
- /* Get information from [Version] section */
- if (!SetupDiGetINFClassW(SelectedDriver->Details.InfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
- goto cleanup;
- /* Format ClassGuid to a string */
- if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
- goto cleanup;
- RequiredSize = lstrlenW(lpGuidString);
- lpFullGuidString = HeapAlloc(GetProcessHeap(), 0, (RequiredSize + 3) * sizeof(WCHAR));
- if (!lpFullGuidString)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
- lpFullGuidString[0] = '{';
- memcpy(&lpFullGuidString[1], lpGuidString, RequiredSize * sizeof(WCHAR));
- lpFullGuidString[RequiredSize + 1] = '}';
- lpFullGuidString[RequiredSize + 2] = '\0';
-
- /* Copy .inf file to Inf\ directory (if needed) */
- Result = InfIsFromOEMLocation(SelectedDriver->Details.InfFileName, &NeedtoCopyFile);
- if (!Result)
- goto cleanup;
- if (NeedtoCopyFile)
- {
- WCHAR NewFileName[MAX_PATH];
- struct InfFileDetails *newInfFileDetails;
- Result = SetupCopyOEMInfW(
- SelectedDriver->Details.InfFileName,
- NULL,
- SPOST_NONE,
- SP_COPY_NOOVERWRITE,
- NewFileName, MAX_PATH,
- NULL,
- NULL);
- if (!Result && GetLastError() != ERROR_FILE_EXISTS)
- goto cleanup;
- /* Create a new struct InfFileDetails, and set it to
- * SelectedDriver->InfFileDetails, to release use of
- * current InfFile */
- newInfFileDetails = CreateInfFileDetails(NewFileName);
- if (!newInfFileDetails)
- goto cleanup;
- DereferenceInfFile(SelectedDriver->InfFileDetails);
- SelectedDriver->InfFileDetails = newInfFileDetails;
- strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
- }
-
- /* Open/Create driver key information */
-#if _WIN32_WINNT >= 0x502
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
-#else
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
-#endif
- if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
- hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
- if (hKey == INVALID_HANDLE_VALUE)
- goto cleanup;
-
- /* Install main section */
- DoAction = 0;
- if (!(InstallParams.FlagsEx & DI_FLAGSEX_NO_DRVREG_MODIFY))
- DoAction |= SPINST_REGISTRY;
- if (!(InstallParams.Flags & DI_NOFILECOPY))
- {
- DoAction |= SPINST_FILES;
- Context = SetupInitDefaultQueueCallback(InstallParams.hwndParent);
- if (!Context)
- goto cleanup;
- }
- *pSectionName = '\0';
- Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
- SelectedDriver->InfFileDetails->hInf, SectionName,
- DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
- SetupDefaultQueueCallbackW, Context,
- DeviceInfoSet, DeviceInfoData);
- if (!Result)
- goto cleanup;
- InstallParams.Flags |= DI_NOFILECOPY;
- SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
-
- /* Write information to driver key */
- *pSectionName = UNICODE_NULL;
- memcpy(&fullVersion, &SelectedDriver->Info.DriverVersion, sizeof(LARGE_INTEGER));
- TRACE("Write information to driver key\n");
- TRACE("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
- TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
- TRACE("DriverVersion : '%ld.%ld.%lu.%ld'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
- TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName));
- TRACE("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
- TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
- TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
- TRACE("ProviderName : '%s'\n", debugstr_w(SelectedDriver->Info.ProviderName));
- sprintfW(Buffer, DateFormat, DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
- rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE_DATA, 0, REG_BINARY, (const BYTE *)&SelectedDriver->Info.DriverDate, sizeof(FILETIME));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_DRVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- {
- sprintfW(Buffer, VersionFormat, fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
- rc = RegSetValueExW(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
- }
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->InfFileDetails->FileName, (strlenW(SelectedDriver->InfFileDetails->FileName) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTION, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.SectionName, (strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTIONEXT, 0, REG_SZ, (const BYTE *)&SectionName[strlenW(SelectedDriver->Details.SectionName)], (strlenW(SectionName) - strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_MATCHINGDEVID, 0, REG_SZ, (const BYTE *)SelectedDriver->MatchingId, (strlenW(SelectedDriver->MatchingId) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_PROVIDER_NAME, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.ProviderName, (strlenW(SelectedDriver->Info.ProviderName) + 1) * sizeof(WCHAR));
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- RegCloseKey(hKey);
- hKey = INVALID_HANDLE_VALUE;
-
- /* FIXME: Process .LogConfigOverride section */
-
- /* Install .Services section */
- strcpyW(pSectionName, DotServices);
- Result = SetupInstallServicesFromInfSectionExW(
- SelectedDriver->InfFileDetails->hInf,
- SectionName,
- 0,
- DeviceInfoSet,
- DeviceInfoData,
- NULL,
- NULL);
- if (!Result)
- goto cleanup;
- if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
- RebootRequired = TRUE;
-
- /* Open device registry key */
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
- if (hKey == INVALID_HANDLE_VALUE)
- goto cleanup;
-
- /* Install .HW section */
- DoAction = 0;
- if (!(InstallParams.FlagsEx & DI_FLAGSEX_NO_DRVREG_MODIFY))
- DoAction |= SPINST_REGISTRY;
- strcpyW(pSectionName, DotHW);
- Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
- SelectedDriver->InfFileDetails->hInf, SectionName,
- DoAction, hKey, NULL, 0,
- NULL, NULL,
- DeviceInfoSet, DeviceInfoData);
- if (!Result)
- goto cleanup;
-
- /* Write information to enum key */
- TRACE("Write information to enum key\n");
- TRACE("Class : '%s'\n", debugstr_w(ClassName));
- TRACE("ClassGUID : '%s'\n", debugstr_w(lpFullGuidString));
- TRACE("DeviceDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
- TRACE("Mfg : '%s'\n", debugstr_w(SelectedDriver->Info.MfgName));
- rc = RegSetValueExW(hKey, REGSTR_VAL_CLASS, 0, REG_SZ, (const BYTE *)ClassName, (strlenW(ClassName) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_CLASSGUID, 0, REG_SZ, (const BYTE *)lpFullGuidString, (strlenW(lpFullGuidString) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_DEVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueExW(hKey, REGSTR_VAL_MFG, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (strlenW(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
-
- /* Start the device */
- if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
- ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
- else
- ret = TRUE;
-
-cleanup:
- /* End of installation */
- if (hKey != INVALID_HANDLE_VALUE)
- RegCloseKey(hKey);
- if (lpGuidString)
- RpcStringFreeW(&lpGuidString);
- HeapFree(GetProcessHeap(), 0, lpFullGuidString);
- if (Context)
- SetupTermDefaultQueueCallback(Context);
- TRACE("Returning %d\n", ret);
- return ret;
-}
-
-static HKEY SETUPDI_OpenDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
-{
- HKEY enumKey, key = INVALID_HANDLE_VALUE;
- LONG l;
-
- l = RegOpenKeyExW(RootKey, REGSTR_PATH_SYSTEMENUM, 0, READ_CONTROL, &enumKey);
- if (!l)
- {
- l = RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key);
- RegCloseKey(enumKey);
- }
- if (l)
- SetLastError(l);
- return key;
-}
-
-static HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
-{
- LPWSTR DriverKey = NULL;
- DWORD dwLength = 0;
- DWORD dwRegType;
- DWORD rc;
- HKEY hEnumKey = NULL;
- HKEY hKey = NULL;
- HKEY key = INVALID_HANDLE_VALUE;
-
- hKey = SETUPDI_OpenDevKey(RootKey, devInfo, KEY_QUERY_VALUE);
- if (hKey == INVALID_HANDLE_VALUE)
- goto cleanup;
- /* Read the 'Driver' key */
- rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, NULL, &dwLength);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- else if (dwRegType != REG_SZ)
- {
- SetLastError(ERROR_GEN_FAILURE);
- goto cleanup;
- }
- DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
- if (!DriverKey)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
- rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- RegCloseKey(hKey);
- hKey = NULL;
- /* Need to open the driver key */
- rc = RegOpenKeyExW(
- RootKey,
- REGSTR_PATH_CLASS_NT,
- 0, /* Options */
- READ_CONTROL,
- &hEnumKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- rc = RegOpenKeyExW(
- hEnumKey,
- DriverKey,
- 0, /* Options */
- samDesired,
- &hKey);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- key = hKey;
-
-cleanup:
- if (hEnumKey != NULL)
- RegCloseKey(hEnumKey);
- if (hKey != NULL && hKey != key)
- RegCloseKey(hKey);
- if (DriverKey)
- HeapFree(GetProcessHeap(), 0, DriverKey);
- return key;
-}
-
-/***********************************************************************
- * SetupDiOpenDevRegKey (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenDevRegKey(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Scope,
- DWORD HwProfile,
- DWORD KeyType,
- REGSAM samDesired)
-{
- struct DeviceInfoSet *set = DeviceInfoSet;
- struct DeviceInfo *devInfo;
- HKEY key = INVALID_HANDLE_VALUE;
- HKEY RootKey;
-
- TRACE("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData,
- Scope, HwProfile, KeyType, samDesired);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return INVALID_HANDLE_VALUE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return INVALID_HANDLE_VALUE;
- }
- if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return INVALID_HANDLE_VALUE;
- }
- devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- if (devInfo->set != set)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return INVALID_HANDLE_VALUE;
- }
- if (Scope != DICS_FLAG_GLOBAL)
- {
- RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
- if (RootKey == INVALID_HANDLE_VALUE)
- return INVALID_HANDLE_VALUE;
- }
- else
- RootKey = set->HKLM;
- switch (KeyType)
- {
- case DIREG_DEV:
- key = SETUPDI_OpenDevKey(RootKey, devInfo, samDesired);
- break;
- case DIREG_DRV:
- key = SETUPDI_OpenDrvKey(RootKey, devInfo, samDesired);
- break;
- default:
- WARN("unknown KeyType %d\n", KeyType);
- }
- if (RootKey != set->HKLM)
- RegCloseKey(RootKey);
- return key;
-}
-
-static BOOL SETUPDI_DeleteDevKey(HKEY RootKey, struct DeviceInfo *devInfo)
-{
- FIXME("\n");
- return FALSE;
-}
-
-static BOOL SETUPDI_DeleteDrvKey(HKEY RootKey, struct DeviceInfo *devInfo)
-{
- FIXME("\n");
- return FALSE;
-}
-
-/***********************************************************************
- * SetupDiDeleteDevRegKey (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiDeleteDevRegKey(
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData,
- DWORD Scope,
- DWORD HwProfile,
- DWORD KeyType)
-{
- struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
- struct DeviceInfo *devInfo;
- BOOL ret = FALSE;
- HKEY RootKey;
-
- TRACE("%p %p %d %d %d\n", DeviceInfoSet, DeviceInfoData, Scope, HwProfile,
- KeyType);
-
- if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
- || !DeviceInfoData->Reserved)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return FALSE;
- }
- if (KeyType != DIREG_DEV && KeyType != DIREG_DRV && KeyType != DIREG_BOTH)
- {
- SetLastError(ERROR_INVALID_FLAGS);
- return FALSE;
- }
- devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- if (devInfo->set != set)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- if (Scope != DICS_FLAG_GLOBAL)
- {
- RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
- if (RootKey == INVALID_HANDLE_VALUE)
- return FALSE;
- }
- else
- RootKey = set->HKLM;
- switch (KeyType)
- {
- case DIREG_DEV:
- ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
- break;
- case DIREG_DRV:
- ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
- break;
- case DIREG_BOTH:
- ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
- if (ret)
- ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
- break;
- default:
- WARN("unknown KeyType %d\n", KeyType);
- }
- if (RootKey != set->HKLM)
- RegCloseKey(RootKey);
- return ret;
-}