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.

685 lines
22 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rndis.c
  5. Author:
  6. ervinp
  7. Environment:
  8. Kernel mode
  9. Revision History:
  10. --*/
  11. #include <ndis.h>
  12. #include <ntddndis.h> // defines OID's
  13. #include "..\inc\rndis.h"
  14. #include "..\inc\rndisapi.h"
  15. #include "usb8023.h"
  16. #include "debug.h"
  17. NDIS_STATUS RndisInitializeHandler( OUT PNDIS_HANDLE pMiniportAdapterContext,
  18. OUT PULONG pMaxReceiveSize,
  19. IN NDIS_HANDLE RndisMiniportHandle,
  20. IN NDIS_HANDLE NdisMiniportHandle,
  21. IN NDIS_HANDLE WrapperConfigurationContext,
  22. IN PDEVICE_OBJECT Pdo)
  23. {
  24. NDIS_STATUS rndisStat;
  25. ADAPTEREXT *adapter;
  26. DBGVERBOSE(("RndisInitializeHandler"));
  27. /*
  28. * Allocate a new device object to represent this connection.
  29. */
  30. adapter = NewAdapter(Pdo);
  31. if (adapter){
  32. adapter->ndisAdapterHandle = (PVOID)NdisMiniportHandle;
  33. adapter->rndisAdapterHandle = (PVOID)RndisMiniportHandle;
  34. if (InitUSB(adapter)){
  35. /*
  36. * Figure out the buffer size required for each packet.
  37. *
  38. * For native RNDIS, the buffer must include the rndis message and RNDIS_PACKET.
  39. * For KLSI, we have to prepend a two-byte size field to each packet.
  40. * For other prototypes, we have to append zeroes to round the length
  41. * up to the next multiple of the endpoint packet size.
  42. *
  43. * We must also need one extra byte for the one-byte short packet that
  44. * must follow a full-sized frame.
  45. */
  46. ASSERT(adapter->writePipeLength);
  47. ASSERT(adapter->readPipeLength);
  48. /*
  49. * Allocate common resources before miniport-specific resources
  50. * because we need to allocate the packet pool first.
  51. */
  52. if (AllocateCommonResources(adapter)){
  53. EnqueueAdapter(adapter);
  54. /*
  55. * Give RNDIS our adapter context, which it will use to call us.
  56. */
  57. *pMiniportAdapterContext = (NDIS_HANDLE)adapter;
  58. *pMaxReceiveSize = PACKET_BUFFER_SIZE;
  59. rndisStat = NDIS_STATUS_SUCCESS;
  60. }
  61. else {
  62. rndisStat = NDIS_STATUS_NOT_ACCEPTED;
  63. }
  64. }
  65. else {
  66. rndisStat = NDIS_STATUS_NOT_ACCEPTED;
  67. }
  68. if (rndisStat != NDIS_STATUS_SUCCESS){
  69. FreeAdapter(adapter);
  70. }
  71. }
  72. else {
  73. rndisStat = NDIS_STATUS_NOT_ACCEPTED;
  74. }
  75. return rndisStat;
  76. }
  77. NDIS_STATUS RndisInitCompleteNotify(IN NDIS_HANDLE MicroportAdapterContext,
  78. IN ULONG DeviceFlags,
  79. IN OUT PULONG pMaxTransferSize)
  80. {
  81. ADAPTEREXT *adapter = (ADAPTEREXT *)MicroportAdapterContext;
  82. if (*pMaxTransferSize > PACKET_BUFFER_SIZE) {
  83. DBGWARN(("Reducing adapter MaxTransferSize from %xh to %xh.",
  84. *pMaxTransferSize, PACKET_BUFFER_SIZE));
  85. *pMaxTransferSize = PACKET_BUFFER_SIZE;
  86. }
  87. StartUSBReadLoop(adapter);
  88. return NDIS_STATUS_SUCCESS;
  89. }
  90. VOID RndisHalt(IN NDIS_HANDLE MicroportAdapterContext)
  91. {
  92. BOOLEAN workItemOrTimerPending;
  93. KIRQL oldIrql;
  94. ADAPTEREXT *adapter = (ADAPTEREXT *)MicroportAdapterContext;
  95. ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
  96. DBGOUT(("> RndisHalt(%ph)", adapter));
  97. ASSERT(adapter->sig == DRIVER_SIG);
  98. HaltAdapter(adapter);
  99. KeAcquireSpinLock(&adapter->adapterSpinLock, &oldIrql);
  100. workItemOrTimerPending = adapter->workItemOrTimerPending;
  101. KeReleaseSpinLock(&adapter->adapterSpinLock, oldIrql);
  102. if (workItemOrTimerPending){
  103. /*
  104. * Wait until workItem fires back to us before freeing the adapter context.
  105. */
  106. KeWaitForSingleObject(&adapter->workItemOrTimerEvent, Executive, KernelMode, FALSE, NULL);
  107. }
  108. DequeueAdapter(adapter);
  109. FreeAdapter(adapter);
  110. #if DBG_WRAP_MEMORY
  111. if (dbgTotalMemCount != 0){
  112. DBGERR(("RndisHalt: unloading with %xh bytes still allocated !!", dbgTotalMemCount));
  113. }
  114. #endif
  115. DBGOUT(("< RndisHalt"));
  116. }
  117. VOID RndisShutdown(IN NDIS_HANDLE MicroportAdapterContext)
  118. {
  119. ADAPTEREXT *adapter = (ADAPTEREXT *)MicroportAdapterContext;
  120. DBGOUT(("RndisShutdown(%ph)", adapter));
  121. #if DBG_WRAP_MEMORY
  122. if (dbgTotalMemCount != 0){
  123. DBGERR(("RndisShutdown: unloading with %xh bytes still allocated !!", dbgTotalMemCount));
  124. }
  125. #endif
  126. }
  127. VOID RndisSendMessageHandler( IN NDIS_HANDLE MicroportAdapterContext,
  128. IN PMDL pMessageMdl,
  129. IN NDIS_HANDLE RndisMessageHandle,
  130. IN RM_CHANNEL_TYPE ChannelType)
  131. {
  132. ADAPTEREXT *adapter = (ADAPTEREXT *)MicroportAdapterContext;
  133. ASSERT(adapter->sig == DRIVER_SIG);
  134. if (!adapter->resetting){
  135. /*
  136. * The message header is guaranteed to be contained in the first buffer of the MDL.
  137. */
  138. PRNDIS_MESSAGE pMsg = GetSystemAddressForMdlSafe(pMessageMdl);
  139. if (pMsg){
  140. ASSERT(!adapter->halting);
  141. if (adapter->numActiveWritePackets <= USB_PACKET_POOL_SIZE*3/4){
  142. USBPACKET *packet = DequeueFreePacket(adapter);
  143. if (packet){
  144. packet->rndisMessageHandle = (PVOID)RndisMessageHandle;
  145. /*
  146. * Move our packet to the usbPendingWritePackets queue
  147. * and send it down the USB pipe.
  148. * Native RNDIS packet messages go intact to the write pipe.
  149. * All other encapsulated commands go to the control pipe.
  150. */
  151. EnqueuePendingWritePacket(packet);
  152. if (ChannelType == RMC_DATA) {
  153. ASSERT(!packet->ndisSendPktMdl);
  154. #ifdef RAW_TEST
  155. if (adapter->rawTest) {
  156. pMessageMdl = AddDataHeader(pMessageMdl);
  157. if (pMessageMdl == NULL) {
  158. DequeuePendingWritePacket(packet);
  159. RndisMSendComplete( (NDIS_HANDLE)adapter->rndisAdapterHandle,
  160. RndisMessageHandle,
  161. NDIS_STATUS_RESOURCES);
  162. return;
  163. }
  164. packet->dataPacket = TRUE;
  165. }
  166. #endif // RAW_TEST
  167. packet->ndisSendPktMdl = pMessageMdl;
  168. packet->dataBufferCurrentLength = CopyMdlToBuffer(packet->dataBuffer, pMessageMdl, packet->dataBufferMaxLength);
  169. SubmitUSBWritePacket(packet);
  170. }
  171. else {
  172. NTSTATUS status;
  173. ULONG msgType = pMsg->NdisMessageType;
  174. BOOLEAN synchronizeUSBcall = FALSE;
  175. ULONG oid;
  176. RNDIS_REQUEST_ID reqId;
  177. switch (msgType){
  178. case REMOTE_NDIS_INITIALIZE_MSG:
  179. {
  180. ULONG maxXferSize = pMsg->Message.InitializeRequest.MaxTransferSize;
  181. DBGOUT(("---- REMOTE_NDIS_INITIALIZE_MSG (MaxTransferSize = %xh) ----", maxXferSize));
  182. ASSERT(maxXferSize <= PACKET_BUFFER_SIZE);
  183. adapter->rndismpMajorVersion = pMsg->Message.InitializeRequest.MajorVersion;
  184. adapter->rndismpMinorVersion = pMsg->Message.InitializeRequest.MinorVersion;
  185. adapter->rndismpMaxTransferSize = maxXferSize;
  186. synchronizeUSBcall = TRUE;
  187. }
  188. break;
  189. case REMOTE_NDIS_SET_MSG:
  190. case REMOTE_NDIS_QUERY_MSG:
  191. oid = pMsg->Message.SetRequest.Oid;
  192. reqId = pMsg->Message.SetRequest.RequestId;
  193. DBGVERBOSE(("> %s (req#%d)", DbgGetOidName(oid), reqId));
  194. if (oid == OID_GEN_CURRENT_PACKET_FILTER){
  195. ULONG pktFilter = *(PULONG)((PUCHAR)&pMsg->Message.SetRequest+pMsg->Message.SetRequest.InformationBufferOffset);
  196. adapter->currentPacketFilter = pktFilter;
  197. adapter->gotPacketFilterIndication = TRUE;
  198. DBGOUT(("---- Got OID_GEN_CURRENT_PACKET_FILTER (%xh) ----", pktFilter));
  199. }
  200. else if (oid == OID_802_3_CURRENT_ADDRESS){
  201. /*
  202. * This oid can be a query or a set.
  203. * If it's a set, save the assigned
  204. * MAC address in case we need to simulate
  205. * it later on a reset.
  206. */
  207. if (msgType == REMOTE_NDIS_SET_MSG){
  208. ASSERT(pMsg->Message.SetRequest.InformationBufferLength == ETHERNET_ADDRESS_LENGTH);
  209. DBGVERBOSE(("COVERAGE - OID_802_3_CURRENT_ADDRESS (SET), msg=%xh.", pMsg));
  210. RtlMoveMemory( adapter->MAC_Address,
  211. ((PUCHAR)&pMsg->Message.SetRequest+pMsg->Message.SetRequest.InformationBufferOffset),
  212. ETHERNET_ADDRESS_LENGTH);
  213. }
  214. }
  215. adapter->dbgCurrentOid = oid;
  216. break;
  217. case REMOTE_NDIS_RESET_MSG:
  218. DBGWARN(("---- REMOTE_NDIS_RESET_MSG ----"));
  219. adapter->numSoftResets++;
  220. break;
  221. case REMOTE_NDIS_HALT_MSG:
  222. DBGWARN(("---- REMOTE_NDIS_HALT_MSG ----"));
  223. break;
  224. }
  225. packet->dataBufferCurrentLength = CopyMdlToBuffer( packet->dataBuffer,
  226. pMessageMdl,
  227. packet->dataBufferMaxLength);
  228. #ifdef RAW_TEST
  229. packet->dataPacket = FALSE;
  230. #endif
  231. status = SubmitPacketToControlPipe(packet, synchronizeUSBcall, FALSE);
  232. /*
  233. * If this is an init message, then start reading the notify pipe.
  234. */
  235. switch (msgType){
  236. case REMOTE_NDIS_INITIALIZE_MSG:
  237. if (NT_SUCCESS(status)){
  238. adapter->initialized = TRUE;
  239. SubmitNotificationRead(adapter, FALSE);
  240. }
  241. else {
  242. DBGERR(("Device failed REMOTE_NDIS_INITIALIZE_MSG with %xh.", status));
  243. }
  244. break;
  245. }
  246. }
  247. }
  248. else {
  249. RndisMSendComplete( (NDIS_HANDLE)adapter->rndisAdapterHandle,
  250. RndisMessageHandle,
  251. NDIS_STATUS_RESOURCES);
  252. }
  253. }
  254. else {
  255. DBGWARN(("RndisSendMessageHandler: throttling sends because only %d packets available for rcv ", USB_PACKET_POOL_SIZE-adapter->numActiveWritePackets));
  256. RndisMSendComplete( (NDIS_HANDLE)adapter->rndisAdapterHandle,
  257. RndisMessageHandle,
  258. NDIS_STATUS_RESOURCES);
  259. }
  260. }
  261. else {
  262. DBGERR(("GetSystemAddressForMdlSafe failed"));
  263. RndisMSendComplete( (NDIS_HANDLE)adapter->rndisAdapterHandle,
  264. RndisMessageHandle,
  265. NDIS_STATUS_INVALID_PACKET);
  266. }
  267. }
  268. else {
  269. DBGWARN(("RndisSendMessageHandler - failing send because adapter is resetting"));
  270. RndisMSendComplete( (NDIS_HANDLE)adapter->rndisAdapterHandle,
  271. RndisMessageHandle,
  272. NDIS_STATUS_MEDIA_BUSY);
  273. }
  274. }
  275. /*
  276. * RndisReturnMessageHandler
  277. *
  278. * This is the completion of a received packet indication call.
  279. */
  280. VOID RndisReturnMessageHandler( IN NDIS_HANDLE MicroportAdapterContext,
  281. IN PMDL pMessageMdl,
  282. IN NDIS_HANDLE MicroportMessageContext)
  283. {
  284. USBPACKET *packet;
  285. DBGVERBOSE(("RndisReturnMessageHandler: msgMdl=%ph, msg context = %ph.", pMessageMdl, MicroportMessageContext));
  286. ASSERT(MicroportMessageContext);
  287. packet = (USBPACKET *)MicroportMessageContext;
  288. ASSERT(packet->sig == DRIVER_SIG);
  289. #ifdef RAW_TEST
  290. {
  291. ADAPTEREXT * adapter = (ADAPTEREXT *)MicroportAdapterContext;
  292. if (adapter->rawTest) {
  293. if (packet->dataPacket) {
  294. UnskipRcvRndisPacketHeader(packet);
  295. }
  296. }
  297. }
  298. #endif // RAW_TEST
  299. /*
  300. * The receive indication is done.
  301. * Put our packet back in the free list.
  302. */
  303. DequeueCompletedReadPacket(packet);
  304. EnqueueFreePacket(packet);
  305. }
  306. BOOLEAN RegisterRNDISMicroport(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  307. {
  308. RNDIS_MICROPORT_CHARACTERISTICS rndisAttribs;
  309. NDIS_HANDLE ndisWrapperHandle;
  310. DBGVERBOSE(("RegisterRNDISMicroport"));
  311. RtlZeroMemory(&rndisAttribs, sizeof(rndisAttribs));
  312. rndisAttribs.RndisVersion = RNDIS_VERSION;
  313. rndisAttribs.Reserved = 0;
  314. rndisAttribs.RmInitializeHandler = RndisInitializeHandler;
  315. rndisAttribs.RmInitCompleteNotifyHandler = RndisInitCompleteNotify;
  316. rndisAttribs.RmHaltHandler = RndisHalt;
  317. rndisAttribs.RmShutdownHandler = RndisShutdown;
  318. rndisAttribs.RmSendMessageHandler = RndisSendMessageHandler;
  319. rndisAttribs.RmReturnMessageHandler = RndisReturnMessageHandler;
  320. RndisMInitializeWrapper( &ndisWrapperHandle,
  321. NULL,
  322. DriverObject,
  323. RegistryPath,
  324. &rndisAttribs);
  325. return TRUE;
  326. }
  327. VOID IndicateSendStatusToRNdis(USBPACKET *packet, NTSTATUS status)
  328. {
  329. #ifdef RAW_TEST
  330. ADAPTEREXT *adapter = packet->adapter;
  331. if (adapter->rawTest && packet->dataPacket) {
  332. FreeDataHeader(packet);
  333. }
  334. #endif /? RAW_TEST
  335. packet->ndisSendPktMdl = NULL;
  336. ASSERT(packet->rndisMessageHandle);
  337. RndisMSendComplete( (NDIS_HANDLE)packet->adapter->rndisAdapterHandle,
  338. (NDIS_HANDLE)packet->rndisMessageHandle,
  339. (NDIS_STATUS)status);
  340. }
  341. VOID RNDISProcessNotification(ADAPTEREXT *adapter)
  342. {
  343. UCHAR notification = *(PUCHAR)adapter->notifyBuffer;
  344. UCHAR notificationCode = *((PUCHAR)adapter->notifyBuffer + 1);
  345. if ((notification == NATIVE_RNDIS_RESPONSE_AVAILABLE) ||
  346. ((notification == CDC_RNDIS_NOTIFICATION) &&
  347. (notificationCode == CDC_RNDIS_RESPONSE_AVAILABLE)))
  348. {
  349. /*
  350. * Try to read a native RNDIS encapsulated command from the control pipe.
  351. */
  352. DBGVERBOSE(("NativeRNDISProcessNotification: NATIVE_RNDIS_RESPONSE_AVAILABLE"));
  353. {
  354. USBPACKET *packet = DequeueFreePacket(adapter);
  355. if (packet){
  356. EnqueuePendingReadPacket(packet);
  357. ReadPacketFromControlPipe(packet, FALSE);
  358. }
  359. else {
  360. DBGWARN(("couldn't get free packet in NativeRNDISProcessNotification"));
  361. }
  362. }
  363. }
  364. else {
  365. DBGERR(("NativeRNDISProcessNotification: unknown notification %xh.", notification));
  366. }
  367. }
  368. NTSTATUS IndicateRndisMessage( IN USBPACKET *packet,
  369. IN BOOLEAN bIsData)
  370. {
  371. ADAPTEREXT *adapter = packet->adapter;
  372. PRNDIS_MESSAGE rndisMsg = (PRNDIS_MESSAGE)packet->dataBuffer;
  373. NDIS_STATUS rcvStat;
  374. ASSERT(packet->dataBufferCurrentLength <= packet->dataBufferMaxLength);
  375. /*
  376. * Indicate the packet to RNDIS, and pass a pointer to our usb packet
  377. * as the MicroportMessageContext.
  378. * The packet/message will be returned to us via RndisReturnMessageHandler.
  379. */
  380. MyInitializeMdl(packet->dataBufferMdl, packet->dataBuffer, packet->dataBufferCurrentLength);
  381. if (adapter->numFreePackets < USB_PACKET_POOL_SIZE/8){
  382. rcvStat = NDIS_STATUS_RESOURCES;
  383. }
  384. else {
  385. rcvStat = NDIS_STATUS_SUCCESS;
  386. }
  387. #ifdef RAW_TEST
  388. if (adapter->rawTest) {
  389. packet->dataPacket = bIsData;
  390. if (bIsData) {
  391. SkipRcvRndisPacketHeader(packet);
  392. }
  393. }
  394. #endif // RAW_TEST
  395. RndisMIndicateReceive( (NDIS_HANDLE)packet->adapter->rndisAdapterHandle,
  396. packet->dataBufferMdl,
  397. (NDIS_HANDLE)packet,
  398. (bIsData? RMC_DATA: RMC_CONTROL),
  399. rcvStat);
  400. return STATUS_PENDING;
  401. }
  402. #ifdef RAW_TEST
  403. //
  404. // Add an RNDIS_PACKET header to a sent "raw" encapsulated Ethernet frame.
  405. //
  406. PMDL AddDataHeader(IN PMDL pMessageMdl)
  407. {
  408. PMDL pHeaderMdl, pTmpMdl;
  409. PRNDIS_MESSAGE pRndisMessage;
  410. PRNDIS_PACKET pRndisPacket;
  411. ULONG TotalLength;
  412. //
  413. // Compute the total length.
  414. //
  415. TotalLength = 0;
  416. for (pTmpMdl = pMessageMdl; pTmpMdl != NULL; pTmpMdl = pTmpMdl->Next)
  417. {
  418. TotalLength += MmGetMdlByteCount(pTmpMdl);
  419. }
  420. //
  421. // Allocate an RNDIS packet header:
  422. //
  423. pRndisMessage = AllocPool(RNDIS_MESSAGE_SIZE(RNDIS_PACKET));
  424. if (pRndisMessage != NULL) {
  425. pHeaderMdl = IoAllocateMdl(pRndisMessage,
  426. RNDIS_MESSAGE_SIZE(RNDIS_PACKET),
  427. FALSE,
  428. FALSE,
  429. NULL);
  430. if (pHeaderMdl != NULL) {
  431. MmBuildMdlForNonPagedPool(pHeaderMdl);
  432. //
  433. // Fill in the RNDIS message generic header:
  434. //
  435. pRndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
  436. pRndisMessage->MessageLength = RNDIS_MESSAGE_SIZE(RNDIS_PACKET) + TotalLength;
  437. //
  438. // Fill in the RNDIS_PACKET structure:
  439. //
  440. pRndisPacket = (PRNDIS_PACKET)&pRndisMessage->Message;
  441. pRndisPacket->DataOffset = sizeof(RNDIS_PACKET);
  442. pRndisPacket->DataLength = TotalLength;
  443. pRndisPacket->OOBDataOffset = 0;
  444. pRndisPacket->OOBDataLength = 0;
  445. pRndisPacket->NumOOBDataElements = 0;
  446. pRndisPacket->PerPacketInfoOffset = 0;
  447. pRndisPacket->PerPacketInfoLength = 0;
  448. pRndisPacket->VcHandle = 0;
  449. pRndisPacket->Reserved = 0;
  450. //
  451. // Link it to the raw data frame:
  452. //
  453. pHeaderMdl->Next = pMessageMdl;
  454. }
  455. else {
  456. FreePool(pRndisMessage);
  457. pHeaderMdl = NULL;
  458. }
  459. }
  460. else {
  461. pHeaderMdl = NULL;
  462. }
  463. return (pHeaderMdl);
  464. }
  465. //
  466. // Remove an RNDIS_PACKET header that we had added to a raw encapsulated
  467. // Ethernet frame.
  468. //
  469. VOID FreeDataHeader(IN USBPACKET * packet)
  470. {
  471. PMDL pHeaderMdl;
  472. PRNDIS_MESSAGE pRndisMessage;
  473. ASSERT(packet->dataPacket == TRUE);
  474. //
  475. // Take out the MDL we had pre-pended
  476. //
  477. pHeaderMdl = packet->ndisSendPktMdl;
  478. packet->ndisSendPktMdl = pHeaderMdl->Next;
  479. //
  480. // Free the RNDIS_PACKET header:
  481. //
  482. pRndisMessage = MmGetMdlVirtualAddress(pHeaderMdl);
  483. FreePool(pRndisMessage);
  484. //
  485. // ... and the MDL itself.
  486. //
  487. IoFreeMdl(pHeaderMdl);
  488. }
  489. //
  490. // Modify a received message to skip the RNDIS_PACKET header
  491. // before indicating this up to RNDISMP, to test raw encapsulation.
  492. //
  493. VOID SkipRcvRndisPacketHeader(IN USBPACKET * packet)
  494. {
  495. PMDL pHeaderMdl;
  496. RNDIS_MESSAGE UNALIGNED * pRndisMessage;
  497. RNDIS_PACKET UNALIGNED * pRndisPacket;
  498. ULONG DataLength;
  499. ULONG DataOffset;
  500. //
  501. // Get some info from the received RNDIS_PACKET message.
  502. // Note that this may contain multiple data packets, in which
  503. // case we only pass up the first one.
  504. //
  505. pHeaderMdl = packet->dataBufferMdl;
  506. pRndisMessage = MmGetMdlVirtualAddress(pHeaderMdl);
  507. pRndisPacket = (RNDIS_PACKET UNALIGNED *)&pRndisMessage->Message;
  508. DataLength = pRndisPacket->DataLength;
  509. DataOffset = FIELD_OFFSET(RNDIS_MESSAGE, Message) + pRndisPacket->DataOffset;
  510. //
  511. // Save away some existing values to restore later.
  512. //
  513. packet->rcvDataOffset = DataOffset;
  514. packet->rcvByteCount = pHeaderMdl->ByteCount;
  515. //
  516. // This is ONLY for test purposes. Simply modify the MDL to reflect
  517. // a single "raw" encapsulated frame.
  518. //
  519. pHeaderMdl->ByteOffset += DataOffset;
  520. (ULONG_PTR)pHeaderMdl->MappedSystemVa += DataOffset;
  521. pHeaderMdl->ByteCount = DataLength;
  522. }
  523. //
  524. // Undo for the above function.
  525. //
  526. VOID UnskipRcvRndisPacketHeader(IN USBPACKET * packet)
  527. {
  528. PMDL pHeaderMdl;
  529. ASSERT(packet->dataPacket == TRUE);
  530. //
  531. // Undo everything we did in the SkipRcv... function.
  532. //
  533. pHeaderMdl = packet->dataBufferMdl;
  534. pHeaderMdl->ByteOffset -= packet->rcvDataOffset;
  535. (ULONG_PTR)pHeaderMdl->MappedSystemVa -= packet->rcvDataOffset;
  536. pHeaderMdl->ByteCount = packet->rcvByteCount;
  537. }
  538. #endif // RAW_TEST