You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
354 lines
7.4 KiB
354 lines
7.4 KiB
/***************************************************************************
|
|
|
|
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
|