/* Unicode constants */
static const WCHAR BackSlash[] = {'\\',0};
-static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
-static const WCHAR Class[] = {'C','l','a','s','s',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};
if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
{
/* That's the first time we go here. We need to fill in the structure */
- OSVERSIONINFOEX VersionInfo;
SYSTEM_INFO SystemInfo;
- VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- ret = GetVersionExW((OSVERSIONINFO*)&VersionInfo);
- if (!ret)
- goto done;
GetSystemInfo(&SystemInfo);
CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
- CurrentPlatform.Platform = VersionInfo.dwPlatformId;
- CurrentPlatform.MajorVersion = VersionInfo.dwMajorVersion;
- CurrentPlatform.MinorVersion = VersionInfo.dwMinorVersion;
+ CurrentPlatform.Platform = OsVersionInfo.dwPlatformId;
+ CurrentPlatform.MajorVersion = OsVersionInfo.dwMajorVersion;
+ CurrentPlatform.MinorVersion = OsVersionInfo.dwMinorVersion;
CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
CurrentPlatform.Reserved = 0;
- CurrentProductType = VersionInfo.wProductType;
- CurrentSuiteMask = VersionInfo.wSuiteMask;
+ CurrentProductType = OsVersionInfo.wProductType;
+ CurrentSuiteMask = OsVersionInfo.wSuiteMask;
}
ProductType = CurrentProductType;
SuiteMask = CurrentSuiteMask;
CallbackInfo.BestScore4 = ULONG_MAX;
CallbackInfo.BestScore5 = ULONG_MAX;
strcpyW(CallbackInfo.BestSection, InfSectionName);
+ TRACE("EnumerateSectionsStartingWith(InfSectionName = %S)\n", InfSectionName);
if (!EnumerateSectionsStartingWith(
InfHandle,
InfSectionName,
SetLastError(ERROR_GEN_FAILURE);
goto done;
}
+ TRACE("CallbackInfo.BestSection = %S\n", CallbackInfo.BestSection);
dwFullLength = lstrlenW(CallbackInfo.BestSection);
if (RequiredSize != NULL)
* SetupDiBuildClassInfoListExA (SETUPAPI.@)
*
* Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote macine.
+ * that are installed on a local or remote machine.
*
* PARAMS
* Flags [I] control exclusion of classes from the list.
* SetupDiBuildClassInfoListExW (SETUPAPI.@)
*
* Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote macine.
+ * that are installed on a local or remote machine.
*
* PARAMS
* Flags [I] control exclusion of classes from the list.
dwLength = MAX_CLASS_NAME_LEN * sizeof(WCHAR);
if (!RegQueryValueExW(hClassKey,
- Class,
+ REGSTR_VAL_CLASS,
NULL,
NULL,
(LPBYTE)szClassName,
return FALSE;
/* Retrieve the class name data and close the key */
- rc = QueryRegistryValue(hKey, Class, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
+ rc = QueryRegistryValue(hKey, REGSTR_VAL_CLASS, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
RegCloseKey(hKey);
/* Make sure we got the data */
* Create an empty DeviceInfoSet list.
*
* PARAMS
- * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
+ * 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
PCWSTR InfSectionName)
{
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *deviceInfo;
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;
return INVALID_HANDLE_VALUE;
}
+ deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
if (Scope == DICS_FLAG_GLOBAL)
RootKey = set->HKLM;
else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
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,
+ hKey = SETUPDI_CreateDevKey(RootKey, deviceInfo, KEY_READ | KEY_WRITE);
#else
- KEY_ALL_ACCESS,
+ hKey = SETUPDI_CreateDevKey(RootKey, deviceInfo, 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);
+ if (hKey == INVALID_HANDLE_VALUE)
goto cleanup;
- }
- rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, NULL, &dwSize);
- if (rc != ERROR_SUCCESS)
+ if (Scope == DICS_FLAG_GLOBAL)
{
- /* 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++ = '\\';
+ HKEY hTempKey = hKey;
- /* 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,
+ rc = RegCreateKeyExW(hTempKey,
+ L"Device Parameters",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
#if _WIN32_WINNT >= 0x502
- KEY_READ | KEY_WRITE,
+ KEY_READ | KEY_WRITE,
#else
- KEY_ALL_ACCESS,
+ 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;
- }
-
+ NULL,
+ &hKey,
+ NULL);
+ if (rc == ERROR_SUCCESS)
+ RegCloseKey(hTempKey);
}
- 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,
+ }
+ else /* KeyType == DIREG_DRV */
+ {
#if _WIN32_WINNT >= 0x502
- KEY_READ | KEY_WRITE,
+ hKey = SETUPDI_CreateDrvKey(RootKey, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_READ | KEY_WRITE);
#else
- KEY_ALL_ACCESS,
+ hKey = SETUPDI_CreateDrvKey(RootKey, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_ALL_ACCESS);
#endif
- NULL,
- &hKey,
- &Disposition);
- if (rc != ERROR_SUCCESS)
- {
- SetLastError(rc);
- goto cleanup;
- }
- }
+ if (hKey == INVALID_HANDLE_VALUE)
+ goto cleanup;
}
/* Do installation of the specified section */
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);
DWORD PropertyBufferSize,
PDWORD RequiredSize)
{
- BOOL ret = FALSE;
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
struct DeviceInfo *devInfo;
+ CONFIGRET cr;
+ LONG lError = ERROR_SUCCESS;
+ DWORD size;
TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData,
Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
+
+ if (Property >= SPDRP_MAXIMUM_PROPERTY)
+ {
+ SetLastError(ERROR_INVALID_REG_PROPERTY);
+ 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);
+ size = PropertyBufferSize;
+ hKey = SETUPDI_OpenDevKey(set->HKLM, devInfo, KEY_QUERY_VALUE);
if (hKey == INVALID_HANDLE_VALUE)
return FALSE;
- l = RegQueryValueExW(hKey, PropertyMap[Property].nameW,
- NULL, PropertyRegDataType, PropertyBuffer, &size);
+ lError = RegQueryValueExW(hKey, PropertyMap[Property].nameW,
+ NULL, PropertyRegDataType, PropertyBuffer, &size);
RegCloseKey(hKey);
if (RequiredSize)
*RequiredSize = size;
- switch(l) {
+
+ switch (lError)
+ {
case ERROR_SUCCESS:
- if (PropertyBuffer != NULL || size == 0)
- ret = TRUE;
- else
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ if (PropertyBuffer == NULL && size != 0)
+ lError = ERROR_INSUFFICIENT_BUFFER;
break;
case ERROR_MORE_DATA:
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ lError = ERROR_INSUFFICIENT_BUFFER;
break;
default:
- SetLastError(l);
+ break;
}
}
else if (Property == SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)
{
- DWORD required = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
+ size = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
if (PropertyRegDataType)
*PropertyRegDataType = REG_SZ;
if (RequiredSize)
- *RequiredSize = required;
- if (PropertyBufferSize >= required)
+ *RequiredSize = size;
+ if (PropertyBufferSize >= size)
{
strcpyW((LPWSTR)PropertyBuffer, devInfo->Data);
- ret = TRUE;
}
else
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ lError = ERROR_INSUFFICIENT_BUFFER;
}
else
{
- ERR("Property 0x%lx not implemented\n", Property);
- SetLastError(ERROR_NOT_SUPPORTED);
- }
- return ret;
-}
+ size = PropertyBufferSize;
-/***********************************************************************
- * 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;
+ cr = CM_Get_DevNode_Registry_Property_ExW(devInfo->dnDevInst,
+ Property + (CM_DRP_DEVICEDESC - SPDRP_DEVICEDESC),
+ PropertyRegDataType,
+ PropertyBuffer,
+ &size,
+ 0,
+ set->hMachine);
+ if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL))
+ {
+ if (RequiredSize)
+ *RequiredSize = size;
+ }
- TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
- PropertyBuffer, PropertyBufferSize);
+ if (cr != CR_SUCCESS)
+ {
+ switch (cr)
+ {
+ case CR_INVALID_DEVINST:
+ lError = ERROR_NO_SUCH_DEVINST;
+ break;
- 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;
+ case CR_INVALID_PROPERTY:
+ lError = ERROR_INVALID_REG_PROPERTY;
+ break;
+
+ case CR_BUFFER_SMALL:
+ lError = ERROR_INSUFFICIENT_BUFFER;
+ break;
+
+ default :
+ lError = ERROR_INVALID_DATA;
+ break;
+ }
+ }
}
- FIXME("%p %p 0x%lx %p 0x%lx\n", DeviceInfoSet, DeviceInfoData,
- Property, PropertyBuffer, PropertyBufferSize);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ret;
+ SetLastError(lError);
+ return (lError == ERROR_SUCCESS);
}
/***********************************************************************
- * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
+ * Internal for SetupDiSetDeviceRegistryPropertyA/W
*/
-BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
+BOOL WINAPI IntSetupDiSetDeviceRegistryPropertyAW(
HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
DWORD Property,
const BYTE *PropertyBuffer,
- DWORD PropertyBufferSize)
+ DWORD PropertyBufferSize,
+ BOOL isAnsi)
{
BOOL ret = FALSE;
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *deviceInfo;
TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
PropertyBuffer, PropertyBufferSize);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
+
+ deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
- && PropertyMap[Property].nameW)
+ && PropertyMap[Property].nameW
+ && PropertyMap[Property].nameA)
{
HKEY hKey;
LONG l;
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
+ hKey = SETUPDI_OpenDevKey(set->HKLM, deviceInfo, 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 (isAnsi)
+ {
+ l = RegSetValueExA(
+ hKey, PropertyMap[Property].nameA, 0,
+ PropertyMap[Property].regType, PropertyBuffer,
+ PropertyBufferSize);
+ }
+ else
+ {
+ l = RegSetValueExW(
+ hKey, PropertyMap[Property].nameW, 0,
+ PropertyMap[Property].regType, PropertyBuffer,
+ PropertyBufferSize);
+ }
if (!l)
ret = TRUE;
else
TRACE("Returning %d\n", ret);
return ret;
}
+/***********************************************************************
+ * SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(
+ HDEVINFO DeviceInfoSet,
+ PSP_DEVINFO_DATA DeviceInfoData,
+ DWORD Property,
+ const BYTE *PropertyBuffer,
+ DWORD PropertyBufferSize)
+{
+ return IntSetupDiSetDeviceRegistryPropertyAW(DeviceInfoSet,
+ DeviceInfoData,
+ Property,
+ PropertyBuffer,
+ PropertyBufferSize,
+ TRUE);
+}
+
+/***********************************************************************
+ * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
+ HDEVINFO DeviceInfoSet,
+ PSP_DEVINFO_DATA DeviceInfoData,
+ DWORD Property,
+ const BYTE *PropertyBuffer,
+ DWORD PropertyBufferSize)
+{
+ return IntSetupDiSetDeviceRegistryPropertyAW(DeviceInfoSet,
+ DeviceInfoData,
+ Property,
+ PropertyBuffer,
+ PropertyBufferSize,
+ FALSE);
+}
/***********************************************************************
* SetupDiInstallClassA (SETUPAPI.@)
HKEY SETUP_CreateClassKey(HINF hInf)
{
- static const WCHAR slash[] = { '\\',0 };
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,
- ClassGUID,
+ REGSTR_VAL_CLASSGUID,
Buffer,
- MAX_PATH,
+ sizeof(Buffer) / sizeof(WCHAR),
&RequiredSize))
{
return INVALID_HANDLE_VALUE;
}
+ /* Build the corresponding registry key name */
lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
- lstrcatW(FullBuffer, slash);
+ 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))
{
- if (!SetupGetLineTextW(NULL,
- hInf,
- Version,
- Class,
- Buffer,
- MAX_PATH,
- &RequiredSize))
- {
- return INVALID_HANDLE_VALUE;
- }
-
- if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
- FullBuffer,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_SET_VALUE,
- NULL,
- &hClassKey,
- NULL))
- {
- return INVALID_HANDLE_VALUE;
- }
+ /* 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,
- Class,
+ REGSTR_VAL_CLASS,
0,
REG_SZ,
(LPBYTE)Buffer,
if (CanHandle & DEVICE_COINSTALLER)
{
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
+ hKey = SETUPDI_OpenDrvKey(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM, (struct DeviceInfo *)DeviceInfoData->Reserved, KEY_QUERY_VALUE);
if (hKey != INVALID_HANDLE_VALUE)
{
rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, &dwRegType, NULL, &dwLength);
&hKey);
if (rc == ERROR_SUCCESS)
{
- LPWSTR lpGuidString;
- if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) == RPC_S_OK)
+ WCHAR szGuidString[40];
+ if (pSetupStringFromGuid(&DeviceInfoData->ClassGuid, szGuidString, ARRAYSIZE(szGuidString)) == ERROR_SUCCESS)
{
- rc = RegQueryValueExW(hKey, lpGuidString, NULL, &dwRegType, NULL, &dwLength);
+ rc = RegQueryValueExW(hKey, szGuidString, 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);
+ rc = RegQueryValueExW(hKey, szGuidString, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
if (rc == ERROR_SUCCESS)
{
LPWSTR ptr;
HeapFree(GetProcessHeap(), 0, KeyBuffer);
}
}
- RpcStringFreeW(&lpGuidString);
}
RegCloseKey(hKey);
}
SetLastError(ERROR_NO_ASSOCIATED_CLASS);
else
{
- memcpy(&ClassGuid, &list->ClassGuid, sizeof(GUID));
+ *ClassGuid = list->ClassGuid;
ret = TRUE;
}
rc = RegOpenKeyExW(HKLM,
REGSTR_PATH_HWPROFILES,
0,
- 0,
+ READ_CONTROL,
&hHWProfilesKey);
if (rc != ERROR_SUCCESS)
{
list->HKLM,
REGSTR_PATH_SYSTEMENUM,
0, /* Options */
- 0,
+ READ_CONTROL,
&hEnumKey);
if (rc != ERROR_SUCCESS)
{
IN HDEVINFO DeviceInfoSet,
IN OUT PSP_DEVINFO_DATA DeviceInfoData)
{
+ struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
PSP_PROPCHANGE_PARAMS PropChange;
- HKEY hKey = INVALID_HANDLE_VALUE;
+ HKEY hRootKey = INVALID_HANDLE_VALUE, hKey = INVALID_HANDLE_VALUE;
LPCWSTR RegistryValueName;
DWORD dwConfigFlags, dwLength, dwRegType;
LONG rc;
case DICS_ENABLE:
case DICS_DISABLE:
{
+ if (PropChange->Scope == DICS_FLAG_GLOBAL)
+ hRootKey = set->HKLM;
+ else /* PropChange->Scope == DICS_FLAG_CONFIGSPECIFIC */
+ {
+ hRootKey = OpenHardwareProfileKey(set->HKLM, PropChange->HwProfile, KEY_CREATE_SUB_KEY);
+ if (hRootKey == INVALID_HANDLE_VALUE)
+ goto cleanup;
+ }
+
/* Enable/disable device in registry */
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
+ hKey = SETUPDI_OpenDrvKey(hRootKey, deviceInfo, 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);
+ hKey = SETUPDI_CreateDevKey(hRootKey, deviceInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
if (hKey == INVALID_HANDLE_VALUE)
break;
dwLength = sizeof(DWORD);
}
cleanup:
+ if (hRootKey != INVALID_HANDLE_VALUE && hRootKey != set->HKLM)
+ RegCloseKey(hRootKey);
+
if (hKey != INVALID_HANDLE_VALUE)
RegCloseKey(hKey);
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData)
{
+ struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *deviceInfo;
BOOL ret = FALSE; /* Return value */
TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
if (!Result)
goto cleanup;
- SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
+ SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
if (SelectedDriver == NULL)
{
SetLastError(ERROR_NO_DRIVER_SELECTED);
goto cleanup;
lstrcatW(SectionName, DotCoInstallers);
+ deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
/* Open/Create driver key information */
#if _WIN32_WINNT >= 0x502
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
+ hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
#else
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
+ hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, 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 _WIN32_WINNT >= 0x502
+ hKey = SETUPDI_CreateDrvKey(set->HKLM, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_READ | KEY_WRITE);
+#else
+ hKey = SETUPDI_CreateDrvKey(set->HKLM, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_ALL_ACCESS);
+#endif
if (hKey == INVALID_HANDLE_VALUE)
goto cleanup;
IN HDEVINFO DeviceInfoSet,
IN OUT PSP_DEVINFO_DATA DeviceInfoData)
{
+ struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *deviceInfo;
SP_DEVINSTALL_PARAMS_W InstallParams;
struct DriverInfoElement *SelectedDriver;
SYSTEMTIME DriverDate;
goto cleanup;
}
- SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
+ SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
if (SelectedDriver == NULL)
{
SetLastError(ERROR_NO_DRIVER_SELECTED);
strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
}
+ deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
/* Open/Create driver key information */
#if _WIN32_WINNT >= 0x502
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
+ hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
#else
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
+ hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, 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 _WIN32_WINNT >= 0x502
+ hKey = SETUPDI_CreateDrvKey(set->HKLM, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_READ | KEY_WRITE);
+#else
+ hKey = SETUPDI_CreateDrvKey(set->HKLM, deviceInfo, (UUID*)&DeviceInfoData->ClassGuid, KEY_ALL_ACCESS);
+#endif
if (hKey == INVALID_HANDLE_VALUE)
goto cleanup;
RebootRequired = TRUE;
/* Open device registry key */
- hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
+ hKey = SETUPDI_OpenDevKey(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM, (struct DeviceInfo *)DeviceInfoData->Reserved, KEY_SET_VALUE);
if (hKey == INVALID_HANDLE_VALUE)
goto cleanup;
return ret;
}
-static HKEY SETUPDI_OpenDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
+HKEY SETUPDI_CreateDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
+{
+ HKEY enumKey, key = INVALID_HANDLE_VALUE;
+ LONG l;
+
+ l = RegCreateKeyExW(RootKey, REGSTR_PATH_SYSTEMENUM, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &enumKey, NULL);
+ if (!l)
+ {
+ l = RegCreateKeyExW(enumKey, devInfo->instanceId, 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &key, NULL);
+ RegCloseKey(enumKey);
+ }
+ if (l)
+ SetLastError(l);
+ return key;
+}
+
+HKEY SETUPDI_CreateDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, UUID *ClassGuid, REGSAM samDesired)
+{
+ 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;
+
+ /* Open device key, to read Driver value */
+ hDeviceKey = SETUPDI_OpenDevKey(RootKey, devInfo, 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(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;
+ }
+ }
+
+ 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", hKey);
+ return hKey;
+}
+
+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, 0, &enumKey);
+ l = RegOpenKeyExW(RootKey, REGSTR_PATH_SYSTEMENUM, 0, READ_CONTROL, &enumKey);
if (!l)
{
l = RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key);
return key;
}
-static HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
+HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
{
LPWSTR DriverKey = NULL;
DWORD dwLength = 0;
RootKey,
REGSTR_PATH_CLASS_NT,
0, /* Options */
- 0,
+ READ_CONTROL,
&hEnumKey);
if (rc != ERROR_SUCCESS)
{
RegCloseKey(hEnumKey);
if (hKey != NULL && hKey != key)
RegCloseKey(hKey);
+ if (DriverKey)
+ HeapFree(GetProcessHeap(), 0, DriverKey);
return key;
}
{
case DIREG_DEV:
key = SETUPDI_OpenDevKey(RootKey, devInfo, samDesired);
+ if (Scope == DICS_FLAG_GLOBAL)
+ {
+ LONG rc;
+ HKEY hTempKey = key;
+ rc = RegOpenKeyExW(hTempKey,
+ L"Device Parameters",
+ 0,
+ samDesired,
+ &key);
+ if (rc == ERROR_SUCCESS)
+ RegCloseKey(hTempKey);
+ }
break;
case DIREG_DRV:
key = SETUPDI_OpenDrvKey(RootKey, devInfo, samDesired);
RegCloseKey(RootKey);
return ret;
}
+
+/***********************************************************************
+ * SetupDiRestartDevices (SETUPAPI.@)
+ */
+BOOL
+WINAPI
+SetupDiRestartDevices(
+ HDEVINFO DeviceInfoSet,
+ PSP_DEVINFO_DATA DeviceInfoData)
+{
+ struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+ struct DeviceInfo *devInfo;
+ CONFIGRET cr;
+
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ 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;
+
+ cr = CM_Enable_DevNode_Ex(devInfo->dnDevInst, 0, set->hMachine);
+ if (cr != CR_SUCCESS)
+ {
+ SetLastError(GetErrorCodeFromCrCode(cr));
+ return FALSE;
+ }
+
+ return TRUE;
+}