Share via

Process Monitor does not capture IRP_MJ_CREATE for serial port (character device) opens

Boilerplate4U 0 Reputation points
2026-04-12T19:53:01.3466667+00:00

Hi,

I have been investigating why Process Monitor does not capture CreateFile (IRP_MJ_CREATE) calls against serial ports (character devices) and I would appreciate some clarification on the architecture.

Setup:

  • Windows Server 2022
  • A userspace program opening COM14 -> \Device\Serial13 (CH340 USB-serial adapter, driver CH341SER.SYS from wch.cn)
  • Same behavior observed with COM10 -> \Device\Silabser0 (Silicon Labs CP210x USB-serial adapter, driver silabser.sys)
  • Process Monitor v3.x, running as Administrator
  • Filter: Process Name is [program] + Operation is IRP_MJ_CREATE

Issue:

When the program opens either port, the API Monitor tool (rohitab.com) clearly shows the following call:

CreateFileA("\\.\COM14", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)

The call succeeds and returns a valid handle. However Sysinternals Process Monitor shows nothing for either device, even with the IRP_MJ_CREATE filter active and all other filters removed.

My understanding:

NtCreateFile is the single kernel entry point for all CreateFile variants regardless of target device type. The Object Manager resolves "\.\COM14" to "??\COM14" which maps to "\Device\Serial13" or "\Device\Silabser0" depending on the adapter. I/O Manager then dispatches IRP_MJ_CREATE down the device stack.

As I understand it, IRP_MJ_CREATE is not filesystem-specific. It is dispatched for all device types including character devices.

My question:

Is Process Monitor implemented as a Filter Manager minifilter (FltRegisterFilter), and if so does Filter Manager only attach to filesystem device stacks, leaving character device stacks uncovered? Or is there another reason why IRP_MJ_CREATE against "\.\COM14" or "\.\COM10" is not captured?

For reference, a WDM upper filter driver registered for the Ports device class (GUID {4D36E978-E325-11CE-BFC1-08002BE10318}) via IoAttachDeviceToDeviceStack would sit in the device stack and would see IRP_MJ_CREATE for the same open. This suggests the limitation is specific to how Process Monitor attaches to device stacks rather than a fundamental limitation of IRP_MJ_CREATE visibility.

Is this a known limitation, a design decision, or am I missing something in the filter configuration?

Thanks!

Sysinternals
Sysinternals

Advanced system utilities to manage, troubleshoot, and diagnose Windows and Linux systems and applications.

0 comments No comments

2 answers

Sort by: Most helpful
  1. Boilerplate4U 0 Reputation points
    2026-04-12T20:00:33.6433333+00:00

    Does Portmon really work on Win 10/11 or Server 2022 ??

    0 comments No comments

  2. Q&A Assist
    2026-04-12T19:53:17.01+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Process Monitor does not sit in arbitrary device stacks and therefore does not see IRP_MJ_CREATE requests for serial (PORTS) class devices such as COM ports. That behavior is a consequence of its architecture rather than a limitation of IRP_MJ_CREATE itself.

    From the available information:

    • IRP_MJ_CREATE is a general I/O request type used across many device types, including file systems and other kernel-mode drivers. Any driver or filter that is layered in the appropriate device stack and that handles the same IRP_MJ_* set as the system-supplied driver will see those requests.
    • A WDM upper filter attached with IoAttachDeviceToDeviceStack to the Ports device class, as described, will indeed see IRP_MJ_CREATE for COM ports, because it is explicitly layered into that device stack.
    • Process Monitor, however, is designed around monitoring file system and registry activity (and related I/O paths) rather than acting as a general-purpose filter for all device classes. Its implementation is based on attaching where the system-supplied infrastructure for those subsystems expects filters (for example, file system filter stacks), not on attaching to arbitrary character-device stacks such as serial ports.

    By contrast, Portmon is specifically implemented to monitor serial and parallel ports by inserting a filter driver directly into the serial/parallel device stacks:

    • On NT-based systems, Portmon enumerates serial and parallel ports from the registry and, when a port is selected, uses ZwCreateFile and IoAttachDeviceByPointer to attach its own filter device object to the target device object. From that point, the Portmon driver sees all requests aimed at that device, including IOCTLs and create/close operations.
    • On Windows 95/98, Portmon uses VCOMM service hooking to intercept all serial/parallel access.

    That design explicitly targets serial/parallel stacks, which is why Portmon can see operations on COM ports while Process Monitor does not.

    Given this, the absence of IRP_MJ_CREATE events for \\.\COM14 or \\.\COM10 in Process Monitor is a design/architecture limitation: it does not attach into the serial-port device stacks where those IRPs flow. The behavior described matches that design and is not due to filter misconfiguration or a fundamental limitation of IRP_MJ_CREATE visibility.

    For detailed serial/parallel monitoring, Portmon (or a custom upper filter for the Ports class) is the appropriate tool; Process Monitor is not intended to provide full coverage of character-device I/O such as COM-port opens.


    References:

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.