Implement SetupDiCallClassInstaller (still doesn't support custom class
installers/co-installers)
Implement SetupDiGetDeviceInstallParamsA by calling
SetupDiGetDeviceInstallParamsW. Add stub for
SetupDiGetDeviceInstallParamsW
Basic implementation of SetupDiSelectBestCompatDrv (selects first driver
of the list)
Add stubs for SetupDiInstallDriverFiles,
SetupDiRegisterCoDeviceInstallers, SetupDiInstallDeviceInterfaces,
SetupDiInstallDevice
Modified: trunk/reactos/lib/setupapi/devinst.c
Modified: trunk/reactos/lib/setupapi/setupapi.spec
_____
Modified: trunk/reactos/lib/setupapi/devinst.c
--- trunk/reactos/lib/setupapi/devinst.c 2005-08-12 19:00:04 UTC
(rev 17343)
+++ trunk/reactos/lib/setupapi/devinst.c 2005-08-12 19:03:35 UTC
(rev 17344)
@@ -79,9 +79,33 @@
/* FIXME: header mess */
DEFINE_GUID(GUID_NULL,
0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00);
+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);
#define SETUP_DEV_INFO_SET_MAGIC 0xd00ff057
+struct CoInstallerElement
+{
+ LIST_ENTRY ListEntry;
+
+ COINSTALLER_PROC Function;
+ BOOL DoPostProcessing;
+ PVOID PrivateData;
+};
+
struct DeviceInterface /* Element of
DeviceInfoElement.InterfaceListHead */
{
LIST_ENTRY ListEntry;
@@ -2758,22 +2782,304 @@
* SetupDiCallClassInstaller (SETUPAPI.@)
*/
BOOL WINAPI SetupDiCallClassInstaller(
- DI_FUNCTION InstallFunction,
- HDEVINFO DeviceInfoSet,
- PSP_DEVINFO_DATA DeviceInfoData)
+ IN DI_FUNCTION InstallFunction,
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
{
- FIXME("%ld %p %p\n", InstallFunction, DeviceInfoSet,
DeviceInfoData);
- return FALSE;
+ BOOL ret = FALSE;
+
+ TRACE("%ld %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_DEV_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
+ {
+#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_ALLOW_INSTALL:
+ 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_REGISTER_COINSTALLERS:
+ CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
+ DefaultHandler = SetupDiRegisterCoDeviceInstallers;
+ break;
+ case DIF_SELECTBESTCOMPATDRV:
+ CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
+ DefaultHandler = SetupDiSelectBestCompatDrv;
+ break;
+ default:
+ FIXME("Install function %ld not implemented\n",
InstallFunction);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ }
+
+ if (CanHandle != 0)
+ {
+ LIST_ENTRY ClassCoInstallersListHead;
+ LIST_ENTRY DeviceCoInstallersListHead;
+ 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 & CLASS_COINSTALLER)
+ {
+ FIXME("Doesn't use Class co-installers at the
moment\n");
+ }
+ if (CanHandle & DEVICE_COINSTALLER)
+ {
+ rc = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+
L"SYSTEM\\CurrentControlSet\\Control\\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, L"Installer32",
NULL, &dwRegType, NULL, &dwLength);
+ if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
+ {
+ LPWSTR KeyBuffer =
HeapAlloc(GetProcessHeap(), 0, dwLength);
+ if (KeyBuffer != NULL)
+ {
+ rc = RegQueryValueExW(hKey,
L"Installer32", NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
+ if (rc == ERROR_SUCCESS)
+ {
+ LPCWSTR ptr;
+ for (ptr = KeyBuffer; *ptr; ptr +=
strlenW(ptr) + 1)
+ {
+ /* Add coinstaller to
DeviceCoInstallersListHead list */
+ FIXME("Device coinstaller is
'%S'\n", ptr);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0,
KeyBuffer);
+ }
+ }
+ RpcStringFreeW(&lpGuidString);
+ }
+ RegCloseKey(hKey);
+ }
+ }
+ if (CanHandle & CLASS_INSTALLER)
+ {
+ hKey =
SetupDiOpenClassRegKey(&DeviceInfoData->ClassGuid, KEY_QUERY_VALUE);
+ if (hKey != INVALID_HANDLE_VALUE)
+ {
+ rc = RegQueryValueExW(hKey, L"Installer32", NULL,
&dwRegType, NULL, &dwLength);
+ if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
+ {
+ LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(),
0, dwLength);
+ if (KeyBuffer != NULL)
+ {
+ rc = RegQueryValueExW(hKey, L"Installer32",
NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
+ if (rc == ERROR_SUCCESS)
+ {
+ /* Set ClassInstaller function pointer
*/
+ FIXME("Installer is '%S'\n",
KeyBuffer);
+ }
+ 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 = (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 = (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);
+ else
+ rc = ERROR_DI_DO_DEFAULT;
+
+ /* Call default handler */
+ if (rc == ERROR_DI_DO_DEFAULT)
+ {
+ if (DefaultHandler /*FIXME && DI_NODI_DEFAULTACTION not
set */)
+ {
+ 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 = (struct
CoInstallerElement *)ListEntry;
+ if (coinstaller->DoPostProcessing)
+ {
+ Context.InstallResult = rc;
+ Context.PrivateData = coinstaller->PrivateData;
+ rc = (*coinstaller->Function)(InstallFunction,
DeviceInfoSet, DeviceInfoData, &Context);
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ /* Call Device co-installers that required postprocessing
*/
+ ListEntry = DeviceCoInstallersListHead.Flink;
+ while (ListEntry != &DeviceCoInstallersListHead)
+ {
+ struct CoInstallerElement *coinstaller = (struct
CoInstallerElement *)ListEntry;
+ if (coinstaller->DoPostProcessing)
+ {
+ Context.InstallResult = rc;
+ Context.PrivateData = coinstaller->PrivateData;
+ rc = (*coinstaller->Function)(InstallFunction,
DeviceInfoSet, DeviceInfoData, &Context);
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ /* Free allocated memory */
+ while (!IsListEmpty(&ClassCoInstallersListHead))
+ {
+ ListEntry = RemoveHeadList(&ClassCoInstallersListHead);
+ HeapFree(GetProcessHeap(), 0, ListEntry);
+ }
+ while (!IsListEmpty(&DeviceCoInstallersListHead))
+ {
+ ListEntry =
RemoveHeadList(&DeviceCoInstallersListHead);
+ HeapFree(GetProcessHeap(), 0, 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)
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ OUT 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;
+}
+
+/**********************************************************************
*
+ * SetupDiGetDeviceInstallParamsW (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetDeviceInstallParamsW(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
+{
FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData,
DeviceInstallParams);
return FALSE;
}
@@ -3864,3 +4170,114 @@
TRACE("Returning %d\n", ret);
return ret;
}
+
+/**********************************************************************
*
+ * SetupDiSelectBestCompatDrv (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiSelectBestCompatDrv(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData)
+{
+ SP_DRVINFO_DATA_W drvInfoData;
+ BOOL ret;
+
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ FIXME("SetupDiSelectBestCompatDrv() is selecting the 1st
driver...\n");
+
+ drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W);
+ ret = SetupDiEnumDriverInfoW(
+ DeviceInfoSet,
+ DeviceInfoData,
+ SPDIT_COMPATDRIVER,
+ 0, /* Member index */
+ &drvInfoData);
+
+ if (ret)
+ {
+ ret = SetupDiSetSelectedDriverW(
+ DeviceInfoSet,
+ DeviceInfoData,
+ &drvInfoData);
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
+/**********************************************************************
*
+ * SetupDiInstallDriverFiles (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiInstallDriverFiles(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+{
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ FIXME("SetupDiInstallDriverFiles not implemented. Doing
nothing\n");
+ //SetLastError(ERROR_GEN_FAILURE);
+ //return FALSE;
+ return TRUE;
+}
+
+/**********************************************************************
*
+ * SetupDiRegisterCoDeviceInstallers (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiRegisterCoDeviceInstallers(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData)
+{
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ FIXME("SetupDiRegisterCoDeviceInstallers not implemented. Doing
nothing\n");
+ //SetLastError(ERROR_GEN_FAILURE);
+ //return FALSE;
+ return TRUE;
+}
+
+/**********************************************************************
*
+ * SetupDiInstallDeviceInterfaces (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiInstallDeviceInterfaces(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData)
+{
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ FIXME("SetupDiInstallDeviceInterfaces not implemented. Doing
nothing\n");
+ //SetLastError(ERROR_GEN_FAILURE);
+ //return FALSE;
+ return TRUE;
+}
+
+/**********************************************************************
*
+ * SetupDiInstallDevice (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiInstallDevice(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData)
+{
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+ /* Steps to follow:
+ * 0. If DI_FLAGSEX_SETFAILEDINSTALL is set, set FAILEDINSTALL flag
in ConfigFlags registry and exit
+ * 1. Create driver key and write InfPath and ProviderName
+ * 2a Process inf sections: {DDInstall}, {DDInstall}.HW
[SetupDiOpenDevRegKey]
+ * b Process {DDInstall}.LogConfigOverride if present
[SetupDiOpenDevRegKey]
+ * c Process {DDInstall}.Services [SetupDiOpenDevRegKey]
+ * 3. Copy inf file to Inf\ directory [SetupCopyOEMInf]
+ * 4. Install other waiting files
+ * 5. Load the driver/Call AddDevice
+ * 6. Send IRP_MN_START_DEVICE if DI_NEEDRESTART, DI_NEEDREBOOT and
DI_DONOTCALLCONFIGMG are not set
+ */
+
+ FIXME("SetupDiInstallDevice not implemented. Doing nothing\n");
+ //SetLastError(ERROR_GEN_FAILURE);
+ //return FALSE;
+ return TRUE;
+}
_____
Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec 2005-08-12 19:00:04 UTC
(rev 17343)
+++ trunk/reactos/lib/setupapi/setupapi.spec 2005-08-12 19:03:35 UTC
(rev 17344)
@@ -321,7 +321,7 @@
@ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr)
@ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr)
@ stdcall SetupDiGetDeviceInstallParamsA(ptr ptr ptr)
-@ stub SetupDiGetDeviceInstallParamsW
+@ stdcall SetupDiGetDeviceInstallParamsW(ptr ptr ptr)
@ stub SetupDiGetDeviceInstanceIdA
@ stub SetupDiGetDeviceInstanceIdW
@ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long
ptr)
@@ -350,8 +350,9 @@
@ stub SetupDiInstallClassExA
@ stub SetupDiInstallClassExW
@ stdcall SetupDiInstallClassW(long wstr long ptr)
-@ stub SetupDiInstallDevice
-@ stub SetupDiInstallDriverFiles
+@ stdcall SetupDiInstallDevice(ptr ptr)
+@ stdcall SetupDiInstallDeviceInterfaces(ptr ptr)
+@ stdcall SetupDiInstallDriverFiles(ptr ptr)
@ stub SetupDiLoadClassIcon
@ stub SetupDiMoveDuplicateDevice
@ stdcall SetupDiOpenClassRegKey(ptr long)
@@ -363,9 +364,11 @@
@ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr)
@ stub SetupDiOpenDeviceInterfaceRegKey
@ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr)
+@ stdcall SetupDiRegisterCoDeviceInstallers(ptr ptr)
@ stub SetupDiRegisterDeviceInfo
@ stub SetupDiRemoveDevice
@ stub SetupDiRemoveDeviceInterface
+@ stdcall SetupDiSelectBestCompatDrv(ptr ptr)
@ stub SetupDiSelectDevice
@ stub SetupDiSelectOEMDrv
@ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long)