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.

1471 lines
31 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. ws2inst.c
  5. Abstract:
  6. This is a temporary WinSock 2 transport & namespace service provider
  7. installation utility.
  8. The command line arguments for this utility are:
  9. ws2inst operation file.ini [options]
  10. Where operation is one of the following:
  11. install - Installs the service provider[s] specified in the
  12. .INI file.
  13. remove - Removes the service provider[s] specified in the .INI
  14. file.
  15. And options may be one or more of the following:
  16. -t - Install/remove transport provider only.
  17. -n - Install/remove namespace provider only.
  18. -b - Install/remove transport and namespace providers (default).
  19. -e - Ignore errors.
  20. The layout of the .INI file is:
  21. [WinSock 2 Transport Service Providers]
  22. ProviderCount = N
  23. Provider0 = Transport_Provider_0_Section_Name
  24. Provider1 = Transport_Provider_1_Section_Name
  25. Provider2 = Transport_Provider_2_Section_Name
  26. .
  27. .
  28. .
  29. ProviderN-1 = Transport_Provider_N-1_Section_Name
  30. [Transport_Provider_X_Section_Name]
  31. ProviderName = Provider_Name
  32. ProviderPath = Path_To_Providers_Dll
  33. ProviderId = Provider_Guid
  34. ProtocolCount = M
  35. [Transport_Provider_X_Section_Name Protocol M]
  36. dwServiceFlags1 = x
  37. dwServiceFlags2 = x
  38. dwServiceFlags3 = x
  39. dwServiceFlags4 = x
  40. dwProviderFlags = x
  41. iVersion = x
  42. iAddressFamily = x
  43. iMaxSockAddr = x
  44. iMinSockAddr = x
  45. iSocketType = x
  46. iProtocol = x
  47. iProtocolMaxOffset = x
  48. iNetworkByteOrder = x
  49. iSecurityScheme = x
  50. dwMessageSize = x
  51. dwProviderReserved = x
  52. szProtocol = Protocol_Name
  53. [WinSock 2 Name Space Providers]
  54. ProviderCount = N
  55. Provider0 = Name_Space_Provider_0_Section_Name
  56. Provider1 = Name_Space_Provider_1_Section_Name
  57. Provider2 = Name_Space_Provider_2_Section_Name
  58. .
  59. .
  60. .
  61. ProviderN-1 = Name_Space_Provider_N-1_Section_Name
  62. [Name_Space_Provider_X_Section_Name]
  63. ProviderName = Provider_Name
  64. ProviderPath = Path_To_Providers_DLL
  65. ProviderId = Provider_Guid
  66. NameSpaceId = Name_Space_ID
  67. Author:
  68. Keith Moore (keithmo) 17-Jun-1996
  69. Revision History:
  70. --*/
  71. #include "precomp.h"
  72. //
  73. // Private constants.
  74. //
  75. #define MAX_INIFILE_LINE 256
  76. #define TRANSPORT_SECTION_NAME TEXT("WinSock 2 Transport Service Providers")
  77. #define NAMESPACE_SECTION_NAME TEXT("WinSock 2 Name Space Providers")
  78. #define OPTION_FLAG_TRANSPORT 0x00000001
  79. #define OPTION_FLAG_NAMESPACE 0x00000002
  80. #define OPTION_FLAG_BOTH 0x00000003 // transport and namespace
  81. #define OPTION_FLAG_IGNORE_ERRORS 0x00000004
  82. //
  83. // Private types.
  84. //
  85. typedef
  86. BOOL
  87. (CALLBACK * LPFN_ENUM_SECTION_CALLBACK)(
  88. LPTSTR IniFile,
  89. LPTSTR ProviderSectionName,
  90. DWORD Context
  91. );
  92. //
  93. // Private prototypes.
  94. //
  95. VOID
  96. Usage(
  97. VOID
  98. );
  99. VOID
  100. InstallFromIniFile(
  101. LPTSTR IniFile,
  102. DWORD Options
  103. );
  104. VOID
  105. RemoveFromIniFile(
  106. LPTSTR IniFile,
  107. DWORD Options
  108. );
  109. VOID
  110. EnumProviderSections(
  111. LPTSTR IniFile,
  112. LPTSTR SectionName,
  113. LPFN_ENUM_SECTION_CALLBACK Callback,
  114. DWORD Context
  115. );
  116. BOOL
  117. InstallTransportProviderCallback(
  118. LPTSTR IniFile,
  119. LPTSTR SectionName,
  120. DWORD Context
  121. );
  122. BOOL
  123. RemoveTransportProviderCallback(
  124. LPTSTR IniFile,
  125. LPTSTR SectionName,
  126. DWORD Context
  127. );
  128. BOOL
  129. InstallNameSpaceProviderCallback(
  130. LPTSTR IniFile,
  131. LPTSTR SectionName,
  132. DWORD Context
  133. );
  134. BOOL
  135. RemoveNameSpaceProviderCallback(
  136. LPTSTR IniFile,
  137. LPTSTR SectionName,
  138. DWORD Context
  139. );
  140. //
  141. // Public functions.
  142. //
  143. INT
  144. __cdecl
  145. _tmain(
  146. INT argc,
  147. LPTSTR argv[]
  148. )
  149. /*++
  150. Routine Description:
  151. Main program entrypoint.
  152. Arguments:
  153. argc - Number of command line arguments.
  154. argv - Array of pointers to command line arguments.
  155. Return Value:
  156. INT - Completion status.
  157. --*/
  158. {
  159. LPTSTR opCode;
  160. LPTSTR iniFile;
  161. LPTSTR arg;
  162. DWORD options;
  163. INT i;
  164. //
  165. // Interpret the command line arguments.
  166. //
  167. if( argc < 3 ) {
  168. Usage();
  169. return 1;
  170. }
  171. opCode = argv[1];
  172. iniFile = argv[2];
  173. options = 0;
  174. for( i = 3 ; i < argc ; i++ ) {
  175. arg = argv[i];
  176. if( *arg != TEXT('-') ) {
  177. Usage();
  178. return 1;
  179. }
  180. arg++;
  181. while( *arg != TEXT('\0') ) {
  182. switch( *arg++ ) {
  183. case TEXT('t') :
  184. case TEXT('T') :
  185. options |= OPTION_FLAG_TRANSPORT;
  186. break;
  187. case TEXT('n') :
  188. case TEXT('N') :
  189. options |= OPTION_FLAG_NAMESPACE;
  190. break;
  191. case TEXT('b') :
  192. case TEXT('B') :
  193. options |= OPTION_FLAG_BOTH;
  194. break;
  195. case TEXT('e') :
  196. case TEXT('E') :
  197. options |= OPTION_FLAG_IGNORE_ERRORS;
  198. break;
  199. default :
  200. Usage();
  201. return 1;
  202. }
  203. }
  204. }
  205. //
  206. // Default == install transports and namespaces.
  207. //
  208. if( ( options & ( OPTION_FLAG_BOTH ) ) == 0 ) {
  209. options |= OPTION_FLAG_BOTH;
  210. }
  211. if( _tcsicmp( opCode, TEXT("install") ) == 0 ) {
  212. InstallFromIniFile(
  213. iniFile,
  214. options
  215. );
  216. } else if( _tcsicmp( opCode, TEXT("remove") ) == 0 ) {
  217. RemoveFromIniFile(
  218. iniFile,
  219. options
  220. );
  221. } else {
  222. Usage();
  223. return 1;
  224. }
  225. return 0;
  226. } // main
  227. //
  228. // Private functions.
  229. //
  230. VOID
  231. Usage(
  232. VOID
  233. )
  234. /*++
  235. Routine Description:
  236. Displays this utility's proper command line parameters.
  237. Arguments:
  238. None.
  239. Return Value:
  240. None.
  241. --*/
  242. {
  243. _ftprintf(
  244. stderr,
  245. TEXT("WS2INST 0.03 by Keith Moore %hs\n")
  246. TEXT("use: WS2INST Operation file.ini [Options]\n")
  247. TEXT("where Operation may be one of the following:\n")
  248. TEXT(" install - Installs service providers specified in .INI file\n")
  249. TEXT(" remove - Removes service providers specified in .INI file\n")
  250. TEXT("and Options may be one or more of the following:\n")
  251. TEXT(" -t - Install/remove transport providers only\n")
  252. TEXT(" -n - Install/remove namespace providers only\n")
  253. TEXT(" -b - Install/remove both (default)\n")
  254. TEXT(" -i - Ignore errors\n"),
  255. __DATE__
  256. );
  257. } // Usage
  258. VOID
  259. InstallFromIniFile(
  260. LPTSTR IniFile,
  261. DWORD Options
  262. )
  263. /*++
  264. Routine Description:
  265. Installs transports and/or namespace providers specified in the
  266. given .INI file.
  267. Arguments:
  268. IniFile - The .INI file describing the providers to install.
  269. Options - Behaviour control options (OPTION_FLAG_*).
  270. Return Value:
  271. None.
  272. --*/
  273. {
  274. //
  275. // Let the user know what we're up to.
  276. //
  277. _tprintf(
  278. TEXT("Installing from %s\n"),
  279. IniFile
  280. );
  281. //
  282. // Install transport providers if so requested.
  283. //
  284. if( Options & OPTION_FLAG_TRANSPORT ) {
  285. EnumProviderSections(
  286. IniFile,
  287. TRANSPORT_SECTION_NAME,
  288. InstallTransportProviderCallback,
  289. Options
  290. );
  291. }
  292. //
  293. // Install namespace providers if so requested.
  294. //
  295. if( Options & OPTION_FLAG_NAMESPACE ) {
  296. EnumProviderSections(
  297. IniFile,
  298. NAMESPACE_SECTION_NAME,
  299. InstallNameSpaceProviderCallback,
  300. Options
  301. );
  302. }
  303. } // InstallFromIniFile
  304. VOID
  305. RemoveFromIniFile(
  306. LPTSTR IniFile,
  307. DWORD Options
  308. )
  309. /*++
  310. Routine Description:
  311. Removes transports and/or namespace providers specified in the
  312. given .INI file.
  313. Arguments:
  314. IniFile - The .INI file describing the providers to remove.
  315. Options - Behaviour control options (OPTION_FLAG_*).
  316. Return Value:
  317. None.
  318. --*/
  319. {
  320. //
  321. // Let the user know what we're up to.
  322. //
  323. _tprintf(
  324. TEXT("Removing from %s\n"),
  325. IniFile
  326. );
  327. //
  328. // Remove transport providers if so requested.
  329. //
  330. if( Options & OPTION_FLAG_TRANSPORT ) {
  331. EnumProviderSections(
  332. IniFile,
  333. TRANSPORT_SECTION_NAME,
  334. RemoveTransportProviderCallback,
  335. Options
  336. );
  337. }
  338. //
  339. // Remove namespace providers if so requested.
  340. //
  341. if( Options & OPTION_FLAG_NAMESPACE ) {
  342. EnumProviderSections(
  343. IniFile,
  344. NAMESPACE_SECTION_NAME,
  345. RemoveNameSpaceProviderCallback,
  346. Options
  347. );
  348. }
  349. } // RemoveFromIniFile
  350. VOID
  351. EnumProviderSections(
  352. LPTSTR IniFile,
  353. LPTSTR SectionName,
  354. LPFN_ENUM_SECTION_CALLBACK Callback,
  355. DWORD Context
  356. )
  357. /*++
  358. Routine Description:
  359. Enumerates the provider sections in the specified .INI file. The
  360. sections must be in the following format:
  361. [section_name]
  362. ProviderCount=N
  363. Provider0=provider_0_name
  364. Provider1=provider_1_name
  365. Provider2=provider_2_name
  366. .
  367. .
  368. .
  369. ProviderN-1=provider_N-1_name
  370. Arguments:
  371. IniFile - The .INI file containing the sections to enumerate.
  372. SectionName - The name of the section to enumerate.
  373. Callback - Pointer to a callback routine. The callback is invoked
  374. once for each section. The prototype for the callback is:
  375. BOOL
  376. CALLBACK
  377. EnumSectionProc(
  378. LPTSTR IniFile,
  379. LPTSTR ProviderSectionName,
  380. DWORD Context
  381. );
  382. Where:
  383. IniFile - The .INI filename passed into EnumProviderSections().
  384. ProviderSectionName - The name of the current section.
  385. Context - The context value passed into EnumProviderSections().
  386. If the callback routine returns FALSE, then the enumeration is
  387. aborted. If the callback routine returns TRUE, then the enumeration
  388. is continued.
  389. Context - An uninterpreted context value passed to the callback function.
  390. Return Value:
  391. None.
  392. --*/
  393. {
  394. TCHAR providerSectionName[MAX_INIFILE_LINE];
  395. TCHAR keyName[MAX_INIFILE_LINE];
  396. DWORD length;
  397. UINT providerCount;
  398. UINT i;
  399. BOOL result;
  400. //
  401. // Get the provider count.
  402. //
  403. providerCount = GetPrivateProfileInt(
  404. SectionName,
  405. TEXT("ProviderCount"),
  406. 0,
  407. IniFile
  408. );
  409. if( providerCount == 0 ) {
  410. return;
  411. }
  412. //
  413. // Do that enumeration thang.
  414. //
  415. for( i = 0 ; i < providerCount ; i++ ) {
  416. wsprintf(
  417. keyName,
  418. TEXT("Provider%u"),
  419. i
  420. );
  421. length = GetPrivateProfileString(
  422. SectionName,
  423. keyName,
  424. TEXT(""),
  425. providerSectionName,
  426. sizeof(providerSectionName) / sizeof(providerSectionName[0]),
  427. IniFile
  428. );
  429. if( length > 0 ) {
  430. result = (Callback)(
  431. IniFile,
  432. providerSectionName,
  433. Context
  434. );
  435. if( !result ) {
  436. break;
  437. }
  438. }
  439. }
  440. } // EnumProviderSections
  441. BOOL
  442. InstallTransportProviderCallback(
  443. LPTSTR IniFile,
  444. LPTSTR SectionName,
  445. DWORD Context
  446. )
  447. /*++
  448. Routine Description:
  449. Callback routine for EnumProviderSections() that installs the
  450. transport service provider described by the given .INI file section.
  451. Arguments:
  452. IniFile - The name of the .INI file describing the transport provider.
  453. SectionName - The name of the .INI file section for this provider.
  454. Context - Actually contains behaviour control options (OPTION_FLAG_*).
  455. Return Value:
  456. BOOL - TRUE if successful, FALSE otherwise.
  457. --*/
  458. {
  459. TCHAR providerName[MAX_INIFILE_LINE];
  460. TCHAR providerPath[MAX_INIFILE_LINE];
  461. TCHAR providerIdString[MAX_INIFILE_LINE];
  462. TCHAR protocolSectionName[MAX_INIFILE_LINE];
  463. UINT protocolCount;
  464. UINT i;
  465. DWORD length;
  466. LPWSAPROTOCOL_INFO protocolInfo;
  467. INT result;
  468. INT error;
  469. GUID providerId;
  470. RPC_STATUS status;
  471. BOOL ignoreErrors;
  472. //
  473. // Let the user know what we're up to.
  474. //
  475. _tprintf(
  476. TEXT("Installing %s\n"),
  477. SectionName
  478. );
  479. //
  480. // Determine if we should ignore errors. If so, then this routine
  481. // will always return TRUE.
  482. //
  483. ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
  484. //
  485. // Read the fixed information.
  486. //
  487. length = GetPrivateProfileString(
  488. SectionName,
  489. TEXT("ProviderName"),
  490. TEXT(""),
  491. providerName,
  492. sizeof(providerName) / sizeof(providerName[0]),
  493. IniFile
  494. );
  495. if( length == 0 ) {
  496. _tprintf(
  497. TEXT("ERROR: missing ProviderName key\n")
  498. );
  499. return ignoreErrors;
  500. }
  501. length = GetPrivateProfileString(
  502. SectionName,
  503. TEXT("ProviderPath"),
  504. TEXT(""),
  505. providerPath,
  506. sizeof(providerPath) / sizeof(providerPath[0]),
  507. IniFile
  508. );
  509. if( length == 0 ) {
  510. _tprintf(
  511. TEXT("ERROR: missing ProviderPath key\n")
  512. );
  513. return ignoreErrors;
  514. }
  515. protocolCount = GetPrivateProfileInt(
  516. SectionName,
  517. TEXT("ProtocolCount"),
  518. 0,
  519. IniFile
  520. );
  521. if( protocolCount == 0 ) {
  522. _tprintf(
  523. TEXT("ERROR: missing ProtocolCount key\n")
  524. );
  525. return ignoreErrors;
  526. }
  527. length = GetPrivateProfileString(
  528. SectionName,
  529. TEXT("ProviderId"),
  530. TEXT(""),
  531. providerIdString,
  532. sizeof(providerIdString) / sizeof(providerIdString[0]),
  533. IniFile
  534. );
  535. if( length == 0 ) {
  536. _tprintf(
  537. TEXT("ERROR: missing ProviderId key\n")
  538. );
  539. return ignoreErrors;
  540. }
  541. //
  542. // Build the GUID.
  543. //
  544. status = UuidFromString(
  545. providerIdString,
  546. &providerId
  547. );
  548. if( status != RPC_S_OK ) {
  549. _tprintf(
  550. TEXT("ERROR: invalid ProviderId %s\n"),
  551. providerIdString
  552. );
  553. return ignoreErrors;
  554. }
  555. //
  556. // Allocate the space for the protocol info structures.
  557. //
  558. protocolInfo = malloc( protocolCount * sizeof(*protocolInfo) );
  559. if( protocolInfo == NULL ) {
  560. _tprintf(
  561. TEXT("ERROR: out of memory\n")
  562. );
  563. return ignoreErrors;
  564. }
  565. //
  566. // Enumerate the protocols.
  567. //
  568. for( i = 0 ; i < protocolCount ; i++ ) {
  569. //
  570. // Build the section name for this protocol.
  571. //
  572. wsprintf(
  573. protocolSectionName,
  574. TEXT("%s Protocol %u"),
  575. SectionName,
  576. i
  577. );
  578. //
  579. // Read the individual protocol info.
  580. //
  581. protocolInfo[i].dwServiceFlags1 = (DWORD)GetPrivateProfileInt(
  582. protocolSectionName,
  583. TEXT("dwServiceFlags1"),
  584. 0,
  585. IniFile
  586. );
  587. protocolInfo[i].dwServiceFlags2 = (DWORD)GetPrivateProfileInt(
  588. protocolSectionName,
  589. TEXT("dwServiceFlags2"),
  590. 0,
  591. IniFile
  592. );
  593. protocolInfo[i].dwServiceFlags3 = (DWORD)GetPrivateProfileInt(
  594. protocolSectionName,
  595. TEXT("dwServiceFlags3"),
  596. 0,
  597. IniFile
  598. );
  599. protocolInfo[i].dwServiceFlags4 = (DWORD)GetPrivateProfileInt(
  600. protocolSectionName,
  601. TEXT("dwServiceFlags4"),
  602. 0,
  603. IniFile
  604. );
  605. protocolInfo[i].dwProviderFlags = (DWORD)GetPrivateProfileInt(
  606. protocolSectionName,
  607. TEXT("dwProviderFlags"),
  608. 0,
  609. IniFile
  610. );
  611. protocolInfo[i].iVersion = (DWORD)GetPrivateProfileInt(
  612. protocolSectionName,
  613. TEXT("iVersion"),
  614. 0,
  615. IniFile
  616. );
  617. protocolInfo[i].iAddressFamily = (DWORD)GetPrivateProfileInt(
  618. protocolSectionName,
  619. TEXT("iAddressFamily"),
  620. 0,
  621. IniFile
  622. );
  623. protocolInfo[i].iMaxSockAddr = (DWORD)GetPrivateProfileInt(
  624. protocolSectionName,
  625. TEXT("iMaxSockAddr"),
  626. 0,
  627. IniFile
  628. );
  629. protocolInfo[i].iMinSockAddr = (DWORD)GetPrivateProfileInt(
  630. protocolSectionName,
  631. TEXT("iMinSockAddr"),
  632. 0,
  633. IniFile
  634. );
  635. protocolInfo[i].iSocketType = (DWORD)GetPrivateProfileInt(
  636. protocolSectionName,
  637. TEXT("iSocketType"),
  638. 0,
  639. IniFile
  640. );
  641. protocolInfo[i].iProtocol = (DWORD)GetPrivateProfileInt(
  642. protocolSectionName,
  643. TEXT("iProtocol"),
  644. 0,
  645. IniFile
  646. );
  647. protocolInfo[i].iProtocolMaxOffset = (DWORD)GetPrivateProfileInt(
  648. protocolSectionName,
  649. TEXT("iProtocolMaxOffset"),
  650. 0,
  651. IniFile
  652. );
  653. protocolInfo[i].iNetworkByteOrder = (DWORD)GetPrivateProfileInt(
  654. protocolSectionName,
  655. TEXT("iNetworkByteOrder"),
  656. 0,
  657. IniFile
  658. );
  659. protocolInfo[i].iSecurityScheme = (DWORD)GetPrivateProfileInt(
  660. protocolSectionName,
  661. TEXT("iSecurityScheme"),
  662. 0,
  663. IniFile
  664. );
  665. protocolInfo[i].dwMessageSize = (DWORD)GetPrivateProfileInt(
  666. protocolSectionName,
  667. TEXT("dwMessageSize"),
  668. 0,
  669. IniFile
  670. );
  671. protocolInfo[i].dwProviderReserved = (DWORD)GetPrivateProfileInt(
  672. protocolSectionName,
  673. TEXT("dwProviderReserved"),
  674. 0,
  675. IniFile
  676. );
  677. length = GetPrivateProfileString(
  678. protocolSectionName,
  679. TEXT("szProtocol"),
  680. TEXT(""),
  681. protocolInfo[i].szProtocol,
  682. sizeof(protocolInfo[i].szProtocol) / sizeof(protocolInfo[i].szProtocol[0]),
  683. IniFile
  684. );
  685. if( length == 0 ) {
  686. _tprintf(
  687. TEXT("ERROR: missing szProtocol key\n")
  688. );
  689. free( protocolInfo );
  690. return ignoreErrors;
  691. }
  692. }
  693. //
  694. // OK, we've got the protocol data, now just ask WS2_32.DLL to
  695. // install 'em.
  696. //
  697. result = WSCInstallProvider(
  698. &providerId,
  699. providerPath,
  700. protocolInfo,
  701. (DWORD)protocolCount,
  702. &error
  703. );
  704. free( protocolInfo );
  705. if( result == SOCKET_ERROR ) {
  706. _tprintf(
  707. TEXT("Cannot install %s, error %d\n"),
  708. providerName,
  709. error
  710. );
  711. return ignoreErrors;
  712. }
  713. return TRUE;
  714. } // InstallTransportProviderCallback
  715. BOOL
  716. RemoveTransportProviderCallback(
  717. LPTSTR IniFile,
  718. LPTSTR SectionName,
  719. DWORD Context
  720. )
  721. /*++
  722. Routine Description:
  723. Callback routine for EnumProviderSections() that removes the
  724. transport service provider described by the given .INI file section.
  725. Arguments:
  726. IniFile - The name of the .INI file describing the transport provider.
  727. SectionName - The name of the .INI file section for this provider.
  728. Context - Actually contains behaviour control options (OPTION_FLAG_*).
  729. Return Value:
  730. BOOL - TRUE if successful, FALSE otherwise.
  731. --*/
  732. {
  733. TCHAR providerName[MAX_INIFILE_LINE];
  734. TCHAR providerIdString[MAX_INIFILE_LINE];
  735. DWORD length;
  736. INT result;
  737. INT error;
  738. GUID providerId;
  739. RPC_STATUS status;
  740. BOOL ignoreErrors;
  741. //
  742. // Let the user know what we're up to.
  743. //
  744. _tprintf(
  745. TEXT("Removing %s\n"),
  746. SectionName
  747. );
  748. //
  749. // Determine if we should ignore errors. If so, then this routine
  750. // will always return TRUE.
  751. //
  752. ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
  753. //
  754. // Read the provider name & ID.
  755. //
  756. length = GetPrivateProfileString(
  757. SectionName,
  758. TEXT("ProviderName"),
  759. TEXT(""),
  760. providerName,
  761. sizeof(providerName) / sizeof(providerName[0]),
  762. IniFile
  763. );
  764. if( length == 0 ) {
  765. _tprintf(
  766. TEXT("ERROR: missing ProviderName key\n")
  767. );
  768. return ignoreErrors;
  769. }
  770. length = GetPrivateProfileString(
  771. SectionName,
  772. TEXT("ProviderId"),
  773. TEXT(""),
  774. providerIdString,
  775. sizeof(providerIdString) / sizeof(providerIdString[0]),
  776. IniFile
  777. );
  778. if( length == 0 ) {
  779. _tprintf(
  780. TEXT("ERROR: missing ProviderId key\n")
  781. );
  782. return ignoreErrors;
  783. }
  784. //
  785. // Build the GUID.
  786. //
  787. status = UuidFromString(
  788. providerIdString,
  789. &providerId
  790. );
  791. if( status != RPC_S_OK ) {
  792. _tprintf(
  793. TEXT("ERROR: invalid ProviderId %s\n"),
  794. providerIdString
  795. );
  796. return ignoreErrors;
  797. }
  798. //
  799. // Remove it.
  800. //
  801. result = WSCDeinstallProvider(
  802. &providerId,
  803. &error
  804. );
  805. if( result == SOCKET_ERROR ) {
  806. _tprintf(
  807. TEXT("Cannot remove %s, error %d\n"),
  808. providerName,
  809. error
  810. );
  811. return ignoreErrors;
  812. }
  813. return TRUE;
  814. } // RemoveTransportProviderCallback
  815. BOOL
  816. InstallNameSpaceProviderCallback(
  817. LPTSTR IniFile,
  818. LPTSTR SectionName,
  819. DWORD Context
  820. )
  821. /*++
  822. Routine Description:
  823. Callback routine for EnumProviderSections() that installs the
  824. namespace service provider described by the given .INI file section.
  825. Arguments:
  826. IniFile - The name of the .INI file describing the namespace provider.
  827. SectionName - The name of the .INI file section for this provider.
  828. Context - Actually contains behaviour control options (OPTION_FLAG_*).
  829. Return Value:
  830. BOOL - TRUE if successful, FALSE otherwise.
  831. --*/
  832. {
  833. TCHAR providerName[MAX_INIFILE_LINE];
  834. TCHAR providerPath[MAX_INIFILE_LINE];
  835. TCHAR providerIdString[MAX_INIFILE_LINE];
  836. UINT i;
  837. DWORD length;
  838. INT result;
  839. INT error;
  840. GUID providerId;
  841. DWORD nameSpaceId;
  842. RPC_STATUS status;
  843. BOOL ignoreErrors;
  844. //
  845. // Let the user know what we're up to.
  846. //
  847. _tprintf(
  848. TEXT("Installing %s\n"),
  849. SectionName
  850. );
  851. //
  852. // Determine if we should ignore errors. If so, then this routine
  853. // will always return TRUE.
  854. //
  855. ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
  856. //
  857. // Read the fixed information.
  858. //
  859. length = GetPrivateProfileString(
  860. SectionName,
  861. TEXT("ProviderName"),
  862. TEXT(""),
  863. providerName,
  864. sizeof(providerName) / sizeof(providerName[0]),
  865. IniFile
  866. );
  867. if( length == 0 ) {
  868. _tprintf(
  869. TEXT("ERROR: missing ProviderName key\n")
  870. );
  871. return ignoreErrors;
  872. }
  873. length = GetPrivateProfileString(
  874. SectionName,
  875. TEXT("ProviderPath"),
  876. TEXT(""),
  877. providerPath,
  878. sizeof(providerPath) / sizeof(providerPath[0]),
  879. IniFile
  880. );
  881. if( length == 0 ) {
  882. _tprintf(
  883. TEXT("ERROR: missing ProviderPath key\n")
  884. );
  885. return ignoreErrors;
  886. }
  887. length = GetPrivateProfileString(
  888. SectionName,
  889. TEXT("ProviderId"),
  890. TEXT(""),
  891. providerIdString,
  892. sizeof(providerIdString) / sizeof(providerIdString[0]),
  893. IniFile
  894. );
  895. if( length == 0 ) {
  896. _tprintf(
  897. TEXT("ERROR: missing ProviderId key\n")
  898. );
  899. return ignoreErrors;
  900. }
  901. //
  902. // Build the GUID.
  903. //
  904. status = UuidFromString(
  905. providerIdString,
  906. &providerId
  907. );
  908. if( status != RPC_S_OK ) {
  909. _tprintf(
  910. TEXT("ERROR: invalid ProviderId %s\n"),
  911. providerIdString
  912. );
  913. return ignoreErrors;
  914. }
  915. nameSpaceId = GetPrivateProfileInt(
  916. SectionName,
  917. TEXT("NameSpaceId"),
  918. 0,
  919. IniFile
  920. );
  921. if( nameSpaceId == 0 ) {
  922. _tprintf(
  923. TEXT("ERROR: missing NameSpaceId key\n")
  924. );
  925. return ignoreErrors;
  926. }
  927. //
  928. // Install it.
  929. //
  930. result = WSCInstallNameSpace(
  931. providerName,
  932. providerPath,
  933. nameSpaceId,
  934. 2,
  935. &providerId
  936. );
  937. if( result == SOCKET_ERROR ) {
  938. error = GetLastError();
  939. _tprintf(
  940. TEXT("Cannot install %s, error %d\n"),
  941. providerName,
  942. error
  943. );
  944. return ignoreErrors;
  945. }
  946. return TRUE;
  947. } // InstallNameSpaceProviderCallback
  948. BOOL
  949. RemoveNameSpaceProviderCallback(
  950. LPTSTR IniFile,
  951. LPTSTR SectionName,
  952. DWORD Context
  953. )
  954. /*++
  955. Routine Description:
  956. Callback routine for EnumProviderSections() that removes the
  957. namespace service provider described by the given .INI file section.
  958. Arguments:
  959. IniFile - The name of the .INI file describing the namespace provider.
  960. SectionName - The name of the .INI file section for this provider.
  961. Context - Actually contains behaviour control options (OPTION_FLAG_*).
  962. Return Value:
  963. BOOL - TRUE if successful, FALSE otherwise.
  964. --*/
  965. {
  966. TCHAR providerName[MAX_INIFILE_LINE];
  967. TCHAR providerIdString[MAX_INIFILE_LINE];
  968. DWORD length;
  969. INT result;
  970. INT error;
  971. GUID providerId;
  972. RPC_STATUS status;
  973. BOOL ignoreErrors;
  974. //
  975. // Let the user know what we're up to.
  976. //
  977. _tprintf(
  978. TEXT("Removing %s\n"),
  979. SectionName
  980. );
  981. //
  982. // Determine if we should ignore errors. If so, then this routine
  983. // will always return TRUE.
  984. //
  985. ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
  986. //
  987. // Read the provider name & ID.
  988. //
  989. length = GetPrivateProfileString(
  990. SectionName,
  991. TEXT("ProviderName"),
  992. TEXT(""),
  993. providerName,
  994. sizeof(providerName) / sizeof(providerName[0]),
  995. IniFile
  996. );
  997. if( length == 0 ) {
  998. _tprintf(
  999. TEXT("ERROR: missing ProviderName key\n")
  1000. );
  1001. return ignoreErrors;
  1002. }
  1003. length = GetPrivateProfileString(
  1004. SectionName,
  1005. TEXT("ProviderId"),
  1006. TEXT(""),
  1007. providerIdString,
  1008. sizeof(providerIdString) / sizeof(providerIdString[0]),
  1009. IniFile
  1010. );
  1011. if( length == 0 ) {
  1012. _tprintf(
  1013. TEXT("ERROR: missing ProviderId key\n")
  1014. );
  1015. return ignoreErrors;
  1016. }
  1017. //
  1018. // Build the GUID.
  1019. //
  1020. status = UuidFromString(
  1021. providerIdString,
  1022. &providerId
  1023. );
  1024. if( status != RPC_S_OK ) {
  1025. _tprintf(
  1026. TEXT("ERROR: invalid ProviderId %s\n"),
  1027. providerIdString
  1028. );
  1029. return ignoreErrors;
  1030. }
  1031. //
  1032. // Remove it.
  1033. //
  1034. result = WSCUnInstallNameSpace(
  1035. &providerId
  1036. );
  1037. if( result == SOCKET_ERROR ) {
  1038. error = GetLastError();
  1039. _tprintf(
  1040. TEXT("Cannot remove %s, error %d\n"),
  1041. providerName,
  1042. error
  1043. );
  1044. return ignoreErrors;
  1045. }
  1046. return TRUE;
  1047. } // RemoveNameSpaceProviderCallback