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.

249 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. driverex.c
  5. Abstract
  6. Driver extension list management.
  7. Authors:
  8. Ervin P.
  9. Environment:
  10. Kernel mode only
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. /*
  15. * Including initguid.h defines the INITGUID symbol, which causes
  16. * GUID_CLASS_INPUT (in hidclass.h and poclass.h)
  17. * and GUID_DEVICE_SYS_BUTTON (in poclass.h) to get defined.
  18. */
  19. #include <initguid.h>
  20. #include <hidclass.h> // hidclass.h only defines GUID_CLASS_INPUT
  21. #include <wdmguid.h>
  22. #ifdef ALLOC_PRAGMA
  23. #pragma alloc_text(PAGE, DllInitialize)
  24. #pragma alloc_text(PAGE, DllUnload)
  25. #pragma alloc_text(PAGE, DriverEntry)
  26. #endif
  27. LIST_ENTRY driverExtList;
  28. FAST_MUTEX driverExtListMutex;
  29. //
  30. // Global counter of HID FDOs used for device object naming, destined to go
  31. // away once the device object naming issues are ironed out
  32. //
  33. ULONG HidpNextHidNumber = 0;
  34. #define MAKEULONG(low, high) ((ULONG)(((USHORT)(low)) | (((ULONG)((USHORT)(high))) << 16)))
  35. /*
  36. ********************************************************************************
  37. * EnqueueDriverExt
  38. ********************************************************************************
  39. *
  40. *
  41. */
  42. BOOLEAN EnqueueDriverExt(PHIDCLASS_DRIVER_EXTENSION driverExt)
  43. {
  44. PLIST_ENTRY listEntry;
  45. BOOLEAN result = TRUE;
  46. DBGVERBOSE(("Enqueue driver extension..."));
  47. ExAcquireFastMutex(&driverExtListMutex);
  48. /*
  49. * Make sure this driver entry is not already in our list.
  50. */
  51. listEntry = &driverExtList;
  52. while ((listEntry = listEntry->Flink) != &driverExtList){
  53. PHIDCLASS_DRIVER_EXTENSION thisDriverExt;
  54. thisDriverExt = CONTAINING_RECORD( listEntry,
  55. HIDCLASS_DRIVER_EXTENSION,
  56. ListEntry);
  57. if (thisDriverExt == driverExt){
  58. /*
  59. * This driver extension is already in our list!
  60. */
  61. ASSERT(thisDriverExt != driverExt);
  62. result = FALSE;
  63. break;
  64. }
  65. }
  66. if (result){
  67. InsertHeadList(&driverExtList, &driverExt->ListEntry);
  68. }
  69. ExReleaseFastMutex(&driverExtListMutex);
  70. return result;
  71. }
  72. /*
  73. ********************************************************************************
  74. * RefDriverExt
  75. ********************************************************************************
  76. *
  77. *
  78. */
  79. PHIDCLASS_DRIVER_EXTENSION RefDriverExt(IN PDRIVER_OBJECT MinidriverObject)
  80. {
  81. PLIST_ENTRY listEntry;
  82. PHIDCLASS_DRIVER_EXTENSION hidDriverExtension, result = NULL;
  83. DBGVERBOSE(("Ref driver extension..."));
  84. ExAcquireFastMutex(&driverExtListMutex);
  85. listEntry = &driverExtList;
  86. while ((listEntry = listEntry->Flink) != &driverExtList){
  87. hidDriverExtension = CONTAINING_RECORD( listEntry,
  88. HIDCLASS_DRIVER_EXTENSION,
  89. ListEntry );
  90. ASSERT(ISPTR(hidDriverExtension));
  91. if (hidDriverExtension->MinidriverObject == MinidriverObject){
  92. hidDriverExtension->ReferenceCount++;
  93. result = hidDriverExtension;
  94. break;
  95. }
  96. }
  97. ExReleaseFastMutex(&driverExtListMutex);
  98. ASSERT(result);
  99. return result;
  100. }
  101. /*
  102. ********************************************************************************
  103. * DerefDriverExt
  104. ********************************************************************************
  105. *
  106. */
  107. PHIDCLASS_DRIVER_EXTENSION DerefDriverExt(IN PDRIVER_OBJECT MinidriverObject)
  108. {
  109. PLIST_ENTRY listEntry;
  110. PHIDCLASS_DRIVER_EXTENSION result = NULL;
  111. DBGVERBOSE(("Deref driver extension..."));
  112. ExAcquireFastMutex(&driverExtListMutex);
  113. listEntry = &driverExtList;
  114. while ((listEntry = listEntry->Flink) != &driverExtList){
  115. PHIDCLASS_DRIVER_EXTENSION hidDriverExtension =
  116. CONTAINING_RECORD( listEntry,
  117. HIDCLASS_DRIVER_EXTENSION,
  118. ListEntry);
  119. ASSERT(ISPTR(hidDriverExtension));
  120. if (hidDriverExtension->MinidriverObject == MinidriverObject){
  121. hidDriverExtension->ReferenceCount--;
  122. /*
  123. * The extra dereference in HidpDriverUnload should
  124. * cause this ReferenceCount to eventually go to -1;
  125. * at that time, we can dequeue it.
  126. */
  127. if (hidDriverExtension->ReferenceCount < 0){
  128. /*
  129. * No need to free hidDriverExtension;
  130. * it gets freed when the driver object is freed.
  131. */
  132. ASSERT(hidDriverExtension->ReferenceCount == -1);
  133. RemoveEntryList(listEntry);
  134. if (hidDriverExtension->RegistryPath.Buffer) {
  135. ExFreePool(hidDriverExtension->RegistryPath.Buffer);
  136. }
  137. }
  138. result = hidDriverExtension;
  139. break;
  140. }
  141. }
  142. ExReleaseFastMutex(&driverExtListMutex);
  143. ASSERT(result);
  144. return result;
  145. }
  146. /*
  147. ********************************************************************************
  148. * DllUnload
  149. ********************************************************************************
  150. *
  151. * We need this routine so that the driver can get unloaded when all
  152. * references have been dropped by the minidriver.
  153. *
  154. */
  155. NTSTATUS
  156. DllUnload (VOID)
  157. {
  158. PAGED_CODE();
  159. DBGVERBOSE(("Unloading..."));
  160. return STATUS_SUCCESS;
  161. }
  162. /*
  163. ********************************************************************************
  164. * DllInitialize
  165. ********************************************************************************
  166. *
  167. * This routine called instead of DriverEntry since we're loaded as a DLL.
  168. *
  169. */
  170. NTSTATUS
  171. DllInitialize (PUNICODE_STRING RegistryPath)
  172. {
  173. PAGED_CODE();
  174. DBGVERBOSE(("Initializing hidclass dll..."));
  175. InitializeListHead(&driverExtList);
  176. ExInitializeFastMutex(&driverExtListMutex);
  177. HidpNextHidNumber = 0;
  178. return STATUS_SUCCESS;
  179. }
  180. /*
  181. ********************************************************************************
  182. * DriverEntry
  183. ********************************************************************************
  184. *
  185. * This routine is required by the linker,
  186. * but SHOULD NEVER BE CALLED since we're loaded as a DLL.
  187. *
  188. */
  189. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
  190. {
  191. UNREFERENCED_PARAMETER(DriverObject);
  192. UNREFERENCED_PARAMETER(RegistryPath);
  193. PAGED_CODE();
  194. ASSERT(!(PVOID)"DriverEntry should never get called!");
  195. return STATUS_SUCCESS;
  196. }