Source code of Windows XP (NT5)
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.

219 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module performs initialization for the SAC device driver.
  7. Author:
  8. Sean Selitrennikoff (v-seans) - Jan 11, 1999
  9. Revision History:
  10. --*/
  11. #include "sac.h"
  12. NTSTATUS
  13. DriverEntry(
  14. IN PDRIVER_OBJECT DriverObject,
  15. IN PUNICODE_STRING RegistryPath
  16. );
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text( INIT, DriverEntry )
  19. #endif
  20. NTSTATUS
  21. DriverEntry (
  22. IN PDRIVER_OBJECT DriverObject,
  23. IN PUNICODE_STRING RegistryPath
  24. )
  25. /*++
  26. Routine Description:
  27. This is the initialization routine for the SAC device driver.
  28. Arguments:
  29. DriverObject - Pointer to driver object created by the system.
  30. Return Value:
  31. The function value is the final status from the initialization operation.
  32. --*/
  33. {
  34. NTSTATUS Status;
  35. UNICODE_STRING DeviceName;
  36. CLONG i;
  37. BOOLEAN Success;
  38. PDEVICE_OBJECT DeviceObject;
  39. PSAC_DEVICE_CONTEXT DeviceContext;
  40. HEADLESS_RSP_QUERY_INFO Response;
  41. SIZE_T Length;
  42. PAGED_CODE( );
  43. IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DriverEntry: Entering.\n")));
  44. //
  45. // If the system is not setup to use a terminal, then just exit now.
  46. //
  47. Length = sizeof(HEADLESS_RSP_QUERY_INFO);
  48. HeadlessDispatch(HeadlessCmdQueryInformation,
  49. NULL,
  50. 0,
  51. &Response,
  52. &Length
  53. );
  54. if ((Response.PortType == HeadlessUndefinedPortType) ||
  55. ((Response.PortType == HeadlessSerialPort) && !Response.Serial.TerminalAttached)) {
  56. return STATUS_PORT_DISCONNECTED;
  57. }
  58. //
  59. // Create the device object. (IoCreateDevice zeroes the memory
  60. // occupied by the object.)
  61. //
  62. // An ACL to the device object in InitializeDeviceData().
  63. //
  64. RtlInitUnicodeString(&DeviceName, SAC_DEVICE_NAME);
  65. Status = IoCreateDevice(DriverObject, // DriverObject
  66. sizeof(SAC_DEVICE_CONTEXT), // DeviceExtension
  67. &DeviceName, // DeviceName
  68. FILE_DEVICE_NAMED_PIPE, // DeviceType
  69. 0, // DeviceCharacteristics
  70. FALSE, // Exclusive
  71. &DeviceObject // DeviceObject
  72. );
  73. if (!NT_SUCCESS(Status)) {
  74. IF_SAC_DEBUG(SAC_DEBUG_FAILS,
  75. KdPrint(( "SAC DriverEntry: unable to create device object: %X\n", Status )));
  76. goto ErrorExit;
  77. }
  78. DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension;
  79. DeviceContext->InitializedAndReady = FALSE;
  80. //
  81. // Initialize the driver object for this file system driver.
  82. //
  83. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  84. DriverObject->MajorFunction[i] = Dispatch;
  85. }
  86. //
  87. // Special case for IRP_MJ_DEVICE_CONTROL since it is
  88. // the most often used function in SAC.
  89. //
  90. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
  91. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl;
  92. DriverObject->FastIoDispatch = NULL;
  93. DriverObject->DriverUnload = UnloadHandler;
  94. //
  95. // Initialize global data.
  96. //
  97. Success = InitializeGlobalData(RegistryPath, DriverObject);
  98. if (!Success) {
  99. Status = STATUS_INSUFFICIENT_RESOURCES;
  100. goto ErrorExit;
  101. }
  102. //
  103. // Initialize our device object.
  104. //
  105. Success = InitializeDeviceData(DeviceObject);
  106. if (!Success) {
  107. Status = STATUS_INSUFFICIENT_RESOURCES;
  108. goto ErrorExit;
  109. }
  110. //
  111. // Register that we want shutdown notification. If this fails, no big deal, as
  112. // we only lose telling the user of this development.
  113. //
  114. IoRegisterShutdownNotification(DeviceObject);
  115. return (Status);
  116. ErrorExit:
  117. FreeGlobalData();
  118. IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC DriverEntry: Exiting with status 0x%x\n", Status)));
  119. return Status;
  120. } // DriverEntry
  121. VOID
  122. UnloadHandler(
  123. IN PDRIVER_OBJECT DriverObject
  124. )
  125. /*++
  126. Routine Description:
  127. This is the routine for handling unloading of the driver.
  128. Arguments:
  129. DriverObject - Pointer to driver object created by the system.
  130. Return Value:
  131. None.
  132. --*/
  133. {
  134. PDEVICE_OBJECT DeviceContext;
  135. PDEVICE_OBJECT NextDeviceContext;
  136. IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC UnloadHandler: Entering.\n")));
  137. //
  138. // Walk down each device, disconnecting it and freeing it.
  139. //
  140. DeviceContext = DriverObject->DeviceObject;
  141. while (DeviceContext != NULL) {
  142. NextDeviceContext = (PDEVICE_OBJECT)DeviceContext->NextDevice;
  143. FreeDeviceData(DeviceContext);
  144. IoDeleteDevice(DeviceContext);
  145. DeviceContext = NextDeviceContext;
  146. }
  147. //
  148. // Free global data
  149. //
  150. FreeGlobalData();
  151. IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC UnloadHandler: Exiting.\n")));
  152. }