## The PNPMON Sample

The PNPMON Sample accompanies Chapter 6 and illustrates how to intercept Plug and Play events in kernel mode. It also incidentally illustrates how to dynamically load a kernel-mode driver from a user-mode application and how to call NT kernel services from a Windows 98/Me VxD.

The sample includes three components:

- TEST.EXE (TEST subdirectory) is a user-mode test program for PNPMON.SYS and PNPMON.VXD.
- PNPMON.SYS (SYS subdirectory) is a kernel-mode driver that doesn’t service any hardware at all. It extends the operating system for the benefit of the TEST application under Windows XP.
- PNPMON.VXD (VXD subdirectory) is a virtual device driver (a VxD) that doesn’t service any hardware at all. It extends the operating system for the benefit of the TEST application under Windows 98/Me.

### Building PNPMON

To build PNPMON.SYS, follow the general instructions for building a WDM sample. The Microsoft Visual C++ project file is named PNPMON.DSP in the SYS subdirectory.

To build PNPMON.VXD, open the Microsoft Visual C++ project named PNPMON in the VXD subdirectory. Select the Build command from the Build menu. The build script depends on your having set the 98/MeDDK environment variable to the directory where you installed the Windows 98/Me DDK. Depending on which version of the DDK you have, you may need to adjust the include or library paths in the project settings.

To build TEST.EXE, follow the general instructions for building user-mode programs. The Microsoft Visual C++ project file is named TEST.DSP in the TEST subdirectory.

### Testing PNPMON

If you're testing in Windows 98/Me, and if you built the PNPMON.VXD project, the build script will have copied PNPMON.VXD to your system directory. If you didn't perform a build, you should copy PNPMON.VXD from the VXD\DEBUG subdirectory to the system directory by hand.

If you're testing in Windows XP, and if you built the PNPMON.SYS project, the build script will have copied PNPMON.SYS to your Drivers directory. If you didn't perform a build, you should copy PNPMON.SYS from the sys\objchk_wxp_x86\i386 subdirectory to the Drivers directory by hand.

Launch the TEST.EXE program from the TEST\DEBUG subdirectory. TEST will present a simple dialog box with the title "PnP Kernel-Mode Notification Monitor". You should also have the TEST program for the PNPEVENT sample simultaneously active.

Follow the PNPEVENT testing instructions and notice that the PNPMON\TEST program also logs messages about PnP events. These events are being collected by the kernel-mode driver (PNPMON.SYS or PNPMON.VXD, depending on which platform you use for testing) and retrieved by TEST.

In Windows XP only, you can try an additional test. With both test programs active and a PNPEVENT device in the system, press the Send Event button in PNPEVENT\TEST’s dialog. The button causes PNPEVENT.SYS to send a custom PnP notification via IoReportTargetDeviceChangeAsynchronous. Target device changing reporting is not supported in Windows 98/Me, so the button has no effect there.

### What to look for

There are three interesting things in this sample:

- Kernel-mode PnP notifications: Look at the file control.cpp in the sys directory, with particular attention to the functions named Register, Deregister, and OnPnpNotify.
- Dynamically loading a driver: Look at helper.cpp in the test directory. Note also that the DriverEntry routine in the driver creates a device object and does not set an AddDevice pointer in the DRIVER_OBJECT -- this makes PNPMON.SYS a legacy driver instead of a WDM driver.
- Calling WDM from a VxD: Check out pnpmon.cpp in the vxd directory, which mixes VxD and WDM system calls. In order to call WDM, the VxD links with wdmvxd.clb from the Windows 98 DDK.