Implement SetupDiCreateDevRegKeyW and SetupDiOpenDevRegKey

Use them in SetupDiInstallDevice

svn path=/trunk/; revision=18444
This commit is contained in:
Hervé Poussineau 2005-10-14 16:53:18 +00:00
parent a7f76e510d
commit 6dc4621495
2 changed files with 284 additions and 87 deletions

View file

@ -3172,6 +3172,156 @@ BOOL WINAPI SetupDiGetDeviceInstallParamsW(
return FALSE;
}
/***********************************************************************
* SetupDiCreateDevRegKey (SETUPAPI.@)
*/
HKEY WINAPI SetupDiCreateDevRegKeyW(
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN DWORD Scope,
IN DWORD HwProfile,
IN DWORD KeyType,
IN HINF InfHandle OPTIONAL,
IN PCWSTR InfSectionName OPTIONAL)
{
struct DeviceInfoSet *list;
HKEY ret = INVALID_HANDLE_VALUE;
TRACE("%p %p %lu %lu %lu %p %s\n", DeviceInfoSet, DeviceInfoData,
Scope, HwProfile, KeyType, InfHandle, debugstr_w(InfSectionName));
if (!DeviceInfoSet)
SetLastError(ERROR_INVALID_HANDLE);
else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_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 (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
SetLastError(ERROR_INVALID_PARAMETER);
else if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
SetLastError(ERROR_INVALID_PARAMETER);
else if (InfHandle && !InfSectionName)
SetLastError(ERROR_INVALID_PARAMETER);
else if (!InfHandle && InfSectionName)
SetLastError(ERROR_INVALID_PARAMETER);
else
{
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 rc;
HKEY hClassKey = INVALID_HANDLE_VALUE;
HKEY hDeviceKey = INVALID_HANDLE_VALUE;
HKEY hKey = INVALID_HANDLE_VALUE;
if (Scope == DICS_FLAG_CONFIGSPECIFIC)
{
FIXME("DICS_FLAG_CONFIGSPECIFIC case unimplemented\n");
goto cleanup;
}
if (KeyType == DIREG_DEV)
{
FIXME("DIREG_DEV case unimplemented\n");
}
else /* KeyType == DIREG_DRV */
{
if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
goto cleanup;
/* The driver key is in HKLM\System\CurrentControlSet\Control\Class\{GUID}\Index */
DriverKey = HeapAlloc(GetProcessHeap(), 0, (wcslen(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_STRING));
if (!DriverKey)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
wcscpy(DriverKey, L"{");
wcscat(DriverKey, lpGuidString);
wcscat(DriverKey, L"}\\");
pDeviceInstance = &DriverKey[wcslen(DriverKey)];
rc = RegOpenKeyExW(list->HKLM,
ControlClass,
0,
KEY_CREATE_SUB_KEY,
&hClassKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* Try all values for Index between 0 and 9999 */
Index = 0;
while (Index <= 9999)
{
DWORD Disposition;
wsprintf(pDeviceInstance, L"%04lu", Index);
rc = RegCreateKeyEx(hClassKey,
DriverKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hKey,
&Disposition);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
if (Disposition == REG_CREATED_NEW_KEY)
break;
RegCloseKey(hKey);
hKey = INVALID_HANDLE_VALUE;
Index++;
}
if (Index > 9999)
{
/* Unable to create more than 9999 devices within the same class */
SetLastError(ERROR_GEN_FAILURE);
goto cleanup;
}
/* Open device key, to write Driver value */
hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, DIREG_DEV, KEY_SET_VALUE);
if (hDeviceKey == INVALID_HANDLE_VALUE)
goto cleanup;
rc = RegSetValueEx(hDeviceKey, L"Driver", 0, REG_SZ, (const BYTE *)DriverKey, (wcslen(DriverKey) + 1) * sizeof(WCHAR));
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);
}
ret = hKey;
cleanup:
if (lpGuidString)
RpcStringFreeW(&lpGuidString);
HeapFree(GetProcessHeap(), 0, DriverKey);
if (hClassKey != INVALID_HANDLE_VALUE)
RegCloseKey(hClassKey);
if (hDeviceKey != INVALID_HANDLE_VALUE)
RegCloseKey(hDeviceKey);
if (hKey != INVALID_HANDLE_VALUE && hKey != ret)
RegCloseKey(hKey);
}
TRACE("Returning 0x%p\n", ret);
return ret;
}
/***********************************************************************
* SetupDiOpenDevRegKey (SETUPAPI.@)
*/
@ -3183,9 +3333,130 @@ HKEY WINAPI SetupDiOpenDevRegKey(
DWORD KeyType,
REGSAM samDesired)
{
FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
struct DeviceInfoSet *list;
HKEY ret = INVALID_HANDLE_VALUE;
TRACE("%p %p %lu %lu %lu 0x%lx\n", DeviceInfoSet, DeviceInfoData,
Scope, HwProfile, KeyType, samDesired);
return INVALID_HANDLE_VALUE;
if (!DeviceInfoSet)
SetLastError(ERROR_INVALID_HANDLE);
else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_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 (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
SetLastError(ERROR_INVALID_PARAMETER);
else if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
SetLastError(ERROR_INVALID_PARAMETER);
else
{
HKEY hKey = INVALID_HANDLE_VALUE;
HKEY hRootKey = INVALID_HANDLE_VALUE;
struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
LPWSTR DriverKey = NULL;
DWORD dwLength = 0;
DWORD dwRegType;
DWORD rc;
if (Scope == DICS_FLAG_CONFIGSPECIFIC)
{
FIXME("DICS_FLAG_CONFIGSPECIFIC case unimplemented\n");
}
else /* Scope == DICS_FLAG_GLOBAL */
{
rc = RegOpenKeyExW(
list->HKLM,
EnumKeyName,
0, /* Options */
KEY_ENUMERATE_SUB_KEYS,
&hRootKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
rc = RegOpenKeyExW(
hRootKey,
deviceInfo->DeviceName,
0, /* Options */
KeyType == DIREG_DEV ? samDesired : KEY_QUERY_VALUE,
&hKey);
RegCloseKey(hRootKey);
hRootKey = INVALID_HANDLE_VALUE;
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
if (KeyType == DIREG_DEV)
{
/* We're done. Just return the hKey handle */
ret = hKey;
goto cleanup;
}
/* Read the 'Driver' key */
rc = RegQueryValueExW(hKey, L"Driver", NULL, &dwRegType, NULL, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
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, L"Driver", NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
RegCloseKey(hKey);
hKey = INVALID_HANDLE_VALUE;
/* Need to open the driver key */
rc = RegOpenKeyExW(
list->HKLM,
ControlClass,
0, /* Options */
KEY_ENUMERATE_SUB_KEYS,
&hRootKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
rc = RegOpenKeyExW(
hRootKey,
DriverKey,
0, /* Options */
samDesired,
&hKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
ret = hKey;
}
cleanup:
if (hRootKey != INVALID_HANDLE_VALUE)
RegCloseKey(hRootKey);
if (hKey != INVALID_HANDLE_VALUE && hKey != ret)
RegCloseKey(hKey);
}
TRACE("Returning 0x%p\n", ret);
return ret;
}
/***********************************************************************
@ -4537,7 +4808,6 @@ SetupDiInstallDevice(
IN PSP_DEVINFO_DATA DeviceInfoData)
{
struct DriverInfoElement *DriverInfo;
struct DeviceInfoSet *DevInfoSet = (struct DeviceInfoSet *)DeviceInfoSet;
struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
SYSTEMTIME DriverDate;
WCHAR SectionName[MAX_PATH];
@ -4554,11 +4824,8 @@ SetupDiInstallDevice(
GUID ClassGuid;
LPWSTR lpGuidString = NULL, lpFullGuidString = NULL;
BOOL RebootRequired = FALSE;
HKEY hEnumKey, hKey = INVALID_HANDLE_VALUE;
HKEY hKey = INVALID_HANDLE_VALUE;
HKEY hClassKey = INVALID_HANDLE_VALUE;
LPWSTR DriverKey = NULL; /* {GUID}\Index */
LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
DWORD Index; /* Index used in the DriverKey name */
LONG rc;
HWND hWnd;
PVOID callback_context;
@ -4642,59 +4909,12 @@ SetupDiInstallDevice(
lpFullGuidString[RequiredSize + 1] = '}';
lpFullGuidString[RequiredSize + 2] = '\0';
/* Create driver key information */
/* The driver key is in HKLM\System\CurrentControlSet\Control\Class\{GUID}\{#ID} */
DriverKey = HeapAlloc(GetProcessHeap(), 0, (wcslen(lpFullGuidString) + 6) * sizeof(WCHAR));
if (!DriverKey)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
/* Open/Create driver key information */
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_SET_VALUE);
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;
}
wcscpy(DriverKey, lpFullGuidString);
wcscat(DriverKey, L"\\");
pDeviceInstance = &DriverKey[wcslen(DriverKey)];
rc = RegOpenKeyExW(DevInfoSet->HKLM,
ControlClass,
0,
KEY_CREATE_SUB_KEY,
&hClassKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* Try all values for Index between 0 and 9999 */
Index = 0;
while (Index <= 9999)
{
DWORD Disposition;
wsprintf(pDeviceInstance, L"%04lu", Index);
rc = RegCreateKeyEx(hClassKey,
DriverKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,
NULL,
&hKey,
&Disposition);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
if (Disposition == REG_CREATED_NEW_KEY)
break;
RegCloseKey(hKey);
hKey = INVALID_HANDLE_VALUE;
Index++;
}
if (Index > 9999)
{
/* Unable to create more than 9999 devices within the same class */
SetLastError(ERROR_GEN_FAILURE);
goto cleanup;
}
/* Write information to driver key */
*pSectionName = UNICODE_NULL;
@ -4821,29 +5041,10 @@ nextfile:
/* Copy .inf file to Inf\ directory */
FIXME("FIXME: Copy .inf file to Inf\\ directory\n"); /* SetupCopyOEMInf */
/* Open enum key */
rc = RegOpenKeyExW(DevInfoSet->HKLM,
EnumKeyName,
0,
KEY_ENUMERATE_SUB_KEYS,
&hEnumKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
rc = RegOpenKeyExW(
hEnumKey,
DevInfo->DeviceName,
0, /* Options */
KEY_SET_VALUE,
&hKey);
RegCloseKey(hEnumKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* 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 */
wcscpy(pSectionName, L".HW");
@ -4862,7 +5063,6 @@ nextfile:
TRACE("Class : '%S'\n", ClassName);
TRACE("ClassGUID : '%S'\n", lpFullGuidString);
TRACE("DeviceDesc : '%S'\n", DriverInfo->Info.Description);
TRACE("Driver : '%S'\n", DriverKey);
TRACE("Mfg : '%S'\n", DriverInfo->Info.MfgName);
rc = RegSetValueEx(hKey, L"Service", 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
@ -4871,8 +5071,6 @@ nextfile:
rc = RegSetValueEx(hKey, L"ClassGUID", 0, REG_SZ, (const BYTE *)lpFullGuidString, (wcslen(lpFullGuidString) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"DeviceDesc", 0, REG_SZ, (const BYTE *)DriverInfo->Info.Description, (wcslen(DriverInfo->Info.Description) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"Driver", 0, REG_SZ, (const BYTE *)DriverKey, (wcslen(DriverKey) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"Mfg", 0, REG_SZ, (const BYTE *)DriverInfo->Info.MfgName, (wcslen(DriverInfo->Info.MfgName) + 1) * sizeof(WCHAR));
if (rc != ERROR_SUCCESS)
@ -4902,7 +5100,6 @@ cleanup:
if (lpGuidString)
RpcStringFreeW(&lpGuidString);
HeapFree(GetProcessHeap(), 0, (LPWSTR)AssociatedService);
HeapFree(GetProcessHeap(), 0, DriverKey);
HeapFree(GetProcessHeap(), 0, ClassName);
HeapFree(GetProcessHeap(), 0, lpFullGuidString);
if (hInf != INVALID_HANDLE_VALUE)

View file

@ -282,7 +282,7 @@
@ stdcall SetupDiClassNameFromGuidExW(ptr wstr long ptr wstr ptr)
@ stdcall SetupDiClassNameFromGuidW(ptr wstr long ptr)
@ stub SetupDiCreateDevRegKeyA
@ stub SetupDiCreateDevRegKeyW
@ stdcall SetupDiCreateDevRegKeyW(ptr ptr long long long ptr wstr)
@ stdcall SetupDiCreateDeviceInfoA(ptr str ptr str ptr long ptr)
@ stdcall SetupDiCreateDeviceInfoW(ptr wstr ptr wstr ptr long ptr)
@ stdcall SetupDiCreateDeviceInfoList(ptr ptr)