|
|
/***************************************************************************
Copyright (c) 2002 Microsoft Corporation
Module Name:
irplist.H
Abstract:
Private interface for Smartcard Driver Utility Library
Environment:
Kernel Mode Only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
Revision History:
05/14/2002 : created
Authors:
Randy Aull
****************************************************************************/
#ifndef __IRPLIST_H__
#define __IRPLIST_H__
typedef struct _LOCKED_LIST { LIST_ENTRY ListHead; KSPIN_LOCK SpinLock; PKSPIN_LOCK ListLock; LONG Count; } LOCKED_LIST, *PLOCKED_LIST; typedef BOOLEAN (*PFNLOCKED_LIST_PROCESS)(PVOID Context, PLIST_ENTRY ListEntry);
#define INIT_LOCKED_LIST(l) \
{ \ InitializeListHead(&(l)->ListHead); \ KeInitializeSpinLock(&(l)->SpinLock); \ (l)->ListLock = &(l)->SpinLock; \ (l)->Count = 0; \ }
void LockedList_Init( PLOCKED_LIST LockedList, PKSPIN_LOCK ListLock );
void LockedList_EnqueueHead( PLOCKED_LIST LockedList, PLIST_ENTRY ListEntry );
void LockedList_EnqueueTail( PLOCKED_LIST LockedList, PLIST_ENTRY ListEntry );
void LockedList_EnqueueAfter( PLOCKED_LIST LockedList, PLIST_ENTRY Entry, PLIST_ENTRY Location );
PLIST_ENTRY LockedList_RemoveHead( PLOCKED_LIST LockedList );
PLIST_ENTRY LockedList_RemoveEntryLocked( PLOCKED_LIST LockedList, PLIST_ENTRY Entry );
PLIST_ENTRY LockedList_RemoveEntry( PLOCKED_LIST LockedList, PLIST_ENTRY Entry );
LONG LockedList_GetCount( PLOCKED_LIST LockedList );
LONG LockedList_Drain( PLOCKED_LIST LockedList, PLIST_ENTRY DrainListHead );
BOOLEAN List_Process( PLIST_ENTRY ListHead, PFNLOCKED_LIST_PROCESS Process, PVOID ProcessContext );
BOOLEAN LockedList_ProcessLocked( PLOCKED_LIST LockedList, PFNLOCKED_LIST_PROCESS Process, PVOID ProcessContext );
BOOLEAN LockedList_Process( PLOCKED_LIST LockedList, BOOLEAN LockAtPassive, PFNLOCKED_LIST_PROCESS Process, PVOID ProcessContext );
#define LL_LOCK(l, k) KeAcquireSpinLock((l)->ListLock, (k))
#define LL_UNLOCK(l, k) KeReleaseSpinLock((l)->ListLock, (k))
#define LL_LOCK_AT_DPC(l) KeAcquireSpinLockAtDpcLevel((l)->ListLock)
#define LL_UNLOCK_FROM_DPC(l) KeReleaseSpinLockFromDpcLevel((l)->ListLock)
#define LL_GET_COUNT(l) (l)->Count
#define LL_ADD_TAIL(l, e) \
{ \ InsertTailList(&(l)->ListHead, (e));\ (l)->Count++; \ }
#define LL_ADD_TAIL_REF(l, e, r) \
{ \ LL_ADD_TAIL(l, e); \ RefObj_AddRef(r); \ }
#define LL_ADD_HEAD(l, e) \
{ \ InsertHeadList(&(l)->ListHead, (e));\ (l)->Count++; \ }
#define LL_ADD_HEAD_REF(l, e, r) \
{ \ LL_ADD_HEAD(l, e); \ RefObj_AddRef(r); \ }
#define LL_REMOVE_HEAD(l) RemoveHeadList(&(l)->ListHead); (l)->Count--
#define LL_REMOVE_TAIL(l) RemoveTailList(&(l)->ListHead); (l)->Count--
#define IRP_LIST_INDEX (3)
typedef NTSTATUS (*PIRP_COMPLETION_ROUTINE) ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status );
typedef struct _IRP_LIST {
LOCKED_LIST LockedList;
PDRIVER_CANCEL CancelRoutine;
//
// Routiune to call from the CancelRoutine when the IRP is cancelled
//
PIRP_COMPLETION_ROUTINE IrpCompletionRoutine;
//
// IRP_LIST assumes that the remove lock logic is done outside of enqueue /
// dequeue / cancel because the caller of XXX_Enqueue will have no way of
// knowing if the remlock was acquired if it returns !NT_SUCCESS()
//
// PIO_REMOVE_LOCK IoRemoveLock;
} IRP_LIST, *PIRP_LIST;
#define IRP_LIST_FROM_IRP(irp) \
(PIRP_LIST) ((irp)->Tail.Overlay.DriverContext[IRP_LIST_INDEX])
//
// void
// IrpList_Init(
// PIRP_LIST IrpList,
// PDRIVER_CANCEL CancelRoutine,
// PIRP_COMPLETION_ROUTINE IrpCompletionRoutine
// );
//
#define IrpList_Init(i, c, r) IrpList_InitEx(i, &(i)->LockedList.SpinLock, c, r)
void IrpList_InitEx( PIRP_LIST IrpList, PKSPIN_LOCK ListLock, PDRIVER_CANCEL CancelRoutine, PIRP_COMPLETION_ROUTINE IrpCompletionRoutine );
//
// Return values:
// STATUS_PENDING: Irp has been enqueued (not the current irp) and cannot be
// touched
//
// !NT_SUCCESS(status): (includes STATUS_CANCELLED) Remove lock could not be
// acquired or the Irp was cancelled, complete the IRP
//
NTSTATUS IrpList_EnqueueEx( PIRP_LIST IrpList, PIRP Irp, BOOLEAN StoreListInIrp );
//
// NTSTATUS
// IrpList_Enqueue(
// PIRP_LIST IrpList,
// PIRP Irp
// );
//
#define IrpList_Enqueue(list, irp) \
IrpList_EnqueueEx(list, irp, TRUE)
//
// IrpList_IsEmptyLocked(PIRP_LIST list)
//
// Returns TRUE or FALSE
//
#define IrpList_IsEmptyLocked(list) \
((list)->LockedList.ListHead.Flink == (&(list)->LockedList.ListHead))
//
// Enqueue an irp while the IRP_LIST's spin lock is being held. This function
// will not use the remove lock to acquire or release the irp. Same return
// values as IrpList_EnqueueEx.
//
NTSTATUS IrpList_EnqueueLocked( PIRP_LIST IrpList, PIRP Irp, BOOLEAN StoreListInIrp, BOOLEAN InsertTail );
PIRP IrpList_Dequeue( PIRP_LIST IrpList );
PIRP IrpList_DequeueLocked( PIRP_LIST IrpList );
BOOLEAN IrpList_DequeueIrpLocked( PIRP_LIST IrpList, PIRP Irp );
BOOLEAN IrpList_DequeueIrp( PIRP_LIST IrpList, PIRP Irp );
typedef BOOLEAN (*PFNPROCESSIRP)( PVOID Context, PIRP Irp );
ULONG IrpList_ProcessAndDrainLocked( PIRP_LIST IrpList, PFNPROCESSIRP FnProcessIrp, PVOID Context, PLIST_ENTRY DrainHead );
ULONG IrpList_ProcessAndDrain( PIRP_LIST IrpList, PFNPROCESSIRP FnProcessIrp, PVOID Context, PLIST_ENTRY DrainHead );
ULONG IrpList_ProcessAndDrainLocked( PIRP_LIST IrpList, PFNPROCESSIRP FnProcessIrp, PVOID Context, PLIST_ENTRY DrainHead );
ULONG IrpList_Drain( PIRP_LIST IrpList, PLIST_ENTRY DrainHead );
ULONG IrpList_DrainLocked( PIRP_LIST IrpList, PLIST_ENTRY DrainHead );
ULONG IrpList_DrainLockedByFileObject( PIRP_LIST IrpList, PLIST_ENTRY DrainHead, PFILE_OBJECT FileObject );
void IrpList_HandleCancel( PIRP_LIST IrpList, PDEVICE_OBJECT DeviceObject, PIRP Irp );
void IrpList_CancelRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp );
#endif
|