Hi everybody,
I need to add support for a currently unsupported VxD, and I'm quite puzzled by the way that DeviceIoControl currently processes the device control requests.
DeviceIoControl starts by checking the high word of dwIoControlCode, which is the device type. If the device type is 0, it gets a client ID by sending a get_file_info request to the server, and uses the client ID as the device type. It then looks in the VxD table for a handler for the device type, and calls it if it exists. No problem with that.
If the high word of dwIoControlCode is not 0, it checks if the device is a CDROM (by calling GetDriveTypeA). If so, it calls CDROM_DeviceIoControl, and if not is just fails.
I was wondering why the same VxD table as for (HIWORD(dwIoControlCode) == 0) wasn't used when the device type in dwIoControlCode is not 0. It seems to be a mistake to me. I was thinking about implementing the following algorithm:
- check HIWORD(dwIoControlCode) - if 0, deviceType = GetCliendID( Device ) - if ! 0, deviceType = HIWORD(dwIoControlCode) - look for a VxD handler in the VxD table using the deviceType. - call the handler if it exists, fails otherwise
This leaves out the special case for CDROM_DeviceIoControl. Could anyone explain to me why that special check is needed, if it is ?
Thanks in advance.
Laurent Pinchart
Laurent Pinchart a écrit :
Hi everybody,
I need to add support for a currently unsupported VxD, and I'm quite puzzled by the way that DeviceIoControl currently processes the device control requests.
DeviceIoControl starts by checking the high word of dwIoControlCode, which is the device type. If the device type is 0, it gets a client ID by sending a get_file_info request to the server, and uses the client ID as the device type. It then looks in the VxD table for a handler for the device type, and calls it if it exists. No problem with that.
If the high word of dwIoControlCode is not 0, it checks if the device is a CDROM (by calling GetDriveTypeA). If so, it calls CDROM_DeviceIoControl, and if not is just fails.
in fact DeviceIOControl is used in two completly separate ways: 1/ control VxD 2/ control "device" handles on specific types
the control on VxD is needed for Win 9x support. In that case the HIWORD of the iocontrol code is always 0. So, in that case, a lookup is made in the list of known VxD:s if wae can handle the request.
the control on "device" handles is done when the high word of the control code is non 0.
as of today (but it's a bit hacky) handles to "device" and VxD:s are viewed (in the server) as very simple objects. They only provide a clientID (a DWORD). all the calls to DeviceIOControl start by getting this client ID.
If the value has the bit 0x10000 set, it means it's a VxD. The low word of the client id then identifies the standard ID of the VxD.
If the 0x20000 bit is set, it's in fact a handle a device. Driver A: through Z: are mapped to 0 to 25 values (in the low word)
Otherwise, it's a handle to the old DOS named devices (with their old IDs too)
So, back to DeviceIoControl when the high word of the io control code is 0. We expect device handle in that case (but don't test the 0x20000 bit for error reporting), and then try to check if the device (from it's driver letter) is a CDROM, and if so apply the io control on it. Support of io control on other types of device (hard disks, storage...) isn't done at the moment.
A+
in fact DeviceIOControl is used in two completly separate ways: 1/ control VxD 2/ control "device" handles on specific types
the control on VxD is needed for Win 9x support. In that case the HIWORD of the iocontrol code is always 0. So, in that case, a lookup is made in the list of known VxD:s if wae can handle the request.
Ok. I read the "Calling DeviceIoControl on Windows 95/98/Me" MSDN page, and I now understand what it's about.
the control on "device" handles is done when the high word of the control code is non 0.
as of today (but it's a bit hacky) handles to "device" and VxD:s are viewed (in the server) as very simple objects. They only provide a
clientID (a DWORD). all the calls to DeviceIOControl start by getting
this client ID.
If the value has the bit 0x10000 set, it means it's a VxD. The low word of the client id then identifies the standard ID of the VxD.
You're refering to both VxDs and WDM (.sys) drivers, right ?
How does the server find the correct low word of the client ID ? The driver I want to implement has a device type of 0xef00 (value passed to IoCreateDevice). I added a field to the VxD table with id set to 0xef00. Does wine, when I call CreateFile( "\\.\MyDevice", ... ), check that table and set the client ID low word to the proper value ?
If the 0x20000 bit is set, it's in fact a handle a device. Driver A: through Z: are mapped to 0 to 25 values (in the low word)
Otherwise, it's a handle to the old DOS named devices (with their old IDs too)
I think we should handler those cases in a new device handler (which would just test if the device is a CDROM for now).
So, back to DeviceIoControl when the high word of the io control code is 0. We expect device handle in that case (but don't test the 0x20000 bit for error reporting), and then try to check if the device (from it's driver letter) is a CDROM, and if so apply the io control on it. Support of io
control on other types of device (hard disks, storage...) isn't done at the moment.
You mean when the high word is not 0, right ?
I'll add a check for the 0x10000 and 0x20000 bits, and will dispatch the call to either a VxD or a device handler. Is that ok ?Can I use the same VxD list as for (HIWORD(dwIoControlCode) == 0 ) ?
Laurent Pinchart
Laurent Pinchart a écrit :
the control on "device" handles is done when the high word of the control code is non 0.
as of today (but it's a bit hacky) handles to "device" and VxD:s are
You're refering to both VxDs and WDM (.sys) drivers, right ?
just VxDs
How does the server find the correct low word of the client ID ? The driver I want to implement has a device type of 0xef00 (value passed to IoCreateDevice). I added a field to the VxD table with id set to 0xef00. Does wine, when I call CreateFile( "\\.\MyDevice", ... ), check that table and set the client ID low word to the proper value ?
this is poorly supported at the moment. only a few of the proper \.\ syntax is handled (see files/file.c for the details)
If the 0x20000 bit is set, it's in fact a handle a device. Driver A: through Z: are mapped to 0 to 25 values (in the low word)
Otherwise, it's a handle to the old DOS named devices (with their old IDs too)
I think we should handler those cases in a new device handler (which would just test if the device is a CDROM for now).
all of this needs to be revisited, but this is not a simple task
So, back to DeviceIoControl when the high word of the io control code is 0. We expect device handle in that case (but don't test the 0x20000 bit for error reporting), and then try to check if the device (from it's driver letter) is a CDROM, and if so apply the io control on it. Support of io
control on other types of device (hard disks, storage...) isn't done at the moment.
You mean when the high word is not 0, right ?
yes
I'll add a check for the 0x10000 and 0x20000 bits, and will dispatch the call to either a VxD or a device handler. Is that ok ?Can I use the same VxD list as for (HIWORD(dwIoControlCode) == 0 ) ?
I don't follow you, you only need the VxD list when the hiword is 0 A+
I'll add a check for the 0x10000 and 0x20000 bits, and will dispatch the call to either a VxD or a device handler. Is that ok ?Can I use the same VxD list as for (HIWORD(dwIoControlCode) == 0 ) ?
I don't follow you, you only need the VxD list when the hiword is 0
I'm trying to implement support for a WDM driver (.sys). The driver registers itself by calling IoCreateDevice with DeviceType set to 0xef00.
The user program calls CreateFile( "\\.\MyDriver", ... ) and uses the returned handle in the call to DeviceIoControl, with dwIoControlCode set to 0xef002407. The dwIoControlCode higword is not 0.
Shouldn't we have a handler list, similar to the VxD list in this case ?
Laurent Pinchart
Laurent Pinchart a écrit :
I'll add a check for the 0x10000 and 0x20000 bits, and will dispatch the call to either a VxD or a device handler. Is that ok ?Can I use the same VxD list as for (HIWORD(dwIoControlCode) == 0 ) ?
I don't follow you, you only need the VxD list when the hiword is 0
I'm trying to implement support for a WDM driver (.sys). The driver registers itself by calling IoCreateDevice with DeviceType set to 0xef00.
I don't think we should support loadable WDM drivers for now. So a hard coded table, as we do for VxD should be just fine. However, the internal structures may be reviewed, so we can install (but not load) devices with the right device types (in fact checking that the device type in the io request matches the type of the device) A+