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.

314 lines
8.3 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Module: device.c
  4. //
  5. // Description:
  6. //
  7. //
  8. //@@BEGIN_MSINTERNAL
  9. // Development Team:
  10. // S.Mohanraj
  11. //
  12. // History: Date Author Comment
  13. //
  14. //@@END_MSINTERNAL
  15. //---------------------------------------------------------------------------
  16. //
  17. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  18. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  20. // PURPOSE.
  21. //
  22. // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
  23. //
  24. //---------------------------------------------------------------------------
  25. #define IRPMJFUNCDESC
  26. //#define TIME_BOMB
  27. #include "common.h"
  28. #ifdef TIME_BOMB
  29. #include <ksdebug.h>
  30. #include "..\timebomb\timebomb.c"
  31. #endif
  32. //---------------------------------------------------------------------------
  33. //---------------------------------------------------------------------------
  34. PDEVICE_INSTANCE gpDeviceInstance = NULL;
  35. DEFINE_KSCREATE_DISPATCH_TABLE(DeviceCreateItems)
  36. {
  37. DEFINE_KSCREATE_ITEMNULL(
  38. CFilterInstance::FilterDispatchCreate,
  39. NULL),
  40. };
  41. //---------------------------------------------------------------------------
  42. //---------------------------------------------------------------------------
  43. #pragma INIT_CODE
  44. #pragma INIT_DATA
  45. NTSTATUS
  46. DriverEntry
  47. (
  48. IN PDRIVER_OBJECT DriverObject,
  49. IN PUNICODE_STRING usRegistryPathName
  50. )
  51. {
  52. NTSTATUS Status = STATUS_SUCCESS;
  53. #ifdef TIME_BOMB
  54. if (HasEvaluationTimeExpired()) {
  55. return STATUS_EVALUATION_EXPIRATION;
  56. }
  57. #endif
  58. KeInitializeMutex(&gMutex, 0);
  59. //
  60. // ISSUE: 02/13/02 ALPERS
  61. // Why would we acquire the mutex in DriverEntry?
  62. //
  63. GrabMutex();
  64. DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
  65. DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
  66. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
  67. DriverObject->DriverUnload = DriverUnload;
  68. DriverObject->DriverExtension->AddDevice = AddDevice;
  69. KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
  70. KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
  71. KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
  72. KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
  73. Status = InitializeUtil();
  74. if(!NT_SUCCESS(Status)) {
  75. Trap();
  76. goto exit;
  77. }
  78. Status = InitializeFilterNode();
  79. if(!NT_SUCCESS(Status)) {
  80. Trap();
  81. goto exit;
  82. }
  83. Status = InitializeDeviceNode();
  84. if(!NT_SUCCESS(Status)) {
  85. Trap();
  86. goto exit;
  87. }
  88. Status = InitializeVirtualSourceLine();
  89. if(!NT_SUCCESS(Status)) {
  90. Trap();
  91. goto exit;
  92. }
  93. InitializeListHead(&gEventQueue);
  94. KeInitializeSpinLock(&gEventLock);
  95. exit:
  96. //
  97. // SECURITY NOTE:
  98. // The PnP system will not send anymore message if this routine fails. Even
  99. // DriverUnload will not be called.
  100. // According to DDK docs DriverEntry should do its own cleanup in case of
  101. // failures.
  102. //
  103. if (!NT_SUCCESS(Status)) {
  104. UninitializeUtil();
  105. UninitializeVirtualSourceLine();
  106. UninitializeDeviceNode();
  107. UninitializeFilterNode();
  108. UninitializeMemory();
  109. }
  110. ReleaseMutex();
  111. return(Status);
  112. }
  113. #pragma PAGEABLE_CODE
  114. #pragma PAGEABLE_DATA
  115. NTSTATUS
  116. DispatchPnp(
  117. IN PDEVICE_OBJECT pDeviceObject,
  118. IN PIRP pIrp
  119. )
  120. {
  121. PIO_STACK_LOCATION pIrpStack;
  122. pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
  123. switch(pIrpStack->MinorFunction) {
  124. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  125. //
  126. // Mark the device as not disableable.
  127. //
  128. pIrp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
  129. break;
  130. case IRP_MN_REMOVE_DEVICE:
  131. //
  132. // We need to unregister the notifications first before killing the
  133. // worker threads
  134. //
  135. UnregisterForPlugPlayNotifications();
  136. //
  137. // Needs to be outside the mutex because KsUnregisterWorker blocks
  138. // until all worker threads are done
  139. //
  140. UninitializeUtil();
  141. GrabMutex();
  142. CShingleInstance::UninitializeShingle();
  143. UninitializeFilterNode();
  144. UninitializeDeviceNode();
  145. UninitializeVirtualSourceLine();
  146. gpDeviceInstance = NULL;
  147. UninitializeMemory();
  148. ReleaseMutex();
  149. break;
  150. }
  151. return(KsDefaultDispatchPnp(pDeviceObject, pIrp));
  152. }
  153. VOID
  154. DriverUnload(
  155. IN PDRIVER_OBJECT DriverObject
  156. )
  157. {
  158. }
  159. NTSTATUS
  160. AddDevice(
  161. IN PDRIVER_OBJECT DriverObject,
  162. IN PDEVICE_OBJECT PhysicalDeviceObject
  163. )
  164. /*++
  165. Routine Description:
  166. When a new device is detected, PnP calls this entry point with the
  167. new PhysicalDeviceObject (PDO). The driver creates an associated
  168. FunctionalDeviceObject (FDO).
  169. Arguments:
  170. DriverObject -
  171. Pointer to the driver object.
  172. PhysicalDeviceObject -
  173. Pointer to the new physical device object.
  174. Return Values:
  175. STATUS_SUCCESS or an appropriate error condition.
  176. --*/
  177. {
  178. PDEVICE_OBJECT FunctionalDeviceObject = NULL;
  179. NTSTATUS Status;
  180. int i;
  181. GrabMutex();
  182. Status = IoCreateDevice(
  183. DriverObject,
  184. sizeof(DEVICE_INSTANCE),
  185. NULL,
  186. FILE_DEVICE_KS,
  187. 0,
  188. FALSE,
  189. &FunctionalDeviceObject);
  190. if(!NT_SUCCESS(Status)) {
  191. Trap();
  192. goto exit;
  193. }
  194. gpDeviceInstance =
  195. (PDEVICE_INSTANCE)FunctionalDeviceObject->DeviceExtension;
  196. gpDeviceInstance->pPhysicalDeviceObject = PhysicalDeviceObject;
  197. Status = KsAllocateDeviceHeader(
  198. &gpDeviceInstance->pDeviceHeader,
  199. SIZEOF_ARRAY(DeviceCreateItems),
  200. (PKSOBJECT_CREATE_ITEM)DeviceCreateItems);
  201. if(!NT_SUCCESS(Status)) {
  202. Trap();
  203. goto exit;
  204. }
  205. KsSetDevicePnpAndBaseObject(
  206. gpDeviceInstance->pDeviceHeader,
  207. IoAttachDeviceToDeviceStack(FunctionalDeviceObject, PhysicalDeviceObject),
  208. FunctionalDeviceObject);
  209. //
  210. // ISSUE: 05/13/2002 ALPERS
  211. // StackSize Problem
  212. // Note that we may still have StackSize problems with deeper objects.
  213. // The problem will be caught by IO verifier.
  214. // However in real world, we do not expect any problems because usbaudio
  215. // driver will never passes-down requests from Sysaudio. In other words,
  216. // even if DeviceStackSize is deeper than Sysaudio, the IRP will never go
  217. // down-level from Usbaudio.
  218. //
  219. //
  220. // Set the StackSize for deeper device stacks.
  221. // Sysaudio StackSize is normally 2.
  222. // SYSAUDIO - FDO
  223. // SWENUM - PDO
  224. //
  225. // Sysaudio forwards the IRPs to other device stacks which might
  226. // be deeper than 2. In that case IoVerifier will bugcheck.
  227. // An example of this is an upper UsbAudio filter driver forwarding
  228. // IRPs to UsbAudio.
  229. //
  230. // Setting FDO StackSize to DEFAULT_LARGE_IRP_LOCATIONS 8 (iomgr.h)
  231. // guarantees that the IRP comes from large IRP lookaside list in kernel.
  232. // Thus no memory is wasted. The system has a list of IRPs that it recycles.
  233. //
  234. // StackSize 7 will almost guarantee that sysaudio will be deep enough
  235. // for any DeviceStack, even with IoVerifier turned on.
  236. //
  237. if (FunctionalDeviceObject->StackSize < SYSTEM_LARGE_IRP_LOCATIONS) {
  238. FunctionalDeviceObject->StackSize = SYSTEM_LARGE_IRP_LOCATIONS;
  239. }
  240. Status = RegisterForPlugPlayNotifications();
  241. if(!NT_SUCCESS(Status)) {
  242. Trap();
  243. goto exit;
  244. }
  245. Status = CShingleInstance::InitializeShingle();
  246. if(!NT_SUCCESS(Status)) {
  247. Trap();
  248. goto exit;
  249. }
  250. DeviceCreateItems[0].Context =
  251. apShingleInstance[KSPROPERTY_SYSAUDIO_NORMAL_DEFAULT];
  252. FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
  253. FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  254. exit:
  255. ReleaseMutex();
  256. return(Status);
  257. }
  258. //---------------------------------------------------------------------------
  259. // End of File: device.c
  260. //---------------------------------------------------------------------------