mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Use only 80 character wide lines in the comments.
svn path=/trunk/; revision=13431
This commit is contained in:
parent
a6b98eefa1
commit
a1775e6e4c
1 changed files with 77 additions and 74 deletions
|
@ -9,34 +9,37 @@
|
|||
*
|
||||
* BACKGROUND
|
||||
*
|
||||
* IRP queuing is a royal pain in the butt, due to the fact that there are tons of
|
||||
* built-in race conditions. IRP handling is difficult in general, but the cancel
|
||||
* logic has been particularly complicated due to some subtle races, coupled
|
||||
* with the fact that the system interfaces have changed over time.
|
||||
* IRP queuing is a royal pain in the butt, due to the fact that there are
|
||||
* tons of built-in race conditions. IRP handling is difficult in general,
|
||||
* but the cancel logic has been particularly complicated due to some subtle
|
||||
* races, coupled with the fact that the system interfaces have changed over
|
||||
* time.
|
||||
*
|
||||
* Walter Oney (2nd. Ed. of Programming the Windows Driver Model) states a common
|
||||
* opinion among driver developers when he says that it is foolish to try to roll
|
||||
* your own cancel logic. There are only a very few people who have gotten it
|
||||
* right in the past. He suggests, instead, that you either use his own well-tested
|
||||
* code, or use the code in the Microsoft Cancel-Safe Queue Library.
|
||||
* Walter Oney (2nd. Ed. of Programming the Windows Driver Model) states a
|
||||
* common opinion among driver developers when he says that it is foolish
|
||||
* to try to roll your own cancel logic. There are only a very few people
|
||||
* who have gotten it right in the past. He suggests, instead, that you
|
||||
* either use his own well-tested code, or use the code in the Microsoft
|
||||
* Cancel-Safe Queue Library.
|
||||
*
|
||||
* We cannot do either, of course, due to copyright issues. I have therefore created
|
||||
* this clone of the Microsoft library in order to concentrate all of the IRP-queuing
|
||||
* bugs in one place. I'm quite sure there are problems here, so if you are a
|
||||
* driver writer, I'd be glad to hear your feedback.
|
||||
* We cannot do either, of course, due to copyright issues. I have therefore
|
||||
* created this clone of the Microsoft library in order to concentrate all
|
||||
* of the IRP-queuing bugs in one place. I'm quite sure there are problems
|
||||
* here, so if you are a driver writer, I'd be glad to hear your feedback.
|
||||
*
|
||||
* Apart from that, please try to use these routines, rather than building your own.
|
||||
* If you think you have found a bug, please bring it up with me or on-list, as this
|
||||
* is complicated and non-obvious stuff. Don't just change this and hope for the best!
|
||||
* Apart from that, please try to use these routines, rather than building
|
||||
* your own. If you think you have found a bug, please bring it up with me
|
||||
* or on-list, as this is complicated and non-obvious stuff. Don't just
|
||||
* change this and hope for the best!
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* This library follows exactly the same interface as the Microsoft Cancel-Safe Queue
|
||||
* routines (IoCsqXxx()). As such, the authoritative reference is the current DDK.
|
||||
* There is also a DDK sample called "cancel" that has an example of how to use this
|
||||
* code. I have also provided a sample driver that makes use of this queue. Finally,
|
||||
* please do read the header and the source if you're curious about the inner workings
|
||||
* of these routines.
|
||||
* routines (IoCsqXxx()). As such, the authoritative reference is the
|
||||
* current DDK. There is also a DDK sample called "cancel" that has an
|
||||
* example of how to use this code. I have also provided a sample driver
|
||||
* that makes use of this queue. Finally, please do read the header and the
|
||||
* source if you're curious about the inner workings of these routines.
|
||||
*/
|
||||
|
||||
#ifndef _REACTOS_CSQ_H
|
||||
|
@ -48,10 +51,11 @@ struct _IO_CSQ;
|
|||
/*
|
||||
* CSQ Callbacks
|
||||
*
|
||||
* The cancel-safe queue is implemented as a set of IoCsqXxx() OS routines copuled
|
||||
* with a set of driver callbacks to handle the basic operations of the queue. You
|
||||
* need to supply one of each of these functions in your own driver. These routines
|
||||
* are also documented in the DDK under CsqXxx(). That is the authoritative documentation.
|
||||
* The cancel-safe queue is implemented as a set of IoCsqXxx() OS routines
|
||||
* copuled with a set of driver callbacks to handle the basic operations of
|
||||
* the queue. You need to supply one of each of these functions in your own
|
||||
* driver. These routines are also documented in the DDK under CsqXxx().
|
||||
* That is the authoritative documentation.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -60,11 +64,11 @@ struct _IO_CSQ;
|
|||
*
|
||||
* Sample implementation:
|
||||
*
|
||||
VOID NTAPI CsqInsertIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("Inserting IRP 0x%x into CSQ\n", Irp));
|
||||
InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
VOID NTAPI CsqInsertIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("Inserting IRP 0x%x into CSQ\n", Irp));
|
||||
InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef VOID (NTAPI *PIO_CSQ_INSERT_IRP) (struct _IO_CSQ *Csq,
|
||||
|
@ -73,16 +77,16 @@ typedef VOID (NTAPI *PIO_CSQ_INSERT_IRP) (struct _IO_CSQ *Csq,
|
|||
|
||||
/*
|
||||
* Function to insert an IRP into the queue with extended context information.
|
||||
* This is useful if you need to be able to de-queue particular IRPs more easily
|
||||
* in some cases.
|
||||
* This is useful if you need to be able to de-queue particular IRPs more
|
||||
* easily in some cases.
|
||||
*
|
||||
* Same deal as above; sample implementation:
|
||||
*
|
||||
NTSTATUS NTAPI CsqInsertIrpEx(PIO_CSQ Csq, PIRP Irp, PVOID InsertContext)
|
||||
{
|
||||
CsqInsertIrp(Csq, Irp);
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
NTSTATUS NTAPI CsqInsertIrpEx(PIO_CSQ Csq, PIRP Irp, PVOID InsertContext)
|
||||
{
|
||||
CsqInsertIrp(Csq, Irp);
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef NTSTATUS (NTAPI *PIO_CSQ_INSERT_IRP_EX) (struct _IO_CSQ *Csq,
|
||||
|
@ -94,11 +98,11 @@ typedef NTSTATUS (NTAPI *PIO_CSQ_INSERT_IRP_EX) (struct _IO_CSQ *Csq,
|
|||
*
|
||||
* Sample:
|
||||
*
|
||||
VOID NTAPI CsqRemoveIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("Removing IRP 0x%x from CSQ\n", Irp));
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
VOID NTAPI CsqRemoveIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("Removing IRP 0x%x from CSQ\n", Irp));
|
||||
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef VOID (NTAPI *PIO_CSQ_REMOVE_IRP) (struct _IO_CSQ *Csq,
|
||||
|
@ -109,18 +113,18 @@ typedef VOID (NTAPI *PIO_CSQ_REMOVE_IRP) (struct _IO_CSQ *Csq,
|
|||
*
|
||||
* Sample:
|
||||
*
|
||||
PIRP NTAPI CsqPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext)
|
||||
{
|
||||
KdPrint(("Peeking for next IRP\n"));
|
||||
PIRP NTAPI CsqPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext)
|
||||
{
|
||||
KdPrint(("Peeking for next IRP\n"));
|
||||
|
||||
if(Irp)
|
||||
return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
|
||||
if(Irp)
|
||||
return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry);
|
||||
|
||||
if(IsListEmpty(&IrpQueue))
|
||||
return NULL;
|
||||
if(IsListEmpty(&IrpQueue))
|
||||
return NULL;
|
||||
|
||||
return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
|
||||
}
|
||||
return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef PIRP (NTAPI *PIO_CSQ_PEEK_NEXT_IRP) (struct _IO_CSQ *Csq,
|
||||
|
@ -133,11 +137,11 @@ typedef PIRP (NTAPI *PIO_CSQ_PEEK_NEXT_IRP) (struct _IO_CSQ *Csq,
|
|||
*
|
||||
* Sample:
|
||||
*
|
||||
VOID NTAPI CsqAcquireLock(PIO_CSQ Csq, PKIRQL Irql)
|
||||
{
|
||||
KdPrint(("Acquiring spin lock\n"));
|
||||
KeAcquireSpinLock(&IrpQueueLock, Irql);
|
||||
}
|
||||
VOID NTAPI CsqAcquireLock(PIO_CSQ Csq, PKIRQL Irql)
|
||||
{
|
||||
KdPrint(("Acquiring spin lock\n"));
|
||||
KeAcquireSpinLock(&IrpQueueLock, Irql);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef VOID (NTAPI *PIO_CSQ_ACQUIRE_LOCK) (struct _IO_CSQ *Csq,
|
||||
|
@ -146,11 +150,11 @@ typedef VOID (NTAPI *PIO_CSQ_ACQUIRE_LOCK) (struct _IO_CSQ *Csq,
|
|||
/*
|
||||
* Unlock the queue:
|
||||
*
|
||||
VOID NTAPI CsqReleaseLock(PIO_CSQ Csq, KIRQL Irql)
|
||||
{
|
||||
KdPrint(("Releasing spin lock\n"));
|
||||
KeReleaseSpinLock(&IrpQueueLock, Irql);
|
||||
}
|
||||
VOID NTAPI CsqReleaseLock(PIO_CSQ Csq, KIRQL Irql)
|
||||
{
|
||||
KdPrint(("Releasing spin lock\n"));
|
||||
KeReleaseSpinLock(&IrpQueueLock, Irql);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef VOID (NTAPI *PIO_CSQ_RELEASE_LOCK) (struct _IO_CSQ *Csq,
|
||||
|
@ -162,13 +166,13 @@ typedef VOID (NTAPI *PIO_CSQ_RELEASE_LOCK) (struct _IO_CSQ *Csq,
|
|||
*
|
||||
* Sample:
|
||||
*
|
||||
VOID NTAPI CsqCompleteCancelledIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("cancelling irp 0x%x\n", Irp));
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
VOID NTAPI CsqCompleteCancelledIrp(PIO_CSQ Csq, PIRP Irp)
|
||||
{
|
||||
KdPrint(("cancelling irp 0x%x\n", Irp));
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
*
|
||||
*/
|
||||
typedef VOID (NTAPI *PIO_CSQ_COMPLETE_CANCELED_IRP) (struct _IO_CSQ *Csq,
|
||||
|
@ -179,8 +183,8 @@ typedef VOID (NTAPI *PIO_CSQ_COMPLETE_CANCELED_IRP) (struct _IO_CSQ *Csq,
|
|||
* STRUCTURES
|
||||
*
|
||||
* NOTE: Please do not use these directly. You will make incompatible code
|
||||
* if you do. Always only use the documented IoCsqXxx() interfaces and you will
|
||||
* amass much Good Karma.
|
||||
* if you do. Always only use the documented IoCsqXxx() interfaces and you
|
||||
* will amass much Good Karma.
|
||||
*/
|
||||
#define IO_TYPE_CSQ_IRP_CONTEXT 1
|
||||
#define IO_TYPE_CSQ 2
|
||||
|
@ -213,9 +217,9 @@ typedef struct _IO_CSQ_IRP_CONTEXT {
|
|||
/*
|
||||
* CANCEL-SAFE QUEUE DDIs
|
||||
*
|
||||
* These device driver interfaces are called to make use of the queue. Again, authoritative
|
||||
* documentation for these functions is in the DDK. The csqtest driver also makes use of
|
||||
* some of them.
|
||||
* These device driver interfaces are called to make use of the queue. Again,
|
||||
* authoritative documentation for these functions is in the DDK. The csqtest
|
||||
* driver also makes use of some of them.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -274,4 +278,3 @@ PIRP NTAPI IoCsqRemoveNextIrp(PIO_CSQ Csq,
|
|||
PVOID PeekContext);
|
||||
|
||||
#endif /* _REACTOS_CSQ_H */
|
||||
|
||||
|
|
Loading…
Reference in a new issue