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.
324 lines
6.2 KiB
324 lines
6.2 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
|
|
Module Name:
|
|
|
|
bdlutil.c
|
|
|
|
Abstract:
|
|
|
|
This module contains supporting routines forthe
|
|
Microsoft Biometric Device Library
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
- Created May 2002 by Reid Kuhn
|
|
|
|
--*/
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
//#include <ntddk.h>
|
|
#include <strsafe.h>
|
|
|
|
#include <wdm.h>
|
|
|
|
#include "bdlint.h"
|
|
|
|
ULONG g_DebugLevel = (BDL_DEBUG_TRACE | BDL_DEBUG_ERROR | BDL_DEBUG_ASSERT);
|
|
|
|
ULONG
|
|
BDLGetDebugLevel()
|
|
{
|
|
return g_DebugLevel;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
BDLCallDriverCompletionRoutine
|
|
(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN PIRP pIrp,
|
|
IN PKEVENT pEvent
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER (pDeviceObject);
|
|
|
|
if (pIrp->Cancel)
|
|
{
|
|
pIrp->IoStatus.Status = STATUS_CANCELLED;
|
|
}
|
|
else
|
|
{
|
|
pIrp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
|
|
KeSetEvent (pEvent, 0, FALSE);
|
|
|
|
return (STATUS_MORE_PROCESSING_REQUIRED);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
BDLCallLowerLevelDriverAndWait
|
|
(
|
|
IN PDEVICE_OBJECT pAttachedDeviceObject,
|
|
IN PIRP pIrp
|
|
)
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
KEVENT Event;
|
|
|
|
//
|
|
// Copy our stack location to the next
|
|
//
|
|
IoCopyCurrentIrpStackLocationToNext(pIrp);
|
|
|
|
//
|
|
// Initialize an event for process synchronization. The event is passed to
|
|
// our completion routine and will be set when the lower level driver is done
|
|
//
|
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
|
|
//
|
|
// Set up the completion routine which will just set the event when it is called
|
|
//
|
|
IoSetCompletionRoutine(pIrp, BDLCallDriverCompletionRoutine, &Event, TRUE, TRUE, TRUE);
|
|
|
|
//
|
|
// When calling the lower lever driver it is done slightly different for Power IRPs
|
|
// than other IRPs
|
|
//
|
|
if (IoGetCurrentIrpStackLocation(pIrp)->MajorFunction == IRP_MJ_POWER)
|
|
{
|
|
PoStartNextPowerIrp(pIrp);
|
|
status = PoCallDriver(pAttachedDeviceObject, pIrp);
|
|
}
|
|
else
|
|
{
|
|
status = IoCallDriver(pAttachedDeviceObject, pIrp);
|
|
}
|
|
|
|
//
|
|
// Wait until the lower lever driver has processed the Irp
|
|
//
|
|
if (status == STATUS_PENDING)
|
|
{
|
|
status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
|
|
ASSERT (STATUS_SUCCESS == status);
|
|
|
|
status = pIrp->IoStatus.Status;
|
|
}
|
|
|
|
return (status);
|
|
}
|
|
|
|
|
|
//
|
|
// These functions are for managing the handle list
|
|
//
|
|
|
|
VOID
|
|
BDLLockHandleList
|
|
(
|
|
IN PBDL_INTERNAL_DEVICE_EXTENSION pBDLExtension,
|
|
OUT KIRQL *pirql
|
|
)
|
|
{
|
|
KeAcquireSpinLock(&(pBDLExtension->HandleListLock), pirql);
|
|
}
|
|
|
|
|
|
VOID
|
|
BDLReleaseHandleList
|
|
(
|
|
IN PBDL_INTERNAL_DEVICE_EXTENSION pBDLExtension,
|
|
IN KIRQL irql
|
|
)
|
|
{
|
|
KeReleaseSpinLock(&(pBDLExtension->HandleListLock), irql);
|
|
}
|
|
|
|
|
|
VOID
|
|
BDLInitializeHandleList
|
|
(
|
|
IN HANDLELIST *pList
|
|
)
|
|
{
|
|
pList->pHead = NULL;
|
|
pList->pTail = NULL;
|
|
pList->NumHandles = 0;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
BDLAddHandleToList
|
|
(
|
|
IN HANDLELIST *pList,
|
|
IN BDD_DATA_HANDLE handle
|
|
)
|
|
{
|
|
LIST_NODE *pListNode = NULL;
|
|
|
|
#if DBG
|
|
|
|
//
|
|
// Make sure same handle isn't added twice
|
|
//
|
|
if (BDLValidateHandleIsInList(pList, handle) == TRUE)
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
#endif
|
|
|
|
if (NULL == (pListNode = (PLIST_NODE) ExAllocatePoolWithTag(
|
|
PagedPool,
|
|
sizeof(LIST_NODE),
|
|
BDL_LIST_ULONG_TAG)))
|
|
{
|
|
return (STATUS_NO_MEMORY);
|
|
}
|
|
|
|
// empty list
|
|
if (pList->pHead == NULL)
|
|
{
|
|
pList->pHead = pList->pTail = pListNode;
|
|
pListNode->pNext = NULL;
|
|
}
|
|
else
|
|
{
|
|
pListNode->pNext = pList->pHead;
|
|
pList->pHead = pListNode;
|
|
}
|
|
|
|
pList->NumHandles++;
|
|
|
|
pListNode->handle = handle;
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
BDLRemoveHandleFromList
|
|
(
|
|
IN HANDLELIST *pList,
|
|
IN BDD_DATA_HANDLE handle
|
|
)
|
|
{
|
|
LIST_NODE *pListNodeToDelete = pList->pHead;
|
|
LIST_NODE *pPrevListNode = pList->pHead;
|
|
|
|
// empty list
|
|
if (pListNodeToDelete == NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
// remove head
|
|
if (pListNodeToDelete->handle == handle)
|
|
{
|
|
// one element
|
|
if (pList->pHead == pList->pTail)
|
|
{
|
|
pList->pHead = pList->pTail = NULL;
|
|
}
|
|
else
|
|
{
|
|
pList->pHead = (PLIST_NODE) pListNodeToDelete->pNext;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pListNodeToDelete = (PLIST_NODE) pListNodeToDelete->pNext;
|
|
|
|
while ( (pListNodeToDelete != NULL) &&
|
|
(pListNodeToDelete->handle != handle))
|
|
{
|
|
pPrevListNode = pListNodeToDelete;
|
|
pListNodeToDelete = (PLIST_NODE) pListNodeToDelete->pNext;
|
|
}
|
|
|
|
if (pListNodeToDelete == NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
pPrevListNode->pNext = pListNodeToDelete->pNext;
|
|
|
|
// removing tail
|
|
if (pList->pTail == pListNodeToDelete)
|
|
{
|
|
pList->pTail = pPrevListNode;
|
|
}
|
|
}
|
|
|
|
pList->NumHandles--;
|
|
|
|
ExFreePoolWithTag(pListNodeToDelete, BDL_LIST_ULONG_TAG);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
BOOLEAN
|
|
BDLGetFirstHandle
|
|
(
|
|
IN HANDLELIST *pList,
|
|
OUT BDD_DATA_HANDLE *phandle
|
|
)
|
|
{
|
|
if (pList->pHead == NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
else
|
|
{
|
|
*phandle = pList->pHead->handle;
|
|
return (TRUE);
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
BDLValidateHandleIsInList
|
|
(
|
|
IN HANDLELIST *pList,
|
|
IN BDD_DATA_HANDLE handle
|
|
)
|
|
{
|
|
LIST_NODE *pListNode = pList->pHead;
|
|
|
|
while ((pListNode != NULL) && (pListNode->handle != handle))
|
|
{
|
|
pListNode = pListNode->pNext;
|
|
}
|
|
|
|
if (pList->pHead != NULL)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
else
|
|
{
|
|
return (TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|