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.

333 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains the dispatch routines for AFD.
  7. Author:
  8. David Treadwell (davidtr) 21-Feb-1992
  9. Revision History:
  10. --*/
  11. #include "afdp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text( PAGEAFD, AfdDispatch )
  14. #pragma alloc_text( PAGEAFD, AfdDispatchDeviceControl )
  15. #endif
  16. NTSTATUS
  17. AfdDispatch (
  18. IN PDEVICE_OBJECT DeviceObject,
  19. IN PIRP Irp
  20. )
  21. /*++
  22. Routine Description:
  23. This is the dispatch routine for AFD.
  24. Arguments:
  25. DeviceObject - Pointer to device object for target device
  26. Irp - Pointer to I/O request packet
  27. Return Value:
  28. NTSTATUS -- Indicates whether the request was successfully queued.
  29. --*/
  30. {
  31. PIO_STACK_LOCATION irpSp;
  32. NTSTATUS status;
  33. #if DBG
  34. KIRQL currentIrql;
  35. currentIrql = KeGetCurrentIrql( );
  36. #endif
  37. irpSp = IoGetCurrentIrpStackLocation( Irp );
  38. switch ( irpSp->MajorFunction ) {
  39. case IRP_MJ_WRITE:
  40. //
  41. // Make the IRP look like a send IRP.
  42. //
  43. ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Write.Length ) ==
  44. FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.OutputBufferLength ) );
  45. ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Write.Key ) ==
  46. FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.InputBufferLength ) );
  47. irpSp->Parameters.Write.Key = 0;
  48. if (IS_SAN_ENDPOINT ((PAFD_ENDPOINT)irpSp->FileObject->FsContext)) {
  49. status = AfdSanRedirectRequest (Irp, irpSp);
  50. }
  51. else {
  52. status = AfdSend( Irp, irpSp );
  53. }
  54. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  55. return status;
  56. case IRP_MJ_READ:
  57. //
  58. // Make the IRP look like a receive IRP.
  59. //
  60. ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Read.Length ) ==
  61. FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.OutputBufferLength ) );
  62. ASSERT( FIELD_OFFSET( IO_STACK_LOCATION, Parameters.Read.Key ) ==
  63. FIELD_OFFSET( IO_STACK_LOCATION, Parameters.DeviceIoControl.InputBufferLength ) );
  64. irpSp->Parameters.Read.Key = 0;
  65. if (IS_SAN_ENDPOINT ((PAFD_ENDPOINT)irpSp->FileObject->FsContext)) {
  66. status = AfdSanRedirectRequest (Irp, irpSp);
  67. }
  68. else {
  69. status = AfdReceive( Irp, irpSp );
  70. }
  71. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  72. return status;
  73. case IRP_MJ_CREATE:
  74. status = AfdCreate( Irp, irpSp );
  75. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  76. Irp->IoStatus.Status = status;
  77. IoCompleteRequest( Irp, AfdPriorityBoost );
  78. return status;
  79. case IRP_MJ_CLEANUP:
  80. status = AfdCleanup( Irp, irpSp );
  81. Irp->IoStatus.Status = status;
  82. IoCompleteRequest( Irp, AfdPriorityBoost );
  83. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  84. return status;
  85. case IRP_MJ_CLOSE:
  86. status = AfdClose( Irp, irpSp );
  87. Irp->IoStatus.Status = status;
  88. IoCompleteRequest( Irp, AfdPriorityBoost );
  89. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  90. return status;
  91. case IRP_MJ_PNP:
  92. status = AfdPnpPower (Irp, irpSp );
  93. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  94. return status;
  95. case IRP_MJ_DEVICE_CONTROL:
  96. return AfdDispatchDeviceControl( DeviceObject, Irp );
  97. //
  98. // SAN support.
  99. // Return special error code to let IO manager use default security.
  100. // (needed to support ObOpenObjectByPointer).
  101. //
  102. case IRP_MJ_QUERY_SECURITY:
  103. case IRP_MJ_SET_SECURITY:
  104. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  105. IoCompleteRequest( Irp, AfdPriorityBoost );
  106. return STATUS_INVALID_DEVICE_REQUEST;
  107. default:
  108. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_INFO_LEVEL,
  109. "AfdDispatch: Invalid major function %lx\n",
  110. irpSp->MajorFunction ));
  111. Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
  112. IoCompleteRequest( Irp, AfdPriorityBoost );
  113. return STATUS_NOT_IMPLEMENTED;
  114. }
  115. } // AfdDispatch
  116. NTSTATUS
  117. AfdDispatchDeviceControl (
  118. IN PDEVICE_OBJECT DeviceObject,
  119. IN PIRP Irp
  120. )
  121. /*++
  122. Routine Description:
  123. This is the dispatch routine for AFD IOCTLs.
  124. Arguments:
  125. DeviceObject - Pointer to device object for target device
  126. Irp - Pointer to I/O request packet
  127. Return Value:
  128. NTSTATUS -- Indicates whether the request was successfully queued.
  129. --*/
  130. {
  131. ULONG code;
  132. ULONG request;
  133. NTSTATUS status;
  134. PAFD_IRP_CALL irpProc;
  135. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation (Irp);
  136. #if DBG
  137. KIRQL currentIrql;
  138. currentIrql = KeGetCurrentIrql( );
  139. #endif
  140. UNREFERENCED_PARAMETER (DeviceObject);
  141. //
  142. // Extract the IOCTL control code and process the request.
  143. //
  144. code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
  145. request = _AFD_REQUEST(code);
  146. if( request < AFD_NUM_IOCTLS && AfdIoctlTable[request] == code ) {
  147. //
  148. // Helps in debugging.
  149. //
  150. IrpSp->MinorFunction = (UCHAR)request;
  151. //
  152. // Try IRP dispatch first
  153. //
  154. irpProc = AfdIrpCallDispatch[request];
  155. if (irpProc!=NULL) {
  156. status = (*irpProc)(Irp, IrpSp);
  157. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  158. return status;
  159. }
  160. }
  161. //
  162. // This is currently not used by helper dlls.
  163. // Commented out because of security concerns
  164. //
  165. #if 0
  166. else if (request==AFD_TRANSPORT_IOCTL) {
  167. //
  168. // This is a "special" used to pass request
  169. // to transport driver using socket handle in
  170. // order to facilitate proper completion
  171. // on sockets associated with completion port.
  172. // It accepts and properly handles all methods.
  173. //
  174. status = AfdDoTransportIoctl (Irp, IrpSp);
  175. ASSERT( KeGetCurrentIrql() == currentIrql );
  176. return status;
  177. }
  178. #endif
  179. //
  180. // If we made it this far, then the ioctl is invalid.
  181. //
  182. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_WARNING_LEVEL,
  183. "AfdDispatchDeviceControl: invalid IOCTL %08lX\n",
  184. code
  185. ));
  186. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  187. IoCompleteRequest( Irp, AfdPriorityBoost );
  188. return STATUS_INVALID_DEVICE_REQUEST;
  189. } // AfdDispatchDeviceControl
  190. NTSTATUS
  191. FASTCALL
  192. AfdDispatchImmediateIrp(
  193. IN PIRP Irp,
  194. IN PIO_STACK_LOCATION IrpSp
  195. )
  196. {
  197. PAFD_IMMEDIATE_CALL immProc;
  198. ULONG code;
  199. ULONG request;
  200. NTSTATUS status;
  201. #if DBG
  202. KIRQL currentIrql;
  203. currentIrql = KeGetCurrentIrql( );
  204. #endif
  205. code = IrpSp->Parameters.DeviceIoControl.IoControlCode;
  206. request = _AFD_REQUEST(code);
  207. immProc = AfdImmediateCallDispatch[request];
  208. if (immProc!=NULL) {
  209. //
  210. // Must be METHOD_NEITHER for the below code to be
  211. // valid.
  212. //
  213. ASSERT ( (code & 3) == METHOD_NEITHER );
  214. #if DBG
  215. if (Irp->RequestorMode!=KernelMode) {
  216. KdPrintEx(( DPFLTR_WSOCKTRANSPORT_ID, DPFLTR_WARNING_LEVEL,
  217. "AfdDispatchDeviceControl: "
  218. "User mode application somehow bypassed fast io dispatch\n"));
  219. }
  220. #endif
  221. status = (*immProc) (
  222. IrpSp->FileObject,
  223. code,
  224. Irp->RequestorMode,
  225. IrpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  226. IrpSp->Parameters.DeviceIoControl.InputBufferLength,
  227. Irp->UserBuffer,
  228. IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  229. &Irp->IoStatus.Information
  230. );
  231. ASSERT( KeGetCurrentIrql( ) == currentIrql );
  232. }
  233. else {
  234. ASSERT (!"Missing IOCTL in dispatch table!!!");
  235. status = STATUS_INVALID_DEVICE_REQUEST;
  236. }
  237. Irp->IoStatus.Status = status;
  238. IoCompleteRequest( Irp, AfdPriorityBoost );
  239. return status;
  240. }