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.

586 lines
15 KiB

  1. /*++
  2. Copyright (c) 1991 - 2001 Microsoft Corporation
  3. Module Name:
  4. ## ## ### #### ## # #### ##### #####
  5. ### ### ### ## ### # ## # ## ## ## ##
  6. ######## ## ## ## #### # ## ## ## ## ##
  7. # ### ## ## ## ## # #### ## ## ## ## ##
  8. # # ## ####### ## # ### ## ##### #####
  9. # ## ## ## ## # ## ## ## # ## ##
  10. # ## ## ## #### # # ## #### ## ##
  11. Abstract:
  12. This module contains the code for all driver initializtion
  13. and create/close IRP processing.
  14. Author:
  15. Wesley Witt (wesw) 1-Oct-2001
  16. Environment:
  17. Kernel mode only.
  18. Notes:
  19. --*/
  20. #include "internal.h"
  21. #ifdef ALLOC_PRAGMA
  22. #pragma alloc_text(INIT,DriverEntry)
  23. #pragma alloc_text(PAGE,SaPortCreate)
  24. #pragma alloc_text(PAGE,SaPortClose)
  25. #pragma alloc_text(PAGE,SaPortSystemControl)
  26. #pragma alloc_text(PAGE,SaPortCleanup)
  27. #endif
  28. #if DBG
  29. extern ULONG SaPortDebugLevel[5];
  30. #endif
  31. ULONG OsMajorVersion;
  32. ULONG OsMinorVersion;
  33. NTSTATUS
  34. DllInitialize(
  35. IN PUNICODE_STRING RegistryPath
  36. )
  37. /*++
  38. Routine Description:
  39. DLL initialization funtion.
  40. Arguments:
  41. RegistryPath - String containing the path to the driver's registry data
  42. Return Value:
  43. STATUS_SUCCESS
  44. --*/
  45. {
  46. UNREFERENCED_PARAMETER(RegistryPath);
  47. return STATUS_SUCCESS;
  48. }
  49. NTSTATUS
  50. DriverEntry(
  51. IN PDRIVER_OBJECT DriverObject,
  52. IN PUNICODE_STRING RegistryPath
  53. )
  54. /*++
  55. Routine Description:
  56. Temporary entry point needed to initialize the scsi port driver.
  57. Arguments:
  58. DriverObject - Pointer to the driver object created by the system.
  59. RegistryPath - String containing the path to the driver's registry data
  60. Return Value:
  61. STATUS_SUCCESS
  62. --*/
  63. {
  64. //
  65. // NOTE: This routine should not be needed ! DriverEntry is defined
  66. // in the miniport driver.
  67. //
  68. UNREFERENCED_PARAMETER(DriverObject);
  69. UNREFERENCED_PARAMETER(RegistryPath);
  70. return STATUS_SUCCESS;
  71. }
  72. NTSTATUS
  73. SaPortDefaultDispatch(
  74. IN PDEVICE_OBJECT DeviceObject,
  75. IN PIRP Irp
  76. )
  77. /*++
  78. Routine Description:
  79. This routine is the default dispatch which passes down to the next layer.
  80. Arguments:
  81. DeviceObject - Supplies the device object.
  82. Irp - Supplies the IO request packet.
  83. Return Value:
  84. NTSTATUS
  85. --*/
  86. {
  87. UNREFERENCED_PARAMETER(DeviceObject);
  88. return CompleteRequest( Irp, STATUS_INVALID_DEVICE_REQUEST, 0 );
  89. }
  90. NTSTATUS
  91. SaPortInitialize(
  92. IN PDRIVER_OBJECT DriverObject,
  93. IN PUNICODE_STRING RegistryPath,
  94. IN PSAPORT_INITIALIZATION_DATA SaPortInitData
  95. )
  96. /*++
  97. Routine Description:
  98. This function is the port driver's substitute for the miniport's DriverEntry
  99. routine. The miniport driver MUST call this function from it's DriverEntry
  100. to initialize the driver stack.
  101. Arguments:
  102. DriverObject - Pointer to the driver object created by the system.
  103. RegistryPath - String containing the path to the driver's registry data
  104. SaPortInitData - Pointer to the miniport's SAPORT_INITIALIZATION_DATA data structure
  105. Return Value:
  106. NT status code
  107. --*/
  108. {
  109. NTSTATUS Status;
  110. PSAPORT_DRIVER_EXTENSION DriverExtension;
  111. PKEY_VALUE_FULL_INFORMATION KeyInformation = NULL;
  112. //
  113. // Create and initialize the driver extension
  114. //
  115. DriverExtension = (PSAPORT_DRIVER_EXTENSION)IoGetDriverObjectExtension( DriverObject, SaPortInitialize );
  116. if (DriverExtension == NULL) {
  117. Status = IoAllocateDriverObjectExtension(
  118. DriverObject,
  119. SaPortInitialize,
  120. sizeof(SAPORT_DRIVER_EXTENSION),
  121. (PVOID*)&DriverExtension
  122. );
  123. if (!NT_SUCCESS(Status)) {
  124. DebugPrint(( SaPortInitData->DeviceType, SAPORT_DEBUG_ERROR_LEVEL, "IoAllocateDriverObjectExtension failed [0x%08x]\n", Status ));
  125. return Status;
  126. }
  127. }
  128. RtlCopyMemory( &DriverExtension->InitData, SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
  129. DriverExtension->RegistryPath.Buffer = (PWSTR) ExAllocatePool( NonPagedPool, RegistryPath->MaximumLength );
  130. if (DriverExtension->RegistryPath.Buffer == NULL) {
  131. REPORT_ERROR( SaPortInitData->DeviceType, "Failed to allocate pool for string", STATUS_INSUFFICIENT_RESOURCES );
  132. return STATUS_INSUFFICIENT_RESOURCES;
  133. }
  134. RtlCopyMemory( DriverExtension->RegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length );
  135. DriverExtension->RegistryPath.Length = RegistryPath->Length;
  136. DriverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
  137. DriverExtension->DriverObject = DriverObject;
  138. //
  139. // Get the OS version; this is used by the
  140. // port driver and the mini-ports to have
  141. // OS dependent code that is dynamic at runtime
  142. //
  143. GetOsVersion();
  144. //
  145. // Get the debug level value from the registry
  146. //
  147. #if DBG
  148. SaPortDebugLevel[SaPortInitData->DeviceType] = 0;
  149. Status = ReadRegistryValue( DriverExtension, RegistryPath, L"DebugLevel", &KeyInformation );
  150. if (NT_SUCCESS(Status) && KeyInformation->Type == REG_DWORD) {
  151. SaPortDebugLevel[SaPortInitData->DeviceType] = *(PULONG)((PUCHAR)KeyInformation + KeyInformation->DataOffset);
  152. }
  153. if (KeyInformation) {
  154. ExFreePool( KeyInformation );
  155. }
  156. #endif
  157. //
  158. // Print a banner that includes the
  159. // OS version and the version/build date
  160. // of the driver
  161. //
  162. #if DBG
  163. PrintDriverVersion( SaPortInitData->DeviceType, DriverObject );
  164. #endif
  165. //
  166. // Parameter validation
  167. //
  168. if (SaPortInitData == NULL || SaPortInitData->StructSize != sizeof(SAPORT_INITIALIZATION_DATA) ||
  169. SaPortInitData->HwInitialize == NULL || SaPortInitData->DeviceIoctl == NULL) {
  170. DebugPrint(( SaPortInitData->DeviceType, SAPORT_DEBUG_ERROR_LEVEL, "SAPORT_INITIALIZATION_DATA fields are invalid [0x%08x]\n", STATUS_INVALID_PARAMETER ));
  171. return STATUS_INVALID_PARAMETER;
  172. }
  173. //
  174. // Now check the device specific callbacks
  175. //
  176. switch (SaPortInitData->DeviceType) {
  177. case SA_DEVICE_DISPLAY:
  178. if (SaPortInitData->Write == NULL) {
  179. return STATUS_INVALID_PARAMETER;
  180. }
  181. Status = STATUS_SUCCESS;
  182. break;
  183. case SA_DEVICE_KEYPAD:
  184. if (SaPortInitData->Read == NULL) {
  185. return STATUS_INVALID_PARAMETER;
  186. }
  187. Status = STATUS_SUCCESS;
  188. break;
  189. case SA_DEVICE_NVRAM:
  190. Status = STATUS_SUCCESS;
  191. break;
  192. case SA_DEVICE_WATCHDOG:
  193. Status = STATUS_SUCCESS;
  194. break;
  195. }
  196. if (!NT_SUCCESS(Status)) {
  197. DebugPrint(( SaPortInitData->DeviceType, SAPORT_DEBUG_ERROR_LEVEL, "SAPORT_INITIALIZATION_DATA fields are invalid [0x%08x]\n", Status ));
  198. return Status;
  199. }
  200. //
  201. // Do any device specific initialization
  202. //
  203. switch (SaPortInitData->DeviceType) {
  204. case SA_DEVICE_DISPLAY:
  205. Status = SaDisplayDeviceInitialization( DriverExtension );
  206. break;
  207. case SA_DEVICE_KEYPAD:
  208. Status = SaKeypadDeviceInitialization( DriverExtension );
  209. break;
  210. case SA_DEVICE_NVRAM:
  211. Status = SaNvramDeviceInitialization( DriverExtension );
  212. break;
  213. case SA_DEVICE_WATCHDOG:
  214. Status = SaWatchdogDeviceInitialization( DriverExtension );
  215. break;
  216. }
  217. if (!NT_SUCCESS(Status)) {
  218. DebugPrint(( SaPortInitData->DeviceType, SAPORT_DEBUG_ERROR_LEVEL, "Device specific initialization failed [0x%08x]\n", Status ));
  219. return Status;
  220. }
  221. //
  222. // Set up the device driver entry points.
  223. //
  224. for (ULONG i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) {
  225. DriverObject->MajorFunction[i] = SaPortDefaultDispatch;
  226. }
  227. DriverObject->MajorFunction[IRP_MJ_CREATE] = SaPortCreate;
  228. DriverObject->MajorFunction[IRP_MJ_CLOSE] = SaPortClose;
  229. DriverObject->MajorFunction[IRP_MJ_READ] = SaPortRead;
  230. DriverObject->MajorFunction[IRP_MJ_WRITE] = SaPortWrite;
  231. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SaPortDeviceControl;
  232. DriverObject->MajorFunction[IRP_MJ_PNP] = SaPortPnp;
  233. DriverObject->MajorFunction[IRP_MJ_POWER] = SaPortPower;
  234. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = SaPortShutdown;
  235. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SaPortSystemControl;
  236. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SaPortCleanup;
  237. //
  238. // Set up the device driver's pnp-power routine & add routine
  239. //
  240. DriverObject->DriverExtension->AddDevice = SaPortAddDevice;
  241. DriverObject->DriverStartIo = SaPortStartIo;
  242. return STATUS_SUCCESS;
  243. }
  244. NTSTATUS
  245. SaPortCleanup(
  246. IN PDEVICE_OBJECT DeviceObject,
  247. IN PIRP Irp
  248. )
  249. /*++
  250. Routine Description:
  251. This routine is the dispatch routine for IRP cleanup.
  252. Arguments:
  253. DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
  254. Irp - a pointer to the I/O Request Packet for this request.
  255. Return Value:
  256. Always returns STATUS_SUCCESS, since this is a null operation.
  257. --*/
  258. {
  259. Irp->IoStatus.Status = STATUS_SUCCESS;
  260. Irp->IoStatus.Information = 0;
  261. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  262. return STATUS_SUCCESS;
  263. }
  264. NTSTATUS
  265. SaPortCreate(
  266. IN PDEVICE_OBJECT DeviceObject,
  267. IN PIRP Irp
  268. )
  269. /*++
  270. Routine Description:
  271. This routine is called only rarely by the I/O system; it's mainly
  272. for layered drivers to call. All it does is complete the IRP
  273. successfully.
  274. Arguments:
  275. DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
  276. Irp - a pointer to the I/O Request Packet for this request.
  277. Return Value:
  278. Always returns STATUS_SUCCESS, since this is a null operation.
  279. --*/
  280. {
  281. NTSTATUS Status = STATUS_SUCCESS;
  282. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  283. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
  284. PVOID FsContext = NULL;
  285. UNREFERENCED_PARAMETER( DeviceObject );
  286. DebugPrint(( DeviceExtension->DeviceType, SAPORT_DEBUG_INFO_LEVEL, "SaPortCreate [fo=%08x]\n", IrpSp->FileObject ));
  287. if (DeviceExtension->InitData->CreateRoutine) {
  288. if (DeviceExtension->InitData->FileContextSize) {
  289. FsContext = ExAllocatePool( PagedPool, DeviceExtension->InitData->FileContextSize );
  290. if (FsContext == NULL) {
  291. return CompleteRequest( Irp, STATUS_INSUFFICIENT_RESOURCES, 0 );
  292. }
  293. RtlZeroMemory( FsContext, DeviceExtension->InitData->FileContextSize );
  294. }
  295. Status = DeviceExtension->InitData->CreateRoutine(
  296. DeviceExtension->MiniPortDeviceExtension,
  297. Irp,
  298. FsContext
  299. );
  300. if (!NT_SUCCESS(Status)) {
  301. REPORT_ERROR( DeviceExtension->DeviceType, "Miniport create routine failed", Status );
  302. if (FsContext) {
  303. ExFreePool( FsContext );
  304. }
  305. } else {
  306. IrpSp->FileObject->FsContext = FsContext;
  307. }
  308. }
  309. return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
  310. }
  311. NTSTATUS
  312. SaPortClose(
  313. IN PDEVICE_OBJECT DeviceObject,
  314. IN PIRP Irp
  315. )
  316. /*++
  317. Routine Description:
  318. This routine is called only rarely by the I/O system; it's mainly
  319. for layered drivers to call. All it does is complete the IRP
  320. successfully.
  321. Arguments:
  322. DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
  323. Irp - a pointer to the I/O Request Packet for this request.
  324. Return Value:
  325. Always returns STATUS_SUCCESS, since this is a null operation.
  326. --*/
  327. {
  328. NTSTATUS Status;
  329. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  330. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
  331. PVOID FsContext;
  332. UNREFERENCED_PARAMETER( DeviceObject );
  333. DebugPrint(( DeviceExtension->DeviceType, SAPORT_DEBUG_INFO_LEVEL, "SaPortClose [fo=%08x]\n", IrpSp->FileObject ));
  334. FsContext = (PVOID) IrpSp->FileObject->FsContext;
  335. if (DeviceExtension->InitData->CloseRoutine) {
  336. Status = DeviceExtension->InitData->CloseRoutine(
  337. DeviceExtension->MiniPortDeviceExtension,
  338. Irp,
  339. FsContext
  340. );
  341. if (!NT_SUCCESS(Status)) {
  342. REPORT_ERROR( DeviceExtension->DeviceType, "Miniport close routine failed", Status );
  343. }
  344. } else {
  345. Status = STATUS_SUCCESS;
  346. }
  347. if (FsContext) {
  348. IrpSp->FileObject->FsContext = NULL;
  349. ExFreePool( FsContext );
  350. }
  351. return CompleteRequest( Irp, STATUS_SUCCESS, 0 );
  352. }
  353. NTSTATUS
  354. SaPortShutdown(
  355. IN PDEVICE_OBJECT DeviceObject,
  356. IN PIRP Irp
  357. )
  358. /*++
  359. Routine Description:
  360. This routine is called only rarely by the I/O system; it's mainly
  361. for layered drivers to call. All it does is complete the IRP
  362. successfully.
  363. Arguments:
  364. DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
  365. Irp - a pointer to the I/O Request Packet for this request.
  366. Return Value:
  367. Always returns STATUS_SUCCESS, since this is a null operation.
  368. --*/
  369. {
  370. NTSTATUS Status = STATUS_SUCCESS;
  371. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  372. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
  373. switch (DeviceExtension->DriverExtension->InitData.DeviceType) {
  374. case SA_DEVICE_DISPLAY:
  375. Status = SaDisplayShutdownNotification( (PDISPLAY_DEVICE_EXTENSION)DeviceExtension, Irp, IrpSp );
  376. break;
  377. case SA_DEVICE_KEYPAD:
  378. Status = SaKeypadShutdownNotification( (PKEYPAD_DEVICE_EXTENSION)DeviceExtension, Irp, IrpSp );
  379. break;
  380. case SA_DEVICE_NVRAM:
  381. Status = SaNvramShutdownNotification( (PNVRAM_DEVICE_EXTENSION)DeviceExtension, Irp, IrpSp );
  382. break;
  383. case SA_DEVICE_WATCHDOG:
  384. Status = SaWatchdogShutdownNotification( (PWATCHDOG_DEVICE_EXTENSION)DeviceExtension, Irp, IrpSp );
  385. break;
  386. }
  387. if (!NT_SUCCESS(Status)) {
  388. REPORT_ERROR( DeviceExtension->DeviceType, "Device specific shutdown notification failed", Status );
  389. }
  390. return ForwardRequest( Irp, DeviceExtension->TargetObject );
  391. }
  392. NTSTATUS
  393. SaPortSystemControl(
  394. IN PDEVICE_OBJECT DeviceObject,
  395. IN PIRP Irp
  396. )
  397. /*++
  398. Routine Description:
  399. IRP_MJ_SYSTEM_CONTROL dispatch routine. Currently, we don't handle
  400. this. So, if this is FDO just pass it to the lower driver. If this
  401. is PDO complete the irp with changing the irp status.
  402. Arguments:
  403. DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
  404. Irp - a pointer to the I/O Request Packet for this request.
  405. Return Value:
  406. --*/
  407. {
  408. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
  409. IoSkipCurrentIrpStackLocation( Irp );
  410. return IoCallDriver( DeviceExtension->TargetObject, Irp );
  411. }