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.

235 lines
4.8 KiB

  1. /*--Copyright (c) 1999-2000 Microsoft Corporation
  2. Module Name:
  3. mdl2ndis.c
  4. Abstract:
  5. MDL <--> NDIS_BUFFER conversion
  6. Author:
  7. Bruce Johnson (bjohnson) 31-Aug-1999
  8. --*/
  9. #include <tcpipbase.h>
  10. #if MILLEN
  11. ULONG g_cConvertedNdisBuffers = 0;
  12. ULONG g_cConvertedMdls = 0;
  13. TDI_STATUS
  14. ConvertMdlToNdisBuffer(
  15. PIRP pIrp,
  16. PMDL pMdl,
  17. PNDIS_BUFFER *ppNdisBuffer
  18. )
  19. {
  20. NDIS_STATUS NdisStatus;
  21. PVOID VirtualAddress;
  22. ULONG Length;
  23. PNDIS_BUFFER pNdisBuffer;
  24. TDI_STATUS TdiStatus = TDI_SUCCESS;
  25. #ifdef DEBUG_MSG
  26. PMDL pSavedMdl = pMdl;
  27. #endif // DEBUG_MSG
  28. //
  29. // Allocate the NDIS_BUFFER chain describing the MDL chain.
  30. //
  31. *ppNdisBuffer = NULL;
  32. pNdisBuffer = NULL;
  33. do {
  34. VirtualAddress = MmGetSystemAddressForMdl(pMdl);
  35. Length = MmGetMdlByteCount(pMdl);
  36. NdisAllocateBuffer(
  37. &NdisStatus,
  38. (pNdisBuffer == NULL) ? (&pNdisBuffer) : (&(pNdisBuffer->Next)),
  39. NULL, //gBufferPool
  40. VirtualAddress,
  41. Length
  42. );
  43. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  44. DEBUGMSG(DBG_ERROR,
  45. (DTEXT("ConvertMdlToNdisBuffer failed to allocate NDIS_BUFFER.\n")));
  46. break;
  47. }
  48. if (*ppNdisBuffer != NULL) {
  49. pNdisBuffer = pNdisBuffer->Next;
  50. }
  51. else {
  52. *ppNdisBuffer = pNdisBuffer;
  53. }
  54. pNdisBuffer->Next = NULL;
  55. pMdl = pMdl->Next;
  56. } while (pMdl != NULL);
  57. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  58. PNDIS_BUFFER pNext;
  59. pNdisBuffer = *ppNdisBuffer;
  60. while (pNdisBuffer) {
  61. pNext = pNdisBuffer->Next;
  62. NdisFreeBuffer(pNdisBuffer);
  63. pNdisBuffer = pNext;
  64. }
  65. *ppNdisBuffer = NULL;
  66. TdiStatus = TDI_NO_RESOURCES;
  67. goto done;
  68. }
  69. InterlockedIncrement(&g_cConvertedNdisBuffers);
  70. done:
  71. // Ensure that it is initialized, either way.
  72. pIrp->Tail.Overlay.DriverContext[0] = *ppNdisBuffer;
  73. DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
  74. (DTEXT("Convert IRP %x MDL %x NDIS_BUFFER %x\n"),
  75. pIrp, pSavedMdl, *ppNdisBuffer));
  76. return TdiStatus;
  77. }
  78. TDI_STATUS
  79. FreeMdlToNdisBufferChain(
  80. PIRP pIrp
  81. )
  82. {
  83. PNDIS_BUFFER pNdisBuffer = pIrp->Tail.Overlay.DriverContext[0];
  84. PNDIS_BUFFER pNext;
  85. if (pNdisBuffer == NULL) {
  86. goto done;
  87. }
  88. DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
  89. (DTEXT("FreeConvert IRP %x NdisBuffer %x\n"), pIrp, pNdisBuffer));
  90. do {
  91. pNext = pNdisBuffer->Next;
  92. NdisFreeBuffer(pNdisBuffer);
  93. pNdisBuffer = pNext;
  94. } while (pNdisBuffer);
  95. pIrp->Tail.Overlay.DriverContext[0] = NULL;
  96. InterlockedDecrement(&g_cConvertedNdisBuffers);
  97. done:
  98. return TDI_SUCCESS;
  99. }
  100. TDI_STATUS
  101. ConvertNdisBufferToMdl(
  102. PNDIS_BUFFER pNdisBuffer,
  103. PMDL *ppMdl
  104. )
  105. {
  106. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  107. TDI_STATUS TdiStatus = TDI_SUCCESS;
  108. PVOID VirtualAddress;
  109. ULONG Length;
  110. PMDL pMdl = NULL;
  111. PMDL pLast = NULL;
  112. #ifdef DEBUG_MSG
  113. PNDIS_BUFFER pSavedNdisBuffer = pNdisBuffer;
  114. #endif // DEBUG_MSG
  115. *ppMdl = NULL;
  116. do {
  117. NdisQueryBuffer(
  118. pNdisBuffer,
  119. &VirtualAddress,
  120. &Length);
  121. pMdl = IoAllocateMdl(
  122. VirtualAddress,
  123. Length,
  124. FALSE,
  125. FALSE,
  126. NULL);
  127. if (pMdl == NULL) {
  128. DEBUGMSG(DBG_ERROR,
  129. (DTEXT("ConvertNdisBufferToMdl failed to allocate MDL.\n")));
  130. NdisStatus = NDIS_STATUS_RESOURCES;
  131. break;
  132. }
  133. if (*ppMdl != NULL) {
  134. pLast->Next = pMdl;
  135. } else {
  136. *ppMdl = pMdl;
  137. }
  138. pMdl->Next = NULL;
  139. pLast = pMdl;
  140. pNdisBuffer = pNdisBuffer->Next;
  141. } while (pNdisBuffer != NULL);
  142. if (NdisStatus != NDIS_STATUS_SUCCESS) {
  143. PMDL pNext;
  144. pMdl = *ppMdl;
  145. while (pMdl) {
  146. pNext = pMdl->Next;
  147. IoFreeMdl(pMdl);
  148. pMdl = pNext;
  149. }
  150. *ppMdl = NULL;
  151. TdiStatus = TDI_NO_RESOURCES;
  152. goto done;
  153. }
  154. InterlockedIncrement(&g_cConvertedMdls);
  155. done:
  156. DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
  157. (DTEXT("Convert NDIS_BUFFER %x MDL %x\n"),
  158. pSavedNdisBuffer, *ppMdl));
  159. return TdiStatus;
  160. }
  161. TDI_STATUS
  162. FreeNdisBufferToMdlChain(
  163. PMDL pMdl
  164. )
  165. {
  166. PMDL pNext;
  167. DEBUGMSG(DBG_INFO && DBG_TDI && DBG_VERBOSE,
  168. (DTEXT("FreeConvert MDL %x\n"), pMdl));
  169. while (pMdl) {
  170. pNext = pMdl->Next;
  171. IoFreeMdl(pMdl);
  172. pMdl = pNext;
  173. }
  174. InterlockedDecrement(&g_cConvertedMdls);
  175. return TDI_SUCCESS;
  176. }
  177. #endif // MILLEN