Win32 specific implementation details¶
This document details implementation details specific to Microsoft Windows.
Serial device management¶
Windows NT can handle serial devices, and provide specific interfaces to communicate with them.
For more information, see Serial Communications in Win32.
Serial device detection using the Win32 API¶
In order to list available serial devices using the Win32, the
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
registry key
contents is read, therefore making the same operations as GetCommPorts
with better compatibility.
Serial link handling using the Win32 API¶
Cahute can open a serial link using the Win32 API with the
cahute_open_win32_serial_link()
function.
This function interprets the provided name or path as a path,
and attempts at opening the device using CreateFile
.
If it succeeds, it calls SetCommTimeouts
with ReadTimeoutInterval
set
to MAXDWORD
in order to only read what is directly available, and create
the event for the overlapped object using CreateEvent
.
If it succeeds, the link can then be opened, with a HANDLE
with
Overlapped I/O and an internal buffer.
The available operations use :
Closing uses
CloseHandle
and, optionally,CancelIo
;Receiving uses
ReadFile
,WaitForSingleObject
, andGetOverlappedResult
;Sending uses
WriteFile
andWaitForSingleObject
, and depending on whether the second function succeeded or not, eitherGetOverlappedResult
orCancelIo
, to ensure we don’t have any buffer reads post-freeing the link;Serial params setting uses
SetCommState
.
Note
If WaitForSingleObject
on receiving ends with WAIT_TIMEOUT
, i.e.
if a timeout has occurred, rather than cancelling the call, the
respective function lets the call continue in the background.
This is because the function is also used by the CESG driver usage implementation in Cahute, which may crash under some circumstances when trying to cancel an overlapped read call; see #17 for more information.
The same overlapped event is used between calls to the receive implementation, until it completes or the link is closed.
Rather than reading directly in the provided buffer, the implementation reads into an internal buffer first, then copies the contents read in the internal buffer in the provided buffer. This is because, while the provided buffer may change from one call to the other, the internal buffer doesn’t, and the operation can safely continue asynchronously in between calls.
USB device management¶
Win32 implements USB devices through drivers, either generic or specific.
For now, most of the USB device management is done using libusb; see libusb specific implementation details for more information.
Note
In order to support older versions of the platform not supported by libusb, such as Windows 2000, we are to implement USB device management on Win32 without libusb; see #73 for more information.
USB driver support¶
Cahute can communicate with USB calculators through the following drivers:
Name |
Description |
Compatibility |
Supported |
---|---|---|---|
Generic volume driver |
The generic volume driver, used when the device presents an UMS interface through its descriptors. |
All versions |
Yes |
CASIO’s official driver provided with FA-124. See Device communication using CESG502 for more information. |
Windows 2000 (NT 5.0)+ |
Yes |
|
Official generic USB device driver by Microsoft. Can be selected automatically if the calculator presents WCID attributes. |
Windows Vista (NT 6.0)+ |
Through libusb |
|
KMF-based driver that comes with the eponym library, with the same interface as WinUSB. |
Windows XP (NT 5.1)+ |
Through libusb |
|
Driver that comes with the eponym library. |
Windows 2000 (NT 5.0)+ |
Through libusb |
|
Driver that comes with the eponym library. libusb loads a dedicated library when using it. |
Windows XP (NT 5.1)+ |
Through libusb |
See libusb-compatible kernel drivers for more information.
Device communication using CESG502¶
CESG502 is distributed with FA-124, and is necessary for CASIO’s software to successfully detect and communicate calculators connected using USB. This means it is necessary to support it for any user program that co-exists with it to work with CASIO’s driver.
CESG502 abstracts both Serial transport over USB bulk and
USB Mass Storage (UMS) transport behind a stream-oriented device.
It can be detected using libusb, but cannot be opened using the same tool;
one must use detection with SetupAPI or cfgmgr32, check that the device
driver is CESG502, and if it’s the case, open and use the device using
fileapi (CreateFile
, ReadFile
, WriteFile
, CloseFile
).
Note
It is possible to access device instance properties on Windows OSes before Vista, e.g. Windows XP; see Accessing Device Instance Properties (Prior to Windows Vista) for more information.
It uses {36fc9e60-c465-11cf-8056-444553540000}
, the same GUID as
generic USB devices, which is normally forbidden for Independent
Hardware Vendors (IHV) such as CASIO, so this key cannot be used to
uniquely identify the driver.
Cahute currently matches the service (CM_DRP_SERVICE
) to PVUSB
,
since this is the value encountered in the wild.
Device opening using a device address¶
We can attempt to find a device through the Win32 API using CfgMgr32:
If the underlying driver to the device is identified as CESG502, we open a serial over USB bulk device with the CESG implementation;
Otherwise, we look for disk drive then volume devices via bus relations, and use the volume device interface as UMS.
Serial over bulk link implementation, using the CESG driver¶
Devices using the CESG502 driver, once opened, behaves mostly like native serial devices; see Serial link handling using the Win32 API for more information. It however has the following differences:
Serial specific parameters are not available (as this is USB);
It does the device enabling control flow automatically when the device is connected;
On reading, the provided buffer must be large enough to get all of the available data at once.
If using Protocol 7.00, 4096 bytes is enough, however in other contexts such as Protocol 7.00 Screenstreaming, 32768 bytes is safer.
UMS link implementation¶
Devices using the native SCSI driver (abstracting UMS away), usually through
the volume manager (VOLMGR
), can be used to implement calculators
presenting UMS.
Once opened using a HANDLE
, operations use the following mechanisms:
Closing uses
CloseHandle
;Requesting using SCSI uses
DeviceIoControl
withIOCTL_SCSI_PASS_THROUGH_DIRECT
.
File handling using the Win32 API¶
When creating or opening a file on Win32, CreateFile
is called with the
appropriate options. Then, depending on the situation:
On creation, we want to set the file size to the provided one.
In order to do this, we call
SetFilePointer
to seek the provided file size fromFILE_BEGIN
,SetEndOfFile
to set the file size explicitely, and finally,SetFilePointer
again to seek toFILE_BEGIN
.On reading, we want to get the current file size.
In order to do this, we call
SetFilePointer
to seek 0 bytes fromFILE_END
, which returns the current file size, then the same function to seek 0 bytes fromFILE_BEGIN
.
Note
Files are opened without exclusivity, meaning another program may modify the file while it is being read or written.
When opening standard output on Win32, we call GetStdHandle
with
STD_OUTPUT_HANDLE
.
Once a file or stdout is opened, we have a HANDLE
we can then use with
the following operations:
Closing uses
CloseHandle
(except for the standard output, which we must not close);Reading uses
ReadFile
;Writing uses
WriteFile
;Seeking uses
SetFilePointer
.