Free Serial Port Monitor Source Code
IntroductionFirst of all excuse my English since it is not my native language and this is my first article. In this article, I'd like to share 'what I know' about how to monitor serial ports. Please note that this is about 'what I know' and I could be wrong about what I understand about driver programming, specially in this article. If you find out that I am wrong, please let me know and we can discuss it further.So, what is a serial port monitor?
Well, I believe you know what it is. The basic idea of this serial port monitor is: create a system driver and then add the filter driver functionality to it. Okay, let's get on to the detail.I.
Serial Port Monitors
System driverAs you can see in the source, this is just a system driver (without real hardware) and it implements minimal dispatch functions for the system driver. If you want to see the requirements of a system driver, please take a look at MSDN. In this driver, I simply forward an IRP sent to this driver to the lower level driver as the default handler and use 'standard PnP and Power dispatch handling' as the WDK suggest. This driver also handles open, clean up, close, read, and control request, plus handles some requests as a serial port driver IRP handler requirement in WDK (Window Driver Kits).II. Attach to and detach from target deviceWhen a client application sends an IO control request to attach to a target device, IOCTLDKPORTMONATTACHDEVICE with a string parameter of the serial port name, the driver does this:.Driver gets the top of the target device object identified by the string parameter in the IOCTLDKPORTMONATTACHDEVICE request with IoGetDeviceObjectPointer. Extern PDEVICEOBJECT gpThisDevObj.NTSTATUS DkCreateClose(PDEVICEOBJECT pDevObj, PIRP pIrp). If (pDevObj!= gpThisDevObj) return DkTgtCreateClose(pDevExt, pIrp).III.
Handling an IO request that is coming to our device objectBefore we discuss further about handling requests, I'd like to say a little bit about the queue in this driver. This driver uses two kinds of queues, one for handling an IRP (Cancel-Safe queue as WDK suggested) and another for collecting data (simple First In First Out data queue / FIFO data queue). We discuss how we collect data later in the next section.Our driver handles open ( IRPMJCREATE), close ( IRPMJCLOSE), clean up ( IRPMJCLEANUP), read ( IRPMJREAD), and control ( IOCTLDKPORTMONATTACHDEVICE and IOCTLDKPORTMONDEATCHDEVICE) requests.
As you can see in the source, open, close, and clean up requests are handled in the same dispatch routine, that is DkCreateClose. For open request, we just initialize our FIFO data queue, complete the request with STATUSSUCCESS, and returns STATUSSUCCESS. For clean up request, we detach the device (if any, as the detach function state), clean the data queue and Cancel-Safe queue, and then complete the request. For close request, it just 'accepts' it, completes the request, and returns STATUSSUCCESS.When we receive a read request from the client application program, we retrieve data from FIFO data queue. If there is data, we copy it to the system buffer which 'represents' the user buffer, and then remove/destroy/delete/free it, and then complete the request with STATUSSUCCESS and with the size of data we get from the FIFO data queue. If there is no data present in the FIFO data queue, we queue the IRP to Cancel-Safe queue then return a pending status, and indicate that the IRP is queued and will be completed later by another function in this driver ( DkTgtCompletePendedIrp function).
Best Free Serial Port Monitor
This is the code fragment in file DkIoReq.c, in function DkReadWrite.IRPMJCREATE.IRPMJWRITE.IRPMJREAD.As you can see, IRPMJWRITE comes just after IRPMJCREATE. This is because this port monitor does not monitor 'IRP state'. It collects data after/before the driver forwards the request, as we discussed in the previous subsection about collecting data above.This driver doesn't check the status of the request whether they succeed or fail.VI. Installation and usageThis driver only supports Windows XP x86. If you use this on other platform than Windows XP, you need to recompile it under the target you want.
So this procedure below is only valid for Windows XP.IV.