Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. bdlutil.c
  5. Abstract:
  6. This module contains supporting routines forthe
  7. Microsoft Biometric Device Library
  8. Environment:
  9. Kernel mode only.
  10. Notes:
  11. Revision History:
  12. - Created May 2002 by Reid Kuhn
  13. --*/
  14. #include <stdarg.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. //#include <ntddk.h>
  18. #include <strsafe.h>
  19. #include <wdm.h>
  20. #include "bdlint.h"
  21. ULONG g_DebugLevel = (BDL_DEBUG_TRACE | BDL_DEBUG_ERROR | BDL_DEBUG_ASSERT);
  22. ULONG
  23. BDLGetDebugLevel()
  24. {
  25. return g_DebugLevel;
  26. }
  27. NTSTATUS
  28. BDLCallDriverCompletionRoutine
  29. (
  30. IN PDEVICE_OBJECT pDeviceObject,
  31. IN PIRP pIrp,
  32. IN PKEVENT pEvent
  33. )
  34. {
  35. UNREFERENCED_PARAMETER (pDeviceObject);
  36. if (pIrp->Cancel)
  37. {
  38. pIrp->IoStatus.Status = STATUS_CANCELLED;
  39. }
  40. else
  41. {
  42. pIrp->IoStatus.Status = STATUS_MORE_PROCESSING_REQUIRED;
  43. }
  44. KeSetEvent (pEvent, 0, FALSE);
  45. return (STATUS_MORE_PROCESSING_REQUIRED);
  46. }
  47. NTSTATUS
  48. BDLCallLowerLevelDriverAndWait
  49. (
  50. IN PDEVICE_OBJECT pAttachedDeviceObject,
  51. IN PIRP pIrp
  52. )
  53. {
  54. NTSTATUS status = STATUS_SUCCESS;
  55. KEVENT Event;
  56. //
  57. // Copy our stack location to the next
  58. //
  59. IoCopyCurrentIrpStackLocationToNext(pIrp);
  60. //
  61. // Initialize an event for process synchronization. The event is passed to
  62. // our completion routine and will be set when the lower level driver is done
  63. //
  64. KeInitializeEvent(&Event, NotificationEvent, FALSE);
  65. //
  66. // Set up the completion routine which will just set the event when it is called
  67. //
  68. IoSetCompletionRoutine(pIrp, BDLCallDriverCompletionRoutine, &Event, TRUE, TRUE, TRUE);
  69. //
  70. // When calling the lower lever driver it is done slightly different for Power IRPs
  71. // than other IRPs
  72. //
  73. if (IoGetCurrentIrpStackLocation(pIrp)->MajorFunction == IRP_MJ_POWER)
  74. {
  75. PoStartNextPowerIrp(pIrp);
  76. status = PoCallDriver(pAttachedDeviceObject, pIrp);
  77. }
  78. else
  79. {
  80. status = IoCallDriver(pAttachedDeviceObject, pIrp);
  81. }
  82. //
  83. // Wait until the lower lever driver has processed the Irp
  84. //
  85. if (status == STATUS_PENDING)
  86. {
  87. status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
  88. ASSERT (STATUS_SUCCESS == status);
  89. status = pIrp->IoStatus.Status;
  90. }
  91. return (status);
  92. }
  93. //
  94. // These functions are for managing the handle list
  95. //
  96. VOID
  97. BDLLockHandleList
  98. (
  99. IN PBDL_INTERNAL_DEVICE_EXTENSION pBDLExtension,
  100. OUT KIRQL *pirql
  101. )
  102. {
  103. KeAcquireSpinLock(&(pBDLExtension->HandleListLock), pirql);
  104. }
  105. VOID
  106. BDLReleaseHandleList
  107. (
  108. IN PBDL_INTERNAL_DEVICE_EXTENSION pBDLExtension,
  109. IN KIRQL irql
  110. )
  111. {
  112. KeReleaseSpinLock(&(pBDLExtension->HandleListLock), irql);
  113. }
  114. VOID
  115. BDLInitializeHandleList
  116. (
  117. IN HANDLELIST *pList
  118. )
  119. {
  120. pList->pHead = NULL;
  121. pList->pTail = NULL;
  122. pList->NumHandles = 0;
  123. }
  124. NTSTATUS
  125. BDLAddHandleToList
  126. (
  127. IN HANDLELIST *pList,
  128. IN BDD_DATA_HANDLE handle
  129. )
  130. {
  131. LIST_NODE *pListNode = NULL;
  132. #if DBG
  133. //
  134. // Make sure same handle isn't added twice
  135. //
  136. if (BDLValidateHandleIsInList(pList, handle) == TRUE)
  137. {
  138. ASSERT(FALSE);
  139. }
  140. #endif
  141. if (NULL == (pListNode = (PLIST_NODE) ExAllocatePoolWithTag(
  142. PagedPool,
  143. sizeof(LIST_NODE),
  144. BDL_LIST_ULONG_TAG)))
  145. {
  146. return (STATUS_NO_MEMORY);
  147. }
  148. // empty list
  149. if (pList->pHead == NULL)
  150. {
  151. pList->pHead = pList->pTail = pListNode;
  152. pListNode->pNext = NULL;
  153. }
  154. else
  155. {
  156. pListNode->pNext = pList->pHead;
  157. pList->pHead = pListNode;
  158. }
  159. pList->NumHandles++;
  160. pListNode->handle = handle;
  161. return(STATUS_SUCCESS);
  162. }
  163. BOOLEAN
  164. BDLRemoveHandleFromList
  165. (
  166. IN HANDLELIST *pList,
  167. IN BDD_DATA_HANDLE handle
  168. )
  169. {
  170. LIST_NODE *pListNodeToDelete = pList->pHead;
  171. LIST_NODE *pPrevListNode = pList->pHead;
  172. // empty list
  173. if (pListNodeToDelete == NULL)
  174. {
  175. return (FALSE);
  176. }
  177. // remove head
  178. if (pListNodeToDelete->handle == handle)
  179. {
  180. // one element
  181. if (pList->pHead == pList->pTail)
  182. {
  183. pList->pHead = pList->pTail = NULL;
  184. }
  185. else
  186. {
  187. pList->pHead = (PLIST_NODE) pListNodeToDelete->pNext;
  188. }
  189. }
  190. else
  191. {
  192. pListNodeToDelete = (PLIST_NODE) pListNodeToDelete->pNext;
  193. while ( (pListNodeToDelete != NULL) &&
  194. (pListNodeToDelete->handle != handle))
  195. {
  196. pPrevListNode = pListNodeToDelete;
  197. pListNodeToDelete = (PLIST_NODE) pListNodeToDelete->pNext;
  198. }
  199. if (pListNodeToDelete == NULL)
  200. {
  201. return (FALSE);
  202. }
  203. pPrevListNode->pNext = pListNodeToDelete->pNext;
  204. // removing tail
  205. if (pList->pTail == pListNodeToDelete)
  206. {
  207. pList->pTail = pPrevListNode;
  208. }
  209. }
  210. pList->NumHandles--;
  211. ExFreePoolWithTag(pListNodeToDelete, BDL_LIST_ULONG_TAG);
  212. return (TRUE);
  213. }
  214. BOOLEAN
  215. BDLGetFirstHandle
  216. (
  217. IN HANDLELIST *pList,
  218. OUT BDD_DATA_HANDLE *phandle
  219. )
  220. {
  221. if (pList->pHead == NULL)
  222. {
  223. return (FALSE);
  224. }
  225. else
  226. {
  227. *phandle = pList->pHead->handle;
  228. return (TRUE);
  229. }
  230. }
  231. BOOLEAN
  232. BDLValidateHandleIsInList
  233. (
  234. IN HANDLELIST *pList,
  235. IN BDD_DATA_HANDLE handle
  236. )
  237. {
  238. LIST_NODE *pListNode = pList->pHead;
  239. while ((pListNode != NULL) && (pListNode->handle != handle))
  240. {
  241. pListNode = pListNode->pNext;
  242. }
  243. if (pList->pHead != NULL)
  244. {
  245. return (FALSE);
  246. }
  247. else
  248. {
  249. return (TRUE);
  250. }
  251. }