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

1667 lines
40 KiB

  1. #include "ipxdefs.h"
  2. HANDLE FwdDriverHandle=NULL;
  3. HANDLE FltDriverHandle=NULL;
  4. DWORD FltTraceId;
  5. extern DWORD g_dwTraceId;
  6. #define FLT_LOG_BUFFER_SIZE 16384
  7. #define NUM_FILTER_LOG_ENTRIES 2
  8. typedef struct _FLT_LOG_ENTRY {
  9. OVERLAPPED ovlp;
  10. UCHAR buffer[FLT_LOG_BUFFER_SIZE];
  11. } FLT_LOG_ENTRY, *PFLT_LOG_ENTRY;
  12. FLT_LOG_ENTRY FltLogEntry [NUM_FILTER_LOG_ENTRIES];
  13. VOID WINAPI
  14. DumpFilterLog (
  15. DWORD error,
  16. DWORD cbCount,
  17. LPOVERLAPPED ovlp
  18. ) {
  19. BOOL res;
  20. PFLT_LOG_ENTRY pEntry = CONTAINING_RECORD (ovlp, FLT_LOG_ENTRY, ovlp);
  21. if (error==NO_ERROR) {
  22. PFLT_PACKET_LOG pLog = (PFLT_PACKET_LOG)pEntry->buffer;
  23. TracePuts (FltTraceId, TEXT (""));
  24. TracePrintfEx (FltTraceId,
  25. DBG_FLT_LOG_ERRORS|TRACE_USE_MASK|TRACE_NO_STDINFO,
  26. TEXT ("%d bytes returned in IRP buffer.\n"), cbCount);
  27. while (((PUCHAR)pLog->Header<=&pEntry->buffer[cbCount])
  28. && (&pLog->Header[pLog->DataSize]<=&pEntry->buffer[cbCount])) {
  29. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO,
  30. TEXT ("Packet # %d,"), pLog->SeqNum);
  31. if (pLog->SrcIfIdx!=-1)
  32. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO,
  33. TEXT (" received on interface: %d,"), pLog->SrcIfIdx);
  34. else
  35. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO,
  36. TEXT (" no source interface context,"));
  37. if (pLog->DstIfIdx!=-1)
  38. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO,
  39. TEXT (" sent on interface: %d."), pLog->DstIfIdx);
  40. else
  41. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO,
  42. TEXT (" no destination interface context."));
  43. TraceDumpEx (FltTraceId, TRACE_NO_STDINFO ,
  44. pLog->Header, pLog->DataSize, 1,
  45. FALSE, NULL);
  46. TracePrintfEx (FltTraceId, TRACE_NO_STDINFO, TEXT("\n"));
  47. pLog = (PFLT_PACKET_LOG)((ULONG_PTR)(&pLog->Header[pLog->DataSize]+3)&(~(ULONG_PTR)3));
  48. }
  49. }
  50. else {
  51. TracePrintfEx (FltTraceId, DBG_FLT_LOG_ERRORS|TRACE_USE_MASK,
  52. TEXT ("IOCTL_FLT_GET_LOGGED_PACKETS completed with error %d\n"),
  53. error);
  54. }
  55. if (FltDriverHandle!=NULL) {
  56. res = DeviceIoControl(
  57. FltDriverHandle,
  58. IOCTL_FLT_GET_LOGGED_PACKETS,
  59. NULL,
  60. 0,
  61. pEntry->buffer,
  62. sizeof (pEntry->buffer),
  63. NULL,
  64. &pEntry->ovlp);
  65. if (!res&&(GetLastError ()!=ERROR_IO_PENDING))
  66. TracePrintfEx (FltTraceId, DBG_FLT_LOG_ERRORS|TRACE_USE_MASK,
  67. TEXT ("DeviceIoControl failed with error %d"),
  68. GetLastError ());
  69. }
  70. }
  71. DWORD
  72. FwStart (
  73. ULONG RouteHashTableSize,
  74. BOOL ThisMachineOnly // allow access to this machine only
  75. // for dialin clients
  76. ) {
  77. SC_HANDLE ScMgrHandle;
  78. SC_HANDLE FwdServiceHandle, FltServiceHandle;
  79. DWORD error = NO_ERROR;
  80. BOOL bOk;
  81. ASSERT (FwdDriverHandle==NULL);
  82. ScMgrHandle = OpenSCManager (NULL, NULL, 0);
  83. if (ScMgrHandle!=NULL) {
  84. FwdServiceHandle = OpenService (ScMgrHandle,
  85. TEXT ("NwLnkFwd"),
  86. SERVICE_START|SERVICE_STOP);
  87. if (FwdServiceHandle!=NULL) {
  88. if (StartService (FwdServiceHandle, 0, NULL)
  89. || (GetLastError ()==ERROR_SERVICE_ALREADY_RUNNING)) {
  90. UNICODE_STRING FileString;
  91. OBJECT_ATTRIBUTES ObjectAttributes;
  92. IO_STATUS_BLOCK IoStatus;
  93. NTSTATUS status;
  94. RtlInitUnicodeString (&FileString, IPXFWD_NAME);
  95. InitializeObjectAttributes(
  96. &ObjectAttributes,
  97. &FileString,
  98. OBJ_CASE_INSENSITIVE,
  99. NULL,
  100. NULL);
  101. status = NtOpenFile(
  102. &FwdDriverHandle,
  103. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  104. &ObjectAttributes,
  105. &IoStatus,
  106. FILE_SHARE_READ | FILE_SHARE_WRITE,
  107. 0);
  108. if (NT_SUCCESS (status)) {
  109. FWD_START_PARAMS params;
  110. params.RouteHashTableSize = RouteHashTableSize;
  111. params.ThisMachineOnly = (UCHAR)ThisMachineOnly;
  112. status = NtDeviceIoControlFile(
  113. FwdDriverHandle,
  114. NULL,
  115. NULL,
  116. NULL,
  117. &IoStatus,
  118. IOCTL_FWD_START,
  119. &params,
  120. sizeof(params),
  121. NULL,
  122. 0);
  123. if (status==STATUS_PENDING){
  124. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  125. if (NT_SUCCESS (status))
  126. status = IoStatus.Status;
  127. }
  128. if (NT_SUCCESS(status)) {
  129. FltServiceHandle = OpenService (ScMgrHandle,
  130. TEXT ("NwLnkFlt"),
  131. SERVICE_START|SERVICE_STOP);
  132. if (FltServiceHandle!=NULL) {
  133. if (StartService (FltServiceHandle, 0, NULL)
  134. || (GetLastError ()==ERROR_SERVICE_ALREADY_RUNNING)) {
  135. UNICODE_STRING FileString;
  136. OBJECT_ATTRIBUTES ObjectAttributes;
  137. IO_STATUS_BLOCK IoStatus;
  138. NTSTATUS status;
  139. RtlInitUnicodeString (&FileString, IPXFLT_NAME);
  140. InitializeObjectAttributes(
  141. &ObjectAttributes,
  142. &FileString,
  143. OBJ_CASE_INSENSITIVE,
  144. NULL,
  145. NULL);
  146. status = NtOpenFile(
  147. &FltDriverHandle,
  148. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  149. &ObjectAttributes,
  150. &IoStatus,
  151. FILE_SHARE_READ | FILE_SHARE_WRITE,
  152. 0);
  153. if (NT_SUCCESS (status)) {
  154. status = NtDeviceIoControlFile(
  155. FltDriverHandle,
  156. NULL,
  157. NULL,
  158. NULL,
  159. &IoStatus,
  160. IOCTL_FLT_START,
  161. NULL,
  162. 0,
  163. NULL,
  164. 0);
  165. if (status==STATUS_PENDING){
  166. status = NtWaitForSingleObject (FltDriverHandle, FALSE, NULL);
  167. if (NT_SUCCESS (status))
  168. status = IoStatus.Status;
  169. }
  170. if (NT_SUCCESS (status)) {
  171. INT i;
  172. FltTraceId = TraceRegister (
  173. TEXT ("IPX Traffic Filter Logging"));
  174. error = NO_ERROR;
  175. bOk = BindIoCompletionCallback (
  176. FltDriverHandle,
  177. DumpFilterLog,
  178. 0);
  179. if (!bOk)
  180. {
  181. error = GetLastError();
  182. }
  183. ASSERTMSG ("Can't set io completion proc", error==NO_ERROR);
  184. for (i=0; i<NUM_FILTER_LOG_ENTRIES; i++) {
  185. BOOL res;
  186. FltLogEntry[i].ovlp.hEvent = NULL;
  187. res = DeviceIoControl(
  188. FltDriverHandle,
  189. IOCTL_FLT_GET_LOGGED_PACKETS,
  190. NULL,
  191. 0,
  192. FltLogEntry[i].buffer,
  193. sizeof (FltLogEntry[i].buffer),
  194. NULL,
  195. &FltLogEntry[i].ovlp);
  196. if (!res&&(GetLastError ()!=ERROR_IO_PENDING))
  197. TracePrintfEx (FltTraceId,
  198. DBG_FLT_LOG_ERRORS|TRACE_USE_MASK,
  199. TEXT ("DeviceIoControl failed with error %d"),
  200. GetLastError ());
  201. }
  202. SetLastError (NO_ERROR);
  203. }
  204. else {
  205. NtClose (FltDriverHandle);
  206. FltDriverHandle = NULL;
  207. error = RtlNtStatusToDosError (status);
  208. }
  209. }
  210. else
  211. error = RtlNtStatusToDosError (status);
  212. if (!NT_SUCCESS (status)) {
  213. SERVICE_STATUS serviceStatus;
  214. ControlService (FltServiceHandle,
  215. SERVICE_CONTROL_STOP,
  216. &serviceStatus);
  217. }
  218. }
  219. else
  220. error = GetLastError ();
  221. CloseServiceHandle (FltServiceHandle);
  222. }
  223. else
  224. error = GetLastError ();
  225. }
  226. else
  227. error = RtlNtStatusToDosError (status);
  228. if (!NT_SUCCESS (status)) {
  229. NtClose (FwdDriverHandle);
  230. FwdDriverHandle = NULL;
  231. }
  232. }
  233. else
  234. error = RtlNtStatusToDosError (status);
  235. if (!NT_SUCCESS (status)) {
  236. SERVICE_STATUS serviceStatus;
  237. ControlService (FwdServiceHandle,
  238. SERVICE_CONTROL_STOP,
  239. &serviceStatus);
  240. }
  241. }
  242. else
  243. error = GetLastError ();
  244. CloseServiceHandle (FwdServiceHandle);
  245. }
  246. else
  247. error = GetLastError ();
  248. CloseServiceHandle (ScMgrHandle);
  249. }
  250. else
  251. error = GetLastError ();
  252. SetLastError (error);
  253. return error;
  254. }
  255. //
  256. // Function: FwIsStarted
  257. //
  258. // Reports whether the forwarder has been started/is running.
  259. //
  260. //
  261. DWORD FwIsStarted (OUT PBOOL pbIsStarted) {
  262. SC_HANDLE hScMgr = NULL, hFwdService = NULL;
  263. SERVICE_STATUS ServiceStatus;
  264. DWORD dwErr = NO_ERROR;
  265. // Sanity check
  266. if (!pbIsStarted)
  267. return ERROR_INVALID_PARAMETER;
  268. // Get a reference to the service controller
  269. hScMgr = OpenSCManager (NULL, NULL, 0);
  270. if (hScMgr == NULL)
  271. return GetLastError();
  272. __try {
  273. // Get a handle to the service
  274. hFwdService = OpenService (hScMgr, TEXT ("NwLnkFwd"), SERVICE_QUERY_STATUS);
  275. if (hFwdService == NULL)
  276. return GetLastError();
  277. // Query the service ServiceStatus
  278. if (! QueryServiceStatus(hFwdService, &ServiceStatus))
  279. return GetLastError();
  280. // Return accordingly
  281. if (ServiceStatus.dwCurrentState == SERVICE_RUNNING ||
  282. ServiceStatus.dwCurrentState == SERVICE_START_PENDING ||
  283. ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING ||
  284. ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING ||
  285. ServiceStatus.dwCurrentState == SERVICE_PAUSED)
  286. *pbIsStarted = TRUE;
  287. else
  288. *pbIsStarted = FALSE;
  289. }
  290. __finally {
  291. if (hScMgr)
  292. CloseServiceHandle(hScMgr);
  293. if (hFwdService)
  294. CloseServiceHandle(hFwdService);
  295. }
  296. return NO_ERROR;
  297. }
  298. //
  299. // Returns whether the given state is a pending state
  300. //
  301. BOOL
  302. FwIsPendingState (
  303. IN DWORD dwState)
  304. {
  305. return (BOOL) ((dwState == SERVICE_START_PENDING) ||
  306. (dwState == SERVICE_STOP_PENDING) ||
  307. (dwState == SERVICE_CONTINUE_PENDING) ||
  308. (dwState == SERVICE_PAUSE_PENDING)
  309. );
  310. }
  311. // Stops the service referred by the opened hService
  312. // handle. It's assumed that the handle is opened for
  313. // stopping the service and querying its status.
  314. //
  315. DWORD
  316. FwStopService(
  317. IN HANDLE hService,
  318. IN DWORD dwSecsTimeout)
  319. {
  320. SERVICE_STATUS SStatus;
  321. DWORD dwState, dwErr, dwOrigTimeout = dwSecsTimeout;
  322. BOOL bOk;
  323. // Get the current status of the service
  324. if (! QueryServiceStatus(hService, &SStatus))
  325. {
  326. dwErr = GetLastError();
  327. TracePrintfEx (
  328. g_dwTraceId,
  329. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  330. TEXT ("QueryServiceStatus returned %d"),
  331. dwErr);
  332. return dwErr;
  333. }
  334. // If it's already stopped, we're done
  335. if (SStatus.dwCurrentState == SERVICE_STOPPED)
  336. return NO_ERROR;
  337. dwState = SStatus.dwCurrentState;
  338. // Tell the service to stop
  339. bOk = ControlService (
  340. hService,
  341. SERVICE_CONTROL_STOP,
  342. &SStatus);
  343. if (! bOk)
  344. {
  345. dwErr = GetLastError();
  346. TracePrintfEx (
  347. g_dwTraceId,
  348. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  349. TEXT ("ControlService(Stop) returned %d"),
  350. dwErr);
  351. return dwErr;
  352. }
  353. // Wait for the service to change states or for the timeout to
  354. // expire.
  355. dwSecsTimeout *= 4;
  356. while (dwSecsTimeout != 0) {
  357. // Get the status of the service
  358. bOk = QueryServiceStatus (
  359. hService,
  360. &SStatus);
  361. if (! bOk)
  362. {
  363. dwErr = GetLastError();
  364. TracePrintfEx (
  365. g_dwTraceId,
  366. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  367. TEXT ("QueryServiceStatus (2) returned %d"),
  368. dwErr);
  369. return dwErr;
  370. }
  371. // See if the state changed
  372. if (dwState != SStatus.dwCurrentState)
  373. {
  374. TracePrintfEx (
  375. g_dwTraceId,
  376. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  377. TEXT ("Service status changed from %d to %d"),
  378. dwState,
  379. SStatus.dwCurrentState);
  380. // If the service changed to a pending state, continue
  381. if (FwIsPendingState (SStatus.dwCurrentState))
  382. {
  383. dwState = SStatus.dwCurrentState;
  384. TracePrintfEx (
  385. g_dwTraceId,
  386. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  387. TEXT ("Pending state detected -- continuing to wait."));
  388. }
  389. // Otherwise, we're either stopped or running
  390. else
  391. {
  392. TracePrintfEx (
  393. g_dwTraceId,
  394. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  395. TEXT ("Non-Pending state detected -- waiting complete."));
  396. break;
  397. }
  398. }
  399. else
  400. {
  401. TracePrintfEx (
  402. g_dwTraceId,
  403. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  404. TEXT ("Service state hasn't changed from %d. Waiting..."),
  405. dwState);
  406. }
  407. // Wait for something to happen
  408. Sleep(250);
  409. dwSecsTimeout--;
  410. }
  411. // Return a timeout error if appropriate
  412. if (dwSecsTimeout == 0)
  413. {
  414. TracePrintfEx (
  415. g_dwTraceId,
  416. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  417. TEXT ("Timeout of %d seconds expired waiting for service to stop."),
  418. dwOrigTimeout);
  419. return ERROR_TIMEOUT;
  420. }
  421. // If the service is now stopped, then everything
  422. // worked great.
  423. if (SStatus.dwCurrentState == SERVICE_STOPPED)
  424. {
  425. TracePrintfEx (
  426. g_dwTraceId,
  427. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  428. TEXT ("Service stoppped successfully."));
  429. return NO_ERROR;
  430. }
  431. // Otherwise, return the fact that we were'nt able to
  432. // get to a running state
  433. if (SStatus.dwWin32ExitCode != NO_ERROR)
  434. {
  435. TracePrintfEx (
  436. g_dwTraceId,
  437. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  438. TEXT ("Service stop failed with code %d."),
  439. SStatus.dwWin32ExitCode);
  440. return SStatus.dwWin32ExitCode;
  441. }
  442. TracePrintfEx (
  443. g_dwTraceId,
  444. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  445. TEXT ("Service stop failed, no error reported."));
  446. return ERROR_CAN_NOT_COMPLETE;
  447. }
  448. DWORD
  449. FwStop (
  450. void
  451. ) {
  452. SC_HANDLE ScMgrHandle;
  453. SC_HANDLE FwdServiceHandle, FltServiceHandle;
  454. NTSTATUS status;
  455. DWORD dwErr;
  456. ASSERT (FwdDriverHandle!=NULL);
  457. ASSERT (FltDriverHandle!=NULL);
  458. // Close references to the filter and forwarder
  459. // drivers
  460. status = NtClose (FltDriverHandle);
  461. FltDriverHandle = NULL;
  462. status = NtClose (FwdDriverHandle);
  463. FwdDriverHandle = NULL;
  464. // Open the service controller
  465. ScMgrHandle = OpenSCManager (NULL, NULL, 0);
  466. if (ScMgrHandle!=NULL)
  467. {
  468. TracePrintfEx (
  469. g_dwTraceId,
  470. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  471. TEXT ("Stopping the filter driver..."));
  472. // Open the service handle to the
  473. // filter service
  474. //
  475. FltServiceHandle = OpenService (
  476. ScMgrHandle,
  477. "NwLnkFlt",
  478. SERVICE_STOP | SERVICE_QUERY_STATUS);
  479. // Stop the filter service
  480. if (FltServiceHandle != NULL)
  481. {
  482. dwErr = FwStopService(FltServiceHandle, 10);
  483. if (dwErr != NO_ERROR)
  484. {
  485. TracePrintfEx (
  486. g_dwTraceId,
  487. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  488. TEXT ("FwStopService returned %d"),
  489. dwErr);
  490. }
  491. CloseServiceHandle (FltServiceHandle);
  492. }
  493. else
  494. {
  495. TracePrintfEx (
  496. g_dwTraceId,
  497. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  498. TEXT ("Unable to open the filter driver service handle %d"),
  499. GetLastError());
  500. }
  501. // Open the service handle to the
  502. // fowarder driver
  503. //
  504. TracePrintfEx (
  505. g_dwTraceId,
  506. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  507. TEXT ("Stopping the forwarder driver..."));
  508. FwdServiceHandle = OpenService (
  509. ScMgrHandle,
  510. "NwLnkFwd",
  511. SERVICE_STOP | SERVICE_QUERY_STATUS);
  512. // Stop the forwarder driver
  513. //
  514. if (FwdServiceHandle != NULL)
  515. {
  516. dwErr = FwStopService(FwdServiceHandle, 10);
  517. if (dwErr != NO_ERROR)
  518. {
  519. TracePrintfEx (
  520. g_dwTraceId,
  521. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  522. TEXT ("FwStopService returned %d"),
  523. dwErr);
  524. }
  525. CloseServiceHandle (FwdServiceHandle);
  526. }
  527. else
  528. {
  529. TracePrintfEx (
  530. g_dwTraceId,
  531. DBG_FLT_LOG_ERRORS | TRACE_USE_MASK,
  532. TEXT ("Unable to open the forwarder driver service handle %d"),
  533. GetLastError());
  534. }
  535. CloseServiceHandle (ScMgrHandle);
  536. }
  537. TraceDeregister (FltTraceId);
  538. return NO_ERROR;
  539. }
  540. // Added for pnp resetting of forwarder's ThisMachineOnly
  541. // setting.
  542. DWORD
  543. FwUpdateConfig(BOOL ThisMachineOnly) {
  544. FWD_UPDATE_CONFIG_PARAMS Params;
  545. IO_STATUS_BLOCK IoStatus;
  546. NTSTATUS status;
  547. Params.bThisMachineOnly = (BOOLEAN)(!!ThisMachineOnly);
  548. // Send the ioctl
  549. status = NtDeviceIoControlFile(FwdDriverHandle,
  550. NULL,
  551. NULL,
  552. NULL,
  553. &IoStatus,
  554. IOCTL_FWD_UPDATE_CONFIG,
  555. &Params,
  556. sizeof (Params),
  557. NULL,
  558. 0);
  559. // Wait for completion
  560. if (status==STATUS_PENDING) {
  561. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  562. if (NT_SUCCESS (status))
  563. status = IoStatus.Status;
  564. }
  565. return RtlNtStatusToDosError (status);
  566. }
  567. VOID
  568. FwCleanup (
  569. void
  570. ) {
  571. if (FwdDriverHandle!=NULL)
  572. FwStop ();
  573. }
  574. DWORD
  575. FwCreateInterface (
  576. IN ULONG InterfaceIndex,
  577. IN NET_INTERFACE_TYPE InterfaceType,
  578. IN PFW_IF_INFO FwIfInfo
  579. ) {
  580. IO_STATUS_BLOCK IoStatus;
  581. NTSTATUS status;
  582. FWD_IF_CREATE_PARAMS params;
  583. ASSERT (FwdDriverHandle!=NULL);
  584. switch (InterfaceIndex) {
  585. case 0:
  586. params.Index = FWD_INTERNAL_INTERFACE_INDEX;
  587. break;
  588. default:
  589. params.Index = InterfaceIndex;
  590. break;
  591. }
  592. switch (InterfaceType) {
  593. case PERMANENT:
  594. params.InterfaceType = FWD_IF_PERMANENT;
  595. break;
  596. case DEMAND_DIAL:
  597. params.InterfaceType = FWD_IF_DEMAND_DIAL;
  598. break;
  599. case LOCAL_WORKSTATION_DIAL:
  600. params.InterfaceType = FWD_IF_LOCAL_WORKSTATION;
  601. break;
  602. case REMOTE_WORKSTATION_DIAL:
  603. params.InterfaceType = FWD_IF_REMOTE_WORKSTATION;
  604. break;
  605. default:
  606. ASSERTMSG ("Invalid interface type ", FALSE);
  607. }
  608. switch (FwIfInfo->NetbiosAccept) {
  609. case ADMIN_STATE_ENABLED:
  610. params.NetbiosAccept = TRUE;
  611. break;
  612. case ADMIN_STATE_DISABLED:
  613. params.NetbiosAccept = FALSE;
  614. break;
  615. default:
  616. ASSERTMSG ("Invalid netbios state ", FALSE);
  617. }
  618. switch (FwIfInfo->NetbiosDeliver) {
  619. case ADMIN_STATE_ENABLED:
  620. params.NetbiosDeliver = FWD_NB_DELIVER_ALL;
  621. break;
  622. case ADMIN_STATE_DISABLED:
  623. params.NetbiosDeliver = FWD_NB_DONT_DELIVER;
  624. break;
  625. case ADMIN_STATE_ENABLED_ONLY_FOR_NETBIOS_STATIC_ROUTING:
  626. params.NetbiosDeliver = FWD_NB_DELIVER_STATIC;
  627. break;
  628. case ADMIN_STATE_ENABLED_ONLY_FOR_OPER_STATE_UP:
  629. params.NetbiosDeliver = FWD_NB_DELIVER_IF_UP;
  630. break;
  631. default:
  632. ASSERTMSG ("Invalid netbios state ", FALSE);
  633. }
  634. status = NtDeviceIoControlFile(
  635. FwdDriverHandle,
  636. NULL,
  637. NULL,
  638. NULL,
  639. &IoStatus,
  640. IOCTL_FWD_CREATE_INTERFACE,
  641. &params,
  642. sizeof (params),
  643. NULL,
  644. 0);
  645. if (status==STATUS_PENDING){
  646. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  647. if (NT_SUCCESS (status))
  648. status = IoStatus.Status;
  649. }
  650. return RtlNtStatusToDosError (status);
  651. }
  652. DWORD
  653. FwDeleteInterface (
  654. IN ULONG InterfaceIndex
  655. ) {
  656. IO_STATUS_BLOCK IoStatus;
  657. NTSTATUS status;
  658. ULONG index;
  659. ASSERT (FwdDriverHandle!=NULL);
  660. switch (InterfaceIndex) {
  661. case 0:
  662. index = FWD_INTERNAL_INTERFACE_INDEX;
  663. break;
  664. default:
  665. index = InterfaceIndex;
  666. break;
  667. }
  668. status = NtDeviceIoControlFile(
  669. FwdDriverHandle,
  670. NULL,
  671. NULL,
  672. NULL,
  673. &IoStatus,
  674. IOCTL_FWD_DELETE_INTERFACE,
  675. &index,
  676. sizeof (index),
  677. NULL,
  678. 0);
  679. if (status==STATUS_PENDING){
  680. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  681. if (NT_SUCCESS (status))
  682. status = IoStatus.Status;
  683. }
  684. return RtlNtStatusToDosError (status);
  685. }
  686. DWORD
  687. FwSetInterface (
  688. IN ULONG InterfaceIndex,
  689. IN PFW_IF_INFO FwIfInfo
  690. ) {
  691. IO_STATUS_BLOCK IoStatus;
  692. NTSTATUS status;
  693. FWD_IF_SET_PARAMS params;
  694. ASSERT (FwdDriverHandle!=NULL);
  695. switch (InterfaceIndex) {
  696. case 0:
  697. params.Index = FWD_INTERNAL_INTERFACE_INDEX;
  698. break;
  699. default:
  700. params.Index = InterfaceIndex;
  701. break;
  702. }
  703. switch (FwIfInfo->NetbiosAccept) {
  704. case ADMIN_STATE_ENABLED:
  705. params.NetbiosAccept = TRUE;
  706. break;
  707. case ADMIN_STATE_DISABLED:
  708. params.NetbiosAccept = FALSE;
  709. break;
  710. default:
  711. ASSERTMSG ("Invalid netbios state ", FALSE);
  712. }
  713. switch (FwIfInfo->NetbiosDeliver) {
  714. case ADMIN_STATE_ENABLED:
  715. params.NetbiosDeliver = FWD_NB_DELIVER_ALL;
  716. break;
  717. case ADMIN_STATE_DISABLED:
  718. params.NetbiosDeliver = FWD_NB_DONT_DELIVER;
  719. break;
  720. case ADMIN_STATE_ENABLED_ONLY_FOR_NETBIOS_STATIC_ROUTING:
  721. params.NetbiosDeliver = FWD_NB_DELIVER_STATIC;
  722. break;
  723. case ADMIN_STATE_ENABLED_ONLY_FOR_OPER_STATE_UP:
  724. params.NetbiosDeliver = FWD_NB_DELIVER_IF_UP;
  725. break;
  726. default:
  727. ASSERTMSG ("Invalid netbios state ", FALSE);
  728. }
  729. status = NtDeviceIoControlFile(
  730. FwdDriverHandle,
  731. NULL,
  732. NULL,
  733. NULL,
  734. &IoStatus,
  735. IOCTL_FWD_SET_INTERFACE,
  736. &params,
  737. sizeof (params),
  738. NULL,
  739. 0);
  740. if (status==STATUS_PENDING){
  741. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  742. if (NT_SUCCESS (status))
  743. status = IoStatus.Status;
  744. }
  745. return RtlNtStatusToDosError (status);
  746. }
  747. DWORD
  748. FwGetInterface (
  749. IN ULONG InterfaceIndex,
  750. OUT PFW_IF_INFO FwIfInfo,
  751. OUT PFW_IF_STATS FwIfStats
  752. ) {
  753. IO_STATUS_BLOCK IoStatus;
  754. NTSTATUS status;
  755. union {
  756. FWD_IF_GET_PARAMS params;
  757. ULONG index;
  758. } iob;
  759. ASSERT (FwdDriverHandle!=NULL);
  760. switch (InterfaceIndex) {
  761. case 0:
  762. iob.index = FWD_INTERNAL_INTERFACE_INDEX;
  763. break;
  764. default:
  765. iob.index = InterfaceIndex;
  766. break;
  767. }
  768. status = NtDeviceIoControlFile(
  769. FwdDriverHandle,
  770. NULL,
  771. NULL,
  772. NULL,
  773. &IoStatus,
  774. IOCTL_FWD_GET_INTERFACE,
  775. &iob,
  776. sizeof (iob.index),
  777. &iob,
  778. sizeof (iob.params));
  779. if (status==STATUS_PENDING){
  780. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  781. if (NT_SUCCESS (status))
  782. status = IoStatus.Status;
  783. }
  784. if (NT_SUCCESS(status)) {
  785. if (iob.params.NetbiosAccept)
  786. FwIfInfo->NetbiosAccept = ADMIN_STATE_ENABLED;
  787. else
  788. FwIfInfo->NetbiosAccept = ADMIN_STATE_DISABLED;
  789. switch (iob.params.NetbiosDeliver) {
  790. case FWD_NB_DONT_DELIVER:
  791. FwIfInfo->NetbiosDeliver = ADMIN_STATE_DISABLED;
  792. break;
  793. case FWD_NB_DELIVER_STATIC:
  794. FwIfInfo->NetbiosDeliver = ADMIN_STATE_ENABLED_ONLY_FOR_NETBIOS_STATIC_ROUTING;
  795. break;
  796. case FWD_NB_DELIVER_IF_UP:
  797. FwIfInfo->NetbiosDeliver = ADMIN_STATE_ENABLED_ONLY_FOR_OPER_STATE_UP;
  798. break;
  799. case FWD_NB_DELIVER_ALL:
  800. FwIfInfo->NetbiosDeliver = ADMIN_STATE_ENABLED;
  801. break;
  802. default:
  803. ASSERTMSG ("Invalid NetbiosDeliver state ", FALSE);
  804. }
  805. switch (iob.params.Stats.OperationalState) {
  806. case FWD_OPER_STATE_UP:
  807. FwIfStats->IfOperState = OPER_STATE_UP;
  808. break;
  809. case FWD_OPER_STATE_DOWN:
  810. FwIfStats->IfOperState = OPER_STATE_DOWN;
  811. break;
  812. case FWD_OPER_STATE_SLEEPING:
  813. FwIfStats->IfOperState = OPER_STATE_SLEEPING;
  814. break;
  815. default:
  816. ASSERTMSG ("Invalid interface state ", FALSE);
  817. }
  818. FwIfStats->MaxPacketSize = iob.params.Stats.MaxPacketSize;
  819. FwIfStats->InHdrErrors = iob.params.Stats.InHdrErrors;
  820. FwIfStats->InFiltered = iob.params.Stats.InFiltered;
  821. FwIfStats->InNoRoutes = iob.params.Stats.InNoRoutes;
  822. FwIfStats->InDiscards = iob.params.Stats.InDiscards;
  823. FwIfStats->InDelivers = iob.params.Stats.InDelivers;
  824. FwIfStats->OutFiltered = iob.params.Stats.OutFiltered;
  825. FwIfStats->OutDiscards = iob.params.Stats.OutDiscards;
  826. FwIfStats->OutDelivers = iob.params.Stats.OutDelivers;
  827. FwIfStats->NetbiosReceived = iob.params.Stats.NetbiosReceived;
  828. FwIfStats->NetbiosSent = iob.params.Stats.NetbiosSent;
  829. return NO_ERROR;
  830. }
  831. return RtlNtStatusToDosError (status);
  832. }
  833. DWORD
  834. FwBindFwInterfaceToAdapter (
  835. IN ULONG InterfaceIndex,
  836. IN PIPX_ADAPTER_BINDING_INFO AdptBindingInfo
  837. ) {
  838. IO_STATUS_BLOCK IoStatus;
  839. NTSTATUS status;
  840. FWD_IF_BIND_PARAMS params;
  841. ASSERT (FwdDriverHandle!=NULL);
  842. switch (InterfaceIndex) {
  843. case 0:
  844. params.Index = FWD_INTERNAL_INTERFACE_INDEX;
  845. break;
  846. default:
  847. params.Index = InterfaceIndex;
  848. break;
  849. }
  850. params.Info.AdapterIndex = (ULONG)NicMapGetPhysicalNicId((USHORT)AdptBindingInfo->AdapterIndex);
  851. GETLONG2ULONG (&params.Info.Network, AdptBindingInfo->Network);
  852. IPX_NODENUM_CPY (&params.Info.LocalNode, AdptBindingInfo->LocalNode);
  853. IPX_NODENUM_CPY (params.Info.RemoteNode, AdptBindingInfo->RemoteNode);
  854. params.Info.MaxPacketSize = AdptBindingInfo->MaxPacketSize;
  855. params.Info.LinkSpeed = AdptBindingInfo->LinkSpeed;
  856. status = NtDeviceIoControlFile(
  857. FwdDriverHandle,
  858. NULL,
  859. NULL,
  860. NULL,
  861. &IoStatus,
  862. IOCTL_FWD_BIND_INTERFACE,
  863. &params,
  864. sizeof (params),
  865. NULL,
  866. 0);
  867. if (status==STATUS_PENDING){
  868. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  869. if (NT_SUCCESS (status))
  870. status = IoStatus.Status;
  871. }
  872. return RtlNtStatusToDosError (status);
  873. }
  874. //
  875. // Function FwRenumberNics
  876. //
  877. // Instructs the forwarder to increment or decrement all nicids above
  878. // the given threshold. This allows the forwarder to keep in sync with
  879. // nic-id compaction that occurs in the stack.
  880. //
  881. DWORD
  882. FwRenumberNics (DWORD dwOpCode,
  883. USHORT usThreshold)
  884. {
  885. IO_STATUS_BLOCK IoStatus;
  886. NTSTATUS status;
  887. FWD_RENUMBER_NICS_DATA FwRenumData;
  888. if (NULL == FwdDriverHandle)
  889. {
  890. return NO_ERROR;
  891. }
  892. // Assign the opcode
  893. if (dwOpCode == NIC_OPCODE_INCREMENT_NICIDS)
  894. FwRenumData.ulOpCode = FWD_NIC_OPCODE_INCREMENT;
  895. else if (dwOpCode == NIC_OPCODE_DECREMENT_NICIDS)
  896. FwRenumData.ulOpCode = FWD_NIC_OPCODE_DECREMENT;
  897. else
  898. return ERROR_INVALID_PARAMETER;
  899. // Assign the threshold
  900. FwRenumData.usThreshold = usThreshold;
  901. // Send the ioctl
  902. status = NtDeviceIoControlFile(FwdDriverHandle,
  903. NULL,
  904. NULL,
  905. NULL,
  906. &IoStatus,
  907. IOCTL_FWD_RENUMBER_NICS,
  908. &FwRenumData,
  909. sizeof (FwRenumData),
  910. NULL,
  911. 0);
  912. // Wait for completion (we might take this out)
  913. //if (status==STATUS_PENDING) {
  914. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  915. if (NT_SUCCESS (status))
  916. status = IoStatus.Status;
  917. //}
  918. return RtlNtStatusToDosError (status);
  919. }
  920. DWORD
  921. FwUnbindFwInterfaceFromAdapter (
  922. IN ULONG InterfaceIndex
  923. ) {
  924. IO_STATUS_BLOCK IoStatus;
  925. NTSTATUS status;
  926. ULONG index;
  927. ASSERT (FwdDriverHandle!=NULL);
  928. switch (InterfaceIndex) {
  929. case 0:
  930. index = FWD_INTERNAL_INTERFACE_INDEX;
  931. break;
  932. default:
  933. index = InterfaceIndex;
  934. break;
  935. }
  936. status = NtDeviceIoControlFile(
  937. FwdDriverHandle,
  938. NULL,
  939. NULL,
  940. NULL,
  941. &IoStatus,
  942. IOCTL_FWD_UNBIND_INTERFACE,
  943. &index,
  944. sizeof (index),
  945. NULL,
  946. 0);
  947. if (status==STATUS_PENDING){
  948. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  949. if (NT_SUCCESS (status))
  950. status = IoStatus.Status;
  951. }
  952. return RtlNtStatusToDosError (status);
  953. }
  954. DWORD
  955. FwDisableFwInterface (
  956. IN ULONG InterfaceIndex
  957. ) {
  958. IO_STATUS_BLOCK IoStatus;
  959. NTSTATUS status;
  960. ULONG index;
  961. ASSERT (FwdDriverHandle!=NULL);
  962. switch (InterfaceIndex) {
  963. case 0:
  964. index = FWD_INTERNAL_INTERFACE_INDEX;
  965. break;
  966. default:
  967. index = InterfaceIndex;
  968. break;
  969. }
  970. status = NtDeviceIoControlFile(
  971. FwdDriverHandle,
  972. NULL,
  973. NULL,
  974. NULL,
  975. &IoStatus,
  976. IOCTL_FWD_DISABLE_INTERFACE,
  977. &index,
  978. sizeof (index),
  979. NULL,
  980. 0);
  981. if (status==STATUS_PENDING){
  982. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  983. if (NT_SUCCESS (status))
  984. status = IoStatus.Status;
  985. }
  986. return RtlNtStatusToDosError (status);
  987. }
  988. DWORD
  989. FwEnableFwInterface (
  990. IN ULONG InterfaceIndex
  991. ) {
  992. IO_STATUS_BLOCK IoStatus;
  993. NTSTATUS status;
  994. ULONG index;
  995. ASSERT (FwdDriverHandle!=NULL);
  996. switch (InterfaceIndex) {
  997. case 0:
  998. index = FWD_INTERNAL_INTERFACE_INDEX;
  999. break;
  1000. default:
  1001. index = InterfaceIndex;
  1002. break;
  1003. }
  1004. status = NtDeviceIoControlFile(
  1005. FwdDriverHandle,
  1006. NULL,
  1007. NULL,
  1008. NULL,
  1009. &IoStatus,
  1010. IOCTL_FWD_ENABLE_INTERFACE,
  1011. &index,
  1012. sizeof (index),
  1013. NULL,
  1014. 0);
  1015. if (status==STATUS_PENDING){
  1016. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  1017. if (NT_SUCCESS (status))
  1018. status = IoStatus.Status;
  1019. }
  1020. return RtlNtStatusToDosError (status);
  1021. }
  1022. DWORD
  1023. FwConnectionRequestFailed (
  1024. IN ULONG InterfaceIndex
  1025. ) {
  1026. IO_STATUS_BLOCK IoStatus;
  1027. NTSTATUS status;
  1028. ULONG index;
  1029. ASSERT (FwdDriverHandle!=NULL);
  1030. switch (InterfaceIndex) {
  1031. case 0:
  1032. index = FWD_INTERNAL_INTERFACE_INDEX;
  1033. break;
  1034. default:
  1035. index = InterfaceIndex;
  1036. break;
  1037. }
  1038. status = NtDeviceIoControlFile(
  1039. FwdDriverHandle,
  1040. NULL,
  1041. NULL,
  1042. NULL,
  1043. &IoStatus,
  1044. IOCTL_FWD_DIAL_REQUEST_FAILED,
  1045. &index,
  1046. sizeof (index),
  1047. NULL,
  1048. 0);
  1049. if (status==STATUS_PENDING){
  1050. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  1051. if (NT_SUCCESS (status))
  1052. status = IoStatus.Status;
  1053. }
  1054. return RtlNtStatusToDosError (status);
  1055. }
  1056. DWORD
  1057. FwNotifyConnectionRequest (
  1058. OUT PFW_DIAL_REQUEST Request, // Buffer to be filled with interface index
  1059. //that requires connection plus packet
  1060. // that forced it
  1061. IN ULONG RequestSize, // Size of the buffer (must at least
  1062. // be sizeof (FW_DIAL_REQUEST)
  1063. IN LPOVERLAPPED lpOverlapped // structure for asyncrhronous
  1064. // operation, hEvent must be set
  1065. ) {
  1066. NTSTATUS status;
  1067. ASSERT (FwdDriverHandle!=NULL);
  1068. ASSERT (lpOverlapped->hEvent!=NULL);
  1069. ASSERT (FIELD_OFFSET (FW_DIAL_REQUEST, IfIndex)==FIELD_OFFSET (FWD_DIAL_REQUEST, IfIndex));
  1070. ASSERT (FIELD_OFFSET (FW_DIAL_REQUEST, Packet)==FIELD_OFFSET (FWD_DIAL_REQUEST, Packet));
  1071. if (RequestSize<sizeof (FWD_DIAL_REQUEST))
  1072. return ERROR_INVALID_PARAMETER;
  1073. status = NtDeviceIoControlFile (
  1074. FwdDriverHandle,
  1075. lpOverlapped->hEvent,
  1076. NULL,
  1077. NULL,
  1078. (PIO_STATUS_BLOCK)lpOverlapped,
  1079. IOCTL_FWD_GET_DIAL_REQUEST,
  1080. NULL,
  1081. 0,
  1082. Request,
  1083. RequestSize);
  1084. if (status==STATUS_PENDING)
  1085. return NO_ERROR;
  1086. else
  1087. return RtlNtStatusToDosError (status);
  1088. }
  1089. // Returns result of notification request. Should be called when
  1090. // the event set in the lpOverlapped structure is signalled.
  1091. //
  1092. DWORD
  1093. FwGetNotificationResult (
  1094. IN LPOVERLAPPED lpOverlapped,
  1095. OUT PULONG nBytes // Number of bytes placed into
  1096. // the request buffer
  1097. ) {
  1098. if (NT_SUCCESS(((PIO_STATUS_BLOCK)lpOverlapped)->Status)) {
  1099. *nBytes = (ULONG)((PIO_STATUS_BLOCK)lpOverlapped)->Information;
  1100. return NO_ERROR;
  1101. }
  1102. else
  1103. return RtlNtStatusToDosError (
  1104. ((PIO_STATUS_BLOCK)lpOverlapped)->Status);
  1105. }
  1106. VOID
  1107. FwUpdateRouteTable (
  1108. DWORD ChangeFlags,
  1109. PVOID CurRoute,
  1110. PVOID PrevRoute
  1111. ) {
  1112. #define IPXCurRoute ((PRTM_IPX_ROUTE)CurRoute)
  1113. #define IPXPrevRoute ((PRTM_IPX_ROUTE)PrevRoute)
  1114. IO_STATUS_BLOCK IoStatus;
  1115. NTSTATUS status;
  1116. FWD_ROUTE_SET_PARAMS params;
  1117. switch (ChangeFlags) {
  1118. case RTM_ROUTE_ADDED:
  1119. params.Action = FWD_ADD_ROUTE;
  1120. params.Network = IPXCurRoute->RR_Network.N_NetNumber;
  1121. IPX_NODENUM_CPY (params.NextHopAddress, IPXCurRoute->RR_NextHopAddress.NHA_Mac);
  1122. params.TickCount = IPXCurRoute->RR_FamilySpecificData.FSD_TickCount;
  1123. params.HopCount = IPXCurRoute->RR_FamilySpecificData.FSD_HopCount;
  1124. params.InterfaceIndex = IPXCurRoute->RR_InterfaceID;
  1125. break;
  1126. case RTM_ROUTE_DELETED:
  1127. params.Action = FWD_DELETE_ROUTE;
  1128. params.Network = IPXPrevRoute->RR_Network.N_NetNumber;
  1129. IPX_NODENUM_CPY (params.NextHopAddress, IPXPrevRoute->RR_NextHopAddress.NHA_Mac);
  1130. params.TickCount = IPXPrevRoute->RR_FamilySpecificData.FSD_TickCount;
  1131. params.HopCount = IPXPrevRoute->RR_FamilySpecificData.FSD_HopCount;
  1132. params.InterfaceIndex = IPXPrevRoute->RR_InterfaceID;
  1133. break;
  1134. case RTM_ROUTE_CHANGED:
  1135. if ((IPX_NODENUM_CMP (IPXPrevRoute->RR_NextHopAddress.NHA_Mac,
  1136. IPXCurRoute->RR_NextHopAddress.NHA_Mac)!=0)
  1137. || (IPXPrevRoute->RR_FamilySpecificData.FSD_TickCount
  1138. !=IPXCurRoute->RR_FamilySpecificData.FSD_TickCount)
  1139. || (IPXPrevRoute->RR_FamilySpecificData.FSD_HopCount
  1140. !=IPXCurRoute->RR_FamilySpecificData.FSD_HopCount)
  1141. || (IPXPrevRoute->RR_InterfaceID
  1142. !=IPXCurRoute->RR_InterfaceID)) {
  1143. params.Action = FWD_UPDATE_ROUTE;
  1144. params.Network = IPXCurRoute->RR_Network.N_NetNumber;
  1145. IPX_NODENUM_CPY (params.NextHopAddress, IPXCurRoute->RR_NextHopAddress.NHA_Mac);
  1146. params.TickCount = IPXCurRoute->RR_FamilySpecificData.FSD_TickCount;
  1147. params.HopCount = IPXCurRoute->RR_FamilySpecificData.FSD_HopCount;
  1148. params.InterfaceIndex = IPXCurRoute->RR_InterfaceID;
  1149. break;
  1150. }
  1151. else
  1152. return;
  1153. }
  1154. status = NtDeviceIoControlFile(
  1155. FwdDriverHandle,
  1156. NULL,
  1157. NULL,
  1158. NULL,
  1159. &IoStatus,
  1160. IOCTL_FWD_SET_ROUTES,
  1161. &params,
  1162. sizeof (params),
  1163. NULL,
  1164. 0);
  1165. if (status==STATUS_PENDING){
  1166. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  1167. if (NT_SUCCESS (status))
  1168. status = IoStatus.Status;
  1169. }
  1170. return;
  1171. #undef IPXPrevRoute
  1172. #undef IPXCurRoute
  1173. }
  1174. //
  1175. // Sets the netbios static routing information on this interface
  1176. //
  1177. DWORD
  1178. FwSetStaticNetbiosNames (
  1179. ULONG InterfaceIndex,
  1180. ULONG NetbiosNamesCount,
  1181. PIPX_STATIC_NETBIOS_NAME_INFO NetbiosNames
  1182. ) {
  1183. IO_STATUS_BLOCK IoStatus;
  1184. ULONG index;
  1185. NTSTATUS status;
  1186. ASSERT (FwdDriverHandle!=NULL);
  1187. switch (InterfaceIndex) {
  1188. case 0:
  1189. index = FWD_INTERNAL_INTERFACE_INDEX;
  1190. break;
  1191. default:
  1192. index = InterfaceIndex;
  1193. break;
  1194. }
  1195. if (NetbiosNamesCount>0) {
  1196. status = NtDeviceIoControlFile(
  1197. FwdDriverHandle,
  1198. NULL,
  1199. NULL,
  1200. NULL,
  1201. &IoStatus,
  1202. IOCTL_FWD_SET_NB_NAMES,
  1203. &index,
  1204. sizeof(index),
  1205. NetbiosNames,
  1206. NetbiosNamesCount
  1207. *sizeof(IPX_STATIC_NETBIOS_NAME_INFO)
  1208. );
  1209. }
  1210. else {
  1211. status = NtDeviceIoControlFile(
  1212. FwdDriverHandle,
  1213. NULL,
  1214. NULL,
  1215. NULL,
  1216. &IoStatus,
  1217. IOCTL_FWD_RESET_NB_NAMES,
  1218. &index,
  1219. sizeof(index),
  1220. NULL,
  1221. 0);
  1222. }
  1223. if (status==STATUS_PENDING) {
  1224. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  1225. if (NT_SUCCESS (status))
  1226. status = IoStatus.Status;
  1227. }
  1228. return RtlNtStatusToDosError (status);
  1229. }
  1230. //
  1231. // Gets the netbios static routing information on this interface
  1232. //
  1233. // If NetbiosNamesCount < nr of names or NetbiosName == NULL then set the
  1234. // correct value in NetbiosNamesCount and return ERROR_INSUFFICIENT_BUFFER
  1235. DWORD
  1236. FwGetStaticNetbiosNames (
  1237. ULONG InterfaceIndex,
  1238. PULONG NetbiosNamesCount,
  1239. PIPX_STATIC_NETBIOS_NAME_INFO NetbiosName
  1240. ) {
  1241. IO_STATUS_BLOCK IoStatus;
  1242. NTSTATUS status;
  1243. ULONG index;
  1244. ULONG bSize;
  1245. PFWD_NB_NAMES_PARAMS params=NULL;
  1246. // Local buffer for small amounts of data
  1247. UCHAR localBuf[FIELD_OFFSET (FWD_NB_NAMES_PARAMS,Names)];
  1248. switch (InterfaceIndex) {
  1249. case 0:
  1250. index = FWD_INTERNAL_INTERFACE_INDEX;
  1251. break;
  1252. default:
  1253. index = InterfaceIndex;
  1254. break;
  1255. }
  1256. bSize = FIELD_OFFSET (FWD_NB_NAMES_PARAMS,
  1257. Names[*NetbiosNamesCount]);
  1258. if (bSize<=sizeof (localBuf)) {
  1259. params = (PFWD_NB_NAMES_PARAMS)&localBuf;
  1260. }
  1261. else {
  1262. params = (PFWD_NB_NAMES_PARAMS)RtlAllocateHeap (
  1263. RtlProcessHeap (), 0,
  1264. bSize);
  1265. }
  1266. if (params!=NULL) {
  1267. status = NtDeviceIoControlFile(
  1268. FwdDriverHandle,
  1269. NULL,
  1270. NULL,
  1271. NULL,
  1272. &IoStatus,
  1273. IOCTL_FWD_GET_NB_NAMES,
  1274. &index,
  1275. sizeof (index),
  1276. params,
  1277. bSize);
  1278. if (status==STATUS_PENDING) {
  1279. status = NtWaitForSingleObject (FwdDriverHandle, FALSE, NULL);
  1280. if (NT_SUCCESS (status))
  1281. status = IoStatus.Status;
  1282. }
  1283. switch (status) {
  1284. case STATUS_SUCCESS:
  1285. case STATUS_BUFFER_OVERFLOW:
  1286. if (IoStatus.Information>FIELD_OFFSET (FWD_NB_NAMES_PARAMS,Names))
  1287. if (NetbiosName)
  1288. {
  1289. ULONG_PTR dwInfoSize, dwBufferSize;
  1290. dwInfoSize =
  1291. IoStatus.Information -
  1292. FIELD_OFFSET (FWD_NB_NAMES_PARAMS,Names);
  1293. dwBufferSize =
  1294. *NetbiosNamesCount * sizeof(IPX_STATIC_NETBIOS_NAME_INFO);
  1295. RtlCopyMemory (
  1296. NetbiosName,
  1297. &params->Names,
  1298. (dwInfoSize > dwBufferSize) ? dwBufferSize : dwInfoSize);
  1299. }
  1300. else if (status==STATUS_BUFFER_OVERFLOW)
  1301. status = STATUS_BUFFER_TOO_SMALL;
  1302. *NetbiosNamesCount = params->TotalCount;
  1303. break;
  1304. }
  1305. if (params!=(PFWD_NB_NAMES_PARAMS)localBuf)
  1306. RtlFreeHeap (RtlProcessHeap (), 0, params);
  1307. }
  1308. else
  1309. status = STATUS_INSUFFICIENT_RESOURCES;
  1310. return RtlNtStatusToDosError (status);
  1311. }
  1312. DWORD
  1313. SetFilters (
  1314. IN ULONG InterfaceIndex,
  1315. IN ULONG FilterMode, // inbound, outbound
  1316. IN ULONG FilterAction,
  1317. IN ULONG FilterSize,
  1318. IN LPVOID FilterInfo,
  1319. IN ULONG FilterInfoSize
  1320. ) {
  1321. IO_STATUS_BLOCK IoStatus;
  1322. FLT_IF_SET_PARAMS params;
  1323. NTSTATUS status;
  1324. ULONG code;
  1325. ASSERT (FltDriverHandle!=NULL);
  1326. switch (FilterMode) {
  1327. case IPX_TRAFFIC_FILTER_INBOUND:
  1328. if (FilterInfoSize>0)
  1329. code = IOCTL_FLT_IF_SET_IN_FILTERS;
  1330. else
  1331. code = IOCTL_FLT_IF_RESET_IN_FILTERS;
  1332. break;
  1333. case IPX_TRAFFIC_FILTER_OUTBOUND:
  1334. if (FilterInfoSize>0)
  1335. code = IOCTL_FLT_IF_SET_OUT_FILTERS;
  1336. else
  1337. code = IOCTL_FLT_IF_RESET_OUT_FILTERS;
  1338. break;
  1339. default:
  1340. ASSERTMSG ("Invalid filter mode ", FALSE);
  1341. return ERROR_INVALID_PARAMETER;
  1342. }
  1343. switch (InterfaceIndex) {
  1344. case 0:
  1345. params.InterfaceIndex = FWD_INTERNAL_INTERFACE_INDEX;
  1346. break;
  1347. default:
  1348. params.InterfaceIndex = InterfaceIndex;
  1349. break;
  1350. }
  1351. if (FilterInfoSize>0) {
  1352. params.FilterAction = FilterAction;
  1353. params.FilterSize = FilterSize;
  1354. status = NtDeviceIoControlFile(
  1355. FltDriverHandle,
  1356. NULL,
  1357. NULL,
  1358. NULL,
  1359. &IoStatus,
  1360. code,
  1361. &params,
  1362. sizeof(params),
  1363. FilterInfo,
  1364. FilterInfoSize
  1365. );
  1366. }
  1367. else {
  1368. status = NtDeviceIoControlFile(
  1369. FltDriverHandle,
  1370. NULL,
  1371. NULL,
  1372. NULL,
  1373. &IoStatus,
  1374. code,
  1375. &params.InterfaceIndex,
  1376. sizeof(params.InterfaceIndex),
  1377. NULL,
  1378. 0
  1379. );
  1380. }
  1381. if (status==STATUS_PENDING) {
  1382. status = NtWaitForSingleObject (FltDriverHandle, FALSE, NULL);
  1383. if (NT_SUCCESS (status))
  1384. status = IoStatus.Status;
  1385. }
  1386. return RtlNtStatusToDosError (status);
  1387. }
  1388. DWORD
  1389. GetFilters(IN ULONG InterfaceIndex,
  1390. IN ULONG FilterMode, // inbound, outbound
  1391. OUT PULONG FilterAction,
  1392. OUT PULONG FilterSize,
  1393. OUT LPVOID FilterInfo,
  1394. IN OUT PULONG FilterInfoSize) {
  1395. IO_STATUS_BLOCK IoStatus;
  1396. NTSTATUS status;
  1397. ULONG index;
  1398. ULONG code;
  1399. PFLT_IF_GET_PARAMS params=NULL;
  1400. ULONG bSize;
  1401. // Local buffer for small amounts of data
  1402. UCHAR localBuf[sizeof (FLT_IF_GET_PARAMS)];
  1403. switch (FilterMode) {
  1404. case IPX_TRAFFIC_FILTER_INBOUND:
  1405. code = IOCTL_FLT_IF_GET_IN_FILTERS;
  1406. break;
  1407. case IPX_TRAFFIC_FILTER_OUTBOUND:
  1408. code = IOCTL_FLT_IF_GET_OUT_FILTERS;
  1409. break;
  1410. default:
  1411. ASSERTMSG ("Invalid filter mode ", FALSE);
  1412. return ERROR_INVALID_PARAMETER;
  1413. }
  1414. switch (InterfaceIndex) {
  1415. case 0:
  1416. index = FWD_INTERNAL_INTERFACE_INDEX;
  1417. break;
  1418. default:
  1419. index = InterfaceIndex;
  1420. break;
  1421. }
  1422. bSize = sizeof (FLT_IF_GET_PARAMS)+*FilterInfoSize;
  1423. if (bSize<=sizeof (localBuf)) {
  1424. params = (PFLT_IF_GET_PARAMS)&localBuf;
  1425. }
  1426. else {
  1427. params = (PFLT_IF_GET_PARAMS)RtlAllocateHeap (
  1428. RtlProcessHeap (), 0,
  1429. bSize);
  1430. }
  1431. if (params!=NULL) {
  1432. status = NtDeviceIoControlFile(
  1433. FltDriverHandle,
  1434. NULL,
  1435. NULL,
  1436. NULL,
  1437. &IoStatus,
  1438. code,
  1439. &index,
  1440. sizeof (index),
  1441. params,
  1442. bSize);
  1443. if (status==STATUS_PENDING) {
  1444. status = NtWaitForSingleObject (FltDriverHandle, FALSE, NULL);
  1445. if (NT_SUCCESS (status))
  1446. status = IoStatus.Status;
  1447. }
  1448. switch (status) {
  1449. case STATUS_SUCCESS:
  1450. case STATUS_BUFFER_OVERFLOW:
  1451. if (FilterInfo && IoStatus.Information>=sizeof (FLT_IF_GET_PARAMS))
  1452. RtlCopyMemory (FilterInfo, &params[1],
  1453. IoStatus.Information
  1454. -sizeof (FLT_IF_GET_PARAMS));
  1455. else if (status==STATUS_BUFFER_OVERFLOW)
  1456. status = STATUS_BUFFER_TOO_SMALL;
  1457. *FilterInfoSize = params->TotalSize;
  1458. *FilterAction = params->FilterAction;
  1459. *FilterSize = params->FilterSize;
  1460. break;
  1461. default:
  1462. break;
  1463. }
  1464. if (params!=(PFLT_IF_GET_PARAMS)localBuf)
  1465. RtlFreeHeap (RtlProcessHeap (), 0, params);
  1466. }
  1467. else
  1468. status = STATUS_INSUFFICIENT_RESOURCES;
  1469. return RtlNtStatusToDosError (status);
  1470. }