Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
17 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\mediasp.c
  5. Abstract:
  6. Media and Address Family Specific routines. These are exported routines
  7. that a media/AF specific module can call.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 06-02-97 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUMBER ' DEM'
  16. RWAN_STATUS
  17. RWanInitMediaSpecific(
  18. VOID
  19. )
  20. /*++
  21. Routine Description:
  22. Initialize all media/AF specific modules. For now, we just
  23. run through our list of media-specific Init routines and call
  24. each of them.
  25. Arguments:
  26. None
  27. Return Value:
  28. RWAN_STATUS_SUCCESS if initialization completed successfully for
  29. atleast one module, RWAN_STATUS_FAILURE otherwise.
  30. --*/
  31. {
  32. RWAN_STATUS RWanStatus;
  33. PRWAN_AFSP_MODULE_CHARS pModuleChars;
  34. INT SuccessfulInits;
  35. SuccessfulInits = 0;
  36. for (pModuleChars = &RWanMediaSpecificInfo[0];
  37. pModuleChars->pAfSpInitHandler != NULL;
  38. pModuleChars++)
  39. {
  40. RWanStatus = (*pModuleChars->pAfSpInitHandler)();
  41. if (RWanStatus == RWAN_STATUS_SUCCESS)
  42. {
  43. SuccessfulInits++;
  44. }
  45. }
  46. if (SuccessfulInits > 0)
  47. {
  48. return (RWAN_STATUS_SUCCESS);
  49. }
  50. else
  51. {
  52. return (RWAN_STATUS_FAILURE);
  53. }
  54. }
  55. VOID
  56. RWanShutdownMediaSpecific(
  57. VOID
  58. )
  59. /*++
  60. Routine Description:
  61. Tell all media/AF-specific modules to shut down.
  62. Arguments:
  63. None
  64. Return Value:
  65. None
  66. --*/
  67. {
  68. PRWAN_AFSP_MODULE_CHARS pModuleChars;
  69. for (pModuleChars = &RWanMediaSpecificInfo[0];
  70. pModuleChars->pAfSpInitHandler != NULL;
  71. pModuleChars++)
  72. {
  73. (*pModuleChars->pAfSpShutdownHandler)();
  74. }
  75. }
  76. RWAN_STATUS
  77. RWanAfSpRegisterNdisAF(
  78. IN PRWAN_NDIS_AF_CHARS pAfChars,
  79. IN RWAN_HANDLE AfSpContext,
  80. OUT PRWAN_HANDLE pRWanSpHandle
  81. )
  82. /*++
  83. Routine Description:
  84. This is called by a media-specific module to register support
  85. of an NDIS Address family for a particular medium. The characteristics
  86. structure contains the module's entry points for various media-specific
  87. operations.
  88. We create an AF_INFO structure to keep track of this AF+Medium,
  89. and return a pointer to it as the handle.
  90. Arguments:
  91. pAfChars - Entry points for the module
  92. AfSpContext - The media-specific module's context for this AF+medium
  93. pRWanSpHandle - Place to return our handle for this AF+medium
  94. Return Value:
  95. RWAN_STATUS_SUCCESS if the new NDIS AF+medium was successfully registered,
  96. RWAN_STATUS_RESOURCES if we failed due to lack of resources.
  97. XXX: Check for duplicates?
  98. --*/
  99. {
  100. PRWAN_NDIS_AF_INFO pAfInfo;
  101. RWAN_STATUS RWanStatus;
  102. do
  103. {
  104. RWAN_ALLOC_MEM(pAfInfo, RWAN_NDIS_AF_INFO, sizeof(RWAN_NDIS_AF_INFO));
  105. if (pAfInfo == NULL)
  106. {
  107. RWanStatus = RWAN_STATUS_RESOURCES;
  108. break;
  109. }
  110. RWAN_SET_SIGNATURE(pAfInfo, nai);
  111. pAfInfo->Flags = 0;
  112. RWAN_INIT_LIST(&pAfInfo->NdisAfList);
  113. RWAN_INIT_LIST(&pAfInfo->TdiProtocolList);
  114. RWAN_COPY_MEM(&pAfInfo->AfChars, pAfChars, sizeof(RWAN_NDIS_AF_CHARS));
  115. pAfInfo->AfSpContext = AfSpContext;
  116. RWAN_ACQUIRE_GLOBAL_LOCK();
  117. RWAN_INSERT_HEAD_LIST(&pRWanGlobal->AfInfoList,
  118. &pAfInfo->AfInfoLink);
  119. pRWanGlobal->AfInfoCount++;
  120. RWAN_RELEASE_GLOBAL_LOCK();
  121. *pRWanSpHandle = (RWAN_HANDLE)pAfInfo;
  122. RWanStatus = RWAN_STATUS_SUCCESS;
  123. break;
  124. }
  125. while (FALSE);
  126. return (RWanStatus);
  127. }
  128. RWAN_STATUS
  129. RWanAfSpDeregisterNdisAF(
  130. IN RWAN_HANDLE RWanSpAFHandle
  131. )
  132. /*++
  133. Routine Description:
  134. This is called by a media-specific module to deregister support
  135. of an NDIS Address family for a particular medium.
  136. Arguments:
  137. RWanSpAFHandle - Actually a pointer to an NDIS_AF_INFO block.
  138. Return Value:
  139. RWAN_STATUS_SUCCESS if we successfully completed the deregistration
  140. here, RWAN_STATUS_PENDING if there are open AFs or TDI protocols
  141. on this block.
  142. --*/
  143. {
  144. PRWAN_NDIS_AF_INFO pAfInfo;
  145. RWAN_STATUS RWanStatus;
  146. pAfInfo = (PRWAN_NDIS_AF_INFO)RWanSpAFHandle;
  147. RWAN_STRUCT_ASSERT(pAfInfo, nai);
  148. RWAN_ACQUIRE_GLOBAL_LOCK();
  149. //
  150. // See if all AF blocks and TDI protocols are gone.
  151. //
  152. if (RWAN_IS_LIST_EMPTY(&pAfInfo->TdiProtocolList) &&
  153. RWAN_IS_LIST_EMPTY(&pAfInfo->NdisAfList))
  154. {
  155. RWanStatus = RWAN_STATUS_SUCCESS;
  156. //
  157. // Remove this AF INFO block from the global list.
  158. //
  159. RWAN_DELETE_FROM_LIST(&pAfInfo->AfInfoLink);
  160. //
  161. // Free this AF INFO block.
  162. //
  163. RWAN_FREE_MEM(pAfInfo);
  164. }
  165. else
  166. {
  167. //
  168. // There is still some activity on this AF INFO.
  169. // Pend this request till all these go away.
  170. //
  171. RWanStatus = RWAN_STATUS_PENDING;
  172. RWAN_SET_BIT(pAfInfo->Flags, RWANF_AFI_CLOSING);
  173. RWAN_ASSERT(FALSE);
  174. }
  175. RWAN_RELEASE_GLOBAL_LOCK();
  176. return (RWanStatus);
  177. }
  178. RWAN_STATUS
  179. RWanAfSpRegisterTdiProtocol(
  180. IN RWAN_HANDLE RWanSpHandle,
  181. IN PRWAN_TDI_PROTOCOL_CHARS pTdiChars,
  182. OUT PRWAN_HANDLE pRWanProtHandle
  183. )
  184. /*++
  185. Routine Description:
  186. This is the API called by a media-specific module to register
  187. support for a TDI protocol over an NDIS AF. We create a TDI
  188. Protocol block and a device object to represent this protocol.
  189. Arguments:
  190. RWanSpHandle - Actually a pointer to our NDIS_AF_INFO structure
  191. pTdiChars - Characteristics of the protocol being registered
  192. pRWanProtHandle - Place to return our context for this protocol
  193. Return Value:
  194. RWAN_STATUS_SUCCESS if we successfully registered this TDI protocol,
  195. RWAN_STATUS_XXX error code otherwise.
  196. --*/
  197. {
  198. RWAN_STATUS RWanStatus;
  199. PRWAN_NDIS_AF_INFO pAfInfo;
  200. PRWAN_TDI_PROTOCOL pProtocol;
  201. #ifdef NT
  202. PRWAN_DEVICE_OBJECT pRWanDeviceObject;
  203. NTSTATUS Status;
  204. #endif // NT
  205. pAfInfo = (PRWAN_NDIS_AF_INFO)RWanSpHandle;
  206. RWAN_STRUCT_ASSERT(pAfInfo, nai);
  207. pProtocol = NULL;
  208. pRWanDeviceObject = NULL;
  209. do
  210. {
  211. RWAN_ALLOC_MEM(pProtocol, RWAN_TDI_PROTOCOL, sizeof(RWAN_TDI_PROTOCOL));
  212. if (pProtocol == NULL)
  213. {
  214. RWanStatus = RWAN_STATUS_RESOURCES;
  215. break;
  216. }
  217. RWAN_SET_SIGNATURE(pProtocol, ntp);
  218. pProtocol->pAfInfo = pAfInfo;
  219. pProtocol->TdiProtocol = pTdiChars->TdiProtocol;
  220. pProtocol->SockAddressFamily = pTdiChars->SockAddressFamily;
  221. pProtocol->SockProtocol = pTdiChars->SockProtocol;
  222. pProtocol->TdiProtocol = pTdiChars->TdiProtocol;
  223. pProtocol->SockType = pTdiChars->SockType;
  224. pProtocol->bAllowAddressObjects = pTdiChars->bAllowAddressObjects;
  225. pProtocol->bAllowConnObjects = pTdiChars->bAllowConnObjects;
  226. pProtocol->pAfSpDeregTdiProtocolComplete =
  227. pTdiChars->pAfSpDeregTdiProtocolComplete;
  228. pProtocol->ProviderInfo = pTdiChars->ProviderInfo;
  229. RWAN_INIT_LIST(&pProtocol->AddrObjList);
  230. #ifdef NT
  231. //
  232. // Create an I/O Device on which we can receive IRPs for this
  233. // protocol.
  234. //
  235. RWAN_ALLOC_MEM(pRWanDeviceObject, RWAN_DEVICE_OBJECT, sizeof(RWAN_DEVICE_OBJECT));
  236. if (pRWanDeviceObject == NULL)
  237. {
  238. RWanStatus = RWAN_STATUS_RESOURCES;
  239. break;
  240. }
  241. RWAN_SET_SIGNATURE(pRWanDeviceObject, ndo);
  242. pRWanDeviceObject->pProtocol = pProtocol;
  243. pProtocol->pRWanDeviceObject = (PVOID)pRWanDeviceObject;
  244. //
  245. // Create the device now. A pointer's worth of space is requested
  246. // in the device extension.
  247. //
  248. Status = IoCreateDevice(
  249. pRWanGlobal->pDriverObject,
  250. sizeof(PRWAN_DEVICE_OBJECT),
  251. pTdiChars->pDeviceName,
  252. FILE_DEVICE_NETWORK,
  253. 0,
  254. FALSE,
  255. &(pRWanDeviceObject->pDeviceObject)
  256. );
  257. if (!NT_SUCCESS(Status))
  258. {
  259. RWanStatus = RWAN_STATUS_FAILURE;
  260. break;
  261. }
  262. //
  263. // Store a pointer to our device context in the
  264. // NT device object extension.
  265. //
  266. *(PRWAN_DEVICE_OBJECT *)(pRWanDeviceObject->pDeviceObject->DeviceExtension) =
  267. pRWanDeviceObject;
  268. RWAN_ACQUIRE_GLOBAL_LOCK();
  269. RWAN_INSERT_HEAD_LIST(&(pRWanGlobal->DeviceObjList),
  270. &(pRWanDeviceObject->DeviceObjectLink));
  271. //
  272. // Add this Protocol to the list of TDI protocols on the
  273. // AF INFO block.
  274. //
  275. RWAN_INSERT_TAIL_LIST(&(pAfInfo->TdiProtocolList),
  276. &(pProtocol->AfInfoLink));
  277. //
  278. // Add this Protocol to the global list of TDI protocols.
  279. //
  280. RWAN_INSERT_TAIL_LIST(&(pRWanGlobal->ProtocolList),
  281. &(pProtocol->TdiProtocolLink));
  282. pRWanGlobal->ProtocolCount++;
  283. RWAN_RELEASE_GLOBAL_LOCK();
  284. #endif // NT
  285. RWanStatus = RWAN_STATUS_SUCCESS;
  286. *pRWanProtHandle = (RWAN_HANDLE)pProtocol;
  287. break;
  288. }
  289. while (FALSE);
  290. if (RWanStatus != RWAN_STATUS_SUCCESS)
  291. {
  292. if (pProtocol != NULL)
  293. {
  294. RWAN_FREE_MEM(pProtocol);
  295. }
  296. #ifdef NT
  297. if (pRWanDeviceObject != NULL)
  298. {
  299. RWAN_FREE_MEM(pRWanDeviceObject);
  300. }
  301. #endif // NT
  302. }
  303. return (RWanStatus);
  304. }
  305. VOID
  306. RWanAfSpDeregisterTdiProtocol(
  307. IN RWAN_HANDLE RWanProtHandle
  308. )
  309. /*++
  310. Routine Description:
  311. This is the API called by a media-specific module to de-register
  312. support for a TDI protocol. We delete the TDI Protocol block
  313. that holds information about this protocol.
  314. Arguments:
  315. RWanProtHandle - Pointer to the TDI Protocol block
  316. Return Value:
  317. None
  318. --*/
  319. {
  320. PRWAN_TDI_PROTOCOL pProtocol;
  321. PRWAN_NDIS_AF_INFO pAfInfo;
  322. #ifdef NT
  323. PRWAN_DEVICE_OBJECT pRWanDeviceObject;
  324. #endif // NT
  325. pProtocol = (PRWAN_TDI_PROTOCOL)RWanProtHandle;
  326. RWAN_STRUCT_ASSERT(pProtocol, ntp);
  327. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pProtocol->AddrObjList));
  328. //
  329. // Unlink this TDI protocol.
  330. //
  331. RWAN_ACQUIRE_GLOBAL_LOCK();
  332. RWAN_DELETE_FROM_LIST(&(pProtocol->TdiProtocolLink));
  333. RWAN_DELETE_FROM_LIST(&(pProtocol->AfInfoLink));
  334. pRWanGlobal->ProtocolCount--;
  335. RWAN_RELEASE_GLOBAL_LOCK();
  336. #ifdef NT
  337. //
  338. // Delete the I/O device we'd created for this protocol.
  339. //
  340. pRWanDeviceObject = (PRWAN_DEVICE_OBJECT)pProtocol->pRWanDeviceObject;
  341. RWAN_ASSERT(pRWanDeviceObject != NULL);
  342. IoDeleteDevice(pRWanDeviceObject->pDeviceObject);
  343. RWAN_FREE_MEM(pRWanDeviceObject);
  344. #endif // NT
  345. RWAN_FREE_MEM(pProtocol);
  346. return;
  347. }
  348. VOID
  349. RWanAfSpOpenAfComplete(
  350. IN RWAN_STATUS RWanStatus,
  351. IN RWAN_HANDLE RWanAfHandle,
  352. IN RWAN_HANDLE AfSpAFContext,
  353. IN ULONG MaxMessageSize
  354. )
  355. /*++
  356. Routine Description:
  357. This is called by an AF-specific module to signify completion
  358. of our call to its OpenAfHandler routine. If the AF-specific module
  359. has successfully set up its context for this AF open, we store
  360. its context for this in our NDIS AF structure.
  361. Otherwise, we tear down this AF.
  362. Arguments:
  363. RWanStatus - Final status of our call to AF-specific module's AfOpen handler
  364. RWanAfHandle - Our context for an NDIS AF Open
  365. AfSpAFContext - AF-Specific module's context for this Open
  366. MaxMessageSize - Max message size for this AF
  367. Return Value:
  368. None
  369. --*/
  370. {
  371. PRWAN_NDIS_AF pAf;
  372. PRWAN_NDIS_ADAPTER pAdapter;
  373. PRWAN_NDIS_AF_INFO pAfInfo;
  374. PLIST_ENTRY pEnt;
  375. PRWAN_TDI_PROTOCOL pTdiProtocol;
  376. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  377. RWAN_STRUCT_ASSERT(pAf, naf);
  378. pAdapter = pAf->pAdapter;
  379. if (RWanStatus == RWAN_STATUS_SUCCESS)
  380. {
  381. RWAN_ACQUIRE_ADAPTER_LOCK(pAdapter);
  382. RWAN_ACQUIRE_AF_LOCK_DPC(pAf);
  383. pAf->AfSpAFContext = AfSpAFContext;
  384. RWAN_SET_BIT(pAf->Flags, RWANF_AF_IN_ADAPTER_LIST);
  385. //
  386. // Add this AF to the adapter's list of open AFs.
  387. //
  388. RWAN_INSERT_HEAD_LIST(&(pAdapter->AfList),
  389. &(pAf->AfLink));
  390. RWAN_RELEASE_AF_LOCK_DPC(pAf);
  391. #if 0
  392. RWanReferenceAdapter(pAdapter); // AF linkage
  393. #endif
  394. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  395. RWAN_ACQUIRE_GLOBAL_LOCK();
  396. pAfInfo = pAf->pAfInfo;
  397. for (pEnt = pAfInfo->TdiProtocolList.Flink;
  398. pEnt != &pAfInfo->TdiProtocolList;
  399. pEnt = pEnt->Flink)
  400. {
  401. pTdiProtocol = CONTAINING_RECORD(pEnt, RWAN_TDI_PROTOCOL, AfInfoLink);
  402. pTdiProtocol->ProviderInfo.MaxSendSize =
  403. MIN(pTdiProtocol->ProviderInfo.MaxSendSize, MaxMessageSize);
  404. }
  405. RWAN_RELEASE_GLOBAL_LOCK();
  406. }
  407. else
  408. {
  409. RWanShutdownAf(pAf);
  410. }
  411. }
  412. VOID
  413. RWanAfSpCloseAfComplete(
  414. IN RWAN_HANDLE RWanAfHandle
  415. )
  416. /*++
  417. Routine Description:
  418. This is called by an AF-specific module to signify completion
  419. of our call to its CloseAfHandler routine.
  420. We now call NDIS to close this AF.
  421. Arguments:
  422. RWanAfHandle - Our context for an NDIS AF Open
  423. Return Value:
  424. None
  425. --*/
  426. {
  427. PRWAN_NDIS_AF pAf;
  428. NDIS_HANDLE NdisAfHandle;
  429. NDIS_STATUS Status;
  430. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  431. RWAN_STRUCT_ASSERT(pAf, naf);
  432. RWAN_ACQUIRE_AF_LOCK(pAf);
  433. pAf->AfSpAFContext = NULL;
  434. NdisAfHandle = pAf->NdisAfHandle;
  435. RWAN_RELEASE_AF_LOCK(pAf);
  436. RWANDEBUGP(DL_LOUD, DC_BIND,
  437. ("AfSpCloseAfComplete: pAf x%x, will CloseAF, AfHandle x%x\n",
  438. pAf, NdisAfHandle));
  439. Status = NdisClCloseAddressFamily(NdisAfHandle);
  440. if (Status != NDIS_STATUS_PENDING)
  441. {
  442. RWanNdisCloseAddressFamilyComplete(
  443. Status,
  444. (NDIS_HANDLE)pAf
  445. );
  446. }
  447. }
  448. RWAN_STATUS
  449. RWanAfSpSendAdapterRequest(
  450. IN RWAN_HANDLE RWanAfHandle,
  451. IN RWAN_HANDLE AfSpReqContext,
  452. IN NDIS_REQUEST_TYPE RequestType,
  453. IN NDIS_OID Oid,
  454. IN PVOID pBuffer,
  455. IN ULONG BufferLength
  456. )
  457. /*++
  458. Routine Description:
  459. Send an NDIS Request down to the miniport on behalf of the media
  460. specific module.
  461. Arguments:
  462. RWanAfHandle - Our context for an NDIS AF Open
  463. AfSpReqContext - The caller's context for this request
  464. RequestType - NDIS request type
  465. Oid - The object being set or queried
  466. pBuffer - Points to parameter value
  467. BufferLength - Length of the above
  468. Return Value:
  469. RWAN_STATUS_PENDING if the request was sent to the miniport,
  470. RWAN_STATUS_RESOURCES if we couldn't allocate resources for the
  471. request.
  472. --*/
  473. {
  474. PRWAN_NDIS_AF pAf;
  475. NDIS_HANDLE NdisAdapterHandle;
  476. PNDIS_REQUEST pNdisRequest;
  477. NDIS_STATUS Status;
  478. PRWAN_NDIS_REQ_CONTEXT pContext;
  479. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  480. RWAN_STRUCT_ASSERT(pAf, naf);
  481. if ((RequestType != NdisRequestQueryInformation) &&
  482. (RequestType != NdisRequestSetInformation))
  483. {
  484. return RWAN_STATUS_BAD_PARAMETER;
  485. }
  486. RWAN_ALLOC_MEM(pNdisRequest, NDIS_REQUEST, sizeof(NDIS_REQUEST) + sizeof(RWAN_NDIS_REQ_CONTEXT));
  487. if (pNdisRequest == NULL)
  488. {
  489. return RWAN_STATUS_RESOURCES;
  490. }
  491. RWAN_ZERO_MEM(pNdisRequest, sizeof(NDIS_REQUEST));
  492. pNdisRequest->RequestType = RequestType;
  493. if (RequestType == NdisRequestQueryInformation)
  494. {
  495. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  496. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  497. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  498. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  499. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  500. }
  501. else
  502. {
  503. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  504. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  505. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  506. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  507. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
  508. }
  509. //
  510. // Fill in context about this request, so that we can complete
  511. // it to the media-specific module later.
  512. //
  513. pContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  514. pContext->pAf = pAf;
  515. pContext->AfSpReqContext = AfSpReqContext;
  516. NdisRequest(&Status,
  517. pAf->pAdapter->NdisAdapterHandle,
  518. pNdisRequest);
  519. if (Status != NDIS_STATUS_PENDING)
  520. {
  521. RWanNdisRequestComplete(
  522. pAf->pAdapter,
  523. pNdisRequest,
  524. Status
  525. );
  526. }
  527. return RWAN_STATUS_PENDING;
  528. }
  529. RWAN_STATUS
  530. RWanAfSpSendAfRequest(
  531. IN RWAN_HANDLE RWanAfHandle,
  532. IN RWAN_HANDLE AfSpReqContext,
  533. IN NDIS_REQUEST_TYPE RequestType,
  534. IN NDIS_OID Oid,
  535. IN PVOID pBuffer,
  536. IN ULONG BufferLength
  537. )
  538. /*++
  539. Routine Description:
  540. Send an NDIS Request down to the call manager on behalf of the media
  541. specific module.
  542. Arguments:
  543. RWanAfHandle - Our context for an NDIS AF Open
  544. AfSpReqContext - The caller's context for this request
  545. RequestType - NDIS request type
  546. Oid - The object being set or queried
  547. pBuffer - Points to parameter value
  548. BufferLength - Length of the above
  549. Return Value:
  550. RWAN_STATUS_PENDING if the request was sent to the call manager,
  551. RWAN_STATUS_RESOURCES if we couldn't allocate resources for the
  552. request.
  553. --*/
  554. {
  555. PRWAN_NDIS_AF pAf;
  556. NDIS_HANDLE NdisAfHandle;
  557. PNDIS_REQUEST pNdisRequest;
  558. NDIS_STATUS Status;
  559. PRWAN_NDIS_REQ_CONTEXT pContext;
  560. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  561. RWAN_STRUCT_ASSERT(pAf, naf);
  562. if ((RequestType != NdisRequestQueryInformation) &&
  563. (RequestType != NdisRequestSetInformation))
  564. {
  565. return RWAN_STATUS_BAD_PARAMETER;
  566. }
  567. RWAN_ALLOC_MEM(pNdisRequest, NDIS_REQUEST, sizeof(NDIS_REQUEST) + sizeof(RWAN_NDIS_REQ_CONTEXT));
  568. if (pNdisRequest == NULL)
  569. {
  570. return RWAN_STATUS_RESOURCES;
  571. }
  572. RWAN_ZERO_MEM(pNdisRequest, sizeof(NDIS_REQUEST));
  573. pNdisRequest->RequestType = RequestType;
  574. if (RequestType == NdisRequestQueryInformation)
  575. {
  576. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  577. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  578. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  579. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  580. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  581. }
  582. else
  583. {
  584. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  585. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  586. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  587. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  588. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
  589. }
  590. //
  591. // Fill in context about this request, so that we can complete
  592. // it to the media-specific module later.
  593. //
  594. pContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  595. pContext->pAf = pAf;
  596. pContext->AfSpReqContext = AfSpReqContext;
  597. Status = NdisCoRequest(
  598. pAf->pAdapter->NdisAdapterHandle,
  599. pAf->NdisAfHandle,
  600. NULL, // NdisVcHandle,
  601. NULL, // NdisPartyHandlem
  602. pNdisRequest
  603. );
  604. if (Status != NDIS_STATUS_PENDING)
  605. {
  606. RWanNdisCoRequestComplete(
  607. Status,
  608. (NDIS_HANDLE)pAf,
  609. NULL,
  610. NULL,
  611. pNdisRequest
  612. );
  613. }
  614. return RWAN_STATUS_PENDING;
  615. }