mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implement SetupDiCreateDevRegKeyW and SetupDiOpenDevRegKey
Use them in SetupDiInstallDevice svn path=/trunk/; revision=18444
This commit is contained in:
parent
a7f76e510d
commit
6dc4621495
2 changed files with 284 additions and 87 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue