usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous reader
for input pipes.
Now I have the problem to connect user application read events to continous
reader completion callbacks.
I think to use the following design pattern:

Actors:

  1. EvtIoRead for a sequential dispatch queue
  2. PipeReadComplete callback
  3. EvtRequestCancel to cancel current pending WDFREQUEST
  4. WDFCOLLECTION of WDFMEMORY objects to cache data
  5. WDFSPINLOCK to synchronize operations

Logic (simplified):

EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request (WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:

Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC

Yes, that is a good design with one exception on how you store the list
of WDFMEMORYs.

Adds to a WDFCOLLECTION can fail since they require an allocation.
Instead, you can put a LIST_ENTRY in the WDFMEMORY context and avoid an
extra point of failure. The context will be there automatically if you
specify WDF_USB_CONTINUOUS_READER_CONFIG:: BufferAttributes when
configuring the continuous reader. Put the WDFMEMORYs into a LIST_ENTRY
list head in the device context. To get back to the WDFMEMORY from its
context, you can do something like this by calling
WdfObjectContextGetObject()

struct READER_CONTEXT {
LIST_ENTRY Link;
};

Struct DEVICE_CONTEXT {
LIST_ENTRY ListHead;
}

PLIST_ENTRY ple = RemoveListHead(&DeviceContext->ListHead);
READER_CONTEXT* pReaderContext = CONTAINING_RECORD(ple, READER_CONTEXT,
Link);
WDFMEMORY memory = (WDFMEMORY)
WdfObjectContextGetObject(pReaderContext);

d

– I can spell, I just can’t type.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 7:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous
reader for input pipes.
Now I have the problem to connect user application read events to
continous reader completion callbacks.
I think to use the following design pattern:

Actors:

  1. EvtIoRead for a sequential dispatch queue
  2. PipeReadComplete callback
  3. EvtRequestCancel to cancel current pending WDFREQUEST
  4. WDFCOLLECTION of WDFMEMORY objects to cache data
  5. WDFSPINLOCK to synchronize operations

Logic (simplified):

EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request
(WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:

Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Thanks a lot Doron,
I will use your suggestions also if this way I can’t have a EvtCleanup on
WDFCOLLECTION to purge outstanding data when device is removed.
Before start coding I have 2 more questions:

  1. Any problem to have more than one continuos reader in a driver ? (my
    device has 2 input pipes to be processed)
  2. Any way to selective stop/start a single continuous reader without
    affecting the other one ?

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Saturday, May 06, 2006 8:37 PM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

Yes, that is a good design with one exception on how you store the list
of WDFMEMORYs.

Adds to a WDFCOLLECTION can fail since they require an allocation.
Instead, you can put a LIST_ENTRY in the WDFMEMORY context and avoid an
extra point of failure. The context will be there automatically if you
specify WDF_USB_CONTINUOUS_READER_CONFIG:: BufferAttributes when
configuring the continuous reader. Put the WDFMEMORYs into a LIST_ENTRY
list head in the device context. To get back to the WDFMEMORY from its
context, you can do something like this by calling
WdfObjectContextGetObject()

struct READER_CONTEXT {
LIST_ENTRY Link;
};

Struct DEVICE_CONTEXT {
LIST_ENTRY ListHead;
}

PLIST_ENTRY ple = RemoveListHead(&DeviceContext->ListHead);
READER_CONTEXT* pReaderContext = CONTAINING_RECORD(ple, READER_CONTEXT,
Link);
WDFMEMORY memory = (WDFMEMORY)
WdfObjectContextGetObject(pReaderContext);

d

– I can spell, I just can’t type.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 7:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous
reader for input pipes.
Now I have the problem to connect user application read events to
continous reader completion callbacks.
I think to use the following design pattern:

Actors:
-------
1) EvtIoRead for a sequential dispatch queue
2) PipeReadComplete callback
3) EvtRequestCancel to cancel current pending WDFREQUEST
4) WDFCOLLECTION of WDFMEMORY objects to cache data
5) WDFSPINLOCK to synchronize operations

Logic (simplified):
-----------------
EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request
(WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:
---------
Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

each pipe state is independent of the next. So a continuous reader on
pipe A does not affect a continuous reader on pipe B. so there is no
problem having more then one pipe have a cont. reader on it. To stop
the reader, call WdfIoTargetStop and restart is WdfIoTargetStart.

You can purge the data in the device’s EvtObjectCleanup routine.

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 2:25 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] usb pipe continuous reader and user requests

Thanks a lot Doron,
I will use your suggestions also if this way I can’t have a EvtCleanup
on WDFCOLLECTION to purge outstanding data when device is removed.
Before start coding I have 2 more questions:

  1. Any problem to have more than one continuos reader in a driver ? (my
    device has 2 input pipes to be processed)
  2. Any way to selective stop/start a single continuous reader without
    affecting the other one ?

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Saturday, May 06, 2006 8:37 PM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

Yes, that is a good design with one exception on how you store the list
of WDFMEMORYs.

Adds to a WDFCOLLECTION can fail since they require an allocation.
Instead, you can put a LIST_ENTRY in the WDFMEMORY context and avoid an
extra point of failure. The context will be there automatically if you
specify WDF_USB_CONTINUOUS_READER_CONFIG:: BufferAttributes when
configuring the continuous reader. Put the WDFMEMORYs into a LIST_ENTRY
list head in the device context. To get back to the WDFMEMORY from its
context, you can do something like this by calling
WdfObjectContextGetObject()

struct READER_CONTEXT {
LIST_ENTRY Link;
};

Struct DEVICE_CONTEXT {
LIST_ENTRY ListHead;
}

PLIST_ENTRY ple = RemoveListHead(&DeviceContext->ListHead);
READER_CONTEXT* pReaderContext = CONTAINING_RECORD(ple, READER_CONTEXT,
Link);
WDFMEMORY memory = (WDFMEMORY)
WdfObjectContextGetObject(pReaderContext);

d

– I can spell, I just can’t type.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 7:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous
reader for input pipes.
Now I have the problem to connect user application read events to
continous reader completion callbacks.
I think to use the following design pattern:

Actors:
-------
1) EvtIoRead for a sequential dispatch queue
2) PipeReadComplete callback
3) EvtRequestCancel to cancel current pending WDFREQUEST
4) WDFCOLLECTION of WDFMEMORY objects to cache data
5) WDFSPINLOCK to synchronize operations

Logic (simplified):
-----------------
EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request
(WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:
---------
Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Sorry,
I did not explain my problem very well.

As far as I undestood calling WdfIoTargetStop will stop BOTH continuos
readers
since the input parameter to the function is a WDFIOTARGET and not a
WDFPIPE.
So I can’t use WdfIoTargetStop to perform some kind of flow control on a
single pipe.
Anyway the opportunity to have more than one continuous reader will
simplify a lot my code.

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 07, 2006 12:02 AM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

each pipe state is independent of the next. So a continuous reader on
pipe A does not affect a continuous reader on pipe B. so there is no
problem having more then one pipe have a cont. reader on it. To stop
the reader, call WdfIoTargetStop and restart is WdfIoTargetStart.

You can purge the data in the device’s EvtObjectCleanup routine.

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 2:25 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] usb pipe continuous reader and user requests

Thanks a lot Doron,
I will use your suggestions also if this way I can’t have a EvtCleanup
on WDFCOLLECTION to purge outstanding data when device is removed.
Before start coding I have 2 more questions:

1) Any problem to have more than one continuos reader in a driver ? (my
device has 2 input pipes to be processed)
2) Any way to selective stop/start a single continuous reader without
affecting the other one ?

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Saturday, May 06, 2006 8:37 PM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

Yes, that is a good design with one exception on how you store the list
of WDFMEMORYs.

Adds to a WDFCOLLECTION can fail since they require an allocation.
Instead, you can put a LIST_ENTRY in the WDFMEMORY context and avoid an
extra point of failure. The context will be there automatically if you
specify WDF_USB_CONTINUOUS_READER_CONFIG:: BufferAttributes when
configuring the continuous reader. Put the WDFMEMORYs into a LIST_ENTRY
list head in the device context. To get back to the WDFMEMORY from its
context, you can do something like this by calling
WdfObjectContextGetObject()

struct READER_CONTEXT {
LIST_ENTRY Link;
};

Struct DEVICE_CONTEXT {
LIST_ENTRY ListHead;
}

PLIST_ENTRY ple = RemoveListHead(&DeviceContext->ListHead);
READER_CONTEXT* pReaderContext = CONTAINING_RECORD(ple, READER_CONTEXT,
Link);
WDFMEMORY memory = (WDFMEMORY)
WdfObjectContextGetObject(pReaderContext);

d

– I can spell, I just can’t type.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 7:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous
reader for input pipes.
Now I have the problem to connect user application read events to
continous reader completion callbacks.
I think to use the following design pattern:

Actors:
-------
1) EvtIoRead for a sequential dispatch queue
2) PipeReadComplete callback
3) EvtRequestCancel to cancel current pending WDFREQUEST
4) WDFCOLLECTION of WDFMEMORY objects to cache data
5) WDFSPINLOCK to synchronize operations

Logic (simplified):
-----------------
EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request
(WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:
---------
Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

WDFUSBPIPE can be cast to a WDFIOTARGET. The same is true for a
WDFUSBDEVICE, it too can be cast to a WDFIOTARGET. This means that you
can call any WdfIoTarget API on either a WDFUSBPIPE or WDFUSBDEVICE.
When you make state changing calls (start/stop/etc) to a WDFUSBDEVICE,
all the WDFUSBPIPEs are also affected and changed to the same state.

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Sunday, May 07, 2006 10:44 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] usb pipe continuous reader and user requests

Sorry,
I did not explain my problem very well.

As far as I undestood calling WdfIoTargetStop will stop BOTH continuos
readers since the input parameter to the function is a WDFIOTARGET and
not a WDFPIPE.
So I can’t use WdfIoTargetStop to perform some kind of flow control on a
single pipe.
Anyway the opportunity to have more than one continuous reader will
simplify a lot my code.

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 07, 2006 12:02 AM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

each pipe state is independent of the next. So a continuous reader on
pipe A does not affect a continuous reader on pipe B. so there is no
problem having more then one pipe have a cont. reader on it. To stop
the reader, call WdfIoTargetStop and restart is WdfIoTargetStart.

You can purge the data in the device’s EvtObjectCleanup routine.

d

– I can spell, I just can’t type.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 2:25 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] usb pipe continuous reader and user requests

Thanks a lot Doron,
I will use your suggestions also if this way I can’t have a EvtCleanup
on WDFCOLLECTION to purge outstanding data when device is removed.
Before start coding I have 2 more questions:

1) Any problem to have more than one continuos reader in a driver ? (my
device has 2 input pipes to be processed)
2) Any way to selective stop/start a single continuous reader without
affecting the other one ?

Best regards,
PaoloC

----- Original Message -----
From: “Doron Holan”
To: “Windows System Software Devs Interest List”
Sent: Saturday, May 06, 2006 8:37 PM
Subject: RE: [ntdev] usb pipe continuous reader and user requests

Yes, that is a good design with one exception on how you store the list
of WDFMEMORYs.

Adds to a WDFCOLLECTION can fail since they require an allocation.
Instead, you can put a LIST_ENTRY in the WDFMEMORY context and avoid an
extra point of failure. The context will be there automatically if you
specify WDF_USB_CONTINUOUS_READER_CONFIG:: BufferAttributes when
configuring the continuous reader. Put the WDFMEMORYs into a LIST_ENTRY
list head in the device context. To get back to the WDFMEMORY from its
context, you can do something like this by calling
WdfObjectContextGetObject()

struct READER_CONTEXT {
LIST_ENTRY Link;
};

Struct DEVICE_CONTEXT {
LIST_ENTRY ListHead;
}

PLIST_ENTRY ple = RemoveListHead(&DeviceContext->ListHead);
READER_CONTEXT* pReaderContext = CONTAINING_RECORD(ple, READER_CONTEXT,
Link);
WDFMEMORY memory = (WDFMEMORY)
WdfObjectContextGetObject(pReaderContext);

d

– I can spell, I just can’t type.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Paolo Cazzola
Sent: Saturday, May 06, 2006 7:39 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] usb pipe continuous reader and user requests

Hi all,
I am currently converting a WDM USB function driver to KMDF 1.0.
The device always needs pending read so I presume to use a continuous
reader for input pipes.
Now I have the problem to connect user application read events to
continous reader completion callbacks.
I think to use the following design pattern:

Actors:
-------
1) EvtIoRead for a sequential dispatch queue
2) PipeReadComplete callback
3) EvtRequestCancel to cancel current pending WDFREQUEST
4) WDFCOLLECTION of WDFMEMORY objects to cache data
5) WDFSPINLOCK to synchronize operations

Logic (simplified):
-----------------
EvtIoRead()
IF WDFCOLLECTION is empty
Save WDFREQUEST in device context
Enable cancellation on such a request (WdfRequestMarkCancelable)
ELSE
Get first WDFMEMORY from WDFCOLLECTION
Use WDFMEMORY data to fill WDFREQUEST
Dereference WDFMEMORY object
Complete WDFREQUEST
ENDIF

PipeReadComplete()
IF there is a pending WDFREQUEST in device context
Use incoming WDFMEMORY to fill WDFREQUEST
Disable cancellation on such a request
(WdfRequestUnmarkCancelable)
Complete WDFREQUEST
ELSE
Add reference to incoming WDFMEMORY
Push incoming WDFMEMORY to WDFCOLLECTION
ENDIF

EvtRequestCancel ()
Remove WDFREQUEST from device context

Question:
---------
Is this a valid pattern or there is some better way to decouple user
requests with receive callbacks.

Best regards,
PaoloC


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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