Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This begins a series of patches which I've been working on as a side project for a while, which seek to improve support for installing and running Plug and Play (PnP) drivers.
After this series it is possible to run Microsoft's sample "toaster" WDM driver (taken from the Windows 7 DDK; the purely WDM driver has been removed from the most recent version, and WDF is much harder to compile.)
Needless to say, this is a huge step forward for running native PnP drivers. On the other hand, most native PnP drivers are designed to actually access hardware, and need to do things like handle interrupts and write to I/O ports. It is not clear how many native PnP drivers can actually execute in user-mode, and so the utility of this may be somewhat questionable. On the other hand, that missing step could certainly be filled in by a simple proxy kernel module, perhaps even using preƫxisting frameworks like UIO. Regardless of whether that would be maintained by the Wine project directly, I imagine it could be hugely beneficial to people who are currently forced to use Windows to interact with various domain-specific hardware.
The series also fixes several problems with our current HID drivers, to make them more architecturally correct. Of course, that's less clearly an advantage.
The work is already done, because I found it interesting enough to do, but there's still time to warn me not to do such obscure and useless work in the future by rejecting these patches ;-)
dlls/setupapi/devinst.c | 62 +++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 15 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 2640005abf..46aeb5a7d6 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -118,6 +118,7 @@ struct device DEVINST devnode; struct list entry; BOOL removed; + SP_DEVINSTALL_PARAMS_W params; };
struct device_iface @@ -730,7 +731,7 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, TRACE("%p, %s, %s, %d\n", set, debugstr_guid(class), debugstr_w(instanceid), phantom);
- if (!(device = heap_alloc(sizeof(*device)))) + if (!(device = heap_alloc_zero(sizeof(*device)))) { SetLastError(ERROR_OUTOFMEMORY); return NULL; @@ -752,6 +753,7 @@ static struct device *SETUPDI_CreateDeviceInfo(struct DeviceInfoSet *set, device->devnode = alloc_devnode(device); device->removed = FALSE; list_add_tail(&set->devices, &device->entry); + device->params.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
if (phantom) RegSetValueExW(device->key, Phantom, 0, REG_DWORD, (const BYTE *)&one, sizeof(one)); @@ -3542,27 +3544,57 @@ BOOL WINAPI SetupDiCallClassInstaller( }
/*********************************************************************** - * SetupDiGetDeviceInstallParamsW (SETUPAPI.@) + * SetupDiGetDeviceInstallParamsW (SETUPAPI.@) */ -BOOL WINAPI SetupDiGetDeviceInstallParamsW( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - PSP_DEVINSTALL_PARAMS_W DeviceInstallParams) +BOOL WINAPI SetupDiGetDeviceInstallParamsW(HDEVINFO devinfo, + SP_DEVINFO_DATA *device_data, SP_DEVINSTALL_PARAMS_W *params) { - FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams); - return FALSE; + struct device *device; + + TRACE("devinfo %p, device_data %p, params %p.\n", devinfo, device_data, params); + + if (params->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W)) + { + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; + } + + if (!(device = get_device(devinfo, device_data))) + return FALSE; + + *params = device->params; + + return TRUE; }
/*********************************************************************** - * SetupDiGetDeviceInstallParamsA (SETUPAPI.@) + * SetupDiGetDeviceInstallParamsA (SETUPAPI.@) */ -BOOL WINAPI SetupDiGetDeviceInstallParamsA( - HDEVINFO DeviceInfoSet, - PSP_DEVINFO_DATA DeviceInfoData, - PSP_DEVINSTALL_PARAMS_A DeviceInstallParams) +BOOL WINAPI SetupDiGetDeviceInstallParamsA(HDEVINFO devinfo, + SP_DEVINFO_DATA *device_data, SP_DEVINSTALL_PARAMS_A *params) { - FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams); - return FALSE; + SP_DEVINSTALL_PARAMS_W paramsW; + BOOL ret; + + if (params->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A)) + { + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; + } + + paramsW.cbSize = sizeof(paramsW); + ret = SetupDiGetDeviceInstallParamsW(devinfo, device_data, ¶msW); + params->Flags = paramsW.Flags; + params->FlagsEx = paramsW.FlagsEx; + params->hwndParent = paramsW.hwndParent; + params->InstallMsgHandler = paramsW.InstallMsgHandler; + params->InstallMsgHandlerContext = paramsW.InstallMsgHandlerContext; + params->FileQueue = paramsW.FileQueue; + params->ClassInstallReserved = paramsW.ClassInstallReserved; + params->Reserved = paramsW.Reserved; + WideCharToMultiByte(CP_ACP, 0, paramsW.DriverPath, -1, params->DriverPath, sizeof(params->DriverPath), NULL, NULL); + + return ret; }
/***********************************************************************