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.

141 lines
2.6 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. DevIoSup.c
  5. Abstract:
  6. This module implements the memory locking routines for Npfs.
  7. Author:
  8. Brian Andrew [BrianAn] 03-Apr-1991
  9. Revision History:
  10. --*/
  11. #include "NpProcs.h"
  12. //
  13. // Local debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_DEVIOSUP)
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE, NpLockUserBuffer)
  18. #pragma alloc_text(PAGE, NpMapUserBuffer)
  19. #endif
  20. PVOID
  21. NpMapUserBuffer (
  22. IN OUT PIRP Irp
  23. )
  24. /*++
  25. Routine Description:
  26. This routine conditionally maps the user buffer for the current I/O
  27. request in the specified mode. If the buffer is already mapped, it
  28. just returns its address.
  29. Arguments:
  30. Irp - Pointer to the Irp for the request.
  31. Return Value:
  32. Mapped address
  33. --*/
  34. {
  35. PAGED_CODE();
  36. //
  37. // If there is no Mdl, then we must be in the Fsd, and we can simply
  38. // return the UserBuffer field from the Irp.
  39. //
  40. if (Irp->MdlAddress == NULL) {
  41. return Irp->UserBuffer;
  42. } else {
  43. return MmGetSystemAddressForMdl( Irp->MdlAddress );
  44. }
  45. }
  46. VOID
  47. NpLockUserBuffer (
  48. IN OUT PIRP Irp,
  49. IN LOCK_OPERATION Operation,
  50. IN ULONG BufferLength
  51. )
  52. /*++
  53. Routine Description:
  54. This routine locks the specified buffer for the specified type of
  55. access. The file system requires this routine since it does not
  56. ask the I/O system to lock its buffers for direct I/O. This routine
  57. may only be called from the Fsd while still in the user context.
  58. Arguments:
  59. Irp - Pointer to the Irp for which the buffer is to be locked.
  60. Operation - IoWriteAccess for read operations, or IoReadAccess for
  61. write operations.
  62. BufferLength - Length of user buffer.
  63. Return Value:
  64. None
  65. --*/
  66. {
  67. PMDL Mdl;
  68. PAGED_CODE();
  69. if (Irp->MdlAddress == NULL) {
  70. //
  71. // This read is bound for the current process. Perform the
  72. // same functions as above, only do not switch processes.
  73. //
  74. Mdl = IoAllocateMdl( Irp->UserBuffer, BufferLength, FALSE, TRUE, Irp );
  75. if (Mdl == NULL) {
  76. ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
  77. }
  78. try {
  79. MmProbeAndLockPages( Mdl,
  80. Irp->RequestorMode,
  81. Operation );
  82. } except(EXCEPTION_EXECUTE_HANDLER) {
  83. IoFreeMdl( Mdl );
  84. Irp->MdlAddress = NULL;
  85. ExRaiseStatus( FsRtlNormalizeNtstatus( GetExceptionCode(),
  86. STATUS_INVALID_USER_BUFFER ));
  87. }
  88. }
  89. }
  90.