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.

851 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: rpccfg.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. #include<nt.h>
  11. #include<ntrtl.h>
  12. #include<nturtl.h>
  13. #include<stdio.h>
  14. #include<string.h>
  15. #include<memory.h>
  16. #include<malloc.h>
  17. #include<stdlib.h>
  18. #include <windows.h>
  19. #include <winsock2.h>
  20. extern "C" {
  21. #include <iphlpapi.h>
  22. };
  23. void
  24. ListInterfaces()
  25. {
  26. PMIB_IFTABLE pMib;
  27. DWORD Size = 20*sizeof(MIB_IFROW)+sizeof(DWORD);
  28. unsigned int i;
  29. DWORD Status;
  30. for (i = 0; i < 2; i++)
  31. {
  32. pMib = (PMIB_IFTABLE) malloc(Size);
  33. if (pMib == 0)
  34. {
  35. return;
  36. }
  37. memset(pMib, 0, Size);
  38. Status = GetIfTable(pMib, &Size, 0);
  39. if (Status == 0)
  40. {
  41. break;
  42. }
  43. free(pMib);
  44. }
  45. if (Status != 0)
  46. {
  47. return;
  48. }
  49. for (i = 0; i < pMib->dwNumEntries; i++)
  50. {
  51. printf("IF[%d]: Ethernet: %s\n", ((pMib->table[i].dwIndex) & 0x00FFFFFF),
  52. (char *) pMib->table[i].bDescr);
  53. }
  54. }
  55. #define RPC_NIC_INDEXES "System\\CurrentControlSet\\Services\\Rpc\\Linkage"
  56. #define RPC_PORT_SETTINGS "Software\\Microsoft\\Rpc\\Internet"
  57. DWORD
  58. NextIndex(
  59. char **Ptr
  60. )
  61. {
  62. char *Index = *Ptr ;
  63. if (*Index == 0)
  64. {
  65. return -1;
  66. }
  67. while (**Ptr) (*Ptr)++ ;
  68. (*Ptr)++ ;
  69. return (DWORD) atoi(Index) ;
  70. }
  71. BOOL
  72. GetCardIndexTable (
  73. DWORD **IndexTable,
  74. DWORD *NumIndexes
  75. )
  76. {
  77. HKEY hKey;
  78. DWORD Size ;
  79. DWORD Type;
  80. char *Buffer;
  81. DWORD Status;
  82. Status =
  83. RegOpenKeyExA(
  84. HKEY_LOCAL_MACHINE,
  85. RPC_NIC_INDEXES,
  86. 0,
  87. KEY_READ,
  88. &hKey);
  89. if (Status == ERROR_FILE_NOT_FOUND)
  90. {
  91. *IndexTable = NULL;
  92. return TRUE;
  93. }
  94. if (Status != ERROR_SUCCESS)
  95. {
  96. return FALSE;
  97. }
  98. Size = 512 ;
  99. Buffer = (char *) malloc(Size) ;
  100. if (Buffer == 0)
  101. {
  102. return FALSE;
  103. }
  104. while(TRUE)
  105. {
  106. Status =
  107. RegQueryValueExA(
  108. hKey,
  109. "Bind",
  110. 0,
  111. &Type,
  112. (unsigned char *) Buffer,
  113. &Size);
  114. if (Status == ERROR_SUCCESS)
  115. {
  116. break;
  117. }
  118. if (Status == ERROR_MORE_DATA)
  119. {
  120. free(Buffer) ;
  121. Buffer = (char *) malloc(Size) ;
  122. if (Buffer == 0)
  123. {
  124. RegCloseKey(hKey);
  125. return FALSE ;
  126. }
  127. continue;
  128. }
  129. if (Status == ERROR_FILE_NOT_FOUND)
  130. {
  131. free(Buffer) ;
  132. *IndexTable = NULL;
  133. RegCloseKey(hKey);
  134. return TRUE;
  135. }
  136. free(Buffer) ;
  137. RegCloseKey(hKey);
  138. return FALSE;
  139. }
  140. if (*Buffer == 0)
  141. {
  142. RegCloseKey(hKey);
  143. return FALSE;
  144. }
  145. //
  146. // we know this much will be enough
  147. //
  148. *IndexTable = (DWORD *) malloc(Size * sizeof(DWORD));
  149. if (*IndexTable == 0)
  150. {
  151. RegCloseKey(hKey);
  152. return FALSE;
  153. }
  154. *NumIndexes = 0;
  155. int Index;
  156. while ((Index = NextIndex(&Buffer)) != -1)
  157. {
  158. (*IndexTable)[*NumIndexes] = Index;
  159. (*NumIndexes)++;
  160. }
  161. RegCloseKey(hKey);
  162. return TRUE;
  163. }
  164. void ResetState (
  165. )
  166. {
  167. DWORD Status;
  168. HKEY hKey;
  169. //
  170. // Reset interface state to default
  171. //
  172. Status =
  173. RegOpenKeyExA(
  174. HKEY_LOCAL_MACHINE,
  175. "System\\CurrentControlSet\\Services\\Rpc",
  176. 0,
  177. KEY_ALL_ACCESS,
  178. &hKey);
  179. if (Status == ERROR_FILE_NOT_FOUND)
  180. {
  181. printf("RPCCFG: State reset to default\n");
  182. return;
  183. }
  184. if (Status != ERROR_SUCCESS)
  185. {
  186. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  187. return;
  188. }
  189. Status = RegDeleteKeyA(hKey, "Linkage");
  190. if (Status != ERROR_SUCCESS)
  191. {
  192. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  193. RegCloseKey(hKey);
  194. return;
  195. }
  196. RegCloseKey(hKey);
  197. //
  198. // Reset Port state to default
  199. //
  200. Status =
  201. RegOpenKeyExA(
  202. HKEY_LOCAL_MACHINE,
  203. "Software\\Microsoft\\Rpc",
  204. 0,
  205. KEY_ALL_ACCESS,
  206. &hKey);
  207. if (Status == ERROR_FILE_NOT_FOUND)
  208. {
  209. printf("RPCCFG: State reset to default\n");
  210. return;
  211. }
  212. if (Status != ERROR_SUCCESS)
  213. {
  214. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  215. return;
  216. }
  217. Status = RegDeleteKeyA(hKey, "Internet");
  218. if (Status != ERROR_SUCCESS)
  219. {
  220. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  221. RegCloseKey(hKey);
  222. return;
  223. }
  224. RegCloseKey(hKey);
  225. printf("RPCCFG: State reset to default\n");
  226. }
  227. void
  228. ListCurrentInterfaces(
  229. )
  230. {
  231. DWORD *IndexTable;
  232. DWORD NumIndexes;
  233. DWORD Status;
  234. unsigned int i;
  235. if (GetCardIndexTable(&IndexTable, &NumIndexes) == FALSE)
  236. {
  237. printf("RPCCFG: Could not list the Interfaces\n");
  238. ResetState();
  239. return;
  240. }
  241. if (IndexTable == 0)
  242. {
  243. printf("RPCCFG: Listening on all interfaces (default configuration)\n");
  244. return;
  245. }
  246. printf("RPCCFG: Listening on the following interfaces\n");
  247. for (i = 0; i < NumIndexes; i++)
  248. {
  249. MIB_IFROW IfEntry;
  250. memset(&IfEntry, 0, sizeof(MIB_IFROW));
  251. //
  252. // Set the index in the row
  253. //
  254. IfEntry.dwIndex = IndexTable[i];
  255. Status = GetIfEntry(&IfEntry);
  256. if (Status != 0)
  257. {
  258. printf("RPCCFG: Could not list the Interfaces\n");
  259. break;
  260. }
  261. printf("IF[%d]: Ethernet: %s\n", IndexTable[i], (char *) IfEntry.bDescr);
  262. }
  263. }
  264. void
  265. ListenOnInterfaces (
  266. USHORT *IfIndices,
  267. USHORT Count
  268. )
  269. {
  270. int i;
  271. HKEY hKey;
  272. DWORD Status;
  273. DWORD disposition;
  274. Status =
  275. RegCreateKeyExA(
  276. HKEY_LOCAL_MACHINE,
  277. RPC_NIC_INDEXES,
  278. 0,
  279. "",
  280. REG_OPTION_NON_VOLATILE,
  281. KEY_ALL_ACCESS,
  282. NULL,
  283. &hKey,
  284. &disposition);
  285. if (Status != ERROR_SUCCESS)
  286. {
  287. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  288. return;
  289. }
  290. int cbIndices = 0;
  291. char *lpIndices = (char *) malloc(17*Count+1);
  292. if (lpIndices == 0)
  293. {
  294. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  295. return;
  296. }
  297. char *current = lpIndices;
  298. for (i = 0; i < Count; i++)
  299. {
  300. sprintf(current, "%d", IfIndices[i]);
  301. int length = strlen(current)+1;
  302. current += length;
  303. cbIndices += length;
  304. }
  305. *current = 0;
  306. cbIndices++;
  307. Status = RegSetValueExA(hKey,
  308. "Bind",
  309. 0,
  310. REG_MULTI_SZ,
  311. (unsigned char *) lpIndices,
  312. cbIndices);
  313. free(lpIndices);
  314. if (Status != ERROR_SUCCESS)
  315. {
  316. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  317. return;
  318. }
  319. }
  320. char *
  321. NextPortRange(
  322. char **Ptr
  323. )
  324. {
  325. char *Port = *Ptr ;
  326. if (*Port == 0)
  327. {
  328. return 0;
  329. }
  330. while (**Ptr) (*Ptr)++ ;
  331. (*Ptr)++ ;
  332. return Port ;
  333. }
  334. void
  335. ListCurrentPortSettings (
  336. )
  337. {
  338. HKEY hKey;
  339. DWORD Size ;
  340. DWORD Type;
  341. char *Buffer;
  342. DWORD Status;
  343. Status =
  344. RegOpenKeyExA(
  345. HKEY_LOCAL_MACHINE,
  346. RPC_PORT_SETTINGS,
  347. 0,
  348. KEY_READ,
  349. &hKey);
  350. if (Status == ERROR_FILE_NOT_FOUND)
  351. {
  352. printf("RPCCFG: Using default port settings\n", Status);
  353. return;
  354. }
  355. if (Status != ERROR_SUCCESS)
  356. {
  357. return;
  358. }
  359. Size = 2048;
  360. Buffer = (char *) malloc(Size) ;
  361. if (Buffer == 0)
  362. {
  363. RegCloseKey(hKey);
  364. return;
  365. }
  366. while(TRUE)
  367. {
  368. Status =
  369. RegQueryValueExA(
  370. hKey,
  371. "Ports",
  372. 0,
  373. &Type,
  374. (unsigned char *) Buffer,
  375. &Size);
  376. if (Status == ERROR_SUCCESS)
  377. {
  378. break;
  379. }
  380. if (Status == ERROR_MORE_DATA)
  381. {
  382. free(Buffer) ;
  383. Buffer = (char *) malloc(Size) ;
  384. if (Buffer == 0)
  385. {
  386. RegCloseKey(hKey);
  387. printf("RPCCFG: Could not perform operation, out of memory\n");
  388. return;
  389. }
  390. continue;
  391. }
  392. if (Status == ERROR_FILE_NOT_FOUND)
  393. {
  394. free(Buffer) ;
  395. printf("RPCCFG: Using default port settings\n", Status);
  396. RegCloseKey(hKey);
  397. return;
  398. }
  399. printf("RPCCFG: Could not perform operation\n");
  400. free(Buffer) ;
  401. RegCloseKey(hKey);
  402. return;
  403. }
  404. if (*Buffer == 0)
  405. {
  406. printf("RPCCFG: Bad settings\n");
  407. RegCloseKey(hKey);
  408. ResetState();
  409. return;
  410. }
  411. char *PortRange;
  412. char Flags[32];
  413. Size = 32;
  414. Status =
  415. RegQueryValueExA(
  416. hKey,
  417. "PortsInternetAvailable",
  418. 0,
  419. &Type,
  420. (unsigned char *) Flags,
  421. &Size);
  422. if (Status != ERROR_SUCCESS)
  423. {
  424. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  425. RegCloseKey(hKey);
  426. return;
  427. }
  428. printf("The following ports/port ranges will be used for ");
  429. if (Flags[0] == 'Y')
  430. {
  431. printf("Internet ports\n");
  432. }
  433. else
  434. {
  435. printf("Intranet ports\n");
  436. }
  437. while ((PortRange = NextPortRange(&Buffer)) != 0)
  438. {
  439. printf("\t%s\n", PortRange);
  440. }
  441. Size = 32;
  442. Status =
  443. RegQueryValueExA(
  444. hKey,
  445. "UseInternetPorts",
  446. 0,
  447. &Type,
  448. (unsigned char *) Flags,
  449. &Size);
  450. if (Status != ERROR_SUCCESS)
  451. {
  452. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  453. RegCloseKey(hKey);
  454. return;
  455. }
  456. printf("\nDefault port allocation is from ");
  457. if (Flags[0] == 'Y')
  458. {
  459. printf("Internet ports\n");
  460. }
  461. else
  462. {
  463. printf("Intranet ports\n");
  464. }
  465. RegCloseKey(hKey);
  466. }
  467. void
  468. SetPortRange(
  469. char **PortRangeTable,
  470. int NumEntries,
  471. char *InternetAvailable
  472. )
  473. {
  474. int i;
  475. DWORD Status;
  476. DWORD disposition;
  477. HKEY hKey;
  478. Status =
  479. RegCreateKeyExA(
  480. HKEY_LOCAL_MACHINE,
  481. RPC_PORT_SETTINGS,
  482. 0,
  483. "",
  484. REG_OPTION_NON_VOLATILE,
  485. KEY_ALL_ACCESS,
  486. NULL,
  487. &hKey,
  488. &disposition);
  489. if (Status != ERROR_SUCCESS)
  490. {
  491. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  492. return;
  493. }
  494. int cbPorts = 0;
  495. char *lpPorts = (char *) malloc(257*NumEntries+1);
  496. if (lpPorts == 0)
  497. {
  498. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  499. return;
  500. }
  501. char *current = lpPorts;
  502. for (i = 0; i < NumEntries; i++)
  503. {
  504. strcpy(current, PortRangeTable[i]);
  505. int length = strlen(current)+1;
  506. current += length;
  507. cbPorts += length;
  508. }
  509. *current = 0;
  510. cbPorts++;
  511. Status = RegSetValueExA(hKey,
  512. "Ports",
  513. 0,
  514. REG_MULTI_SZ,
  515. (unsigned char *) lpPorts,
  516. cbPorts);
  517. free(lpPorts);
  518. if (Status != ERROR_SUCCESS)
  519. {
  520. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  521. return;
  522. }
  523. Status = RegSetValueExA(hKey,
  524. "PortsInternetAvailable",
  525. 0,
  526. REG_SZ,
  527. (unsigned char *) InternetAvailable,
  528. strlen(InternetAvailable)+1);
  529. if (Status != ERROR_SUCCESS)
  530. {
  531. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  532. return;
  533. }
  534. }
  535. void
  536. SetDefaultPortSetting (
  537. char *PortSetting
  538. )
  539. {
  540. int i;
  541. HKEY hKey;
  542. DWORD Status;
  543. DWORD disposition;
  544. Status =
  545. RegCreateKeyExA(
  546. HKEY_LOCAL_MACHINE,
  547. RPC_PORT_SETTINGS,
  548. 0,
  549. "",
  550. REG_OPTION_NON_VOLATILE,
  551. KEY_ALL_ACCESS,
  552. NULL,
  553. &hKey,
  554. &disposition);
  555. if (Status != ERROR_SUCCESS)
  556. {
  557. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  558. return;
  559. }
  560. if (PortSetting[0] == '0')
  561. {
  562. PortSetting = "Y";
  563. }
  564. else
  565. {
  566. PortSetting = "N";
  567. }
  568. Status = RegSetValueExA(hKey,
  569. "UseInternetPorts",
  570. 0,
  571. REG_SZ,
  572. (unsigned char *) PortSetting,
  573. strlen(PortSetting)+1);
  574. if (Status != ERROR_SUCCESS)
  575. {
  576. printf("RPCCFG: Could not perform operation (%d)\n", Status);
  577. return;
  578. }
  579. RegCloseKey(hKey);
  580. }
  581. void
  582. Help (
  583. )
  584. {
  585. printf("usage: RPCCFG [-l] [-a ifindex1 [ifindex2 ...]] [-r] [-q] [-d 0|1] \n");
  586. printf(" [-pi port|port-range ...] [-pe port|port-range ...] \n");
  587. printf("\t-?: This help message\n");
  588. printf("\t-l: List all the interfaces\n");
  589. printf("\t-q: List the interface indices on which we are currently listening\n");
  590. printf("\t and our port usage settings\n");
  591. printf("\t-r: Reset the interface and port settings to default\n");
  592. printf("\t-a: Listen on the listed interface indices (eg: -a 1 3 5)\n");
  593. printf("\t this will cause RPC servers to listen on the listed interfaces\n");
  594. printf("\t by default. The interfaces listed are typically inside the firewall\n");
  595. printf("\t-pi:Specify the intranet available ports, the ports may be single\n");
  596. printf("\t values or ranges (eg: -pi 555 600-700 900), this option may not be\n");
  597. printf("\t used with the -pe option\n");
  598. printf("\t-pe:Specify the internet available ports, the ports may be single\n");
  599. printf("\t values or ranges this option may not be used with the -pi option\n");
  600. printf("\t-d: Specify the default port usage\n");
  601. printf("\t 0: Use internet available ports by default\n");
  602. printf("\t 1: Use intranet available ports by default\n");
  603. }
  604. void
  605. __cdecl main (int argc, char *argv[])
  606. {
  607. int argscan;
  608. USHORT IfIndices[512];
  609. char *PortRangeTable[512];
  610. int i;
  611. BOOL fPortChanged = 0;
  612. BOOL fInterfaceChanged = 0;
  613. if (argc == 1)
  614. {
  615. Help();
  616. }
  617. for (argscan = 1; argscan < argc;argscan++)
  618. {
  619. if (strcmp(argv[argscan], "-l") == 0)
  620. {
  621. ListInterfaces();
  622. }
  623. else if (strcmp(argv[argscan], "-?") == 0)
  624. {
  625. Help();
  626. }
  627. else if (strcmp(argv[argscan], "-r") == 0)
  628. {
  629. fPortChanged = 1;
  630. fInterfaceChanged = 1;
  631. ResetState();
  632. }
  633. else if (strcmp(argv[argscan], "-q") == 0)
  634. {
  635. ListCurrentInterfaces();
  636. printf("\n");
  637. ListCurrentPortSettings();
  638. }
  639. else if (strcmp(argv[argscan], "-a") == 0)
  640. {
  641. int count = 0;
  642. for (i = 0; i < 512; i++)
  643. {
  644. argscan++;
  645. if (argscan == argc)
  646. {
  647. break;
  648. }
  649. if (argv[argscan][0] == '-')
  650. {
  651. argscan--;
  652. break;
  653. }
  654. count++;
  655. IfIndices[i] = (USHORT)atoi(argv[argscan]);
  656. if (IfIndices[i] == 0)
  657. {
  658. printf("RPCCFG: Bad interface index\n");
  659. return;
  660. }
  661. }
  662. if (i == 512)
  663. {
  664. printf("RPCCFG: Too many interfaces\n");
  665. return;
  666. }
  667. if (count)
  668. {
  669. ListenOnInterfaces(IfIndices, (USHORT)count);
  670. fInterfaceChanged = 1;
  671. }
  672. }
  673. else if (strncmp(argv[argscan], "-p", 2) == 0)
  674. {
  675. int count = 0;
  676. char *option = argv[argscan];
  677. for (i = 0; i < 512; i++)
  678. {
  679. argscan++;
  680. if (argscan == argc)
  681. {
  682. break;
  683. }
  684. if (argv[argscan][0] == '-')
  685. {
  686. argscan--;
  687. break;
  688. }
  689. count++;
  690. PortRangeTable[i] = argv[argscan];
  691. }
  692. if (i == 512)
  693. {
  694. printf("RPCCFG: Too many ports\n");
  695. return;
  696. }
  697. if (strcmp(option, "-pi") == 0)
  698. {
  699. SetPortRange(PortRangeTable, count, "N");
  700. }
  701. else
  702. {
  703. SetPortRange(PortRangeTable, count, "Y");
  704. }
  705. fPortChanged = 1;
  706. }
  707. else if (strcmp(argv[argscan], "-d") == 0)
  708. {
  709. argscan++;
  710. if (argscan == argc)
  711. {
  712. break;
  713. }
  714. SetDefaultPortSetting(argv[argscan]);
  715. fPortChanged = 1;
  716. }
  717. }
  718. if (fInterfaceChanged)
  719. {
  720. ListCurrentInterfaces();
  721. printf("\n");
  722. }
  723. if (fPortChanged)
  724. {
  725. ListCurrentPortSettings();
  726. }
  727. }