Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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