access parallel port from driver

Hi All,

I am working on a virtualization product where I need to access the parallel port hardware from VM.

Based on the porttalk.sys sample driver, I can access parallel port and use READ_PORT_UCHAR and WRITE_PORT_UCHAR calls for reading and writing to the hardware…

But now comes into picture parport.sys parallel port driver provided in Windows… According to MS documentation this driver should be used to interact with the hardware… How can I use it ?

Is there any problem with using a simple driver that calls READ_PORT_UCHAR and WRITE_PORT_UCHAR calls ?

Please suggest…

?
Thanks
Anshul Makkar
www.justkernel.com

anshul makkar wrote:

I am working on a virtualization product where I need to access the
parallel port hardware from VM.

Based on the porttalk.sys sample driver, I can access parallel port
and use READ_PORT_UCHAR and WRITE_PORT_UCHAR calls for reading and
writing to the hardware…

But now comes into picture parport.sys parallel port driver provided
in Windows… According to MS documentation this driver should be used
to interact with the hardware… How can I use it ?

Is there any problem with using a simple driver that calls
READ_PORT_UCHAR and WRITE_PORT_UCHAR calls ?

Sure, but it’s up to you to decide whether the problems are fatal. The
parallel port driver owns those I/O ports. While it is alive, it is
allowed to assume that it is the only component accessing them.

Is this only for debugging? If you’re shipping something, then you need
to be a good neighbor and follow the rules. That means either
investigating the partport.sys ioctls, or installing your own driver in
Device Manager. If this is only for debugging, then you can disable the
port in Device Manager. That causes parport.sys to unload. Or, you
could just close your eyes and hope – the odds are that parport.sys
won’t access the ports unless there is printing going on.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

It is going to be a Very Bad Idea to go for the port directly. It is
generally a Very Bad Idea to assume there is even a parallel port
available on most modern computers. The interface is, as far as I
remember, officially deprecated.

If there is a parallel port, it has already been claimed by parport.sys
and it is therefore not available to you.

In the past, I’ve usually been asked this question by someone who has
hacked together some device, often homebuilt, but frighteningly frquently,
some proposed product. Often the question arises because the device has
some critical timing constraint (either input rate or response time) which
must be met. The prototype was tested on some old MS-DOS machine in the
hardware lab.

I would first suggest that plugging anything at all into the parallel port
(including printing devices) should be considered A Really, Really Bad
Idea. Among other very real problems, the problem of Fried Motherboard
Syndrome from improperly-designed static discharge protection is
significant. Decades ago, when we thought about doing a student hardware
lab with a $15,000 minicomputer, we looked into building an opto-isolated
bus interface so there was never an actual electrical connection between
the external device and the backplane. The optoisolators would be
socketed so if they were fried they could be easily replaced. But we
never got the budget for the lab, so the board was never built.

If you are comfortable with the idea of using the parallel port, then you
will want to look at IoAttachDeviceToDeviceStack, or whatever it is called
in KMDF, to establish your device as a device that wants to communicate to
the lower-level driver. I have no idea what can go wrong here, but the
failure modes (such as what happens if a user tells Windows that a printer
is attached to that port) are going to be profoundly ugly.

I’d suggest buying some generic parallel I/O card and using its driver.
You will save much pain and agony.
joe

Hi All,

I am working on a virtualization product where I need to access the
parallel port hardware from VM.

Based on the porttalk.sys sample driver, I can access parallel port and
use READ_PORT_UCHAR and WRITE_PORT_UCHAR calls for reading and writing to
the hardware…

But now comes into picture parport.sys parallel port driver provided in
Windows… According to MS documentation this driver should be used to
interact with the hardware… How can I use it ?

Is there any problem with using a simple driver that calls READ_PORT_UCHAR
and WRITE_PORT_UCHAR calls ?

Please suggest…

 
Thanks
Anshul Makkar
www.justkernel.com


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@flounder.com wrote:

It is going to be a Very Bad Idea to go for the port directly. It is
generally a Very Bad Idea to assume there is even a parallel port
available on most modern computers. The interface is, as far as I
remember, officially deprecated.

If there is a parallel port, it has already been claimed by parport.sys
and it is therefore not available to you.

If you are comfortable with the idea of using the parallel port, then you
will want to look at IoAttachDeviceToDeviceStack, or whatever it is called
in KMDF, to establish your device as a device that wants to communicate to
the lower-level driver. I have no idea what can go wrong here, but the
failure modes (such as what happens if a user tells Windows that a printer
is attached to that port) are going to be profoundly ugly.

