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.

157 lines
5.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. FsCtlBuf.h
  5. Abstract:
  6. This module defines routines that get the buffers for the various types of ioctl/fsctls. It is essntially
  7. just the reverse of the IopXXXControlFile routine in io\internal.c, the appropriate parts of which are
  8. reproduced here.
  9. Author:
  10. Joe Linn [JoeLinn] 4-aug-1994
  11. Revision History:
  12. --*/
  13. #ifndef _fsctlbuf_
  14. #define _fsctlbuf_
  15. // the presentation here is in three pieces: the macros for METHODBUFFERED, METHODDIRECT, AND METHODNEITHER.
  16. // it's set up this way so that you can find out what you've got just by reading this and not looking thru
  17. // IO system....
  18. /* here is the code for case 0
  19. case 0:
  20. //
  21. // For this case, allocate a buffer that is large enough to contain
  22. // both the input and the output buffers. Copy the input buffer to
  23. // the allocated buffer and set the appropriate IRP fields.
  24. //
  25. try {
  26. if (InputBufferLength || OutputBufferLength) {
  27. irp->AssociatedIrp.SystemBuffer =
  28. RxAllocatePool( poolType,
  29. (InputBufferLength > OutputBufferLength) ? InputBufferLength : OutputBufferLength );
  30. if (ARGUMENT_PRESENT( InputBuffer )) {
  31. RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
  32. InputBuffer,
  33. InputBufferLength );
  34. }
  35. irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
  36. irp->UserBuffer = OutputBuffer;
  37. if (ARGUMENT_PRESENT( OutputBuffer )) {
  38. irp->Flags |= IRP_INPUT_OPERATION;
  39. }
  40. } else {
  41. irp->Flags = 0;
  42. irp->UserBuffer = (PVOID) NULL;
  43. }
  44. } except(EXCEPTION_EXECUTE_HANDLER) {
  45. <<<elided>>>
  46. }
  47. break;
  48. So, the bottom line is that irp->AssociatedIrp.SystemBuffer is a buffer of length (I-length+O-length) and
  49. is preloaded with the input. Even though the original outputbuffer is passed thru in irp->UserBuffer, it is not to be used
  50. in the FS; rather the FS writes its answer into the same buffer. we get the
  51. following macros:
  52. */
  53. #define METHODBUFFERED_SharedBuffer(IRP) (IRP)->AssociatedIrp.SystemBuffer
  54. /* for 1 and 2
  55. case 1:
  56. case 2:
  57. //
  58. // For these two cases, allocate a buffer that is large enough to
  59. // contain the input buffer, if any, and copy the information to
  60. // the allocated buffer. Then build an MDL for either read or write
  61. // access, depending on the method, for the output buffer. Note
  62. // that the buffer length parameters have been jammed to zero for
  63. // users if the buffer parameter was not passed. (Kernel callers
  64. // should be calling the service correctly in the first place.)
  65. //
  66. // Note also that it doesn't make a whole lot of sense to specify
  67. // either method #1 or #2 if the IOCTL does not require the caller
  68. // to specify an output buffer.
  69. //
  70. try {
  71. if (InputBufferLength && ARGUMENT_PRESENT( InputBuffer )) {
  72. irp->AssociatedIrp.SystemBuffer =
  73. RxAllocatePool( poolType, InputBufferLength );
  74. RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
  75. InputBuffer,
  76. InputBufferLength );
  77. irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
  78. } else {
  79. irp->Flags = 0;
  80. }
  81. if (OutputBufferLength != 0) {
  82. irp->MdlAddress = IoAllocateMdl( OutputBuffer,
  83. OutputBufferLength,
  84. FALSE,
  85. TRUE,
  86. irp );
  87. if (irp->MdlAddress == NULL) {
  88. ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
  89. }
  90. MmProbeAndLockPages( irp->MdlAddress,
  91. requestorMode,
  92. (LOCK_OPERATION) ((method == 1) ? IoReadAccess : IoWriteAccess) );
  93. }
  94. } except(EXCEPTION_EXECUTE_HANDLER) {
  95. <<<ELIDED>>>
  96. }
  97. break;
  98. So the deal is that the input buffer has been copied in as in case 0 but what we have is an MDL for
  99. the output buffer. this leads to the following
  100. */
  101. #define METHODDIRECT_BufferedInputBuffer(IRP) ((IRP)->AssociatedIrp.SystemBuffer)
  102. #define METHODDIRECT_DirectBuffer(IRP) (((IRP)->MdlAddress) \
  103. ? MmGetSystemAddressForMdlSafe((IRP)->MdlAddress,NormalPagePriority):NULL)
  104. /* and finally
  105. case 3:
  106. //
  107. // For this case, do nothing. Everything is up to the driver.
  108. // Simply give the driver a copy of the caller's parameters and
  109. // let the driver do everything itself.
  110. //
  111. irp->UserBuffer = OutputBuffer;
  112. irpSp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
  113. }
  114. So we can get 'em.....but we don't really know how they're gonna be used. Nevertheless.......
  115. */
  116. #define METHODNEITHER_OriginalInputBuffer(IRPSP) ((IRPSP)->Parameters.DeviceIoControl.Type3InputBuffer)
  117. #define METHODNEITHER_OriginalOutputBuffer(IRP) ((IRP)->UserBuffer)
  118. #endif // _fsctlbuf_
  119.