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.

313 lines
8.9 KiB

  1. /*++
  2. Copyright (c) 1991 - 2002 Microsoft Corporation
  3. Module Name:
  4. ## ## ### ## # ## ##### #### ##### #####
  5. ### ### ## # ## ### ## ## ## ## # ## ## ## ##
  6. ######## ### ## ### ## ## ## ## ## ## ## ##
  7. # ### ## ### ## # # ## ## ## ## ## ## ## ##
  8. # # ## ### ### ### ## ## ## ##### #####
  9. # ## # ## ### ### ## ## ## ## # ## ##
  10. # ## ### ## ## ##### ## #### ## ##
  11. Abstract:
  12. This module contains the entire implementation of
  13. the virtual watchdog miniport driver.
  14. @@BEGIN_DDKSPLIT
  15. Author:
  16. Wesley Witt (wesw) 1-Oct-2001
  17. @@END_DDKSPLIT
  18. Environment:
  19. Kernel mode only.
  20. Notes:
  21. --*/
  22. #include "mswd.h"
  23. #ifdef ALLOC_PRAGMA
  24. #pragma alloc_text(INIT,DriverEntry)
  25. #endif
  26. VOID
  27. MsWdTimerReset(
  28. IN PDEVICE_EXTENSION DeviceExtension
  29. )
  30. {
  31. LARGE_INTEGER DueTime;
  32. KeQuerySystemTime( &DeviceExtension->StartTime );
  33. DueTime.QuadPart = DeviceExtension->TimeoutValue.QuadPart;
  34. KeSetTimer( &DeviceExtension->Timer, DueTime, &DeviceExtension->TimerDpc );
  35. }
  36. VOID
  37. MsWdShutdownWorker(
  38. IN PDEVICE_OBJECT DeviceObject,
  39. IN PVOID Context
  40. )
  41. {
  42. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) Context;
  43. ULONG ExpireBehavior;
  44. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  45. ExpireBehavior = DeviceExtension->ExpireBehavior;
  46. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  47. SaPortShutdownSystem( ExpireBehavior == 1 );
  48. }
  49. VOID
  50. MsWdTimerDpc(
  51. IN PKDPC Dpc,
  52. IN PVOID DeferredContext,
  53. IN PVOID SystemArgument1,
  54. IN PVOID SystemArgument2
  55. )
  56. {
  57. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeferredContext;
  58. PIO_WORKITEM WorkItem;
  59. WorkItem = IoAllocateWorkItem( DeviceExtension->DeviceObject );
  60. if (WorkItem) {
  61. IoQueueWorkItem( WorkItem, MsWdShutdownWorker, DelayedWorkQueue, DeviceExtension );
  62. }
  63. }
  64. NTSTATUS
  65. MsWdDeviceIoctl(
  66. IN PVOID DeviceExtensionIn,
  67. IN PIRP Irp,
  68. IN PVOID FsContext,
  69. IN ULONG FunctionCode,
  70. IN PVOID InputBuffer,
  71. IN ULONG InputBufferLength,
  72. IN PVOID OutputBuffer,
  73. IN ULONG OutputBufferLength
  74. )
  75. /*++
  76. Routine Description:
  77. This function is called by the SAPORT driver so that
  78. the mini-port driver can service an IOCTL call.
  79. Arguments:
  80. DeviceExtension - A pointer to the mini-port's device extension
  81. FunctionCode - The IOCTL function code
  82. InputBuffer - Pointer to the input buffer, contains the data sent down by the I/O
  83. InputBufferLength - Length in bytes of the InputBuffer
  84. OutputBuffer - Pointer to the output buffer, contains the data generated by this call
  85. OutputBufferLength - Length in bytes of the OutputBuffer
  86. Context:
  87. IRQL: IRQL PASSIVE_LEVEL, arbitrary thread context
  88. Return Value:
  89. If the function succeeds, it must return STATUS_SUCCESS.
  90. Otherwise, it must return one of the error status values defined in ntstatus.h.
  91. --*/
  92. {
  93. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtensionIn;
  94. NTSTATUS Status = STATUS_SUCCESS;
  95. PSA_WD_CAPS WdCaps = NULL;
  96. LARGE_INTEGER CurrentTime;
  97. switch (FunctionCode) {
  98. case FUNC_SA_GET_VERSION:
  99. *((PULONG)OutputBuffer) = SA_INTERFACE_VERSION;
  100. break;
  101. case FUNC_SA_GET_CAPABILITIES:
  102. WdCaps = (PSA_WD_CAPS)OutputBuffer;
  103. WdCaps->SizeOfStruct = sizeof(SA_WD_CAPS);
  104. WdCaps->Minimum = 1;
  105. WdCaps->Maximum = 512;
  106. break;
  107. case FUNC_SAWD_DISABLE:
  108. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  109. if (*((PULONG)InputBuffer) == 1) {
  110. DeviceExtension->Enabled = 1;
  111. MsWdTimerReset( DeviceExtension );
  112. } else if (*((PULONG)InputBuffer) == 0) {
  113. DeviceExtension->Enabled = 0;
  114. KeCancelTimer( &DeviceExtension->Timer );
  115. } else {
  116. Status = STATUS_INVALID_PARAMETER_1;
  117. }
  118. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  119. break;
  120. case FUNC_SAWD_QUERY_EXPIRE_BEHAVIOR:
  121. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  122. *((PULONG)OutputBuffer) = DeviceExtension->ExpireBehavior;
  123. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  124. break;
  125. case FUNC_SAWD_SET_EXPIRE_BEHAVIOR:
  126. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  127. if (*((PULONG)InputBuffer) == 1) {
  128. DeviceExtension->ExpireBehavior = 1;
  129. } else {
  130. DeviceExtension->ExpireBehavior = 0;
  131. }
  132. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  133. break;
  134. case FUNC_SAWD_PING:
  135. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  136. MsWdTimerReset( DeviceExtension );
  137. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  138. break;
  139. case FUNC_SAWD_QUERY_TIMER:
  140. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  141. KeQuerySystemTime( &CurrentTime );
  142. CurrentTime.QuadPart = DeviceExtension->TimeoutValue.QuadPart - (CurrentTime.QuadPart - DeviceExtension->StartTime.QuadPart);
  143. *((PULONG)OutputBuffer) = (ULONG)NanoToSec( CurrentTime.QuadPart );
  144. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  145. break;
  146. case FUNC_SAWD_SET_TIMER:
  147. ExAcquireFastMutex( &DeviceExtension->WdIoLock );
  148. DeviceExtension->TimeoutValue.QuadPart = (ULONGLONG)-SecToNano( *((PLONG)InputBuffer) );
  149. MsWdTimerReset( DeviceExtension );
  150. ExReleaseFastMutex( &DeviceExtension->WdIoLock );
  151. break;
  152. default:
  153. Status = STATUS_NOT_SUPPORTED;
  154. REPORT_ERROR( SA_DEVICE_WATCHDOG, "Unsupported device control", Status );
  155. break;
  156. }
  157. return Status;
  158. }
  159. NTSTATUS
  160. MsWdHwInitialize(
  161. IN PDEVICE_OBJECT DeviceObject,
  162. IN PIRP Irp,
  163. IN PVOID DeviceExtensionIn,
  164. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResources,
  165. IN ULONG PartialResourceCount
  166. )
  167. /*++
  168. Routine Description:
  169. This function is called by the SAPORT driver so that
  170. the mini-port driver can initialize it's hardware
  171. resources.
  172. Arguments:
  173. DeviceObject - Pointer to the target device object.
  174. Irp - Pointer to an IRP structure that describes the requested I/O operation.
  175. DeviceExtension - A pointer to the mini-port's device extension.
  176. PartialResources - Pointer to the translated resources alloacted by the system.
  177. PartialResourceCount - The number of resources in the PartialResources array.
  178. Context:
  179. IRQL: IRQL PASSIVE_LEVEL, system thread context
  180. Return Value:
  181. If the function succeeds, it must return STATUS_SUCCESS.
  182. Otherwise, it must return one of the error status values defined in ntstatus.h.
  183. --*/
  184. {
  185. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) DeviceExtensionIn;
  186. DeviceExtension->DeviceObject = DeviceObject;
  187. ExInitializeFastMutex( &DeviceExtension->WdIoLock );
  188. KeInitializeTimer( &DeviceExtension->Timer );
  189. KeInitializeDpc( &DeviceExtension->TimerDpc, MsWdTimerDpc, DeviceExtension );
  190. DeviceExtension->TimeoutValue.QuadPart = -SecToNano(DEFAULT_WD_TIMEOUT_SECS);
  191. DeviceExtension->Enabled = 1;
  192. DeviceExtension->ExpireBehavior = 0;
  193. MsWdTimerReset( DeviceExtension );
  194. return STATUS_SUCCESS;
  195. }
  196. NTSTATUS
  197. DriverEntry(
  198. IN PDRIVER_OBJECT DriverObject,
  199. IN PUNICODE_STRING RegistryPath
  200. )
  201. /*++
  202. Routine Description:
  203. This routine is the driver's entry point, called by the I/O system
  204. to load the driver. The driver's entry points are initialized and
  205. a mutex to control paging is initialized.
  206. In DBG mode, this routine also examines the registry for special
  207. debug parameters.
  208. Arguments:
  209. DriverObject - a pointer to the object that represents this device driver.
  210. RegistryPath - a pointer to this driver's key in the Services tree.
  211. Return Value:
  212. STATUS_SUCCESS
  213. --*/
  214. {
  215. NTSTATUS Status;
  216. SAPORT_INITIALIZATION_DATA SaPortInitData;
  217. RtlZeroMemory( &SaPortInitData, sizeof(SAPORT_INITIALIZATION_DATA) );
  218. SaPortInitData.StructSize = sizeof(SAPORT_INITIALIZATION_DATA);
  219. SaPortInitData.DeviceType = SA_DEVICE_WATCHDOG;
  220. SaPortInitData.HwInitialize = MsWdHwInitialize;
  221. SaPortInitData.DeviceIoctl = MsWdDeviceIoctl;
  222. SaPortInitData.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
  223. Status = SaPortInitialize( DriverObject, RegistryPath, &SaPortInitData );
  224. if (!NT_SUCCESS(Status)) {
  225. REPORT_ERROR( SA_DEVICE_WATCHDOG, "SaPortInitialize failed\n", Status );
  226. return Status;
  227. }
  228. return STATUS_SUCCESS;
  229. }