True but there is a way to resolve it. The MS parport.sys drive allows
another driver to take control of the parallel port registers in a
controlled manner and then give them back when it is finished so it is
possible to do this cleanly. Once you have claimed the device this way
parport.sys blocks all other accesses. I’ve written drivers that do this
quite a few times in the past (long before USB even existed) and it
works reliably and so much better than solutions which involved
uninstalling parport.sys. This will only work if the parallel port in
question actually looks like an old school ISA device. In a lot of
modern machines (especially laptops) they are actually USB devices
anyway and you can forget direct register access.

I am slightly astonished as to why anyone would take this route in the
modern PC environment. If you are interfacing to old hardware then you
don’t have much choice but for anything new USB is a much better
candidate. In fact even for legacy hardware I’d probably consider some
sort of microcontroller with a usb function block to deal with the IO
side of things rather than trying to do it on a PC.

Mike

Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: xxxxx@mpcdata.com web: www.mpcdata.com
tel: +44 (0) 1225 710600 fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635

Hi,
I am trying to learn how the driver stack works and I can take this parport.sys (in current thread )as an example.
We have a driver available, like here in this case its parport.sys. Now we want to use this driver by attaching our driver above it in the device stack… How can this be done… Do we need to write a filter driver on top of parport.sys or a normal driver and then attach it to device stack.

Further just saw some docs on parallel port system driver, I couldn’t find any IOCTL for read and write… Most of the IOCTL relate to controlling the parallel port… So how can we read and write using this parport.sys .

Another point, if we have a parport.sys driver, then whats the need to create another driver on top of it… Can’t we just write a user mode app that will call Createfile(//Device/LPT1), and then ReadFile and Writefile.

Sorry for asking such basic questions but I couldn’t find practical answers to these in books.

If you have some sample source code, please suggest.

Thanks
Alan Hopes.

Well you can attach a driver above a driver, this is the filtering case.
Or you can access a driver without being in the same stack, it depends
on what you wish to do. If you want to take complete control of the
lower driver, then filtering is probably best. If you just need to
access the device, then having to handle all the calls to the device is
overkill so avoid the filtering.

A read and write are done with separate IRP’s not IOCTL, but IRP_MJ_READ
and IRP_MJ_WRITE.

As far as why another driver, it really depends on what you are trying
to do. Say you have a device connected to the parport, if this is a
totally unique device and there will only be one program that accesses
it, then as you suggest just write an application. But what happens if
multiple applications need to access the device, or the device acts like
a standard windows device (not likely but say you had a disk that
attached to the parport), in that case you want a driver.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> Hi,
> I am trying to learn how the driver stack works and I can take this parport.sys (in current thread )as an example.
> We have a driver available, like here in this case its parport.sys. Now we want to use this driver by attaching our driver above it in the device stack… How can this be done… Do we need to write a filter driver on top of parport.sys or a normal driver and then attach it to device stack.
>
> Further just saw some docs on parallel port system driver, I couldn’t find any IOCTL for read and write… Most of the IOCTL relate to controlling the parallel port… So how can we read and write using this parport.sys .
>
> Another point, if we have a parport.sys driver, then whats the need to create another driver on top of it… Can’t we just write a user mode app that will call Createfile(//Device/LPT1), and then ReadFile and Writefile.
>
> Sorry for asking such basic questions but I couldn’t find practical answers to these in books.
>
> If you have some sample source code, please suggest.
>
> Thanks
> Alan Hopes.

Thanks for your replies…

It’s a driver for a shippable product (not testing in labs), so , as suggested, I will go with the approach where in I will create a driver that will attach to lower layer parport.sys driver.

Further , following suggestions from some other threads
"There is already a standard system driver (parport.sys) that owns the parallel ports. Yes, you could write a kernel driver that talks directly to the parallel port I/O ports, and expose ioctls to user-mode code. However, such a driver is just as bad as inpout32.dll, because it is using I/O ports that it does not own.

The pedantically correct method is to write a driver that talks to parport.sys, and uses its services to gain access to the parallel port. That takes a fair amount of effort, certainly more than just banging the ports. If you hope to ship this out as a commercial product, then you probably want to do that. If this is for internal, diagnostic, or lab use, then I wouldn’t go to the trouble."

The IRPs received from upper layer will be forwarded to lower level parport.sys (read, write and controlling IRPs). So it will be a kind of filter driver.

Please suggest if my approach is correct and also if, based on your experience,? there are any problems that can be foreseen.
?
Thanks
Anshul Makkar
www.justkernel.com


From: Mike Pumford
To: Windows System Software Devs Interest List
Sent: Monday, 20 February 2012 3:36 PM
Subject: Re: [ntdev] access parallel port from driver

xxxxx@flounder.com wrote:
> It is going to be a Very Bad Idea to go for the port directly.? It is
> generally a Very Bad Idea to assume there is even a parallel port
> available on most modern computers.? The interface is, as far as I
> remember, officially deprecated.
>
> If there is a parallel port, it has already been claimed by parport.sys
> and it is therefore not available to you.
>

> If you are comfortable with the idea of using the parallel port, then you
> will want to look at IoAttachDeviceToDeviceStack, or whatever it is called
> in KMDF, to establish your device as a device that wants to communicate to
> the lower-level driver.? I have no idea what can go wrong here, but the
> failure modes (such as what happens if a user tells Windows that a printer
> is attached to that port) are going to be profoundly ugly.
>
True but there is a way to resolve it. The MS parport.sys drive allows another driver to take control of the parallel port registers in a controlled manner and then give them back when it is finished so it is possible to do this cleanly. Once you have claimed the device this way parport.sys blocks all other accesses. I’ve written drivers that do this quite a few times in the past (long before USB even existed) and it works reliably and so much better than solutions which involved uninstalling parport.sys. This will only work if the parallel port in question actually looks like an old school ISA device. In a lot of modern machines (especially laptops) they are actually USB devices anyway and you can forget direct register access.

I am slightly astonished as to why anyone would take this route in the modern PC environment.? If you are interfacing to old hardware then you don’t have much choice but for anything new USB is a much better candidate. In fact even for legacy hardware I’d probably consider some sort of microcontroller with a usb function block to deal with the IO side of things rather than trying to do it on a PC.

Mike
– Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: xxxxx@mpcdata.com? ? ? ? web: www.mpcdata.com
tel: +44 (0) 1225 710600? ? ? ? ? ? fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Don, thanks for your reply. That made the concept a lot clear…

Please can you share some example/link where-in I can find how to attach to device stack, how to pass IRPs to lower level driver…

Thanks
Alan Hopes

Well that depends on the driver type. For KMDF drivers, take a look at
the toaster filter driver for a simple3 filter sample, and the tostmon.c
shows how to open for access. As much as possible I would do this in
KMDF, but if you want to look at WDM samples, take a look at the OSR
article http://www.osronline.com/article.cfm?id=87

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@gmail.com” wrote in message
news:xxxxx@ntdev:

> Don, thanks for your reply. That made the concept a lot clear…
>
> Please can you share some example/link where-in I can find how to attach to device stack, how to pass IRPs to lower level driver…
>
> Thanks
> Alan Hopes

Mike Pumford wrote:

I am slightly astonished as to why anyone would take this route in the
modern PC environment. If you are interfacing to old hardware then you
don’t have much choice but for anything new USB is a much better
candidate.

This is absolutely true. And that doesn’t mean using one of the hacky
USB-to-parallel or USB-to-serial adapters – those are just as bad.
There is an incredibly wide variety of USB experimenter’s kits on the
market today, with a plethora of digital and analog I/O lines, sensors,
and even the occasionally small LCD screen, just itching for someone to
hook up their own wires. They are simple, functional, future-proofed,
and a heck of a lot of fun to play with.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

anshul makkar wrote:

It’s a driver for a shippable product (not testing in labs), so , as
suggested, I will go with the approach where in I will create a driver
that will attach to lower layer parport.sys driver.

A shippable product in 2012 that relies on a hardware parallel port?
Such a product must have a very short life span. Few systems today
include a parallel port connector at all.

Further , following suggestions from some other threads

The IRPs received from upper layer will be forwarded to lower level
parport.sys (read, write and controlling IRPs). So it will be a kind
of filter driver.

If you can find a Windows Server 2003 DDK (build 3790), the source code
for parport.sys is included. You can answer many of these questions
yourself. You use ioctls for device control, and WriteFile/ReadFile to
send and receive data.

Please suggest if my approach is correct and also if, based on your
experience, there are any problems that can be foreseen.

Besides the fact that parallel ports are slow and do not have any error
detection?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> There is an incredibly wide variety of USB experimenter’s kits on the

market today, with a plethora of digital and analog I/O lines, sensors,
and even the occasionally small LCD screen, just itching for someone to
hook up their own wires. They are simple, functional, future-proofed,
and a heck of a lot of fun to play with.

Arduino is one well-known. But it includes the USB-to-serial chip.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Be afraid. Be very afraid. First, ask most users what a “parallel port”
is and they prbably won’t know, since computers generally don’t have them.
I haven’t seen a post-1990s laptop with one. many of thr macines
certified to run Vista and Windows7 don’t have them. Rememer my comment
about “more firghteningly, peolple sometimes vuild actual products”?
Essentially, you have designed a device to run on a dead technology, and
you can only sell it to people who happen to own this dead technology (the
last remaining machine I have that has a parallel port was purchsed in the
1990s; none of the remaining 12 machines I own has a parallel port
connector. I just looked. This was a bad idea in the 1990s (because
there were no standards for bidirectional ports) and its viability as a
Good Idea has been decreasing exponentially since that time. Didn’t
anyone familiar with the current Intel/Microsoft (and a few other
participants) Standard review this design for sanity?
joe

Thanks for your replies…

It’s a driver for a shippable product (not testing in labs), so , as
suggested, I will go with the approach where in I will create a driver
that will attach to lower layer parport.sys driver.

Further , following suggestions from some other threads
"There is already a standard system driver (parport.sys) that owns the
parallel ports. Yes, you could write a kernel driver that talks directly
to the parallel port I/O ports, and expose ioctls to user-mode code.
However, such a driver is just as bad as inpout32.dll, because it is using
I/O ports that it does not own.

The pedantically correct method is to write a driver that talks to
parport.sys, and uses its services to gain access to the parallel port.
That takes a fair amount of effort, certainly more than just banging the
ports. If you hope to ship this out as a commercial product, then you
probably want to do that. If this is for internal, diagnostic, or lab use,
then I wouldn’t go to the trouble."

The IRPs received from upper layer will be forwarded to lower level
parport.sys (read, write and controlling IRPs). So it will be a kind of
filter driver.

Please suggest if my approach is correct and also if, based on your
experience,  there are any problems that can be foreseen.
 
Thanks
Anshul Makkar
www.justkernel.com


From: Mike Pumford
> To: Windows System Software Devs Interest List
> Sent: Monday, 20 February 2012 3:36 PM
> Subject: Re: [ntdev] access parallel port from driver
>
> xxxxx@flounder.com wrote:
>> It is going to be a Very Bad Idea to go for the port directly. It is
>> generally a Very Bad Idea to assume there is even a parallel port
>> available on most modern computers. The interface is, as far as I
>> remember, officially deprecated.
>>
>> If there is a parallel port, it has already been claimed by parport.sys
>> and it is therefore not available to you.
>>
>
>> If you are comfortable with the idea of using the parallel port, then
>> you
>> will want to look at IoAttachDeviceToDeviceStack, or whatever it is
>> called
>> in KMDF, to establish your device as a device that wants to communicate
>> to
>> the lower-level driver. I have no idea what can go wrong here, but the
>> failure modes (such as what happens if a user tells Windows that a
>> printer
>> is attached to that port) are going to be profoundly ugly.
>>
> True but there is a way to resolve it. The MS parport.sys drive allows
> another driver to take control of the parallel port registers in a
> controlled manner and then give them back when it is finished so it is
> possible to do this cleanly. Once you have claimed the device this way
> parport.sys blocks all other accesses. I’ve written drivers that do this
> quite a few times in the past (long before USB even existed) and it works
> reliably and so much better than solutions which involved uninstalling
> parport.sys. This will only work if the parallel port in question actually
> looks like an old school ISA device. In a lot of modern machines
> (especially laptops) they are actually USB devices anyway and you can
> forget direct register access.
>
> I am slightly astonished as to why anyone would take this route in the
> modern PC environment. If you are interfacing to old hardware then you
> don’t have much choice but for anything new USB is a much better
> candidate. In fact even for legacy hardware I’d probably consider some
> sort of microcontroller with a usb function block to deal with the IO side
> of things rather than trying to do it on a PC.
>
> Mike
> – Mike Pumford, Senior Software Engineer
> MPC Data Limited
> e-mail: xxxxx@mpcdata.com web: www.mpcdata.com
> tel: +44 (0) 1225 710600 fax: +44 (0) 1225 710601
> ddi: +44 (0) 1225 710635
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Don, sorry to bother you. But the link http://www.osronline.com/article.cfm?id=87 just says how to build your IRPs to perform IO…

But as per my understanding, in this case my device object will be attached to FDO of parport.sys… I need to just forward the the IRPs to lower object in the device stack i.e device object of the parport.sys, I don’t need to build any IRPs.

Please suggest if my understanding is correct.

Request you to please provide some link or sample as to how to attach my device object in the stack, how to call lower level device object etc.

Thanks
Alan Hopes.

There are many ways to do this. In WDM, the
IoCopyCurrentIrpStackLocationToNext is about the simplest, followed by
IoCallDriver. I have not studied KMDF to see if it has its own wrappers
for these. I already told you about IoAttachDeviceToDeviceStack. You
might consider reading those documents first, then doing some file
searches in the sample drivers. USB drivers are good examples to look at
because they all call USBD, the generic USB class driver.
joe

Don, sorry to bother you. But the link
http://www.osronline.com/article.cfm?id=87 just says how to build your
IRPs to perform IO…

But as per my understanding, in this case my device object will be
attached to FDO of parport.sys… I need to just forward the the IRPs to
lower object in the device stack i.e device object of the parport.sys, I
don’t need to build any IRPs.

Please suggest if my understanding is correct.

Request you to please provide some link or sample as to how to attach my
device object in the stack, how to call lower level device object etc.

Thanks
Alan Hopes.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

Don, sorry to bother you. But the link http://www.osronline.com/article.cfm?id=87 just says how to build your IRPs to perform IO…

But as per my understanding, in this case my device object will be attached to FDO of parport.sys… I need to just forward the the IRPs to lower object in the device stack i.e device object of the parport.sys, I don’t need to build any IRPs.

That’s only true if the requests you are given exactly match the
requests that parport.sys expects to receive. I’m assuming you will be
exposing your own custom interface, which you will need to translate
into parport.sys terms.

Request you to please provide some link or sample as to how to attach my device object in the stack, how to call lower level device object etc.

There are an infinite number of samples showing this, since every filter
driver has to do so. Have you looked through any of the WDK samples at all?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi ,
Does parport.sys allow to take control of the port from user-mode. i mean we can open parport through createfile and then pass ioctls … Thus it exposes symlink so that driver can be accessed from user mode.

Thanks
anshul makkar
-----Original message-----
From: Tim Roberts
Sent: 21/02/2012, 23:18
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] access parallel port from driver

xxxxx@gmail.com wrote:

Don, sorry to bother you. But the link http://www.osronline.com/article.cfm?id=87 just says how to build your IRPs to perform IO…

But as per my understanding, in this case my device object will be attached to FDO of parport.sys… I need to just forward the the IRPs to lower object in the device stack i.e device object of the parport.sys, I don’t need to build any IRPs.

That’s only true if the requests you are given exactly match the
requests that parport.sys expects to receive. I’m assuming you will be
exposing your own custom interface, which you will need to translate
into parport.sys terms.

Request you to please provide some link or sample as to how to attach my device object in the stack, how to call lower level device object etc.

There are an infinite number of samples showing this, since every filter
driver has to do so. Have you looked through any of the WDK samples at all?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Anshul Makkar wrote:

Does parport.sys allow to take control of the port from user-mode. i mean we can open parport through createfile and then pass ioctls … Thus it exposes symlink so that driver can be accessed from user mode.

How quickly we lose our history… Of course it exposes a symlink:
LPT1: or \.\lpt1. The ioctls it supports are listed here:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff543945.aspx
And the higher-level article on working with parallel drivers is here:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff544814.aspx


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim, Thanks for replying.

I need access to parallel port and not to the device attached to the port.

As per the information on “http://msdn.microsoft.com/en-us/library/windows/hardware/ff544284(v=vs.85).aspx”, there is no symlink for the parallel port exported by parport.sys.

?
Thanks
Anshul Makkar
www.justkernel.com


From: Tim Roberts
To: Windows System Software Devs Interest List
Sent: Wednesday, 22 February 2012 12:09 AM
Subject: Re: [ntdev] access parallel port from driver

Anshul Makkar wrote:
> Does parport.sys allow to take control of the port from user-mode.? i mean we can open parport through createfile and then pass ioctls … Thus it exposes symlink so that driver can be accessed from user mode.

How quickly we lose our history… Of course it exposes a symlink:
LPT1: or \.\lpt1.? The ioctls it supports are listed here:
? ? http://msdn.microsoft.com/en-us/library/windows/hardware/ff543945.aspx
And the higher-level article on working with parallel drivers is here:
? ? http://msdn.microsoft.com/en-us/library/windows/hardware/ff544814.aspx


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer