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.

181 lines
3.5 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. mdlutil.cxx
  5. Abstract:
  6. This module implements general MDL utilities.
  7. Author:
  8. Keith Moore (keithmo) 25-Aug-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #endif // ALLOC_PRAGMA
  14. #if 0
  15. NOT PAGEABLE -- UlGetMdlChainByteCount
  16. NOT PAGEABLE -- UlCloneMdl
  17. NOT PAGEABLE -- UlFindLastMdlInChain
  18. #endif
  19. //
  20. // Public functions.
  21. //
  22. /***************************************************************************++
  23. Routine Description:
  24. Calculates the total byte length of the specified MDL chain.
  25. Arguments:
  26. pMdlChain - Supplies the head of the MDL chain to scan.
  27. Return Value:
  28. ULONG_PTR - The total byte length of the chain.
  29. --***************************************************************************/
  30. ULONG
  31. UlGetMdlChainByteCount(
  32. IN PMDL pMdlChain
  33. )
  34. {
  35. ULONG totalLength;
  36. //
  37. // Simply scan through the MDL chain and sum the lengths.
  38. //
  39. totalLength = 0;
  40. do
  41. {
  42. totalLength += (ULONG)MmGetMdlByteCount( pMdlChain );
  43. pMdlChain = pMdlChain->Next;
  44. } while (pMdlChain != NULL);
  45. return totalLength;
  46. } // UlGetMdlChainByteCount
  47. /***************************************************************************++
  48. Routine Description:
  49. Clones the specified MDL, resulting in a new MDL that describes
  50. the exact same memory (pages, etc) as the original MDL.
  51. Arguments:
  52. pMdl - Supplies the MDL to clone.
  53. Return Value:
  54. PMDL - The newly cloned MDL if successful, NULL otherwise.
  55. --***************************************************************************/
  56. PMDL
  57. UlCloneMdl(
  58. IN PMDL pMdl
  59. )
  60. {
  61. PMDL pMdlClone;
  62. ULONG mdlLength;
  63. PVOID pMdlAddress;
  64. //
  65. // Ensure the incoming MDL is of the type we expect (either nonpaged
  66. // or already mapped into system space).
  67. //
  68. ASSERT( (pMdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
  69. MDL_SOURCE_IS_NONPAGED_POOL)) != 0);
  70. //
  71. // Snag the length & virtual address from the MDL.
  72. //
  73. mdlLength = MmGetMdlByteCount( pMdl );
  74. ASSERT( mdlLength > 0 );
  75. pMdlAddress = MmGetMdlVirtualAddress( pMdl );
  76. ASSERT( pMdlAddress != NULL );
  77. //
  78. // Allocate a new MDL, then initialize it with the incoming MDL.
  79. //
  80. pMdlClone = UlAllocateMdl(
  81. pMdlAddress, // VirtualAddress
  82. mdlLength, // Length
  83. FALSE, // SecondaryBuffer
  84. FALSE, // ChargeQuota
  85. NULL // Irp
  86. );
  87. if (pMdlClone != NULL)
  88. {
  89. IoBuildPartialMdl(
  90. pMdl, // SourceMdl
  91. pMdlClone, // TargetMdl
  92. pMdlAddress, // VirtualAddress
  93. mdlLength // Length
  94. );
  95. }
  96. return pMdlClone;
  97. } // UlCloneMdl
  98. /***************************************************************************++
  99. Routine Description:
  100. Finds the last MDL in the specified MDL chain.
  101. Arguments:
  102. pMdlChain - Supplies the MDL chain to scan.
  103. Return Value:
  104. PMDL - Pointer to the last MDL in the MDL chain.
  105. --***************************************************************************/
  106. PMDL
  107. UlFindLastMdlInChain(
  108. IN PMDL pMdlChain
  109. )
  110. {
  111. while (pMdlChain->Next != NULL)
  112. {
  113. pMdlChain = pMdlChain->Next;
  114. }
  115. return pMdlChain;
  116. } // UlFindLastMdlInChain
  117. //
  118. // Private functions.
  119. //