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.

386 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. misc.c
  5. Abstract:
  6. This module contains the miscellaneous SPUD routines.
  7. Author:
  8. John Ballard (jballard) 21-Oct-1996
  9. Revision History:
  10. Keith Moore (keithmo) 04-Feb-1998
  11. Cleanup, added much needed comments.
  12. --*/
  13. #include "spudp.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text( PAGE, SpudEnterService )
  16. #pragma alloc_text( PAGE, SpudLeaveService )
  17. #pragma alloc_text( PAGE, SpudGetAfdDeviceObject )
  18. #endif
  19. #if 0
  20. NOT PAGEABLE -- SpudAssert
  21. NOT PAGEABLE -- SpudReferenceCompletionPort
  22. NOT PAGEABLE -- SpudDereferenceCompletionPort
  23. #endif
  24. //
  25. // Public funcitons.
  26. //
  27. NTSTATUS
  28. SpudEnterService(
  29. #if DBG
  30. IN PSTR ServiceName,
  31. #endif
  32. IN BOOLEAN InitRequired
  33. )
  34. /*++
  35. Routine Description:
  36. Common service entry prologue. This routine ensures that all necessary
  37. initialization required by the service has been performed.
  38. Arguments:
  39. ServiceName - Name of the service being invoked (DBG only).
  40. InitRequired - If TRUE, then the driver must have already been fully
  41. initialized. This parameter is TRUE for all services *except*
  42. SPUDInitialize().
  43. Return Value:
  44. NTSTATUS - Completion status
  45. --*/
  46. {
  47. //
  48. // Sanity check.
  49. //
  50. PAGED_CODE();
  51. #if DBG
  52. UNREFERENCED_PARAMETER( ServiceName );
  53. #endif
  54. //
  55. // If InitRequired is TRUE, then the current process must match the
  56. // one that owns our driver.
  57. //
  58. if( InitRequired &&
  59. ( SpudOwningProcess != PsGetCurrentProcess() ) ) {
  60. return STATUS_INVALID_DEVICE_REQUEST;
  61. }
  62. //
  63. // If InitRequired is FALSE, then there must be no owning process.
  64. //
  65. if( !InitRequired &&
  66. ( SpudOwningProcess != NULL ) ) {
  67. return STATUS_INVALID_DEVICE_REQUEST;
  68. }
  69. //
  70. // Looks good.
  71. //
  72. return STATUS_SUCCESS;
  73. } // SpudEnterService
  74. VOID
  75. SpudLeaveService(
  76. #if DBG
  77. IN PSTR ServiceName,
  78. IN NTSTATUS Status,
  79. #endif
  80. IN BOOLEAN DerefRequired
  81. )
  82. /*++
  83. Routine Description:
  84. Common service exit routine.
  85. Arguments:
  86. ServiceName - Name of the service being invoked (DBG only).
  87. Status - Service completion status (DBG only).
  88. DerefRequired - TRUE if the completion port should be dereferenced
  89. before returning.
  90. Return Value:
  91. None.
  92. --*/
  93. {
  94. //
  95. // Sanity check.
  96. //
  97. PAGED_CODE();
  98. #if DBG
  99. UNREFERENCED_PARAMETER( ServiceName );
  100. UNREFERENCED_PARAMETER( Status );
  101. #endif
  102. if( DerefRequired ) {
  103. SpudDereferenceCompletionPort();
  104. }
  105. } // SpudLeaveService
  106. NTSTATUS
  107. SpudGetAfdDeviceObject(
  108. IN PFILE_OBJECT AfdFileObject
  109. )
  110. /*++
  111. Routine Description:
  112. Retreives AFD's device object & fast IO dispatch table from a
  113. socket's file object.
  114. Arguments:
  115. AfdFileObject - The FILE_OBJECT for an open socket.
  116. Return Value:
  117. NTSTATUS - Completion status.
  118. --*/
  119. {
  120. //
  121. // Sanity check.
  122. //
  123. PAGED_CODE();
  124. //
  125. // Chase down the device object associated with the file object, then
  126. // snag the fast I/O dispatch table.
  127. //
  128. SpudAfdDeviceObject = IoGetRelatedDeviceObject( AfdFileObject );
  129. if( !SpudAfdDeviceObject ) {
  130. return STATUS_INVALID_DEVICE_REQUEST;
  131. }
  132. SpudAfdFastIoDeviceControl =
  133. SpudAfdDeviceObject->DriverObject->FastIoDispatch->FastIoDeviceControl;
  134. if( !SpudAfdFastIoDeviceControl ) {
  135. SpudAfdDeviceObject = NULL;
  136. return STATUS_INVALID_DEVICE_REQUEST;
  137. }
  138. return STATUS_SUCCESS;
  139. } // SpudGetAfdDeviceObject
  140. #if DBG
  141. VOID
  142. SpudAssert(
  143. IN PVOID FailedAssertion,
  144. IN PVOID FileName,
  145. IN ULONG LineNumber,
  146. IN PCHAR Message OPTIONAL
  147. )
  148. /*++
  149. Routine Description:
  150. Private assertion failure handler. This is necessary to make ASSERT()s
  151. work on free builds. (RtlAssert() is a noop on free builds.)
  152. Arguments:
  153. FailedAssertion - The text of the failed assertion.
  154. FileName - The file name containing the failed assertion.
  155. LineNumber - The line number of the failed assertion.
  156. Message - An optional message to display with the assertion.
  157. Return Value:
  158. None.
  159. --*/
  160. {
  161. //
  162. // If we 're to use our private assert, then do it ourselves.
  163. // Otherwise, let RtlAssert() handle it.
  164. //
  165. if( SpudUsePrivateAssert ) {
  166. DbgPrint(
  167. "\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n",
  168. Message
  169. ? Message
  170. : "",
  171. FailedAssertion,
  172. FileName,
  173. LineNumber
  174. );
  175. DbgBreakPoint();
  176. } else {
  177. RtlAssert(
  178. FailedAssertion,
  179. FileName,
  180. LineNumber,
  181. Message
  182. );
  183. }
  184. } // SpudAssert
  185. #endif // DBG
  186. PVOID
  187. SpudReferenceCompletionPort(
  188. VOID
  189. )
  190. /*++
  191. Routine Description:
  192. Bumps our private reference on the completion port pointer.
  193. Arguments:
  194. None.
  195. Return Value:
  196. PVOID - A pointer to the completion port object if successful,
  197. NULL otherwise.
  198. --*/
  199. {
  200. PVOID port;
  201. KIRQL oldIrql;
  202. KeAcquireSpinLock(
  203. &SpudCompletionPortLock,
  204. &oldIrql
  205. );
  206. port = SpudCompletionPort;
  207. if( port != NULL ) {
  208. SpudCompletionPortRefCount++;
  209. ASSERT( SpudCompletionPortRefCount > 0 );
  210. }
  211. KeReleaseSpinLock(
  212. &SpudCompletionPortLock,
  213. oldIrql
  214. );
  215. return port;
  216. } // SpudReferenceCompletionPort
  217. VOID
  218. SpudDereferenceCompletionPort(
  219. VOID
  220. )
  221. /*++
  222. Routine Description:
  223. Removes a private reference from the completion port object.
  224. Arguments:
  225. None.
  226. Return Value:
  227. None.
  228. --*/
  229. {
  230. KIRQL oldIrql;
  231. KeAcquireSpinLock(
  232. &SpudCompletionPortLock,
  233. &oldIrql
  234. );
  235. if( SpudCompletionPort != NULL ) {
  236. ASSERT( SpudCompletionPortRefCount > 0 );
  237. SpudCompletionPortRefCount--;
  238. if( SpudCompletionPortRefCount == 0 ) {
  239. TRACE_OB_DEREFERENCE( SpudCompletionPort );
  240. ObDereferenceObject( SpudCompletionPort );
  241. SpudCompletionPort = NULL;
  242. }
  243. }
  244. KeReleaseSpinLock(
  245. &SpudCompletionPortLock,
  246. oldIrql
  247. );
  248. } // SpudDereferenceCompletionPort