mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 05:26:58 +00:00
[SYSETUP] Implement the CriticalDeviceCoInstaller
The CriticalDeviceCoInstaller adds devices of registered classes to the critical device database.
This commit is contained in:
parent
c7af85b64b
commit
4aa1bee757
|
@ -31,7 +31,7 @@ ComputerClassInstaller(
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
|
@ -41,12 +41,208 @@ CriticalDeviceCoInstaller(
|
|||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
|
||||
IN OUT PCOINSTALLER_CONTEXT_DATA Context)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT1("Install function %u ignored\n", InstallFunction);
|
||||
WCHAR szDeviceId[256];
|
||||
WCHAR szServiceName[256];
|
||||
WCHAR szClassGUID[64];
|
||||
DWORD dwRequiredSize;
|
||||
HKEY hDriverKey = NULL;
|
||||
HKEY hDatabaseKey = NULL, hDeviceKey = NULL;
|
||||
DWORD dwDisposition;
|
||||
PWSTR Ptr;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
DPRINT("CriticalDeviceCoInstaller(%lu %p %p %p)\n",
|
||||
InstallFunction, DeviceInfoSet, DeviceInfoData, Context);
|
||||
|
||||
if (InstallFunction != DIF_INSTALLDEVICE)
|
||||
return ERROR_SUCCESS;
|
||||
|
||||
/* Get the MatchingDeviceId property */
|
||||
hDriverKey = SetupDiOpenDevRegKey(DeviceInfoSet,
|
||||
DeviceInfoData,
|
||||
DICS_FLAG_GLOBAL,
|
||||
0,
|
||||
DIREG_DRV,
|
||||
KEY_READ);
|
||||
if (hDriverKey == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (Context->PostProcessing)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Failed to open the driver key! (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Failed to open the driver key! Postprocessing required!\n");
|
||||
return ERROR_DI_POSTPROCESSING_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
dwRequiredSize = sizeof(szDeviceId);
|
||||
dwError = RegQueryValueExW(hDriverKey,
|
||||
L"MatchingDeviceId",
|
||||
NULL,
|
||||
NULL,
|
||||
(PBYTE)szDeviceId,
|
||||
&dwRequiredSize);
|
||||
RegCloseKey(hDriverKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
if (Context->PostProcessing)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Failed to read the MatchingDeviceId value! (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Failed to read the MatchingDeviceId value! Postprocessing required!\n");
|
||||
return ERROR_DI_POSTPROCESSING_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("MatchingDeviceId: %S\n", szDeviceId);
|
||||
|
||||
/* Get the ClassGUID property */
|
||||
dwRequiredSize = 0;
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
|
||||
DeviceInfoData,
|
||||
SPDRP_CLASSGUID,
|
||||
NULL,
|
||||
(PBYTE)szClassGUID,
|
||||
sizeof(szClassGUID),
|
||||
&dwRequiredSize))
|
||||
{
|
||||
if (Context->PostProcessing)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Failed to read the ClassGUID! (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Failed to read the ClassGUID! Postprocessing required!\n");
|
||||
return ERROR_DI_POSTPROCESSING_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("ClassGUID %S\n", szClassGUID);
|
||||
|
||||
/* Get the Service property (optional) */
|
||||
dwRequiredSize = 0;
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
|
||||
DeviceInfoData,
|
||||
SPDRP_SERVICE,
|
||||
NULL,
|
||||
(PBYTE)szServiceName,
|
||||
sizeof(szServiceName),
|
||||
&dwRequiredSize))
|
||||
{
|
||||
if (Context->PostProcessing)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
if (dwError != ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
DPRINT1("Failed to read the Service name! (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
szServiceName[0] = UNICODE_NULL;
|
||||
dwError = ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Failed to read the Service name! Postprocessing required!\n");
|
||||
return ERROR_DI_POSTPROCESSING_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Service %S\n", szServiceName);
|
||||
|
||||
/* Replace the first backslash by a number sign */
|
||||
Ptr = wcschr(szDeviceId, L'\\');
|
||||
if (Ptr != NULL)
|
||||
{
|
||||
*Ptr = L'#';
|
||||
|
||||
/* Terminate the device id at the second backslash */
|
||||
Ptr = wcschr(Ptr, L'\\');
|
||||
if (Ptr != NULL)
|
||||
*Ptr = UNICODE_NULL;
|
||||
}
|
||||
|
||||
DPRINT("DeviceId: %S\n", szDeviceId);
|
||||
|
||||
/* Open the critical device database key */
|
||||
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\CriticalDeviceDatabase",
|
||||
0,
|
||||
KEY_WRITE,
|
||||
&hDatabaseKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegOpenKeyExW failed (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create a new key for the device */
|
||||
dwError = RegCreateKeyExW(hDatabaseKey,
|
||||
szDeviceId,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_WRITE,
|
||||
NULL,
|
||||
&hDeviceKey,
|
||||
&dwDisposition);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegCreateKeyExW failed (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the ClassGUID value */
|
||||
dwError = RegSetValueExW(hDeviceKey,
|
||||
L"ClassGUID",
|
||||
0,
|
||||
REG_SZ,
|
||||
(PBYTE)szClassGUID,
|
||||
(wcslen(szClassGUID) + 1) * sizeof(WCHAR));
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If available, set the Service value */
|
||||
if (szServiceName[0] != UNICODE_NULL)
|
||||
{
|
||||
dwError = RegSetValueExW(hDeviceKey,
|
||||
L"Service",
|
||||
0,
|
||||
REG_SZ,
|
||||
(PBYTE)szServiceName,
|
||||
(wcslen(szServiceName) + 1) * sizeof(WCHAR));
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegSetValueExW failed (Error %lu)\n", dwError);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (hDeviceKey != NULL)
|
||||
RegCloseKey(hDeviceKey);
|
||||
|
||||
if (hDatabaseKey != NULL)
|
||||
RegCloseKey(hDatabaseKey);
|
||||
|
||||
DPRINT("CriticalDeviceCoInstaller() done (Error %lu)\n", dwError);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue