Tech Support > Microsoft Windows > Drivers > Writing a Port Monitor for 200/XP/2003
Writing a Port Monitor for 200/XP/2003
Posted by Brad McCready on February 23rd, 2004


Hi Guys,

I am trying to write a fairly simple port monitor to run on 2000/XP/2003
using visual studio c++ .net. Trying to install the monitor using a .inf,
results in an error, it seems that InitializePrintMonitor2 is called
correctly, but then the DLL is detached and no other functions are called. I
was expecting the Spooler to stay attached to the DLL, and at least the
EnumPorts function to be called.

If I manually add the monitor to the registry, same thing happens - Spooler
attaches to the monitor dll, InitializePrintMonitor2 is called, then the
spooler detaches again.

The only functions exported are my DLLMain and InitializePrintMonitor2, do I
need to export the other functions referenced in my MONITOR2 structure too?

I believe my MONITOR2 structure is filled correctly, you can see my very
simple InitializePrintMonitor2 function below. Am I missing something here,
what's the best way to debug a print monitor?

LPMONITOR2 WINAPI InitializePrintMonitor2(PMONITORINIT pMonitorInit,PHANDLE
phMonitor)
{
if ( Is_Win2000( ) )
Monitor2.cbSize = MONITOR2_SIZE_WIN2K;

*phMonitor = (PHANDLE)pMonitorInit;
return &Monitor2;
}


Thanks for your help.

Brad


Posted by Ashwin [MS] on February 24th, 2004


Firstly, I suggest that you build using the DDK build environment instead of
VS. Second, are you basing your driver atleast loosely on the localmon
sample in the DDK? I suggest that you start with that sample and then
add/delete code that is specific to your scenario. If you still have a
problem, I suggest that you contact the DDK Support group at
Microsoft...they will be able to help you write a simple "null" local
monitor.

--
- Ashwin

Microsoft Printing, Imaging and Fax Team
This posting is provided "AS IS" with no warranties, and confers no rights.

"Brad McCready" <tr0n-remove@optusnet.com.au> wrote in message
news:eDrmxOm%23DHA.3668@TK2MSFTNGP09.phx.gbl...


Posted by Eric Brown on February 24th, 2004


Brad,

You only need DllMain and the Initialize entry points in your .def file.

Try this as your handle instead
*phMonitor = (PHANDLE)&Monitor2;

You can narrow down whether you have an .inf file problem by installing the port monitor
manually. Just create the correct registry key under Monitors (and Ports if necessary).
As a reference, see the registry keys for any other port monitors installed on your system
already, it's fairly trivial (but do double-check you've done it right or you'll go off on
a wild goose chase). You might have to do a "net stop spooler" and "net start spooler"
afterwards for the spooler to know they're there, not sure on that.

Also, what functions you do or don't have defined in your monitor2 structure might affect
this. If you don't get past it, post your monitor2 structure as well

Eric


"Brad McCready" <tr0n-remove@optusnet.com.au> wrote in message
news:eDrmxOm%23DHA.3668@TK2MSFTNGP09.phx.gbl...


Posted by Brad McCready on February 25th, 2004


The problem happens whether the port monitor is installed by .inf file or
manually through the registry. I have added a whole lot of
OutputDebugStrings throughout, I can attach WinDbg to the process
spoolsv.exe and watch as it attaches to the port monitor.

InitializePrintMonitor2 is called and finishes, then the spoolsv.exe
detaches from the port monitor, and it's not called again. I am assuming
that I am either doing something incorrectly in InitializePrintMonitor2 or I
am returning an incorrect Value. Whats the best way to go about finding the
problem?

I tried your suggestion of *phMonitor = (PHANDLE)&Monitor2, but the same
problem occurs.


Here is my Monitor2 structure, all the fuctions are defined, but currently
only have a OutputDebugString statement in them.

MONITOR2 Monitor2 = {
sizeof(MONITOR2), //cbsize
MyEnumPorts, // EnumPorts
MyOpenPort, // OpenPort
NULL, // OpenPortEx
MyStartDocPort, // StartDocPort
MyWritePort, // WritePort
MyReadPort, // ReadPort
MyEndDocPort, // EndDocPort
MyClosePort, // ClosePort
NULL, // AddPort
NULL, // AddPortEx
NULL, // ConfigurePort
NULL, // DeletePort
NULL, // GetPrinterDataFromPort
NULL, // SetPortTimeOuts
MyXcvOpenPort, // XcvOpenPort
MyXcvDataPort, // XcvDataPort
MyXcvClosePort, // XcvClosePort
NULL, // Shutdown
NULL // SendRecvBidiDataFromPort
};

LPMONITOR2 WINAPI InitializePrintMonitor2(PMONITORINIT pMonitorInit,PHANDLE
phMonitor)
{
if ( Is_Win2000( ) )
Monitor2.cbSize = MONITOR2_SIZE_WIN2K;

*phMonitor = (PHANDLE)pMonitorInit;
return &Monitor2;
}


"Eric Brown" <ebrown1@austin.rr.com> wrote in message
news:fkO_b.35106$M76.23852@fe2.texas.rr.com...


Posted by Eric Brown on March 2nd, 2004


Another thing you can do is step through the spooler code to get an idea of what it's
going after the init.

Is it possible your monitor is initializing correctly, and just not being used?

Eric

"Brad McCready" <tr0n-remove@optusnet.com.au> wrote in message
news:uuprHO2%23DHA.3668@TK2MSFTNGP09.phx.gbl...


Posted by Eric Brown on March 2nd, 2004


Brad,

Also, do you have a resource file with version info? I recall the spooler handles port
monitors slightly differently based on what the target OS version is. Maybe Ashwin can
clarify this.

Eric


Posted by Carey Gregory on March 2nd, 2004


"Eric Brown" <ebrown1@austin.rr.com> wrote:

No, his enumeration function should still get called in that case. And
the phMonitor parameter shouldn't matter either since that's a pointer to
private memory.

I didn't go through the MONITOR2 struct to see if all the required functions
are present, but that's one thing to check. Another possibility is some
sort of stack or memory corruption.

Oh, and the spooler attaching and detaching is normal.


--
Carey Gregory
Windows Print Drivers & Components
http://www.gw-tech.com

Posted by Ashwin [MS] on March 3rd, 2004


Basically, the default local port monitor works differently from how a
custom/OEM port monitor should work.

So there are fundamental differences between the way the localmon sample
operates and the way an OEM port monitor needs to operate.

- The major difference between the localmon sample and an OEM port monitor
is regarding access to the registry on the system. In the localmon sample
registry information is stored in:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports

However, this is the location where the spooler process (localspl.dll) reads
all the ports that it manages. By adding any OEM port monitor ports here
localspl will believe that it is meant to manage these ports as well and the
OEM port monitor will not be used. Also, if using the localmon sample as a
template, all local ports will be duplicated as the localmon sample will
enumerate the ports just as the spooler will.

- The registry location intended for port monitors is:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Print\Monitors

Under this key in the registry is where the port names that are managed by
this port monitor are intended to be written. For example, if your port
monitor is named "OEM Port Monitor" then under that key, a new key should be
created for managing the ports that "OEM Port Monitor" manages.

- The localmon sample interacts with the registry by using the SDK function
GetProfileString and WriteProfileString. These functions rely on the
registry having a IniFileMapping key that maps the lpAppName parameter to an
actual location in the registry. OEM Port monitors should use other
registry manipulation functions, such as the RegXXXKey functions described
in the SDK (see Registry for more information) since OEM port monitors will
not have values in the IniFileMapping key.


--
- Ashwin

Microsoft Printing, Imaging and Fax Team
This posting is provided "AS IS" with no warranties, and confers no rights.

"Eric Brown" <ebrown1@austin.rr.com> wrote in message
news%Z0c.27786$OH4.25069@fe2.texas.rr.com...


Posted by Carey Gregory on March 3rd, 2004


"Ashwin [MS]" <ashwinn@online.microsoft.com> wrote:

Good point (I made that mistake the first time I tried writing a port
monitor), but as I recall the symptoms he's seeing would be different if he
was making that mistake.


--
Carey Gregory
Windows Print Drivers & Components
http://www.gw-tech.com


Similar Posts