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.

6475 lines
174 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. io.c
  5. Abstract:
  6. This file contains the procedures to process I/O requests from
  7. a User Mode entity. All OS dependent I/O interface functions
  8. will be conditionally coded, and will be responsible for translating
  9. the I/O functions from the OS format to buffers that are useable by
  10. the main I/O handling routine.
  11. Author:
  12. Tony Bell (TonyBe) June 06, 1995
  13. Environment:
  14. Kernel Mode
  15. Revision History:
  16. TonyBe 06/06/95 Created
  17. --*/
  18. #include "wan.h"
  19. #define __FILE_SIG__ IO_FILESIG
  20. //
  21. // Local function prototypes
  22. //
  23. NTSTATUS
  24. ExecuteIo(
  25. IN ULONG ulFuncCode,
  26. IN PUCHAR pInputBuffer,
  27. IN ULONG ulInputBufferLength,
  28. IN PUCHAR pOutputBuffer,
  29. IN ULONG ulOutputBufferLength,
  30. OUT PULONG pulBytesWritten
  31. );
  32. NTSTATUS
  33. MapConnectionId(
  34. IN PUCHAR pInputBuffer,
  35. IN ULONG ulInputBufferLength,
  36. IN PUCHAR pOutputBuffer,
  37. IN ULONG ulOutputBufferLength,
  38. OUT PULONG pulBytesWritten
  39. );
  40. NTSTATUS
  41. GetBundleHandle(
  42. IN PUCHAR pInputBuffer,
  43. IN ULONG ulInputBufferLength,
  44. IN PUCHAR pOutputBuffer,
  45. IN ULONG ulOutputBufferLength,
  46. OUT PULONG pulBytesWritten
  47. );
  48. NTSTATUS
  49. SetFriendlyName(
  50. IN PUCHAR pInputBuffer,
  51. IN ULONG ulInputBufferLength,
  52. IN PUCHAR pOutputBuffer,
  53. IN ULONG ulOutputBufferLength,
  54. OUT PULONG pulBytesWritten
  55. );
  56. NTSTATUS
  57. ActivateRoute(
  58. IN PUCHAR pInputBuffer,
  59. IN ULONG ulInputBufferLength,
  60. IN PUCHAR pOutputBuffer,
  61. IN ULONG ulOutputBufferLength,
  62. OUT PULONG pulBytesWritten
  63. );
  64. NTSTATUS
  65. BundleLink(
  66. IN PUCHAR pInputBuffer,
  67. IN ULONG ulInputBufferLength,
  68. IN PUCHAR pOutputBuffer,
  69. IN ULONG ulOutputBufferLength,
  70. OUT PULONG pulBytesWritten
  71. );
  72. NTSTATUS
  73. EnumLinksInBundle(
  74. IN PUCHAR pInputBuffer,
  75. IN ULONG ulInputBufferLength,
  76. IN PUCHAR pOutputBuffer,
  77. IN ULONG ulOutputBufferLength,
  78. OUT PULONG pulBytesWritten
  79. );
  80. NTSTATUS
  81. SetProtocolPriority(
  82. IN PUCHAR pInputBuffer,
  83. IN ULONG ulInputBufferLength,
  84. IN PUCHAR pOutputBuffer,
  85. IN ULONG ulOutputBufferLength,
  86. OUT PULONG pulBytesWritten
  87. );
  88. NTSTATUS
  89. SetBandwidthOnDemand(
  90. IN PUCHAR pInputBuffer,
  91. IN ULONG ulInputBufferLength,
  92. IN PUCHAR pOutputBuffer,
  93. IN ULONG ulOutputBufferLength,
  94. OUT PULONG pulBytesWritten
  95. );
  96. NTSTATUS
  97. SetThresholdEvent(
  98. IN PUCHAR pInputBuffer,
  99. IN ULONG ulInputBufferLength,
  100. IN PUCHAR pOutputBuffer,
  101. IN ULONG ulOutputBufferLength,
  102. OUT PULONG pulBytesWritten
  103. );
  104. NTSTATUS
  105. IoSendPacket(
  106. IN PUCHAR pInputBuffer,
  107. IN ULONG ulInputBufferLength,
  108. IN PUCHAR pOutputBuffer,
  109. IN ULONG ulOutputBufferLength,
  110. OUT PULONG pulBytesWritten
  111. );
  112. NTSTATUS
  113. IoReceivePacket(
  114. IN PUCHAR pInputBuffer,
  115. IN ULONG ulInputBufferLength,
  116. IN PUCHAR pOutputBuffer,
  117. IN ULONG ulOutputBufferLength,
  118. OUT PULONG pulBytesWritten
  119. );
  120. NTSTATUS
  121. FlushReceivePacket(
  122. IN PUCHAR pInputBuffer,
  123. IN ULONG ulInputBufferLength,
  124. IN PUCHAR pOutputBuffer,
  125. IN ULONG ulOutputBufferLength,
  126. OUT PULONG pulBytesWritten
  127. );
  128. NTSTATUS
  129. GetStatistics(
  130. IN PUCHAR pInputBuffer,
  131. IN ULONG ulInputBufferLength,
  132. IN PUCHAR pOutputBuffer,
  133. IN ULONG ulOutputBufferLength,
  134. OUT PULONG pulBytesWritten
  135. );
  136. NTSTATUS
  137. SetLinkInfo(
  138. IN PUCHAR pInputBuffer,
  139. IN ULONG ulInputBufferLength,
  140. IN PUCHAR pOutputBuffer,
  141. IN ULONG ulOutputBufferLength,
  142. OUT PULONG pulBytesWritten
  143. );
  144. NTSTATUS
  145. GetLinkInfo(
  146. IN PUCHAR pInputBuffer,
  147. IN ULONG ulInputBufferLength,
  148. IN PUCHAR pOutputBuffer,
  149. IN ULONG ulOutputBufferLength,
  150. OUT PULONG pulBytesWritten
  151. );
  152. NTSTATUS
  153. SetCompressionInfo(
  154. IN PUCHAR pInputBuffer,
  155. IN ULONG ulInputBufferLength,
  156. IN PUCHAR pOutputBuffer,
  157. IN ULONG ulOutputBufferLength,
  158. OUT PULONG pulBytesWritten
  159. );
  160. NTSTATUS
  161. GetCompressionInfo(
  162. IN PUCHAR pInputBuffer,
  163. IN ULONG ulInputBufferLength,
  164. IN PUCHAR pOutputBuffer,
  165. IN ULONG ulOutputBufferLength,
  166. OUT PULONG pulBytesWritten
  167. );
  168. NTSTATUS
  169. SetVJInfo(
  170. IN PUCHAR pInputBuffer,
  171. IN ULONG ulInputBufferLength,
  172. IN PUCHAR pOutputBuffer,
  173. IN ULONG ulOutputBufferLength,
  174. OUT PULONG pulBytesWritten
  175. );
  176. NTSTATUS
  177. GetVJInfo(
  178. IN PUCHAR pInputBuffer,
  179. IN ULONG ulInputBufferLength,
  180. IN PUCHAR pOutputBuffer,
  181. IN ULONG ulOutputBufferLength,
  182. OUT PULONG pulBytesWritten
  183. );
  184. NTSTATUS
  185. SetEncryptionInfo(
  186. IN PUCHAR pInputBuffer,
  187. IN ULONG ulInputBufferLength,
  188. IN PUCHAR pOutputBuffer,
  189. IN ULONG ulOutputBufferLength,
  190. OUT PULONG pulBytesWritten
  191. );
  192. NTSTATUS
  193. GetEncryptionInfo(
  194. IN PUCHAR pInputBuffer,
  195. IN ULONG ulInputBufferLength,
  196. IN PUCHAR pOutputBuffer,
  197. IN ULONG ulOutputBufferLength,
  198. OUT PULONG pulBytesWritten
  199. );
  200. NTSTATUS
  201. GetIdleTime(
  202. IN PUCHAR pInputBuffer,
  203. IN ULONG ulInputBufferLength,
  204. IN PUCHAR pOutputBuffer,
  205. IN ULONG ulOutputBufferLength,
  206. OUT PULONG pulBytesWritten
  207. );
  208. NTSTATUS
  209. SetDebugInfo(
  210. IN PUCHAR pInputBuffer,
  211. IN ULONG ulInputBufferLength,
  212. IN PUCHAR pOutputBuffer,
  213. IN ULONG ulOutputBufferLength,
  214. OUT PULONG pulBytesWritten
  215. );
  216. NTSTATUS
  217. EnumActiveBundles(
  218. IN PUCHAR pInputBuffer,
  219. IN ULONG ulInputBufferLength,
  220. IN PUCHAR pOutputBuffer,
  221. IN ULONG ulOutputBufferLength,
  222. OUT PULONG pulBytesWritten
  223. );
  224. NTSTATUS
  225. GetBandwidthUtilization(
  226. IN PUCHAR pInputBuffer,
  227. IN ULONG ulInputBufferLength,
  228. IN PUCHAR pOutputBuffer,
  229. IN ULONG ulOutputBufferLength,
  230. OUT PULONG pulBytesWritten
  231. );
  232. NTSTATUS
  233. EnumProtocolUtilization(
  234. IN PUCHAR pInputBuffer,
  235. IN ULONG ulInputBufferLength,
  236. IN PUCHAR pOutputBuffer,
  237. IN ULONG ulOutputBufferLength,
  238. OUT PULONG pulBytesWritten
  239. );
  240. NTSTATUS
  241. FlushThresholdEvents(
  242. IN PUCHAR pInputBuffer,
  243. IN ULONG ulInputBufferLength,
  244. IN PUCHAR pOutputBuffer,
  245. IN ULONG ulOutputBufferLength,
  246. OUT PULONG pulBytesWritten
  247. );
  248. NTSTATUS
  249. GetWanInfo(
  250. IN PUCHAR pInputBuffer,
  251. IN ULONG ulInputBufferLength,
  252. IN PUCHAR pOutputBuffer,
  253. IN ULONG ulOutputBufferLength,
  254. OUT PULONG pulBytesWritten
  255. );
  256. NTSTATUS
  257. DeactivateRoute(
  258. IN PUCHAR pInputBuffer,
  259. IN ULONG ulInputBufferLength,
  260. IN PUCHAR pOutputBuffer,
  261. IN ULONG ulOutputBufferLength,
  262. OUT PULONG pulBytesWritten
  263. );
  264. NTSTATUS
  265. GetDriverInfo(
  266. IN PUCHAR pInputBuffer,
  267. IN ULONG ulInputBufferLength,
  268. IN PUCHAR pOutputBuffer,
  269. IN ULONG ulOutputBufferLength,
  270. OUT PULONG pulBytesWritten
  271. );
  272. NTSTATUS
  273. SetProtocolEvent(
  274. IN PUCHAR pInputBuffer,
  275. IN ULONG ulInputBufferLength,
  276. IN PUCHAR pOutputBuffer,
  277. IN ULONG ulOutputBufferLength,
  278. OUT PULONG pulBytesWritten
  279. );
  280. NTSTATUS
  281. GetProtocolEvent(
  282. IN PUCHAR pInputBuffer,
  283. IN ULONG ulInputBufferLength,
  284. IN PUCHAR pOutputBuffer,
  285. IN ULONG ulOutputBufferLength,
  286. OUT PULONG pulBytesWritten
  287. );
  288. NTSTATUS
  289. FlushProtocolEvent(
  290. IN PUCHAR pInputBuffer,
  291. IN ULONG ulInputBufferLength,
  292. IN PUCHAR pOutputBuffer,
  293. IN ULONG ulOutputBufferLength,
  294. OUT PULONG pulBytesWritten
  295. );
  296. NTSTATUS
  297. IoGetProtocolInfo(
  298. IN PUCHAR pInputBuffer,
  299. IN ULONG ulInputBufferLength,
  300. IN PUCHAR pOutputBuffer,
  301. IN ULONG ulOutputBufferLength,
  302. OUT PULONG pulBytesWritten
  303. );
  304. NTSTATUS
  305. SetHibernateEvent(
  306. IN PUCHAR pInputBuffer,
  307. IN ULONG ulInputBufferLength,
  308. IN PUCHAR pOutputBuffer,
  309. IN ULONG ulOutputBufferLength,
  310. OUT PULONG pulBytesWritten
  311. );
  312. NTSTATUS
  313. FlushHibernateEvent(
  314. IN PUCHAR pInputBuffer,
  315. IN ULONG ulInputBufferLength,
  316. IN PUCHAR pOutputBuffer,
  317. IN ULONG ulOutputBufferLength,
  318. OUT PULONG pulBytesWritten
  319. );
  320. NTSTATUS
  321. GetBundleInfo(
  322. IN PUCHAR pInputBuffer,
  323. IN ULONG ulInputBufferLength,
  324. IN PUCHAR pOutputBuffer,
  325. IN ULONG ulOutputBufferLength,
  326. OUT PULONG pulBytesWritten
  327. );
  328. NTSTATUS
  329. UnmapConnectionId(
  330. IN PUCHAR pInputBuffer,
  331. IN ULONG ulInputBufferLength,
  332. IN PUCHAR pOutputBuffer,
  333. IN ULONG ulOutputBufferLength,
  334. OUT PULONG pulBytesWritten
  335. );
  336. VOID
  337. CancelThresholdEvents(
  338. VOID
  339. );
  340. VOID
  341. CancelIoReceivePackets(
  342. VOID
  343. );
  344. VOID
  345. AddProtocolCBToBundle(
  346. PPROTOCOLCB ProtocolCB,
  347. PBUNDLECB BundleCB
  348. );
  349. VOID
  350. SortProtocolListByPriority(
  351. IN PBUNDLECB BundleCB
  352. );
  353. NDIS_HANDLE
  354. AssignProtocolCBHandle(
  355. PBUNDLECB BundleCB,
  356. PPROTOCOLCB ProtocolCB
  357. );
  358. VOID
  359. FreeProtocolCBHandle(
  360. PBUNDLECB BundleCB,
  361. PPROTOCOLCB ProtocolCB
  362. );
  363. NTSTATUS
  364. NotImplemented(
  365. IN PUCHAR pInputBuffer,
  366. IN ULONG ulInputBufferLength,
  367. IN PUCHAR pOutputBuffer,
  368. IN ULONG ulOutputBufferLength,
  369. OUT PULONG pulBytesWritten
  370. );
  371. //
  372. // End of local function prototypes
  373. //
  374. CONST
  375. IO_DISPATCH_TABLE IoDispatchTable[] =
  376. {
  377. {FUNC_MAP_CONNECTION_ID , MapConnectionId},
  378. {FUNC_GET_BUNDLE_HANDLE , GetBundleHandle},
  379. {FUNC_SET_FRIENDLY_NAME , SetFriendlyName},
  380. {FUNC_ROUTE , ActivateRoute},
  381. {FUNC_ADD_LINK_TO_BUNDLE , BundleLink},
  382. {FUNC_ENUM_LINKS_IN_BUNDLE , EnumLinksInBundle},
  383. {FUNC_SET_PROTOCOL_PRIORITY , SetProtocolPriority},
  384. {FUNC_SET_BANDWIDTH_ON_DEMAND, SetBandwidthOnDemand},
  385. {FUNC_SET_THRESHOLD_EVENT , SetThresholdEvent},
  386. {FUNC_FLUSH_THRESHOLD_EVENTS, FlushThresholdEvents},
  387. {FUNC_SEND_PACKET , IoSendPacket},
  388. {FUNC_RECEIVE_PACKET , IoReceivePacket},
  389. {FUNC_FLUSH_RECEIVE_PACKETS , FlushReceivePacket},
  390. {FUNC_GET_STATS , GetStatistics},
  391. {FUNC_SET_LINK_INFO , SetLinkInfo},
  392. {FUNC_GET_LINK_INFO , GetLinkInfo},
  393. {FUNC_SET_COMPRESSION_INFO , SetCompressionInfo},
  394. {FUNC_GET_COMPRESSION_INFO , GetCompressionInfo},
  395. {FUNC_SET_BRIDGE_INFO , NotImplemented},
  396. {FUNC_GET_BRIDGE_INFO , NotImplemented},
  397. {FUNC_SET_VJ_INFO , SetVJInfo},
  398. {FUNC_GET_VJ_INFO , GetVJInfo},
  399. {FUNC_SET_CIPX_INFO , NotImplemented},
  400. {FUNC_GET_CIPX_INFO , NotImplemented},
  401. {FUNC_SET_ENCRYPTION_INFO , SetEncryptionInfo},
  402. {FUNC_GET_ENCRYPTION_INFO , GetEncryptionInfo},
  403. {FUNC_SET_DEBUG_INFO , SetDebugInfo},
  404. {FUNC_ENUM_ACTIVE_BUNDLES , EnumActiveBundles},
  405. {FUNC_GET_NDISWANCB , NotImplemented},
  406. {FUNC_GET_MINIPORTCB , NotImplemented},
  407. {FUNC_GET_OPENCB , NotImplemented},
  408. {FUNC_GET_BANDWIDTH_UTILIZATION, GetBandwidthUtilization},
  409. {FUNC_ENUM_PROTOCOL_UTILIZATION, EnumProtocolUtilization},
  410. {FUNC_ENUM_MINIPORTCB , NotImplemented},
  411. {FUNC_ENUM_OPENCB , NotImplemented},
  412. {FUNC_GET_WAN_INFO , GetWanInfo},
  413. {FUNC_GET_IDLE_TIME , GetIdleTime},
  414. {FUNC_UNROUTE , DeactivateRoute},
  415. {FUNC_GET_DRIVER_INFO , GetDriverInfo},
  416. {FUNC_SET_PROTOCOL_EVENT , SetProtocolEvent},
  417. {FUNC_GET_PROTOCOL_EVENT , GetProtocolEvent},
  418. {FUNC_FLUSH_PROTOCOL_EVENT , FlushProtocolEvent},
  419. {FUNC_GET_PROTOCOL_INFO , IoGetProtocolInfo},
  420. {FUNC_SET_HIBERNATE_EVENT , SetHibernateEvent},
  421. {FUNC_FLUSH_HIBERNATE_EVENT , FlushHibernateEvent},
  422. {FUNC_GET_BUNDLE_INFO , GetBundleInfo},
  423. {FUNC_UNMAP_CONNECTION_ID , UnmapConnectionId}
  424. };
  425. #define MAX_FUNC_CODES sizeof(IoDispatchTable)/sizeof(IO_DISPATCH_TABLE)
  426. #ifdef NT
  427. NTSTATUS
  428. NdisWanIoctl(
  429. IN PDEVICE_OBJECT pDeviceObject,
  430. IN PIRP pIrp
  431. )
  432. /*++
  433. Routine Name:
  434. Routine Description:
  435. Arguments:
  436. Return Values:
  437. --*/
  438. {
  439. NTSTATUS Status, ReturnStatus;
  440. ULONG ulBytesWritten = 0;
  441. //
  442. // Get current Irp stack location
  443. //
  444. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  445. //
  446. // Ioctl Function Code
  447. //
  448. ULONG ulFuncCode = (pIrpSp->Parameters.DeviceIoControl.IoControlCode >> 2) & 0x00000FFF ;
  449. ULONG ulDeviceType = (pIrpSp->Parameters.DeviceIoControl.IoControlCode >> 16) & 0x0000FFFF;
  450. ULONG ulMethod = pIrpSp->Parameters.DeviceIoControl.IoControlCode & 0x00000003;
  451. //
  452. // Input buffer, Output buffer, and lengths
  453. //
  454. PUCHAR pInputBuffer = pIrp->AssociatedIrp.SystemBuffer;
  455. PUCHAR pOutputBuffer = pInputBuffer;
  456. ULONG ulInputBufferLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
  457. ULONG ulOutputBufferLength = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  458. //
  459. // if this is win64 make sure the calling process is 64bit
  460. // since this interface is only used by rasman and rasman
  461. // will always be 64bit on 64bit systems we will not bother
  462. // with thunking. if the process is not a 64bit process get
  463. // out.
  464. #ifdef _WIN64
  465. if (IoIs32bitProcess(pIrp)) {
  466. pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  467. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  468. return (STATUS_NOT_SUPPORTED);
  469. }
  470. #endif
  471. // NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanIoctl: FunctionCode: 0x%x, MajorFunction: 0x%x, DeviceType: 0x%x",
  472. // ulFuncCode, pIrpSp->MajorFunction, ulDeviceType));
  473. #ifdef MY_DEVICE_OBJECT
  474. //
  475. // Make sure that this is for us
  476. //
  477. if ((pIrpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL) ||
  478. (ulDeviceType != FILE_DEVICE_NDISWAN) ||
  479. (ulMethod != METHOD_BUFFERED) ||
  480. (pDeviceObject != NdisWanCB.pDeviceObject)) {
  481. if (NdisWanCB.MajorFunction[pIrpSp->MajorFunction] == NULL) {
  482. pIrp->IoStatus.Information = 0;
  483. pIrp->IoStatus.Status = STATUS_SUCCESS;
  484. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  485. return(STATUS_SUCCESS);
  486. }
  487. return(NdisWanCB.MajorFunction[pIrpSp->MajorFunction](pDeviceObject, pIrp));
  488. }
  489. #else
  490. if (pIrpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL ||
  491. ulDeviceType != FILE_DEVICE_NETWORK ||
  492. ulMethod != METHOD_BUFFERED) {
  493. pIrp->IoStatus.Information = 0;
  494. pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  495. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  496. return (STATUS_NOT_SUPPORTED);
  497. }
  498. #endif
  499. //
  500. // If this is a function code that requires an irp to be pended and completed
  501. // later, we need to queue the irp up somewhere. In order for this to be somewhat
  502. // portable we will pass the irp in as the input buffer and store it in a
  503. // a structure that it has it's own linkage for queueing.
  504. //
  505. if ((ulFuncCode == FUNC_SET_THRESHOLD_EVENT) ||
  506. (ulFuncCode == FUNC_RECEIVE_PACKET) ||
  507. (ulFuncCode == FUNC_SET_PROTOCOL_EVENT) ||
  508. (ulFuncCode == FUNC_SET_HIBERNATE_EVENT)) {
  509. pInputBuffer = (PUCHAR)pIrp;
  510. }
  511. Status = ExecuteIo(ulFuncCode,
  512. pInputBuffer,
  513. ulInputBufferLength,
  514. pOutputBuffer,
  515. ulOutputBufferLength,
  516. &ulBytesWritten);
  517. // NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanIoctl: Status: 0x%x, BytesWritten: %d",
  518. // Status, ulBytesWritten));
  519. switch (Status) {
  520. case STATUS_SUCCESS:
  521. ReturnStatus = Status;
  522. pIrp->IoStatus.Information = ulBytesWritten;
  523. break;
  524. case STATUS_PENDING:
  525. return(Status);
  526. case STATUS_INFO_LENGTH_MISMATCH:
  527. //
  528. // See if this was a request to get size needed for
  529. // ioctl.
  530. //
  531. if (ulOutputBufferLength >= sizeof(ULONG)) {
  532. *(PULONG)pOutputBuffer = ulBytesWritten;
  533. ulBytesWritten = sizeof(ULONG);
  534. pIrp->IoStatus.Information = sizeof(ULONG);
  535. } else {
  536. pIrp->IoStatus.Information = 0;
  537. }
  538. ReturnStatus = Status =
  539. STATUS_SUCCESS;
  540. break;
  541. default:
  542. if (Status < 0xC0000000) {
  543. Status =
  544. ReturnStatus = STATUS_UNSUCCESSFUL;
  545. } else {
  546. ReturnStatus = Status;
  547. }
  548. pIrp->IoStatus.Information = 0;
  549. break;
  550. }
  551. pIrp->IoStatus.Status = Status;
  552. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  553. return(ReturnStatus);
  554. }
  555. NTSTATUS
  556. NdisWanIrpStub(
  557. IN PDEVICE_OBJECT pDeviceObject,
  558. IN PIRP pIrp
  559. )
  560. /*++
  561. Routine Name:
  562. Routine Description:
  563. Arguments:
  564. Return Values:
  565. --*/
  566. {
  567. //
  568. // Get current Irp stack location
  569. //
  570. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  571. NdisWanDbgOut(DBG_VERBOSE, DBG_IO, ("NdisWanIrpStub: Entry"));
  572. #ifdef MY_DEVICE_OBJECT
  573. //
  574. // Make sure that this is for us
  575. //
  576. if (pDeviceObject != NdisWanCB.pDeviceObject &&
  577. NdisWanCB.MajorFunction[pIrpSp->MajorFunction] != NULL) {
  578. NdisWanDbgOut(DBG_VERBOSE, DBG_IO, ("NdisWanIrpStub: Exit1"));
  579. return(NdisWanCB.MajorFunction[pIrpSp->MajorFunction](pDeviceObject, pIrp));
  580. }
  581. pIrp->IoStatus.Information = 0;
  582. pIrp->IoStatus.Status = STATUS_SUCCESS;
  583. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  584. NdisWanDbgOut(DBG_VERBOSE, DBG_IO, ("NdisWanIrpStub: Exit2"));
  585. return (STATUS_SUCCESS);
  586. #else
  587. pIrp->IoStatus.Information = 0;
  588. pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  589. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  590. NdisWanDbgOut(DBG_VERBOSE, DBG_IO, ("NdisWanIrpStub: Exit2"));
  591. return (STATUS_NOT_SUPPORTED);
  592. #endif
  593. }
  594. NTSTATUS
  595. NdisWanCreate(
  596. IN PDEVICE_OBJECT pDeviceObject,
  597. IN PIRP pIrp
  598. )
  599. /*++
  600. Routine Name:
  601. NdisWanCreate
  602. Routine Description:
  603. This routine is called when an app (rasman) opens ndiswan.
  604. Arguments:
  605. Return Values:
  606. --*/
  607. {
  608. //
  609. // Get current Irp stack location
  610. //
  611. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  612. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCreate: Entry"));
  613. #ifdef MY_DEVICE_OBJECT
  614. //
  615. // Make sure that this is for us
  616. //
  617. if (pDeviceObject != NdisWanCB.pDeviceObject &&
  618. NdisWanCB.MajorFunction[pIrpSp->MajorFunction] != NULL) {
  619. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCreate: Exit1"));
  620. return(NdisWanCB.MajorFunction[pIrpSp->MajorFunction](pDeviceObject, pIrp));
  621. }
  622. #endif
  623. if (InterlockedIncrement(&NdisWanCB.RefCount) == 1) {
  624. ULONG i;
  625. ULONG ArraySize;
  626. PPROTOCOL_INFO InfoArray;
  627. BOOLEAN bEvent = FALSE;
  628. //
  629. // This is the first guy!
  630. //
  631. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  632. ArraySize = ProtocolInfoTable->ulArraySize;
  633. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  634. i < ArraySize; i++, InfoArray++) {
  635. if (InfoArray->ProtocolType != 0) {
  636. InfoArray->Flags |= PROTOCOL_EVENT_OCCURRED;
  637. bEvent = TRUE;
  638. }
  639. }
  640. if (bEvent) {
  641. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_OCCURRED;
  642. }
  643. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  644. }
  645. pIrp->IoStatus.Information = 0;
  646. pIrp->IoStatus.Status = STATUS_SUCCESS;
  647. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  648. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCreate: Exit2"));
  649. return (STATUS_SUCCESS);
  650. }
  651. NTSTATUS
  652. NdisWanCleanup(
  653. IN PDEVICE_OBJECT pDeviceObject,
  654. IN PIRP pIrp
  655. )
  656. /*++
  657. Routine Name:
  658. NdisWanCleanup
  659. Routine Description:
  660. This routine is called when all apps (rasman) that have opened
  661. ndiswan have gone away. If ndiswan is still routed to any
  662. transports it will complete all sends and do linedowns to
  663. cleanup.
  664. Arguments:
  665. Return Values:
  666. --*/
  667. {
  668. //
  669. // Get current Irp stack location
  670. //
  671. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  672. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCleanup: Entry"));
  673. #ifdef MY_DEVICE_OBJECT
  674. //
  675. // Make sure that this is for us
  676. //
  677. if (pDeviceObject != NdisWanCB.pDeviceObject &&
  678. NdisWanCB.MajorFunction[pIrpSp->MajorFunction] != NULL) {
  679. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCleanup: Exit1"));
  680. return(NdisWanCB.MajorFunction[pIrpSp->MajorFunction](pDeviceObject, pIrp));
  681. }
  682. #endif
  683. pIrp->IoStatus.Information = 0;
  684. pIrp->IoStatus.Status = STATUS_SUCCESS;
  685. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  686. InterlockedDecrement(&NdisWanCB.RefCount);
  687. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCleanup: Exit2"));
  688. return (STATUS_SUCCESS);
  689. }
  690. NTSTATUS
  691. NdisWanPnPPower(
  692. IN PDEVICE_OBJECT pDeviceObject,
  693. IN PIRP pIrp
  694. )
  695. /*++
  696. Routine Name:
  697. Routine Description:
  698. Arguments:
  699. Return Values:
  700. --*/
  701. {
  702. //
  703. // Get current Irp stack location
  704. //
  705. PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  706. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanPnPPower: Entry"));
  707. #ifdef MY_DEVICE_OBJECT
  708. //
  709. // Make sure that this is for us
  710. //
  711. if (pDeviceObject != NdisWanCB.pDeviceObject &&
  712. NdisWanCB.MajorFunction[pIrpSp->MajorFunction] != NULL) {
  713. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanPnPPower: Exit1"));
  714. return(NdisWanCB.MajorFunction[pIrpSp->MajorFunction](pDeviceObject, pIrp));
  715. }
  716. #endif
  717. pIrp->IoStatus.Information = 0;
  718. pIrp->IoStatus.Status = STATUS_SUCCESS;
  719. PoStartNextPowerIrp(pIrp);
  720. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  721. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanPnPPower: Exit2"));
  722. return (STATUS_SUCCESS);
  723. }
  724. VOID
  725. NdisWanCancelRoutine(
  726. IN PDEVICE_OBJECT pDeviceObject,
  727. IN PIRP pIrp
  728. )
  729. /*++
  730. Routine Name:
  731. Routine Description:
  732. Arguments:
  733. Return Values:
  734. --*/
  735. {
  736. BOOLEAN Found = FALSE;
  737. PLIST_ENTRY Entry;
  738. ULONG CopySize = 0;
  739. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("NdisWanCancelRoutine: Irp 0x%p", pIrp));
  740. IoReleaseCancelSpinLock(pIrp->CancelIrql);
  741. do {
  742. //
  743. // Is this the hibernate event irp?
  744. //
  745. NdisAcquireSpinLock(&NdisWanCB.Lock);
  746. if (pIrp == NdisWanCB.HibernateEventIrp) {
  747. NdisWanCB.HibernateEventIrp = NULL;
  748. Found = TRUE;
  749. }
  750. NdisReleaseSpinLock(&NdisWanCB.Lock);
  751. if (Found) {
  752. break;
  753. }
  754. //
  755. // Is this the protocol event irp?
  756. //
  757. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  758. if (pIrp == ProtocolInfoTable->EventIrp) {
  759. ProtocolInfoTable->EventIrp = NULL;
  760. Found = TRUE;
  761. }
  762. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  763. if (Found) {
  764. break;
  765. }
  766. //
  767. // We need to walk the async event queue looking for
  768. // the async event that this irp is associated with
  769. //
  770. NdisAcquireSpinLock(&IoRecvList.Lock);
  771. for (Entry = IoRecvList.IrpList.Flink;
  772. Entry != &IoRecvList.IrpList;
  773. Entry = Entry->Flink) {
  774. PIRP MyIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  775. if (MyIrp == (PVOID)pIrp) {
  776. IoRecvList.ulIrpCount--;
  777. //
  778. // Remove from the list
  779. //
  780. RemoveEntryList(Entry);
  781. Found = TRUE;
  782. ((PNDISWAN_IO_PACKET)(pIrp->AssociatedIrp.SystemBuffer))->usHandleType = CANCELEDHANDLE;
  783. INSERT_RECV_EVENT('c');
  784. CopySize = sizeof(NDISWAN_IO_PACKET);
  785. IoRecvList.LastIrp = pIrp;
  786. IoRecvList.LastIrpStatus = STATUS_SUCCESS;
  787. IoRecvList.LastCopySize = CopySize;
  788. IoRecvList.LastPacketNumber =
  789. ((PNDISWAN_IO_PACKET)(pIrp->AssociatedIrp.SystemBuffer))->PacketNumber;
  790. break;
  791. }
  792. }
  793. NdisReleaseSpinLock(&IoRecvList.Lock);
  794. if (Found) {
  795. break;
  796. }
  797. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  798. for (Entry = ThresholdEventQueue.List.Flink;
  799. Entry != &ThresholdEventQueue.List;
  800. Entry = Entry->Flink) {
  801. PIRP MyIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  802. if (MyIrp == (PVOID)pIrp) {
  803. ThresholdEventQueue.ulCount--;
  804. //
  805. // Remove from the list
  806. //
  807. RemoveEntryList(Entry);
  808. Found = TRUE;
  809. break;
  810. }
  811. }
  812. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  813. } while (FALSE);
  814. //
  815. // Complete the irp
  816. //
  817. pIrp->Cancel = TRUE;
  818. pIrp->IoStatus.Status = STATUS_CANCELLED;
  819. pIrp->IoStatus.Information = CopySize;
  820. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  821. }
  822. #endif
  823. NTSTATUS
  824. ExecuteIo(
  825. IN ULONG ulFuncCode,
  826. IN PUCHAR pInputBuffer,
  827. IN ULONG ulInputBufferLength,
  828. IN PUCHAR pOutputBuffer,
  829. IN ULONG ulOutputBufferLength,
  830. OUT PULONG pulBytesWritten
  831. )
  832. /*++
  833. Routine Name:
  834. Routine Description:
  835. Arguments:
  836. Return Values:
  837. --*/
  838. {
  839. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  840. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("ExecuteIo: FuncCode 0x%x", ulFuncCode));
  841. if (ulFuncCode < MAX_FUNC_CODES) {
  842. Status = (*IoDispatchTable[ulFuncCode].Function)(pInputBuffer,
  843. ulInputBufferLength,
  844. pOutputBuffer,
  845. ulOutputBufferLength,
  846. pulBytesWritten);
  847. }
  848. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("ExecuteIo: Status 0x%x", Status));
  849. return (Status);
  850. }
  851. NTSTATUS
  852. MapConnectionId(
  853. IN PUCHAR pInputBuffer,
  854. IN ULONG ulInputBufferLength,
  855. IN PUCHAR pOutputBuffer,
  856. IN ULONG ulOutputBufferLength,
  857. OUT PULONG pulBytesWritten
  858. )
  859. /*++
  860. Routine Name:
  861. MapConnectionId
  862. Routine Description:
  863. This functions takes a WAN Wrapper connection id, finds the corresponding
  864. LinkCB and BundleCB, and returns handles to these CB's.
  865. Arguments:
  866. pInputBuffer - Pointer to the input structure that should be NDISWAN_MAP_CONNECTION_ID
  867. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_MAP_CONNECTION_ID)
  868. pOutputBuffer - Pointer to the output structure that should be NDISWAN_MAP_CONNNECTION_ID
  869. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_MAP_CONNECTION_ID)
  870. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  871. Return Values:
  872. NDISWAN_ERROR_INVALID_HANDLE
  873. STATUS_INFO_LENGTH_MISMATCH
  874. STATUS_SUCCESS
  875. --*/
  876. {
  877. NTSTATUS Status = STATUS_SUCCESS;
  878. PNDISWAN_MAP_CONNECTION_ID In = (PNDISWAN_MAP_CONNECTION_ID)pInputBuffer;
  879. PNDISWAN_MAP_CONNECTION_ID Out = (PNDISWAN_MAP_CONNECTION_ID)pOutputBuffer;
  880. ULONG SizeNeeded = sizeof(NDISWAN_MAP_CONNECTION_ID);
  881. ULONG i;
  882. POPENCB OpenCB = NULL;
  883. PLINKCB LinkCB = NULL;
  884. PBUNDLECB BundleCB = NULL;
  885. LOCK_STATE LockState;
  886. ULONG Count;
  887. BOOLEAN Found = FALSE;
  888. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("MapConnectionId:"));
  889. *pulBytesWritten = SizeNeeded;
  890. if (ulInputBufferLength < SizeNeeded ||
  891. ulOutputBufferLength < SizeNeeded) {
  892. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("MapConnectionId: Buffer to small: Size: %d, SizeNeeded %d",
  893. ulOutputBufferLength, SizeNeeded));
  894. return (STATUS_INFO_LENGTH_MISMATCH);
  895. }
  896. ASSERT(In->hLinkContext != NULL);
  897. do {
  898. //
  899. // Find the linkcb that has this connection id and return
  900. // both the linkcb index and the bundlecb index
  901. //
  902. NdisAcquireReadWriteLock(&ConnTableLock, FALSE, &LockState);
  903. do {
  904. ULONG index;
  905. PLIST_ENTRY le;
  906. if (PtrToUlong(In->hConnectionID) < ConnectionTable->ulArraySize) {
  907. //
  908. // This might be my handle and thus a direct index
  909. //
  910. LinkCB = *(ConnectionTable->LinkArray +
  911. PtrToUlong(In->hConnectionID));
  912. if ((LinkCB != NULL) &&
  913. (LinkCB->hLinkContext == NULL)) {
  914. Found = TRUE;
  915. break;
  916. }
  917. }
  918. //
  919. // The connectionid was not my handle so find the
  920. // correct linkcb in the connection table. Walk
  921. // the list backward.
  922. //
  923. le = ConnectionTable->LinkList.Blink;
  924. while (le != &ConnectionTable->LinkList) {
  925. LinkCB =
  926. CONTAINING_RECORD(le, LINKCB, ConnTableLinkage);
  927. if (LinkCB != NULL &&
  928. In->hConnectionID == LinkCB->ConnectionWrapperID &&
  929. LinkCB->hLinkContext == NULL) {
  930. Found = TRUE;
  931. break;
  932. }
  933. le = le->Blink;
  934. }
  935. } while (FALSE);
  936. if (!Found) {
  937. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  938. break;
  939. }
  940. NdisDprAcquireSpinLock(&LinkCB->Lock);
  941. if (LinkCB->State != LINK_UP) {
  942. Found = FALSE;
  943. NdisDprReleaseSpinLock(&LinkCB->Lock);
  944. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  945. break;
  946. }
  947. BundleCB = LinkCB->BundleCB;
  948. //
  949. // We have found the right link, return the link and bundle handles
  950. //
  951. Out->hLinkHandle = LinkCB->hLinkHandle;
  952. Out->hBundleHandle = BundleCB->hBundleHandle;
  953. LinkCB->hLinkContext = In->hLinkContext;
  954. BundleCB->hBundleContext = In->hBundleContext;
  955. REF_LINKCB(LinkCB);
  956. //
  957. // Copy the friendly name to the link
  958. //
  959. {
  960. ULONG CopyLength;
  961. CopyLength = (ulInputBufferLength -
  962. FIELD_OFFSET(NDISWAN_MAP_CONNECTION_ID, szName[0]));
  963. CopyLength = (CopyLength > In->ulNameLength) ?
  964. In->ulNameLength : CopyLength;
  965. CopyLength = (CopyLength > MAX_NAME_LENGTH) ?
  966. MAX_NAME_LENGTH : CopyLength;
  967. NdisMoveMemory(LinkCB->Name, In->szName, CopyLength);
  968. }
  969. OpenCB = LinkCB->OpenCB;
  970. NdisDprReleaseSpinLock(&LinkCB->Lock);
  971. //
  972. // If this link has some recv's pending because
  973. // we did not have a context mapped yet, we could
  974. // get into a state where our recv's stall. We
  975. // will kick start this by scheduling a routine
  976. // to complete the pending recv's.
  977. //
  978. NdisDprAcquireSpinLock(&IoRecvList.Lock);
  979. if (LinkCB->RecvDescCount != 0){
  980. if (!IoRecvList.TimerScheduled) {
  981. WAN_TIME TimeOut;
  982. IoRecvList.TimerScheduled = TRUE;
  983. NdisWanInitWanTime(&TimeOut, 15);
  984. KeSetTimer(&IoRecvList.Timer,
  985. TimeOut,
  986. &IoRecvList.Dpc);
  987. }
  988. }
  989. NdisDprReleaseSpinLock(&IoRecvList.Lock);
  990. NdisReleaseReadWriteLock(&ConnTableLock, &LockState);
  991. } while ( 0 );
  992. if (!Found) {
  993. //
  994. // We did not find a match to the connection id
  995. //
  996. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("MapConnectionId: ConnectionId not found! ConnectionId: 0x%x",
  997. In->hConnectionID));
  998. *pulBytesWritten = 0;
  999. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1000. }
  1001. if (OpenCB != NULL) {
  1002. //
  1003. // Wait for initialization to complete
  1004. //
  1005. NdisWanWaitForNotificationEvent(&OpenCB->InitEvent);
  1006. }
  1007. return (Status);
  1008. }
  1009. NTSTATUS
  1010. GetBundleHandle(
  1011. IN PUCHAR pInputBuffer,
  1012. IN ULONG ulInputBufferLength,
  1013. IN PUCHAR pOutputBuffer,
  1014. IN ULONG ulOutputBufferLength,
  1015. OUT PULONG pulBytesWritten
  1016. )
  1017. /*++
  1018. Routine Name:
  1019. GetBundleHandle
  1020. Routine Description:
  1021. This function takes a handle to a linkcb and returns the handle to the bundlecb
  1022. that the linkcb belongs to
  1023. Arguments:
  1024. pInputBuffer - Pointer to the input structure that should be NDISWAN_GET_BUNDLE_HANDLE
  1025. ulInputBufferLength - Length of the input buffer should be sizeof(NDISWAN_GET_BUNDLE_HANDLE)
  1026. pOutputBuffer - Pointer to the output structure that should be NDISWAN_GET_BUNDLE_HANDLE
  1027. ulOutputBufferLength - Length of the output buffer should be sizeof(NDISWAN_GET_BUNDLE_HANDLE)
  1028. Return Values:
  1029. NDISWAN_ERROR_INVALID_HANDLE
  1030. STATUS_INFO_LENGTH_MISMATCH
  1031. STATUS_SUCCESS
  1032. --*/
  1033. {
  1034. NTSTATUS Status = STATUS_SUCCESS;
  1035. PNDISWAN_GET_BUNDLE_HANDLE In = (PNDISWAN_GET_BUNDLE_HANDLE)pInputBuffer;
  1036. PNDISWAN_GET_BUNDLE_HANDLE Out = (PNDISWAN_GET_BUNDLE_HANDLE)pOutputBuffer;
  1037. ULONG SizeNeeded = sizeof(NDISWAN_GET_BUNDLE_HANDLE);
  1038. PLINKCB LinkCB = NULL;
  1039. PBUNDLECB BundleCB = NULL;
  1040. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetBundleHandle:"));
  1041. *pulBytesWritten = SizeNeeded;
  1042. do {
  1043. if (ulInputBufferLength < SizeNeeded ||
  1044. ulOutputBufferLength < SizeNeeded) {
  1045. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetBundleHandle: Buffer to small: Size: %d, SizeNeeded %d",
  1046. ulOutputBufferLength, SizeNeeded));
  1047. Status = STATUS_INFO_LENGTH_MISMATCH;
  1048. break;
  1049. }
  1050. if (!AreLinkAndBundleValid(In->hLinkHandle,
  1051. TRUE,
  1052. &LinkCB,
  1053. &BundleCB)) {
  1054. NdisWanDbgOut(DBG_FAILURE, DBG_IO,
  1055. ("GetBundleHandle: Invalid LinkHandle: 0x%x", In->hLinkHandle));
  1056. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1057. break;
  1058. }
  1059. //
  1060. // Get the bundle handle that this link belongs to
  1061. //
  1062. Out->hBundleHandle = BundleCB->hBundleHandle;
  1063. } while ( 0 );
  1064. //
  1065. // Derefs for the refs applied in AreLinkAndBundleValid
  1066. //
  1067. DEREF_LINKCB(LinkCB);
  1068. DEREF_BUNDLECB(BundleCB);
  1069. return (Status);
  1070. }
  1071. NTSTATUS
  1072. SetFriendlyName(
  1073. IN PUCHAR pInputBuffer,
  1074. IN ULONG ulInputBufferLength,
  1075. IN PUCHAR pOutputBuffer,
  1076. IN ULONG ulOutputBufferLength,
  1077. OUT PULONG pulBytesWritten
  1078. )
  1079. /*++
  1080. Routine Name:
  1081. SetFriendlyName
  1082. Routine Description:
  1083. Sets the friendly name of either a bundlecb or a linkcb
  1084. Arguments:
  1085. pInputBuffer - Pointer to the input structure that should be NDISWAN_SET_FRIENDLY_NAME
  1086. ulInputBufferLength - Length of the input buffer should be sizeof(NDISWAN_SET_FRIENDLY_NAME)
  1087. pOutputBuffer - Pointer to the output structure that should be NDISWAN_SET_FRIENDLY_NAME
  1088. ulOutputBufferLength - Length of the output buffer should be sizeof(NDISWAN_SET_FRIENDLY_NAME)
  1089. Return Values:
  1090. NDISWAN_ERROR_INVALID_HANDLE_TYPE
  1091. NDISWAN_ERROR_INVALID_HANDLE
  1092. STATUS_INFO_LENGTH_MISMATCH
  1093. STATUS_SUCCESS
  1094. --*/
  1095. {
  1096. NTSTATUS Status = STATUS_SUCCESS;
  1097. ULONG SizeNeeded = sizeof(NDISWAN_SET_FRIENDLY_NAME);
  1098. PLINKCB LinkCB;
  1099. PBUNDLECB BundleCB;
  1100. PUCHAR Dest;
  1101. ULONG CopyLength;
  1102. PNDISWAN_SET_FRIENDLY_NAME In =
  1103. (PNDISWAN_SET_FRIENDLY_NAME)pInputBuffer;
  1104. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetFriendlyName:"));
  1105. *pulBytesWritten = 0;
  1106. do {
  1107. if (ulInputBufferLength < SizeNeeded) {
  1108. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetFriendlyName: Buffer to small: Size: %d, SizeNeeded %d",
  1109. ulInputBufferLength, SizeNeeded));
  1110. *pulBytesWritten = SizeNeeded;
  1111. Status = STATUS_INFO_LENGTH_MISMATCH;
  1112. break;
  1113. }
  1114. if (In->usHandleType == LINKHANDLE) {
  1115. //
  1116. // Is this a link handle
  1117. //
  1118. if (!IsLinkValid(In->hHandle,
  1119. TRUE,
  1120. &LinkCB)) {
  1121. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetFriendlyName: Invalid LinkHandle: %x",
  1122. In->hHandle));
  1123. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1124. break;
  1125. }
  1126. NdisAcquireSpinLock(&LinkCB->Lock);
  1127. Dest = LinkCB->Name;
  1128. CopyLength = In->ulNameLength;
  1129. if (ulInputBufferLength - FIELD_OFFSET(NDISWAN_SET_FRIENDLY_NAME, szName) < CopyLength) {
  1130. CopyLength =
  1131. ulInputBufferLength - FIELD_OFFSET(NDISWAN_SET_FRIENDLY_NAME, szName);
  1132. }
  1133. if (CopyLength > MAX_NAME_LENGTH) {
  1134. CopyLength = MAX_NAME_LENGTH;
  1135. }
  1136. NdisMoveMemory(Dest,
  1137. In->szName,
  1138. CopyLength);
  1139. //
  1140. // Deref for the ref applied by IsLinkValid
  1141. //
  1142. DEREF_LINKCB_LOCKED(LinkCB);
  1143. } else if (In->usHandleType == BUNDLEHANDLE) {
  1144. //
  1145. // Or a bundle handle
  1146. //
  1147. if (!IsBundleValid(In->hHandle,
  1148. TRUE,
  1149. &BundleCB)) {
  1150. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetFriendlyName: Invalid BundleHandle: 0x%x",
  1151. In->hHandle));
  1152. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1153. break;
  1154. }
  1155. AcquireBundleLock(BundleCB);
  1156. Dest = BundleCB->Name;
  1157. CopyLength = In->ulNameLength;
  1158. if (ulInputBufferLength - FIELD_OFFSET(NDISWAN_SET_FRIENDLY_NAME, szName) < CopyLength) {
  1159. CopyLength =
  1160. ulInputBufferLength - FIELD_OFFSET(NDISWAN_SET_FRIENDLY_NAME, szName);
  1161. }
  1162. if (CopyLength > MAX_NAME_LENGTH) {
  1163. CopyLength = MAX_NAME_LENGTH;
  1164. }
  1165. NdisMoveMemory(Dest,
  1166. In->szName,
  1167. CopyLength);
  1168. //
  1169. // Deref for the ref applied by IsBundleValid
  1170. //
  1171. DEREF_BUNDLECB_LOCKED(BundleCB);
  1172. } else {
  1173. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetFriendlyName: Invalid HandleType: 0x%x",
  1174. In->usHandleType));
  1175. Status = NDISWAN_ERROR_INVALID_HANDLE_TYPE;
  1176. break;
  1177. }
  1178. } while ( 0 );
  1179. return (Status);
  1180. }
  1181. NTSTATUS
  1182. ActivateRoute(
  1183. IN PUCHAR pInputBuffer,
  1184. IN ULONG ulInputBufferLength,
  1185. IN PUCHAR pOutputBuffer,
  1186. IN ULONG ulOutputBufferLength,
  1187. OUT PULONG pulBytesWritten
  1188. )
  1189. /*++
  1190. Routine Name:
  1191. ActivateRoute
  1192. Routine Description:
  1193. This function routes the bundle given by hbundlehandle to
  1194. the protocol give by usprotocoltype.
  1195. Arguments:
  1196. pInputBuffer - Pointer to the input structure that should be NDISWAN_ACTIVATE_ROUTE
  1197. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_ACTIVATE_ROUTE)
  1198. pOutputBuffer - Pointer to the output structure that should be NDISWAN_ACTIVATE_ROUTE
  1199. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_ACTIVATE_ROUTE)
  1200. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  1201. Return Values:
  1202. NDISWAN_ERROR_ALREADY_ROUTED
  1203. NDISWAN_ERROR_INVALID_HANDLE
  1204. STATUS_INSUFFICIENT_RESOURCES
  1205. STATUS_INFO_LENGTH_MISMATCH
  1206. --*/
  1207. {
  1208. NTSTATUS Status = STATUS_SUCCESS;
  1209. PNDISWAN_ROUTE In = (PNDISWAN_ROUTE)pInputBuffer;
  1210. PNDISWAN_ROUTE Out = (PNDISWAN_ROUTE)pOutputBuffer;
  1211. ULONG SizeNeeded = sizeof(NDISWAN_ROUTE);
  1212. ULONG AllocationSize, i;
  1213. PBUNDLECB BundleCB = NULL;
  1214. BOOLEAN RouteExists = FALSE;
  1215. PPROTOCOLCB ProtocolCB;
  1216. NDIS_HANDLE hProto;
  1217. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("ActivateRoute:"));
  1218. *pulBytesWritten = SizeNeeded;
  1219. do {
  1220. if (ulInputBufferLength < SizeNeeded ||
  1221. ulOutputBufferLength < SizeNeeded ||
  1222. In->ulBufferLength > ulInputBufferLength ||
  1223. In->usBindingNameLength > ulInputBufferLength) {
  1224. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("ActivateRoute: Buffer to small: Size: %d, SizeNeeded %d",
  1225. ulInputBufferLength, SizeNeeded));
  1226. Status = STATUS_INFO_LENGTH_MISMATCH;
  1227. break;
  1228. }
  1229. //
  1230. // If this is a valid bundle
  1231. //
  1232. if (!IsBundleValid(In->hBundleHandle,
  1233. TRUE,
  1234. &BundleCB)) {
  1235. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("ActivateRoute: Invalid BundleHandle: 0x%x, ProtocolType: 0x%x",
  1236. In->hBundleHandle, In->usProtocolType));
  1237. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1238. break;
  1239. }
  1240. AcquireBundleLock(BundleCB);
  1241. //
  1242. // Create and initialize a ProtocolCB for this new route
  1243. //
  1244. ProtocolCB =
  1245. NdisWanAllocateProtocolCB(In);
  1246. if (ProtocolCB == NULL) {
  1247. //
  1248. // Memory allocation failed
  1249. //
  1250. ReleaseBundleLock(BundleCB);
  1251. Status = STATUS_INSUFFICIENT_RESOURCES;
  1252. break;
  1253. }
  1254. //
  1255. // Assign a handle for this protocolcb
  1256. //
  1257. hProto =
  1258. AssignProtocolCBHandle(BundleCB, ProtocolCB);
  1259. if (hProto == (NDIS_HANDLE)MAX_PROTOCOLS) {
  1260. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("ActivateRoute: No room in ProtocolCB Table: ProtocolType: 0x%2.2x",
  1261. ProtocolCB->ProtocolType));
  1262. ProtocolCB->State = PROTOCOL_UNROUTING;
  1263. NdisWanFreeProtocolCB(ProtocolCB);
  1264. ReleaseBundleLock(BundleCB);
  1265. Status = NDISWAN_ERROR_NO_ROUTE;
  1266. break;
  1267. }
  1268. //
  1269. // Do a new lineup to protocol
  1270. //
  1271. ReleaseBundleLock(BundleCB);
  1272. Status = DoNewLineUpToProtocol(ProtocolCB);
  1273. if (Status == NDIS_STATUS_SUCCESS) {
  1274. Out->usDeviceNameLength =
  1275. (ProtocolCB->OutDeviceName.Length > MAX_NAME_LENGTH) ?
  1276. MAX_NAME_LENGTH : ProtocolCB->OutDeviceName.Length;
  1277. NdisMoveMemory(&Out->DeviceName[0],
  1278. ProtocolCB->OutDeviceName.Buffer,
  1279. Out->usDeviceNameLength);
  1280. //
  1281. // Insert the protocolcb in the bundle's protocolcb table
  1282. // and list.
  1283. //
  1284. AddProtocolCBToBundle(ProtocolCB, BundleCB);
  1285. } else {
  1286. AcquireBundleLock(BundleCB);
  1287. FreeProtocolCBHandle(BundleCB, ProtocolCB);
  1288. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("ActivateRoute: Error during LineUp to ProtocolType: 0x%x",
  1289. ProtocolCB->ProtocolType));
  1290. ProtocolCB->State = PROTOCOL_UNROUTING;
  1291. NdisWanFreeProtocolCB(ProtocolCB);
  1292. ReleaseBundleLock(BundleCB);
  1293. }
  1294. } while ( 0 );
  1295. //
  1296. // Deref for ref applied by IsBundleValid
  1297. //
  1298. DEREF_BUNDLECB(BundleCB);
  1299. return (Status);
  1300. }
  1301. NTSTATUS
  1302. BundleLink(
  1303. IN PUCHAR pInputBuffer,
  1304. IN ULONG ulInputBufferLength,
  1305. IN PUCHAR pOutputBuffer,
  1306. IN ULONG ulOutputBufferLength,
  1307. OUT PULONG pulBytesWritten
  1308. )
  1309. /*++
  1310. Routine Name:
  1311. BundleLink
  1312. Routine Description:
  1313. This function bundles the link given by hLinkHandle to the bundle given
  1314. by hBundlehandle. The resources used by the bundle that the link used
  1315. to belong to are freed.
  1316. Arguments:
  1317. pInputBuffer - Pointer to the input structure that should be NDISWAN_ADD_LINK_TO_BUNDLE
  1318. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_ADD_LINK_TO_BUNDLE)
  1319. pOutputBuffer - Pointer to the output structure that should be NDISWAN_ADD_LINK_TO_BUNDLE
  1320. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_ADD_LINK_TO_BUNDLE)
  1321. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  1322. Return Values:
  1323. NDISWAN_ERROR_INVALID_HANDLE
  1324. STATUS_INFO_LENGTH_MISMATCH
  1325. --*/
  1326. {
  1327. ULONG SizeNeeded = sizeof(NDISWAN_ADD_LINK_TO_BUNDLE);
  1328. PLINKCB LinkCB = NULL;
  1329. PBUNDLECB OldBundleCB = NULL, NewBundleCB = NULL;
  1330. NTSTATUS Status = STATUS_SUCCESS;
  1331. PPROTOCOLCB IoProtocolCB;
  1332. PPACKET_QUEUE PacketQueue;
  1333. PACKET_QUEUE TempPacketQueue;
  1334. PNDISWAN_ADD_LINK_TO_BUNDLE In =
  1335. (PNDISWAN_ADD_LINK_TO_BUNDLE)pInputBuffer;
  1336. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("BundleLink:"));
  1337. *pulBytesWritten = 0;
  1338. do {
  1339. if (ulInputBufferLength < SizeNeeded) {
  1340. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("BundleLink: Buffer to small: Size: %d, SizeNeeded %d",
  1341. ulInputBufferLength, SizeNeeded));
  1342. Status = STATUS_INFO_LENGTH_MISMATCH;
  1343. break;
  1344. }
  1345. if (!AreLinkAndBundleValid(In->hLinkHandle,
  1346. TRUE,
  1347. &LinkCB,
  1348. &OldBundleCB)) {
  1349. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("BundleLink: Invalid LinkHandle: 0x%x",
  1350. In->hLinkHandle));
  1351. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1352. break;
  1353. }
  1354. if (!IsBundleValid(In->hBundleHandle,
  1355. TRUE,
  1356. &NewBundleCB)) {
  1357. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("BundleLink: Invalid NewBundleCB: 0x%p, OldBundleCB: 0x%p",
  1358. NewBundleCB, OldBundleCB));
  1359. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1360. break;
  1361. }
  1362. if (NewBundleCB == OldBundleCB) {
  1363. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("BundleLink: Invalid NewBundleCB: 0x%p, OldBundleCB: 0x%p",
  1364. NewBundleCB, OldBundleCB));
  1365. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1366. break;
  1367. }
  1368. AcquireBundleLock(OldBundleCB);
  1369. ASSERT(OldBundleCB->ulLinkCBCount == 1);
  1370. ASSERT(OldBundleCB->ulNumberOfRoutes == 0);
  1371. OldBundleCB->State = BUNDLE_GOING_DOWN;
  1372. if (OldBundleCB->OutstandingFrames != 0) {
  1373. NdisWanClearSyncEvent(&OldBundleCB->OutstandingFramesEvent);
  1374. OldBundleCB->Flags |= FRAMES_PENDING_EVENT;
  1375. ReleaseBundleLock(OldBundleCB);
  1376. NdisWanWaitForSyncEvent(&OldBundleCB->OutstandingFramesEvent);
  1377. AcquireBundleLock(OldBundleCB);
  1378. }
  1379. //
  1380. // Remove any ppp packets that might be on the old bundle
  1381. // queue so we can move them to the new bundle.
  1382. //
  1383. IoProtocolCB = OldBundleCB->IoProtocolCB;
  1384. PacketQueue = &IoProtocolCB->PacketQueue[MAX_MCML];
  1385. NdisZeroMemory(&TempPacketQueue, sizeof(TempPacketQueue));
  1386. if (!IsPacketQueueEmpty(PacketQueue)) {
  1387. while (!IsPacketQueueEmpty(PacketQueue)) {
  1388. PNDIS_PACKET Packet;
  1389. UINT PacketLength;
  1390. Packet =
  1391. RemoveHeadPacketQueue(PacketQueue);
  1392. NdisQueryPacket(Packet,
  1393. NULL,
  1394. NULL,
  1395. NULL,
  1396. &PacketLength);
  1397. InsertTailPacketQueue(&TempPacketQueue,
  1398. Packet,
  1399. PacketLength);
  1400. }
  1401. }
  1402. //
  1403. // Remove the link from the old bundle. This returns
  1404. // with the OldBundleCB lock released!
  1405. //
  1406. RemoveLinkFromBundle(OldBundleCB, LinkCB, TRUE);
  1407. AcquireBundleLock(NewBundleCB);
  1408. //
  1409. // Add the link to the new bundle
  1410. //
  1411. AddLinkToBundle(NewBundleCB, LinkCB);
  1412. SetBundleFlags(NewBundleCB);
  1413. //
  1414. // If there were any ppp packets on the old bundle
  1415. // queue we can now place them on the new bundle.
  1416. //
  1417. if (!IsPacketQueueEmpty(&TempPacketQueue)) {
  1418. IoProtocolCB = NewBundleCB->IoProtocolCB;
  1419. PacketQueue = &IoProtocolCB->PacketQueue[MAX_MCML];
  1420. while (!IsPacketQueueEmpty(&TempPacketQueue)) {
  1421. PNDIS_PACKET Packet;
  1422. UINT PacketLength;
  1423. Packet =
  1424. RemoveHeadPacketQueue(&TempPacketQueue)
  1425. NdisQueryPacket(Packet,
  1426. NULL,
  1427. NULL,
  1428. NULL,
  1429. &PacketLength);
  1430. InsertTailPacketQueue(PacketQueue,
  1431. Packet,
  1432. PacketLength);
  1433. }
  1434. }
  1435. ReleaseBundleLock(NewBundleCB);
  1436. } while ( 0 );
  1437. //
  1438. // Derefs for the refs applied by AreLinkAndBundleValid
  1439. //
  1440. DEREF_LINKCB(LinkCB);
  1441. DEREF_BUNDLECB(OldBundleCB);
  1442. //
  1443. // Deref for the ref applied by IsBundleValid
  1444. //
  1445. DEREF_BUNDLECB(NewBundleCB);
  1446. return (Status);
  1447. }
  1448. NTSTATUS
  1449. EnumLinksInBundle(
  1450. IN PUCHAR pInputBuffer,
  1451. IN ULONG ulInputBufferLength,
  1452. IN PUCHAR pOutputBuffer,
  1453. IN ULONG ulOutputBufferLength,
  1454. OUT PULONG pulBytesWritten
  1455. )
  1456. /*++
  1457. Routine Name:
  1458. Routine Description:
  1459. Arguments:
  1460. Return Values:
  1461. --*/
  1462. {
  1463. ULONG SizeNeeded = 0;
  1464. ULONG i;
  1465. PBUNDLECB BundleCB = NULL;
  1466. PLINKCB LinkCB;
  1467. NTSTATUS Status = STATUS_SUCCESS;
  1468. PNDISWAN_ENUM_LINKS_IN_BUNDLE In =
  1469. (PNDISWAN_ENUM_LINKS_IN_BUNDLE)pInputBuffer;
  1470. PNDISWAN_ENUM_LINKS_IN_BUNDLE Out =
  1471. (PNDISWAN_ENUM_LINKS_IN_BUNDLE)pOutputBuffer;
  1472. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("EnumLinksInBundle:"));
  1473. do {
  1474. if (ulInputBufferLength < sizeof(NDISWAN_ENUM_LINKS_IN_BUNDLE)) {
  1475. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("EnumLinksInBundle: Buffer to small: Size: %d, SizeNeeded %d",
  1476. ulInputBufferLength, sizeof(NDISWAN_ENUM_LINKS_IN_BUNDLE)));
  1477. Status = STATUS_INFO_LENGTH_MISMATCH;
  1478. break;
  1479. }
  1480. if (!IsBundleValid(In->hBundleHandle,
  1481. TRUE,
  1482. &BundleCB)) {
  1483. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("EnumLinksInBundle: Invalid BundleHandle: 0x%x",
  1484. In->hBundleHandle));
  1485. Status = NDISWAN_ERROR_INVALID_HANDLE;
  1486. break;
  1487. }
  1488. AcquireBundleLock(BundleCB);
  1489. SizeNeeded = sizeof(NDISWAN_ENUM_LINKS_IN_BUNDLE) +
  1490. (sizeof(NDIS_HANDLE) * BundleCB->ulLinkCBCount);
  1491. *pulBytesWritten = SizeNeeded;
  1492. if (ulOutputBufferLength < SizeNeeded) {
  1493. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("EnumLinksInBundle: Buffer to small: Size: %d, SizeNeeded %d",
  1494. ulOutputBufferLength, SizeNeeded));
  1495. Status = STATUS_INFO_LENGTH_MISMATCH;
  1496. break;
  1497. }
  1498. Out->ulNumberOfLinks = BundleCB->ulLinkCBCount;
  1499. //
  1500. // Walk the list of linkcb's and put the handle for each
  1501. // cb in the output handle array
  1502. //
  1503. i = 0;
  1504. for (LinkCB = (PLINKCB)BundleCB->LinkCBList.Flink;
  1505. (PVOID)LinkCB != (PVOID)&BundleCB->LinkCBList;
  1506. LinkCB = (PLINKCB)LinkCB->Linkage.Flink) {
  1507. Out->hLinkHandleArray[i++] = LinkCB->hLinkHandle;
  1508. }
  1509. } while ( 0 );
  1510. //
  1511. // Deref for ref applied by IsBundleValid
  1512. //
  1513. DEREF_BUNDLECB_LOCKED(BundleCB);
  1514. return (Status);
  1515. }
  1516. NTSTATUS
  1517. SetProtocolPriority(
  1518. IN PUCHAR pInputBuffer,
  1519. IN ULONG ulInputBufferLength,
  1520. IN PUCHAR pOutputBuffer,
  1521. IN ULONG ulOutputBufferLength,
  1522. OUT PULONG pulBytesWritten
  1523. )
  1524. /*++
  1525. Routine Name:
  1526. SetProtocolPriority
  1527. Routine Description:
  1528. This function sets the the priority, given by uspriority, for the
  1529. protocol given by usprotocoltype on the bundle given by hbundlehandle.
  1530. Arguments:
  1531. pInputBuffer - Pointer to the input structure that should be NDISWAN_SET_PROTOCOL_PRIORITY
  1532. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_SET_PROTOCOL_PRIORITY)
  1533. pOutputBuffer - Pointer to the output structure that should be NDISWAN_SET_PROTOCOL_PRIORITY
  1534. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_SET_PROTOCOL_PRIORITY)
  1535. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  1536. Return Values:
  1537. NDISWAN_ERROR_INVALID_HANDLE
  1538. STATUS_INFO_LENGTH_MISMATCH
  1539. --*/
  1540. {
  1541. NTSTATUS Status = STATUS_SUCCESS;
  1542. ULONG SizeNeeded = sizeof(NDISWAN_SET_PROTOCOL_PRIORITY);
  1543. PNDISWAN_SET_PROTOCOL_PRIORITY In = (PNDISWAN_SET_PROTOCOL_PRIORITY)pInputBuffer;
  1544. PBUNDLECB BundleCB = NULL;
  1545. PPROTOCOLCB ProtocolCB;
  1546. ULONG BytesPerSecond;
  1547. *pulBytesWritten = 0;
  1548. return (STATUS_SUCCESS);
  1549. }
  1550. NTSTATUS
  1551. SetBandwidthOnDemand(
  1552. IN PUCHAR pInputBuffer,
  1553. IN ULONG ulInputBufferLength,
  1554. IN PUCHAR pOutputBuffer,
  1555. IN ULONG ulOutputBufferLength,
  1556. OUT PULONG pulBytesWritten
  1557. )
  1558. /*++
  1559. Routine Name:
  1560. SetBandwidthOnDemand
  1561. Routine Description:
  1562. This function sets the bandwidth on demand parameters for the bundle given by
  1563. hbundlehandle.
  1564. Arguments:
  1565. pInputBuffer - Pointer to the input structure that should be NDISWAN_SET_BANDWIDTH_ON_DEMAND
  1566. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_SET_BANDWIDTH_ON_DEMAND)
  1567. pOutputBuffer - Pointer to the output structure that should be NDISWAN_SET_BANDWIDTH_ON_DEMAND
  1568. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_SET_BANDWIDTH_ON_DEMAND)
  1569. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  1570. Return Values:
  1571. NDISWAN_ERROR_INVALID_HANDLE
  1572. STATUS_INFO_LENGTH_MISMATCH
  1573. --*/
  1574. {
  1575. NTSTATUS Status = STATUS_SUCCESS;
  1576. PBUNDLECB BundleCB = NULL;
  1577. ULONG SizeNeeded = sizeof(NDISWAN_SET_BANDWIDTH_ON_DEMAND);
  1578. PNDISWAN_SET_BANDWIDTH_ON_DEMAND In = (PNDISWAN_SET_BANDWIDTH_ON_DEMAND)pInputBuffer;
  1579. WAN_TIME Temp1, Temp2;
  1580. ULONGLONG SecondsInSamplePeriod;
  1581. ULONGLONG BytesPerSecond;
  1582. ULONGLONG BytesInSamplePeriod;
  1583. ULONGLONG temp;
  1584. ULONG LowestSamplePeriod = 0;
  1585. PBOND_INFO BonDInfo;
  1586. PSAMPLE_TABLE SampleTable;
  1587. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetBandwidthOnDemand:"));
  1588. *pulBytesWritten = 0;
  1589. if (ulInputBufferLength < SizeNeeded) {
  1590. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetBandwidthOnDemand: Buffer to small: Size: %d, SizeNeeded %d",
  1591. ulInputBufferLength, SizeNeeded));
  1592. *pulBytesWritten = SizeNeeded;
  1593. return STATUS_INFO_LENGTH_MISMATCH;
  1594. }
  1595. //
  1596. // If this is a valid bundle handle
  1597. //
  1598. if (!IsBundleValid(In->hBundleHandle,
  1599. TRUE,
  1600. &BundleCB)) {
  1601. NdisWanDbgOut(DBG_FAILURE, DBG_IO,
  1602. ("SetBandwidthOnDemand: Invalid BundleHandle: 0x%x",
  1603. In->hBundleHandle));
  1604. return NDISWAN_ERROR_INVALID_HANDLE;
  1605. }
  1606. do {
  1607. AcquireBundleLock(BundleCB);
  1608. if (BundleCB->BonDAllocation == NULL) {
  1609. PUCHAR pMem;
  1610. NdisWanAllocatePriorityMemory(&pMem,
  1611. BONDALLOC_SIZE,
  1612. BONDALLOC_TAG,
  1613. LowPoolPriority);
  1614. if (pMem == NULL) {
  1615. // ReleaseBundleLock(BundleCB);
  1616. Status = STATUS_INSUFFICIENT_RESOURCES;
  1617. break;
  1618. }
  1619. BundleCB->BonDAllocation = pMem;
  1620. BundleCB->SUpperBonDInfo = (PBOND_INFO)pMem;
  1621. pMem += (sizeof(BOND_INFO) + sizeof(PVOID));
  1622. (ULONG_PTR)pMem &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1623. BundleCB->SLowerBonDInfo = (PBOND_INFO)pMem;
  1624. pMem += (sizeof(BOND_INFO) + sizeof(PVOID));
  1625. (ULONG_PTR)pMem &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1626. BundleCB->RUpperBonDInfo = (PBOND_INFO)pMem;
  1627. pMem += (sizeof(BOND_INFO) + sizeof(PVOID));
  1628. (ULONG_PTR)pMem &= ~((ULONG_PTR)sizeof(PVOID) - 1);
  1629. BundleCB->RLowerBonDInfo = (PBOND_INFO)pMem;
  1630. BonDInfo = BundleCB->SUpperBonDInfo;
  1631. BonDInfo->DataType = TRANSMIT_DATA;
  1632. BonDInfo->usPercentBandwidth = 0xFFFF;
  1633. SampleTable = &BonDInfo->SampleTable;
  1634. SampleTable->ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  1635. BonDInfo = BundleCB->SLowerBonDInfo;
  1636. BonDInfo->DataType = TRANSMIT_DATA;
  1637. BonDInfo->usPercentBandwidth = 0xFFFF;
  1638. SampleTable = &BonDInfo->SampleTable;
  1639. SampleTable->ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  1640. BonDInfo = BundleCB->RUpperBonDInfo;
  1641. BonDInfo->DataType = RECEIVE_DATA;
  1642. BonDInfo->usPercentBandwidth = 0xFFFF;
  1643. SampleTable = &BonDInfo->SampleTable;
  1644. SampleTable->ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  1645. BonDInfo = BundleCB->RLowerBonDInfo;
  1646. BonDInfo->DataType = RECEIVE_DATA;
  1647. BonDInfo->usPercentBandwidth = 0xFFFF;
  1648. SampleTable = &BonDInfo->SampleTable;
  1649. SampleTable->ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  1650. }
  1651. if (In->usLowerXmitThreshold > 0) {
  1652. BonDInfo = BundleCB->SLowerBonDInfo;
  1653. SampleTable = &BonDInfo->SampleTable;
  1654. //
  1655. // One second is the smallest sample period we support!
  1656. //
  1657. if (In->ulLowerXmitSamplePeriod < 1000) {
  1658. In->ulLowerXmitSamplePeriod = 1000;
  1659. }
  1660. //
  1661. // We need to init the sample period in 100 nanoseconds
  1662. //
  1663. NdisWanInitWanTime(&Temp1, MILS_TO_100NANOS);
  1664. NdisWanInitWanTime(&Temp2, In->ulLowerXmitSamplePeriod);
  1665. NdisWanMultiplyWanTime(&SampleTable->SamplePeriod,
  1666. &Temp1,&Temp2);
  1667. //
  1668. // The sample rate is the sample period divided by the number of
  1669. // samples in the sample array
  1670. //
  1671. NdisWanInitWanTime(&Temp1, SampleTable->ulSampleArraySize);
  1672. NdisWanDivideWanTime(&SampleTable->SampleRate,
  1673. &SampleTable->SamplePeriod,
  1674. &Temp1);
  1675. //
  1676. // Convert %bandwidth to Bytes/SamplePeriod
  1677. // 100bsp * 100 / 8 = BytesPerSecond
  1678. // BytesPerSecond * SecondsInSamplePeriod = BytesInSamplePeriod
  1679. // BytesInSamplePeriod * %Bandwidth / 100 = BytesInSamplePeriod
  1680. //
  1681. SecondsInSamplePeriod = BonDInfo->ulSecondsInSamplePeriod =
  1682. In->ulLowerXmitSamplePeriod / 1000;
  1683. BytesPerSecond =
  1684. BundleCB->SFlowSpec.PeakBandwidth;
  1685. BytesInSamplePeriod =
  1686. BytesPerSecond * SecondsInSamplePeriod;
  1687. BonDInfo->ulBytesInSamplePeriod = BytesInSamplePeriod;
  1688. BonDInfo->usPercentBandwidth = In->usLowerXmitThreshold;
  1689. temp = In->usLowerXmitThreshold;
  1690. temp *= BytesInSamplePeriod;
  1691. temp /= 100;
  1692. BonDInfo->ulBytesThreshold = (ULONG)temp;
  1693. if (BonDInfo->State == BonDSignaled) {
  1694. BonDInfo->State = BonDIdle;
  1695. }
  1696. NdisWanGetSystemTime(&BonDInfo->StartTime);
  1697. if (In->ulLowerXmitSamplePeriod < LowestSamplePeriod ||
  1698. LowestSamplePeriod == 0) {
  1699. LowestSamplePeriod = In->ulLowerXmitSamplePeriod;
  1700. }
  1701. }
  1702. if (In->usUpperXmitThreshold > 0) {
  1703. BonDInfo = BundleCB->SUpperBonDInfo;
  1704. SampleTable = &BonDInfo->SampleTable;
  1705. //
  1706. // One second is the smallest sample period we support!
  1707. //
  1708. if (In->ulUpperXmitSamplePeriod < 1000) {
  1709. In->ulUpperXmitSamplePeriod = 1000;
  1710. }
  1711. //
  1712. // We need to init the sample period in 100 nanoseconds
  1713. //
  1714. NdisWanInitWanTime(&Temp1, MILS_TO_100NANOS);
  1715. NdisWanInitWanTime(&Temp2, In->ulUpperXmitSamplePeriod);
  1716. NdisWanMultiplyWanTime(&SampleTable->SamplePeriod,
  1717. &Temp1,
  1718. &Temp2);
  1719. //
  1720. // The sample rate is the sample period divided by the number of
  1721. // samples in the sample array
  1722. //
  1723. NdisWanInitWanTime(&Temp1, SampleTable->ulSampleArraySize);
  1724. NdisWanDivideWanTime(&SampleTable->SampleRate,
  1725. &SampleTable->SamplePeriod,
  1726. &Temp1);
  1727. //
  1728. // Convert %bandwidth to Bytes/SamplePeriod
  1729. // 100bsp * 100 / 8 = BytesPerSecond
  1730. // BytesPerSecond * SecondsInSamplePeriod = BytesInSamplePeriod
  1731. // BytesInSamplePeriod * %Bandwidth / 100 = BytesInSamplePeriod
  1732. //
  1733. SecondsInSamplePeriod = BonDInfo->ulSecondsInSamplePeriod =
  1734. In->ulUpperXmitSamplePeriod / 1000;
  1735. BytesPerSecond =
  1736. BundleCB->SFlowSpec.PeakBandwidth;
  1737. BytesInSamplePeriod =
  1738. BytesPerSecond * SecondsInSamplePeriod;
  1739. BonDInfo->ulBytesInSamplePeriod =
  1740. (ULONG)BytesInSamplePeriod;
  1741. BonDInfo->usPercentBandwidth = In->usUpperXmitThreshold;
  1742. temp = In->usUpperXmitThreshold;
  1743. temp *= BytesInSamplePeriod;
  1744. temp /= 100;
  1745. BonDInfo->ulBytesThreshold = (ULONG)temp;
  1746. if (BonDInfo->State == BonDSignaled) {
  1747. BonDInfo->State = BonDIdle;
  1748. }
  1749. NdisWanGetSystemTime(&BonDInfo->StartTime);
  1750. if (In->ulUpperXmitSamplePeriod < LowestSamplePeriod ||
  1751. LowestSamplePeriod == 0) {
  1752. LowestSamplePeriod = In->ulUpperXmitSamplePeriod;
  1753. }
  1754. }
  1755. if (In->usLowerRecvThreshold > 0) {
  1756. BonDInfo = BundleCB->RLowerBonDInfo;
  1757. SampleTable = &BonDInfo->SampleTable;
  1758. //
  1759. // One second is the smallest sample period we support!
  1760. //
  1761. if (In->ulLowerRecvSamplePeriod < 1000) {
  1762. In->ulLowerRecvSamplePeriod = 1000;
  1763. }
  1764. //
  1765. // We need to init the sample period in 100 nanoseconds
  1766. //
  1767. NdisWanInitWanTime(&Temp1, MILS_TO_100NANOS);
  1768. NdisWanInitWanTime(&Temp2, In->ulLowerRecvSamplePeriod);
  1769. NdisWanMultiplyWanTime(&SampleTable->SamplePeriod,
  1770. &Temp1,&Temp2);
  1771. //
  1772. // The sample rate is the sample period divided by the number of
  1773. // samples in the sample array
  1774. //
  1775. NdisWanInitWanTime(&Temp1, SampleTable->ulSampleArraySize);
  1776. NdisWanDivideWanTime(&SampleTable->SampleRate,
  1777. &SampleTable->SamplePeriod,
  1778. &Temp1);
  1779. //
  1780. // Convert %bandwidth to Bytes/SamplePeriod
  1781. // 100bsp * 100 / 8 = BytesPerSecond
  1782. // BytesPerSecond * SecondsInSamplePeriod = BytesInSamplePeriod
  1783. // BytesInSamplePeriod * %Bandwidth / 100 = BytesInSamplePeriod
  1784. //
  1785. SecondsInSamplePeriod = BonDInfo->ulSecondsInSamplePeriod =
  1786. In->ulLowerRecvSamplePeriod / 1000;
  1787. BytesPerSecond =
  1788. BundleCB->RFlowSpec.PeakBandwidth;
  1789. BytesInSamplePeriod =
  1790. BytesPerSecond * SecondsInSamplePeriod;
  1791. BonDInfo->ulBytesInSamplePeriod = BytesInSamplePeriod;
  1792. BonDInfo->usPercentBandwidth = In->usLowerRecvThreshold;
  1793. temp = In->usLowerRecvThreshold;
  1794. temp *= BytesInSamplePeriod;
  1795. temp /= 100;
  1796. BonDInfo->ulBytesThreshold = (ULONG)temp;
  1797. if (BonDInfo->State == BonDSignaled) {
  1798. BonDInfo->State = BonDIdle;
  1799. }
  1800. NdisWanGetSystemTime(&BonDInfo->StartTime);
  1801. if (In->ulLowerRecvSamplePeriod < LowestSamplePeriod ||
  1802. LowestSamplePeriod == 0) {
  1803. LowestSamplePeriod = In->ulLowerRecvSamplePeriod;
  1804. }
  1805. }
  1806. if (In->usUpperRecvThreshold > 0) {
  1807. BonDInfo = BundleCB->RUpperBonDInfo;
  1808. SampleTable = &BonDInfo->SampleTable;
  1809. //
  1810. // One second is the smallest sample period we support!
  1811. //
  1812. if (In->ulUpperRecvSamplePeriod < 1000) {
  1813. In->ulUpperRecvSamplePeriod = 1000;
  1814. }
  1815. //
  1816. // We need to init the sample period in 100 nanoseconds
  1817. //
  1818. NdisWanInitWanTime(&Temp1, MILS_TO_100NANOS);
  1819. NdisWanInitWanTime(&Temp2, In->ulUpperRecvSamplePeriod);
  1820. NdisWanMultiplyWanTime(&SampleTable->SamplePeriod,
  1821. &Temp1,
  1822. &Temp2);
  1823. //
  1824. // The sample rate is the sample period divided by the number of
  1825. // samples in the sample array
  1826. //
  1827. NdisWanInitWanTime(&Temp1, SampleTable->ulSampleArraySize);
  1828. NdisWanDivideWanTime(&SampleTable->SampleRate,
  1829. &SampleTable->SamplePeriod,
  1830. &Temp1);
  1831. //
  1832. // Convert %bandwidth to Bytes/SamplePeriod
  1833. // 100bsp * 100 / 8 = BytesPerSecond
  1834. // BytesPerSecond * SecondsInSamplePeriod = BytesInSamplePeriod
  1835. // BytesInSamplePeriod * %Bandwidth / 100 = BytesInSamplePeriod
  1836. //
  1837. SecondsInSamplePeriod = BonDInfo->ulSecondsInSamplePeriod =
  1838. In->ulUpperRecvSamplePeriod / 1000;
  1839. BytesPerSecond =
  1840. BundleCB->RFlowSpec.PeakBandwidth;
  1841. BytesInSamplePeriod =
  1842. BytesPerSecond * SecondsInSamplePeriod;
  1843. BonDInfo->ulBytesInSamplePeriod = BytesInSamplePeriod;
  1844. BonDInfo->usPercentBandwidth = In->usUpperRecvThreshold;
  1845. temp = In->usUpperRecvThreshold;
  1846. temp *= BytesInSamplePeriod;
  1847. temp /= 100;
  1848. BonDInfo->ulBytesThreshold = (ULONG)temp;
  1849. if (BonDInfo->State == BonDSignaled) {
  1850. BonDInfo->State = BonDIdle;
  1851. }
  1852. NdisWanGetSystemTime(&BonDInfo->StartTime);
  1853. if (In->ulUpperRecvSamplePeriod < LowestSamplePeriod ||
  1854. LowestSamplePeriod == 0) {
  1855. LowestSamplePeriod = In->ulUpperRecvSamplePeriod;
  1856. }
  1857. }
  1858. #if 0
  1859. //
  1860. // I want to set a periodic timer with a period equal to
  1861. // the smallest non-zero period
  1862. //
  1863. if (LowestSamplePeriod != 0) {
  1864. LARGE_INTEGER FireTime;
  1865. BundleCB->TimerPeriod = LowestSamplePeriod/10;
  1866. FireTime.QuadPart = Int32x32To64(BundleCB->TimerPeriod, -10000);
  1867. KeSetTimerEx(&BundleCB->BonDTimer,
  1868. FireTime,
  1869. BundleCB->TimerPeriod,
  1870. &BundleCB->TimerDpc);
  1871. }
  1872. #endif
  1873. if (!(BundleCB->Flags & BOND_ENABLED) &&
  1874. (LowestSamplePeriod != 0)) {
  1875. InsertTailGlobalListEx(BonDWorkList, &BundleCB->BonDLinkage, 1000, 1000);
  1876. BundleCB->Flags |= BOND_ENABLED;
  1877. }
  1878. } while ( 0 );
  1879. //
  1880. // Deref for ref applied by IsBundleValid. This release the
  1881. // BundleCB->Lock.
  1882. //
  1883. DEREF_BUNDLECB_LOCKED(BundleCB);
  1884. return (Status);
  1885. }
  1886. #ifdef NT
  1887. NTSTATUS
  1888. SetThresholdEvent(
  1889. IN PUCHAR pInputBuffer,
  1890. IN ULONG ulInputBufferLength,
  1891. IN PUCHAR pOutputBuffer,
  1892. IN ULONG ulOutputBufferLength,
  1893. OUT PULONG pulBytesWritten
  1894. )
  1895. /*++
  1896. Routine Name:
  1897. SetThresholdEvent
  1898. Routine Description:
  1899. This function queues up an asyncevent for bandwidth on demand
  1900. events.
  1901. Arguments:
  1902. pInputBuffer - Pointer to the input structure that should be WAN_ASYNC_EVENT
  1903. ulInputBufferLength - Length of input buffer should be sizeof(WAN_ASYNC_EVENT)
  1904. pOutputBuffer - Pointer to the output structure that should be WAN_ASYNC_EVENT
  1905. ulOutputBufferLength - Length of output buffer should be sizeof(WAN_ASYNC_EVENT)
  1906. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  1907. Return Values:
  1908. --*/
  1909. {
  1910. ULONG SizeNeeded = sizeof(NDISWAN_SET_THRESHOLD_EVENT);
  1911. PIRP pIrp = (PIRP)pInputBuffer;
  1912. KIRQL Irql;
  1913. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetThresholdEvent:"));
  1914. *pulBytesWritten = 0;
  1915. if (ulOutputBufferLength < SizeNeeded) {
  1916. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetThresholdEvent: Buffer to small: Size: %d, SizeNeeded %d",
  1917. ulInputBufferLength, SizeNeeded));
  1918. *pulBytesWritten = SizeNeeded;
  1919. return(STATUS_INFO_LENGTH_MISMATCH);
  1920. }
  1921. //
  1922. // The IRP was pended so setup a cancel routine and let the
  1923. // i/o subsystem know about the pend.
  1924. //
  1925. IoMarkIrpPending(pIrp);
  1926. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  1927. //
  1928. // Setup the structure
  1929. //
  1930. InsertTailList(&ThresholdEventQueue.List, &(pIrp->Tail.Overlay.ListEntry));
  1931. ThresholdEventQueue.ulCount++;
  1932. if (ThresholdEventQueue.ulCount > ThresholdEventQueue.ulMaxCount) {
  1933. ThresholdEventQueue.ulMaxCount = ThresholdEventQueue.ulCount;
  1934. }
  1935. IoSetCancelRoutine(pIrp, NdisWanCancelRoutine);
  1936. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  1937. return (STATUS_PENDING);
  1938. }
  1939. #endif
  1940. NTSTATUS
  1941. FlushThresholdEvents(
  1942. IN PUCHAR pInputBuffer,
  1943. IN ULONG ulInputBufferLength,
  1944. IN PUCHAR pOutputBuffer,
  1945. IN ULONG ulOutputBufferLength,
  1946. OUT PULONG pulBytesWritten
  1947. )
  1948. /*++
  1949. Routine Name:
  1950. Routine Description:
  1951. Arguments:
  1952. Return Values:
  1953. --*/
  1954. {
  1955. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("FlushThresholdEvents:"));
  1956. *pulBytesWritten = 0;
  1957. CancelThresholdEvents();
  1958. return (STATUS_SUCCESS);
  1959. }
  1960. NTSTATUS
  1961. IoSendPacket(
  1962. IN PUCHAR pInputBuffer,
  1963. IN ULONG ulInputBufferLength,
  1964. IN PUCHAR pOutputBuffer,
  1965. IN ULONG ulOutputBufferLength,
  1966. OUT PULONG pulBytesWritten
  1967. )
  1968. /*++
  1969. Routine Name:
  1970. Routine Description:
  1971. Arguments:
  1972. Return Values:
  1973. --*/
  1974. {
  1975. NTSTATUS Status = STATUS_SUCCESS;
  1976. ULONG SizeNeeded = sizeof(NDISWAN_IO_PACKET);
  1977. PNDISWAN_IO_PACKET In = (PNDISWAN_IO_PACKET)pInputBuffer;
  1978. PLINKCB LinkCB = NULL;
  1979. PBUNDLECB BundleCB = NULL;
  1980. NdisWanDbgOut(DBG_TRACE, DBG_SEND, ("IoSendPacket:"));
  1981. *pulBytesWritten = 0;
  1982. do {
  1983. if (ulInputBufferLength < SizeNeeded) {
  1984. NdisWanDbgOut(DBG_FAILURE, DBG_SEND, ("IoSendPacket: Buffer to small: Size: %d, SizeNeeded %d",
  1985. ulInputBufferLength, SizeNeeded));
  1986. *pulBytesWritten = SizeNeeded;
  1987. Status = STATUS_INFO_LENGTH_MISMATCH;
  1988. break;
  1989. }
  1990. if (ulInputBufferLength - SizeNeeded > glLargeDataBufferSize) {
  1991. Status = STATUS_INFO_LENGTH_MISMATCH;
  1992. break;
  1993. }
  1994. if ((LONG)ulInputBufferLength - FIELD_OFFSET(NDISWAN_IO_PACKET, PacketData) <
  1995. (LONG)(In->usHeaderSize + In->usPacketSize)) {
  1996. Status = STATUS_INFO_LENGTH_MISMATCH;
  1997. break;
  1998. }
  1999. if (In->usHandleType == LINKHANDLE) {
  2000. if (!AreLinkAndBundleValid(In->hHandle,
  2001. TRUE,
  2002. &LinkCB,
  2003. &BundleCB)) {
  2004. NdisWanDbgOut(DBG_FAILURE, DBG_SEND, ("IoSendPacket: Invalid Handle: 0x%x, HandleType: 0x%x",
  2005. In->hHandle, In->usHandleType));
  2006. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2007. break;
  2008. }
  2009. AcquireBundleLock(BundleCB);
  2010. } else {
  2011. if (!IsBundleValid(In->hHandle,
  2012. TRUE,
  2013. &BundleCB)) {
  2014. NdisWanDbgOut(DBG_FAILURE, DBG_SEND, ("IoSendPacket: Invalid Handle: 0x%x, HandleType: 0x%x",
  2015. In->hHandle, In->usHandleType));
  2016. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2017. break;
  2018. }
  2019. AcquireBundleLock(BundleCB);
  2020. if (BundleCB->ulLinkCBCount == 0) {
  2021. NdisWanDbgOut(DBG_FAILURE, DBG_SEND, ("IoSendPacket: Invalid Handle: 0x%x, HandleType: 0x%x",
  2022. In->hHandle, In->usHandleType));
  2023. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2024. break;
  2025. }
  2026. LinkCB = (PLINKCB)BundleCB->LinkCBList.Flink;
  2027. //
  2028. // LinkCB's lock can be acquired while BundleCB's lock
  2029. // is held
  2030. //
  2031. NdisDprAcquireSpinLock(&LinkCB->Lock);
  2032. if (LinkCB->State != LINK_UP) {
  2033. NdisWanDbgOut(DBG_FAILURE, DBG_SEND, ("IoSendPacket: Invalid Handle: 0x%x, HandleType: 0x%x",
  2034. In->hHandle, In->usHandleType));
  2035. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2036. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2037. LinkCB = NULL;
  2038. break;
  2039. }
  2040. REF_LINKCB(LinkCB);
  2041. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2042. }
  2043. #if 0
  2044. if (LinkCB->Stats.FramesTransmitted == 0) {
  2045. if (In->PacketData[0] != 0xC0 ||
  2046. In->PacketData[1] != 0x21 ||
  2047. In->PacketData[2] != 0x01) {
  2048. DbgPrint("NDISWAN: IOSP-FirstFrame not LCP ConfigReq bcb %p, lcb %p\n",
  2049. BundleCB, LinkCB);
  2050. DbgBreakPoint();
  2051. }
  2052. }
  2053. #endif
  2054. //
  2055. // Queue an Ndis Packet for this send
  2056. //
  2057. Status =
  2058. BuildIoPacket(LinkCB, BundleCB, In, FALSE);
  2059. } while ( 0 );
  2060. //
  2061. // Derefs for the refs applied above
  2062. //
  2063. DEREF_BUNDLECB_LOCKED(BundleCB);
  2064. return (Status);
  2065. }
  2066. #ifdef NT
  2067. NTSTATUS
  2068. IoReceivePacket(
  2069. IN PUCHAR pInputBuffer,
  2070. IN ULONG ulInputBufferLength,
  2071. IN PUCHAR pOutputBuffer,
  2072. IN ULONG ulOutputBufferLength,
  2073. OUT PULONG pulBytesWritten
  2074. )
  2075. /*++
  2076. Routine Name:
  2077. Routine Description:
  2078. Arguments:
  2079. Return Values:
  2080. --*/
  2081. {
  2082. ULONG SizeNeeded = sizeof(NDISWAN_IO_PACKET) + 1500;
  2083. PIRP Irp = (PIRP)pInputBuffer;
  2084. PIO_STACK_LOCATION IrpSp;
  2085. PNDISWAN_IO_PACKET IoPacket;
  2086. PRECV_DESC RecvDesc;
  2087. KIRQL Irql;
  2088. PLINKCB LinkCB;
  2089. NdisWanDbgOut(DBG_TRACE, DBG_RECEIVE, ("IoReceivePacket:"));
  2090. if (SizeNeeded > ulOutputBufferLength) {
  2091. NdisWanDbgOut(DBG_FAILURE, DBG_RECEIVE, ("IoReceivePacket: Buffer to small: Size: %d, SizeNeeded %d",
  2092. ulOutputBufferLength, SizeNeeded));
  2093. *pulBytesWritten = SizeNeeded;
  2094. return(STATUS_INFO_LENGTH_MISMATCH);
  2095. }
  2096. //
  2097. // Do we have any receive's buffered up that
  2098. // can be completed?
  2099. //
  2100. NdisAcquireSpinLock(&IoRecvList.Lock);
  2101. RecvDesc = (PRECV_DESC)IoRecvList.DescList.Flink;
  2102. while ((PVOID)RecvDesc != (PVOID)&IoRecvList.DescList) {
  2103. LinkCB = RecvDesc->LinkCB;
  2104. NdisDprAcquireSpinLock(&LinkCB->Lock);
  2105. if ((LinkCB->hLinkContext != NULL)) {
  2106. break;
  2107. }
  2108. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2109. RecvDesc = (PRECV_DESC)RecvDesc->Linkage.Flink;
  2110. }
  2111. IoMarkIrpPending(Irp);
  2112. if ((PVOID)RecvDesc != (PVOID)&IoRecvList.DescList) {
  2113. LONG BufferLength, DataLength, CopySize;
  2114. RemoveEntryList(&RecvDesc->Linkage);
  2115. IoRecvList.ulDescCount--;
  2116. LinkCB->RecvDescCount--;
  2117. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2118. INSERT_RECV_EVENT('s');
  2119. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  2120. BufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  2121. DataLength = BufferLength - sizeof(NDISWAN_IO_PACKET) + 1;
  2122. CopySize = (RecvDesc->CurrentLength > DataLength) ?
  2123. DataLength : RecvDesc->CurrentLength;
  2124. IoPacket = Irp->AssociatedIrp.SystemBuffer;
  2125. IoPacket->hHandle = LinkCB->hLinkContext;
  2126. IoPacket->usHandleType = LINKHANDLE;
  2127. IoPacket->usHeaderSize = 14;
  2128. IoPacket->usPacketSize = (USHORT)CopySize;
  2129. IoPacket->usPacketFlags = 0;
  2130. NdisMoveMemory(IoPacket->PacketData,
  2131. RecvDesc->CurrentBuffer,
  2132. CopySize);
  2133. #if DBG
  2134. if (gbDumpRecv) {
  2135. INT i;
  2136. for (i = 0; i < RecvDesc->CurrentLength; i++) {
  2137. if (i % 16 == 0) {
  2138. DbgPrint("\n");
  2139. }
  2140. DbgPrint("%x ", RecvDesc->CurrentBuffer[i]);
  2141. }
  2142. DbgPrint("\n");
  2143. }
  2144. #endif
  2145. Irp->IoStatus.Status = STATUS_SUCCESS;
  2146. Irp->IoStatus.Information = sizeof(NDISWAN_IO_PACKET) - 1 + CopySize;
  2147. IoRecvList.LastPacketNumber = IoPacket->PacketNumber;
  2148. IoRecvList.LastIrp = Irp;
  2149. IoRecvList.LastIrpStatus = STATUS_SUCCESS;
  2150. IoRecvList.LastCopySize = (ULONG)Irp->IoStatus.Information;
  2151. ASSERT((LONG_PTR)Irp->IoStatus.Information > 0);
  2152. NdisReleaseSpinLock(&IoRecvList.Lock);
  2153. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  2154. NdisWanFreeRecvDesc(RecvDesc);
  2155. } else {
  2156. //
  2157. // We did not have anything buffered so lets queue
  2158. //
  2159. //
  2160. // The IRP was pended so setup a cancel routine and let the
  2161. // i/o subsystem know about the pend.
  2162. //
  2163. //
  2164. // Setup the structure
  2165. //
  2166. InsertTailList(&IoRecvList.IrpList, &(Irp->Tail.Overlay.ListEntry));
  2167. IoRecvList.ulIrpCount++;
  2168. IoSetCancelRoutine(Irp, NdisWanCancelRoutine);
  2169. INSERT_RECV_EVENT('i');
  2170. NdisReleaseSpinLock(&IoRecvList.Lock);
  2171. }
  2172. return (NDIS_STATUS_PENDING);
  2173. }
  2174. VOID
  2175. IoRecvIrpWorker(
  2176. PKDPC Dpc,
  2177. PVOID Context,
  2178. PVOID Arg1,
  2179. PVOID Arg2
  2180. )
  2181. {
  2182. PLIST_ENTRY Entry;
  2183. PNDISWAN_IO_PACKET IoPacket;
  2184. PIO_STACK_LOCATION IrpSp;
  2185. PIRP Irp;
  2186. PRECV_DESC RecvDesc;
  2187. KIRQL Irql;
  2188. LONG BufferLength, DataLength, CopySize;
  2189. PLINKCB LinkCB;
  2190. PBUNDLECB BundleCB;
  2191. NdisAcquireSpinLock(&IoRecvList.Lock);
  2192. do {
  2193. IoRecvList.TimerScheduled = FALSE;
  2194. //
  2195. // Do we have any irps that we can complete?
  2196. //
  2197. if (IoRecvList.ulIrpCount == 0) {
  2198. break;
  2199. }
  2200. //
  2201. // Do we have any receive's buffered up?
  2202. //
  2203. RecvDesc = (PRECV_DESC)IoRecvList.DescList.Flink;
  2204. while ((PVOID)RecvDesc != (PVOID)&IoRecvList.DescList) {
  2205. LinkCB = RecvDesc->LinkCB;
  2206. NdisDprAcquireSpinLock(&LinkCB->Lock);
  2207. if (LinkCB->hLinkContext != NULL) {
  2208. break;
  2209. }
  2210. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2211. RecvDesc = (PRECV_DESC)RecvDesc->Linkage.Flink;
  2212. }
  2213. if ((PVOID)RecvDesc == (PVOID)&IoRecvList.DescList) {
  2214. if (!IoRecvList.TimerScheduled) {
  2215. WAN_TIME TimeOut;
  2216. IoRecvList.TimerScheduled = TRUE;
  2217. NdisWanInitWanTime(&TimeOut, 15);
  2218. KeSetTimer(&IoRecvList.Timer,
  2219. TimeOut,
  2220. &IoRecvList.Dpc);
  2221. }
  2222. break;
  2223. }
  2224. Entry = IoRecvList.IrpList.Flink;
  2225. Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  2226. if (!IoSetCancelRoutine(Irp, NULL)) {
  2227. break;
  2228. }
  2229. //
  2230. // Get the recvdesc
  2231. //
  2232. RemoveEntryList(&RecvDesc->Linkage);
  2233. IoRecvList.ulDescCount--;
  2234. LinkCB->RecvDescCount--;
  2235. RemoveHeadList(&IoRecvList.IrpList);
  2236. IoRecvList.ulIrpCount--;
  2237. INSERT_RECV_EVENT('w');
  2238. IrpSp = IoGetCurrentIrpStackLocation(Irp);
  2239. BufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
  2240. DataLength = BufferLength - sizeof(NDISWAN_IO_PACKET);
  2241. CopySize = (RecvDesc->CurrentLength > DataLength) ?
  2242. DataLength : RecvDesc->CurrentLength;
  2243. IoPacket = Irp->AssociatedIrp.SystemBuffer;
  2244. IoPacket->hHandle = LinkCB->hLinkContext;
  2245. IoPacket->usHandleType = LINKHANDLE;
  2246. IoPacket->usHeaderSize = 14;
  2247. IoPacket->usPacketSize = (USHORT)CopySize;
  2248. IoPacket->usPacketFlags = 0;
  2249. NdisDprReleaseSpinLock(&LinkCB->Lock);
  2250. NdisReleaseSpinLock(&IoRecvList.Lock);
  2251. #if DBG
  2252. if (gbDumpRecv) {
  2253. INT i;
  2254. for (i = 0; i < RecvDesc->CurrentLength; i++) {
  2255. if (i % 16 == 0) {
  2256. DbgPrint("\n");
  2257. }
  2258. DbgPrint("%x ", RecvDesc->CurrentBuffer[i]);
  2259. }
  2260. DbgPrint("\n");
  2261. }
  2262. #endif
  2263. NdisMoveMemory(IoPacket->PacketData,
  2264. RecvDesc->CurrentBuffer,
  2265. CopySize);
  2266. Irp->IoStatus.Status = STATUS_SUCCESS;
  2267. Irp->IoStatus.Information = sizeof(NDISWAN_IO_PACKET) - 1 + CopySize;
  2268. IoRecvList.LastPacketNumber = IoPacket->PacketNumber;
  2269. IoRecvList.LastIrp = Irp;
  2270. IoRecvList.LastIrpStatus = STATUS_SUCCESS;
  2271. IoRecvList.LastCopySize = (ULONG)Irp->IoStatus.Information;
  2272. ASSERT((LONG_PTR)Irp->IoStatus.Information > 0);
  2273. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  2274. NdisWanFreeRecvDesc(RecvDesc);
  2275. NdisAcquireSpinLock(&IoRecvList.Lock);
  2276. } while (FALSE);
  2277. NdisReleaseSpinLock(&IoRecvList.Lock);
  2278. }
  2279. #endif
  2280. NTSTATUS
  2281. FlushReceivePacket(
  2282. IN PUCHAR pInputBuffer,
  2283. IN ULONG ulInputBufferLength,
  2284. IN PUCHAR pOutputBuffer,
  2285. IN ULONG ulOutputBufferLength,
  2286. OUT PULONG pulBytesWritten
  2287. )
  2288. /*++
  2289. Routine Name:
  2290. Routine Description:
  2291. Arguments:
  2292. Return Values:
  2293. --*/
  2294. {
  2295. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("FlushReceivePacket:"));
  2296. *pulBytesWritten = 0;
  2297. CancelIoReceivePackets();
  2298. return (STATUS_SUCCESS);
  2299. }
  2300. NTSTATUS
  2301. GetStatistics(
  2302. IN PUCHAR pInputBuffer,
  2303. IN ULONG ulInputBufferLength,
  2304. IN PUCHAR pOutputBuffer,
  2305. IN ULONG ulOutputBufferLength,
  2306. OUT PULONG pulBytesWritten
  2307. )
  2308. /*++
  2309. Routine Name:
  2310. Routine Description:
  2311. Arguments:
  2312. Return Values:
  2313. --*/
  2314. {
  2315. NTSTATUS Status = STATUS_SUCCESS;
  2316. ULONG SizeNeeded = sizeof(NDISWAN_GET_STATS);
  2317. PNDISWAN_GET_STATS In = (PNDISWAN_GET_STATS)pInputBuffer;
  2318. PNDISWAN_GET_STATS Out = (PNDISWAN_GET_STATS)pOutputBuffer;
  2319. PBUNDLECB BundleCB = NULL;
  2320. PLINKCB LinkCB = NULL;
  2321. NdisWanDbgOut(DBG_VERBOSE, DBG_IO, ("GetStatistics:"));
  2322. *pulBytesWritten = SizeNeeded;
  2323. do {
  2324. if (ulOutputBufferLength < SizeNeeded) {
  2325. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetStatistics: Buffer to small: Size: %d, SizeNeeded %d",
  2326. ulOutputBufferLength, SizeNeeded));
  2327. Status = STATUS_INFO_LENGTH_MISMATCH;
  2328. break;
  2329. }
  2330. NdisZeroMemory(&Out->Stats, sizeof(Out->Stats));
  2331. if (In->usHandleType == LINKHANDLE) {
  2332. //
  2333. // Looking for link stats
  2334. //
  2335. if (!AreLinkAndBundleValid(In->hHandle,
  2336. FALSE,
  2337. &LinkCB,
  2338. &BundleCB)) {
  2339. NdisWanDbgOut(DBG_INFO, DBG_IO, ("GetStatistics: Invalid LinkHandle: 0x%x",
  2340. In->hHandle));
  2341. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2342. break;
  2343. }
  2344. AcquireBundleLock(BundleCB);
  2345. //
  2346. // At this point we have a valid bundlecb and linkcb
  2347. //
  2348. //
  2349. // Copy the stats over
  2350. //
  2351. NdisMoveMemory((PUCHAR)&Out->Stats.LinkStats,
  2352. (PUCHAR)&LinkCB->Stats,
  2353. sizeof(WAN_STATS));
  2354. //
  2355. // Copy the stats over
  2356. //
  2357. NdisMoveMemory((PUCHAR)&Out->Stats.BundleStats,
  2358. (PUCHAR)&BundleCB->Stats,
  2359. sizeof(WAN_STATS));
  2360. } else if (In->usHandleType == BUNDLEHANDLE) {
  2361. //
  2362. // Looking for bundle stats
  2363. //
  2364. if (!IsBundleValid(In->hHandle,
  2365. FALSE,
  2366. &BundleCB)) {
  2367. NdisWanDbgOut(DBG_INFO, DBG_IO, ("GetStatistics: Invalid BundleHandle: 0x%x",
  2368. In->hHandle));
  2369. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2370. break;
  2371. }
  2372. AcquireBundleLock(BundleCB);
  2373. //
  2374. // At this point we have a valid bundlecb
  2375. //
  2376. //
  2377. // Copy the stats over
  2378. //
  2379. NdisMoveMemory((PUCHAR)&Out->Stats.BundleStats,
  2380. (PUCHAR)&BundleCB->Stats,
  2381. sizeof(WAN_STATS));
  2382. } else {
  2383. Status = NDISWAN_ERROR_INVALID_HANDLE_TYPE;
  2384. break;
  2385. }
  2386. //
  2387. // If we only have one protocol bound see if
  2388. // it is keeping stats
  2389. //
  2390. if (BundleCB->ulNumberOfRoutes == 1) {
  2391. PPROTOCOLCB ProtocolCB;
  2392. PMINIPORTCB MiniportCB;
  2393. ProtocolCB =
  2394. (PPROTOCOLCB)BundleCB->ProtocolCBList.Flink;
  2395. MiniportCB = ProtocolCB->MiniportCB;
  2396. if (MiniportCB->Flags & PROTOCOL_KEEPS_STATS) {
  2397. NDIS_WAN_GET_STATS WanStats;
  2398. ReleaseBundleLock(BundleCB);
  2399. NdisZeroMemory(&WanStats, sizeof(NDIS_WAN_GET_STATS));
  2400. ETH_COPY_NETWORK_ADDRESS(WanStats.LocalAddress, ProtocolCB->TransportAddress);
  2401. NdisMoveMemory((PUCHAR)&WanStats.BytesSent,
  2402. (PUCHAR)&Out->Stats.BundleStats,
  2403. sizeof(WAN_STATS));
  2404. NdisMIndicateStatus(MiniportCB->MiniportHandle,
  2405. NDIS_STATUS_WAN_GET_STATS,
  2406. &WanStats,
  2407. sizeof(NDIS_WAN_GET_STATS));
  2408. NdisMoveMemory((PUCHAR)&Out->Stats.LinkStats,
  2409. (PUCHAR)&WanStats.BytesSent,
  2410. sizeof(WAN_STATS));
  2411. NdisMoveMemory((PUCHAR)&Out->Stats.BundleStats,
  2412. (PUCHAR)&WanStats.BytesSent,
  2413. sizeof(WAN_STATS));
  2414. AcquireBundleLock(BundleCB);
  2415. }
  2416. }
  2417. } while ( 0 );
  2418. //
  2419. // Derefs for the refs applied above
  2420. //
  2421. DEREF_BUNDLECB_LOCKED(BundleCB);
  2422. DEREF_LINKCB(LinkCB);
  2423. return (Status);
  2424. }
  2425. NTSTATUS
  2426. SetLinkInfo(
  2427. IN PUCHAR pInputBuffer,
  2428. IN ULONG ulInputBufferLength,
  2429. IN PUCHAR pOutputBuffer,
  2430. IN ULONG ulOutputBufferLength,
  2431. OUT PULONG pulBytesWritten
  2432. )
  2433. /*++
  2434. Routine Name:
  2435. Routine Description:
  2436. Arguments:
  2437. Return Values:
  2438. --*/
  2439. {
  2440. NTSTATUS Status = STATUS_SUCCESS;
  2441. ULONG SizeNeeded = sizeof(NDISWAN_SET_LINK_INFO);
  2442. WAN_REQUEST WanRequest;
  2443. PNDISWAN_SET_LINK_INFO In = (PNDISWAN_SET_LINK_INFO)pInputBuffer;
  2444. PWAN_LINK_INFO LinkInfo;
  2445. POPENCB OpenCB;
  2446. PLINKCB TempLinkCB,LinkCB = NULL;
  2447. PBUNDLECB BundleCB = NULL;
  2448. BOOLEAN MediaBroadband = FALSE;
  2449. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetLinkInfo:"));
  2450. *pulBytesWritten = 0;
  2451. do {
  2452. if (ulInputBufferLength < SizeNeeded) {
  2453. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetLinkInfo: Buffer to small: Size: %d, SizeNeeded %d",
  2454. ulInputBufferLength, SizeNeeded));
  2455. *pulBytesWritten = SizeNeeded;
  2456. Status = STATUS_INFO_LENGTH_MISMATCH;
  2457. break;
  2458. }
  2459. if (!AreLinkAndBundleValid(In->hLinkHandle,
  2460. TRUE,
  2461. &LinkCB,
  2462. &BundleCB)) {
  2463. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2464. break;
  2465. }
  2466. LinkInfo = &LinkCB->LinkInfo;
  2467. OpenCB = LinkCB->OpenCB;
  2468. if (OpenCB->MediumType == NdisMediumAtm ||
  2469. (OpenCB->MediumType == NdisMediumWan &&
  2470. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  2471. OpenCB->MediumSubType == NdisWanMediumPppoe)) ||
  2472. (OpenCB->MediumType == NdisMediumCoWan &&
  2473. (OpenCB->MediumSubType == NdisWanMediumAtm ||
  2474. OpenCB->MediumSubType == NdisWanMediumPppoe))) {
  2475. MediaBroadband = TRUE;
  2476. }
  2477. //
  2478. // Wait for initialization to complete
  2479. //
  2480. NdisWanWaitForNotificationEvent(&OpenCB->InitEvent);
  2481. WanRequest.Type = SYNC;
  2482. WanRequest.Origin = NDISWAN;
  2483. NdisWanInitializeNotificationEvent(&WanRequest.NotificationEvent);
  2484. WanRequest.OpenCB = OpenCB;
  2485. if (OpenCB->Flags & OPEN_LEGACY) {
  2486. NDIS_WAN_SET_LINK_INFO WanMiniportLinkInfo;
  2487. NdisZeroMemory(&WanMiniportLinkInfo, sizeof (NDIS_WAN_SET_LINK_INFO));
  2488. //
  2489. // Copy into buffer to be sent to WAN Miniport this
  2490. // skips over the LinkHandle in the NDIS_WAN_SET_LINK_INFO
  2491. // structure.
  2492. //
  2493. WanMiniportLinkInfo.NdisLinkHandle = LinkCB->NdisLinkHandle;
  2494. WanMiniportLinkInfo.MaxSendFrameSize = In->LinkInfo.MaxSendFrameSize;
  2495. WanMiniportLinkInfo.MaxRecvFrameSize = In->LinkInfo.MaxRecvFrameSize;
  2496. WanMiniportLinkInfo.SendFramingBits = In->LinkInfo.SendFramingBits;
  2497. WanMiniportLinkInfo.RecvFramingBits = In->LinkInfo.RecvFramingBits;
  2498. WanMiniportLinkInfo.SendCompressionBits = In->LinkInfo.SendCompressionBits;
  2499. WanMiniportLinkInfo.RecvCompressionBits = In->LinkInfo.RecvCompressionBits;
  2500. WanMiniportLinkInfo.SendACCM = In->LinkInfo.SendACCM;
  2501. WanMiniportLinkInfo.RecvACCM = In->LinkInfo.RecvACCM;
  2502. //
  2503. // Submit this to the WAN Miniport
  2504. //
  2505. WanRequest.NdisRequest.RequestType =
  2506. NdisRequestSetInformation;
  2507. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.Oid =
  2508. OID_WAN_SET_LINK_INFO;
  2509. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer =
  2510. &WanMiniportLinkInfo;
  2511. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
  2512. sizeof(NDIS_WAN_SET_LINK_INFO);
  2513. NdisWanSubmitNdisRequest(OpenCB, &WanRequest);
  2514. } else {
  2515. NDIS_WAN_CO_SET_LINK_INFO WanMiniportLinkInfo;
  2516. NdisAcquireSpinLock(&LinkCB->Lock);
  2517. if (LinkCB->ClCallState == CL_CALL_CONNECTED) {
  2518. //
  2519. // Ref so that we don't allow the
  2520. // vc to go away.
  2521. //
  2522. LinkCB->VcRefCount++;
  2523. NdisReleaseSpinLock(&LinkCB->Lock);
  2524. NdisZeroMemory(&WanMiniportLinkInfo, sizeof (NDIS_WAN_CO_SET_LINK_INFO));
  2525. //
  2526. // Copy into buffer to be sent to WAN Miniport this
  2527. // skips over the LinkHandle in the NDIS_WAN_SET_LINK_INFO
  2528. // structure.
  2529. //
  2530. WanMiniportLinkInfo.MaxSendFrameSize = In->LinkInfo.MaxSendFrameSize;
  2531. WanMiniportLinkInfo.MaxRecvFrameSize = In->LinkInfo.MaxRecvFrameSize;
  2532. WanMiniportLinkInfo.SendFramingBits = In->LinkInfo.SendFramingBits;
  2533. WanMiniportLinkInfo.RecvFramingBits = In->LinkInfo.RecvFramingBits;
  2534. WanMiniportLinkInfo.SendCompressionBits = In->LinkInfo.SendCompressionBits;
  2535. WanMiniportLinkInfo.RecvCompressionBits = In->LinkInfo.RecvCompressionBits;
  2536. WanMiniportLinkInfo.SendACCM = In->LinkInfo.SendACCM;
  2537. WanMiniportLinkInfo.RecvACCM = In->LinkInfo.RecvACCM;
  2538. //
  2539. // Submit this to the WAN Miniport
  2540. //
  2541. WanRequest.NdisRequest.RequestType =
  2542. NdisRequestSetInformation;
  2543. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.Oid =
  2544. OID_WAN_CO_SET_LINK_INFO;
  2545. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer =
  2546. &WanMiniportLinkInfo;
  2547. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
  2548. sizeof(NDIS_WAN_CO_SET_LINK_INFO);
  2549. WanRequest.AfHandle = NULL;
  2550. WanRequest.VcHandle = LinkCB->NdisLinkHandle;
  2551. NdisWanSubmitNdisRequest(OpenCB, &WanRequest);
  2552. NdisAcquireSpinLock(&LinkCB->Lock);
  2553. DerefVc(LinkCB);
  2554. NdisReleaseSpinLock(&LinkCB->Lock);
  2555. } else {
  2556. NdisReleaseSpinLock(&LinkCB->Lock);
  2557. }
  2558. }
  2559. //
  2560. // Copy info into our linkcb
  2561. //
  2562. AcquireBundleLock(BundleCB);
  2563. ASSERT(In->LinkInfo.SendFramingBits != 0);
  2564. ASSERT(In->LinkInfo.RecvFramingBits != 0);
  2565. //
  2566. // If we are using broadband the we must preserve the LLC and
  2567. // ADDRESS_CONTROL framing bits.
  2568. //
  2569. if (MediaBroadband) {
  2570. LinkInfo->SendFramingBits |= In->LinkInfo.SendFramingBits;
  2571. LinkInfo->RecvFramingBits |= In->LinkInfo.RecvFramingBits;
  2572. } else {
  2573. LinkInfo->SendFramingBits = In->LinkInfo.SendFramingBits;
  2574. LinkInfo->RecvFramingBits = In->LinkInfo.RecvFramingBits;
  2575. }
  2576. LinkCB->SFlowSpec.MaxSduSize =
  2577. LinkInfo->MaxSendFrameSize = In->LinkInfo.MaxSendFrameSize;
  2578. if (OpenCB->WanInfo.MaxFrameSize < LinkCB->SFlowSpec.MaxSduSize) {
  2579. LinkCB->SFlowSpec.MaxSduSize = OpenCB->WanInfo.MaxFrameSize;
  2580. }
  2581. LinkCB->RFlowSpec.MaxSduSize =
  2582. LinkInfo->MaxRecvFrameSize = In->LinkInfo.MaxRecvFrameSize;
  2583. LinkInfo->SendCompressionBits = In->LinkInfo.SendCompressionBits;
  2584. LinkInfo->RecvCompressionBits = In->LinkInfo.RecvCompressionBits;
  2585. LinkInfo->SendACCM = In->LinkInfo.SendACCM;
  2586. LinkInfo->RecvACCM = In->LinkInfo.RecvACCM;
  2587. LinkInfo->MaxRRecvFrameSize = In->LinkInfo.MaxRRecvFrameSize;
  2588. LinkInfo->MaxRSendFrameSize = In->LinkInfo.MaxRSendFrameSize;
  2589. if (LinkInfo->RecvFramingBits & LLC_ENCAPSULATION) {
  2590. LinkCB->RecvHandler = ReceiveLLC;
  2591. } else if (LinkInfo->RecvFramingBits & PPP_FRAMING) {
  2592. LinkCB->RecvHandler = ReceivePPP;
  2593. } else if (LinkInfo->RecvFramingBits & RAS_FRAMING) {
  2594. LinkCB->RecvHandler = ReceiveRAS;
  2595. } else if (LinkInfo->RecvFramingBits & SLIP_FRAMING) {
  2596. LinkCB->RecvHandler = ReceiveSLIP;
  2597. } else if (LinkInfo->RecvFramingBits & (ARAP_V1_FRAMING | ARAP_V2_FRAMING)) {
  2598. LinkCB->RecvHandler = ReceiveARAP;
  2599. } else {
  2600. if (MediaBroadband) {
  2601. LinkCB->RecvHandler = DetectBroadbandFraming;
  2602. } else {
  2603. LinkCB->RecvHandler = DetectFraming;
  2604. }
  2605. }
  2606. //
  2607. // We need to set our bundle framing based on the framing for
  2608. // each link in the bundle so we will walk the linkcb list
  2609. // and | in each link's framing bits into the bundle.
  2610. //
  2611. //
  2612. BundleCB->FramingInfo.SendFramingBits = 0;
  2613. BundleCB->FramingInfo.RecvFramingBits = 0;
  2614. for (TempLinkCB = (PLINKCB)BundleCB->LinkCBList.Flink;
  2615. (PVOID)TempLinkCB != (PVOID)&BundleCB->LinkCBList;
  2616. TempLinkCB = (PLINKCB)TempLinkCB->Linkage.Flink) {
  2617. BundleCB->FramingInfo.SendFramingBits |= TempLinkCB->LinkInfo.SendFramingBits;
  2618. BundleCB->FramingInfo.RecvFramingBits |= TempLinkCB->LinkInfo.RecvFramingBits;
  2619. }
  2620. BundleCB->FramingInfo.MaxRSendFrameSize = LinkInfo->MaxRSendFrameSize;
  2621. //
  2622. // Since I use the receive frame size for memory allocation.
  2623. //
  2624. BundleCB->FramingInfo.MaxRRecvFrameSize = (LinkInfo->MaxRRecvFrameSize) ?
  2625. LinkInfo->MaxRRecvFrameSize : glMRRU;
  2626. //
  2627. // If VJ header compression has been negotiated allocate
  2628. // and initialize resources.
  2629. //
  2630. if (BundleCB->FramingInfo.SendFramingBits & SLIP_VJ_COMPRESSION ||
  2631. BundleCB->FramingInfo.SendFramingBits & SLIP_VJ_AUTODETECT ||
  2632. BundleCB->FramingInfo.RecvFramingBits & SLIP_VJ_COMPRESSION ||
  2633. BundleCB->FramingInfo.RecvFramingBits & SLIP_VJ_AUTODETECT) {
  2634. Status = sl_compress_init(&BundleCB->VJCompress, MAX_VJ_STATES);
  2635. if (Status != NDIS_STATUS_SUCCESS) {
  2636. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("Error allocating VJ Info!"));
  2637. }
  2638. }
  2639. //
  2640. // Configure multilink variables if needed
  2641. //
  2642. if (BundleCB->FramingInfo.SendFramingBits & PPP_MULTILINK_FRAMING) {
  2643. if (BundleCB->FramingInfo.SendFramingBits & PPP_SHORT_SEQUENCE_HDR_FORMAT) {
  2644. BundleCB->SendSeqMask = SHORT_SEQ_MASK;
  2645. BundleCB->SendSeqTest = TEST_SHORT_SEQ;
  2646. } else {
  2647. BundleCB->SendSeqMask = LONG_SEQ_MASK;
  2648. BundleCB->SendSeqTest = TEST_LONG_SEQ;
  2649. }
  2650. }
  2651. if (BundleCB->FramingInfo.RecvFramingBits & PPP_MULTILINK_FRAMING) {
  2652. if (BundleCB->FramingInfo.RecvFramingBits & PPP_SHORT_SEQUENCE_HDR_FORMAT) {
  2653. BundleCB->RecvSeqMask = SHORT_SEQ_MASK;
  2654. BundleCB->RecvSeqTest = TEST_SHORT_SEQ;
  2655. } else {
  2656. BundleCB->RecvSeqMask = LONG_SEQ_MASK;
  2657. BundleCB->RecvSeqTest = TEST_LONG_SEQ;
  2658. }
  2659. }
  2660. SetBundleFlags(BundleCB);
  2661. UpdateBundleInfo(BundleCB);
  2662. } while ( 0 );
  2663. //
  2664. // Derefs for the refs applied by AreLinkAndBundleValid
  2665. //
  2666. DEREF_BUNDLECB_LOCKED(BundleCB);
  2667. DEREF_LINKCB(LinkCB);
  2668. return (Status);
  2669. }
  2670. NTSTATUS
  2671. GetLinkInfo(
  2672. IN PUCHAR pInputBuffer,
  2673. IN ULONG ulInputBufferLength,
  2674. IN PUCHAR pOutputBuffer,
  2675. IN ULONG ulOutputBufferLength,
  2676. OUT PULONG pulBytesWritten
  2677. )
  2678. /*++
  2679. Routine Name:
  2680. Routine Description:
  2681. Arguments:
  2682. Return Values:
  2683. --*/
  2684. {
  2685. NTSTATUS Status = STATUS_SUCCESS;
  2686. ULONG SizeNeeded = sizeof(NDISWAN_GET_LINK_INFO);
  2687. PNDISWAN_GET_LINK_INFO In = (PNDISWAN_GET_LINK_INFO)pInputBuffer;
  2688. PNDISWAN_GET_LINK_INFO Out = (PNDISWAN_GET_LINK_INFO)pOutputBuffer;
  2689. PLINKCB LinkCB = NULL;
  2690. PWAN_LINK_INFO LinkInfo;
  2691. POPENCB OpenCB;
  2692. WAN_REQUEST WanRequest;
  2693. union {
  2694. NDIS_WAN_GET_LINK_INFO Mp;
  2695. NDIS_WAN_CO_GET_LINK_INFO Co;
  2696. } WanMiniportLinkInfo;
  2697. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetLinkInfo:"));
  2698. *pulBytesWritten = SizeNeeded;
  2699. do {
  2700. if (ulOutputBufferLength < SizeNeeded) {
  2701. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetLinkInfo: Buffer to small: Size: %d, SizeNeeded %d",
  2702. ulOutputBufferLength, SizeNeeded));
  2703. Status = STATUS_INFO_LENGTH_MISMATCH;
  2704. break;
  2705. }
  2706. if (!IsLinkValid(In->hLinkHandle,
  2707. TRUE,
  2708. &LinkCB)) {
  2709. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetLinkInfo: Invalid LinkHandle: 0x%x",
  2710. In->hLinkHandle));
  2711. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2712. break;
  2713. }
  2714. LinkInfo = &LinkCB->LinkInfo;
  2715. OpenCB = LinkCB->OpenCB;
  2716. WanRequest.Type = SYNC;
  2717. WanRequest.Origin = NDISWAN;
  2718. NdisWanInitializeNotificationEvent(&WanRequest.NotificationEvent);
  2719. WanRequest.OpenCB = OpenCB;
  2720. NdisZeroMemory(&WanMiniportLinkInfo,
  2721. sizeof (WanMiniportLinkInfo));
  2722. if (OpenCB->Flags & OPEN_LEGACY) {
  2723. //
  2724. // Setup the link context for this request
  2725. //
  2726. WanMiniportLinkInfo.Mp.NdisLinkHandle =
  2727. LinkCB->NdisLinkHandle;
  2728. //
  2729. // Submit this to the WAN Miniport
  2730. //
  2731. WanRequest.NdisRequest.RequestType =
  2732. NdisRequestQueryInformation;
  2733. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.Oid =
  2734. OID_WAN_GET_LINK_INFO;
  2735. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer =
  2736. &WanMiniportLinkInfo.Mp;
  2737. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
  2738. sizeof(NDIS_WAN_GET_LINK_INFO);
  2739. Status = NdisWanSubmitNdisRequest(OpenCB, &WanRequest);
  2740. if (Status == NDIS_STATUS_SUCCESS) {
  2741. LinkInfo->MaxSendFrameSize =
  2742. WanMiniportLinkInfo.Mp.MaxSendFrameSize;
  2743. LinkInfo->MaxRecvFrameSize =
  2744. WanMiniportLinkInfo.Mp.MaxRecvFrameSize;
  2745. LinkInfo->SendFramingBits =
  2746. WanMiniportLinkInfo.Mp.SendFramingBits;
  2747. LinkInfo->RecvFramingBits =
  2748. WanMiniportLinkInfo.Mp.RecvFramingBits;
  2749. LinkInfo->SendCompressionBits =
  2750. WanMiniportLinkInfo.Mp.SendCompressionBits;
  2751. LinkInfo->RecvCompressionBits =
  2752. WanMiniportLinkInfo.Mp.RecvCompressionBits;
  2753. LinkInfo->SendACCM =
  2754. WanMiniportLinkInfo.Mp.SendACCM;
  2755. LinkInfo->RecvACCM =
  2756. WanMiniportLinkInfo.Mp.RecvACCM;
  2757. }
  2758. } else {
  2759. NdisAcquireSpinLock(&LinkCB->Lock);
  2760. if (LinkCB->ClCallState == CL_CALL_CONNECTED) {
  2761. //
  2762. // Ref so that we don't allow the
  2763. // vc to go away.
  2764. //
  2765. LinkCB->VcRefCount++;
  2766. NdisReleaseSpinLock(&LinkCB->Lock);
  2767. //
  2768. // Submit this to the WAN Miniport
  2769. //
  2770. WanRequest.NdisRequest.RequestType =
  2771. NdisRequestQueryInformation;
  2772. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.Oid =
  2773. OID_WAN_CO_GET_LINK_INFO;
  2774. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer =
  2775. &WanMiniportLinkInfo.Co;
  2776. WanRequest.NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
  2777. sizeof(NDIS_WAN_CO_GET_LINK_INFO);
  2778. WanRequest.AfHandle = NULL;
  2779. WanRequest.VcHandle = LinkCB->NdisLinkHandle;
  2780. Status = NdisWanSubmitNdisRequest(OpenCB, &WanRequest);
  2781. NdisAcquireSpinLock(&LinkCB->Lock);
  2782. DerefVc(LinkCB);
  2783. NdisReleaseSpinLock(&LinkCB->Lock);
  2784. if (Status == NDIS_STATUS_SUCCESS) {
  2785. LinkInfo->MaxSendFrameSize =
  2786. WanMiniportLinkInfo.Co.MaxSendFrameSize;
  2787. LinkInfo->MaxRecvFrameSize =
  2788. WanMiniportLinkInfo.Co.MaxRecvFrameSize;
  2789. LinkInfo->SendFramingBits =
  2790. WanMiniportLinkInfo.Co.SendFramingBits;
  2791. LinkInfo->RecvFramingBits =
  2792. WanMiniportLinkInfo.Co.RecvFramingBits;
  2793. LinkInfo->SendCompressionBits =
  2794. WanMiniportLinkInfo.Co.SendCompressionBits;
  2795. LinkInfo->RecvCompressionBits =
  2796. WanMiniportLinkInfo.Co.RecvCompressionBits;
  2797. LinkInfo->SendACCM =
  2798. WanMiniportLinkInfo.Co.SendACCM;
  2799. LinkInfo->RecvACCM =
  2800. WanMiniportLinkInfo.Co.RecvACCM;
  2801. }
  2802. } else {
  2803. NdisReleaseSpinLock(&LinkCB->Lock);
  2804. }
  2805. }
  2806. Status = NDIS_STATUS_SUCCESS;
  2807. //
  2808. // Fill Recv and Send MRRU
  2809. //
  2810. LinkInfo->MaxRSendFrameSize = glMaxMTU;
  2811. LinkInfo->MaxRRecvFrameSize = glMRRU;
  2812. NdisMoveMemory(&Out->LinkInfo,
  2813. LinkInfo,
  2814. sizeof(WAN_LINK_INFO));
  2815. Out->hLinkHandle = LinkCB->hLinkHandle;
  2816. } while ( 0 );
  2817. //
  2818. // Deref for ref applied by IsLinkValid
  2819. //
  2820. DEREF_LINKCB(LinkCB);
  2821. return (Status);
  2822. }
  2823. NTSTATUS
  2824. SetCompressionInfo(
  2825. IN PUCHAR pInputBuffer,
  2826. IN ULONG ulInputBufferLength,
  2827. IN PUCHAR pOutputBuffer,
  2828. IN ULONG ulOutputBufferLength,
  2829. OUT PULONG pulBytesWritten
  2830. )
  2831. /*++
  2832. Routine Name:
  2833. Routine Description:
  2834. Arguments:
  2835. Return Values:
  2836. --*/
  2837. {
  2838. NTSTATUS Status = STATUS_SUCCESS;
  2839. ULONG SizeNeeded = sizeof(NDISWAN_SET_COMPRESSION_INFO);
  2840. PNDISWAN_SET_COMPRESSION_INFO In = (PNDISWAN_SET_COMPRESSION_INFO)pInputBuffer;
  2841. PLINKCB LinkCB = NULL;
  2842. PBUNDLECB BundleCB = NULL;
  2843. POPENCB OpenCB;
  2844. WAN_REQUEST WanRequest;
  2845. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetCompressionInfo:"));
  2846. *pulBytesWritten = 0;
  2847. do {
  2848. if (ulInputBufferLength < SizeNeeded) {
  2849. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetCompressionInfo: Buffer to small: Size: %d, SizeNeeded %d",
  2850. ulInputBufferLength, SizeNeeded));
  2851. *pulBytesWritten = SizeNeeded;
  2852. Status = STATUS_INFO_LENGTH_MISMATCH;
  2853. break;
  2854. }
  2855. if (!AreLinkAndBundleValid(In->hLinkHandle,
  2856. TRUE,
  2857. &LinkCB,
  2858. &BundleCB)) {
  2859. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetCompressionInfo: Invalid LinkHandle: 0x%x",
  2860. In->hLinkHandle));
  2861. Status = NDISWAN_ERROR_INVALID_HANDLE;
  2862. break;
  2863. }
  2864. OpenCB = LinkCB->OpenCB;
  2865. #ifdef DEBUG_CCP
  2866. {
  2867. PCOMPRESS_INFO CompInfo;
  2868. PUCHAR Key;
  2869. CompInfo = &In->SendCapabilities;
  2870. DbgPrint("==>NdisWan: Set Send CompressInfo\n");
  2871. DbgPrint("MSCompType: %x\n", CompInfo->MSCompType);
  2872. DbgPrint("AuthType: %x\n", CompInfo->AuthType);
  2873. DbgPrint("Flags: %x\n", CompInfo->Flags);
  2874. CompInfo = &In->RecvCapabilities;
  2875. DbgPrint("==>NdisWan: Set Recv CompressInfo\n");
  2876. DbgPrint("MSCompType: %x\n", CompInfo->MSCompType);
  2877. DbgPrint("AuthType: %x\n", CompInfo->AuthType);
  2878. DbgPrint("Flags: %x\n", CompInfo->Flags);
  2879. }
  2880. #endif
  2881. AcquireBundleLock(BundleCB);
  2882. BundleCB->SendCompInfo.Flags =
  2883. In->SendCapabilities.Flags;
  2884. BundleCB->RecvCompInfo.Flags =
  2885. In->RecvCapabilities.Flags;
  2886. if (In->SendCapabilities.Flags & CCP_SET_KEYS) {
  2887. BundleCB->SendCompInfo.AuthType =
  2888. In->SendCapabilities.AuthType;
  2889. NdisMoveMemory(&BundleCB->SendCompInfo.LMSessionKey,
  2890. &In->SendCapabilities.LMSessionKey,
  2891. sizeof(BundleCB->SendCompInfo.LMSessionKey));
  2892. NdisMoveMemory(&BundleCB->SendCompInfo.UserSessionKey,
  2893. &In->SendCapabilities.UserSessionKey,
  2894. sizeof(BundleCB->SendCompInfo.UserSessionKey));
  2895. NdisMoveMemory(&BundleCB->SendCompInfo.Challenge,
  2896. &In->SendCapabilities.Challenge,
  2897. sizeof(BundleCB->SendCompInfo.Challenge));
  2898. NdisMoveMemory(&BundleCB->SendCompInfo.NTResponse,
  2899. &In->SendCapabilities.NTResponse,
  2900. sizeof(BundleCB->SendCompInfo.NTResponse));
  2901. #ifdef EAP_ON
  2902. NdisMoveMemory(&BundleCB->SendCompInfo.EapKey,
  2903. &In->SendCapabilities.EapKey,
  2904. sizeof(BundleCB->SendCompInfo.EapKey));
  2905. #endif
  2906. #ifdef DEBUG_CCP
  2907. {
  2908. PCOMPRESS_INFO CompInfo;
  2909. PUCHAR Key;
  2910. CompInfo = &BundleCB->SendCompInfo;
  2911. Key = CompInfo->LMSessionKey;
  2912. DbgPrint("Send KeyInfo\n");
  2913. DbgPrint("LMSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2914. Key[0],Key[1],Key[2],Key[3],
  2915. Key[4],Key[5],Key[6],Key[7]);
  2916. Key = CompInfo->UserSessionKey;
  2917. DbgPrint("UserSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2918. Key[0],Key[1],Key[2],Key[3],
  2919. Key[4],Key[5],Key[6],Key[7],
  2920. Key[8],Key[9],Key[10],Key[11],
  2921. Key[12],Key[13],Key[14],Key[15]);
  2922. Key = CompInfo->Challenge;
  2923. DbgPrint("Challenge: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2924. Key[0],Key[1],Key[2],Key[3],
  2925. Key[4],Key[5],Key[6],Key[7]);
  2926. Key = CompInfo->NTResponse;
  2927. DbgPrint("NTResponse: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2928. Key[0],Key[1],Key[2],Key[3],
  2929. Key[4],Key[5],Key[6],Key[7],
  2930. Key[8],Key[9],Key[10],Key[11],
  2931. Key[12],Key[13],Key[14],Key[15]);
  2932. DbgPrint(" %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2933. Key[16],Key[17],Key[18],Key[19],
  2934. Key[20],Key[21],Key[22],Key[23]);
  2935. #ifdef EAP_ON
  2936. {
  2937. ULONG KeyLength, i;
  2938. Key = CompInfo->EapKey;
  2939. KeyLength = sizeof(CompInfo->EapKey);
  2940. i = 0;
  2941. DbgPrint("Eap Key:\n");
  2942. while (i <= KeyLength-16) {
  2943. DbgPrint("%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2944. Key[i],Key[i+1],Key[i+2],Key[i+3],
  2945. Key[i+4],Key[i+5],Key[i+6],Key[i+7],
  2946. Key[i+8],Key[i+9],Key[i+10],Key[i+11],
  2947. Key[i+12],Key[i+13],Key[i+14],Key[i+15]);
  2948. i += 16;
  2949. }
  2950. }
  2951. #endif
  2952. }
  2953. #endif
  2954. }
  2955. if (In->RecvCapabilities.Flags & CCP_SET_KEYS) {
  2956. BundleCB->RecvCompInfo.AuthType =
  2957. In->RecvCapabilities.AuthType;
  2958. NdisMoveMemory(&BundleCB->RecvCompInfo.LMSessionKey,
  2959. &In->RecvCapabilities.LMSessionKey,
  2960. sizeof(BundleCB->RecvCompInfo.LMSessionKey));
  2961. NdisMoveMemory(&BundleCB->RecvCompInfo.UserSessionKey,
  2962. &In->RecvCapabilities.UserSessionKey,
  2963. sizeof(BundleCB->RecvCompInfo.UserSessionKey));
  2964. NdisMoveMemory(&BundleCB->RecvCompInfo.Challenge,
  2965. &In->RecvCapabilities.Challenge,
  2966. sizeof(BundleCB->RecvCompInfo.Challenge));
  2967. NdisMoveMemory(&BundleCB->RecvCompInfo.NTResponse,
  2968. &In->RecvCapabilities.NTResponse,
  2969. sizeof(BundleCB->RecvCompInfo.NTResponse));
  2970. #ifdef EAP_ON
  2971. NdisMoveMemory(&BundleCB->RecvCompInfo.EapKey,
  2972. &In->RecvCapabilities.EapKey,
  2973. sizeof(BundleCB->RecvCompInfo.EapKey));
  2974. #endif
  2975. #ifdef DEBUG_CCP
  2976. {
  2977. PCOMPRESS_INFO CompInfo;
  2978. PUCHAR Key;
  2979. CompInfo = &BundleCB->RecvCompInfo;
  2980. Key = CompInfo->LMSessionKey;
  2981. DbgPrint("Recv KeyInfo\n");
  2982. DbgPrint("LMSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2983. Key[0],Key[1],Key[2],Key[3],
  2984. Key[4],Key[5],Key[6],Key[7]);
  2985. Key = CompInfo->UserSessionKey;
  2986. DbgPrint("UserSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2987. Key[0],Key[1],Key[2],Key[3],
  2988. Key[4],Key[5],Key[6],Key[7],
  2989. Key[8],Key[9],Key[10],Key[11],
  2990. Key[12],Key[13],Key[14],Key[15]);
  2991. Key = CompInfo->Challenge;
  2992. DbgPrint("Challenge: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2993. Key[0],Key[1],Key[2],Key[3],
  2994. Key[4],Key[5],Key[6],Key[7]);
  2995. Key = CompInfo->NTResponse;
  2996. DbgPrint("NTResponse: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  2997. Key[0],Key[1],Key[2],Key[3],
  2998. Key[4],Key[5],Key[6],Key[7],
  2999. Key[8],Key[9],Key[10],Key[11],
  3000. Key[12],Key[13],Key[14],Key[15]);
  3001. DbgPrint(" %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3002. Key[16],Key[17],Key[18],Key[19],
  3003. Key[20],Key[21],Key[22],Key[23]);
  3004. #ifdef EAP_ON
  3005. {
  3006. ULONG KeyLength, i;
  3007. Key = CompInfo->EapKey;
  3008. KeyLength = sizeof(CompInfo->EapKey);
  3009. i = 0;
  3010. DbgPrint("Eap Key:\n");
  3011. while (i <= KeyLength-16) {
  3012. DbgPrint("%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3013. Key[i],Key[i+1],Key[i+2],Key[i+3],
  3014. Key[i+4],Key[i+5],Key[i+6],Key[i+7],
  3015. Key[i+8],Key[i+9],Key[i+10],Key[i+11],
  3016. Key[i+12],Key[i+13],Key[i+14],Key[i+15]);
  3017. i += 16;
  3018. }
  3019. }
  3020. #endif
  3021. }
  3022. #endif
  3023. }
  3024. do {
  3025. if (In->SendCapabilities.Flags & CCP_SET_COMPTYPE) {
  3026. BundleCB->SendCompInfo.MSCompType =
  3027. In->SendCapabilities.MSCompType;
  3028. do {
  3029. if (!(BundleCB->Flags & SEND_CCP_ALLOCATED)) {
  3030. BundleCB->SCoherencyCounter = 0;
  3031. BundleCB->Flags |= SEND_CCP_ALLOCATED;
  3032. Status = WanAllocateCCP(BundleCB,
  3033. &BundleCB->SendCompInfo,
  3034. TRUE);
  3035. if (Status != STATUS_SUCCESS) {
  3036. break;
  3037. }
  3038. }
  3039. if (!(BundleCB->Flags & SEND_ECP_ALLOCATED)) {
  3040. BundleCB->SCoherencyCounter = 0;
  3041. BundleCB->Flags |= SEND_ECP_ALLOCATED;
  3042. Status = WanAllocateECP(BundleCB,
  3043. &BundleCB->SendCompInfo,
  3044. &BundleCB->SendCryptoInfo,
  3045. TRUE);
  3046. if (Status != STATUS_SUCCESS) {
  3047. break;
  3048. }
  3049. }
  3050. } while (FALSE);
  3051. if (Status != STATUS_SUCCESS) {
  3052. break;
  3053. }
  3054. }
  3055. if (In->RecvCapabilities.Flags & CCP_SET_COMPTYPE) {
  3056. BundleCB->RecvCompInfo.MSCompType =
  3057. In->RecvCapabilities.MSCompType;
  3058. do {
  3059. if (!(BundleCB->Flags & RECV_CCP_ALLOCATED)) {
  3060. BundleCB->RCoherencyCounter = 0;
  3061. BundleCB->LastRC4Reset = 0;
  3062. BundleCB->CCPIdentifier = 0;
  3063. BundleCB->Flags |= RECV_CCP_ALLOCATED;
  3064. Status = WanAllocateCCP(BundleCB,
  3065. &BundleCB->RecvCompInfo,
  3066. FALSE);
  3067. if (Status != STATUS_SUCCESS) {
  3068. break;
  3069. }
  3070. }
  3071. if (!(BundleCB->Flags & RECV_ECP_ALLOCATED)) {
  3072. BundleCB->RCoherencyCounter = 0;
  3073. BundleCB->LastRC4Reset = 0;
  3074. BundleCB->CCPIdentifier = 0;
  3075. BundleCB->Flags |= RECV_ECP_ALLOCATED;
  3076. Status = WanAllocateECP(BundleCB,
  3077. &BundleCB->RecvCompInfo,
  3078. &BundleCB->RecvCryptoInfo,
  3079. FALSE);
  3080. if (Status != STATUS_SUCCESS) {
  3081. break;
  3082. }
  3083. }
  3084. } while (FALSE);
  3085. if (Status != STATUS_SUCCESS) {
  3086. break;
  3087. }
  3088. }
  3089. } while (FALSE);
  3090. if (Status != STATUS_SUCCESS) {
  3091. if (BundleCB->Flags & SEND_CCP_ALLOCATED) {
  3092. BundleCB->Flags &= ~SEND_CCP_ALLOCATED;
  3093. WanDeallocateCCP(BundleCB,
  3094. &BundleCB->SendCompInfo,
  3095. TRUE);
  3096. }
  3097. if (BundleCB->Flags & RECV_CCP_ALLOCATED) {
  3098. BundleCB->Flags &= ~RECV_CCP_ALLOCATED;
  3099. WanDeallocateCCP(BundleCB,
  3100. &BundleCB->RecvCompInfo,
  3101. FALSE);
  3102. }
  3103. if (BundleCB->Flags & SEND_ECP_ALLOCATED) {
  3104. BundleCB->Flags &= ~SEND_ECP_ALLOCATED;
  3105. WanDeallocateECP(BundleCB,
  3106. &BundleCB->SendCompInfo,
  3107. &BundleCB->SendCryptoInfo);
  3108. }
  3109. if (BundleCB->Flags & RECV_ECP_ALLOCATED) {
  3110. BundleCB->Flags &= ~RECV_ECP_ALLOCATED;
  3111. WanDeallocateECP(BundleCB,
  3112. &BundleCB->RecvCompInfo,
  3113. &BundleCB->RecvCryptoInfo);
  3114. }
  3115. }
  3116. if (In->SendCapabilities.Flags & CCP_PAUSE_DATA) {
  3117. BundleCB->Flags |= PAUSE_DATA;
  3118. } else {
  3119. BundleCB->Flags &= ~PAUSE_DATA;
  3120. if (!(BundleCB->Flags & DEFERRED_WORK_QUEUED)) {
  3121. //
  3122. // Need to kick off sends again!
  3123. //
  3124. REF_BUNDLECB(BundleCB);
  3125. BundleCB->Flags |= DEFERRED_WORK_QUEUED;
  3126. InsertTailGlobalListEx(DeferredWorkList,
  3127. &BundleCB->DeferredLinkage,
  3128. 15,
  3129. 0);
  3130. }
  3131. }
  3132. SetBundleFlags(BundleCB);
  3133. } while ( 0 );
  3134. //
  3135. // Derefs for the refs applied in AreLinkAndBundleValid
  3136. //
  3137. DEREF_BUNDLECB_LOCKED(BundleCB);
  3138. DEREF_LINKCB(LinkCB);
  3139. return (Status);
  3140. }
  3141. NTSTATUS
  3142. GetCompressionInfo(
  3143. IN PUCHAR pInputBuffer,
  3144. IN ULONG ulInputBufferLength,
  3145. IN PUCHAR pOutputBuffer,
  3146. IN ULONG ulOutputBufferLength,
  3147. OUT PULONG pulBytesWritten
  3148. )
  3149. /*++
  3150. Routine Name:
  3151. Routine Description:
  3152. Arguments:
  3153. Return Values:
  3154. --*/
  3155. {
  3156. NTSTATUS Status = STATUS_SUCCESS;
  3157. ULONG SizeNeeded = sizeof(NDISWAN_GET_COMPRESSION_INFO);
  3158. PNDISWAN_GET_COMPRESSION_INFO In = (PNDISWAN_GET_COMPRESSION_INFO)pInputBuffer;
  3159. PNDISWAN_GET_COMPRESSION_INFO Out = (PNDISWAN_GET_COMPRESSION_INFO)pOutputBuffer;
  3160. PLINKCB LinkCB = NULL;
  3161. PBUNDLECB BundleCB = NULL;
  3162. POPENCB OpenCB;
  3163. ULONG i;
  3164. WAN_REQUEST WanRequest;
  3165. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetCompressionInfo:"));
  3166. *pulBytesWritten = SizeNeeded;
  3167. do {
  3168. if (ulInputBufferLength < SizeNeeded ||
  3169. ulOutputBufferLength < SizeNeeded) {
  3170. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetCompressionInfo: Buffer to small: Size: %d, SizeNeeded %d",
  3171. ulOutputBufferLength, SizeNeeded));
  3172. Status = STATUS_INFO_LENGTH_MISMATCH;
  3173. break;
  3174. }
  3175. if (!AreLinkAndBundleValid(In->hLinkHandle,
  3176. TRUE,
  3177. &LinkCB,
  3178. &BundleCB)) {
  3179. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3180. break;
  3181. }
  3182. OpenCB = LinkCB->OpenCB;
  3183. Out->SendCapabilities.CompType = COMPTYPE_NONE;
  3184. Out->SendCapabilities.CompLength = 0;
  3185. Out->RecvCapabilities.CompType = COMPTYPE_NONE;
  3186. Out->RecvCapabilities.CompLength = 0;
  3187. AcquireBundleLock(BundleCB);
  3188. //
  3189. // Fill in the ndiswan specific stuff
  3190. //
  3191. NdisMoveMemory(Out->SendCapabilities.LMSessionKey,
  3192. BundleCB->SendCompInfo.LMSessionKey,
  3193. sizeof(Out->SendCapabilities.LMSessionKey));
  3194. NdisMoveMemory(Out->SendCapabilities.UserSessionKey,
  3195. BundleCB->SendCompInfo.UserSessionKey,
  3196. sizeof(Out->SendCapabilities.UserSessionKey));
  3197. NdisMoveMemory(Out->SendCapabilities.Challenge,
  3198. BundleCB->SendCompInfo.Challenge,
  3199. sizeof(Out->SendCapabilities.Challenge));
  3200. NdisMoveMemory(Out->SendCapabilities.NTResponse,
  3201. BundleCB->SendCompInfo.NTResponse,
  3202. sizeof(Out->SendCapabilities.NTResponse));
  3203. #ifdef EAP_ON
  3204. NdisMoveMemory(Out->SendCapabilities.EapKey,
  3205. BundleCB->SendCompInfo.EapKey,
  3206. sizeof(Out->SendCapabilities.EapKey));
  3207. Out->SendCapabilities.EapKeyLength =
  3208. BundleCB->SendCompInfo.EapKeyLength;
  3209. #endif
  3210. NdisMoveMemory(Out->RecvCapabilities.LMSessionKey,
  3211. BundleCB->RecvCompInfo.LMSessionKey,
  3212. sizeof(Out->RecvCapabilities.LMSessionKey));
  3213. NdisMoveMemory(Out->RecvCapabilities.UserSessionKey,
  3214. BundleCB->RecvCompInfo.UserSessionKey,
  3215. sizeof(Out->RecvCapabilities.UserSessionKey));
  3216. NdisMoveMemory(Out->RecvCapabilities.Challenge,
  3217. BundleCB->RecvCompInfo.Challenge,
  3218. sizeof(Out->RecvCapabilities.Challenge));
  3219. NdisMoveMemory(Out->RecvCapabilities.NTResponse,
  3220. BundleCB->RecvCompInfo.NTResponse,
  3221. sizeof(Out->RecvCapabilities.NTResponse));
  3222. #ifdef EAP_ON
  3223. NdisMoveMemory(Out->RecvCapabilities.EapKey,
  3224. BundleCB->RecvCompInfo.EapKey,
  3225. sizeof(Out->RecvCapabilities.EapKey));
  3226. Out->RecvCapabilities.EapKeyLength =
  3227. BundleCB->RecvCompInfo.EapKeyLength;
  3228. #endif
  3229. //
  3230. // We will set encryption capabilities based on session key
  3231. // availability and auth type being used.
  3232. //
  3233. // Set send side capabilities
  3234. //
  3235. Out->SendCapabilities.MSCompType = NDISWAN_COMPRESSION;
  3236. if (BundleCB->SendCompInfo.AuthType == AUTH_USE_MSCHAPV1) {
  3237. for (i = 0; i < sizeof(Out->SendCapabilities.LMSessionKey); i++) {
  3238. if (Out->SendCapabilities.LMSessionKey[i] != 0) {
  3239. Out->SendCapabilities.MSCompType |=
  3240. (NDISWAN_ENCRYPTION |
  3241. NDISWAN_40_ENCRYPTION |
  3242. NDISWAN_56_ENCRYPTION);
  3243. break;
  3244. }
  3245. }
  3246. #ifdef ENCRYPT_128BIT
  3247. for (i = 0; i < sizeof(Out->SendCapabilities.UserSessionKey); i++) {
  3248. if (Out->SendCapabilities.UserSessionKey[i] != 0) {
  3249. Out->SendCapabilities.MSCompType |=
  3250. (NDISWAN_128_ENCRYPTION);
  3251. break;
  3252. }
  3253. }
  3254. #endif
  3255. } else if (BundleCB->SendCompInfo.AuthType == AUTH_USE_MSCHAPV2) {
  3256. for (i = 0; i < sizeof(Out->SendCapabilities.UserSessionKey); i++) {
  3257. if (Out->SendCapabilities.UserSessionKey[i] != 0) {
  3258. Out->SendCapabilities.MSCompType |=
  3259. (NDISWAN_40_ENCRYPTION |
  3260. NDISWAN_56_ENCRYPTION);
  3261. #ifdef ENCRYPT_128BIT
  3262. Out->SendCapabilities.MSCompType |=
  3263. (NDISWAN_128_ENCRYPTION);
  3264. #endif
  3265. break;
  3266. }
  3267. }
  3268. #ifdef EAP_ON
  3269. } else if (BundleCB->SendCompInfo.AuthType == AUTH_USE_EAP) {
  3270. for (i = 0; i < sizeof(Out->SendCapabilities.EapKey); i++) {
  3271. if (Out->SendCapabilities.EapKey[i] != 0) {
  3272. Out->SendCapabilities.MSCompType |=
  3273. (NDISWAN_40_ENCRYPTION |
  3274. NDISWAN_56_ENCRYPTION);
  3275. #ifdef ENCRYPT_128BIT
  3276. Out->SendCapabilities.MSCompType |=
  3277. (NDISWAN_128_ENCRYPTION);
  3278. #endif
  3279. break;
  3280. }
  3281. }
  3282. #endif
  3283. }
  3284. // Set send side capabilities
  3285. //
  3286. Out->RecvCapabilities.MSCompType = NDISWAN_COMPRESSION;
  3287. if (BundleCB->RecvCompInfo.AuthType == AUTH_USE_MSCHAPV1) {
  3288. for (i = 0; i < sizeof(Out->RecvCapabilities.LMSessionKey); i++) {
  3289. if (Out->RecvCapabilities.LMSessionKey[i] != 0) {
  3290. Out->RecvCapabilities.MSCompType |=
  3291. (NDISWAN_ENCRYPTION |
  3292. NDISWAN_40_ENCRYPTION |
  3293. NDISWAN_56_ENCRYPTION);
  3294. break;
  3295. }
  3296. }
  3297. #ifdef ENCRYPT_128BIT
  3298. for (i = 0; i < sizeof(Out->RecvCapabilities.UserSessionKey); i++) {
  3299. if (Out->RecvCapabilities.UserSessionKey[i] != 0) {
  3300. Out->RecvCapabilities.MSCompType |=
  3301. (NDISWAN_128_ENCRYPTION);
  3302. break;
  3303. }
  3304. }
  3305. #endif
  3306. } else if (BundleCB->RecvCompInfo.AuthType == AUTH_USE_MSCHAPV2) {
  3307. for (i = 0; i < sizeof(Out->RecvCapabilities.UserSessionKey); i++) {
  3308. if (Out->RecvCapabilities.UserSessionKey[i] != 0) {
  3309. Out->RecvCapabilities.MSCompType |=
  3310. (NDISWAN_40_ENCRYPTION |
  3311. NDISWAN_56_ENCRYPTION);
  3312. #ifdef ENCRYPT_128BIT
  3313. Out->RecvCapabilities.MSCompType |=
  3314. (NDISWAN_128_ENCRYPTION);
  3315. #endif
  3316. break;
  3317. }
  3318. }
  3319. #ifdef EAP_ON
  3320. } else if (BundleCB->RecvCompInfo.AuthType == AUTH_USE_EAP) {
  3321. for (i = 0; i < sizeof(Out->RecvCapabilities.EapKey); i++) {
  3322. if (Out->RecvCapabilities.EapKey[i] != 0) {
  3323. Out->RecvCapabilities.MSCompType |=
  3324. (NDISWAN_40_ENCRYPTION |
  3325. NDISWAN_56_ENCRYPTION);
  3326. #ifdef ENCRYPT_128BIT
  3327. Out->RecvCapabilities.MSCompType |=
  3328. (NDISWAN_128_ENCRYPTION);
  3329. #endif
  3330. break;
  3331. }
  3332. }
  3333. #endif
  3334. }
  3335. if (gbHistoryless &&
  3336. (OpenCB->MediumSubType == NdisWanMediumPPTP ||
  3337. OpenCB->MediumSubType == NdisWanMediumL2TP)) {
  3338. Out->SendCapabilities.MSCompType |= NDISWAN_HISTORY_LESS;
  3339. Out->RecvCapabilities.MSCompType |= NDISWAN_HISTORY_LESS;
  3340. }
  3341. #ifdef DEBUG_CCP
  3342. {
  3343. PCOMPRESS_INFO CompInfo;
  3344. PUCHAR Key;
  3345. CompInfo = &Out->SendCapabilities;
  3346. DbgPrint("NdisWan: Get Send CompressInfo\n");
  3347. DbgPrint("MSCompType: %x\n", CompInfo->MSCompType);
  3348. DbgPrint("AuthType: %x\n", CompInfo->AuthType);
  3349. DbgPrint("Flags: %x\n", CompInfo->Flags);
  3350. Key = CompInfo->LMSessionKey;
  3351. DbgPrint("LMSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3352. Key[0],Key[1],Key[2],Key[3],
  3353. Key[4],Key[5],Key[6],Key[7]);
  3354. Key = CompInfo->UserSessionKey;
  3355. DbgPrint("UserSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3356. Key[0],Key[1],Key[2],Key[3],
  3357. Key[4],Key[5],Key[6],Key[7],
  3358. Key[8],Key[9],Key[10],Key[11],
  3359. Key[12],Key[13],Key[14],Key[15]);
  3360. Key = CompInfo->Challenge;
  3361. DbgPrint("Challenge: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3362. Key[0],Key[1],Key[2],Key[3],
  3363. Key[4],Key[5],Key[6],Key[7]);
  3364. Key = CompInfo->NTResponse;
  3365. DbgPrint("NTResponse: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3366. Key[0],Key[1],Key[2],Key[3],
  3367. Key[4],Key[5],Key[6],Key[7],
  3368. Key[8],Key[9],Key[10],Key[11],
  3369. Key[12],Key[13],Key[14],Key[15]);
  3370. DbgPrint(" %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3371. Key[16],Key[17],Key[18],Key[19],
  3372. Key[20],Key[21],Key[22],Key[23]);
  3373. }
  3374. #endif
  3375. #ifdef DEBUG_CCP
  3376. {
  3377. PCOMPRESS_INFO CompInfo;
  3378. PUCHAR Key;
  3379. CompInfo = &Out->RecvCapabilities;
  3380. DbgPrint("NdisWan: Get Receive CompressInfo\n");
  3381. DbgPrint("MSCompType: %x\n", CompInfo->MSCompType);
  3382. DbgPrint("AuthType: %x\n", CompInfo->AuthType);
  3383. DbgPrint("Flags: %x\n", CompInfo->Flags);
  3384. Key = CompInfo->LMSessionKey;
  3385. DbgPrint("LMSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3386. Key[0],Key[1],Key[2],Key[3],
  3387. Key[4],Key[5],Key[6],Key[7]);
  3388. Key = CompInfo->UserSessionKey;
  3389. DbgPrint("UserSession Key: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3390. Key[0],Key[1],Key[2],Key[3],
  3391. Key[4],Key[5],Key[6],Key[7],
  3392. Key[8],Key[9],Key[10],Key[11],
  3393. Key[12],Key[13],Key[14],Key[15]);
  3394. Key = CompInfo->Challenge;
  3395. DbgPrint("Challenge: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3396. Key[0],Key[1],Key[2],Key[3],
  3397. Key[4],Key[5],Key[6],Key[7]);
  3398. Key = CompInfo->NTResponse;
  3399. DbgPrint("NTResponse: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3400. Key[0],Key[1],Key[2],Key[3],
  3401. Key[4],Key[5],Key[6],Key[7],
  3402. Key[8],Key[9],Key[10],Key[11],
  3403. Key[12],Key[13],Key[14],Key[15]);
  3404. DbgPrint(" %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
  3405. Key[16],Key[17],Key[18],Key[19],
  3406. Key[20],Key[21],Key[22],Key[23]);
  3407. }
  3408. #endif
  3409. } while ( 0 );
  3410. //
  3411. // Derefs for the refs applied in AreLinkAndBundleValid
  3412. //
  3413. DEREF_BUNDLECB_LOCKED(BundleCB);
  3414. DEREF_LINKCB(LinkCB);
  3415. return (Status);
  3416. }
  3417. NTSTATUS
  3418. SetVJInfo(
  3419. IN PUCHAR pInputBuffer,
  3420. IN ULONG ulInputBufferLength,
  3421. IN PUCHAR pOutputBuffer,
  3422. IN ULONG ulOutputBufferLength,
  3423. OUT PULONG pulBytesWritten
  3424. )
  3425. /*++
  3426. Routine Name:
  3427. Routine Description:
  3428. Arguments:
  3429. Return Values:
  3430. --*/
  3431. {
  3432. NTSTATUS Status = STATUS_SUCCESS;
  3433. PLINKCB LinkCB = NULL;
  3434. PBUNDLECB BundleCB = NULL;
  3435. ULONG SizeNeeded = sizeof(NDISWAN_SET_VJ_INFO);
  3436. PNDISWAN_SET_VJ_INFO In = (PNDISWAN_SET_VJ_INFO)pInputBuffer;
  3437. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetVJInfo:"));
  3438. *pulBytesWritten = 0;
  3439. do {
  3440. if (ulInputBufferLength < SizeNeeded) {
  3441. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("SetVJInfo: Buffer to small: Size: %d, SizeNeeded %d",
  3442. ulInputBufferLength, SizeNeeded));
  3443. *pulBytesWritten = SizeNeeded;
  3444. Status = STATUS_INFO_LENGTH_MISMATCH;
  3445. break;
  3446. }
  3447. if (!AreLinkAndBundleValid(In->hLinkHandle,
  3448. TRUE,
  3449. &LinkCB,
  3450. &BundleCB)) {
  3451. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3452. break;
  3453. }
  3454. AcquireBundleLock(BundleCB);
  3455. NdisMoveMemory(&BundleCB->RecvVJInfo,
  3456. &In->RecvCapabilities,
  3457. sizeof(VJ_INFO));
  3458. if (In->RecvCapabilities.IPCompressionProtocol == 0x2D) {
  3459. if (In->RecvCapabilities.MaxSlotID < MAX_VJ_STATES) {
  3460. Status = sl_compress_init(&BundleCB->VJCompress,
  3461. (UCHAR)(In->RecvCapabilities.MaxSlotID + 1));
  3462. if (Status != NDIS_STATUS_SUCCESS) {
  3463. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("Error allocating VJ Info!"));
  3464. }
  3465. }
  3466. }
  3467. NdisMoveMemory(&BundleCB->SendVJInfo,
  3468. &In->SendCapabilities,
  3469. sizeof(VJ_INFO));
  3470. if (In->SendCapabilities.IPCompressionProtocol == 0x2D) {
  3471. if (In->SendCapabilities.MaxSlotID < MAX_VJ_STATES) {
  3472. Status = sl_compress_init(&BundleCB->VJCompress,
  3473. (UCHAR)(In->SendCapabilities.MaxSlotID + 1));
  3474. if (Status != NDIS_STATUS_SUCCESS) {
  3475. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("Error allocating VJ Info!"));
  3476. }
  3477. }
  3478. }
  3479. SetBundleFlags(BundleCB);
  3480. } while ( 0 );
  3481. //
  3482. // Derefs for the refs applied in AreLinkAndBundleValid
  3483. //
  3484. DEREF_BUNDLECB_LOCKED(BundleCB);
  3485. DEREF_LINKCB(LinkCB);
  3486. return (Status);
  3487. }
  3488. NTSTATUS
  3489. GetVJInfo(
  3490. IN PUCHAR pInputBuffer,
  3491. IN ULONG ulInputBufferLength,
  3492. IN PUCHAR pOutputBuffer,
  3493. IN ULONG ulOutputBufferLength,
  3494. OUT PULONG pulBytesWritten
  3495. )
  3496. /*++
  3497. Routine Name:
  3498. Routine Description:
  3499. Arguments:
  3500. Return Values:
  3501. --*/
  3502. {
  3503. ULONG SizeNeeded = sizeof(NDISWAN_GET_VJ_INFO);
  3504. PLINKCB LinkCB = NULL;
  3505. POPENCB OpenCB = NULL;
  3506. NTSTATUS Status = STATUS_SUCCESS;
  3507. PNDISWAN_GET_VJ_INFO In = (PNDISWAN_GET_VJ_INFO)pInputBuffer;
  3508. PNDISWAN_GET_VJ_INFO Out = (PNDISWAN_GET_VJ_INFO)pOutputBuffer;
  3509. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetVJInfo:"));
  3510. *pulBytesWritten = SizeNeeded;
  3511. do {
  3512. if (ulOutputBufferLength < SizeNeeded) {
  3513. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetVJInfo: Buffer to small: Size: %d, SizeNeeded %d",
  3514. ulOutputBufferLength, SizeNeeded));
  3515. Status = STATUS_INFO_LENGTH_MISMATCH;
  3516. break;
  3517. }
  3518. if (!IsLinkValid(In->hLinkHandle,
  3519. TRUE,
  3520. &LinkCB)) {
  3521. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3522. break;
  3523. }
  3524. OpenCB = LinkCB->OpenCB;
  3525. if (OpenCB->MediumSubType == NdisWanMediumPPTP ||
  3526. OpenCB->MediumSubType == NdisWanMediumL2TP) {
  3527. Out->SendCapabilities.IPCompressionProtocol =
  3528. Out->RecvCapabilities.IPCompressionProtocol = 0;
  3529. } else {
  3530. Out->SendCapabilities.IPCompressionProtocol =
  3531. Out->RecvCapabilities.IPCompressionProtocol = 0x2D;
  3532. }
  3533. Out->SendCapabilities.MaxSlotID =
  3534. Out->RecvCapabilities.MaxSlotID = MAX_VJ_STATES - 1;
  3535. Out->SendCapabilities.CompSlotID =
  3536. Out->RecvCapabilities.CompSlotID = 1;
  3537. } while ( 0 );
  3538. //
  3539. // Deref for ref applied by IsLinkValid
  3540. //
  3541. DEREF_LINKCB(LinkCB);
  3542. return (Status);
  3543. }
  3544. NTSTATUS
  3545. GetBandwidthUtilization(
  3546. IN PUCHAR pInputBuffer,
  3547. IN ULONG ulInputBufferLength,
  3548. IN PUCHAR pOutputBuffer,
  3549. IN ULONG ulOutputBufferLength,
  3550. OUT PULONG pulBytesWritten
  3551. )
  3552. /*++
  3553. Routine Name:
  3554. Routine Description:
  3555. Arguments:
  3556. Return Values:
  3557. --*/
  3558. {
  3559. ULONG SizeNeeded = sizeof(NDISWAN_GET_BANDWIDTH_UTILIZATION);
  3560. PBUNDLECB BundleCB = NULL;
  3561. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  3562. PNDISWAN_GET_BANDWIDTH_UTILIZATION In =
  3563. (PNDISWAN_GET_BANDWIDTH_UTILIZATION)pInputBuffer;
  3564. PNDISWAN_GET_BANDWIDTH_UTILIZATION Out =
  3565. (PNDISWAN_GET_BANDWIDTH_UTILIZATION)pOutputBuffer;
  3566. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetBandwidthUtilization: Enter"));
  3567. *pulBytesWritten = 0;
  3568. if (ulInputBufferLength < sizeof(In->hBundleHandle) ||
  3569. ulOutputBufferLength < SizeNeeded) {
  3570. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetBandwidthUtilization: Buffer to small: Size: %d, SizeNeeded %d",
  3571. ulOutputBufferLength, SizeNeeded));
  3572. *pulBytesWritten = SizeNeeded;
  3573. return STATUS_INFO_LENGTH_MISMATCH;
  3574. }
  3575. if (!IsBundleValid(In->hBundleHandle,
  3576. FALSE,
  3577. &BundleCB)) {
  3578. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetBandwidthUtilization: Invalid BundleHandle: 0x%x",
  3579. In->hBundleHandle));
  3580. return NDISWAN_ERROR_INVALID_HANDLE;
  3581. }
  3582. do {
  3583. ULONGLONG MaxByteCount, temp;
  3584. AcquireBundleLock(BundleCB);
  3585. if(BundleCB->SUpperBonDInfo == NULL ||
  3586. BundleCB->RUpperBonDInfo == NULL)
  3587. {
  3588. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3589. break;
  3590. }
  3591. MaxByteCount = BundleCB->SUpperBonDInfo->ulBytesInSamplePeriod;
  3592. temp = 0;
  3593. if (MaxByteCount != 0) {
  3594. temp = BundleCB->SUpperBonDInfo->SampleTable.ulCurrentSampleByteCount;
  3595. temp *= 100;
  3596. temp /= MaxByteCount;
  3597. }
  3598. Out->ulUpperXmitUtil = (ULONG)temp;
  3599. MaxByteCount = BundleCB->SLowerBonDInfo->ulBytesInSamplePeriod;
  3600. temp = 0;
  3601. if (MaxByteCount != 0) {
  3602. temp = BundleCB->SLowerBonDInfo->SampleTable.ulCurrentSampleByteCount;
  3603. temp *= 100;
  3604. temp /= MaxByteCount;
  3605. }
  3606. Out->ulLowerXmitUtil = (ULONG)temp;
  3607. MaxByteCount = BundleCB->RUpperBonDInfo->ulBytesInSamplePeriod;
  3608. temp = 0;
  3609. if (MaxByteCount != 0) {
  3610. temp = BundleCB->RUpperBonDInfo->SampleTable.ulCurrentSampleByteCount;
  3611. temp *= 100;
  3612. temp /= MaxByteCount;
  3613. }
  3614. Out->ulUpperRecvUtil = (ULONG)temp;
  3615. MaxByteCount = BundleCB->RLowerBonDInfo->ulBytesInSamplePeriod;
  3616. temp = 0;
  3617. if (MaxByteCount != 0) {
  3618. temp = BundleCB->RLowerBonDInfo->SampleTable.ulCurrentSampleByteCount;
  3619. temp *= 100;
  3620. temp /= MaxByteCount;
  3621. }
  3622. Out->ulLowerRecvUtil = (ULONG)temp;
  3623. *pulBytesWritten = SizeNeeded;
  3624. } while (FALSE);
  3625. //
  3626. // Deref for ref applied by IsBundleValid. This releases
  3627. // the BundleCB->Lock.
  3628. //
  3629. DEREF_BUNDLECB_LOCKED(BundleCB);
  3630. return (Status);
  3631. }
  3632. NTSTATUS
  3633. EnumProtocolUtilization(
  3634. IN PUCHAR pInputBuffer,
  3635. IN ULONG ulInputBufferLength,
  3636. IN PUCHAR pOutputBuffer,
  3637. IN ULONG ulOutputBufferLength,
  3638. OUT PULONG pulBytesWritten
  3639. )
  3640. /*++
  3641. Routine Name:
  3642. Routine Description:
  3643. Arguments:
  3644. Return Values:
  3645. --*/
  3646. {
  3647. ULONG SizeNeeded = sizeof(NDISWAN_ENUM_PROTOCOL_UTILIZATION);
  3648. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("EnumProtocolUtilization:"));
  3649. *pulBytesWritten = SizeNeeded;
  3650. if (ulOutputBufferLength < SizeNeeded) {
  3651. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("EnumProtocolUtilization: Buffer to small: Size: %d, SizeNeeded %d",
  3652. ulOutputBufferLength, SizeNeeded));
  3653. return(STATUS_INFO_LENGTH_MISMATCH);
  3654. }
  3655. return (STATUS_NOT_IMPLEMENTED);
  3656. }
  3657. NTSTATUS
  3658. EnumActiveBundles(
  3659. IN PUCHAR pInputBuffer,
  3660. IN ULONG ulInputBufferLength,
  3661. IN PUCHAR pOutputBuffer,
  3662. IN ULONG ulOutputBufferLength,
  3663. OUT PULONG pulBytesWritten
  3664. )
  3665. /*++
  3666. Routine Name:
  3667. Routine Description:
  3668. Arguments:
  3669. Return Values:
  3670. --*/
  3671. {
  3672. ULONG SizeNeeded = sizeof(NDISWAN_ENUM_ACTIVE_BUNDLES);
  3673. PNDISWAN_ENUM_ACTIVE_BUNDLES Out = (PNDISWAN_ENUM_ACTIVE_BUNDLES)pOutputBuffer;
  3674. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetNumActiveBundles:"));
  3675. *pulBytesWritten = SizeNeeded;
  3676. if (ulOutputBufferLength < SizeNeeded) {
  3677. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetNumActiveBundles: Buffer to small: Size: %d, SizeNeeded %d",
  3678. ulOutputBufferLength, SizeNeeded));
  3679. return(STATUS_INFO_LENGTH_MISMATCH);
  3680. }
  3681. //
  3682. // Does this information need to be protected by the lock?
  3683. // I would hate to have things get slowed for this call!
  3684. //
  3685. Out->ulNumberOfActiveBundles = ConnectionTable->ulNumActiveBundles;
  3686. return (STATUS_SUCCESS);
  3687. }
  3688. NTSTATUS
  3689. GetWanInfo(
  3690. IN PUCHAR pInputBuffer,
  3691. IN ULONG ulInputBufferLength,
  3692. IN PUCHAR pOutputBuffer,
  3693. IN ULONG ulOutputBufferLength,
  3694. OUT PULONG pulBytesWritten
  3695. )
  3696. /*++
  3697. Routine Name:
  3698. Routine Description:
  3699. Arguments:
  3700. Return Values:
  3701. --*/
  3702. {
  3703. ULONG SizeNeeded = sizeof(NDISWAN_GET_WAN_INFO);
  3704. PNDISWAN_GET_WAN_INFO In = (PNDISWAN_GET_WAN_INFO)pInputBuffer;
  3705. PNDISWAN_GET_WAN_INFO Out = (PNDISWAN_GET_WAN_INFO)pOutputBuffer;
  3706. POPENCB OpenCB;
  3707. PLINKCB LinkCB = NULL;
  3708. NTSTATUS Status = STATUS_SUCCESS;
  3709. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetWanInfo:"));
  3710. *pulBytesWritten = SizeNeeded;
  3711. do {
  3712. if (ulOutputBufferLength < SizeNeeded) {
  3713. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetWanInfo: Buffer to small: Size: %d, SizeNeeded %d",
  3714. ulOutputBufferLength, SizeNeeded));
  3715. Status = STATUS_INFO_LENGTH_MISMATCH;
  3716. break;
  3717. }
  3718. if (!IsLinkValid(In->hLinkHandle,
  3719. FALSE,
  3720. &LinkCB)) {
  3721. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetWanInfo: Invalid LinkHandle: 0x%x",
  3722. In->hLinkHandle));
  3723. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3724. break;
  3725. }
  3726. OpenCB = LinkCB->OpenCB;
  3727. Out->WanInfo.MaxFrameSize = OpenCB->WanInfo.MaxFrameSize;
  3728. Out->WanInfo.MaxTransmit = OpenCB->WanInfo.MaxTransmit;
  3729. Out->WanInfo.FramingBits = OpenCB->WanInfo.FramingBits;
  3730. Out->WanInfo.DesiredACCM = OpenCB->WanInfo.DesiredACCM;
  3731. Out->WanInfo.MaxReconstructedFrameSize = glMRRU;
  3732. Out->WanInfo.LinkSpeed = LinkCB->SFlowSpec.PeakBandwidth*8;
  3733. } while ( 0 );
  3734. //
  3735. // Deref for ref applied by IsLinkValid
  3736. //
  3737. DEREF_LINKCB(LinkCB);
  3738. return (Status);
  3739. }
  3740. NTSTATUS
  3741. SetDebugInfo(
  3742. IN PUCHAR pInputBuffer,
  3743. IN ULONG ulInputBufferLength,
  3744. IN PUCHAR pOutputBuffer,
  3745. IN ULONG ulOutputBufferLength,
  3746. OUT PULONG pulBytesWritten
  3747. )
  3748. /*++
  3749. Routine Name:
  3750. Routine Description:
  3751. Arguments:
  3752. Return Values:
  3753. --*/
  3754. {
  3755. PNDISWAN_SET_DEBUG_INFO pDebugInfo = (PNDISWAN_SET_DEBUG_INFO)pInputBuffer;
  3756. ULONG SizeNeeded = sizeof(NDISWAN_SET_DEBUG_INFO);
  3757. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetDebugInfo: OldLevel: 0x%x OldMask: 0x%x",
  3758. glDebugLevel, glDebugMask));
  3759. *pulBytesWritten = 0;
  3760. if (ulInputBufferLength < SizeNeeded) {
  3761. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("Buffer to small: Size: %d, SizeNeeded %d",
  3762. ulInputBufferLength, SizeNeeded));
  3763. *pulBytesWritten = SizeNeeded;
  3764. return(STATUS_INFO_LENGTH_MISMATCH);
  3765. }
  3766. glDebugLevel = pDebugInfo->ulDebugLevel;
  3767. glDebugMask = pDebugInfo->ulDebugMask;
  3768. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetDebugInfo: NewLevel: 0x%x NewMask: 0x%x",
  3769. glDebugLevel, glDebugMask));
  3770. return (STATUS_SUCCESS);
  3771. }
  3772. NTSTATUS
  3773. SetEncryptionInfo(
  3774. IN PUCHAR pInputBuffer,
  3775. IN ULONG ulInputBufferLength,
  3776. IN PUCHAR pOutputBuffer,
  3777. IN ULONG ulOutputBufferLength,
  3778. OUT PULONG pulBytesWritten
  3779. )
  3780. /*++
  3781. Routine Name:
  3782. Routine Description:
  3783. Arguments:
  3784. Return Values:
  3785. --*/
  3786. {
  3787. ULONG SizeNeeded = sizeof(NDISWAN_SET_ENCRYPTION_INFO);
  3788. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("SetEncryptionInfo:"));
  3789. *pulBytesWritten = 0;
  3790. if (ulInputBufferLength < SizeNeeded) {
  3791. *pulBytesWritten = SizeNeeded;
  3792. return(STATUS_INFO_LENGTH_MISMATCH);
  3793. }
  3794. return (STATUS_NOT_IMPLEMENTED);
  3795. }
  3796. NTSTATUS
  3797. GetEncryptionInfo(
  3798. IN PUCHAR pInputBuffer,
  3799. IN ULONG ulInputBufferLength,
  3800. IN PUCHAR pOutputBuffer,
  3801. IN ULONG ulOutputBufferLength,
  3802. OUT PULONG pulBytesWritten
  3803. )
  3804. /*++
  3805. Routine Name:
  3806. Routine Description:
  3807. Arguments:
  3808. Return Values:
  3809. --*/
  3810. {
  3811. ULONG SizeNeeded = sizeof(NDISWAN_GET_ENCRYPTION_INFO);
  3812. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetEncryptionInfo:"));
  3813. *pulBytesWritten = SizeNeeded;
  3814. if (ulOutputBufferLength < SizeNeeded) {
  3815. return(STATUS_INFO_LENGTH_MISMATCH);
  3816. }
  3817. return (STATUS_NOT_IMPLEMENTED);
  3818. }
  3819. NTSTATUS
  3820. GetIdleTime(
  3821. IN PUCHAR pInputBuffer,
  3822. IN ULONG ulInputBufferLength,
  3823. IN PUCHAR pOutputBuffer,
  3824. IN ULONG ulOutputBufferLength,
  3825. OUT PULONG pulBytesWritten
  3826. )
  3827. /*++
  3828. Routine Name:
  3829. Routine Description:
  3830. Arguments:
  3831. Return Values:
  3832. --*/
  3833. {
  3834. ULONG SizeNeeded = sizeof(NDISWAN_GET_IDLE_TIME);
  3835. PNDISWAN_GET_IDLE_TIME In = (PNDISWAN_GET_IDLE_TIME)pInputBuffer;
  3836. PNDISWAN_GET_IDLE_TIME Out = (PNDISWAN_GET_IDLE_TIME)pOutputBuffer;
  3837. PBUNDLECB BundleCB = NULL;
  3838. PPROTOCOLCB ProtocolCB = NULL;
  3839. WAN_TIME CurrentTime, Diff, OneSecond;
  3840. WAN_TIME LastNonIdleData;
  3841. NTSTATUS Status = STATUS_SUCCESS;
  3842. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetIdleTime:"));
  3843. *pulBytesWritten = SizeNeeded;
  3844. do {
  3845. if (ulOutputBufferLength < SizeNeeded) {
  3846. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetIdleTime: Buffer to small: Size: %d, SizeNeeded %d",
  3847. ulInputBufferLength, SizeNeeded));
  3848. Status = STATUS_INFO_LENGTH_MISMATCH;
  3849. break;
  3850. }
  3851. if (!IsBundleValid(In->hBundleHandle,
  3852. FALSE,
  3853. &BundleCB)) {
  3854. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetIdleTime: Invalid BundleHandle: 0x%x",
  3855. In->hBundleHandle));
  3856. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3857. break;
  3858. }
  3859. AcquireBundleLock(BundleCB);
  3860. if (BundleCB->Flags & DISABLE_IDLE_DETECT) {
  3861. Out->ulSeconds = 0;
  3862. break;
  3863. }
  3864. //
  3865. // If this is for the bundle
  3866. //
  3867. if (In->usProtocolType == BUNDLE_IDLE_TIME) {
  3868. LastNonIdleData = BundleCB->LastNonIdleData;
  3869. } else {
  3870. //
  3871. // Find the protocol type
  3872. //
  3873. for (ProtocolCB = (PPROTOCOLCB)BundleCB->ProtocolCBList.Flink;
  3874. (PVOID)ProtocolCB != (PVOID)&BundleCB->ProtocolCBList;
  3875. ProtocolCB = (PPROTOCOLCB)ProtocolCB->Linkage.Flink) {
  3876. if (ProtocolCB->ProtocolType == In->usProtocolType) {
  3877. break;
  3878. }
  3879. }
  3880. if ((PVOID)ProtocolCB == (PVOID)&BundleCB->ProtocolCBList) {
  3881. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetIdleTime: Invalid ProtocolType: 0x%x",
  3882. In->usProtocolType));
  3883. Status = NDISWAN_ERROR_NO_ROUTE;
  3884. break;
  3885. }
  3886. LastNonIdleData = ProtocolCB->LastNonIdleData;
  3887. }
  3888. NdisWanGetSystemTime(&CurrentTime);
  3889. NdisWanCalcTimeDiff(&Diff, &CurrentTime, &LastNonIdleData);
  3890. NdisWanInitWanTime(&OneSecond, ONE_SECOND);
  3891. NdisWanDivideWanTime(&CurrentTime, &Diff, &OneSecond);
  3892. Out->ulSeconds = CurrentTime.LowPart;
  3893. } while ( 0 );
  3894. //
  3895. // Deref for ref applied by IsBundleValid. This releases the
  3896. // BundleCB->Lock.
  3897. //
  3898. DEREF_BUNDLECB_LOCKED(BundleCB);
  3899. return (Status);
  3900. }
  3901. NTSTATUS
  3902. DeactivateRoute(
  3903. IN PUCHAR pInputBuffer,
  3904. IN ULONG ulInputBufferLength,
  3905. IN PUCHAR pOutputBuffer,
  3906. IN ULONG ulOutputBufferLength,
  3907. OUT PULONG pulBytesWritten
  3908. )
  3909. /*++
  3910. Routine Name:
  3911. DeactivateRoute
  3912. Routine Description:
  3913. This function unroutes the protocol given by usprotocoltype
  3914. from the bundle given by hbundlehandle.
  3915. Arguments:
  3916. pInputBuffer - Pointer to the input structure that should be NDISWAN_UNROUTE
  3917. ulInputBufferLength - Length of input buffer should be sizeof(NDISWAN_UNROUTE)
  3918. pOutputBuffer - Pointer to the output structure that should be NDISWAN_UNROUTE
  3919. ulOutputBufferLength - Length of output buffer should be sizeof(NDISWAN_UNROUTE)
  3920. pulBytesWritten - Then number of bytes written to the output buffer is returned here
  3921. Return Values:
  3922. NDISWAN_ERROR_ALREADY_ROUTED
  3923. NDISWAN_ERROR_INVALID_HANDLE
  3924. STATUS_INSUFFICIENT_RESOURCES
  3925. STATUS_INFO_LENGTH_MISMATCH
  3926. --*/
  3927. {
  3928. NTSTATUS Status = STATUS_SUCCESS;
  3929. PNDISWAN_UNROUTE In = (PNDISWAN_UNROUTE)pInputBuffer;
  3930. PNDISWAN_UNROUTE Out = (PNDISWAN_UNROUTE)pOutputBuffer;
  3931. ULONG SizeNeeded = sizeof(NDISWAN_UNROUTE);
  3932. ULONG AllocationSize, i;
  3933. PBUNDLECB BundleCB = NULL;
  3934. BOOLEAN RouteExists = FALSE;
  3935. BOOLEAN FreeBundle = FALSE;
  3936. PPROTOCOLCB ProtocolCB;
  3937. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("DeactivateRoute:"));
  3938. *pulBytesWritten = 0;
  3939. do {
  3940. if (ulInputBufferLength < SizeNeeded) {
  3941. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("DeactivateRoute: Buffer to small: Size: %d, SizeNeeded %d",
  3942. ulInputBufferLength, SizeNeeded));
  3943. *pulBytesWritten = SizeNeeded;
  3944. Status = STATUS_INFO_LENGTH_MISMATCH;
  3945. break;
  3946. }
  3947. if (!IsBundleValid(In->hBundleHandle, FALSE, &BundleCB)) {
  3948. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("DeactivateRoute: Invalid BundleHandle: 0x%x, ProtocolType: 0x%x",
  3949. In->hBundleHandle, In->usProtocolType));
  3950. Status = NDISWAN_ERROR_INVALID_HANDLE;
  3951. break;
  3952. }
  3953. //
  3954. // This is a call to unroute
  3955. //
  3956. AcquireBundleLock(BundleCB);
  3957. //
  3958. // Find the protocolcb for this route
  3959. //
  3960. //
  3961. for (ProtocolCB = (PPROTOCOLCB)BundleCB->ProtocolCBList.Flink;
  3962. (PVOID)ProtocolCB != (PVOID)&BundleCB->ProtocolCBList;
  3963. ProtocolCB = (PPROTOCOLCB)ProtocolCB->Linkage.Flink) {
  3964. //
  3965. // If we already have a route to this protocol type
  3966. // flag it as already existing
  3967. //
  3968. if (ProtocolCB->ProtocolType == In->usProtocolType) {
  3969. RouteExists = TRUE;
  3970. break;
  3971. }
  3972. }
  3973. if (!RouteExists) {
  3974. //
  3975. // A route already exists for this protocoltype
  3976. //
  3977. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("DeactivateRoute: Route does not exist: ProtocolType: 0x%2.2x",
  3978. In->usProtocolType));
  3979. Status = NDISWAN_ERROR_NOT_ROUTED;
  3980. break;
  3981. }
  3982. //
  3983. // If the protocol is already unrouting because
  3984. // of a halt on the protocols miniportcb we
  3985. // will just get the out!
  3986. //
  3987. if (ProtocolCB->State == PROTOCOL_UNROUTING) {
  3988. break;
  3989. }
  3990. ProtocolCB->State = PROTOCOL_UNROUTING;
  3991. BundleCB->SendMask &= ~ProtocolCB->SendMaskBit;
  3992. //
  3993. // Flush the protocol packet queues. This could cause us
  3994. // to complete frames to ndis out of order. Ndis should
  3995. // handle this.
  3996. //
  3997. FlushProtocolPacketQueue(ProtocolCB);
  3998. //
  3999. // If we have any outstanding Vc's we need to dispatch
  4000. // incoming close calls to them
  4001. //
  4002. while (!IsListEmpty(&ProtocolCB->VcList)) {
  4003. PLIST_ENTRY Entry;
  4004. PCM_VCCB CmVcCB;
  4005. Entry = RemoveHeadList(&ProtocolCB->VcList);
  4006. CmVcCB = (PCM_VCCB)CONTAINING_RECORD(Entry, CM_VCCB, Linkage);
  4007. if (CmVcCB->State == CMVC_ACTIVE) {
  4008. InterlockedExchange((PLONG)&CmVcCB->State, CMVC_CLOSE_DISPATCHED);
  4009. ReleaseBundleLock(BundleCB);
  4010. NdisCmDispatchIncomingCloseCall(NDIS_STATUS_SUCCESS,
  4011. CmVcCB->NdisVcHandle,
  4012. NULL,
  4013. 0);
  4014. AcquireBundleLock(BundleCB);
  4015. }
  4016. }
  4017. DEREF_PROTOCOLCB(ProtocolCB);
  4018. ReleaseBundleLock(BundleCB);
  4019. NdisWanWaitForSyncEvent(&ProtocolCB->UnrouteEvent);
  4020. AcquireBundleLock(BundleCB);
  4021. DoLineDownToProtocol(ProtocolCB);
  4022. NdisWanFreeProtocolCB(ProtocolCB);
  4023. } while ( 0 );
  4024. //
  4025. // Deref for ref applied by IsBundleValid
  4026. //
  4027. DEREF_BUNDLECB_LOCKED(BundleCB);
  4028. return (Status);
  4029. }
  4030. NTSTATUS
  4031. GetDriverInfo(
  4032. IN PUCHAR pInputBuffer,
  4033. IN ULONG ulInputBufferLength,
  4034. IN PUCHAR pOutputBuffer,
  4035. IN ULONG ulOutputBufferLength,
  4036. OUT PULONG pulBytesWritten
  4037. )
  4038. /*++
  4039. Routine Name:
  4040. Routine Description:
  4041. Arguments:
  4042. Return Values:
  4043. --*/
  4044. {
  4045. NTSTATUS Status = STATUS_SUCCESS;
  4046. ULONG SizeNeeded = sizeof(NDISWAN_DRIVER_INFO);
  4047. PNDISWAN_DRIVER_INFO Out = (PNDISWAN_DRIVER_INFO)pOutputBuffer;
  4048. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetDriverInfo:"));
  4049. *pulBytesWritten = SizeNeeded;
  4050. do {
  4051. if (ulOutputBufferLength < SizeNeeded) {
  4052. Status = STATUS_INFO_LENGTH_MISMATCH;
  4053. break;
  4054. }
  4055. NdisZeroMemory(Out, ulOutputBufferLength);
  4056. #ifdef ENCRYPT_128BIT
  4057. Out->DriverCaps = NDISWAN_128BIT_ENABLED;
  4058. #else
  4059. Out->DriverCaps = 0;
  4060. #endif
  4061. } while ( 0 );
  4062. return (Status);
  4063. }
  4064. NTSTATUS
  4065. SetProtocolEvent(
  4066. IN PUCHAR pInputBuffer,
  4067. IN ULONG ulInputBufferLength,
  4068. IN PUCHAR pOutputBuffer,
  4069. IN ULONG ulOutputBufferLength,
  4070. OUT PULONG pulBytesWritten
  4071. )
  4072. /*++
  4073. Routine Name:
  4074. Routine Description:
  4075. Arguments:
  4076. Return Values:
  4077. --*/
  4078. {
  4079. PIRP Irp = (PIRP)pInputBuffer;
  4080. NTSTATUS Status = STATUS_PENDING;
  4081. KIRQL Irql;
  4082. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  4083. do {
  4084. if ((ProtocolInfoTable->Flags & PROTOCOL_EVENT_OCCURRED) &&
  4085. !(ProtocolInfoTable->Flags & PROTOCOL_EVENT_SIGNALLED)) {
  4086. //
  4087. // An event occurred but we did not signal so
  4088. // signal now!
  4089. //
  4090. ProtocolInfoTable->Flags |= PROTOCOL_EVENT_SIGNALLED;
  4091. *pulBytesWritten = 0;
  4092. Status = STATUS_SUCCESS;
  4093. break;
  4094. }
  4095. if (ProtocolInfoTable->EventIrp != NULL) {
  4096. *pulBytesWritten = 0;
  4097. Status = STATUS_SUCCESS;
  4098. break;
  4099. }
  4100. ProtocolInfoTable->EventIrp = Irp;
  4101. IoMarkIrpPending(Irp);
  4102. IoSetCancelRoutine(Irp, NdisWanCancelRoutine);
  4103. Status = STATUS_PENDING;
  4104. } while (FALSE);
  4105. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  4106. return (Status);
  4107. }
  4108. NTSTATUS
  4109. GetProtocolEvent(
  4110. IN PUCHAR pInputBuffer,
  4111. IN ULONG ulInputBufferLength,
  4112. IN PUCHAR pOutputBuffer,
  4113. IN ULONG ulOutputBufferLength,
  4114. OUT PULONG pulBytesWritten
  4115. )
  4116. /*++
  4117. Routine Name:
  4118. Routine Description:
  4119. Arguments:
  4120. Return Values:
  4121. --*/
  4122. {
  4123. PNDISWAN_GET_PROTOCOL_EVENT Out =
  4124. (PNDISWAN_GET_PROTOCOL_EVENT)pOutputBuffer;
  4125. PPROTOCOL_INFO InfoArray;
  4126. ULONG ArraySize;
  4127. ULONG SizeNeeded = sizeof(NDISWAN_GET_PROTOCOL_EVENT);
  4128. NTSTATUS Status = STATUS_SUCCESS;
  4129. UINT i, j;
  4130. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetProtocolEvent:"));
  4131. *pulBytesWritten = 0;
  4132. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  4133. ArraySize = ProtocolInfoTable->ulArraySize;
  4134. do {
  4135. if (ulOutputBufferLength < SizeNeeded) {
  4136. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetProtocolEvent: Buffer to small: Size: %d, SizeNeeded %d",
  4137. ulInputBufferLength, SizeNeeded));
  4138. *pulBytesWritten = SizeNeeded;
  4139. Status = STATUS_INFO_LENGTH_MISMATCH;
  4140. break;
  4141. }
  4142. *pulBytesWritten = sizeof(NDISWAN_GET_PROTOCOL_EVENT);
  4143. NdisZeroMemory(Out, sizeof(NDISWAN_GET_PROTOCOL_EVENT));
  4144. j = 0;
  4145. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  4146. i < ArraySize;
  4147. i++, InfoArray++) {
  4148. if (InfoArray->Flags & PROTOCOL_EVENT_OCCURRED) {
  4149. PPROTOCOL_EVENT oevent = &Out->ProtocolEvent[j];
  4150. oevent->usProtocolType = InfoArray->ProtocolType;
  4151. if (InfoArray->Flags & PROTOCOL_REBOUND) {
  4152. //
  4153. // This means we were unbound and then
  4154. // bound again without our miniport being
  4155. // halted. We need to tell ras about two events,
  4156. // the unbind and the bind.
  4157. //
  4158. InfoArray->Flags &= ~(PROTOCOL_REBOUND |
  4159. PROTOCOL_EVENT_OCCURRED);
  4160. oevent->ulFlags = PROTOCOL_REMOVED;
  4161. Out->ulNumProtocols++;
  4162. j++;
  4163. if (j < MAX_PROTOCOLS) {
  4164. oevent = &Out->ProtocolEvent[j];
  4165. oevent->usProtocolType = InfoArray->ProtocolType;
  4166. oevent->ulFlags = PROTOCOL_ADDED;
  4167. Out->ulNumProtocols++;
  4168. j++;
  4169. }
  4170. } else {
  4171. oevent->ulFlags = (InfoArray->Flags & PROTOCOL_BOUND) ?
  4172. PROTOCOL_ADDED : PROTOCOL_REMOVED;
  4173. InfoArray->Flags &= ~PROTOCOL_EVENT_OCCURRED;
  4174. Out->ulNumProtocols++;
  4175. j++;
  4176. }
  4177. if (j == MAX_PROTOCOLS) {
  4178. break;
  4179. }
  4180. }
  4181. }
  4182. ProtocolInfoTable->Flags &=
  4183. ~(PROTOCOL_EVENT_OCCURRED | PROTOCOL_EVENT_SIGNALLED);
  4184. } while (FALSE);
  4185. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  4186. return (Status);
  4187. }
  4188. NTSTATUS
  4189. FlushProtocolEvent(
  4190. IN PUCHAR pInputBuffer,
  4191. IN ULONG ulInputBufferLength,
  4192. IN PUCHAR pOutputBuffer,
  4193. IN ULONG ulOutputBufferLength,
  4194. OUT PULONG pulBytesWritten
  4195. )
  4196. /*++
  4197. Routine Name:
  4198. Routine Description:
  4199. Arguments:
  4200. Return Values:
  4201. --*/
  4202. {
  4203. PIRP Irp;
  4204. KIRQL Irql;
  4205. *pulBytesWritten = 0;
  4206. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  4207. Irp = ProtocolInfoTable->EventIrp;
  4208. if ((Irp != NULL) &&
  4209. IoSetCancelRoutine(Irp, NULL)) {
  4210. ProtocolInfoTable->EventIrp = NULL;
  4211. Irp->Cancel = TRUE;
  4212. Irp->IoStatus.Status = STATUS_CANCELLED;
  4213. Irp->IoStatus.Information = 0;
  4214. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  4215. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  4216. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  4217. }
  4218. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  4219. return (STATUS_SUCCESS);
  4220. }
  4221. NTSTATUS
  4222. IoGetProtocolInfo(
  4223. IN PUCHAR pInputBuffer,
  4224. IN ULONG ulInputBufferLength,
  4225. IN PUCHAR pOutputBuffer,
  4226. IN ULONG ulOutputBufferLength,
  4227. OUT PULONG pulBytesWritten
  4228. )
  4229. /*++
  4230. Routine Name:
  4231. Routine Description:
  4232. Arguments:
  4233. Return Values:
  4234. --*/
  4235. {
  4236. NTSTATUS Status = STATUS_SUCCESS;
  4237. ULONG SizeNeeded = sizeof(NDISWAN_GET_PROTOCOL_INFO);
  4238. PNDISWAN_GET_PROTOCOL_INFO Out =
  4239. (PNDISWAN_GET_PROTOCOL_INFO)pOutputBuffer;
  4240. do {
  4241. ULONG i = 0;
  4242. ULONG j = 0;
  4243. PMINIPORTCB MiniportCB;
  4244. ULONG ArraySize;
  4245. PPROTOCOL_INFO InfoArray;
  4246. *pulBytesWritten = SizeNeeded;
  4247. if (ulOutputBufferLength < SizeNeeded) {
  4248. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("IoGetProtocolInfo: Buffer to small: Size: %d, SizeNeeded %d",
  4249. ulInputBufferLength, SizeNeeded));
  4250. Status = STATUS_INFO_LENGTH_MISMATCH;
  4251. break;
  4252. }
  4253. NdisAcquireSpinLock(&ProtocolInfoTable->Lock);
  4254. ArraySize = ProtocolInfoTable->ulArraySize;
  4255. for (i = 0, InfoArray = ProtocolInfoTable->ProtocolInfo;
  4256. i < ArraySize;
  4257. i++, InfoArray++) {
  4258. if (InfoArray->Flags & PROTOCOL_BOUND) {
  4259. Out->ProtocolInfo[j].ProtocolType = InfoArray->ProtocolType;
  4260. Out->ProtocolInfo[j].PPPId = InfoArray->PPPId;
  4261. Out->ProtocolInfo[j].MTU = InfoArray->MTU;
  4262. Out->ProtocolInfo[j].TunnelMTU = InfoArray->TunnelMTU;
  4263. Out->ProtocolInfo[j].PacketQueueDepth = InfoArray->PacketQueueDepth;
  4264. j++;
  4265. }
  4266. }
  4267. NdisReleaseSpinLock(&ProtocolInfoTable->Lock);
  4268. Out->ulNumProtocols = j;
  4269. } while (FALSE);
  4270. return (Status);
  4271. }
  4272. NTSTATUS
  4273. SetHibernateEvent(
  4274. IN PUCHAR pInputBuffer,
  4275. IN ULONG ulInputBufferLength,
  4276. IN PUCHAR pOutputBuffer,
  4277. IN ULONG ulOutputBufferLength,
  4278. OUT PULONG pulBytesWritten
  4279. )
  4280. /*++
  4281. Routine Name:
  4282. Routine Description:
  4283. Arguments:
  4284. Return Values:
  4285. --*/
  4286. {
  4287. PIRP Irp = (PIRP)pInputBuffer;
  4288. NTSTATUS Status = STATUS_PENDING;
  4289. KIRQL Irql;
  4290. NdisAcquireSpinLock(&NdisWanCB.Lock);
  4291. do {
  4292. if (NdisWanCB.HibernateEventIrp != NULL) {
  4293. *pulBytesWritten = 0;
  4294. Status = STATUS_SUCCESS;
  4295. break;
  4296. }
  4297. NdisWanCB.HibernateEventIrp = Irp;
  4298. IoMarkIrpPending(Irp);
  4299. IoSetCancelRoutine(Irp, NdisWanCancelRoutine);
  4300. Status = STATUS_PENDING;
  4301. } while (FALSE);
  4302. NdisReleaseSpinLock(&NdisWanCB.Lock);
  4303. return (Status);
  4304. }
  4305. NTSTATUS
  4306. FlushHibernateEvent(
  4307. IN PUCHAR pInputBuffer,
  4308. IN ULONG ulInputBufferLength,
  4309. IN PUCHAR pOutputBuffer,
  4310. IN ULONG ulOutputBufferLength,
  4311. OUT PULONG pulBytesWritten
  4312. )
  4313. /*++
  4314. Routine Name:
  4315. Routine Description:
  4316. Arguments:
  4317. Return Values:
  4318. --*/
  4319. {
  4320. PIRP Irp;
  4321. KIRQL Irql;
  4322. *pulBytesWritten = 0;
  4323. NdisAcquireSpinLock(&NdisWanCB.Lock);
  4324. Irp = NdisWanCB.HibernateEventIrp;
  4325. if ((Irp != NULL) &&
  4326. IoSetCancelRoutine(Irp, NULL)) {
  4327. NdisWanCB.HibernateEventIrp = NULL;
  4328. Irp->Cancel = TRUE;
  4329. Irp->IoStatus.Status = STATUS_CANCELLED;
  4330. Irp->IoStatus.Information = 0;
  4331. NdisReleaseSpinLock(&NdisWanCB.Lock);
  4332. IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
  4333. NdisAcquireSpinLock(&NdisWanCB.Lock);
  4334. }
  4335. NdisReleaseSpinLock(&NdisWanCB.Lock);
  4336. return (STATUS_SUCCESS);
  4337. }
  4338. NTSTATUS
  4339. GetBundleInfo(
  4340. IN PUCHAR pInputBuffer,
  4341. IN ULONG ulInputBufferLength,
  4342. IN PUCHAR pOutputBuffer,
  4343. IN ULONG ulOutputBufferLength,
  4344. OUT PULONG pulBytesWritten
  4345. )
  4346. /*++
  4347. Routine Name:
  4348. Routine Description:
  4349. Arguments:
  4350. Return Values:
  4351. --*/
  4352. {
  4353. ULONG SizeNeeded = sizeof(NDISWAN_GET_BUNDLE_INFO);
  4354. PNDISWAN_GET_BUNDLE_INFO In = (PNDISWAN_GET_BUNDLE_INFO)pInputBuffer;
  4355. PNDISWAN_GET_BUNDLE_INFO Out = (PNDISWAN_GET_BUNDLE_INFO)pOutputBuffer;
  4356. POPENCB OpenCB;
  4357. PBUNDLECB BundleCB = NULL;
  4358. NTSTATUS Status = STATUS_SUCCESS;
  4359. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("GetWanInfo:"));
  4360. *pulBytesWritten = SizeNeeded;
  4361. do {
  4362. if (ulInputBufferLength < SizeNeeded ||
  4363. ulOutputBufferLength < SizeNeeded) {
  4364. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetBundleInfo: Buffer to small: Size: %d, SizeNeeded %d",
  4365. ulOutputBufferLength, SizeNeeded));
  4366. Status = STATUS_INFO_LENGTH_MISMATCH;
  4367. break;
  4368. }
  4369. if (!IsBundleValid(In->hBundleHandle,
  4370. FALSE,
  4371. &BundleCB)) {
  4372. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("GetBundleInfo: Invalid Bundle Handle: 0x%x",
  4373. In->hBundleHandle));
  4374. *pulBytesWritten = 0;
  4375. Status = NDISWAN_ERROR_INVALID_HANDLE;
  4376. break;
  4377. }
  4378. AcquireBundleLock(BundleCB);
  4379. Out->BundleInfo.SendFramingBits =
  4380. BundleCB->FramingInfo.SendFramingBits;
  4381. Out->BundleInfo.SendBundleSpeed =
  4382. BundleCB->SFlowSpec.PeakBandwidth*8;
  4383. Out->BundleInfo.SendMSCompType =
  4384. BundleCB->SendCompInfo.MSCompType;
  4385. Out->BundleInfo.SendAuthType =
  4386. BundleCB->SendCompInfo.AuthType;
  4387. Out->BundleInfo.RecvFramingBits =
  4388. BundleCB->FramingInfo.RecvFramingBits;
  4389. Out->BundleInfo.RecvBundleSpeed =
  4390. BundleCB->RFlowSpec.PeakBandwidth*8;
  4391. Out->BundleInfo.RecvMSCompType =
  4392. BundleCB->RecvCompInfo.MSCompType;
  4393. Out->BundleInfo.RecvAuthType =
  4394. BundleCB->RecvCompInfo.AuthType;
  4395. } while ( 0 );
  4396. //
  4397. // Deref for ref applied by IsBundleValid. This releases
  4398. // the BundleCB->Lock
  4399. //
  4400. DEREF_BUNDLECB_LOCKED(BundleCB);
  4401. return (Status);
  4402. }
  4403. NTSTATUS
  4404. UnmapConnectionId(
  4405. IN PUCHAR pInputBuffer,
  4406. IN ULONG ulInputBufferLength,
  4407. IN PUCHAR pOutputBuffer,
  4408. IN ULONG ulOutputBufferLength,
  4409. OUT PULONG pulBytesWritten
  4410. )
  4411. /*++
  4412. Routine Name:
  4413. Routine Description:
  4414. Arguments:
  4415. Return Values:
  4416. --*/
  4417. {
  4418. ULONG SizeNeeded = sizeof(NDISWAN_UNMAP_CONNECTION_ID);
  4419. NTSTATUS Status = STATUS_SUCCESS;
  4420. LOCK_STATE LockState;
  4421. PNDISWAN_UNMAP_CONNECTION_ID In =
  4422. (PNDISWAN_UNMAP_CONNECTION_ID)pInputBuffer;
  4423. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("UnmapConnectionId:"));
  4424. *pulBytesWritten = 0;
  4425. do {
  4426. PLINKCB LinkCB = NULL;
  4427. if (ulInputBufferLength < SizeNeeded) {
  4428. NdisWanDbgOut(DBG_FAILURE, DBG_IO, ("UnmapConnectionId: Buffer to small: Size: %d, SizeNeeded %d",
  4429. ulInputBufferLength, SizeNeeded));
  4430. Status = STATUS_INFO_LENGTH_MISMATCH;
  4431. break;
  4432. }
  4433. //
  4434. // Validate the link handle
  4435. //
  4436. if (IsLinkValid(In->hLinkHandle, FALSE, &LinkCB)) {
  4437. NdisAcquireSpinLock(&LinkCB->Lock);
  4438. //
  4439. // Remove the ref applied to the link at mapconnectionid time.
  4440. // We don't have to use the full deref code as the ref applied
  4441. // in IsLinkValid will keep the link around.
  4442. //
  4443. LinkCB->RefCount--;
  4444. //
  4445. // Remove the ref applied by IsLinkValid
  4446. //
  4447. DEREF_LINKCB_LOCKED(LinkCB);
  4448. } else {
  4449. NdisWanDbgOut(DBG_FAILURE, DBG_IO,
  4450. ("UnmapConnectionId: Invalid LinkHandle %x",
  4451. In->hLinkHandle));
  4452. Status = NDISWAN_ERROR_INVALID_HANDLE;
  4453. break;
  4454. }
  4455. } while (FALSE);
  4456. NdisWanDbgOut(DBG_TRACE, DBG_IO, ("UnmapConnectionId:"));
  4457. return (Status);
  4458. }
  4459. VOID
  4460. CancelThresholdEvents(
  4461. VOID
  4462. )
  4463. /*++
  4464. Routine Name:
  4465. Routine Description:
  4466. Arguments:
  4467. Return Values:
  4468. --*/
  4469. {
  4470. #ifdef NT
  4471. KIRQL Irql;
  4472. PIRP pIrp;
  4473. PLIST_ENTRY Entry;
  4474. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  4475. while (!IsListEmpty(&ThresholdEventQueue.List)) {
  4476. Entry = RemoveHeadList(&ThresholdEventQueue.List);
  4477. ThresholdEventQueue.ulCount--;
  4478. pIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  4479. if (!IoSetCancelRoutine(pIrp, NULL)) {
  4480. //
  4481. // Irp is being canceled so let
  4482. // cancel routine handle it.
  4483. //
  4484. continue;
  4485. }
  4486. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  4487. pIrp->Cancel = TRUE;
  4488. pIrp->IoStatus.Status = STATUS_CANCELLED;
  4489. pIrp->IoStatus.Information = 0;
  4490. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  4491. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  4492. }
  4493. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  4494. #endif // End #ifdef NT
  4495. }
  4496. VOID
  4497. CancelIoReceivePackets(
  4498. VOID
  4499. )
  4500. /*++
  4501. Routine Name:
  4502. Routine Description:
  4503. Arguments:
  4504. Return Values:
  4505. --*/
  4506. {
  4507. #ifdef NT
  4508. PIRP pIrp;
  4509. PLIST_ENTRY Entry;
  4510. NdisAcquireSpinLock(&IoRecvList.Lock);
  4511. while (!IsListEmpty(&IoRecvList.IrpList)) {
  4512. Entry = RemoveHeadList(&IoRecvList.IrpList);
  4513. IoRecvList.ulIrpCount--;
  4514. INSERT_RECV_EVENT('c');
  4515. pIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  4516. if (!IoSetCancelRoutine(pIrp, NULL)) {
  4517. //
  4518. // Irp is being canceled so let
  4519. // cancel routine complete it
  4520. //
  4521. continue;
  4522. }
  4523. pIrp->Cancel = TRUE;
  4524. pIrp->IoStatus.Status = STATUS_CANCELLED;
  4525. pIrp->IoStatus.Information = sizeof(NDISWAN_IO_PACKET);
  4526. ((PNDISWAN_IO_PACKET)(pIrp->AssociatedIrp.SystemBuffer))->usHandleType = CANCELEDHANDLE;
  4527. IoRecvList.LastIrp = pIrp;
  4528. IoRecvList.LastIrpStatus = STATUS_CANCELLED;
  4529. IoRecvList.LastCopySize = (ULONG)pIrp->IoStatus.Information;
  4530. IoRecvList.LastPacketNumber =
  4531. ((PNDISWAN_IO_PACKET)(pIrp->AssociatedIrp.SystemBuffer))->PacketNumber;
  4532. NdisReleaseSpinLock(&IoRecvList.Lock);
  4533. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  4534. NdisAcquireSpinLock(&IoRecvList.Lock);
  4535. }
  4536. NdisReleaseSpinLock(&IoRecvList.Lock);
  4537. #endif // End #ifdef NT
  4538. }
  4539. VOID
  4540. AddProtocolCBToBundle(
  4541. PPROTOCOLCB ProtocolCB,
  4542. PBUNDLECB BundleCB
  4543. )
  4544. /*++
  4545. Routine Name:
  4546. AddProtocolCBToBundle
  4547. Routine Description:
  4548. This routine adds the protocolcb to the bundlecb protocollist and
  4549. protocoltable. It also assigns the protocolcb's handle (index into
  4550. the table) and set's the initial priority of all of the protocols
  4551. on the list.
  4552. Arguments:
  4553. ProtocolCB - Pointer to the protocol control block
  4554. BundleCB - Pointer to the bundle control block
  4555. Return Values:
  4556. None
  4557. --*/
  4558. {
  4559. ULONG i, InitialByteQuota;
  4560. ULONG InitialPriority;
  4561. AcquireBundleLock(BundleCB);
  4562. //
  4563. // Add to list
  4564. //
  4565. InsertTailList(&BundleCB->ProtocolCBList, &ProtocolCB->Linkage);
  4566. //
  4567. // Insert in table
  4568. //
  4569. ASSERT(BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] ==
  4570. (PPROTOCOLCB)RESERVED_PROTOCOLCB);
  4571. BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] =
  4572. ProtocolCB;
  4573. BundleCB->ulNumberOfRoutes++;
  4574. //
  4575. // Setup the send mask for this protocolcb
  4576. //
  4577. ProtocolCB->SendMaskBit = BundleCB->SendMask + 0x00000001;
  4578. BundleCB->SendMask = (BundleCB->SendMask << 1) | 0x00000001;
  4579. ProtocolCB->State = PROTOCOL_ROUTED;
  4580. if (BundleCB->NextProtocol == NULL) {
  4581. BundleCB->NextProtocol = ProtocolCB;
  4582. }
  4583. REF_BUNDLECB(BundleCB);
  4584. ReleaseBundleLock(BundleCB);
  4585. }
  4586. VOID
  4587. RemoveProtocolCBFromBundle(
  4588. PPROTOCOLCB ProtocolCB
  4589. )
  4590. {
  4591. PBUNDLECB BundleCB = ProtocolCB->BundleCB;
  4592. //
  4593. // If this protocolcb was not yet inserted in
  4594. // the table just return.
  4595. //
  4596. if (BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] !=
  4597. ProtocolCB) {
  4598. return;
  4599. }
  4600. RemoveEntryList(&ProtocolCB->Linkage);
  4601. BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] = NULL;
  4602. BundleCB->ulNumberOfRoutes--;
  4603. if (BundleCB->NextProtocol == ProtocolCB) {
  4604. BundleCB->NextProtocol =
  4605. (PPROTOCOLCB)ProtocolCB->Linkage.Flink;
  4606. if ((PVOID)BundleCB->NextProtocol ==
  4607. (PVOID)&BundleCB->ProtocolCBList) {
  4608. if (BundleCB->ulNumberOfRoutes != 0) {
  4609. //
  4610. // If we are back to the head of the list
  4611. // but there are still routes get the next.
  4612. //
  4613. BundleCB->NextProtocol =
  4614. (PPROTOCOLCB)BundleCB->ProtocolCBList.Flink;
  4615. } else {
  4616. //
  4617. // No more routes left...
  4618. //
  4619. BundleCB->NextProtocol = NULL;
  4620. }
  4621. }
  4622. }
  4623. //
  4624. // Deref for the ref applied when the protocolcb was
  4625. // added to the bundle. Don't need to do the entire
  4626. // bundlecb ref code here.
  4627. //
  4628. BundleCB->RefCount--;
  4629. }
  4630. VOID
  4631. SortProtocolListByPriority(
  4632. IN PBUNDLECB BundleCB
  4633. )
  4634. /*++
  4635. Routine Name:
  4636. Routine Description:
  4637. Arguments:
  4638. Return Values:
  4639. --*/
  4640. {
  4641. }
  4642. VOID
  4643. CompleteThresholdEvent(
  4644. PBUNDLECB BundleCB,
  4645. ULONG DataType,
  4646. ULONG ThresholdType
  4647. )
  4648. /*++
  4649. Routine Name:
  4650. Routine Description:
  4651. Arguments:
  4652. Return Values:
  4653. --*/
  4654. {
  4655. #ifdef NT
  4656. PLIST_ENTRY Entry;
  4657. PIRP pIrp;
  4658. PNDISWAN_SET_THRESHOLD_EVENT ThresholdEvent;
  4659. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  4660. if (IsListEmpty(&ThresholdEventQueue.List)) {
  4661. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  4662. return;
  4663. }
  4664. Entry = RemoveHeadList(&ThresholdEventQueue.List);
  4665. ThresholdEventQueue.ulCount--;
  4666. pIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
  4667. if (IoSetCancelRoutine(pIrp, NULL)) {
  4668. pIrp->IoStatus.Status = STATUS_SUCCESS;
  4669. pIrp->IoStatus.Information = sizeof(NDISWAN_SET_THRESHOLD_EVENT);
  4670. ThresholdEvent = (PNDISWAN_SET_THRESHOLD_EVENT)pIrp->AssociatedIrp.SystemBuffer;
  4671. ThresholdEvent->hBundleContext = BundleCB->hBundleContext;
  4672. ThresholdEvent->ulThreshold = ThresholdType;
  4673. ThresholdEvent->ulDataType = DataType;
  4674. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  4675. IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
  4676. NdisAcquireSpinLock(&ThresholdEventQueue.Lock);
  4677. }
  4678. NdisReleaseSpinLock(&ThresholdEventQueue.Lock);
  4679. #endif // End #ifdef NT
  4680. }
  4681. VOID
  4682. FlushProtocolPacketQueue(
  4683. PPROTOCOLCB ProtocolCB
  4684. )
  4685. {
  4686. ULONG Class;
  4687. PBUNDLECB BundleCB;
  4688. BundleCB = ProtocolCB->BundleCB;
  4689. for (Class = 0; Class <= MAX_MCML; Class++) {
  4690. PPACKET_QUEUE PacketQueue;
  4691. PacketQueue = &ProtocolCB->PacketQueue[Class];
  4692. while (!IsPacketQueueEmpty(PacketQueue)) {
  4693. PNDIS_PACKET NdisPacket;
  4694. NdisPacket =
  4695. RemoveHeadPacketQueue(PacketQueue);
  4696. ReleaseBundleLock(BundleCB);
  4697. //
  4698. // Complete the NdisPacket
  4699. //
  4700. CompleteNdisPacket(ProtocolCB->MiniportCB,
  4701. ProtocolCB,
  4702. NdisPacket);
  4703. AcquireBundleLock(BundleCB);
  4704. }
  4705. }
  4706. }
  4707. NDIS_HANDLE
  4708. AssignProtocolCBHandle(
  4709. PBUNDLECB BundleCB,
  4710. PPROTOCOLCB ProtocolCB
  4711. )
  4712. {
  4713. ULONG i;
  4714. //
  4715. // Find the first unused slot in the table
  4716. //
  4717. for (i = 0; i < MAX_PROTOCOLS; i++) {
  4718. if (BundleCB->ProtocolCBTable[i] == NULL) {
  4719. ProtocolCB->ProtocolHandle = (NDIS_HANDLE)ULongToPtr(i);
  4720. ProtocolCB->BundleCB = BundleCB;
  4721. BundleCB->ProtocolCBTable[i] = (PPROTOCOLCB)RESERVED_PROTOCOLCB;
  4722. break;
  4723. }
  4724. }
  4725. //
  4726. // If there is no room in the inn return
  4727. // i == MAX_PROTOCOLS which flags as an error.
  4728. //
  4729. return((NDIS_HANDLE)ULongToPtr(i));
  4730. }
  4731. VOID
  4732. FreeProtocolCBHandle(
  4733. PBUNDLECB BundleCB,
  4734. PPROTOCOLCB ProtocolCB
  4735. )
  4736. {
  4737. ASSERT(BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] ==
  4738. (PPROTOCOLCB)RESERVED_PROTOCOLCB);
  4739. ASSERT((ULONG_PTR)ProtocolCB->ProtocolHandle < MAX_PROTOCOLS);
  4740. BundleCB->ProtocolCBTable[(ULONG_PTR)ProtocolCB->ProtocolHandle] = NULL;
  4741. }
  4742. VOID
  4743. SetBundleFlags(
  4744. PBUNDLECB BundleCB
  4745. )
  4746. {
  4747. BundleCB->SendFlags = ((BundleCB->SendCompInfo.MSCompType & NDISWAN_COMPRESSION) &&
  4748. (BundleCB->SendCompressContext != NULL)) ? DO_COMPRESSION : 0;
  4749. BundleCB->SendFlags |=
  4750. (BundleCB->SendCompInfo.MSCompType & NDISWAN_HISTORY_LESS) ? DO_HISTORY_LESS : 0;
  4751. if (BundleCB->SendCryptoInfo.RC4Key != NULL) {
  4752. if (BundleCB->SendCompInfo.MSCompType & NDISWAN_ENCRYPTION) {
  4753. BundleCB->SendFlags |= (DO_ENCRYPTION | DO_LEGACY_ENCRYPTION);
  4754. } else if (BundleCB->SendCompInfo.MSCompType & NDISWAN_40_ENCRYPTION) {
  4755. BundleCB->SendFlags |= (DO_ENCRYPTION | DO_40_ENCRYPTION);
  4756. } else if (BundleCB->SendCompInfo.MSCompType & NDISWAN_56_ENCRYPTION) {
  4757. BundleCB->SendFlags |= (DO_ENCRYPTION | DO_56_ENCRYPTION);
  4758. }
  4759. #ifdef ENCRYPT_128BIT
  4760. else if (BundleCB->SendCompInfo.MSCompType & NDISWAN_128_ENCRYPTION) {
  4761. BundleCB->SendFlags |= (DO_ENCRYPTION | DO_128_ENCRYPTION);
  4762. }
  4763. #endif
  4764. }
  4765. BundleCB->SendFlags |=
  4766. (BundleCB->SendVJInfo.IPCompressionProtocol == 0x2D &&
  4767. BundleCB->VJCompress != NULL) ? DO_VJ : 0;
  4768. BundleCB->SendFlags |=
  4769. ((BundleCB->FramingInfo.SendFramingBits & PPP_MULTILINK_FRAMING) &&
  4770. ((BundleCB->ulLinkCBCount > 1) || (BundleCB->Flags & QOS_ENABLED))) ?
  4771. DO_MULTILINK : 0;
  4772. BundleCB->SendFlags |=
  4773. (BundleCB->FramingInfo.SendFramingBits & NBF_PRESERVE_MAC_ADDRESS) ?
  4774. SAVE_MAC_ADDRESS : 0;
  4775. BundleCB->RecvFlags = ((BundleCB->RecvCompInfo.MSCompType & NDISWAN_COMPRESSION) &&
  4776. (BundleCB->RecvCompressContext != NULL)) ? DO_COMPRESSION : 0;
  4777. BundleCB->RecvFlags |=
  4778. (BundleCB->RecvCompInfo.MSCompType & NDISWAN_HISTORY_LESS) ? DO_HISTORY_LESS : 0;
  4779. if (BundleCB->RecvCryptoInfo.RC4Key != NULL) {
  4780. if (BundleCB->RecvCompInfo.MSCompType & NDISWAN_ENCRYPTION) {
  4781. BundleCB->RecvFlags |= (DO_ENCRYPTION | DO_LEGACY_ENCRYPTION);
  4782. } else if (BundleCB->RecvCompInfo.MSCompType & NDISWAN_40_ENCRYPTION) {
  4783. BundleCB->RecvFlags |= (DO_ENCRYPTION | DO_40_ENCRYPTION);
  4784. } else if (BundleCB->RecvCompInfo.MSCompType & NDISWAN_56_ENCRYPTION) {
  4785. BundleCB->RecvFlags |= (DO_ENCRYPTION | DO_56_ENCRYPTION);
  4786. }
  4787. #ifdef ENCRYPT_128BIT
  4788. else if (BundleCB->RecvCompInfo.MSCompType & NDISWAN_128_ENCRYPTION) {
  4789. BundleCB->RecvFlags |= (DO_ENCRYPTION | DO_128_ENCRYPTION);
  4790. }
  4791. #endif
  4792. }
  4793. BundleCB->RecvFlags |=
  4794. (BundleCB->RecvVJInfo.IPCompressionProtocol == 0x2D &&
  4795. BundleCB->VJCompress != NULL) ? DO_VJ : 0;
  4796. BundleCB->RecvFlags |=
  4797. ((BundleCB->FramingInfo.RecvFramingBits & PPP_MULTILINK_FRAMING) &&
  4798. ((BundleCB->ulLinkCBCount > 1) || (BundleCB->Flags & QOS_ENABLED))) ?
  4799. DO_MULTILINK : 0;
  4800. BundleCB->RecvFlags |=
  4801. (BundleCB->FramingInfo.SendFramingBits & NBF_PRESERVE_MAC_ADDRESS) ?
  4802. SAVE_MAC_ADDRESS : 0;
  4803. }
  4804. NTSTATUS
  4805. NotImplemented(
  4806. IN PUCHAR pInputBuffer,
  4807. IN ULONG ulInputBufferLength,
  4808. IN PUCHAR pOutputBuffer,
  4809. IN ULONG ulOutputBufferLength,
  4810. OUT PULONG pulBytesWritten
  4811. )
  4812. /*++
  4813. Routine Name:
  4814. Routine Description:
  4815. Arguments:
  4816. Return Values:
  4817. --*/
  4818. {
  4819. return (STATUS_NOT_IMPLEMENTED);
  4820. }