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.

183 lines
4.0 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. mdlutil.c
  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. MdlLength - Supplies the length of the MDL to clone.
  54. Return Value:
  55. PMDL - The newly cloned MDL if successful, NULL otherwise.
  56. --***************************************************************************/
  57. PMDL
  58. UlCloneMdl(
  59. IN PMDL pMdl,
  60. IN ULONG MdlLength
  61. )
  62. {
  63. PMDL pMdlClone;
  64. PVOID pMdlAddress;
  65. //
  66. // Ensure the incoming MDL is of the type we expect (either nonpaged
  67. // or locked). For a response that doesn't need to goto the cache entry,
  68. // there is no need to map the buffer as either the lower layer will map
  69. // it or some miniport can handle it unmapped.
  70. //
  71. ASSERT( pMdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_SOURCE_IS_NONPAGED_POOL) );
  72. ASSERT( MdlLength > 0 );
  73. //
  74. // Snag the virtual address from the MDL. Note a MDL returned from
  75. // MmAllocatePagesForMdl doesn't have the virtual address set.
  76. //
  77. pMdlAddress = MmGetMdlVirtualAddress( pMdl );
  78. ASSERT( pMdlAddress != NULL || (pMdl->MdlFlags & MDL_PAGES_LOCKED) );
  79. //
  80. // Allocate a new MDL, then initialize it with the incoming MDL.
  81. //
  82. pMdlClone = UlAllocateMdl(
  83. pMdlAddress, // VirtualAddress
  84. MdlLength, // Length
  85. FALSE, // SecondaryBuffer
  86. FALSE, // ChargeQuota
  87. NULL // Irp
  88. );
  89. if (pMdlClone != NULL)
  90. {
  91. IoBuildPartialMdl(
  92. pMdl, // SourceMdl
  93. pMdlClone, // TargetMdl
  94. pMdlAddress, // VirtualAddress
  95. MdlLength // Length
  96. );
  97. }
  98. return pMdlClone;
  99. } // UlCloneMdl
  100. /***************************************************************************++
  101. Routine Description:
  102. Finds the last MDL in the specified MDL chain.
  103. Arguments:
  104. pMdlChain - Supplies the MDL chain to scan.
  105. Return Value:
  106. PMDL - Pointer to the last MDL in the MDL chain.
  107. --***************************************************************************/
  108. PMDL
  109. UlFindLastMdlInChain(
  110. IN PMDL pMdlChain
  111. )
  112. {
  113. while (pMdlChain->Next != NULL)
  114. {
  115. pMdlChain = pMdlChain->Next;
  116. }
  117. return pMdlChain;
  118. } // UlFindLastMdlInChain
  119. //
  120. // Private functions.
  121. //