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.

535 lines
15 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. send.c
  5. Abstract:
  6. NDIS entry points to handle requests.
  7. Environment:
  8. Kernel mode only.
  9. Revision History:
  10. alid 10/22/2001 modified for tunmp
  11. arvindm 4/10/2000 Created
  12. --*/
  13. #include "precomp.h"
  14. #define __FILENUMBER 'TQER'
  15. NDIS_OID TunMpSupportedOidArray[] =
  16. {
  17. OID_GEN_SUPPORTED_LIST,
  18. OID_GEN_HARDWARE_STATUS,
  19. OID_GEN_MEDIA_SUPPORTED,
  20. OID_GEN_MEDIA_IN_USE,
  21. OID_GEN_MAXIMUM_LOOKAHEAD,
  22. OID_GEN_MAXIMUM_FRAME_SIZE,
  23. OID_GEN_MAC_OPTIONS,
  24. OID_GEN_LINK_SPEED,
  25. OID_GEN_TRANSMIT_BUFFER_SPACE,
  26. OID_GEN_RECEIVE_BUFFER_SPACE,
  27. OID_GEN_TRANSMIT_BLOCK_SIZE,
  28. OID_GEN_RECEIVE_BLOCK_SIZE,
  29. OID_GEN_VENDOR_ID,
  30. OID_GEN_VENDOR_DESCRIPTION,
  31. OID_GEN_CURRENT_PACKET_FILTER,
  32. OID_GEN_CURRENT_LOOKAHEAD,
  33. OID_GEN_DRIVER_VERSION,
  34. OID_GEN_MAXIMUM_TOTAL_SIZE,
  35. OID_GEN_MEDIA_CONNECT_STATUS,
  36. OID_GEN_MAXIMUM_SEND_PACKETS,
  37. OID_PNP_CAPABILITIES,
  38. OID_PNP_SET_POWER,
  39. OID_PNP_QUERY_POWER,
  40. OID_GEN_XMIT_OK,
  41. OID_GEN_RCV_OK,
  42. OID_GEN_XMIT_ERROR,
  43. OID_GEN_RCV_ERROR,
  44. OID_GEN_RCV_NO_BUFFER,
  45. OID_802_3_PERMANENT_ADDRESS,
  46. OID_802_3_CURRENT_ADDRESS,
  47. OID_802_3_MULTICAST_LIST,
  48. OID_802_3_MAXIMUM_LIST_SIZE,
  49. OID_802_3_RCV_ERROR_ALIGNMENT,
  50. OID_802_3_XMIT_ONE_COLLISION,
  51. OID_802_3_XMIT_MORE_COLLISIONS,
  52. OID_CUSTOM_TUNMP_INSTANCE_ID
  53. };
  54. UINT TunMpSupportedOids = sizeof(TunMpSupportedOidArray)/sizeof(NDIS_OID);
  55. UCHAR TunMpVendorDescription[] = "MS Tunnel Interface Driver";
  56. UCHAR TunMpVendorId[3] = {0xFF, 0xFF, 0xFF};
  57. NDIS_PNP_CAPABILITIES Power_Management_Capabilities = { 0,
  58. NdisDeviceStateUnspecified,
  59. NdisDeviceStateUnspecified,
  60. NdisDeviceStateUnspecified
  61. };
  62. NDIS_STATUS
  63. TunMpQueryInformation(
  64. IN NDIS_HANDLE MiniportAdapterContext,
  65. IN NDIS_OID Oid,
  66. IN PVOID InformationBuffer,
  67. IN ULONG InformationBufferLength,
  68. OUT PULONG BytesWritten,
  69. OUT PULONG BytesNeeded
  70. )
  71. /*++
  72. Routine Description:
  73. Miniport QueryInfo handler.
  74. Arguments:
  75. MiniportAdapterContext Pointer to the adapter structure
  76. Oid Oid for this query
  77. InformationBuffer Buffer for information
  78. InformationBufferLength Size of this buffer
  79. BytesWritten Specifies how much info is written
  80. BytesNeeded In case the buffer is smaller than what
  81. we need, tell them how much is needed
  82. Return Value:
  83. Return code from the NdisRequest below.
  84. --*/
  85. {
  86. PTUN_ADAPTER pAdapter = (PTUN_ADAPTER)MiniportAdapterContext;
  87. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  88. UINT i;
  89. NDIS_OID MaskOid;
  90. PVOID SourceBuffer;
  91. UINT SourceBufferLength;
  92. ULONG GenericUlong = 0;
  93. USHORT GenericUshort;
  94. DEBUGP(DL_LOUD, ("==>TunMpQueryInformation: Adapter %p, Oid %lx\n",
  95. pAdapter, Oid));
  96. *BytesWritten = 0;
  97. *BytesNeeded = 0;
  98. //
  99. // Initialize these once, since this is the majority of cases.
  100. //
  101. SourceBuffer = (PVOID)&GenericUlong;
  102. SourceBufferLength = sizeof(ULONG);
  103. switch (Oid)
  104. {
  105. case OID_GEN_MAC_OPTIONS:
  106. GenericUlong = (ULONG)(NDIS_MAC_OPTION_NO_LOOPBACK);
  107. break;
  108. case OID_GEN_SUPPORTED_LIST:
  109. (NDIS_OID*)SourceBuffer = TunMpSupportedOidArray;
  110. SourceBufferLength = TunMpSupportedOids * sizeof(ULONG);
  111. break;
  112. case OID_GEN_HARDWARE_STATUS:
  113. GenericUlong = NdisHardwareStatusReady;
  114. break;
  115. case OID_GEN_MEDIA_SUPPORTED:
  116. case OID_GEN_MEDIA_IN_USE:
  117. GenericUlong = pAdapter->Medium;
  118. break;
  119. case OID_GEN_MAXIMUM_LOOKAHEAD:
  120. GenericUlong = pAdapter->MaxLookAhead;
  121. break;
  122. case OID_GEN_MAXIMUM_FRAME_SIZE:
  123. GenericUlong = pAdapter->MediumMaxFrameLen;
  124. break;
  125. case OID_GEN_LINK_SPEED:
  126. GenericUlong = pAdapter->MediumLinkSpeed;
  127. break;
  128. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  129. GenericUlong = (pAdapter->MediumMaxPacketLen);
  130. break;
  131. case OID_GEN_RECEIVE_BUFFER_SPACE:
  132. GenericUlong = (pAdapter->MediumMaxPacketLen);
  133. break;
  134. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  135. GenericUlong = 1;
  136. break;
  137. case OID_GEN_RECEIVE_BLOCK_SIZE:
  138. GenericUlong = 1;
  139. break;
  140. case OID_GEN_VENDOR_ID:
  141. SourceBuffer = TunMpVendorId;
  142. SourceBufferLength = sizeof(TunMpVendorId);
  143. break;
  144. case OID_GEN_VENDOR_DESCRIPTION:
  145. SourceBuffer = TunMpVendorDescription;
  146. SourceBufferLength = sizeof(TunMpVendorDescription);
  147. break;
  148. case OID_GEN_CURRENT_PACKET_FILTER:
  149. GenericUlong = pAdapter->PacketFilter;
  150. break;
  151. case OID_GEN_CURRENT_LOOKAHEAD:
  152. GenericUlong = pAdapter->MaxLookAhead;
  153. break;
  154. case OID_GEN_DRIVER_VERSION:
  155. GenericUshort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
  156. SourceBuffer = &GenericUshort;
  157. SourceBufferLength = sizeof(USHORT);
  158. break;
  159. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  160. GenericUlong = pAdapter->MediumMaxPacketLen;
  161. break;
  162. case OID_GEN_MEDIA_CONNECT_STATUS:
  163. KdPrint(("OID_GEN_MEDIA_CONNECT_STATUS: %lx\n", Oid));
  164. if(TUN_TEST_FLAG(pAdapter, TUN_ADAPTER_OPEN))
  165. GenericUlong = NdisMediaStateConnected;
  166. else
  167. GenericUlong = NdisMediaStateDisconnected;
  168. break;
  169. case OID_GEN_MAXIMUM_SEND_PACKETS:
  170. GenericUlong = MAX_RECV_QUEUE_SIZE;
  171. break;
  172. case OID_GEN_XMIT_OK:
  173. SourceBuffer = &(pAdapter->SendPackets);
  174. SourceBufferLength = sizeof(ULONG);
  175. break;
  176. case OID_GEN_RCV_OK:
  177. SourceBuffer = &(pAdapter->RcvPackets);
  178. SourceBufferLength = sizeof(ULONG);
  179. break;
  180. case OID_GEN_XMIT_ERROR:
  181. SourceBuffer = &(pAdapter->XmitError);
  182. SourceBufferLength = sizeof(ULONG);
  183. break;
  184. case OID_GEN_RCV_ERROR:
  185. SourceBuffer = &(pAdapter->RcvError);
  186. SourceBufferLength = sizeof(ULONG);
  187. break;
  188. case OID_GEN_RCV_NO_BUFFER:
  189. SourceBuffer = &(pAdapter->RcvNoBuffer);
  190. SourceBufferLength = sizeof(ULONG);
  191. break;
  192. case OID_802_3_PERMANENT_ADDRESS:
  193. SourceBuffer = pAdapter->PermanentAddress;
  194. SourceBufferLength = TUN_MAC_ADDR_LEN;
  195. break;
  196. case OID_802_3_CURRENT_ADDRESS:
  197. SourceBuffer = pAdapter->CurrentAddress;
  198. SourceBufferLength = TUN_MAC_ADDR_LEN;
  199. break;
  200. case OID_802_3_MAXIMUM_LIST_SIZE:
  201. GenericUlong = TUN_MAX_MULTICAST_ADDRESS;
  202. break;
  203. case OID_802_3_RCV_ERROR_ALIGNMENT:
  204. case OID_802_3_XMIT_ONE_COLLISION:
  205. case OID_802_3_XMIT_MORE_COLLISIONS:
  206. GenericUlong = 0;
  207. break;
  208. case OID_PNP_CAPABILITIES:
  209. //
  210. // we support going to D3, but we don't do any WOL
  211. //
  212. SourceBufferLength = sizeof (NDIS_PNP_CAPABILITIES);
  213. SourceBuffer = (PVOID)&Power_Management_Capabilities;
  214. break;
  215. case OID_PNP_QUERY_POWER:
  216. //
  217. // we should always succeed this OID.
  218. //
  219. SourceBufferLength = 0;
  220. break;
  221. case OID_CUSTOM_TUNMP_INSTANCE_ID:
  222. GenericUlong = pAdapter->DeviceInstanceNumber;
  223. break;
  224. default:
  225. NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
  226. break;
  227. }
  228. if (NdisStatus == NDIS_STATUS_SUCCESS)
  229. {
  230. *BytesNeeded = SourceBufferLength;
  231. if (SourceBufferLength <= InformationBufferLength)
  232. {
  233. *BytesWritten = SourceBufferLength;
  234. if (SourceBufferLength)
  235. {
  236. NdisMoveMemory(InformationBuffer, SourceBuffer, SourceBufferLength);
  237. }
  238. }
  239. else
  240. {
  241. NdisStatus = NDIS_STATUS_BUFFER_TOO_SHORT;
  242. }
  243. }
  244. DEBUGP(DL_LOUD, ("<==TunMpQueryInformation: Adapter %p, NdisStatus %lx\n",
  245. pAdapter, NdisStatus));
  246. return (NdisStatus);
  247. }
  248. NDIS_STATUS
  249. TunMpSetInformation(
  250. IN NDIS_HANDLE MiniportAdapterContext,
  251. IN NDIS_OID Oid,
  252. IN PVOID InformationBuffer,
  253. IN ULONG InformationBufferLength,
  254. OUT PULONG BytesRead,
  255. OUT PULONG BytesNeeded
  256. )
  257. /*++
  258. Routine Description:
  259. Miniport SetInfo handler.
  260. Arguments:
  261. MiniportAdapterContext Pointer to the adapter structure
  262. Oid Oid for this query
  263. InformationBuffer Buffer for information
  264. InformationBufferLength Size of this buffer
  265. BytesRead Specifies how much info is read
  266. BytesNeeded In case the buffer is smaller than what we need,
  267. tell them how much is needed
  268. Return Value:
  269. Return code from the NdisRequest below.
  270. --*/
  271. {
  272. PTUN_ADAPTER pAdapter = (PTUN_ADAPTER)MiniportAdapterContext;
  273. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  274. NDIS_DEVICE_POWER_STATE NewPowerState;
  275. DEBUGP(DL_LOUD, ("==>TunMpSetInformation: Adapter %p, Oid %lx\n",
  276. pAdapter, Oid));
  277. *BytesRead = 0;
  278. *BytesNeeded = 0;
  279. switch (Oid)
  280. {
  281. case OID_GEN_CURRENT_PACKET_FILTER:
  282. if (InformationBufferLength != sizeof(ULONG))
  283. {
  284. NdisStatus = NDIS_STATUS_INVALID_DATA;
  285. }
  286. else
  287. {
  288. ULONG PacketFilter;
  289. PacketFilter = *(UNALIGNED ULONG *)InformationBuffer;
  290. pAdapter->PacketFilter = PacketFilter;
  291. *BytesRead = InformationBufferLength;
  292. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  293. if (PacketFilter != 0)
  294. {
  295. //
  296. // if packet filter is set to a non-zero value, then activate
  297. // the adapter. i.e. start indicating packets.
  298. //
  299. TUN_SET_FLAG(pAdapter, TUN_ADAPTER_ACTIVE);
  300. }
  301. else
  302. {
  303. //
  304. // if packet filter is set to zero, then we should
  305. // fail all writes
  306. //
  307. TUN_CLEAR_FLAG(pAdapter, TUN_ADAPTER_ACTIVE);
  308. if (pAdapter->PendedSendCount != 0)
  309. {
  310. NdisStatus = NDIS_STATUS_PENDING;
  311. TUN_SET_FLAG(pAdapter, TUN_COMPLETE_REQUEST);
  312. }
  313. else
  314. {
  315. NdisStatus = NDIS_STATUS_SUCCESS;
  316. }
  317. }
  318. TUN_RELEASE_LOCK(&pAdapter->Lock);
  319. }
  320. break;
  321. case OID_GEN_CURRENT_LOOKAHEAD:
  322. if (InformationBufferLength != sizeof(ULONG))
  323. {
  324. NdisStatus = NDIS_STATUS_INVALID_DATA;
  325. }
  326. else
  327. {
  328. ULONG CurrentLookahead;
  329. CurrentLookahead = *(UNALIGNED ULONG *)InformationBuffer;
  330. if (CurrentLookahead > TUN_MAX_LOOKAHEAD)
  331. {
  332. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  333. }
  334. else if (CurrentLookahead >= pAdapter->MaxLookAhead)
  335. {
  336. pAdapter->MaxLookAhead = CurrentLookahead;
  337. *BytesRead = sizeof(ULONG);
  338. NdisStatus = NDIS_STATUS_SUCCESS;
  339. }
  340. }
  341. break;
  342. case OID_802_3_MULTICAST_LIST:
  343. if (pAdapter->Medium != NdisMedium802_3)
  344. {
  345. NdisStatus = NDIS_STATUS_INVALID_OID;
  346. break;
  347. }
  348. if ((InformationBufferLength % ETH_LENGTH_OF_ADDRESS) != 0)
  349. {
  350. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  351. break;
  352. }
  353. //1 set BytesNeeded, check for max multicastlist
  354. break;
  355. case OID_PNP_SET_POWER:
  356. if (InformationBufferLength != sizeof(NDIS_DEVICE_POWER_STATE ))
  357. {
  358. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  359. break;
  360. }
  361. NewPowerState = *(PNDIS_DEVICE_POWER_STATE)InformationBuffer;
  362. *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
  363. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  364. if (NewPowerState != NdisDeviceStateD0)
  365. {
  366. //
  367. // complete any oustanding NDIS sends. do not allow any
  368. // more NDIS sends. wait for all the indicated packets
  369. // to return and do not allow any more packet
  370. // indications (application Write)
  371. //
  372. TUN_CLEAR_FLAG(pAdapter, TUN_ADAPTER_ACTIVE);
  373. TUN_SET_FLAG(pAdapter, TUN_ADAPTER_OFF);
  374. //
  375. // complete all outstanding NDIS Send requests
  376. //
  377. TUN_RELEASE_LOCK(&pAdapter->Lock);
  378. //
  379. // abort all pending NDIS send requests
  380. TunFlushReceiveQueue(pAdapter);
  381. //
  382. // cancel all pending read IRPs if any
  383. //
  384. TunCancelPendingReads(pAdapter);
  385. TUN_ACQUIRE_LOCK(&pAdapter->Lock);
  386. //
  387. // is there any outstanding NDIS sends?
  388. //
  389. if ((pAdapter->PendedSendCount != 0) ||
  390. (pAdapter->PendedReadCount != 0))
  391. {
  392. NdisStatus = NDIS_STATUS_PENDING;
  393. TUN_SET_FLAG(pAdapter, TUN_COMPLETE_REQUEST);
  394. }
  395. }
  396. else
  397. {
  398. TUN_CLEAR_FLAG(pAdapter, TUN_ADAPTER_OFF);
  399. if (pAdapter->PacketFilter != 0)
  400. {
  401. TUN_SET_FLAG(pAdapter, TUN_ADAPTER_ACTIVE);
  402. }
  403. //
  404. //
  405. NdisStatus = NDIS_STATUS_SUCCESS;
  406. }
  407. TUN_RELEASE_LOCK(&pAdapter->Lock);
  408. break;
  409. default:
  410. NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
  411. break;
  412. }
  413. DEBUGP(DL_LOUD, ("<==TunMpSetInformation: Adapter %p, NdisStatus %lx\n",
  414. pAdapter, NdisStatus));
  415. return NdisStatus;
  416. }