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
18 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains the dispatch routines for
  7. ws2ifsl.sys driver
  8. Author:
  9. Vadim Eydelman (VadimE) Dec-1996
  10. Revision History:
  11. Vadim Eydelman (VadimE) Oct-1997, rewrite to properly handle IRP
  12. cancellation
  13. --*/
  14. #include "precomp.h"
  15. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text (PAGE, DispatchCreate)
  17. #pragma alloc_text (PAGE, DispatchCleanup)
  18. #pragma alloc_text (PAGE, DispatchClose)
  19. #pragma alloc_text (PAGE, DispatchReadWrite)
  20. #pragma alloc_text (PAGE, DispatchDeviceControl)
  21. #pragma alloc_text (PAGE, FastIoDeviceControl)
  22. #endif
  23. NTSTATUS
  24. DispatchCreate (
  25. IN PDEVICE_OBJECT DeviceObject,
  26. IN PIRP Irp
  27. )
  28. /*++
  29. Routine Description:
  30. This routine is called as the result of a request to create
  31. a file associated with WS2IFSL driver device object.
  32. Arguments:
  33. DeviceObject - WS2IFSL device object
  34. Irp - create Irp
  35. Return Value:
  36. STATUS_SUCCESS - requested file object can be created
  37. STATUS_INVALID_PARAMETER - required extened attribute is missing
  38. or invalid
  39. STATUS_INSUFFICIENT_RESOURCES - not enough resources to complete
  40. this request
  41. --*/
  42. {
  43. NTSTATUS status;
  44. PIO_STACK_LOCATION irpSp;
  45. PFILE_FULL_EA_INFORMATION eaBuffer;
  46. PAGED_CODE ();
  47. // Get extended attribute buffer which identifies the
  48. // type of file that should be created.
  49. eaBuffer = Irp->AssociatedIrp.SystemBuffer;
  50. if (eaBuffer!=NULL) {
  51. irpSp = IoGetCurrentIrpStackLocation (Irp);
  52. if ((eaBuffer->EaNameLength==WS2IFSL_SOCKET_EA_NAME_LENGTH)
  53. && (strcmp (eaBuffer->EaName, WS2IFSL_SOCKET_EA_NAME)==0)) {
  54. // This is the request to create socket file
  55. status = CreateSocketFile (irpSp->FileObject,
  56. Irp->RequestorMode,
  57. eaBuffer);
  58. }
  59. else if ((eaBuffer->EaNameLength==WS2IFSL_PROCESS_EA_NAME_LENGTH)
  60. && (strcmp (eaBuffer->EaName, WS2IFSL_PROCESS_EA_NAME)==0)) {
  61. // This is the request to create process file
  62. status = CreateProcessFile (irpSp->FileObject,
  63. Irp->RequestorMode,
  64. eaBuffer);
  65. }
  66. else
  67. status = STATUS_INVALID_PARAMETER;
  68. }
  69. else
  70. status = STATUS_INVALID_PARAMETER;
  71. Irp->IoStatus.Status = status;
  72. Irp->IoStatus.Information = 0;
  73. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  74. return status;
  75. } // DispatchCreate
  76. NTSTATUS
  77. DispatchCleanup (
  78. IN PDEVICE_OBJECT DeviceObject,
  79. IN PIRP Irp
  80. )
  81. /*++
  82. Routine Description:
  83. This routine is called when all handles to a file associated with WS2IFSL
  84. driver device object are closed, so the driver should cleanup all the
  85. outstanding IRPs.
  86. Arguments:
  87. DeviceObject - WS2IFSL device object
  88. Irp - cleanup Irp
  89. Return Value:
  90. STATUS_SUCCESS - cleanup operation completed
  91. STATUS_PENDING - cleanup operation started and IoCompleteRequest will be
  92. called when it is done
  93. --*/
  94. {
  95. NTSTATUS status;
  96. PIO_STACK_LOCATION irpSp;
  97. ULONG eaNameTag;
  98. PAGED_CODE ();
  99. // Get the file type from file object context
  100. irpSp = IoGetCurrentIrpStackLocation (Irp);
  101. eaNameTag = *((PULONG)irpSp->FileObject->FsContext);
  102. // Call appropriate routine based on file type
  103. switch (eaNameTag) {
  104. case SOCKET_FILE_EANAME_TAG:
  105. status = CleanupSocketFile (irpSp->FileObject, Irp);
  106. break;
  107. case PROCESS_FILE_EANAME_TAG:
  108. status = CleanupProcessFile (irpSp->FileObject, Irp);
  109. break;
  110. default:
  111. ASSERTMSG ("Unknown file EA name tag", FALSE);
  112. status = STATUS_INVALID_HANDLE;
  113. break;
  114. }
  115. // Complete the request if it was not marked pending
  116. if (status!=STATUS_PENDING) {
  117. Irp->IoStatus.Status = status;
  118. Irp->IoStatus.Information = 0;
  119. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  120. }
  121. return status;
  122. } // DispatchCleanup
  123. NTSTATUS
  124. DispatchClose (
  125. IN PDEVICE_OBJECT DeviceObject,
  126. IN PIRP Irp
  127. )
  128. /*++
  129. Routine Description:
  130. This routine is called when all references to a file associated with WS2IFSL
  131. driver device object are released and IO system is about to delete the
  132. file object itself
  133. Arguments:
  134. DeviceObject - WS2IFSL device object
  135. Irp - close Irp
  136. Return Value:
  137. STATUS_SUCCESS - close operation completed
  138. --*/
  139. {
  140. NTSTATUS status;
  141. PIO_STACK_LOCATION irpSp;
  142. ULONG eaNameTag;
  143. PAGED_CODE ();
  144. // Get the file type from file object context
  145. irpSp = IoGetCurrentIrpStackLocation (Irp);
  146. eaNameTag = *((PULONG)irpSp->FileObject->FsContext);
  147. // Call appropriate routine based on file type
  148. switch (eaNameTag) {
  149. case SOCKET_FILE_EANAME_TAG:
  150. CloseSocketFile (irpSp->FileObject);
  151. status = STATUS_SUCCESS;
  152. break;
  153. case PROCESS_FILE_EANAME_TAG:
  154. CloseProcessFile (irpSp->FileObject);
  155. status = STATUS_SUCCESS;
  156. break;
  157. default:
  158. ASSERTMSG ("Unknown file EA name tag", FALSE);
  159. status = STATUS_INVALID_HANDLE;
  160. break;
  161. }
  162. // Complete the request
  163. Irp->IoStatus.Status = status;
  164. Irp->IoStatus.Information = 0;
  165. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  166. return status;
  167. } // DispatchClose
  168. NTSTATUS
  169. DispatchReadWrite (
  170. IN PDEVICE_OBJECT DeviceObject,
  171. IN PIRP Irp
  172. )
  173. /*++
  174. Routine Description:
  175. This routine is called to perform read or write operation on file object.
  176. It is only supported for socket files.
  177. Arguments:
  178. DeviceObject - WS2IFSL device object
  179. Irp - read/write Irp
  180. Return Value:
  181. STATUS_PENDING - operation is passed onto WS2IFSL DLL to execute
  182. STATUS_CANCELED - operation canceled because WS2IFSL DLL has been unloaded
  183. STATUS_INVALID_DEVICE_REQUEST - the operation cannot be performed on
  184. this file object.
  185. STATUS_INVALID_HANDLE - file object is not valid in the context of
  186. current process
  187. --*/
  188. {
  189. NTSTATUS status;
  190. PIO_STACK_LOCATION irpSp;
  191. ULONG eaNameTag;
  192. PAGED_CODE ();
  193. // Get the file type from file object context
  194. irpSp = IoGetCurrentIrpStackLocation (Irp);
  195. eaNameTag = *((PULONG)irpSp->FileObject->FsContext);
  196. // Call appropriate routine based on file type
  197. switch (eaNameTag) {
  198. case SOCKET_FILE_EANAME_TAG:
  199. status = DoSocketReadWrite (irpSp->FileObject, Irp);
  200. break;
  201. default:
  202. ASSERTMSG ("Unknown file EA name tag", FALSE);
  203. case PROCESS_FILE_EANAME_TAG:
  204. // This operation is not valid for process files
  205. status = STATUS_INVALID_DEVICE_REQUEST;
  206. break;
  207. }
  208. // Complete the request if it was not marked pending
  209. if (status!=STATUS_PENDING) {
  210. Irp->IoStatus.Status = status;
  211. Irp->IoStatus.Information = 0;
  212. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  213. }
  214. return status;
  215. } // DispatchReadWrite
  216. NTSTATUS
  217. DispatchDeviceControl (
  218. IN PDEVICE_OBJECT DeviceObject,
  219. IN PIRP Irp
  220. )
  221. /*++
  222. Routine Description:
  223. This routine is called to perform device control operation on file object.
  224. Arguments:
  225. DeviceObject - WS2IFSL device object
  226. Irp - device control Irp
  227. Return Value:
  228. STATUS_SUCCESS - device control operation completed
  229. STATUS_PENDING - operation is in progress
  230. STATUS_INVALID_DEVICE_REQUEST - the operation cannot be performed on
  231. this file object.
  232. STATUS_INVALID_HANDLE - file object is not valid in the context of
  233. current process
  234. --*/
  235. {
  236. NTSTATUS status;
  237. PIO_STACK_LOCATION irpSp;
  238. ULONG eaNameTag;
  239. ULONG function;
  240. PAGED_CODE ();
  241. // Get the file type from file object context
  242. irpSp = IoGetCurrentIrpStackLocation (Irp);
  243. eaNameTag = *((PULONG)irpSp->FileObject->FsContext);
  244. // Call appropriate routine based on file type
  245. switch (eaNameTag) {
  246. case SOCKET_FILE_EANAME_TAG:
  247. function = WS2IFSL_IOCTL_FUNCTION(SOCKET,irpSp->Parameters.DeviceIoControl.IoControlCode);
  248. if ((function<sizeof(SocketIoControlMap)/sizeof(SocketIoControlMap[0])) &&
  249. (SocketIoctlCodeMap[function]==irpSp->Parameters.DeviceIoControl.IoControlCode)) {
  250. // Use table dispatch to call appropriate internal IOCTL routine
  251. ASSERTMSG ("Socket file device control requests should have been handled"
  252. " by FastIo path ", FALSE);
  253. SocketIoControlMap[function] (
  254. irpSp->FileObject,
  255. Irp->RequestorMode,
  256. irpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  257. irpSp->Parameters.DeviceIoControl.InputBufferLength,
  258. Irp->UserBuffer,
  259. irpSp->Parameters.DeviceIoControl.OutputBufferLength,
  260. &Irp->IoStatus);
  261. status = Irp->IoStatus.Status;
  262. }
  263. else if ((irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_SEND_DATAGRAM)
  264. || (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE_DATAGRAM)
  265. || (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE))
  266. // Handle some "popular" afd IOCTLs
  267. status = DoSocketAfdIoctl (irpSp->FileObject, Irp);
  268. else {
  269. WsPrint (DBG_FAILURES,
  270. ("WS2IFSL-%04lx DispatchDeviceControl: Unsupported IOCTL - %lx!!!\n",
  271. PsGetCurrentProcessId(),
  272. irpSp->Parameters.DeviceIoControl.IoControlCode
  273. ));
  274. status = STATUS_INVALID_DEVICE_REQUEST;
  275. }
  276. break;
  277. case PROCESS_FILE_EANAME_TAG:
  278. function = WS2IFSL_IOCTL_FUNCTION(PROCESS,irpSp->Parameters.DeviceIoControl.IoControlCode);
  279. if ((function<sizeof(ProcessIoControlMap)/sizeof(ProcessIoControlMap[0])) &&
  280. (ProcessIoctlCodeMap[function]==irpSp->Parameters.DeviceIoControl.IoControlCode)) {
  281. // Use table dispatch to call appropriate internal IOCTL routine
  282. ASSERTMSG ("Process file device control requests should have been handled"
  283. " by FastIo path ", FALSE);
  284. ProcessIoControlMap[function] (
  285. irpSp->FileObject,
  286. Irp->RequestorMode,
  287. irpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  288. irpSp->Parameters.DeviceIoControl.InputBufferLength,
  289. Irp->UserBuffer,
  290. irpSp->Parameters.DeviceIoControl.OutputBufferLength,
  291. &Irp->IoStatus);
  292. status = Irp->IoStatus.Status;
  293. }
  294. else {
  295. WsPrint (DBG_FAILURES,
  296. ("WS2IFSL-%04lx DispatchDeviceControl: Unsupported IOCTL - %lx!!!\n",
  297. PsGetCurrentProcessId(),
  298. irpSp->Parameters.DeviceIoControl.IoControlCode
  299. ));
  300. status = STATUS_INVALID_DEVICE_REQUEST;
  301. }
  302. break;
  303. default:
  304. ASSERTMSG ("Unknown file EA name tag", FALSE);
  305. status = STATUS_INVALID_DEVICE_REQUEST;
  306. break;
  307. }
  308. // Complete the request if it was not marked pending
  309. if (status!=STATUS_PENDING) {
  310. Irp->IoStatus.Status = status;
  311. Irp->IoStatus.Information = 0;
  312. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  313. }
  314. return status;
  315. } // DispatchDeviceControl
  316. BOOLEAN
  317. FastIoDeviceControl (
  318. IN PFILE_OBJECT FileObject,
  319. IN BOOLEAN Wait,
  320. IN PVOID InputBuffer OPTIONAL,
  321. IN ULONG InputBufferLength,
  322. OUT PVOID OutputBuffer OPTIONAL,
  323. IN ULONG OutputBufferLength,
  324. IN ULONG IoControlCode,
  325. OUT PIO_STATUS_BLOCK IoStatus,
  326. IN PDEVICE_OBJECT DeviceObject
  327. )
  328. /*++
  329. Routine Description:
  330. This routine is called to perform device control operation on file object.
  331. This is IO system fast path that assumes immediate action
  332. Arguments:
  333. FileObject - file object to which request is directed;
  334. Wait - ??? (always TRUE);
  335. InputBuffer - address of the input buffer;
  336. InputBufferLength - size of the input buffer;
  337. OutputBuffer - address of the output buffer;
  338. OutputBufferLength - size of the output buffer;
  339. IoControlCode - code of the operation to be performed;
  340. IoStatus - status of the operation returned by the driver:
  341. DeviceObject - WS2IFSL device object
  342. Return Value:
  343. TRUE - operation completed,
  344. FALSE - operation should be preformed using Irps
  345. --*/
  346. {
  347. BOOLEAN done = FALSE;
  348. ULONG eaNameTag;
  349. ULONG function;
  350. PAGED_CODE ();
  351. // Get the file type from file object context
  352. eaNameTag = *((PULONG)FileObject->FsContext);
  353. // Call appropriate routine based on file type
  354. switch (eaNameTag) {
  355. case SOCKET_FILE_EANAME_TAG:
  356. function = WS2IFSL_IOCTL_FUNCTION(SOCKET,IoControlCode);
  357. if ((function<sizeof(SocketIoControlMap)/sizeof(SocketIoControlMap[0])) &&
  358. (SocketIoctlCodeMap[function]==IoControlCode)) {
  359. IO_STATUS_BLOCK IoStatusTemp;
  360. // Use table dispatch to call appropriate internal IOCTL routine
  361. SocketIoControlMap[function] (
  362. FileObject,
  363. ExGetPreviousMode(),
  364. InputBuffer,
  365. InputBufferLength,
  366. OutputBuffer,
  367. OutputBufferLength,
  368. &IoStatusTemp);
  369. if (NT_SUCCESS(IoStatusTemp.Status))
  370. {
  371. done = TRUE;
  372. memcpy(IoStatus, &IoStatusTemp, sizeof(IoStatusTemp));
  373. }
  374. }
  375. else if ((IoControlCode==IOCTL_AFD_SEND_DATAGRAM)
  376. || (IoControlCode==IOCTL_AFD_RECEIVE_DATAGRAM)
  377. || (IoControlCode==IOCTL_AFD_RECEIVE))
  378. // AFD ioctls can only be handled on "slow" io path (need IRP)
  379. NOTHING;
  380. else {
  381. WsPrint (DBG_FAILURES,
  382. ("WS2IFSL-%04lx FastIoDeviceControl: Unsupported IOCTL - %lx!!!\n",
  383. PsGetCurrentProcessId(), IoControlCode));
  384. //
  385. // Let the real dispatch deal with the error.
  386. NOTHING;
  387. }
  388. break;
  389. case PROCESS_FILE_EANAME_TAG:
  390. function = WS2IFSL_IOCTL_FUNCTION(PROCESS,IoControlCode);
  391. if ((function<sizeof(ProcessIoControlMap)/sizeof(ProcessIoControlMap[0])) &&
  392. (ProcessIoctlCodeMap[function]==IoControlCode)) {
  393. // Use table dispatch to call appropriate internal IOCTL routine
  394. IO_STATUS_BLOCK IoStatusTemp;
  395. ProcessIoControlMap[function] (
  396. FileObject,
  397. ExGetPreviousMode(),
  398. InputBuffer,
  399. InputBufferLength,
  400. OutputBuffer,
  401. OutputBufferLength,
  402. &IoStatusTemp);
  403. if (NT_SUCCESS(IoStatusTemp.Status))
  404. {
  405. done = TRUE;
  406. memcpy(IoStatus, &IoStatusTemp, sizeof(IoStatusTemp));
  407. }
  408. }
  409. else {
  410. WsPrint (DBG_FAILURES,
  411. ("WS2IFSL-%04lx FastIoDeviceControl: Unsupported IOCTL - %lx!!!\n",
  412. PsGetCurrentProcessId(),IoControlCode));
  413. //
  414. // Let the real dispatch deal with the error.
  415. NOTHING;
  416. }
  417. break;
  418. default:
  419. ASSERTMSG ("Unknown file EA name tag", FALSE);
  420. //
  421. // Let the real dispatch deal with the error.
  422. NOTHING;
  423. break;
  424. }
  425. return done;
  426. } // FastIoDeviceControl
  427. NTSTATUS
  428. DispatchPnP (
  429. IN PDEVICE_OBJECT DeviceObject,
  430. IN PIRP Irp
  431. )
  432. /*++
  433. Routine Description:
  434. This routine is called to perform PnP control operation on file object.
  435. Arguments:
  436. DeviceObject - WS2IFSL device object
  437. Irp - PnP Irp
  438. Return Value:
  439. STATUS_SUCCESS - device control operation completed
  440. STATUS_PENDING - operation is in progress
  441. STATUS_INVALID_DEVICE_REQUEST - the operation cannot be performed on
  442. this file object.
  443. --*/
  444. {
  445. NTSTATUS status;
  446. PIO_STACK_LOCATION irpSp;
  447. ULONG eaNameTag;
  448. PAGED_CODE ();
  449. // Get the file type from file object context
  450. irpSp = IoGetCurrentIrpStackLocation (Irp);
  451. eaNameTag = *((PULONG)irpSp->FileObject->FsContext);
  452. // Call appropriate routine based on file type
  453. switch (eaNameTag) {
  454. case SOCKET_FILE_EANAME_TAG:
  455. switch (irpSp->MinorFunction) {
  456. case IRP_MN_QUERY_DEVICE_RELATIONS:
  457. status = SocketPnPTargetQuery (irpSp->FileObject, Irp);
  458. break;
  459. default:
  460. status = STATUS_INVALID_DEVICE_REQUEST;
  461. break;
  462. }
  463. break;
  464. default:
  465. ASSERTMSG ("Unknown file EA name tag", FALSE);
  466. case PROCESS_FILE_EANAME_TAG:
  467. status = STATUS_INVALID_DEVICE_REQUEST;
  468. break;
  469. }
  470. // Complete the request if it was not marked pending
  471. if (status!=STATUS_PENDING) {
  472. Irp->IoStatus.Status = status;
  473. Irp->IoStatus.Information = 0;
  474. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  475. }
  476. return status;
  477. }