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.

840 lines
18 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. pRWanDeviceObject->pDeviceObject->Flags |= DO_DIRECT_IO;
  263. //
  264. // Store a pointer to our device context in the
  265. // NT device object extension.
  266. //
  267. *(PRWAN_DEVICE_OBJECT *)(pRWanDeviceObject->pDeviceObject->DeviceExtension) =
  268. pRWanDeviceObject;
  269. RWAN_ACQUIRE_GLOBAL_LOCK();
  270. RWAN_INSERT_HEAD_LIST(&(pRWanGlobal->DeviceObjList),
  271. &(pRWanDeviceObject->DeviceObjectLink));
  272. //
  273. // Add this Protocol to the list of TDI protocols on the
  274. // AF INFO block.
  275. //
  276. RWAN_INSERT_TAIL_LIST(&(pAfInfo->TdiProtocolList),
  277. &(pProtocol->AfInfoLink));
  278. //
  279. // Add this Protocol to the global list of TDI protocols.
  280. //
  281. RWAN_INSERT_TAIL_LIST(&(pRWanGlobal->ProtocolList),
  282. &(pProtocol->TdiProtocolLink));
  283. pRWanGlobal->ProtocolCount++;
  284. RWAN_RELEASE_GLOBAL_LOCK();
  285. #endif // NT
  286. RWanStatus = RWAN_STATUS_SUCCESS;
  287. *pRWanProtHandle = (RWAN_HANDLE)pProtocol;
  288. break;
  289. }
  290. while (FALSE);
  291. if (RWanStatus != RWAN_STATUS_SUCCESS)
  292. {
  293. if (pProtocol != NULL)
  294. {
  295. RWAN_FREE_MEM(pProtocol);
  296. }
  297. #ifdef NT
  298. if (pRWanDeviceObject != NULL)
  299. {
  300. RWAN_FREE_MEM(pRWanDeviceObject);
  301. }
  302. #endif // NT
  303. }
  304. return (RWanStatus);
  305. }
  306. VOID
  307. RWanAfSpDeregisterTdiProtocol(
  308. IN RWAN_HANDLE RWanProtHandle
  309. )
  310. /*++
  311. Routine Description:
  312. This is the API called by a media-specific module to de-register
  313. support for a TDI protocol. We delete the TDI Protocol block
  314. that holds information about this protocol.
  315. Arguments:
  316. RWanProtHandle - Pointer to the TDI Protocol block
  317. Return Value:
  318. None
  319. --*/
  320. {
  321. PRWAN_TDI_PROTOCOL pProtocol;
  322. PRWAN_NDIS_AF_INFO pAfInfo;
  323. #ifdef NT
  324. PRWAN_DEVICE_OBJECT pRWanDeviceObject;
  325. #endif // NT
  326. pProtocol = (PRWAN_TDI_PROTOCOL)RWanProtHandle;
  327. RWAN_STRUCT_ASSERT(pProtocol, ntp);
  328. RWAN_ASSERT(RWAN_IS_LIST_EMPTY(&pProtocol->AddrObjList));
  329. //
  330. // Unlink this TDI protocol.
  331. //
  332. RWAN_ACQUIRE_GLOBAL_LOCK();
  333. RWAN_DELETE_FROM_LIST(&(pProtocol->TdiProtocolLink));
  334. RWAN_DELETE_FROM_LIST(&(pProtocol->AfInfoLink));
  335. pRWanGlobal->ProtocolCount--;
  336. RWAN_RELEASE_GLOBAL_LOCK();
  337. #ifdef NT
  338. //
  339. // Delete the I/O device we'd created for this protocol.
  340. //
  341. pRWanDeviceObject = (PRWAN_DEVICE_OBJECT)pProtocol->pRWanDeviceObject;
  342. RWAN_ASSERT(pRWanDeviceObject != NULL);
  343. IoDeleteDevice(pRWanDeviceObject->pDeviceObject);
  344. RWAN_FREE_MEM(pRWanDeviceObject);
  345. #endif // NT
  346. RWAN_FREE_MEM(pProtocol);
  347. return;
  348. }
  349. VOID
  350. RWanAfSpOpenAfComplete(
  351. IN RWAN_STATUS RWanStatus,
  352. IN RWAN_HANDLE RWanAfHandle,
  353. IN RWAN_HANDLE AfSpAFContext,
  354. IN ULONG MaxMessageSize
  355. )
  356. /*++
  357. Routine Description:
  358. This is called by an AF-specific module to signify completion
  359. of our call to its OpenAfHandler routine. If the AF-specific module
  360. has successfully set up its context for this AF open, we store
  361. its context for this in our NDIS AF structure.
  362. Otherwise, we tear down this AF.
  363. Arguments:
  364. RWanStatus - Final status of our call to AF-specific module's AfOpen handler
  365. RWanAfHandle - Our context for an NDIS AF Open
  366. AfSpAFContext - AF-Specific module's context for this Open
  367. MaxMessageSize - Max message size for this AF
  368. Return Value:
  369. None
  370. --*/
  371. {
  372. PRWAN_NDIS_AF pAf;
  373. PRWAN_NDIS_ADAPTER pAdapter;
  374. PRWAN_NDIS_AF_INFO pAfInfo;
  375. PLIST_ENTRY pEnt;
  376. PRWAN_TDI_PROTOCOL pTdiProtocol;
  377. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  378. RWAN_STRUCT_ASSERT(pAf, naf);
  379. pAdapter = pAf->pAdapter;
  380. if (RWanStatus == RWAN_STATUS_SUCCESS)
  381. {
  382. RWAN_ACQUIRE_ADAPTER_LOCK(pAdapter);
  383. RWAN_ACQUIRE_AF_LOCK_DPC(pAf);
  384. pAf->AfSpAFContext = AfSpAFContext;
  385. RWAN_SET_BIT(pAf->Flags, RWANF_AF_IN_ADAPTER_LIST);
  386. //
  387. // Add this AF to the adapter's list of open AFs.
  388. //
  389. RWAN_INSERT_HEAD_LIST(&(pAdapter->AfList),
  390. &(pAf->AfLink));
  391. RWAN_RELEASE_AF_LOCK_DPC(pAf);
  392. #if 0
  393. RWanReferenceAdapter(pAdapter); // AF linkage
  394. #endif
  395. RWAN_RELEASE_ADAPTER_LOCK(pAdapter);
  396. RWAN_ACQUIRE_GLOBAL_LOCK();
  397. pAfInfo = pAf->pAfInfo;
  398. for (pEnt = pAfInfo->TdiProtocolList.Flink;
  399. pEnt != &pAfInfo->TdiProtocolList;
  400. pEnt = pEnt->Flink)
  401. {
  402. pTdiProtocol = CONTAINING_RECORD(pEnt, RWAN_TDI_PROTOCOL, AfInfoLink);
  403. pTdiProtocol->ProviderInfo.MaxSendSize =
  404. MIN(pTdiProtocol->ProviderInfo.MaxSendSize, MaxMessageSize);
  405. }
  406. RWAN_RELEASE_GLOBAL_LOCK();
  407. }
  408. else
  409. {
  410. RWanShutdownAf(pAf);
  411. }
  412. }
  413. VOID
  414. RWanAfSpCloseAfComplete(
  415. IN RWAN_HANDLE RWanAfHandle
  416. )
  417. /*++
  418. Routine Description:
  419. This is called by an AF-specific module to signify completion
  420. of our call to its CloseAfHandler routine.
  421. We now call NDIS to close this AF.
  422. Arguments:
  423. RWanAfHandle - Our context for an NDIS AF Open
  424. Return Value:
  425. None
  426. --*/
  427. {
  428. PRWAN_NDIS_AF pAf;
  429. NDIS_HANDLE NdisAfHandle;
  430. NDIS_STATUS Status;
  431. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  432. RWAN_STRUCT_ASSERT(pAf, naf);
  433. RWAN_ACQUIRE_AF_LOCK(pAf);
  434. pAf->AfSpAFContext = NULL;
  435. NdisAfHandle = pAf->NdisAfHandle;
  436. RWAN_RELEASE_AF_LOCK(pAf);
  437. RWANDEBUGP(DL_LOUD, DC_BIND,
  438. ("AfSpCloseAfComplete: pAf x%p, will CloseAF, AfHandle x%p\n",
  439. pAf, NdisAfHandle));
  440. Status = NdisClCloseAddressFamily(NdisAfHandle);
  441. if (Status != NDIS_STATUS_PENDING)
  442. {
  443. RWanNdisCloseAddressFamilyComplete(
  444. Status,
  445. (NDIS_HANDLE)pAf
  446. );
  447. }
  448. }
  449. RWAN_STATUS
  450. RWanAfSpSendAdapterRequest(
  451. IN RWAN_HANDLE RWanAfHandle,
  452. IN RWAN_HANDLE AfSpReqContext,
  453. IN NDIS_REQUEST_TYPE RequestType,
  454. IN NDIS_OID Oid,
  455. IN PVOID pBuffer,
  456. IN ULONG BufferLength
  457. )
  458. /*++
  459. Routine Description:
  460. Send an NDIS Request down to the miniport on behalf of the media
  461. specific module.
  462. Arguments:
  463. RWanAfHandle - Our context for an NDIS AF Open
  464. AfSpReqContext - The caller's context for this request
  465. RequestType - NDIS request type
  466. Oid - The object being set or queried
  467. pBuffer - Points to parameter value
  468. BufferLength - Length of the above
  469. Return Value:
  470. RWAN_STATUS_PENDING if the request was sent to the miniport,
  471. RWAN_STATUS_RESOURCES if we couldn't allocate resources for the
  472. request.
  473. --*/
  474. {
  475. PRWAN_NDIS_AF pAf;
  476. NDIS_HANDLE NdisAdapterHandle;
  477. PNDIS_REQUEST pNdisRequest;
  478. NDIS_STATUS Status;
  479. PRWAN_NDIS_REQ_CONTEXT pContext;
  480. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  481. RWAN_STRUCT_ASSERT(pAf, naf);
  482. if ((RequestType != NdisRequestQueryInformation) &&
  483. (RequestType != NdisRequestSetInformation))
  484. {
  485. return RWAN_STATUS_BAD_PARAMETER;
  486. }
  487. RWAN_ALLOC_MEM(pNdisRequest, NDIS_REQUEST, sizeof(NDIS_REQUEST) + sizeof(RWAN_NDIS_REQ_CONTEXT));
  488. if (pNdisRequest == NULL)
  489. {
  490. return RWAN_STATUS_RESOURCES;
  491. }
  492. RWAN_ZERO_MEM(pNdisRequest, sizeof(NDIS_REQUEST));
  493. pNdisRequest->RequestType = RequestType;
  494. if (RequestType == NdisRequestQueryInformation)
  495. {
  496. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  497. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  498. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  499. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  500. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  501. }
  502. else
  503. {
  504. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  505. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  506. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  507. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  508. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
  509. }
  510. //
  511. // Fill in context about this request, so that we can complete
  512. // it to the media-specific module later.
  513. //
  514. pContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  515. pContext->pAf = pAf;
  516. pContext->AfSpReqContext = AfSpReqContext;
  517. NdisRequest(&Status,
  518. pAf->pAdapter->NdisAdapterHandle,
  519. pNdisRequest);
  520. if (Status != NDIS_STATUS_PENDING)
  521. {
  522. RWanNdisRequestComplete(
  523. pAf->pAdapter,
  524. pNdisRequest,
  525. Status
  526. );
  527. }
  528. return RWAN_STATUS_PENDING;
  529. }
  530. RWAN_STATUS
  531. RWanAfSpSendAfRequest(
  532. IN RWAN_HANDLE RWanAfHandle,
  533. IN RWAN_HANDLE AfSpReqContext,
  534. IN NDIS_REQUEST_TYPE RequestType,
  535. IN NDIS_OID Oid,
  536. IN PVOID pBuffer,
  537. IN ULONG BufferLength
  538. )
  539. /*++
  540. Routine Description:
  541. Send an NDIS Request down to the call manager on behalf of the media
  542. specific module.
  543. Arguments:
  544. RWanAfHandle - Our context for an NDIS AF Open
  545. AfSpReqContext - The caller's context for this request
  546. RequestType - NDIS request type
  547. Oid - The object being set or queried
  548. pBuffer - Points to parameter value
  549. BufferLength - Length of the above
  550. Return Value:
  551. RWAN_STATUS_PENDING if the request was sent to the call manager,
  552. RWAN_STATUS_RESOURCES if we couldn't allocate resources for the
  553. request.
  554. --*/
  555. {
  556. PRWAN_NDIS_AF pAf;
  557. NDIS_HANDLE NdisAfHandle;
  558. PNDIS_REQUEST pNdisRequest;
  559. NDIS_STATUS Status;
  560. PRWAN_NDIS_REQ_CONTEXT pContext;
  561. pAf = (PRWAN_NDIS_AF)RWanAfHandle;
  562. RWAN_STRUCT_ASSERT(pAf, naf);
  563. if ((RequestType != NdisRequestQueryInformation) &&
  564. (RequestType != NdisRequestSetInformation))
  565. {
  566. return RWAN_STATUS_BAD_PARAMETER;
  567. }
  568. RWAN_ALLOC_MEM(pNdisRequest, NDIS_REQUEST, sizeof(NDIS_REQUEST) + sizeof(RWAN_NDIS_REQ_CONTEXT));
  569. if (pNdisRequest == NULL)
  570. {
  571. return RWAN_STATUS_RESOURCES;
  572. }
  573. RWAN_ZERO_MEM(pNdisRequest, sizeof(NDIS_REQUEST));
  574. pNdisRequest->RequestType = RequestType;
  575. if (RequestType == NdisRequestQueryInformation)
  576. {
  577. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  578. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  579. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  580. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  581. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  582. }
  583. else
  584. {
  585. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  586. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  587. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  588. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  589. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = BufferLength;
  590. }
  591. //
  592. // Fill in context about this request, so that we can complete
  593. // it to the media-specific module later.
  594. //
  595. pContext = (PRWAN_NDIS_REQ_CONTEXT)((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
  596. pContext->pAf = pAf;
  597. pContext->AfSpReqContext = AfSpReqContext;
  598. Status = NdisCoRequest(
  599. pAf->pAdapter->NdisAdapterHandle,
  600. pAf->NdisAfHandle,
  601. NULL, // NdisVcHandle,
  602. NULL, // NdisPartyHandlem
  603. pNdisRequest
  604. );
  605. if (Status != NDIS_STATUS_PENDING)
  606. {
  607. RWanNdisCoRequestComplete(
  608. Status,
  609. (NDIS_HANDLE)pAf,
  610. NULL,
  611. NULL,
  612. pNdisRequest
  613. );
  614. }
  615. return RWAN_STATUS_PENDING;
  616. }