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.

945 lines
26 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. tunmp.c
  5. Abstract:
  6. Microsoft Tunnel interface Miniport driver
  7. Environment:
  8. Kernel mode only.
  9. Revision History:
  10. alid 10/22/2001
  11. --*/
  12. #include "precomp.h"
  13. #define __FILENUMBER 'MUNT'
  14. NTSTATUS
  15. DriverEntry(
  16. IN PDRIVER_OBJECT DriverObject,
  17. IN PUNICODE_STRING RegistryPath
  18. )
  19. /*++
  20. Routine Description:
  21. Arguments:
  22. Return Value:
  23. --*/
  24. {
  25. NDIS_STATUS Status;
  26. NDIS_MINIPORT_CHARACTERISTICS MChars;
  27. NDIS_STRING Name;
  28. DEBUGP(DL_INFO, ("Tunmp: ==>DriverEntry\n"));
  29. //
  30. // Register the miniport with NDIS.
  31. //
  32. NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
  33. if (NdisWrapperHandle == NULL)
  34. {
  35. Status = NDIS_STATUS_FAILURE;
  36. return Status;
  37. }
  38. TUN_INIT_LOCK(&TunGlobalLock);
  39. TUN_INIT_LIST_HEAD(&TunAdapterList);
  40. TUN_ZERO_MEM(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
  41. MChars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
  42. MChars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
  43. MChars.InitializeHandler = TunMpInitialize;
  44. MChars.QueryInformationHandler = TunMpQueryInformation;
  45. MChars.SetInformationHandler = TunMpSetInformation;
  46. MChars.ResetHandler = NULL;
  47. MChars.ReturnPacketHandler = TunMpReturnPacket;
  48. MChars.SendPacketsHandler = TunMpSendPackets;
  49. MChars.HaltHandler = TunMpHalt;
  50. MChars.CheckForHangHandler = NULL;
  51. MChars.CancelSendPacketsHandler = NULL;
  52. MChars.PnPEventNotifyHandler = NULL;
  53. MChars.AdapterShutdownHandler = TunMpShutdown;
  54. Status = NdisMRegisterMiniport(NdisWrapperHandle,
  55. &MChars,
  56. sizeof(MChars));
  57. if (Status == NDIS_STATUS_SUCCESS)
  58. {
  59. NdisMRegisterUnloadHandler(NdisWrapperHandle, TunMpUnload);
  60. Status = TunCreateSD();
  61. }
  62. if(Status != NDIS_STATUS_SUCCESS)
  63. {
  64. NdisTerminateWrapper(NdisWrapperHandle, NULL);
  65. }
  66. DEBUGP(DL_INFO, ("Tunmp: <==DriverEntry Status %lx\n", Status));
  67. return(Status);
  68. }
  69. VOID
  70. TunMpUnload(
  71. IN PDRIVER_OBJECT DriverObject
  72. )
  73. {
  74. TunDeleteSD();
  75. return;
  76. }
  77. NDIS_STATUS
  78. TunMpInitialize(
  79. OUT PNDIS_STATUS OpenErrorStatus,
  80. OUT PUINT SelectedMediumIndex,
  81. IN PNDIS_MEDIUM MediumArray,
  82. IN UINT MediumArraySize,
  83. IN NDIS_HANDLE MiniportAdapterHandle,
  84. IN NDIS_HANDLE ConfigurationContext
  85. )
  86. /*++
  87. Routine Description:
  88. This is the initialize handler.
  89. Arguments:
  90. OpenErrorStatus Not used by us.
  91. SelectedMediumIndex Place-holder for what media we are using
  92. MediumArray Array of ndis media passed down to us to pick from
  93. MediumArraySize Size of the array
  94. MiniportAdapterHandle The handle NDIS uses to refer to us
  95. WrapperConfigurationContext For use by NdisOpenConfiguration
  96. Return Value:
  97. NDIS_STATUS_SUCCESS unless something goes wrong
  98. --*/
  99. {
  100. UINT i, Length;
  101. PTUN_ADAPTER pAdapter = NULL;
  102. NDIS_MEDIUM AdapterMedium;
  103. NDIS_HANDLE ConfigHandle = NULL;
  104. PNDIS_CONFIGURATION_PARAMETER Parameter;
  105. PUCHAR NetworkAddress;
  106. NDIS_STATUS Status;
  107. NDIS_STRING MiniportNameStr = NDIS_STRING_CONST("MiniportName");
  108. DEBUGP(DL_INFO, ("==>TunMpInitialize: MiniportAdapterHandle %p\n", MiniportAdapterHandle));
  109. do
  110. {
  111. TUN_ALLOC_MEM(pAdapter, sizeof(TUN_ADAPTER));
  112. if (pAdapter == NULL)
  113. {
  114. Status = NDIS_STATUS_RESOURCES;
  115. break;
  116. }
  117. TUN_ZERO_MEM(pAdapter, sizeof(TUN_ADAPTER));
  118. TUN_SET_SIGNATURE(pAdapter, mc);
  119. pAdapter->MiniportHandle = MiniportAdapterHandle;
  120. //1 no need to specify NDIS_ATTRIBUTE_IGNORE...
  121. NdisMSetAttributesEx(MiniportAdapterHandle,
  122. pAdapter,
  123. 0,
  124. NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS |
  125. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
  126. NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
  127. NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND |
  128. NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK |
  129. NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS |
  130. NDIS_ATTRIBUTE_DESERIALIZE,
  131. 0);
  132. NdisOpenConfiguration(&Status,
  133. &ConfigHandle,
  134. ConfigurationContext);
  135. if (Status != NDIS_STATUS_SUCCESS)
  136. {
  137. DEBUGP(DL_ERROR, ("TunMpInitialize: NdisOpenConfiguration failed. Status %lx\n", Status));
  138. break;
  139. }
  140. AdapterMedium = NdisMedium802_3; // Default
  141. TUN_COPY_MEM(pAdapter->PermanentAddress,
  142. TUN_CARD_ADDRESS,
  143. TUN_MAC_ADDR_LEN);
  144. TUN_COPY_MEM(pAdapter->CurrentAddress,
  145. TUN_CARD_ADDRESS,
  146. TUN_MAC_ADDR_LEN);
  147. pAdapter->Medium = AdapterMedium;
  148. pAdapter->MediumLinkSpeed = MediaParams[(UINT)AdapterMedium].LinkSpeed;
  149. pAdapter->MediumMinPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  150. pAdapter->MediumMaxPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen+
  151. MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  152. pAdapter->MediumMacHeaderLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  153. pAdapter->MediumMaxFrameLen = MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  154. pAdapter->MaxLookAhead = MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  155. //Get the software-configurable network address that was stored in the
  156. //registry when the adapter was installed in the machine.
  157. NdisReadNetworkAddress(&Status,
  158. &NetworkAddress,
  159. &Length,
  160. ConfigHandle);
  161. if (Status == NDIS_STATUS_SUCCESS)
  162. {
  163. #if TUN_ALLOW_ANY_MAC_ADDRESS
  164. if ((Length == ETH_LENGTH_OF_ADDRESS) &&
  165. (!ETH_IS_MULTICAST(NetworkAddress)))
  166. #else
  167. if ((Length == ETH_LENGTH_OF_ADDRESS) &&
  168. (!ETH_IS_MULTICAST(NetworkAddress)) &&
  169. (NetworkAddress[0] & 0x02))
  170. #endif
  171. {
  172. TUN_COPY_MEM(pAdapter->CurrentAddress,
  173. NetworkAddress,
  174. Length);
  175. }
  176. }
  177. //
  178. // read the miniport name
  179. //
  180. //1 make sure miniport name is really used
  181. NdisReadConfiguration(&Status,
  182. &Parameter,
  183. ConfigHandle,
  184. &MiniportNameStr,
  185. NdisParameterString);
  186. if (Status == NDIS_STATUS_SUCCESS)
  187. {
  188. TUN_ALLOC_MEM(pAdapter->MiniportName.Buffer,
  189. Parameter->ParameterData.StringData.Length);
  190. if (pAdapter->MiniportName.Buffer == NULL)
  191. {
  192. DEBUGP(DL_ERROR, ("TunMpInitialize: failed to allocate memory for miniport name.\n"));
  193. Status = NDIS_STATUS_RESOURCES;
  194. break;
  195. }
  196. pAdapter->MiniportName.Length = pAdapter->MiniportName.MaximumLength =
  197. Parameter->ParameterData.StringData.Length;
  198. TUN_COPY_MEM(pAdapter->MiniportName.Buffer,
  199. Parameter->ParameterData.StringData.Buffer,
  200. Parameter->ParameterData.StringData.Length);
  201. }
  202. else
  203. {
  204. DEBUGP(DL_ERROR, ("TunMpInitialize: NdisReadConfiguration failed to read miniport name. Status %lx\n", Status));
  205. break;
  206. }
  207. NdisCloseConfiguration(ConfigHandle);
  208. ConfigHandle = NULL;
  209. //
  210. //Make sure the medium saved is one of the ones being offered
  211. //
  212. for (i = 0; i < MediumArraySize; i++)
  213. {
  214. if (MediumArray[i] == AdapterMedium)
  215. {
  216. *SelectedMediumIndex = i;
  217. break;
  218. }
  219. }
  220. if (i == MediumArraySize)
  221. {
  222. Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  223. DEBUGP(DL_ERROR, ("TunMpInitialize: Status %lx, AdapterMedium %lx\n",
  224. Status, AdapterMedium));
  225. break;
  226. }
  227. Status = TunMpCreateDevice(pAdapter);
  228. if (Status != NDIS_STATUS_SUCCESS)
  229. {
  230. DEBUGP(DL_ERROR, ("TunMpInitialize: TunMpCreateDevice failed. Status %lx\n",
  231. Status));
  232. break;
  233. }
  234. pAdapter->RefCount = 1;
  235. //Initialize the adapter spin lock
  236. TUN_INIT_LOCK(&pAdapter->Lock);
  237. //
  238. //Get the list heads for the pended read/write IRPS and received
  239. //packets (from the NDIS) initialized
  240. //
  241. InitializeListHead(&pAdapter->PendedReads); //read IRPs
  242. InitializeListHead(&pAdapter->PendedWrites); //writes IRPs
  243. InitializeListHead(&pAdapter->RecvPktQueue); //received packets
  244. NdisAllocatePacketPoolEx(&Status,
  245. &pAdapter->SendPacketPool,
  246. MIN_SEND_PACKET_POOL_SIZE,
  247. MAX_SEND_PACKET_POOL_SIZE
  248. - MIN_SEND_PACKET_POOL_SIZE,
  249. 4 * sizeof(PVOID)
  250. );
  251. if (Status != NDIS_STATUS_SUCCESS)
  252. {
  253. DEBUGP(DL_ERROR, ("TunMpInitialize: NdisAllocatePacketPoolEx for Send failed. Status %lx\n",
  254. Status));
  255. break;
  256. }
  257. //
  258. //Get the adapter listed in the tun global list of adapters
  259. //
  260. TUN_ACQUIRE_LOCK(&TunGlobalLock);
  261. TUN_INSERT_HEAD_LIST(&TunAdapterList, &pAdapter->Link);
  262. TUN_RELEASE_LOCK(&TunGlobalLock);
  263. } while (FALSE);
  264. if (Status != NDIS_STATUS_SUCCESS)
  265. {
  266. if (pAdapter != NULL)
  267. {
  268. if (ConfigHandle)
  269. {
  270. NdisCloseConfiguration(ConfigHandle);
  271. }
  272. if (pAdapter->NdisDeviceHandle)
  273. {
  274. NdisMDeregisterDevice(pAdapter->NdisDeviceHandle);
  275. }
  276. if (pAdapter->SendPacketPool)
  277. {
  278. NdisFreePacketPool(pAdapter->SendPacketPool);
  279. }
  280. TUN_FREE_MEM(pAdapter);
  281. }
  282. }
  283. DEBUGP(DL_INFO, ("<==TunMpInitialize: MiniportAdapterHandle %p, Status\n",
  284. MiniportAdapterHandle, Status));
  285. return Status;
  286. }
  287. NDIS_STATUS
  288. TunMpCreateDevice(
  289. IN PTUN_ADAPTER pAdapter
  290. )
  291. {
  292. LONG DeviceInstanceNumber;
  293. UNICODE_STRING usDeviceID;
  294. WCHAR TempBuffer[4] = {0};
  295. WCHAR DeviceNameBuffer[sizeof(DEVICE_NAME)+4] = {0};
  296. WCHAR SymbolicNameBuffer[sizeof(SYMBOLIC_NAME)+4] = {0};
  297. UNICODE_STRING DeviceName, SymbolicName;
  298. PDRIVER_DISPATCH MajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1];
  299. NTSTATUS NtStatus;
  300. NDIS_STATUS Status;
  301. UINT i;
  302. PDEVICE_OBJECT DeviceObject = NULL;
  303. NDIS_HANDLE NdisDeviceHandle = NULL;
  304. DEBUGP(DL_INFO, ("==>TunMpCreateDevice, pAdapter %p\n", pAdapter));
  305. do
  306. {
  307. DeviceInstanceNumber = InterlockedIncrement(&GlobalDeviceInstanceNumber);
  308. //
  309. // for the time being, allow one device only
  310. //
  311. if (DeviceInstanceNumber > 0)
  312. {
  313. Status = NDIS_STATUS_RESOURCES;
  314. break;
  315. }
  316. pAdapter->DeviceInstanceNumber = (ULONG)DeviceInstanceNumber;
  317. //
  318. //Initiallize a unicode string
  319. //
  320. usDeviceID.Buffer = TempBuffer;
  321. usDeviceID.Length = 0;
  322. usDeviceID.MaximumLength = sizeof(TempBuffer);
  323. NtStatus = RtlIntegerToUnicodeString ((ULONG)DeviceInstanceNumber, 10, &usDeviceID);
  324. if (!NT_SUCCESS(NtStatus))
  325. {
  326. //1 GlobalDeviceInstanceNumber is not protected properly
  327. InterlockedDecrement(&GlobalDeviceInstanceNumber);
  328. Status = NDIS_STATUS_RESOURCES;
  329. DEBUGP(DL_ERROR, ("TunMpCreateDevice: RtlIntegerToUnicodeString failed. NtStatus %lx\n",
  330. NtStatus));
  331. break;
  332. }
  333. wcscpy(DeviceNameBuffer, DEVICE_NAME);
  334. RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
  335. RtlAppendUnicodeStringToString(&DeviceName, &usDeviceID);
  336. wcscpy(SymbolicNameBuffer, SYMBOLIC_NAME);
  337. RtlInitUnicodeString(&SymbolicName, SymbolicNameBuffer);
  338. RtlAppendUnicodeStringToString(&SymbolicName, &usDeviceID);
  339. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
  340. {
  341. MajorFunctions[i] = NULL;
  342. }
  343. MajorFunctions[IRP_MJ_CREATE] = TunFOpen;
  344. MajorFunctions[IRP_MJ_CLOSE] = TunFClose;
  345. MajorFunctions[IRP_MJ_READ] = TunRead;
  346. MajorFunctions[IRP_MJ_WRITE] = TunWrite;
  347. MajorFunctions[IRP_MJ_CLEANUP] = TunFCleanup;
  348. MajorFunctions[IRP_MJ_DEVICE_CONTROL] = TunFIoControl;
  349. Status = NdisMRegisterDevice(
  350. NdisWrapperHandle,
  351. &DeviceName,
  352. &SymbolicName,
  353. MajorFunctions,
  354. &DeviceObject,
  355. &NdisDeviceHandle
  356. );
  357. if (Status != NDIS_STATUS_SUCCESS)
  358. {
  359. DEBUGP(DL_ERROR, ("TunMpCreateDevice: NdisMRegisterDevice failed. Status %lx\n",
  360. Status));
  361. InterlockedDecrement(&GlobalDeviceInstanceNumber);
  362. break;
  363. }
  364. DeviceObject->Flags |= DO_DIRECT_IO;
  365. pAdapter->DeviceObject = DeviceObject;
  366. pAdapter->NdisDeviceHandle = NdisDeviceHandle;
  367. Status = TunSetSecurity(DeviceObject);
  368. if (!NT_SUCCESS(Status))
  369. {
  370. NdisMDeregisterDevice(NdisDeviceHandle);
  371. pAdapter->NdisDeviceHandle = NULL;
  372. }
  373. }while (FALSE);
  374. DEBUGP(DL_INFO, ("<==TunMpCreateDevice, pAdapter %p, Status %lx\n", pAdapter, Status));
  375. return Status;
  376. }
  377. VOID
  378. TunMpHalt(
  379. IN NDIS_HANDLE MiniportAdapterContext
  380. )
  381. /*++
  382. Routine Description:
  383. Halt handler. It frees the adapter object and corresponding device object.
  384. Arguments:
  385. MiniportAdapterContext Pointer to the Adapter
  386. Return Value:
  387. None.
  388. --*/
  389. {
  390. PTUN_ADAPTER pAdapter = (PTUN_ADAPTER)MiniportAdapterContext;
  391. NDIS_EVENT HaltReadyEvent;
  392. DEBUGP(DL_INFO, ("==>TunMpHalt, pAdapter %p\n", pAdapter));
  393. NdisInitializeEvent(&HaltReadyEvent);
  394. //
  395. // let's wait for the app to close all the handles
  396. //
  397. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  398. if (TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_CANT_HALT))
  399. {
  400. pAdapter->HaltEvent = &HaltReadyEvent;
  401. }
  402. TUN_RELEASE_LOCK(&pAdapter->Lock);
  403. if (pAdapter->HaltEvent)
  404. {
  405. NdisWaitEvent(pAdapter->HaltEvent, 0);
  406. }
  407. pAdapter->HaltEvent = 0;
  408. //
  409. // we should not have any pending NDIS sends
  410. //
  411. ASSERT(pAdapter->PendedReadCount == 0);
  412. //
  413. // Free the resources now
  414. //
  415. if (pAdapter->NdisDeviceHandle)
  416. {
  417. NdisMDeregisterDevice(pAdapter->NdisDeviceHandle);
  418. }
  419. InterlockedDecrement(&GlobalDeviceInstanceNumber);
  420. if (pAdapter->SendPacketPool)
  421. {
  422. NdisFreePacketPool(pAdapter->SendPacketPool);
  423. }
  424. //
  425. // remove it from the global queue
  426. //
  427. TUN_ACQUIRE_LOCK(&TunGlobalLock);
  428. TUN_REMOVE_ENTRY_LIST(&pAdapter->Link);
  429. TUN_RELEASE_LOCK(&TunGlobalLock);
  430. TUN_FREE_MEM(pAdapter);
  431. DEBUGP(DL_INFO, ("<==TunMpHalt, pAdapter %p\n", pAdapter));
  432. }
  433. VOID
  434. TunMpShutdown(
  435. IN NDIS_HANDLE MiniportAdapterContext
  436. )
  437. {
  438. DEBUGP(DL_INFO, ("==>TunMpShutdown, pAdapter %p\n", MiniportAdapterContext));
  439. //
  440. // nothing to do here
  441. //
  442. DEBUGP(DL_INFO, ("<==TunMpShutdown, pAdapter %p\n", MiniportAdapterContext));
  443. }
  444. VOID
  445. TunMpSendPackets(
  446. IN NDIS_HANDLE MiniportAdapterContext,
  447. IN PPNDIS_PACKET PacketArray,
  448. IN UINT NumberOfPackets
  449. )
  450. /*++
  451. Routine Description:
  452. Send packets handler. Just queues packets in the list of pended received packets.
  453. And then calls TunServiceReads to process packets.
  454. Arguments:
  455. MiniportAdapterContext Pointer to the adapter
  456. Packet Packet to send
  457. Flags Unused, passed down below
  458. Return Value:
  459. Return code from NdisSend
  460. --*/
  461. {
  462. PTUN_ADAPTER pAdapter = (PTUN_ADAPTER)MiniportAdapterContext;
  463. NDIS_STATUS NdisStatus;
  464. UINT Index;
  465. UINT BytesToSend;
  466. PLIST_ENTRY pRcvPacketEntry;
  467. PNDIS_PACKET pOldRcvPacket;
  468. DEBUGP(DL_LOUD, ("==>TunMpSendPackets, pAdapter %p, PacketArray %p, NumberOfPackets\n",
  469. MiniportAdapterContext, PacketArray, NumberOfPackets));
  470. TUN_REF_ADAPTER(pAdapter); // queued rcv packet
  471. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  472. if ((!TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_OPEN)) ||
  473. TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_OFF))
  474. {
  475. pAdapter->XmitError += NumberOfPackets;
  476. TUN_RELEASE_LOCK(&pAdapter->Lock);
  477. if (!TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_OPEN))
  478. {
  479. DEBUGP(DL_WARN, ("TunMpSendPackets, pAdapter %p, Adapter not open\n",
  480. pAdapter));
  481. NdisStatus = NDIS_STATUS_NO_CABLE;
  482. }
  483. else
  484. {
  485. DEBUGP(DL_WARN, ("TunMpSendPackets, pAdapter %p, Adapter off.\n",
  486. pAdapter));
  487. NdisStatus = NDIS_STATUS_ADAPTER_NOT_READY;
  488. }
  489. for(Index = 0; Index < NumberOfPackets; Index++)
  490. {
  491. NDIS_SET_PACKET_STATUS(PacketArray[Index], NdisStatus);
  492. NdisMSendComplete(pAdapter->MiniportHandle,
  493. PacketArray[Index],
  494. NdisStatus);
  495. }
  496. TUN_DEREF_ADAPTER(pAdapter);
  497. DEBUGP(DL_LOUD, ("<==TunMpSendPackets, pAdapter %p\n",
  498. MiniportAdapterContext));
  499. return;
  500. }
  501. for(Index = 0; Index < NumberOfPackets; Index++)
  502. {
  503. NdisQueryPacket(PacketArray[Index], NULL, NULL, NULL, &BytesToSend);
  504. //
  505. //if the packet size is invalid or no data buffer associated with it,
  506. //inform NDIS about the invalidity
  507. //
  508. if ((BytesToSend == 0) || (BytesToSend > pAdapter->MediumMaxPacketLen))
  509. {
  510. NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_FAILURE);
  511. pAdapter->XmitError++;
  512. TUN_RELEASE_LOCK(&pAdapter->Lock);
  513. NdisMSendComplete(pAdapter->MiniportHandle,
  514. PacketArray[Index],
  515. NDIS_STATUS_FAILURE);
  516. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  517. continue;
  518. }
  519. //
  520. //if there are already MAX_PEND packets in miniport's pended packet queue,
  521. // refuse the new ones with NDIS_STATUS_RESOURCES
  522. //
  523. else if(pAdapter->RecvPktCount >= MAX_RECV_QUEUE_SIZE)
  524. {
  525. pAdapter->XmitError += NumberOfPackets - Index;
  526. pAdapter->XmitErrorNoReadIrps += NumberOfPackets - Index;
  527. TUN_RELEASE_LOCK(&pAdapter->Lock);
  528. for (;Index < NumberOfPackets; Index++)
  529. {
  530. NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_RESOURCES);
  531. NdisMSendComplete(pAdapter->MiniportHandle,
  532. PacketArray[Index],
  533. NDIS_STATUS_RESOURCES);
  534. }
  535. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  536. break;
  537. }
  538. //
  539. //queue the new packet, and set the packet status to pending
  540. //
  541. TUN_INSERT_TAIL_LIST(&pAdapter->RecvPktQueue, TUN_RCV_PKT_TO_LIST_ENTRY(PacketArray[Index]));
  542. //need to make sure the packet pointer in this statement
  543. pAdapter->RecvPktCount++;
  544. TUN_REF_ADAPTER(pAdapter); // pended send
  545. NDIS_SET_PACKET_STATUS(PacketArray[Index], NDIS_STATUS_PENDING);
  546. }
  547. TUN_RELEASE_LOCK(&pAdapter->Lock);
  548. //
  549. // Run the receive queue service routine now.
  550. //
  551. TunServiceReads(pAdapter);
  552. TUN_DEREF_ADAPTER(pAdapter);
  553. DEBUGP(DL_LOUD, ("<==TunMpSendPackets, pAdapter %p\n",
  554. MiniportAdapterContext));
  555. return;
  556. }
  557. VOID
  558. TunMpReturnPacket(
  559. IN NDIS_HANDLE MiniportAdapterContext,
  560. IN PNDIS_PACKET NdisPacket
  561. )
  562. /*++
  563. Routine Description:
  564. NDIS entry point called to signify completion of a packet send.
  565. We pick up and complete the Write IRP corresponding to this packet.
  566. NDIS 5.1:
  567. Arguments:
  568. ProtocolBindingContext - pointer to open context
  569. pNdisPacket - packet that completed send
  570. Status - status of send
  571. Return Value:
  572. None
  573. --*/
  574. {
  575. PIRP pIrp;
  576. PIO_STACK_LOCATION pIrpSp;
  577. PTUN_ADAPTER pAdapter;
  578. pAdapter = (PTUN_ADAPTER)MiniportAdapterContext;
  579. DEBUGP(DL_LOUD, ("==>TunMpReturnPacket, pAdapter %p\n",
  580. pAdapter));
  581. //1 get rid of this
  582. TUN_STRUCT_ASSERT(pAdapter, mc);
  583. pIrp = TUN_IRP_FROM_SEND_PKT(NdisPacket);
  584. //
  585. // We are done with the NDIS_PACKET:
  586. //
  587. TUN_DEREF_SEND_PKT(NdisPacket);
  588. //
  589. // Complete the Write IRP with the right status.
  590. //
  591. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  592. pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
  593. pIrp->IoStatus.Status = STATUS_SUCCESS;
  594. DEBUGP(DL_VERY_LOUD, ("SendComplete: packet %p/IRP %p/Length %d "
  595. "completed with status %x\n",
  596. NdisPacket, pIrp, pIrp->IoStatus.Information, pIrp->IoStatus.Status));
  597. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  598. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  599. pAdapter->PendedSendCount--;
  600. pAdapter->RcvPackets++;
  601. if ((!TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_ACTIVE)) &&
  602. (pAdapter->PendedSendCount == 0) &&
  603. (TUN_TEST_FLAG(pAdapter, TUN_COMPLETE_REQUEST)) &&
  604. ((!TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_OFF)) ||
  605. (pAdapter->PendedReadCount == 0)))
  606. {
  607. TUN_CLEAR_FLAG(pAdapter, TUN_COMPLETE_REQUEST);
  608. TUN_RELEASE_LOCK(&pAdapter->Lock);
  609. NdisMSetInformationComplete(&pAdapter->MiniportHandle,
  610. NDIS_STATUS_SUCCESS);
  611. }
  612. else
  613. {
  614. TUN_RELEASE_LOCK(&pAdapter->Lock);
  615. }
  616. TUN_DEREF_ADAPTER(pAdapter); // send complete - dequeued send IRP
  617. DEBUGP(DL_LOUD, ("<==TunMpReturnPacket, pAdapter %p\n",
  618. pAdapter));
  619. }
  620. VOID
  621. TunMpRefAdapter(
  622. IN PTUN_ADAPTER pAdapter
  623. )
  624. /*++
  625. Routine Description:
  626. Reference the given open context.
  627. NOTE: Can be called with or without holding the opencontext lock.
  628. Arguments:
  629. pOpenContext - pointer to open context
  630. Return Value:
  631. None
  632. --*/
  633. {
  634. NdisInterlockedIncrement(&pAdapter->RefCount);
  635. }
  636. VOID
  637. TunMpDerefAdapter(
  638. IN PTUN_ADAPTER pAdapter
  639. )
  640. /*++
  641. Routine Description:
  642. Dereference the given open context. If the ref count goes to zero,
  643. free it.
  644. NOTE: called without holding the opencontext lock
  645. Arguments:
  646. pAdapter - pointer to open context
  647. Return Value:
  648. None
  649. --*/
  650. {
  651. //1 how do we protect against ref count going to zero and back up again?
  652. if (NdisInterlockedDecrement(&pAdapter->RefCount) == 0)
  653. {
  654. DEBUGP(DL_INFO, ("DerefAdapter: Adapter %p, Flags %x, ref count is zero!\n",
  655. pAdapter, pAdapter->Flags));
  656. TUN_ASSERT(pAdapter->MiniportHandle == NULL);
  657. TUN_ASSERT(pAdapter->RefCount == 0);
  658. TUN_ASSERT(pAdapter->pFileObject == NULL);
  659. pAdapter->mc_sig++;
  660. //
  661. // Free it.
  662. //
  663. TUN_FREE_MEM(pAdapter);
  664. }
  665. }
  666. #if DBG
  667. VOID
  668. TunMpDbgRefAdapter(
  669. IN PTUN_ADAPTER pAdapter,
  670. IN ULONG FileNumber,
  671. IN ULONG LineNumber
  672. )
  673. {
  674. DEBUGP(DL_VERY_LOUD, (" RefAdapter: Adapter %p, old ref %d, File %c%c%c%c, line %d\n",
  675. pAdapter,
  676. pAdapter->RefCount,
  677. (CHAR)(FileNumber),
  678. (CHAR)(FileNumber >> 8),
  679. (CHAR)(FileNumber >> 16),
  680. (CHAR)(FileNumber >> 24),
  681. LineNumber));
  682. TunMpRefAdapter(pAdapter);
  683. }
  684. VOID
  685. TunMpDbgDerefAdapter(
  686. IN PTUN_ADAPTER pAdapter,
  687. IN ULONG FileNumber,
  688. IN ULONG LineNumber
  689. )
  690. {
  691. DEBUGP(DL_VERY_LOUD, ("DerefAdapter: Adapter %p, old ref %d, File %c%c%c%c, line %d\n",
  692. pAdapter,
  693. pAdapter->RefCount,
  694. (CHAR)(FileNumber),
  695. (CHAR)(FileNumber >> 8),
  696. (CHAR)(FileNumber >> 16),
  697. (CHAR)(FileNumber >> 24),
  698. LineNumber));
  699. TunMpDerefAdapter(pAdapter);
  700. }
  701. #endif // DBG