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.

765 lines
26 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. process.c
  5. Abstract:
  6. This module implements process file object for ws2ifsl.sys driver.
  7. Author:
  8. Vadim Eydelman (VadimE) Dec-1996
  9. Revision History:
  10. Vadim Eydelman (VadimE) Oct-1997, rewrite to properly handle IRP
  11. cancellation
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // Internal routine prototypes
  16. //
  17. VOID
  18. RetrieveDrvRequest (
  19. IN PFILE_OBJECT ProcessFile,
  20. IN KPROCESSOR_MODE RequestorMode,
  21. IN PVOID InputBuffer,
  22. IN ULONG InputBufferLength,
  23. OUT PVOID OutputBuffer,
  24. IN ULONG OutputBufferLength,
  25. OUT PIO_STATUS_BLOCK IoStatus
  26. );
  27. VOID
  28. CompleteDrvCancel (
  29. IN PFILE_OBJECT SocketFile,
  30. IN KPROCESSOR_MODE RequestorMode,
  31. IN PVOID InputBuffer,
  32. IN ULONG InputBufferLength,
  33. OUT PVOID OutputBuffer,
  34. IN ULONG OutputBufferLength,
  35. OUT PIO_STATUS_BLOCK IoStatus
  36. );
  37. VOID
  38. CallCompleteDrvRequest (
  39. IN PFILE_OBJECT SocketFile,
  40. IN KPROCESSOR_MODE RequestorMode,
  41. IN PVOID InputBuffer,
  42. IN ULONG InputBufferLength,
  43. OUT PVOID OutputBuffer,
  44. IN ULONG OutputBufferLength,
  45. OUT PIO_STATUS_BLOCK IoStatus
  46. );
  47. #ifdef ALLOC_PRAGMA
  48. #pragma alloc_text(PAGE, CreateProcessFile)
  49. #pragma alloc_text(PAGE, CleanupProcessFile)
  50. #pragma alloc_text(PAGE, CloseProcessFile)
  51. #pragma alloc_text(PAGE, RetrieveDrvRequest)
  52. #pragma alloc_text(PAGE, CompleteDrvCancel)
  53. #pragma alloc_text(PAGE, CallCompleteDrvRequest)
  54. #endif
  55. ULONG ProcessIoctlCodeMap[3] = {
  56. #if WS2IFSL_IOCTL_FUNCTION(PROCESS,IOCTL_WS2IFSL_RETRIEVE_DRV_REQ)!=0
  57. #error Mismatch between IOCTL function code and ProcessIoControlMap
  58. #endif
  59. IOCTL_WS2IFSL_RETRIEVE_DRV_REQ,
  60. #if WS2IFSL_IOCTL_FUNCTION(PROCESS,IOCTL_WS2IFSL_COMPLETE_DRV_CAN)!=1
  61. #error Mismatch between IOCTL function code and ProcessIoControlMap
  62. #endif
  63. IOCTL_WS2IFSL_COMPLETE_DRV_CAN,
  64. #if WS2IFSL_IOCTL_FUNCTION(PROCESS,IOCTL_WS2IFSL_COMPLETE_DRV_REQ)!=2
  65. #error Mismatch between IOCTL function code and ProcessIoControlMap
  66. #endif
  67. IOCTL_WS2IFSL_COMPLETE_DRV_REQ
  68. };
  69. PPROCESS_DEVICE_CONTROL ProcessIoControlMap[3] = {
  70. RetrieveDrvRequest,
  71. CompleteDrvCancel,
  72. CallCompleteDrvRequest
  73. };
  74. NTSTATUS
  75. CreateProcessFile (
  76. IN PFILE_OBJECT ProcessFile,
  77. IN KPROCESSOR_MODE RequestorMode,
  78. IN PFILE_FULL_EA_INFORMATION eaInfo
  79. )
  80. /*++
  81. Routine Description:
  82. Allocates and initializes process file context structure
  83. Arguments:
  84. ProcessFile - socket file object
  85. eaInfo - EA for process file
  86. Return Value:
  87. STATUS_SUCCESS - operation completed OK
  88. STATUS_INSUFFICIENT_RESOURCES - not enough memory to allocate context
  89. STATUS_INVALID_PARAMETER - invalid creation parameters
  90. STATUS_INVALID_HANDLE - invalid event handle(s)
  91. STATUS_OBJECT_TYPE_MISMATCH - event handle(s) is not for event object
  92. --*/
  93. {
  94. NTSTATUS status = STATUS_SUCCESS;
  95. PIFSL_PROCESS_CTX ProcessCtx;
  96. PETHREAD apcThread;
  97. PAGED_CODE ();
  98. //
  99. // Verify the size of the input strucuture
  100. //
  101. if (eaInfo->EaValueLength!=WS2IFSL_PROCESS_EA_VALUE_LENGTH) {
  102. WsPrint (DBG_PROCESS|DBG_FAILURES,
  103. ("WS2IFSL-%04lx CreateProcessFile: Invalid ea info size (%ld)"
  104. " for process file %p.\n",
  105. PsGetCurrentProcessId(),
  106. eaInfo->EaValueLength,
  107. ProcessFile));
  108. return STATUS_INVALID_PARAMETER;
  109. }
  110. //
  111. // Reference event handles for signalling to user mode DLL
  112. //
  113. status = ObReferenceObjectByHandle(
  114. GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->ApcThread,
  115. THREAD_SET_CONTEXT, // DesiredAccess
  116. *PsThreadType,
  117. RequestorMode,
  118. (PVOID *)&apcThread,
  119. NULL
  120. );
  121. if (NT_SUCCESS (status)) {
  122. if (IoThreadToProcess (apcThread)==IoGetCurrentProcess ()) {
  123. // Allocate process context and charge it to the process
  124. try {
  125. ProcessCtx = (PIFSL_PROCESS_CTX) ExAllocatePoolWithQuotaTag (
  126. NonPagedPool,
  127. sizeof (IFSL_PROCESS_CTX),
  128. PROCESS_FILE_CONTEXT_TAG);
  129. }
  130. except (EXCEPTION_EXECUTE_HANDLER) {
  131. ProcessCtx = NULL;
  132. status = GetExceptionCode ();
  133. }
  134. if (ProcessCtx!=NULL) {
  135. // Initialize process context structure
  136. ProcessCtx->EANameTag = PROCESS_FILE_EANAME_TAG;
  137. ProcessCtx->UniqueId = PsGetCurrentProcessId();
  138. ProcessCtx->CancelId = 0;
  139. InitializeRequestQueue (ProcessCtx,
  140. (PKTHREAD)apcThread,
  141. RequestorMode,
  142. (PKNORMAL_ROUTINE)GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->RequestRoutine,
  143. GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->ApcContext);
  144. InitializeCancelQueue (ProcessCtx,
  145. (PKTHREAD)apcThread,
  146. RequestorMode,
  147. (PKNORMAL_ROUTINE)GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->CancelRoutine,
  148. GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->ApcContext);
  149. #if DBG
  150. ProcessCtx->DbgLevel
  151. = GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->DbgLevel|DbgLevel;
  152. #endif
  153. ProcessFile->FsContext = ProcessCtx;
  154. WsProcessPrint (ProcessCtx, DBG_PROCESS,
  155. ("WS2IFSL-%04lx CreateProcessFile: Process file %p (ctx: %p).\n",
  156. ProcessCtx->UniqueId,
  157. ProcessFile, ProcessFile->FsContext));
  158. return STATUS_SUCCESS;
  159. }
  160. else {
  161. WsPrint (DBG_PROCESS|DBG_FAILURES,
  162. ("WS2IFSL-%04lx CreateProcessFile: Could not allocate context for"
  163. " process file %p.\n",
  164. PsGetCurrentProcessId(),
  165. ProcessFile));
  166. if (NT_SUCCESS (status)) {
  167. ASSERT (FALSE);
  168. status = STATUS_INSUFFICIENT_RESOURCES;
  169. }
  170. }
  171. }
  172. else {
  173. WsPrint (DBG_PROCESS|DBG_FAILURES,
  174. ("WS2IFSL-%04lx CreateProcessFile: Apc thread (%p)"
  175. " is not from current process for process file %p.\n",
  176. PsGetCurrentProcessId(),
  177. GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->ApcThread,
  178. ProcessFile));
  179. }
  180. ObDereferenceObject (apcThread);
  181. }
  182. else {
  183. WsPrint (DBG_PROCESS|DBG_FAILURES,
  184. ("WS2IFSL-%04lx CreateProcessFile: Could not reference apc thread (%p)"
  185. " for process file %p, status: %lx.\n",
  186. PsGetCurrentProcessId(),
  187. GET_WS2IFSL_PROCESS_EA_VALUE(eaInfo)->ApcThread,
  188. ProcessFile,
  189. status));
  190. }
  191. return status;
  192. } // CreateProcessFile
  193. NTSTATUS
  194. CleanupProcessFile (
  195. IN PFILE_OBJECT ProcessFile,
  196. IN PIRP Irp
  197. )
  198. /*++
  199. Routine Description:
  200. Cleanup routine for process file, NOP
  201. Arguments:
  202. ProcessFile - process file object
  203. Irp - cleanup request
  204. Return Value:
  205. STATUS_SUCESS - operation completed OK
  206. --*/
  207. {
  208. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  209. PAGED_CODE ();
  210. WsProcessPrint (ProcessCtx, DBG_PROCESS,
  211. ("WS2IFSL-%04lx CleanupProcessFile: Process file %p (ctx:%p)\n",
  212. ProcessCtx->UniqueId,
  213. ProcessFile, ProcessFile->FsContext));
  214. return STATUS_SUCCESS;
  215. } // CleanupProcessFile
  216. VOID
  217. CloseProcessFile (
  218. IN PFILE_OBJECT ProcessFile
  219. )
  220. /*++
  221. Routine Description:
  222. Deallocate all resources associated with process file
  223. Arguments:
  224. ProcessFile - process file object
  225. Return Value:
  226. None
  227. --*/
  228. {
  229. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  230. PAGED_CODE ();
  231. WsProcessPrint (ProcessCtx, DBG_PROCESS,
  232. ("WS2IFSL-%04lx CloseProcessFile: Process file %p (ctx:%p)\n",
  233. ProcessCtx->UniqueId, ProcessFile, ProcessFile->FsContext));
  234. ASSERT (IsListEmpty (&ProcessCtx->RequestQueue.ListHead));
  235. ASSERT (IsListEmpty (&ProcessCtx->CancelQueue.ListHead));
  236. ObDereferenceObject (ProcessCtx->RequestQueue.Apc.Thread);
  237. // Now free the context itself
  238. ExFreePool (ProcessCtx);
  239. } // CloseProcessFile
  240. VOID
  241. RetrieveDrvRequest (
  242. IN PFILE_OBJECT ProcessFile,
  243. IN KPROCESSOR_MODE RequestorMode,
  244. IN PVOID InputBuffer,
  245. IN ULONG InputBufferLength,
  246. OUT PVOID OutputBuffer,
  247. IN ULONG OutputBufferLength,
  248. OUT PIO_STATUS_BLOCK IoStatus
  249. )
  250. /*++
  251. Routine Description:
  252. Retrievs parameters and data of the request to be executed by
  253. user mode DLL
  254. Arguments:
  255. ProcessFile - Identifies the process
  256. InputBuffer - input buffer pointer
  257. - identifies the request to retreive
  258. and received request parameters
  259. InputBufferLength - size of the input buffer
  260. OutputBuffer - output buffer pointer
  261. - buffer to receive data and address
  262. for send operation
  263. OutputBufferLength - size of output buffer
  264. IoStatus - IO status information block
  265. Status: STATUS_SUCCESS - operation retreived OK, no more pending
  266. requests in the queue.
  267. STATUS_MORE_ENTRIES - operation retrieved OK, more requests
  268. are available in the queue
  269. STATUS_CANCELLED - operation was cancelled before it
  270. could be retrieved
  271. STATUS_INVALID_PARAMETER - one of the parameters was invalid
  272. STATUS_INSUFFICIENT_RESOURCES - insufficient resources or
  273. buffer space to perform the
  274. operation.
  275. Information: - number of bytes copied to OutputBuffer
  276. Return Value:
  277. None (result returned via IoStatus block)
  278. --*/
  279. {
  280. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  281. PIFSL_SOCKET_CTX SocketCtx;
  282. PWS2IFSL_RTRV_PARAMS params;
  283. PIRP irp = NULL;
  284. PIO_STACK_LOCATION irpSp;
  285. BOOLEAN more =FALSE;
  286. ULONG bytesCopied;
  287. PAGED_CODE();
  288. IoStatus->Information = 0;
  289. // Check input buffer size
  290. if (InputBufferLength<sizeof (WS2IFSL_RTRV_PARAMS)) {
  291. IoStatus->Status = STATUS_INVALID_PARAMETER;
  292. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  293. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid input buffer size (%ld).\n",
  294. PsGetCurrentProcessId(),
  295. InputBufferLength));
  296. return;
  297. }
  298. try {
  299. // Verify buffers
  300. if (RequestorMode!=KernelMode) {
  301. ProbeForRead (InputBuffer,
  302. sizeof (*params),
  303. sizeof (ULONG));
  304. if (OutputBufferLength>0)
  305. ProbeForWrite (OutputBuffer,
  306. OutputBufferLength,
  307. sizeof (UCHAR));
  308. }
  309. params = InputBuffer;
  310. // Dequeue the request indetified in the input buffer
  311. irp = DequeueRequest (ProcessCtx,
  312. params->UniqueId,
  313. &more);
  314. if (irp!=NULL) {
  315. //
  316. // Copy request parameters and data
  317. //
  318. irpSp = IoGetCurrentIrpStackLocation (irp);
  319. if (OutputBuffer==NULL) {
  320. //
  321. // Special condition, dll could not allocate support
  322. // structures
  323. //
  324. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  325. }
  326. SocketCtx = irpSp->FileObject->FsContext;
  327. params->DllContext = SocketCtx->DllContext;
  328. switch (irpSp->MajorFunction) {
  329. case IRP_MJ_READ:
  330. params->RequestType = WS2IFSL_REQUEST_READ;
  331. params->DataLen = irpSp->Parameters.Read.Length;
  332. params->AddrLen = 0;
  333. params->Flags = 0;
  334. break;
  335. case IRP_MJ_WRITE:
  336. bytesCopied = CopyMdlChainToBuffer (irp->MdlAddress,
  337. OutputBuffer,
  338. OutputBufferLength);
  339. if (bytesCopied<irpSp->Parameters.Write.Length) {
  340. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  341. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid output buffer size (%ld).\n",
  342. PsGetCurrentProcessId(),
  343. OutputBufferLength));
  344. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  345. }
  346. params->RequestType = WS2IFSL_REQUEST_WRITE;
  347. params->DataLen = bytesCopied;
  348. params->AddrLen = 0;
  349. params->Flags = 0;
  350. IoStatus->Information = bytesCopied;
  351. break;
  352. case IRP_MJ_DEVICE_CONTROL:
  353. switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
  354. case IOCTL_AFD_RECEIVE_DATAGRAM:
  355. params->RequestType = WS2IFSL_REQUEST_RECVFROM;
  356. params->DataLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  357. params->AddrLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  358. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  359. break;
  360. case IOCTL_AFD_RECEIVE:
  361. params->RequestType = WS2IFSL_REQUEST_RECV;
  362. params->DataLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  363. params->AddrLen = 0;
  364. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  365. break;
  366. case IOCTL_AFD_SEND_DATAGRAM:
  367. bytesCopied = CopyMdlChainToBuffer (irp->MdlAddress,
  368. OutputBuffer,
  369. OutputBufferLength);
  370. if ((bytesCopied<=irpSp->Parameters.DeviceIoControl.OutputBufferLength)
  371. || (ADDR_ALIGN(bytesCopied)+irpSp->Parameters.DeviceIoControl.InputBufferLength
  372. < OutputBufferLength)) {
  373. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  374. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid output buffer size (%ld).\n",
  375. PsGetCurrentProcessId(),
  376. OutputBufferLength));
  377. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  378. }
  379. RtlCopyMemory (
  380. (PUCHAR)OutputBuffer + ADDR_ALIGN(bytesCopied),
  381. irpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  382. irpSp->Parameters.DeviceIoControl.InputBufferLength);
  383. params->RequestType = WS2IFSL_REQUEST_SENDTO;
  384. params->DataLen = bytesCopied;
  385. params->AddrLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  386. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  387. IoStatus->Information = ADDR_ALIGN(bytesCopied)
  388. + irpSp->Parameters.DeviceIoControl.InputBufferLength;
  389. break;
  390. default:
  391. ASSERTMSG ("Unknown IOCTL!!!", FALSE);
  392. ExRaiseStatus( STATUS_INVALID_PARAMETER );
  393. }
  394. break;
  395. case IRP_MJ_PNP:
  396. params->RequestType = WS2IFSL_REQUEST_QUERYHANDLE;
  397. params->DataLen = sizeof (HANDLE);
  398. params->AddrLen = 0;
  399. params->Flags = 0;
  400. break;
  401. }
  402. //
  403. // Insert the request into the socket list
  404. //
  405. if (InsertProcessedRequest (SocketCtx, irp)) {
  406. if (more)
  407. IoStatus->Status = STATUS_MORE_ENTRIES;
  408. else
  409. IoStatus->Status = STATUS_SUCCESS;
  410. WsProcessPrint (ProcessCtx, DBG_RETRIEVE,
  411. ("WS2IFSL-%04lx RetrieveDrvRequest:"
  412. " Irp %p (id:%ld), socket file %p, op %ld.\n",
  413. ProcessCtx->UniqueId,
  414. irp, params->UniqueId, irpSp->FileObject,
  415. params->RequestType));
  416. }
  417. else {
  418. ExRaiseStatus (STATUS_CANCELLED);
  419. }
  420. }
  421. else {
  422. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  423. ("WS2IFSL-%04lx RetrieveDrvRequest:"
  424. " Request with id %ld is not in the queue.\n",
  425. ProcessCtx->UniqueId,
  426. params->UniqueId));
  427. IoStatus->Status = STATUS_CANCELLED;
  428. }
  429. }
  430. except (EXCEPTION_EXECUTE_HANDLER) {
  431. //
  432. // Something failed, complete the request (if any)
  433. //
  434. IoStatus->Status = GetExceptionCode ();
  435. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  436. ("WS2IFSL-%04lx RetrieveDrvRequest: Failed to process"
  437. " id %ld, status %lx, irp %p (func: %s).\n",
  438. ProcessCtx->UniqueId,params->UniqueId, IoStatus->Status,
  439. irp, irp
  440. ? (irpSp->MajorFunction==IRP_MJ_READ
  441. ? "read"
  442. : (irpSp->MajorFunction==IRP_MJ_WRITE
  443. ? "Write"
  444. : (irpSp->MajorFunction==IRP_MJ_PNP
  445. ? "PnP"
  446. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE_DATAGRAM
  447. ? "RecvFrom"
  448. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE
  449. ? "Recv"
  450. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_SEND_DATAGRAM
  451. ? "SendTo"
  452. : "UnknownCtl"
  453. )
  454. )
  455. )
  456. )
  457. )
  458. )
  459. : "Unknown"));
  460. if (irp!=NULL) {
  461. irp->IoStatus.Status = IoStatus->Status;
  462. irp->IoStatus.Information = 0;
  463. CompleteSocketIrp (irp);
  464. }
  465. }
  466. }
  467. VOID
  468. CompleteDrvCancel (
  469. IN PFILE_OBJECT ProcessFile,
  470. IN KPROCESSOR_MODE RequestorMode,
  471. IN PVOID InputBuffer,
  472. IN ULONG InputBufferLength,
  473. OUT PVOID OutputBuffer,
  474. IN ULONG OutputBufferLength,
  475. OUT PIO_STATUS_BLOCK IoStatus
  476. )
  477. /*++
  478. Routine Description:
  479. Indicates that user mode has completed cancel request
  480. Arguments:
  481. ProcessFile - Identifies the process
  482. InputBuffer - input buffer pointer
  483. - identifies the request being completed
  484. InputBufferLength - size of the input buffer
  485. OutputBuffer - NULL
  486. OutputBufferLength - 0
  487. IoStatus - IO status information block
  488. Status: STATUS_SUCCESS - operation completed OK, no more pending
  489. requests in the queue.
  490. STATUS_MORE_ENTRIES - operation completed OK, more requests
  491. are available in the queue
  492. Information: - 0
  493. Return Value:
  494. None (result returned via IoStatus block)
  495. --*/
  496. {
  497. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  498. PWS2IFSL_CNCL_PARAMS params;
  499. BOOLEAN more = FALSE;
  500. PIFSL_CANCEL_CTX cancelCtx;
  501. PAGED_CODE();
  502. IoStatus->Information = 0;
  503. if (InputBufferLength<sizeof (*params)) {
  504. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  505. ("WS2IFSL-%04lx CompleteDrvCancel: Invalid input buffer size (%ld)"
  506. " for process file %p.\n",
  507. PsGetCurrentProcessId(),
  508. InputBufferLength,
  509. ProcessFile));
  510. IoStatus->Status = STATUS_INVALID_PARAMETER;
  511. return;
  512. }
  513. // Verify input buffer
  514. try {
  515. if (RequestorMode!=KernelMode) {
  516. ProbeForRead (InputBuffer,
  517. sizeof (*params),
  518. sizeof (ULONG));
  519. }
  520. params = InputBuffer;
  521. cancelCtx = DequeueCancel (ProcessCtx,
  522. params->UniqueId,
  523. &more);
  524. }
  525. except (EXCEPTION_EXECUTE_HANDLER) {
  526. IoStatus->Status = GetExceptionCode ();
  527. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  528. ("WS2IFSL-%04lx CompleteDrvCancel: Invalid input buffer (%p).\n",
  529. PsGetCurrentProcessId(),
  530. InputBuffer));
  531. return ;
  532. }
  533. if (cancelCtx!=NULL) {
  534. FreeSocketCancel (cancelCtx);
  535. }
  536. else {
  537. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  538. ("WS2IFSL-%04lx CompleteDrvCancel: Canceled request id %ld is gone already.\n",
  539. ProcessCtx->UniqueId, params->UniqueId));
  540. }
  541. if (more) {
  542. IoStatus->Status = STATUS_MORE_ENTRIES;
  543. }
  544. else {
  545. IoStatus->Status = STATUS_SUCCESS;
  546. }
  547. }
  548. VOID
  549. CallCompleteDrvRequest (
  550. IN PFILE_OBJECT ProcessFile,
  551. IN KPROCESSOR_MODE RequestorMode,
  552. IN PVOID InputBuffer,
  553. IN ULONG InputBufferLength,
  554. OUT PVOID OutputBuffer,
  555. IN ULONG OutputBufferLength,
  556. OUT PIO_STATUS_BLOCK IoStatus
  557. )
  558. /*++
  559. Routine Description:
  560. Validate parameters and call to complete request that was
  561. prviously passed to user mode DLL on a specified socket file
  562. Arguments:
  563. SocketFile - Socket file on which to operate
  564. InputBuffer - input buffer pointer
  565. identifies the request to complete and
  566. supplies description of the results
  567. InputBufferLength - size of the input buffer
  568. OutputBuffer - result buffer (data and address)
  569. OutputBufferLength - sizeof result buffer
  570. IoStatus - IO status information block
  571. Status: STATUS_SUCCESS - request was completed OK
  572. STATUS_CANCELLED - request was already cancelled
  573. STATUS_INVALID_PARAMETER - one of the parameters was invalid
  574. Return Value:
  575. None (result returned via IoStatus block)
  576. --*/
  577. {
  578. WS2IFSL_CMPL_PARAMS params;
  579. PFILE_OBJECT SocketFile;
  580. PAGED_CODE();
  581. IoStatus->Information = 0;
  582. if (InputBufferLength<sizeof (WS2IFSL_CMPL_PARAMS)) {
  583. IoStatus->Status = STATUS_INVALID_PARAMETER;
  584. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  585. ("WS2IFSL-%04lx CompleteDrvRequest: Invalid input buffer size (%ld).\n",
  586. PsGetCurrentProcessId(),
  587. InputBufferLength));
  588. return;
  589. }
  590. // Check and copy parameters
  591. try {
  592. if (RequestorMode !=KernelMode) {
  593. ProbeForRead (InputBuffer,
  594. sizeof (WS2IFSL_CMPL_PARAMS),
  595. sizeof (ULONG));
  596. if (OutputBufferLength>0)
  597. ProbeForRead (OutputBuffer,
  598. OutputBufferLength,
  599. sizeof (UCHAR));
  600. }
  601. params = *((PWS2IFSL_CMPL_PARAMS)InputBuffer);
  602. }
  603. except(EXCEPTION_EXECUTE_HANDLER) {
  604. IoStatus->Status = GetExceptionCode ();
  605. WsProcessPrint (
  606. (PIFSL_PROCESS_CTX)ProcessFile->FsContext,
  607. DBG_DRV_COMPLETE|DBG_FAILURES,
  608. ("WS2IFSL-%04lx CallCompleteDrvRequest: Exception accessing"
  609. " buffers.\n",
  610. ((PIFSL_PROCESS_CTX)ProcessFile->FsContext)->UniqueId));
  611. return;
  612. }
  613. if (params.DataLen>OutputBufferLength) {
  614. IoStatus->Status = STATUS_INVALID_PARAMETER;
  615. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  616. ("WS2IFSL-%04lx CompleteDrvRequest: Mismatch in output buffer size"
  617. " (data:%ld, total:%ld) for socket handle %p.\n",
  618. PsGetCurrentProcessId(),
  619. params.DataLen,
  620. OutputBufferLength,
  621. params.SocketHdl));
  622. return;
  623. }
  624. if (params.AddrLen>0) {
  625. if ((params.AddrLen>OutputBufferLength) ||
  626. (ADDR_ALIGN(params.DataLen)+params.AddrLen
  627. >OutputBufferLength)) {
  628. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  629. ("WS2IFSL-%04lx CompleteDrvRequest: Mismatch in output buffer size"
  630. " (data:%ld, addr:%ld, total:%ld) for socket handle %p.\n",
  631. PsGetCurrentProcessId(),
  632. params.DataLen,
  633. params.AddrLen,
  634. OutputBufferLength,
  635. params.SocketHdl));
  636. return;
  637. }
  638. }
  639. IoStatus->Status = ObReferenceObjectByHandle (
  640. params.SocketHdl,
  641. FILE_ALL_ACCESS,
  642. *IoFileObjectType,
  643. RequestorMode,
  644. (PVOID *)&SocketFile,
  645. NULL
  646. );
  647. if (NT_SUCCESS (IoStatus->Status)) {
  648. if ((IoGetRelatedDeviceObject (SocketFile)==DeviceObject)
  649. && ((*((PULONG)SocketFile->FsContext))
  650. ==SOCKET_FILE_EANAME_TAG)) {
  651. CompleteDrvRequest (SocketFile,
  652. &params,
  653. OutputBuffer,
  654. OutputBufferLength,
  655. IoStatus
  656. );
  657. }
  658. ObDereferenceObject (SocketFile);
  659. }
  660. }