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.

2038 lines
89 KiB

  1. /***************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. REQUEST.C
  5. Abstract:
  6. Handles set and query requests
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 5/13/99 : created
  17. Author:
  18. Tom Green
  19. ****************************************************************************/
  20. #include "precomp.h"
  21. #ifdef TESTING
  22. extern PUCHAR pOffloadBuffer;
  23. extern ULONG OffloadSize;
  24. #endif
  25. // supported OID list
  26. NDIS_OID RndismpSupportedOids[] =
  27. {
  28. OID_GEN_SUPPORTED_LIST,
  29. OID_GEN_MEDIA_IN_USE,
  30. OID_GEN_MAXIMUM_LOOKAHEAD,
  31. OID_GEN_MAXIMUM_TOTAL_SIZE,
  32. OID_GEN_PROTOCOL_OPTIONS,
  33. OID_GEN_TRANSMIT_BUFFER_SPACE,
  34. OID_GEN_RECEIVE_BUFFER_SPACE,
  35. OID_GEN_TRANSMIT_BLOCK_SIZE,
  36. OID_GEN_RECEIVE_BLOCK_SIZE,
  37. OID_GEN_VENDOR_DESCRIPTION,
  38. OID_GEN_DRIVER_VERSION,
  39. OID_GEN_VENDOR_ID,
  40. OID_GEN_VENDOR_DRIVER_VERSION,
  41. OID_GEN_CURRENT_LOOKAHEAD,
  42. OID_GEN_MAXIMUM_SEND_PACKETS,
  43. OID_GEN_XMIT_OK,
  44. OID_GEN_RCV_OK,
  45. OID_GEN_XMIT_ERROR,
  46. OID_GEN_RCV_ERROR,
  47. OID_GEN_RCV_NO_BUFFER,
  48. OID_GEN_MAC_OPTIONS,
  49. OID_RNDISMP_STATISTICS,
  50. #ifdef TESTING
  51. OID_TCP_TASK_OFFLOAD,
  52. OID_GEN_TRANSPORT_HEADER_OFFSET,
  53. OID_GEN_PHYSICAL_MEDIUM,
  54. #endif
  55. OID_GEN_SUPPORTED_GUIDS
  56. };
  57. UINT RndismpSupportedOidsNum = sizeof(RndismpSupportedOids) / sizeof(NDIS_OID);
  58. #ifdef BINARY_MOF_TEST
  59. UCHAR RndismpBinaryMof[] = {
  60. 0x46, 0x4f, 0x4d, 0x42, 0x01, 0x00, 0x00, 0x00, 0x45, 0x02, 0x00, 0x00, 0xbc, 0x04, 0x00, 0x00,
  61. 0x44, 0x53, 0x00, 0x01, 0x1a, 0x7d, 0xda, 0x54, 0x18, 0x44, 0x82, 0x00, 0x01, 0x06, 0x18, 0x42,
  62. 0x20, 0xe4, 0x03, 0x89, 0xc0, 0x61, 0x68, 0x24, 0x18, 0x06, 0xe5, 0x01, 0x44, 0x6a, 0x20, 0xe4,
  63. 0x82, 0x89, 0x09, 0x10, 0x01, 0x21, 0xaf, 0x02, 0x6c, 0x0a, 0x30, 0x09, 0xa2, 0xfe, 0xfd, 0x15,
  64. 0xa1, 0xa1, 0x84, 0x40, 0x48, 0xa2, 0x00, 0xf3, 0x02, 0x74, 0x0b, 0x30, 0x2c, 0xc0, 0xb6, 0x00,
  65. 0xd3, 0x02, 0x1c, 0x23, 0x12, 0x65, 0xd0, 0x94, 0xc0, 0x4a, 0x20, 0x24, 0x54, 0x80, 0x72, 0x01,
  66. 0xbe, 0x05, 0x68, 0x07, 0x94, 0x64, 0x01, 0x96, 0x61, 0x34, 0x07, 0x0e, 0xc6, 0x09, 0x8a, 0x46,
  67. 0x46, 0xa9, 0x80, 0x90, 0x67, 0x01, 0xd6, 0x71, 0x09, 0x41, 0xf7, 0x02, 0xa4, 0x09, 0x70, 0x26,
  68. 0xc0, 0xdb, 0x34, 0xa4, 0x59, 0xc0, 0x30, 0x22, 0xd8, 0x16, 0x8e, 0x30, 0xe2, 0x9c, 0x42, 0x94,
  69. 0xc6, 0x10, 0x84, 0x19, 0x31, 0x4a, 0x73, 0x58, 0x82, 0x8a, 0x11, 0xa5, 0x30, 0x04, 0x01, 0x86,
  70. 0x88, 0x55, 0x9c, 0x00, 0x6b, 0x58, 0x42, 0x39, 0x80, 0x13, 0xb0, 0xfd, 0x39, 0x48, 0x13, 0x84,
  71. 0x1c, 0x4c, 0x0b, 0x25, 0x7b, 0x40, 0x9a, 0xc6, 0xf1, 0x05, 0x39, 0x87, 0x83, 0x61, 0x26, 0x86,
  72. 0x2c, 0x55, 0x98, 0x28, 0x2d, 0x73, 0x23, 0xe3, 0xb4, 0x45, 0x01, 0xe2, 0x05, 0x08, 0x07, 0xd5,
  73. 0x58, 0x3b, 0xc7, 0xd0, 0x05, 0x80, 0xa9, 0x1e, 0x1e, 0x4a, 0xcc, 0x98, 0x09, 0x5a, 0xbc, 0x93,
  74. 0x38, 0xcc, 0xc0, 0x61, 0x4b, 0xc7, 0xd0, 0x40, 0x02, 0x27, 0x68, 0x10, 0x49, 0x8a, 0x71, 0x84,
  75. 0x14, 0xe4, 0x5c, 0x42, 0x9c, 0x7c, 0x41, 0x02, 0x94, 0x0a, 0xd0, 0x09, 0xac, 0x19, 0x77, 0x3a,
  76. 0x66, 0x4d, 0x39, 0x50, 0x78, 0x8f, 0xdc, 0xf8, 0x41, 0xe2, 0xf4, 0x09, 0xac, 0x79, 0x44, 0x89,
  77. 0x13, 0xba, 0xa9, 0x09, 0x28, 0xa4, 0x02, 0x88, 0x16, 0x40, 0x94, 0x66, 0x32, 0xa8, 0xab, 0x40,
  78. 0x82, 0x47, 0x03, 0x8f, 0xe0, 0xa8, 0x0c, 0x7a, 0x1a, 0x41, 0xe2, 0x7b, 0x18, 0xef, 0x04, 0x1e,
  79. 0x99, 0x87, 0x79, 0x8a, 0x0c, 0xf3, 0xff, 0xff, 0x8e, 0x80, 0x75, 0x8d, 0xa7, 0x11, 0x9d, 0x80,
  80. 0xe5, 0xa0, 0xa1, 0xae, 0x03, 0x1e, 0x57, 0xb4, 0xf8, 0xa7, 0x6c, 0xb8, 0xba, 0xc6, 0x82, 0xba,
  81. 0x2a, 0xd8, 0xe1, 0x54, 0x34, 0xb6, 0x52, 0x05, 0x98, 0x1d, 0x9c, 0xe6, 0x9c, 0xe0, 0x68, 0x3c,
  82. 0x55, 0xcf, 0xe6, 0xe1, 0x20, 0xc1, 0x23, 0x82, 0xa7, 0xc0, 0xa7, 0x65, 0x1d, 0xc3, 0x25, 0x03,
  83. 0x34, 0x62, 0xb8, 0x73, 0x32, 0x7a, 0x82, 0x3b, 0x94, 0x80, 0xd1, 0xc0, 0xbd, 0x1b, 0x1c, 0x0d,
  84. 0xec, 0x59, 0xbf, 0x04, 0x44, 0x78, 0x38, 0xf0, 0x5c, 0x3d, 0x06, 0xfd, 0x08, 0xe4, 0x64, 0x36,
  85. 0x28, 0x3d, 0x37, 0x02, 0x7a, 0x05, 0xe0, 0x27, 0x09, 0x76, 0x3c, 0x30, 0xc8, 0x29, 0x1d, 0xad,
  86. 0x53, 0x43, 0xe8, 0xad, 0xe1, 0x19, 0xc1, 0x05, 0x7e, 0x4c, 0x00, 0xcb, 0xe9, 0x00, 0x3b, 0x16,
  87. 0x3c, 0x52, 0xe3, 0x47, 0x0c, 0xe1, 0x18, 0x31, 0xc6, 0x69, 0x04, 0x0a, 0xeb, 0x91, 0x04, 0xa9,
  88. 0x70, 0xf6, 0x64, 0x98, 0x6f, 0x0a, 0x35, 0x0a, 0xb8, 0x09, 0x58, 0xd4, 0x65, 0x02, 0x25, 0xe5,
  89. 0x32, 0x81, 0x98, 0x47, 0xd8, 0xb7, 0x04, 0x4f, 0xf8, 0xac, 0x7c, 0x98, 0xf0, 0xa5, 0x00, 0xfe,
  90. 0xed, 0xc3, 0xc3, 0x08, 0xfd, 0xb0, 0xf1, 0x44, 0xe2, 0x23, 0x43, 0x5c, 0xcc, 0xff, 0x1f, 0xd7,
  91. 0x03, 0xb7, 0x5f, 0x01, 0x08, 0xb1, 0xcb, 0xbc, 0x16, 0xe8, 0x38, 0x11, 0x21, 0xc1, 0x1b, 0x05,
  92. 0x16, 0xe3, 0x60, 0x3c, 0x50, 0x9f, 0x13, 0x3c, 0x4c, 0x83, 0x1c, 0x59, 0xbc, 0x88, 0x09, 0x4e,
  93. 0xed, 0xa8, 0xb1, 0x73, 0xe0, 0x03, 0x38, 0x86, 0xf0, 0xe7, 0x13, 0xfe, 0x00, 0xa2, 0x1c, 0xc7,
  94. 0x21, 0x79, 0xc8, 0x46, 0x38, 0x81, 0x72, 0x2f, 0x2b, 0xe4, 0x58, 0x72, 0x14, 0xa7, 0xf5, 0x74,
  95. 0x10, 0xe8, 0x04, 0x30, 0x0a, 0x6d, 0xfa, 0xd4, 0x68, 0xd4, 0xaa, 0x41, 0x99, 0x1a, 0x65, 0x1a,
  96. 0xd4, 0xea, 0x53, 0xa9, 0x31, 0x63, 0xf3, 0xb5, 0xb4, 0x77, 0x83, 0x40, 0x1c, 0x0a, 0x84, 0x66,
  97. 0xa4, 0x10, 0x88, 0xff, 0xff};
  98. ULONG RndismpBinaryMofSize = sizeof(RndismpBinaryMof);
  99. #define RNDISMPDeviceOIDGuid \
  100. { 0x437cf222,0x72fe,0x11d4, { 0x97,0xf9,0x00,0x20,0x48,0x57,0x03,0x37}}
  101. #endif // BINARY_MOF_TEST
  102. NDIS_GUID CustomGuidList[] =
  103. {
  104. {
  105. RNDISMPStatisticsOIDGuid,
  106. OID_RNDISMP_STATISTICS,
  107. sizeof(UINT32), // size is size of each element in the array
  108. (fNDIS_GUID_TO_OID|fNDIS_GUID_ARRAY)
  109. }
  110. #ifdef BINARY_MOF_TEST
  111. ,
  112. {
  113. RNDISMPDeviceOIDGuid,
  114. OID_RNDISMP_DEVICE_OID,
  115. sizeof(UINT32),
  116. fNDIS_GUID_TO_OID
  117. },
  118. {
  119. BINARY_MOF_GUID,
  120. OID_RNDISMP_GET_MOF_OID,
  121. sizeof(UINT8),
  122. (fNDIS_GUID_TO_OID|fNDIS_GUID_ARRAY)
  123. }
  124. #endif
  125. };
  126. UINT CustomGuidCount = sizeof(CustomGuidList)/sizeof(NDIS_GUID);
  127. /****************************************************************************/
  128. /* RndismpQueryInformation */
  129. /****************************************************************************/
  130. /* */
  131. /* Routine Description: */
  132. /* */
  133. /* NDIS Entry point called to handle a query for a particular OID. */
  134. /* */
  135. /* Arguments: */
  136. /* */
  137. /* MiniportAdapterContext - a context version of our Adapter pointer */
  138. /* Oid - the NDIS_OID to process. */
  139. /* InformationBuffer - a pointer into the NdisRequest->InformationBuffer */
  140. /* into which store the result of the query. */
  141. /* InformationBufferLength - a pointer to the number of bytes left in */
  142. /* the InformationBuffer. */
  143. /* pBytesWritten - a pointer to the number of bytes written into the */
  144. /* InformationBuffer. */
  145. /* pBytesNeeded - If there is not enough room in the information buffer */
  146. /* then this will contain the number of bytes needed to complete the */
  147. /* request. */
  148. /* */
  149. /* Return: */
  150. /* */
  151. /* NDIS_STATUS */
  152. /* */
  153. /****************************************************************************/
  154. NDIS_STATUS
  155. RndismpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
  156. IN NDIS_OID Oid,
  157. IN PVOID InformationBuffer,
  158. IN ULONG InformationBufferLength,
  159. OUT PULONG pBytesWritten,
  160. OUT PULONG pBytesNeeded)
  161. {
  162. PRNDISMP_ADAPTER pAdapter;
  163. NDIS_STATUS Status;
  164. // get adapter context
  165. pAdapter = PRNDISMP_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
  166. CHECK_VALID_ADAPTER(pAdapter);
  167. TRACE3(("RndismpQueryInformation\n"));
  168. Status = ProcessQueryInformation(pAdapter,
  169. NULL,
  170. NULL,
  171. Oid,
  172. InformationBuffer,
  173. InformationBufferLength,
  174. pBytesWritten,
  175. pBytesNeeded);
  176. return Status;
  177. }
  178. /****************************************************************************/
  179. /* ProcessQueryInformation */
  180. /****************************************************************************/
  181. /* */
  182. /* Routine Description: */
  183. /* */
  184. /* Utility routine to process a Query (connection-less or connection- */
  185. /* oriented). */
  186. /* */
  187. /* Arguments: */
  188. /* */
  189. /* pAdapter - Pointer to our adapter structure */
  190. /* pVc - Pointer to a VC, possibly NULL. */
  191. /* pRequest - Pointer to NDIS request, if this came via our CoRequest */
  192. /* handler. */
  193. /* Oid - the NDIS_OID to process. */
  194. /* InformationBuffer - a pointer into the NdisRequest->InformationBuffer */
  195. /* into which store the result of the query. */
  196. /* InformationBufferLength - a pointer to the number of bytes left in */
  197. /* the InformationBuffer. */
  198. /* pBytesWritten - a pointer to the number of bytes written into the */
  199. /* InformationBuffer. */
  200. /* pBytesNeeded - If there is not enough room in the information buffer */
  201. /* then this will contain the number of bytes needed to complete the */
  202. /* request. */
  203. /* */
  204. /* Return: */
  205. /* */
  206. /* NDIS_STATUS */
  207. /* */
  208. /****************************************************************************/
  209. NDIS_STATUS
  210. ProcessQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
  211. IN PRNDISMP_VC pVc,
  212. IN PNDIS_REQUEST pRequest,
  213. IN NDIS_OID Oid,
  214. IN PVOID InformationBuffer,
  215. IN ULONG InformationBufferLength,
  216. OUT PULONG pBytesWritten,
  217. OUT PULONG pBytesNeeded)
  218. {
  219. NDIS_STATUS Status;
  220. UINT OIDHandler;
  221. OIDHandler = GetOIDSupport(pAdapter, Oid);
  222. switch(OIDHandler)
  223. {
  224. case DRIVER_SUPPORTED_OID:
  225. Status = DriverQueryInformation(pAdapter,
  226. pVc,
  227. pRequest,
  228. Oid,
  229. InformationBuffer,
  230. InformationBufferLength,
  231. pBytesWritten,
  232. pBytesNeeded);
  233. break;
  234. case DEVICE_SUPPORTED_OID:
  235. Status = DeviceQueryInformation(pAdapter,
  236. pVc,
  237. pRequest,
  238. Oid,
  239. InformationBuffer,
  240. InformationBufferLength,
  241. pBytesWritten,
  242. pBytesNeeded);
  243. break;
  244. case OID_NOT_SUPPORTED:
  245. default:
  246. TRACE2(("Invalid Query OID (%08X)\n", Oid));
  247. Status = NDIS_STATUS_INVALID_OID;
  248. break;
  249. }
  250. TRACE2(("ProcessQueryInfo: Oid %08X, returning Status %x\n", Oid, Status));
  251. return Status;
  252. } // ProcessQueryInformation
  253. /****************************************************************************/
  254. /* RndismpSetInformation */
  255. /****************************************************************************/
  256. /* */
  257. /* Routine Description: */
  258. /* */
  259. /* The RndismpSetInformation processes a Set request for */
  260. /* NDIS_OIDs that are specific about the Driver. */
  261. /* */
  262. /* Arguments: */
  263. /* */
  264. /* MiniportAdapterContext - a context version of our Adapter pointer */
  265. /* Oid - the NDIS_OID to process. */
  266. /* InformationBuffer - Holds the data to be set. */
  267. /* InformationBufferLength - The length of InformationBuffer. */
  268. /* pBytesRead - If the call is successful, returns the number */
  269. /* of bytes read from InformationBuffer. */
  270. /* pBytesNeeded - If there is not enough data in InformationBuffer */
  271. /* to satisfy the OID, returns the amount of storage needed. */
  272. /* */
  273. /* Return: */
  274. /* */
  275. /* NDIS_STATUS */
  276. /* */
  277. /****************************************************************************/
  278. NDIS_STATUS
  279. RndismpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
  280. IN NDIS_OID Oid,
  281. IN PVOID InformationBuffer,
  282. IN ULONG InformationBufferLength,
  283. OUT PULONG pBytesRead,
  284. OUT PULONG pBytesNeeded)
  285. {
  286. PRNDISMP_ADAPTER pAdapter;
  287. NDIS_STATUS Status;
  288. // get adapter context
  289. pAdapter = PRNDISMP_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
  290. CHECK_VALID_ADAPTER(pAdapter);
  291. TRACE3(("RndismpSetInformation\n"));
  292. Status = ProcessSetInformation(pAdapter,
  293. NULL,
  294. NULL,
  295. Oid,
  296. InformationBuffer,
  297. InformationBufferLength,
  298. pBytesRead,
  299. pBytesNeeded);
  300. return Status;
  301. }
  302. /****************************************************************************/
  303. /* ProcessSetInformation */
  304. /****************************************************************************/
  305. /* */
  306. /* Routine Description: */
  307. /* */
  308. /* Utility routine to process a Set (connection-less or connection- */
  309. /* oriented). */
  310. /* */
  311. /* Arguments: */
  312. /* */
  313. /* pAdapter - Pointer to our adapter structure */
  314. /* pVc - Pointer to a VC, possibly NULL. */
  315. /* pRequest - Pointer to NDIS request, if this came via our CoRequest */
  316. /* handler. */
  317. /* Oid - the NDIS_OID to process. */
  318. /* InformationBuffer - a pointer into the NdisRequest->InformationBuffer */
  319. /* into which store the result of the query. */
  320. /* InformationBufferLength - a pointer to the number of bytes left in */
  321. /* the InformationBuffer. */
  322. /* pBytesRead - a pointer to the number of bytes read from the */
  323. /* InformationBuffer. */
  324. /* pBytesNeeded - If there is not enough room in the information buffer */
  325. /* then this will contain the number of bytes needed to complete the */
  326. /* request. */
  327. /* */
  328. /* Return: */
  329. /* */
  330. /* NDIS_STATUS */
  331. /* */
  332. /****************************************************************************/
  333. NDIS_STATUS
  334. ProcessSetInformation(IN PRNDISMP_ADAPTER pAdapter,
  335. IN PRNDISMP_VC pVc OPTIONAL,
  336. IN PNDIS_REQUEST pRequest OPTIONAL,
  337. IN NDIS_OID Oid,
  338. IN PVOID InformationBuffer,
  339. IN ULONG InformationBufferLength,
  340. OUT PULONG pBytesRead,
  341. OUT PULONG pBytesNeeded)
  342. {
  343. NDIS_STATUS Status;
  344. UINT OIDHandler;
  345. OIDHandler = GetOIDSupport(pAdapter, Oid);
  346. switch(OIDHandler)
  347. {
  348. case DRIVER_SUPPORTED_OID:
  349. Status = DriverSetInformation(pAdapter,
  350. pVc,
  351. pRequest,
  352. Oid,
  353. InformationBuffer,
  354. InformationBufferLength,
  355. pBytesRead,
  356. pBytesNeeded);
  357. break;
  358. case DEVICE_SUPPORTED_OID:
  359. Status = DeviceSetInformation(pAdapter,
  360. pVc,
  361. pRequest,
  362. Oid,
  363. InformationBuffer,
  364. InformationBufferLength,
  365. pBytesRead,
  366. pBytesNeeded);
  367. break;
  368. case OID_NOT_SUPPORTED:
  369. default:
  370. TRACE2(("Invalid Set OID (%08X), Adapter %p\n", Oid, pAdapter));
  371. Status = NDIS_STATUS_INVALID_OID;
  372. break;
  373. }
  374. return Status;
  375. } // ProcessSetInformation
  376. /****************************************************************************/
  377. /* DriverQueryInformation */
  378. /****************************************************************************/
  379. /* */
  380. /* Routine Description: */
  381. /* */
  382. /* The RndismpQueryInformation processes a Query request for */
  383. /* NDIS_OIDs that are specific about the Driver. This routine */
  384. /* Handles OIDs supported by the driver instead of the device */
  385. /* */
  386. /* Arguments: */
  387. /* */
  388. /* pAdapter - Pointer to our adapter structure */
  389. /* pVc - Pointer to a VC, possibly NULL. */
  390. /* pRequest - Pointer to NDIS request, if this came via our CoRequest */
  391. /* handler. */
  392. /* Oid - the NDIS_OID to process. */
  393. /* InformationBuffer - a pointer into the NdisRequest->InformationBuffer */
  394. /* into which store the result of the query. */
  395. /* InformationBufferLength - a pointer to the number of bytes left in */
  396. /* the InformationBuffer. */
  397. /* pBytesWritten - a pointer to the number of bytes written into the */
  398. /* InformationBuffer. */
  399. /* pBytesNeeded - If there is not enough room in the information buffer */
  400. /* then this will contain the number of bytes needed to complete the */
  401. /* request. */
  402. /* */
  403. /* Return: */
  404. /* */
  405. /* NDIS_STATUS */
  406. /* */
  407. /****************************************************************************/
  408. NDIS_STATUS
  409. DriverQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
  410. IN PRNDISMP_VC pVc OPTIONAL,
  411. IN PNDIS_REQUEST pRequest OPTIONAL,
  412. IN NDIS_OID Oid,
  413. IN PVOID InformationBuffer,
  414. IN ULONG InformationBufferLength,
  415. OUT PULONG pBytesWritten,
  416. OUT PULONG pBytesNeeded)
  417. {
  418. NDIS_STATUS Status;
  419. PVOID MoveSource;
  420. UINT MoveBytes;
  421. ULONG GenericUlong;
  422. USHORT GenericUshort;
  423. CHAR VendorDescription[] = "Remote NDIS Network Card";
  424. TRACE3(("DriverQueryInformation\n"));
  425. OID_NAME_TRACE(Oid, "DriverQuery");
  426. Status = NDIS_STATUS_SUCCESS;
  427. MoveSource = (PVOID) (&GenericUlong);
  428. MoveBytes = sizeof(GenericUlong);
  429. // this is one we have to handle
  430. switch(Oid)
  431. {
  432. case OID_GEN_DRIVER_VERSION:
  433. GenericUshort = (pAdapter->DriverBlock->MajorNdisVersion << 8) +
  434. (pAdapter->DriverBlock->MinorNdisVersion);
  435. MoveSource = (PVOID)&GenericUshort;
  436. MoveBytes = sizeof(GenericUshort);
  437. break;
  438. case OID_GEN_VENDOR_ID:
  439. TRACE1(("Query for OID_GEN_VENDOR_ID not supported by device!\n"));
  440. GenericUlong = 0xFFFFFF;
  441. break;
  442. case OID_GEN_VENDOR_DESCRIPTION:
  443. TRACE1(("Query for OID_GEN_VENDOR_DESCRIPTION not supported by device!\n"));
  444. if (pAdapter->FriendlyNameAnsi.Length != 0)
  445. {
  446. MoveSource = pAdapter->FriendlyNameAnsi.Buffer;
  447. MoveBytes = pAdapter->FriendlyNameAnsi.Length;
  448. }
  449. else
  450. {
  451. MoveSource = VendorDescription;
  452. MoveBytes = sizeof(VendorDescription);
  453. }
  454. break;
  455. case OID_GEN_VENDOR_DRIVER_VERSION:
  456. TRACE1(("Query for OID_GEN_VENDOR_DRIVER_VERSION not supported by device!\n"));
  457. GenericUlong = 0xA000B;
  458. break;
  459. case OID_GEN_MAC_OPTIONS:
  460. GenericUlong = pAdapter->MacOptions;
  461. break;
  462. case OID_GEN_SUPPORTED_LIST:
  463. // get the list we generated
  464. MoveSource = (PVOID) (pAdapter->SupportedOIDList);
  465. MoveBytes = pAdapter->SupportedOIDListSize;
  466. break;
  467. case OID_GEN_MEDIA_IN_USE:
  468. Status = DeviceQueryInformation(pAdapter,
  469. pVc,
  470. pRequest,
  471. OID_GEN_MEDIA_SUPPORTED,
  472. InformationBuffer,
  473. InformationBufferLength,
  474. pBytesWritten,
  475. pBytesNeeded);
  476. break;
  477. case OID_GEN_MAXIMUM_LOOKAHEAD:
  478. Status = DeviceQueryInformation(pAdapter,
  479. pVc,
  480. pRequest,
  481. OID_GEN_MAXIMUM_FRAME_SIZE,
  482. InformationBuffer,
  483. InformationBufferLength,
  484. pBytesWritten,
  485. pBytesNeeded);
  486. break;
  487. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  488. GenericUlong = pAdapter->MaxTransferSize;
  489. break;
  490. case OID_GEN_RECEIVE_BUFFER_SPACE:
  491. GenericUlong = pAdapter->MaxReceiveSize * 8;
  492. break;
  493. case OID_GEN_CURRENT_LOOKAHEAD:
  494. Status = DeviceQueryInformation(pAdapter,
  495. pVc,
  496. pRequest,
  497. OID_GEN_MAXIMUM_FRAME_SIZE,
  498. InformationBuffer,
  499. InformationBufferLength,
  500. pBytesWritten,
  501. pBytesNeeded);
  502. break;
  503. case OID_GEN_MAXIMUM_FRAME_SIZE:
  504. Status = DeviceQueryInformation(pAdapter,
  505. pVc,
  506. pRequest,
  507. OID_GEN_MAXIMUM_FRAME_SIZE,
  508. InformationBuffer,
  509. InformationBufferLength,
  510. pBytesWritten,
  511. pBytesNeeded);
  512. break;
  513. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  514. TRACE1(("Query for OID_GEN_MAXIMUM_TOTAL_SIZE not supported by device!\n"));
  515. GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
  516. break;
  517. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  518. TRACE1(("Query for OID_GEN_TRANSMIT_BLOCK_SIZE not supported by device!\n"));
  519. GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
  520. break;
  521. case OID_GEN_RECEIVE_BLOCK_SIZE:
  522. TRACE1(("Query for OID_GEN_RECEIVE_BLOCK_SIZE not supported by device!\n"));
  523. GenericUlong = (ULONG) MAXIMUM_ETHERNET_PACKET_SIZE;
  524. break;
  525. case OID_GEN_MAXIMUM_SEND_PACKETS:
  526. GenericUlong = (ULONG) pAdapter->MaxPacketsPerMessage;
  527. break;
  528. case OID_PNP_CAPABILITIES:
  529. case OID_PNP_QUERY_POWER:
  530. Status = NDIS_STATUS_NOT_SUPPORTED;
  531. break;
  532. case OID_GEN_XMIT_OK:
  533. GenericUlong = RNDISMP_GET_ADAPTER_STATS(pAdapter, XmitOk);
  534. break;
  535. case OID_GEN_XMIT_ERROR:
  536. GenericUlong = RNDISMP_GET_ADAPTER_STATS(pAdapter, XmitError);
  537. break;
  538. case OID_GEN_RCV_OK:
  539. GenericUlong = RNDISMP_GET_ADAPTER_STATS(pAdapter, RecvOk);
  540. break;
  541. case OID_GEN_RCV_ERROR:
  542. GenericUlong = RNDISMP_GET_ADAPTER_STATS(pAdapter, RecvError);
  543. break;
  544. case OID_GEN_RCV_NO_BUFFER:
  545. GenericUlong = RNDISMP_GET_ADAPTER_STATS(pAdapter, RecvNoBuf);
  546. break;
  547. case OID_GEN_SUPPORTED_GUIDS:
  548. MoveSource = (PVOID)&CustomGuidList[0];
  549. MoveBytes = sizeof(CustomGuidList);
  550. TRACE1(("Query for supported GUIDs, len %d\n", InformationBufferLength));
  551. break;
  552. case OID_RNDISMP_STATISTICS:
  553. MoveSource = &pAdapter->Statistics;
  554. MoveBytes = sizeof(pAdapter->Statistics);
  555. break;
  556. #ifdef BINARY_MOF_TEST
  557. case OID_RNDISMP_DEVICE_OID:
  558. DbgPrint("*** RNDISMP: Query for Device OID\n");
  559. GenericUlong = 0xabcdefab;
  560. break;
  561. case OID_RNDISMP_GET_MOF_OID:
  562. DbgPrint("*** RNDISMP: Query for MOF Info: Src %p, Size %d\n",
  563. RndismpBinaryMof, RndismpBinaryMofSize);
  564. MoveSource = RndismpBinaryMof;
  565. MoveBytes = RndismpBinaryMofSize;
  566. break;
  567. #endif // BINARY_MOF_TEST
  568. #ifdef TESTING
  569. case OID_TCP_TASK_OFFLOAD:
  570. DbgPrint("RNDISMP: got query for TCP offload\n");
  571. MoveSource = pOffloadBuffer;
  572. MoveBytes = OffloadSize;
  573. break;
  574. case OID_GEN_PHYSICAL_MEDIUM:
  575. DbgPrint("RNDISMP: got query for physical medium\n");
  576. GenericUlong = NdisPhysicalMediumDSL;
  577. break;
  578. #endif
  579. default:
  580. Status = NDIS_STATUS_INVALID_OID;
  581. break;
  582. }
  583. // copy stuff to information buffer
  584. if (Status == NDIS_STATUS_SUCCESS)
  585. {
  586. if (MoveBytes > InformationBufferLength)
  587. {
  588. // Not enough room in InformationBuffer
  589. *pBytesNeeded = MoveBytes;
  590. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  591. }
  592. else
  593. {
  594. // Copy result into InformationBuffer
  595. *pBytesWritten = MoveBytes;
  596. if (MoveBytes > 0)
  597. RNDISMP_MOVE_MEM(InformationBuffer, MoveSource, MoveBytes);
  598. }
  599. }
  600. TRACE2(("Status (%08X) BytesWritten (%08X)\n", Status, *pBytesWritten));
  601. return Status;
  602. } // DriverQueryInformation
  603. /****************************************************************************/
  604. /* DeviceQueryInformation */
  605. /****************************************************************************/
  606. /* */
  607. /* Routine Description: */
  608. /* */
  609. /* The DeviceQueryInformation processes a Query request */
  610. /* that is going to the Remote NDIS device */
  611. /* */
  612. /* Arguments: */
  613. /* */
  614. /* pAdapter - pointer to our Adapter structure */
  615. /* pVc - optional pointer to our VC structure, if this is a per-Vc req. */
  616. /* pRequest - optional pointer to NDIS request, if CONDIS. */
  617. /* Oid - the NDIS_OID to process. */
  618. /* InformationBuffer - a pointer into the NdisRequest->InformationBuffer */
  619. /* into which store the result of the query. */
  620. /* InformationBufferLength - a pointer to the number of bytes left in */
  621. /* the InformationBuffer. */
  622. /* pBytesWritten - a pointer to the number of bytes written into the */
  623. /* InformationBuffer. */
  624. /* pBytesNeeded - If there is not enough room in the information buffer */
  625. /* then this will contain the number of bytes needed to complete the */
  626. /* request. */
  627. /* */
  628. /* Return: */
  629. /* */
  630. /* NDIS_STATUS */
  631. /* */
  632. /****************************************************************************/
  633. NDIS_STATUS
  634. DeviceQueryInformation(IN PRNDISMP_ADAPTER pAdapter,
  635. IN PRNDISMP_VC pVc OPTIONAL,
  636. IN PNDIS_REQUEST pRequest OPTIONAL,
  637. IN NDIS_OID Oid,
  638. IN PVOID InformationBuffer,
  639. IN ULONG InformationBufferLength,
  640. OUT PULONG pBytesWritten,
  641. OUT PULONG pBytesNeeded)
  642. {
  643. PRNDISMP_MESSAGE_FRAME pMsgFrame;
  644. PRNDISMP_REQUEST_CONTEXT pReqContext;
  645. NDIS_STATUS Status;
  646. PUCHAR pSrcBuffer;
  647. ULONG ByteLength;
  648. OID_NAME_TRACE(Oid, "DeviceQuery");
  649. TRACE3(("DeviceQuery: OID %x, InfoBuf %p, Len %d, pBytesWrit %p, pBytesNeed %p\n",
  650. Oid, InformationBuffer, InformationBufferLength, pBytesWritten, pBytesNeeded));
  651. //
  652. // Debug code for Win9X/WinMe:
  653. //
  654. // TRACE1(("DeviceQuery: NdisRequest = %x, AdapterFlags %x, list empty %d\n",
  655. // *(PULONG)((PUCHAR)pAdapter->MiniportAdapterHandle + 0x13c),
  656. // *(PULONG)((PUCHAR)pAdapter->MiniportAdapterHandle + 0x3c),
  657. // IsListEmpty(&pAdapter->PendingFrameList)
  658. // ));
  659. // if (!IsListEmpty(&pAdapter->PendingFrameList))
  660. // {
  661. // TRACE0(("DeviceQuery: Adapter %p, PendingFrameList @%p not empty!\n",
  662. // pAdapter, &pAdapter->PendingFrameList));
  663. // DbgBreakPoint();
  664. // }
  665. do
  666. {
  667. if (pAdapter->Halting)
  668. {
  669. Status = NDIS_STATUS_NOT_ACCEPTED;
  670. break;
  671. }
  672. if (pAdapter->bRunningOnWin9x)
  673. {
  674. //
  675. // Intercept some queries to complete them synchronously.
  676. // This is because NDIS/Win9X-Me has a very short timeout for
  677. // internally generated queries (the ones intercepted below).
  678. //
  679. switch (Oid)
  680. {
  681. case OID_802_3_MAXIMUM_LIST_SIZE:
  682. pSrcBuffer = (PUCHAR)&pAdapter->MaxMulticastListSize;
  683. ByteLength = sizeof(pAdapter->MaxMulticastListSize);
  684. break;
  685. case OID_GEN_MAXIMUM_LOOKAHEAD:
  686. case OID_GEN_MAXIMUM_FRAME_SIZE:
  687. pSrcBuffer = (PUCHAR)&pAdapter->MaximumFrameSize;
  688. ByteLength = sizeof(pAdapter->MaximumFrameSize);
  689. break;
  690. case OID_802_3_CURRENT_ADDRESS:
  691. pSrcBuffer = (PUCHAR)pAdapter->MacAddress;
  692. ByteLength = ETH_LENGTH_OF_ADDRESS;
  693. break;
  694. case OID_GEN_MAC_OPTIONS:
  695. pSrcBuffer = (PUCHAR)&pAdapter->MacOptions;
  696. ByteLength = sizeof(pAdapter->MacOptions);
  697. break;
  698. default:
  699. pSrcBuffer = NULL;
  700. ByteLength = 0;
  701. break;
  702. }
  703. if (pSrcBuffer != NULL)
  704. {
  705. if (InformationBufferLength < ByteLength)
  706. {
  707. *pBytesNeeded = ByteLength;
  708. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  709. }
  710. else
  711. {
  712. TRACE1(("DeviceQuery: Adapter %p, intercepted OID %x\n",
  713. pAdapter, Oid));
  714. *pBytesNeeded = *pBytesWritten = ByteLength;
  715. NdisMoveMemory(InformationBuffer, pSrcBuffer, ByteLength);
  716. Status = NDIS_STATUS_SUCCESS;
  717. }
  718. break;
  719. }
  720. }
  721. pReqContext = AllocateRequestContext(pAdapter);
  722. if (pReqContext == NULL)
  723. {
  724. Status = NDIS_STATUS_RESOURCES;
  725. break;
  726. }
  727. //
  728. // HACKHACK to avoid a strange length from going to the device,
  729. // we minimize the amount of data sent with the query.
  730. //
  731. // In general, there is no point sending a huge information buffer
  732. // along with a Query that does not require an IN parameter.
  733. // Long term, we may have to separate out the few OIDs that do
  734. // use IN parameters and allow those buffers to pass through
  735. //
  736. pMsgFrame = BuildRndisMessageCommon(pAdapter,
  737. pVc,
  738. REMOTE_NDIS_QUERY_MSG,
  739. Oid,
  740. InformationBuffer,
  741. ((InformationBufferLength > 48)?
  742. 48: InformationBufferLength));
  743. // see if we got a message
  744. if (!pMsgFrame)
  745. {
  746. Status = NDIS_STATUS_RESOURCES;
  747. FreeRequestContext(pAdapter, pReqContext);
  748. break;
  749. }
  750. Status = NDIS_STATUS_PENDING;
  751. pReqContext->InformationBuffer = InformationBuffer;
  752. pReqContext->InformationBufferLength = InformationBufferLength;
  753. pReqContext->pBytesRead = NULL;
  754. pReqContext->pBytesWritten = pBytesWritten;
  755. pReqContext->pBytesNeeded = pBytesNeeded;
  756. pReqContext->Oid = Oid;
  757. pReqContext->RetryCount = 0;
  758. pReqContext->bInternal = FALSE;
  759. pReqContext->pVc = pVc;
  760. pReqContext->pNdisRequest = pRequest;
  761. pMsgFrame->pReqContext = pReqContext;
  762. // Add a ref to keep the frame around until we complete the request.
  763. ReferenceMsgFrame(pMsgFrame);
  764. TRACE3(("DeviceQuery: Oid %x, pReqContext %p, InfoBuf %p, pMsgFrame %p/%d\n",
  765. Oid, pReqContext, pReqContext->InformationBuffer, pMsgFrame, pMsgFrame->RefCount));
  766. // send the message to the microport
  767. RNDISMP_SEND_TO_MICROPORT(pAdapter, pMsgFrame, TRUE, CompleteSendDeviceRequest);
  768. break;
  769. }
  770. while (FALSE);
  771. return Status;
  772. } // DeviceQueryInformation
  773. /****************************************************************************/
  774. /* DriverSetInformation */
  775. /****************************************************************************/
  776. /* */
  777. /* Routine Description: */
  778. /* */
  779. /* Utility routine to handle SetInformation requests that aren't */
  780. /* specific to the device. We also land up here for requests for any */
  781. /* OIDs that aren't supported by the device. */
  782. /* */
  783. /* Arguments: */
  784. /* */
  785. /* pAdapter - Pointer to our adapter structure */
  786. /* pVc - Pointer to a VC, possibly NULL. */
  787. /* pRequest - Pointer to NDIS request, if this came via our CoRequest */
  788. /* handler. */
  789. /* Oid - the NDIS_OID to process. */
  790. /* InformationBuffer - Holds the data to be set. */
  791. /* InformationBufferLength - The length of InformationBuffer. */
  792. /* pBytesRead - If the call is successful, returns the number */
  793. /* of bytes read from InformationBuffer. */
  794. /* pBytesNeeded - If there is not enough data in InformationBuffer */
  795. /* to satisfy the OID, returns the amount of storage needed. */
  796. /* */
  797. /* Return: */
  798. /* */
  799. /* NDIS_STATUS */
  800. /* */
  801. /****************************************************************************/
  802. NDIS_STATUS
  803. DriverSetInformation(IN PRNDISMP_ADAPTER pAdapter,
  804. IN PRNDISMP_VC pVc OPTIONAL,
  805. IN PNDIS_REQUEST pRequest OPTIONAL,
  806. IN NDIS_OID Oid,
  807. IN PVOID InformationBuffer,
  808. IN ULONG InformationBufferLength,
  809. OUT PULONG pBytesRead,
  810. OUT PULONG pBytesNeeded)
  811. {
  812. NDIS_STATUS Status;
  813. TRACE2(("DriverSetInformation: Adapter %p, Oid %x\n", pAdapter, Oid));
  814. OID_NAME_TRACE(Oid, "DriverSet");
  815. Status = NDIS_STATUS_SUCCESS;
  816. switch(Oid)
  817. {
  818. case OID_GEN_CURRENT_LOOKAHEAD:
  819. // Verify the Length
  820. if(InformationBufferLength != sizeof(ULONG))
  821. Status = NDIS_STATUS_INVALID_LENGTH;
  822. *pBytesRead = sizeof(ULONG);
  823. break;
  824. case OID_PNP_SET_POWER:
  825. case OID_PNP_ADD_WAKE_UP_PATTERN:
  826. case OID_PNP_REMOVE_WAKE_UP_PATTERN:
  827. case OID_PNP_ENABLE_WAKE_UP:
  828. Status = NDIS_STATUS_NOT_SUPPORTED;
  829. break;
  830. #ifdef TESTING
  831. case OID_TCP_TASK_OFFLOAD:
  832. Status = NDIS_STATUS_SUCCESS;
  833. DbgPrint("RNDISMP: Set TCP_TASK_OFFLOAD\n");
  834. break;
  835. case OID_GEN_TRANSPORT_HEADER_OFFSET:
  836. Status = NDIS_STATUS_SUCCESS;
  837. break;
  838. #endif
  839. default:
  840. Status = NDIS_STATUS_INVALID_OID;
  841. break;
  842. }
  843. TRACE2(("Status (%08X) BytesRead (%08X)\n", Status, *pBytesRead));
  844. return Status;
  845. } // DriverSetInformation
  846. /****************************************************************************/
  847. /* DeviceSetInformation */
  848. /****************************************************************************/
  849. /* */
  850. /* Routine Description: */
  851. /* */
  852. /* The DeviceSetInformation processes a set request */
  853. /* that is going to the Remote NDIS device */
  854. /* */
  855. /* Arguments: */
  856. /* */
  857. /* pAdapter - pointer to our Adapter structure */
  858. /* pVc - optional pointer to our VC structure, if this is a per-Vc req. */
  859. /* pRequest - optional pointer to NDIS request, if CONDIS. */
  860. /* Oid - the NDIS_OID to process. */
  861. /* InformationBuffer - Holds the data to be set. */
  862. /* InformationBufferLength - The length of InformationBuffer. */
  863. /* pBytesRead - If the call is successful, returns the number */
  864. /* of bytes read from InformationBuffer. */
  865. /* pBytesNeeded - If there is not enough data in InformationBuffer */
  866. /* to satisfy the OID, returns the amount of storage needed. */
  867. /* */
  868. /* Return: */
  869. /* */
  870. /* NDIS_STATUS */
  871. /* */
  872. /****************************************************************************/
  873. NDIS_STATUS
  874. DeviceSetInformation(IN PRNDISMP_ADAPTER pAdapter,
  875. IN PRNDISMP_VC pVc OPTIONAL,
  876. IN PNDIS_REQUEST pRequest OPTIONAL,
  877. IN NDIS_OID Oid,
  878. IN PVOID InformationBuffer,
  879. IN ULONG InformationBufferLength,
  880. OUT PULONG pBytesRead,
  881. OUT PULONG pBytesNeeded)
  882. {
  883. PRNDISMP_MESSAGE_FRAME pMsgFrame;
  884. PRNDISMP_REQUEST_CONTEXT pReqContext;
  885. NDIS_STATUS Status;
  886. TRACE2(("DeviceSetInformation: Adapter %p, Oid %x\n"));
  887. OID_NAME_TRACE(Oid, "DeviceSet");
  888. #if DBG
  889. if (Oid == OID_GEN_CURRENT_PACKET_FILTER)
  890. {
  891. PULONG pFilter = (PULONG)InformationBuffer;
  892. TRACE1(("DeviceSetInfo: Adapter %p: Setting packet filter to %x\n",
  893. pAdapter, *pFilter));
  894. }
  895. #endif
  896. do
  897. {
  898. if (pAdapter->Halting)
  899. {
  900. TRACE1(("DeviceSetInfo: Adapter %p is halting: succeeding Oid %x\n",
  901. pAdapter, Oid));
  902. Status = NDIS_STATUS_SUCCESS;
  903. break;
  904. }
  905. pReqContext = AllocateRequestContext(pAdapter);
  906. if (pReqContext == NULL)
  907. {
  908. Status = NDIS_STATUS_RESOURCES;
  909. break;
  910. }
  911. pMsgFrame = BuildRndisMessageCommon(pAdapter,
  912. pVc,
  913. REMOTE_NDIS_SET_MSG,
  914. Oid,
  915. InformationBuffer,
  916. InformationBufferLength);
  917. // see if we got a message
  918. if (!pMsgFrame)
  919. {
  920. Status = NDIS_STATUS_RESOURCES;
  921. FreeRequestContext(pAdapter, pReqContext);
  922. break;
  923. }
  924. Status = NDIS_STATUS_PENDING;
  925. pReqContext->InformationBuffer = InformationBuffer;
  926. pReqContext->InformationBufferLength = InformationBufferLength;
  927. pReqContext->pBytesRead = pBytesRead;
  928. pReqContext->pBytesWritten = NULL;
  929. pReqContext->pBytesNeeded = pBytesNeeded;
  930. pReqContext->Oid = Oid;
  931. pReqContext->RetryCount = 0;
  932. pReqContext->bInternal = FALSE;
  933. pReqContext->pVc = pVc;
  934. pReqContext->pNdisRequest = pRequest;
  935. pMsgFrame->pReqContext = pReqContext;
  936. #ifndef BUILD_WIN9X
  937. // Add a ref to keep the frame around until we complete the request.
  938. ReferenceMsgFrame(pMsgFrame);
  939. // send the message to the microport
  940. RNDISMP_SEND_TO_MICROPORT(pAdapter, pMsgFrame, TRUE, CompleteSendDeviceRequest);
  941. #else
  942. //
  943. // Win9X!
  944. //
  945. // Special-case for setting the current packet filter to 0.
  946. // We complete this one synchronously, otherwise NdisCloseAdapter
  947. // doesn't seem to complete.
  948. //
  949. if ((Oid == OID_GEN_CURRENT_PACKET_FILTER )
  950. &&
  951. ( (*(PULONG)InformationBuffer == 0) || (pAdapter->bRunningOnWin98Gold) ))
  952. {
  953. //
  954. // Do not queue the request, so that when we get a completion
  955. // from the device, we simply drop it.
  956. //
  957. RNDISMP_SEND_TO_MICROPORT(pAdapter, pMsgFrame, FALSE, CompleteSendDiscardDeviceRequest);
  958. Status = NDIS_STATUS_SUCCESS;
  959. }
  960. else
  961. {
  962. // Add a ref to keep the frame around until we complete the request.
  963. ReferenceMsgFrame(pMsgFrame);
  964. // send the message to the microport
  965. RNDISMP_SEND_TO_MICROPORT(pAdapter, pMsgFrame, TRUE, CompleteSendDeviceRequest);
  966. }
  967. #endif // BUILD_WIN9X
  968. break;
  969. }
  970. while (FALSE);
  971. return Status;
  972. } // DeviceSetInformation
  973. /****************************************************************************/
  974. /* QuerySetCompletionMessage */
  975. /****************************************************************************/
  976. /* */
  977. /* Routine Description: */
  978. /* */
  979. /* Completion message from microport in response to query or set message */
  980. /* miniport sent. This information is now ready to pass to upper layers */
  981. /* since the original call into the miniport returned STATUS_PENDING */
  982. /* */
  983. /* Danger Danger - an OID_GEN_SUPPORTED_LIST query is special cased here */
  984. /* This is only sent to the device from the adapter init routine to build */
  985. /* a list of OIDs supported by the driver and device. */
  986. /* All OID_GEN_SUPPORTED_LIST queries from upper layers are handled by */
  987. /* the driver and not the device. */
  988. /* */
  989. /* Arguments: */
  990. /* */
  991. /* pAdapter - Pointer to our adapter structure */
  992. /* pMessage - pointer to RNDIS message */
  993. /* pMdl - pointer to MDL from microport */
  994. /* TotalLength - length of complete message */
  995. /* MicroportMessageContext - context for message from microport */
  996. /* ReceiveStatus - used by microport to indicate it is low on resource */
  997. /* bMessageCopied - is this a copy of the original message? */
  998. /* */
  999. /* Return: */
  1000. /* */
  1001. /* BOOLEAN - should the message be returned to the microport? */
  1002. /* */
  1003. /****************************************************************************/
  1004. BOOLEAN
  1005. QuerySetCompletionMessage(IN PRNDISMP_ADAPTER pAdapter,
  1006. IN PRNDIS_MESSAGE pMessage,
  1007. IN PMDL pMdl,
  1008. IN ULONG TotalLength,
  1009. IN NDIS_HANDLE MicroportMessageContext,
  1010. IN NDIS_STATUS ReceiveStatus,
  1011. IN BOOLEAN bMessageCopied)
  1012. {
  1013. PRNDISMP_MESSAGE_FRAME pMsgFrame;
  1014. PRNDISMP_REQUEST_CONTEXT pReqContext;
  1015. PRNDIS_QUERY_COMPLETE pQueryComplMessage;
  1016. PRNDIS_SET_COMPLETE pSetComplMessage;
  1017. UINT32 NdisMessageType;
  1018. NDIS_STATUS Status;
  1019. UINT BytesWritten;
  1020. UINT BytesRead;
  1021. BOOLEAN bInternal;
  1022. TRACE3(("QuerySetCompletionMessage\n"));
  1023. pReqContext = NULL;
  1024. pMsgFrame = NULL;
  1025. pQueryComplMessage = RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(pMessage);
  1026. pSetComplMessage = RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(pMessage);
  1027. bInternal = FALSE;
  1028. NdisMessageType = 0xdead;
  1029. Status = NDIS_STATUS_SUCCESS;
  1030. do
  1031. {
  1032. // get request frame from request ID in message
  1033. RNDISMP_LOOKUP_PENDING_MESSAGE(pMsgFrame, pAdapter, pQueryComplMessage->RequestId);
  1034. if (pMsgFrame == NULL)
  1035. {
  1036. // invalid request ID or aborted request.
  1037. TRACE1(("Invalid/aborted request ID %08X in Query/Set Complete msg %p\n",
  1038. pQueryComplMessage->RequestId, pQueryComplMessage));
  1039. break;
  1040. }
  1041. pReqContext = pMsgFrame->pReqContext;
  1042. ASSERT(pReqContext != NULL);
  1043. bInternal = pReqContext->bInternal;
  1044. NdisMessageType = pMessage->NdisMessageType;
  1045. if (NdisMessageType != RNDIS_COMPLETION(pMsgFrame->NdisMessageType))
  1046. {
  1047. TRACE1(("Query/Response mismatch: Msg @ %p, ReqId %d, req type %X, compl type %X\n",
  1048. pMessage,
  1049. pQueryComplMessage->RequestId,
  1050. pMsgFrame->NdisMessageType,
  1051. NdisMessageType));
  1052. ASSERT(FALSE);
  1053. pMsgFrame = NULL;
  1054. Status = NDIS_STATUS_FAILURE;
  1055. break;
  1056. }
  1057. switch(NdisMessageType)
  1058. {
  1059. // a query complete message indicates we have a response
  1060. // to a query message the miniport sent down. we carry around
  1061. // appropriate context so we can indicate the completion
  1062. // to upper layers and pass the query data up
  1063. //
  1064. // OID_GEN_SUPPORTED_LIST is a special case since it
  1065. // is never indicated to upper layers from the device
  1066. case REMOTE_NDIS_QUERY_CMPLT:
  1067. // an OID_GEN_SUPPORTED_LIST is never completed to the upper
  1068. // layers. This is sent from our adapter init routine
  1069. // in preparation for building a list of OIDs
  1070. TRACE2(("QueryCompl: pReqContext %p, OID %08X, pMsgFrame %p, %d bytes, Status %x\n",
  1071. pReqContext,
  1072. pReqContext->Oid,
  1073. pMsgFrame,
  1074. pQueryComplMessage->InformationBufferLength,
  1075. pQueryComplMessage->Status));
  1076. pReqContext->CompletionStatus = pQueryComplMessage->Status;
  1077. if (pReqContext->Oid == OID_GEN_SUPPORTED_LIST)
  1078. {
  1079. if (pReqContext->CompletionStatus == NDIS_STATUS_SUCCESS)
  1080. {
  1081. // Build a list of supported OIDs.
  1082. TRACE1(("QueryComplete: SupportedList: InfoBufLength %d (%d OIDs)\n",
  1083. pQueryComplMessage->InformationBufferLength,
  1084. pQueryComplMessage->InformationBufferLength/sizeof(NDIS_OID)));
  1085. Status = BuildOIDLists(pAdapter,
  1086. (PNDIS_OID) (((PUCHAR)(pQueryComplMessage)) +
  1087. pQueryComplMessage->InformationBufferOffset),
  1088. pQueryComplMessage->InformationBufferLength / sizeof(NDIS_OID),
  1089. pAdapter->DriverOIDList,
  1090. pAdapter->NumDriverOIDs);
  1091. }
  1092. // the adapter init routine is waiting for a response
  1093. NdisSetEvent(pReqContext->pEvent);
  1094. break;
  1095. }
  1096. // something other than OID_GEN_SUPPORTED_LIST
  1097. *pReqContext->pBytesNeeded = pQueryComplMessage->InformationBufferLength;
  1098. if (pQueryComplMessage->InformationBufferLength > pReqContext->InformationBufferLength)
  1099. {
  1100. TRACE0(("Query Complete (Oid = %08X): InfoBuffLen %d < %d\n",
  1101. pReqContext->Oid,
  1102. pQueryComplMessage->InformationBufferLength,
  1103. pReqContext->InformationBufferLength));
  1104. Status = NDIS_STATUS_BUFFER_TOO_SHORT;
  1105. break;
  1106. }
  1107. if (pQueryComplMessage->Status != RNDIS_STATUS_SUCCESS)
  1108. {
  1109. TRACE0(("Query Complete (Oid = %08X): error status %08X\n",
  1110. pReqContext->Oid, pQueryComplMessage->Status));
  1111. *pReqContext->pBytesNeeded = pQueryComplMessage->InformationBufferLength;
  1112. *pReqContext->pBytesWritten = 0;
  1113. Status = pQueryComplMessage->Status;
  1114. }
  1115. else
  1116. {
  1117. // copy information from RNDIS message to NDIS buffer passed down
  1118. TRACE2(("QueryCompl: copy %d bytes to %p\n",
  1119. pQueryComplMessage->InformationBufferLength,
  1120. pReqContext->InformationBuffer));
  1121. RNDISMP_MOVE_MEM(pReqContext->InformationBuffer,
  1122. MESSAGE_TO_INFO_BUFFER(pQueryComplMessage),
  1123. pQueryComplMessage->InformationBufferLength);
  1124. // tell the upper layers the size
  1125. *pReqContext->pBytesWritten = pQueryComplMessage->InformationBufferLength;
  1126. BytesWritten = *pReqContext->pBytesWritten;
  1127. TRACE3(("Query Compl OK: Adapter %p, Oid %x\n",
  1128. pAdapter, pReqContext->Oid));
  1129. TRACE2(("Info Data (%08X)\n", *((PUINT) pReqContext->InformationBuffer)));
  1130. if (pReqContext->Oid == OID_GEN_MEDIA_CONNECT_STATUS)
  1131. {
  1132. TRACE3(("Adapter %p: link is %s\n",
  1133. pAdapter, (((*(PULONG)pReqContext->InformationBuffer) == NdisMediaStateConnected)?
  1134. "Connected": "Not connected")));
  1135. }
  1136. if (pReqContext->Oid == OID_GEN_MAC_OPTIONS)
  1137. {
  1138. PULONG pMacOptions = (PULONG)pReqContext->InformationBuffer;
  1139. ULONG MacOptions = *pMacOptions;
  1140. TRACE1(("Adapter %p: OID_GEN_MAC_OPTIONS from device is %x\n",
  1141. pAdapter, MacOptions));
  1142. //
  1143. // We only let the device dictate some of these bits.
  1144. //
  1145. MacOptions = (MacOptions & RNDIS_DEVICE_MAC_OPTIONS_MASK) |
  1146. pAdapter->MacOptions;
  1147. *pMacOptions = MacOptions;
  1148. TRACE1(("Adapter %p: Modified OID_GEN_MAC_OPTIONS is %x\n",
  1149. pAdapter, *pMacOptions));
  1150. }
  1151. #if 0
  1152. //
  1153. // Temp hack for old-firmware Peracom devices - report a smaller
  1154. // value for max multicast list aize.
  1155. //
  1156. if (pReqContext->Oid == OID_802_3_MAXIMUM_LIST_SIZE)
  1157. {
  1158. PULONG pListSize = (PULONG)pReqContext->InformationBuffer;
  1159. if (*pListSize > 64)
  1160. {
  1161. TRACE1(("Adapter %p: Truncating max multicast list size from %d to 63!\n",
  1162. pAdapter, *pListSize));
  1163. *pListSize = 64;
  1164. }
  1165. }
  1166. #endif
  1167. //
  1168. // If this is an internally generated query,
  1169. // wake up the originating thread - that thread will
  1170. // take care of freeing resources.
  1171. //
  1172. if (bInternal && pReqContext->pEvent)
  1173. {
  1174. NdisSetEvent(pReqContext->pEvent);
  1175. pMsgFrame = NULL;
  1176. pReqContext = NULL;
  1177. }
  1178. Status = NDIS_STATUS_SUCCESS;
  1179. }
  1180. break;
  1181. case REMOTE_NDIS_SET_CMPLT:
  1182. TRACE2(("SetCompl: OID %08X, pReq %p, Status %x\n",
  1183. pReqContext->Oid,
  1184. pReqContext,
  1185. pSetComplMessage->Status));
  1186. if (pSetComplMessage->Status == RNDIS_STATUS_SUCCESS)
  1187. {
  1188. *pReqContext->pBytesRead = pReqContext->InformationBufferLength;
  1189. BytesRead = *pReqContext->pBytesRead;
  1190. Status = NDIS_STATUS_SUCCESS;
  1191. }
  1192. else
  1193. {
  1194. // don't really expect to see this other than via NDISTEST
  1195. TRACE1(("Set Complete (Oid = %08X) failure: %08X\n",
  1196. pReqContext->Oid,
  1197. pSetComplMessage->Status));
  1198. *pReqContext->pBytesRead = 0;
  1199. BytesRead = 0;
  1200. Status = pSetComplMessage->Status;
  1201. }
  1202. pReqContext->CompletionStatus = Status;
  1203. if (bInternal && pReqContext->pEvent)
  1204. {
  1205. NdisSetEvent(pReqContext->pEvent);
  1206. pMsgFrame = NULL;
  1207. pReqContext = NULL;
  1208. }
  1209. break;
  1210. default:
  1211. TRACE1(("Invalid Ndis Message Type (%08X)\n", NdisMessageType));
  1212. ASSERT(FALSE); // we shouldn't have sent an invalid message type!
  1213. break;
  1214. }
  1215. break;
  1216. }
  1217. while (FALSE);
  1218. //
  1219. // Send the completion to the upper layers unless it was a request
  1220. // we generated outselves.
  1221. //
  1222. if (!bInternal && pReqContext)
  1223. {
  1224. if (pReqContext->pNdisRequest)
  1225. {
  1226. NdisMCoRequestComplete(Status,
  1227. pAdapter->MiniportAdapterHandle,
  1228. pReqContext->pNdisRequest);
  1229. }
  1230. else
  1231. {
  1232. if (NdisMessageType == REMOTE_NDIS_QUERY_CMPLT)
  1233. {
  1234. TRACE3(("Status (%08X) BytesWritten (%08X)\n", Status, BytesWritten));
  1235. // complete the query
  1236. NdisMQueryInformationComplete(pAdapter->MiniportAdapterHandle,
  1237. Status);
  1238. }
  1239. else if (NdisMessageType == REMOTE_NDIS_SET_CMPLT)
  1240. {
  1241. TRACE3(("Status (%08X) BytesRead (%08X)\n", Status, BytesRead));
  1242. // complete the set
  1243. NdisMSetInformationComplete(pAdapter->MiniportAdapterHandle,
  1244. Status);
  1245. }
  1246. }
  1247. }
  1248. if (pReqContext)
  1249. {
  1250. FreeRequestContext(pAdapter, pReqContext);
  1251. }
  1252. if (pMsgFrame)
  1253. {
  1254. DereferenceMsgFrame(pMsgFrame);
  1255. }
  1256. return (TRUE);
  1257. } // QuerySetCompletionMessage
  1258. /****************************************************************************/
  1259. /* CompleteSendDeviceRequest */
  1260. /****************************************************************************/
  1261. /* */
  1262. /* Routine Description: */
  1263. /* */
  1264. /* Completion of send of a device set or query request thru the microport. */
  1265. /* If the message send failed, complete the request right now. */
  1266. /* */
  1267. /* Arguments: */
  1268. /* */
  1269. /* pMsgFrame - our context for the message */
  1270. /* SendStatus - microport's send status */
  1271. /* */
  1272. /* Return: */
  1273. /* */
  1274. /* None. */
  1275. /* */
  1276. /****************************************************************************/
  1277. VOID
  1278. CompleteSendDeviceRequest(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
  1279. IN NDIS_STATUS SendStatus)
  1280. {
  1281. PRNDISMP_ADAPTER pAdapter;
  1282. PRNDISMP_MESSAGE_FRAME pOrgMsgFrame;
  1283. PRNDISMP_REQUEST_CONTEXT pReqContext;
  1284. UINT NdisMessageType;
  1285. pAdapter = pMsgFrame->pAdapter;
  1286. TRACE3(("CompleteSendDevice Request: Adapter %p, MsgFrame %p, Status %x\n",
  1287. pAdapter, pMsgFrame, SendStatus));
  1288. if (SendStatus != NDIS_STATUS_SUCCESS)
  1289. {
  1290. //
  1291. // Microport failed to send the Request message;
  1292. // attempt to fail the original NDIS request.
  1293. //
  1294. TRACE1(("CompleteSendDeviceReq: Adapter %p, MsgFrame %p, failed %x\n",
  1295. pAdapter, pMsgFrame, SendStatus));
  1296. RNDISMP_LOOKUP_PENDING_MESSAGE(pOrgMsgFrame, pAdapter, pMsgFrame->RequestId);
  1297. if (pOrgMsgFrame == pMsgFrame)
  1298. {
  1299. //
  1300. // The request has not been aborted, so complete it now.
  1301. //
  1302. pReqContext = pMsgFrame->pReqContext;
  1303. NdisMessageType = pMsgFrame->NdisMessageType;
  1304. TRACE1(("CompleteSendReq: Adapter %p: Device req send failed, Oid %x, retry count %d\n",
  1305. pAdapter, pReqContext->Oid, pReqContext->RetryCount));
  1306. if (NdisMessageType == REMOTE_NDIS_QUERY_MSG)
  1307. {
  1308. // complete the query
  1309. NdisMQueryInformationComplete(pAdapter->MiniportAdapterHandle,
  1310. SendStatus);
  1311. }
  1312. else if (NdisMessageType == REMOTE_NDIS_SET_MSG)
  1313. {
  1314. // complete the set
  1315. NdisMSetInformationComplete(pAdapter->MiniportAdapterHandle,
  1316. SendStatus);
  1317. }
  1318. else
  1319. {
  1320. ASSERT(FALSE);
  1321. }
  1322. FreeRequestContext(pAdapter, pReqContext);
  1323. pMsgFrame->pReqContext = (PRNDISMP_REQUEST_CONTEXT)UlongToPtr(0xbcbcbcbc);
  1324. //
  1325. // Deref for NDIS request completion:
  1326. //
  1327. DereferenceMsgFrame(pMsgFrame);
  1328. }
  1329. //
  1330. // else we failed to locate the request on the pending list;
  1331. // it must have been removed when aborting all requests due
  1332. // to a reset.
  1333. //
  1334. }
  1335. //
  1336. // else sent the message out successfully; wait for a response.
  1337. //
  1338. //
  1339. // Deref for send-complete:
  1340. //
  1341. DereferenceMsgFrame(pMsgFrame);
  1342. }
  1343. #ifdef BUILD_WIN9X
  1344. /****************************************************************************/
  1345. /* CompleteSendDiscardDeviceRequest */
  1346. /****************************************************************************/
  1347. /* */
  1348. /* Routine Description: */
  1349. /* */
  1350. /* Completion of send of a device set or query request thru the microport. */
  1351. /* The sender of the request just wants us to free it up here. */
  1352. /* */
  1353. /* Arguments: */
  1354. /* */
  1355. /* pMsgFrame - our context for the message */
  1356. /* SendStatus - microport's send status */
  1357. /* */
  1358. /* Return: */
  1359. /* */
  1360. /* None. */
  1361. /* */
  1362. /****************************************************************************/
  1363. VOID
  1364. CompleteSendDiscardDeviceRequest(IN PRNDISMP_MESSAGE_FRAME pMsgFrame,
  1365. IN NDIS_STATUS SendStatus)
  1366. {
  1367. PRNDISMP_ADAPTER pAdapter;
  1368. PRNDISMP_REQUEST_CONTEXT pReqContext;
  1369. pAdapter = pMsgFrame->pAdapter;
  1370. pReqContext = pMsgFrame->pReqContext;
  1371. TRACE1(("CompleteSendDiscard: Adapter %p, MsgFrame %p, ReqContext %p\n",
  1372. pAdapter, pMsgFrame, pReqContext));
  1373. FreeRequestContext(pAdapter, pReqContext);
  1374. DereferenceMsgFrame(pMsgFrame);
  1375. }
  1376. #endif // BUILD_WIN9X
  1377. /****************************************************************************/
  1378. /* BuildOIDLists */
  1379. /****************************************************************************/
  1380. /* */
  1381. /* Routine Description: */
  1382. /* */
  1383. /* Build list of supported OIDs and associated function pointers */
  1384. /* */
  1385. /* Arguments: */
  1386. /* */
  1387. /* Adapter - Adapter object */
  1388. /* DeviceOIDList - list of OIDs supported by the device */
  1389. /* NumDeviceOID - number of OIDs supported by device */
  1390. /* DriverOIDList - list of OIDs supported by the driver */
  1391. /* NumDriverOID - number of OIDs supported by driver */
  1392. /* */
  1393. /* Return: */
  1394. /* */
  1395. /* NDIS_STATUS */
  1396. /* */
  1397. /****************************************************************************/
  1398. NDIS_STATUS
  1399. BuildOIDLists(IN PRNDISMP_ADAPTER Adapter,
  1400. IN PNDIS_OID DeviceOIDList,
  1401. IN UINT NumDeviceOID,
  1402. IN PNDIS_OID DriverOIDList,
  1403. IN UINT NumDriverOID)
  1404. {
  1405. UINT DeviceIndex;
  1406. UINT DriverIndex;
  1407. UINT NumOID;
  1408. NDIS_STATUS Status;
  1409. PNDIS_OID OIDList;
  1410. PUINT OIDHandlerList;
  1411. TRACE3(("BuildOIDLists\n"));
  1412. ASSERT(DeviceOIDList);
  1413. ASSERT(DriverOIDList);
  1414. NumOID = NumDriverOID;
  1415. // see what OIDs are duplicated in the device and route
  1416. // those to the device
  1417. for(DeviceIndex = 0; DeviceIndex < NumDeviceOID; DeviceIndex++)
  1418. {
  1419. for(DriverIndex = 0; DriverIndex < NumDriverOID; DriverIndex++)
  1420. {
  1421. if(DeviceOIDList[DeviceIndex] == DriverOIDList[DriverIndex])
  1422. {
  1423. // this OID is supported by the device, so don't
  1424. // support in the driver, set to 0 for when we build new list
  1425. DriverOIDList[DriverIndex] = 0;
  1426. break;
  1427. }
  1428. }
  1429. // if no match, increment the OID count
  1430. if(DriverIndex == NumDriverOID)
  1431. NumOID++;
  1432. }
  1433. // allocate OID list
  1434. Status = MemAlloc(&Adapter->SupportedOIDList,
  1435. NumOID * sizeof(NDIS_OID));
  1436. // see if we got our buffer
  1437. if(Status == NDIS_STATUS_SUCCESS)
  1438. {
  1439. Adapter->SupportedOIDListSize = NumOID * sizeof(NDIS_OID);
  1440. }
  1441. else
  1442. {
  1443. Adapter->OIDHandlerList = (PUINT) NULL;
  1444. Adapter->OIDHandlerListSize = 0;
  1445. Adapter->SupportedOIDList = (PNDIS_OID) NULL;
  1446. Adapter->SupportedOIDListSize = 0;
  1447. Status = NDIS_STATUS_FAILURE;
  1448. goto BuildDone;
  1449. }
  1450. // allocate list to indicate whether the OID is device or driver supported
  1451. Status = MemAlloc(&Adapter->OIDHandlerList,
  1452. NumOID * sizeof(UINT));
  1453. // see if we got our buffer
  1454. if(Status == NDIS_STATUS_SUCCESS)
  1455. {
  1456. Adapter->OIDHandlerListSize = NumOID * sizeof(UINT);
  1457. }
  1458. else
  1459. {
  1460. // free up allocated OID list cause this allocation failed
  1461. MemFree(Adapter->SupportedOIDList, Adapter->SupportedOIDListSize);
  1462. Adapter->OIDHandlerList = (PUINT) NULL;
  1463. Adapter->OIDHandlerListSize = 0;
  1464. Adapter->SupportedOIDList = (PNDIS_OID) NULL;
  1465. Adapter->SupportedOIDListSize = 0;
  1466. Status = NDIS_STATUS_FAILURE;
  1467. goto BuildDone;
  1468. }
  1469. Adapter->NumOIDSupported = NumOID;
  1470. OIDHandlerList = Adapter->OIDHandlerList;
  1471. OIDList = Adapter->SupportedOIDList;
  1472. // O.K., build our lists
  1473. for(DriverIndex = 0; DriverIndex < NumDriverOID; DriverIndex++)
  1474. {
  1475. if(DriverOIDList[DriverIndex] != 0)
  1476. {
  1477. // got one, so add to the list
  1478. *OIDList = DriverOIDList[DriverIndex];
  1479. OIDList++;
  1480. // set flag
  1481. *OIDHandlerList = DRIVER_SUPPORTED_OID;
  1482. OIDHandlerList++;
  1483. }
  1484. }
  1485. // let's add device supported OIDs
  1486. for(DeviceIndex = 0; DeviceIndex < NumDeviceOID; DeviceIndex++)
  1487. {
  1488. if(DeviceOIDList[DeviceIndex] != 0)
  1489. {
  1490. // got one, so add to the list
  1491. *OIDList = DeviceOIDList[DeviceIndex];
  1492. OIDList++;
  1493. // set flag
  1494. *OIDHandlerList = DEVICE_SUPPORTED_OID;
  1495. OIDHandlerList++;
  1496. }
  1497. }
  1498. // Now do a fixup to point OID_GEN_SUPPORTED_LIST at the driver since
  1499. // we now have a complete list.
  1500. //
  1501. for(DeviceIndex = 0; DeviceIndex < Adapter->NumOIDSupported; DeviceIndex++)
  1502. {
  1503. if (Adapter->SupportedOIDList[DeviceIndex] == OID_GEN_SUPPORTED_LIST)
  1504. {
  1505. Adapter->OIDHandlerList[DeviceIndex] = DRIVER_SUPPORTED_OID;
  1506. }
  1507. }
  1508. BuildDone:
  1509. if(Status == NDIS_STATUS_SUCCESS)
  1510. {
  1511. DISPLAY_OID_LIST(Adapter);
  1512. }
  1513. return Status;
  1514. } // BuildOIDLists
  1515. /****************************************************************************/
  1516. /* GetOIDSupport */
  1517. /****************************************************************************/
  1518. /* */
  1519. /* Routine Description: */
  1520. /* */
  1521. /* Returns flag to indicate if OID is device or driver supported */
  1522. /* */
  1523. /* Arguments: */
  1524. /* */
  1525. /* Adapter - Adapter object */
  1526. /* Oid - looking for a match on this OID */
  1527. /* */
  1528. /* Return: */
  1529. /* */
  1530. /* UINT */
  1531. /* */
  1532. /****************************************************************************/
  1533. UINT
  1534. GetOIDSupport(IN PRNDISMP_ADAPTER Adapter, IN NDIS_OID Oid)
  1535. {
  1536. UINT Index;
  1537. TRACE3(("GetOIDSupport\n"));
  1538. // sanity check
  1539. ASSERT(Adapter->SupportedOIDList);
  1540. ASSERT(Adapter->OIDHandlerList);
  1541. // search for a match on the OID
  1542. for(Index = 0; Index < Adapter->NumOIDSupported; Index++)
  1543. {
  1544. if(Adapter->SupportedOIDList[Index] == Oid)
  1545. {
  1546. return Adapter->OIDHandlerList[Index];
  1547. }
  1548. }
  1549. return OID_NOT_SUPPORTED;
  1550. } // GetOIDSupport
  1551. /****************************************************************************/
  1552. /* FreeOIDLists */
  1553. /****************************************************************************/
  1554. /* */
  1555. /* Routine Description: */
  1556. /* */
  1557. /* Free OID and handler lists */
  1558. /* */
  1559. /* Arguments: */
  1560. /* */
  1561. /* Adapter - Adapter object */
  1562. /* */
  1563. /* Return: */
  1564. /* */
  1565. /* VOID */
  1566. /* */
  1567. /****************************************************************************/
  1568. VOID
  1569. FreeOIDLists(IN PRNDISMP_ADAPTER Adapter)
  1570. {
  1571. UINT Size1, Size2;
  1572. PUCHAR Buffer1, Buffer2;
  1573. TRACE3(("FreeOIDLists\n"));
  1574. // grab the spinlock
  1575. NdisAcquireSpinLock(&Adapter->Lock);
  1576. Buffer1 = (PUCHAR) Adapter->SupportedOIDList;
  1577. Size1 = Adapter->SupportedOIDListSize;
  1578. Buffer2 = (PUCHAR) Adapter->OIDHandlerList;
  1579. Size2 = Adapter->OIDHandlerListSize;
  1580. Adapter->SupportedOIDList = (PUINT) NULL;
  1581. Adapter->SupportedOIDListSize = 0;
  1582. Adapter->OIDHandlerList = (PUINT) NULL;
  1583. Adapter->OIDHandlerListSize = 0;
  1584. Adapter->NumOIDSupported = 0;
  1585. // release spinlock
  1586. NdisReleaseSpinLock(&Adapter->Lock);
  1587. if(Buffer1)
  1588. MemFree(Buffer1, Size1);
  1589. if(Buffer2)
  1590. MemFree(Buffer2, Size2);
  1591. } // FreeOIDLists
  1592. /****************************************************************************/
  1593. /* AllocateRequestContext */
  1594. /****************************************************************************/
  1595. /* */
  1596. /* Routine Description: */
  1597. /* */
  1598. /* Allocate a context structure to keep track of an NDIS request */
  1599. /* */
  1600. /* Arguments: */
  1601. /* */
  1602. /* pAdapter - Pointer to our adapter structure */
  1603. /* */
  1604. /* Return: */
  1605. /* */
  1606. /* PRNDISMP_REQUEST_CONTEXT */
  1607. /* */
  1608. /****************************************************************************/
  1609. PRNDISMP_REQUEST_CONTEXT
  1610. AllocateRequestContext(IN PRNDISMP_ADAPTER pAdapter)
  1611. {
  1612. NDIS_STATUS Status;
  1613. PRNDISMP_REQUEST_CONTEXT pReqContext;
  1614. Status = MemAlloc(&pReqContext, sizeof(RNDISMP_REQUEST_CONTEXT));
  1615. if (Status != NDIS_STATUS_SUCCESS)
  1616. {
  1617. pReqContext = NULL;
  1618. }
  1619. TRACE3(("AllocReqContext: %p\n", pReqContext));
  1620. return pReqContext;
  1621. } // AllocateRequestContext
  1622. /****************************************************************************/
  1623. /* FreeRequestContext */
  1624. /****************************************************************************/
  1625. /* */
  1626. /* Routine Description: */
  1627. /* */
  1628. /* Freeing up miniport resources associated with a request */
  1629. /* */
  1630. /* Arguments: */
  1631. /* */
  1632. /* pAdapter - Pointer to our adapter structure */
  1633. /* pReqContext - Pointer to request context to be freed */
  1634. /* */
  1635. /* Return: */
  1636. /* */
  1637. /* VOID */
  1638. /* */
  1639. /****************************************************************************/
  1640. VOID
  1641. FreeRequestContext(IN PRNDISMP_ADAPTER pAdapter,
  1642. IN PRNDISMP_REQUEST_CONTEXT pReqContext)
  1643. {
  1644. TRACE3(("FreeReqContext: %p\n", pReqContext));
  1645. MemFree(pReqContext, -1);
  1646. } // FreeRequestContext
  1647. /****************************************************************************/
  1648. /* SyncQueryDevice */
  1649. /****************************************************************************/
  1650. /* */
  1651. /* Routine Description: */
  1652. /* */
  1653. /* Init-time routine called to query the device for an OID, and wait */
  1654. /* until we get a response. */
  1655. /* */
  1656. /* Arguments: */
  1657. /* */
  1658. /* pAdapter - Pointer to our adapter structure */
  1659. /* Oid - Object Identifier to be queried */
  1660. /* InformationBuffer - buffer to copy query response into */
  1661. /* InformationBufferLength - length of the above */
  1662. /* */
  1663. /* Return: */
  1664. /* */
  1665. /* NDIS_STATUS_SUCCESS if successful, NDIS_STATUS_xxx error otherwise */
  1666. /* */
  1667. /****************************************************************************/
  1668. NDIS_STATUS
  1669. SyncQueryDevice(IN PRNDISMP_ADAPTER pAdapter,
  1670. IN NDIS_OID Oid,
  1671. IN OUT PUCHAR InformationBuffer,
  1672. IN ULONG InformationBufferLength)
  1673. {
  1674. NDIS_STATUS Status;
  1675. PRNDISMP_MESSAGE_FRAME pMsgFrame = NULL;
  1676. PRNDISMP_MESSAGE_FRAME pPendingMsgFrame;
  1677. PRNDISMP_REQUEST_CONTEXT pReqContext = NULL;
  1678. RNDIS_REQUEST_ID RequestId;
  1679. NDIS_EVENT Event;
  1680. BOOLEAN bWokenUp;
  1681. ULONG BytesNeeded, BytesWritten;
  1682. do
  1683. {
  1684. pReqContext = AllocateRequestContext(pAdapter);
  1685. if (pReqContext == NULL)
  1686. {
  1687. Status = NDIS_STATUS_RESOURCES;
  1688. break;
  1689. }
  1690. //
  1691. // Build a query message for the specified OID.
  1692. //
  1693. pMsgFrame = BuildRndisMessageCommon(pAdapter,
  1694. NULL,
  1695. REMOTE_NDIS_QUERY_MSG,
  1696. Oid,
  1697. (PVOID) NULL,
  1698. 0);
  1699. if (pMsgFrame == NULL)
  1700. {
  1701. Status = NDIS_STATUS_RESOURCES;
  1702. break;
  1703. }
  1704. //
  1705. // Context for the request - mark this as an internally generated
  1706. // request.
  1707. //
  1708. pReqContext->pNdisRequest = NULL;
  1709. pReqContext->Oid = Oid;
  1710. pReqContext->InformationBuffer = InformationBuffer;
  1711. pReqContext->InformationBufferLength = InformationBufferLength;
  1712. pReqContext->pBytesNeeded = &BytesNeeded;
  1713. pReqContext->pBytesWritten = &BytesWritten;
  1714. pReqContext->pBytesRead = NULL;
  1715. pReqContext->bInternal = TRUE;
  1716. pReqContext->CompletionStatus = NDIS_STATUS_DEVICE_FAILED;
  1717. NdisInitializeEvent(&Event);
  1718. pReqContext->pEvent = &Event;
  1719. pMsgFrame->pVc = NULL;
  1720. pMsgFrame->pReqContext = pReqContext;
  1721. RequestId = pMsgFrame->RequestId;
  1722. // send the message to the microport.
  1723. RNDISMP_SEND_TO_MICROPORT(pAdapter, pMsgFrame, TRUE, NULL);
  1724. RNDISMP_ASSERT_AT_PASSIVE();
  1725. bWokenUp = NdisWaitEvent(&Event, MINIPORT_INIT_TIMEOUT);
  1726. // remove the message from the pending queue - it may or may not be there.
  1727. RNDISMP_LOOKUP_PENDING_MESSAGE(pPendingMsgFrame, pAdapter, RequestId);
  1728. if (!bWokenUp || (pReqContext->CompletionStatus != NDIS_STATUS_SUCCESS))
  1729. {
  1730. TRACE1(("SyncQueryDevice error: Adapter %p, Oid %x, WokenUp %d, ComplStatus %x\n",
  1731. pAdapter, Oid, bWokenUp, pReqContext->CompletionStatus));
  1732. Status = NDIS_STATUS_DEVICE_FAILED;
  1733. break;
  1734. }
  1735. Status = NDIS_STATUS_SUCCESS;
  1736. }
  1737. while (FALSE);
  1738. if (pReqContext != NULL)
  1739. {
  1740. FreeRequestContext(pAdapter, pReqContext);
  1741. }
  1742. if (pMsgFrame != NULL)
  1743. {
  1744. DereferenceMsgFrame(pMsgFrame);
  1745. }
  1746. return (Status);
  1747. }