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.

767 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. PsGetCurrentProcessId(),
  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. ASSERT (ProcessCtx->UniqueId==PsGetCurrentProcessId());
  211. WsProcessPrint (ProcessCtx, DBG_PROCESS,
  212. ("WS2IFSL-%04lx CleanupProcessFile: Process file %p (ctx:%p)\n",
  213. PsGetCurrentProcessId(),
  214. ProcessFile, ProcessFile->FsContext));
  215. return STATUS_SUCCESS;
  216. } // CleanupProcessFile
  217. VOID
  218. CloseProcessFile (
  219. IN PFILE_OBJECT ProcessFile
  220. )
  221. /*++
  222. Routine Description:
  223. Deallocate all resources associated with process file
  224. Arguments:
  225. ProcessFile - process file object
  226. Return Value:
  227. None
  228. --*/
  229. {
  230. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  231. PAGED_CODE ();
  232. WsProcessPrint (ProcessCtx, DBG_PROCESS,
  233. ("WS2IFSL-%04lx CloseProcessFile: Process file %p (ctx:%p)\n",
  234. ProcessCtx->UniqueId, ProcessFile, ProcessFile->FsContext));
  235. ASSERT (IsListEmpty (&ProcessCtx->RequestQueue.ListHead));
  236. ASSERT (IsListEmpty (&ProcessCtx->CancelQueue.ListHead));
  237. ObDereferenceObject (ProcessCtx->RequestQueue.Apc.Thread);
  238. // Now free the context itself
  239. ExFreePool (ProcessCtx);
  240. } // CloseProcessFile
  241. VOID
  242. RetrieveDrvRequest (
  243. IN PFILE_OBJECT ProcessFile,
  244. IN KPROCESSOR_MODE RequestorMode,
  245. IN PVOID InputBuffer,
  246. IN ULONG InputBufferLength,
  247. OUT PVOID OutputBuffer,
  248. IN ULONG OutputBufferLength,
  249. OUT PIO_STATUS_BLOCK IoStatus
  250. )
  251. /*++
  252. Routine Description:
  253. Retrievs parameters and data of the request to be executed by
  254. user mode DLL
  255. Arguments:
  256. ProcessFile - Identifies the process
  257. InputBuffer - input buffer pointer
  258. - identifies the request to retreive
  259. and received request parameters
  260. InputBufferLength - size of the input buffer
  261. OutputBuffer - output buffer pointer
  262. - buffer to receive data and address
  263. for send operation
  264. OutputBufferLength - size of output buffer
  265. IoStatus - IO status information block
  266. Status: STATUS_SUCCESS - operation retreived OK, no more pending
  267. requests in the queue.
  268. STATUS_MORE_ENTRIES - operation retrieved OK, more requests
  269. are available in the queue
  270. STATUS_CANCELLED - operation was cancelled before it
  271. could be retrieved
  272. STATUS_INVALID_PARAMETER - one of the parameters was invalid
  273. STATUS_INSUFFICIENT_RESOURCES - insufficient resources or
  274. buffer space to perform the
  275. operation.
  276. Information: - number of bytes copied to OutputBuffer
  277. Return Value:
  278. None (result returned via IoStatus block)
  279. --*/
  280. {
  281. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  282. PIFSL_SOCKET_CTX SocketCtx;
  283. PWS2IFSL_RTRV_PARAMS params;
  284. PIRP irp = NULL;
  285. PIO_STACK_LOCATION irpSp;
  286. BOOLEAN more =FALSE;
  287. ULONG bytesCopied;
  288. PAGED_CODE();
  289. IoStatus->Information = 0;
  290. // Check input buffer size
  291. if (InputBufferLength<sizeof (WS2IFSL_RTRV_PARAMS)) {
  292. IoStatus->Status = STATUS_INVALID_PARAMETER;
  293. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  294. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid input buffer size (%ld).\n",
  295. PsGetCurrentProcessId(),
  296. InputBufferLength));
  297. return;
  298. }
  299. try {
  300. // Verify buffers
  301. if (RequestorMode!=KernelMode) {
  302. ProbeForRead (InputBuffer,
  303. sizeof (*params),
  304. sizeof (ULONG));
  305. if (OutputBufferLength>0)
  306. ProbeForWrite (OutputBuffer,
  307. OutputBufferLength,
  308. sizeof (UCHAR));
  309. }
  310. params = InputBuffer;
  311. // Dequeue the request indetified in the input buffer
  312. irp = DequeueRequest (ProcessCtx,
  313. params->UniqueId,
  314. &more);
  315. if (irp!=NULL) {
  316. //
  317. // Copy request parameters and data
  318. //
  319. irpSp = IoGetCurrentIrpStackLocation (irp);
  320. if (OutputBuffer==NULL) {
  321. //
  322. // Special condition, dll could not allocate support
  323. // structures
  324. //
  325. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  326. }
  327. SocketCtx = irpSp->FileObject->FsContext;
  328. params->DllContext = SocketCtx->DllContext;
  329. switch (irpSp->MajorFunction) {
  330. case IRP_MJ_READ:
  331. params->RequestType = WS2IFSL_REQUEST_READ;
  332. params->DataLen = irpSp->Parameters.Read.Length;
  333. params->AddrLen = 0;
  334. params->Flags = 0;
  335. break;
  336. case IRP_MJ_WRITE:
  337. bytesCopied = CopyMdlChainToBuffer (irp->MdlAddress,
  338. OutputBuffer,
  339. OutputBufferLength);
  340. if (bytesCopied<irpSp->Parameters.Write.Length) {
  341. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  342. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid output buffer size (%ld).\n",
  343. PsGetCurrentProcessId(),
  344. OutputBufferLength));
  345. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  346. }
  347. params->RequestType = WS2IFSL_REQUEST_WRITE;
  348. params->DataLen = bytesCopied;
  349. params->AddrLen = 0;
  350. params->Flags = 0;
  351. IoStatus->Information = bytesCopied;
  352. break;
  353. case IRP_MJ_DEVICE_CONTROL:
  354. switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
  355. case IOCTL_AFD_RECEIVE_DATAGRAM:
  356. params->RequestType = WS2IFSL_REQUEST_RECVFROM;
  357. params->DataLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  358. params->AddrLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  359. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  360. break;
  361. case IOCTL_AFD_RECEIVE:
  362. params->RequestType = WS2IFSL_REQUEST_RECV;
  363. params->DataLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  364. params->AddrLen = 0;
  365. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  366. break;
  367. case IOCTL_AFD_SEND_DATAGRAM:
  368. bytesCopied = CopyMdlChainToBuffer (irp->MdlAddress,
  369. OutputBuffer,
  370. OutputBufferLength);
  371. if ((bytesCopied<=irpSp->Parameters.DeviceIoControl.OutputBufferLength)
  372. || (ADDR_ALIGN(bytesCopied)+irpSp->Parameters.DeviceIoControl.InputBufferLength
  373. < OutputBufferLength)) {
  374. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  375. ("WS2IFSL-%04lx RetrieveDrvRequest: Invalid output buffer size (%ld).\n",
  376. PsGetCurrentProcessId(),
  377. OutputBufferLength));
  378. ExRaiseStatus (STATUS_INSUFFICIENT_RESOURCES);
  379. }
  380. RtlCopyMemory (
  381. (PUCHAR)OutputBuffer + ADDR_ALIGN(bytesCopied),
  382. irpSp->Parameters.DeviceIoControl.Type3InputBuffer,
  383. irpSp->Parameters.DeviceIoControl.InputBufferLength);
  384. params->RequestType = WS2IFSL_REQUEST_SENDTO;
  385. params->DataLen = bytesCopied;
  386. params->AddrLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
  387. params->Flags = (ULONG)(ULONG_PTR)irp->Tail.Overlay.IfslRequestFlags;
  388. IoStatus->Information = ADDR_ALIGN(bytesCopied)
  389. + irpSp->Parameters.DeviceIoControl.InputBufferLength;
  390. break;
  391. default:
  392. ASSERTMSG ("Unknown IOCTL!!!", FALSE);
  393. ExRaiseStatus( STATUS_INVALID_PARAMETER );
  394. }
  395. break;
  396. case IRP_MJ_PNP:
  397. params->RequestType = WS2IFSL_REQUEST_QUERYHANDLE;
  398. params->DataLen = sizeof (HANDLE);
  399. params->AddrLen = 0;
  400. params->Flags = 0;
  401. break;
  402. }
  403. //
  404. // Insert the request into the socket list
  405. //
  406. if (InsertProcessedRequest (SocketCtx, irp)) {
  407. if (more)
  408. IoStatus->Status = STATUS_MORE_ENTRIES;
  409. else
  410. IoStatus->Status = STATUS_SUCCESS;
  411. WsProcessPrint (ProcessCtx, DBG_RETRIEVE,
  412. ("WS2IFSL-%04lx RetrieveDrvRequest:"
  413. " Irp %p (id:%ld), socket file %p, op %ld.\n",
  414. PsGetCurrentProcessId(),
  415. irp, params->UniqueId, irpSp->FileObject,
  416. params->RequestType));
  417. }
  418. else {
  419. ExRaiseStatus (STATUS_CANCELLED);
  420. }
  421. }
  422. else {
  423. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  424. ("WS2IFSL-%04lx RetrieveDrvRequest:"
  425. " Request with id %ld is not in the queue.\n",
  426. PsGetCurrentProcessId(),
  427. params->UniqueId));
  428. IoStatus->Status = STATUS_CANCELLED;
  429. }
  430. }
  431. except (EXCEPTION_EXECUTE_HANDLER) {
  432. //
  433. // Something failed, complete the request (if any)
  434. //
  435. IoStatus->Status = GetExceptionCode ();
  436. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  437. ("WS2IFSL-%04lx RetrieveDrvRequest: Failed to process"
  438. " id %ld, status %lx, irp %p (func: %s).\n",
  439. PsGetCurrentProcessId(),params->UniqueId, IoStatus->Status,
  440. irp, irp
  441. ? (irpSp->MajorFunction==IRP_MJ_READ
  442. ? "read"
  443. : (irpSp->MajorFunction==IRP_MJ_WRITE
  444. ? "Write"
  445. : (irpSp->MajorFunction==IRP_MJ_PNP
  446. ? "PnP"
  447. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE_DATAGRAM
  448. ? "RecvFrom"
  449. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_RECEIVE
  450. ? "Recv"
  451. : (irpSp->Parameters.DeviceIoControl.IoControlCode==IOCTL_AFD_SEND_DATAGRAM
  452. ? "SendTo"
  453. : "UnknownCtl"
  454. )
  455. )
  456. )
  457. )
  458. )
  459. )
  460. : "Unknown"));
  461. if (irp!=NULL) {
  462. irp->IoStatus.Status = IoStatus->Status;
  463. irp->IoStatus.Information = 0;
  464. CompleteSocketIrp (irp);
  465. }
  466. }
  467. }
  468. VOID
  469. CompleteDrvCancel (
  470. IN PFILE_OBJECT ProcessFile,
  471. IN KPROCESSOR_MODE RequestorMode,
  472. IN PVOID InputBuffer,
  473. IN ULONG InputBufferLength,
  474. OUT PVOID OutputBuffer,
  475. IN ULONG OutputBufferLength,
  476. OUT PIO_STATUS_BLOCK IoStatus
  477. )
  478. /*++
  479. Routine Description:
  480. Indicates that user mode has completed cancel request
  481. Arguments:
  482. ProcessFile - Identifies the process
  483. InputBuffer - input buffer pointer
  484. - identifies the request being completed
  485. InputBufferLength - size of the input buffer
  486. OutputBuffer - NULL
  487. OutputBufferLength - 0
  488. IoStatus - IO status information block
  489. Status: STATUS_SUCCESS - operation completed OK, no more pending
  490. requests in the queue.
  491. STATUS_MORE_ENTRIES - operation completed OK, more requests
  492. are available in the queue
  493. Information: - 0
  494. Return Value:
  495. None (result returned via IoStatus block)
  496. --*/
  497. {
  498. PIFSL_PROCESS_CTX ProcessCtx = ProcessFile->FsContext;
  499. PWS2IFSL_CNCL_PARAMS params;
  500. BOOLEAN more = FALSE;
  501. PIFSL_CANCEL_CTX cancelCtx;
  502. PAGED_CODE();
  503. IoStatus->Information = 0;
  504. if (InputBufferLength<sizeof (*params)) {
  505. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  506. ("WS2IFSL-%04lx CompleteDrvCancel: Invalid input buffer size (%ld)"
  507. " for process file %p.\n",
  508. PsGetCurrentProcessId(),
  509. InputBufferLength,
  510. ProcessFile));
  511. IoStatus->Status = STATUS_INVALID_PARAMETER;
  512. return;
  513. }
  514. // Verify input buffer
  515. try {
  516. if (RequestorMode!=KernelMode) {
  517. ProbeForRead (InputBuffer,
  518. sizeof (*params),
  519. sizeof (ULONG));
  520. }
  521. params = InputBuffer;
  522. cancelCtx = DequeueCancel (ProcessCtx,
  523. params->UniqueId,
  524. &more);
  525. }
  526. except (EXCEPTION_EXECUTE_HANDLER) {
  527. IoStatus->Status = GetExceptionCode ();
  528. WsPrint (DBG_RETRIEVE|DBG_FAILURES,
  529. ("WS2IFSL-%04lx CompleteDrvCancel: Invalid input buffer (%p).\n",
  530. PsGetCurrentProcessId(),
  531. InputBuffer));
  532. return ;
  533. }
  534. if (cancelCtx!=NULL) {
  535. FreeSocketCancel (cancelCtx);
  536. }
  537. else {
  538. WsProcessPrint (ProcessCtx, DBG_RETRIEVE|DBG_FAILURES,
  539. ("WS2IFSL-%04lx CompleteDrvCancel: Canceled request id %ld is gone already.\n",
  540. PsGetCurrentProcessId(), params->UniqueId));
  541. }
  542. if (more) {
  543. IoStatus->Status = STATUS_MORE_ENTRIES;
  544. }
  545. else {
  546. IoStatus->Status = STATUS_SUCCESS;
  547. }
  548. }
  549. VOID
  550. CallCompleteDrvRequest (
  551. IN PFILE_OBJECT ProcessFile,
  552. IN KPROCESSOR_MODE RequestorMode,
  553. IN PVOID InputBuffer,
  554. IN ULONG InputBufferLength,
  555. OUT PVOID OutputBuffer,
  556. IN ULONG OutputBufferLength,
  557. OUT PIO_STATUS_BLOCK IoStatus
  558. )
  559. /*++
  560. Routine Description:
  561. Validate parameters and call to complete request that was
  562. prviously passed to user mode DLL on a specified socket file
  563. Arguments:
  564. SocketFile - Socket file on which to operate
  565. InputBuffer - input buffer pointer
  566. identifies the request to complete and
  567. supplies description of the results
  568. InputBufferLength - size of the input buffer
  569. OutputBuffer - result buffer (data and address)
  570. OutputBufferLength - sizeof result buffer
  571. IoStatus - IO status information block
  572. Status: STATUS_SUCCESS - request was completed OK
  573. STATUS_CANCELLED - request was already cancelled
  574. STATUS_INVALID_PARAMETER - one of the parameters was invalid
  575. Return Value:
  576. None (result returned via IoStatus block)
  577. --*/
  578. {
  579. WS2IFSL_CMPL_PARAMS params;
  580. PFILE_OBJECT SocketFile;
  581. PAGED_CODE();
  582. IoStatus->Information = 0;
  583. if (InputBufferLength<sizeof (WS2IFSL_CMPL_PARAMS)) {
  584. IoStatus->Status = STATUS_INVALID_PARAMETER;
  585. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  586. ("WS2IFSL-%04lx CompleteDrvRequest: Invalid input buffer size (%ld).\n",
  587. PsGetCurrentProcessId(),
  588. InputBufferLength));
  589. return;
  590. }
  591. // Check and copy parameters
  592. try {
  593. if (RequestorMode !=KernelMode) {
  594. ProbeForRead (InputBuffer,
  595. sizeof (WS2IFSL_CMPL_PARAMS),
  596. sizeof (ULONG));
  597. if (OutputBufferLength>0)
  598. ProbeForRead (OutputBuffer,
  599. OutputBufferLength,
  600. sizeof (UCHAR));
  601. }
  602. params = *((PWS2IFSL_CMPL_PARAMS)InputBuffer);
  603. }
  604. except(EXCEPTION_EXECUTE_HANDLER) {
  605. IoStatus->Status = GetExceptionCode ();
  606. WsProcessPrint (
  607. (PIFSL_PROCESS_CTX)ProcessFile->FsContext,
  608. DBG_DRV_COMPLETE|DBG_FAILURES,
  609. ("WS2IFSL-%04lx CallCompleteDrvRequest: Exception accessing"
  610. " buffers.\n",
  611. PsGetCurrentProcessId()));
  612. return;
  613. }
  614. if (params.DataLen>OutputBufferLength) {
  615. IoStatus->Status = STATUS_INVALID_PARAMETER;
  616. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  617. ("WS2IFSL-%04lx CompleteDrvRequest: Mismatch in output buffer size"
  618. " (data:%ld, total:%ld) for socket handle %p.\n",
  619. PsGetCurrentProcessId(),
  620. params.DataLen,
  621. OutputBufferLength,
  622. params.SocketHdl));
  623. return;
  624. }
  625. if (params.AddrLen>0) {
  626. if ((params.AddrLen>OutputBufferLength) ||
  627. (ADDR_ALIGN(params.DataLen)+params.AddrLen
  628. >OutputBufferLength)) {
  629. WsPrint (DBG_DRV_COMPLETE|DBG_FAILURES,
  630. ("WS2IFSL-%04lx CompleteDrvRequest: Mismatch in output buffer size"
  631. " (data:%ld, addr:%ld, total:%ld) for socket handle %p.\n",
  632. PsGetCurrentProcessId(),
  633. params.DataLen,
  634. params.AddrLen,
  635. OutputBufferLength,
  636. params.SocketHdl));
  637. return;
  638. }
  639. }
  640. IoStatus->Status = ObReferenceObjectByHandle (
  641. params.SocketHdl,
  642. FILE_ALL_ACCESS,
  643. *IoFileObjectType,
  644. RequestorMode,
  645. (PVOID *)&SocketFile,
  646. NULL
  647. );
  648. if (NT_SUCCESS (IoStatus->Status)) {
  649. if ((IoGetRelatedDeviceObject (SocketFile)==DeviceObject)
  650. && ((*((PULONG)SocketFile->FsContext))
  651. ==SOCKET_FILE_EANAME_TAG)) {
  652. CompleteDrvRequest (SocketFile,
  653. &params,
  654. OutputBuffer,
  655. OutputBufferLength,
  656. IoStatus
  657. );
  658. }
  659. ObDereferenceObject (SocketFile);
  660. }
  661. }