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.

897 lines
26 KiB

  1. //
  2. // File: ncwins.cpp
  3. //
  4. // Purpose: Manage the creation and maintanence of the Winsock service.
  5. //
  6. // Entry Point:
  7. // HrAddOrRemoveWinsockDependancy
  8. //
  9. // Changes: 18-Mar-97 Created scottbri
  10. //
  11. #include "pch.h"
  12. #pragma hdrstop
  13. #include "nceh.h"
  14. #include "ncxbase.h"
  15. #include "ncinf.h"
  16. #include "ncreg.h"
  17. #include "ncsetup.h"
  18. #include "ncsvc.h"
  19. #include "resource.h"
  20. #include <winsock2.h>
  21. #include <ws2spi.h>
  22. extern "C"
  23. {
  24. #include <wsasetup.h>
  25. }
  26. extern const WCHAR c_szBackslash[];
  27. extern const WCHAR c_szParameters[];
  28. static const WCHAR c_szWinsockName[] = L"Winsock";
  29. static const WCHAR c_szLibraryName[] = L"LibraryPath";
  30. static const WCHAR c_szDisplayString[] = L"DisplayString";
  31. static const WCHAR c_szSupportedNameSpace[] = L"SupportedNameSpace";
  32. static const WCHAR c_szProviderId[] = L"ProviderId";
  33. static const WCHAR c_szVersion[] = L"Version";
  34. static const WCHAR c_szTransportService[] = L"TransportService";
  35. static const WCHAR c_szHelperDllName[] = L"HelperDllName";
  36. static const WCHAR c_szMaxSockAddrLength[] = L"MaxSockAddrLength";
  37. static const WCHAR c_szMinSockAddrLength[] = L"MinSockAddrLength";
  38. static const WCHAR c_szWinsockMapping[] = L"Mapping";
  39. static const WCHAR c_szErrorControl[] = L"ErrorControl";
  40. static const WCHAR c_szStartType[] = L"Start";
  41. static const WCHAR c_szServiceType[] = L"Type";
  42. static const WCHAR c_szTransports[] = L"Transports";
  43. static const WCHAR c_szAFDServiceName[] = L"AFD";
  44. static const WCHAR c_szTDI[] = L"TDI";
  45. static const WCHAR c_szAddSecLabel[] = L"AddSock";
  46. static const WCHAR c_szRemoveSecLabel[] = L"DelSock";
  47. static const WCHAR c_szServices[] = L"System\\CurrentControlSet\\Services";
  48. static const WCHAR c_szAfdSrvImagePath[] = L"\\SystemRoot\\System32\\drivers\\afd.sys";
  49. typedef struct {
  50. PCWSTR pszVal;
  51. DWORD dwData;
  52. } WRITEREGDW;
  53. // Begin - Stolen from nt\private\inc\wsahelp.h
  54. // Not exposed in public sdk header files, only documented in MSDN
  55. // so the structure is unlikely to change
  56. typedef struct _WINSOCK_MAPPING {
  57. DWORD Rows;
  58. DWORD Columns;
  59. struct {
  60. DWORD AddressFamily;
  61. DWORD SocketType;
  62. DWORD Protocol;
  63. } Mapping[1];
  64. } WINSOCK_MAPPING, *PWINSOCK_MAPPING;
  65. typedef
  66. DWORD
  67. (WINAPI * PWSH_GET_WINSOCK_MAPPING) (
  68. OUT PWINSOCK_MAPPING Mapping,
  69. IN DWORD MappingLength
  70. );
  71. DWORD
  72. WINAPI
  73. WSHGetWinsockMapping (
  74. OUT PWINSOCK_MAPPING Mapping,
  75. IN DWORD MappingLength
  76. );
  77. // End - Stolen from nt\private\inc\wsahelp.h
  78. HRESULT HrRunWinsock2Migration()
  79. {
  80. HRESULT hr;
  81. NC_TRY
  82. {
  83. WSA_SETUP_DISPOSITION Disposition;
  84. DWORD dwErr = MigrateWinsockConfiguration (&Disposition, NULL, 0);
  85. hr = HRESULT_FROM_WIN32(dwErr);
  86. }
  87. NC_CATCH_ALL
  88. {
  89. hr = E_UNEXPECTED;
  90. }
  91. TraceHr (ttidError, FAL, hr, FALSE, "HrRunWinsock2Migration");
  92. return hr;
  93. }
  94. //
  95. // Function: HrRemoveNameSpaceProvider
  96. //
  97. // Purpose: Remove a Winsock namespace
  98. //
  99. // Returns: HRESULT, S_OK on success
  100. //
  101. HRESULT
  102. HrRemoveNameSpaceProvider (
  103. const GUID *pguidProvider)
  104. {
  105. DWORD dwErr;
  106. // Ignore any WSAEINVAL error. It occurs when the name space provider was
  107. // already removed.
  108. //
  109. dwErr = WSCUnInstallNameSpace((GUID *)pguidProvider);
  110. if ((0 != dwErr) && (WSAEINVAL != GetLastError()))
  111. {
  112. TraceError("HrRemoveNameSpaceProvider", HrFromLastWin32Error());
  113. return HrFromLastWin32Error();
  114. }
  115. #ifdef _WIN64
  116. // Uninstall 32 bit name space as well.
  117. //
  118. dwErr = WSCUnInstallNameSpace32((GUID *)pguidProvider);
  119. if ((0 != dwErr) && (WSAEINVAL != GetLastError()))
  120. {
  121. TraceError("HrRemoveNameSpaceProvider", HrFromLastWin32Error());
  122. return HrFromLastWin32Error();
  123. }
  124. #endif
  125. return S_OK;
  126. }
  127. //
  128. // Function: HrAddNameSpaceProvider
  129. //
  130. // Purpose: Create a Winsock namespace
  131. //
  132. // Returns: HRESULT, S_OK on success
  133. //
  134. HRESULT
  135. HrAddNameSpaceProvider (
  136. PCWSTR pszDisplayName,
  137. PCWSTR pszPathDLLName,
  138. DWORD dwNameSpace,
  139. BOOL fSchemaSupport,
  140. const GUID * pguidProvider)
  141. {
  142. // Call the Winsock API to create a namespace
  143. if (WSCInstallNameSpace((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
  144. dwNameSpace, fSchemaSupport,
  145. (GUID *)pguidProvider))
  146. {
  147. // They namespace provider may already be registered
  148. TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
  149. "Name space provider may already be registered.");
  150. TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
  151. "Trying to unregister and then re-register.");
  152. // Try unregistering it, and then give one more try at registering it.
  153. HrRemoveNameSpaceProvider(pguidProvider);
  154. if (WSCInstallNameSpace((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
  155. dwNameSpace, fSchemaSupport,
  156. (GUID *)pguidProvider))
  157. {
  158. TraceError("HrAddNameSpaceProvider - Second attempt failed, returning error", HrFromLastWin32Error());
  159. return HrFromLastWin32Error();
  160. }
  161. }
  162. #ifdef _WIN64
  163. // Call the Winsock API to create a 32 namespace
  164. if (WSCInstallNameSpace32((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
  165. dwNameSpace, fSchemaSupport,
  166. (GUID *)pguidProvider))
  167. {
  168. // They namespace provider may already be registered
  169. TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
  170. "32 bit Name space provider may already be registered.");
  171. TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
  172. "Trying to unregister and then re-register 32 bit name space.");
  173. // Try unregistering it, and then give one more try at registering it.
  174. // Use direct call to ws2_32 to avoid unregistering 64 bit provider.
  175. WSCUnInstallNameSpace32((GUID *)pguidProvider);
  176. if (WSCInstallNameSpace32((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
  177. dwNameSpace, fSchemaSupport,
  178. (GUID *)pguidProvider))
  179. {
  180. TraceError("HrAddNameSpaceProvider - Second attempt failed (32 bit), returning error", HrFromLastWin32Error());
  181. return HrFromLastWin32Error();
  182. }
  183. }
  184. #endif
  185. return S_OK;
  186. }
  187. //
  188. // Function: HrInstallWinsock
  189. //
  190. // Purpose: Copy winsock and afd related files, and setup the appropriate
  191. // registry values
  192. //
  193. // Parameters: none
  194. //
  195. // Returns: HRESULT, S_OK if afd and winsock are installed successfully
  196. //
  197. HRESULT HrInstallWinsock()
  198. {
  199. DWORD dwDisposition;
  200. HKEY hkeyParameters = NULL;
  201. HKEY hkeyWinsock = NULL;
  202. HRESULT hr;
  203. INT i;
  204. WRITEREGDW regdata[3];
  205. tstring strBuf;
  206. CService srvc;
  207. CServiceManager sm;
  208. hr = sm.HrCreateService( &srvc, c_szAFDServiceName,
  209. SzLoadIds(IDS_NETCFG_AFD_SERVICE_DESC),
  210. 0x1, 0x2, 0x1, c_szAfdSrvImagePath,
  211. NULL, c_szTDI, NULL, SERVICE_ALL_ACCESS,
  212. NULL, NULL, NULL);
  213. if (SUCCEEDED(hr))
  214. {
  215. // For VadimE, start AFD as soon as it is installed
  216. //
  217. (VOID)sm.HrStartServiceNoWait(c_szAFDServiceName);
  218. srvc.Close();
  219. }
  220. // Close the service control manager.
  221. sm.Close();
  222. if (FAILED(hr) && (HRESULT_FROM_WIN32 (ERROR_SERVICE_EXISTS) != hr))
  223. {
  224. goto Done;
  225. }
  226. // Create/Open the Services\Winsock key
  227. strBuf = c_szServices;
  228. strBuf += c_szBackslash;
  229. strBuf += c_szWinsockName;
  230. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
  231. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  232. &hkeyWinsock, &dwDisposition);
  233. if (S_OK != hr)
  234. {
  235. goto Done;
  236. }
  237. // Create/Open the Services\Winsock\Parameters key
  238. strBuf += c_szBackslash;
  239. strBuf += c_szParameters;
  240. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
  241. REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
  242. &hkeyParameters, &dwDisposition);
  243. if (S_OK != hr)
  244. {
  245. goto Done;
  246. }
  247. // Populate the Winsock key
  248. regdata[0].pszVal = c_szErrorControl;
  249. regdata[0].dwData = 0x1; // ErrorControl
  250. regdata[1].pszVal = c_szStartType;
  251. regdata[1].dwData = 0x3; // Start Type
  252. regdata[2].pszVal = c_szServiceType;
  253. regdata[2].dwData = 0x4; // Service Type
  254. // Write the data to the components Winsock subkey
  255. for (i=0; i<3; i++)
  256. {
  257. hr = HrRegSetDword(hkeyWinsock, regdata[i].pszVal, regdata[i].dwData);
  258. if (S_OK != hr)
  259. {
  260. goto Done;
  261. }
  262. }
  263. Done:
  264. TraceError("HrInstallWinsock",hr);
  265. RegSafeCloseKey(hkeyParameters);
  266. RegSafeCloseKey(hkeyWinsock);
  267. return hr;
  268. }
  269. //
  270. // Function: FIsWinsockInstalled
  271. //
  272. // Purpose: Verify whether winsock is installed
  273. //
  274. // Parameters: pfInstalled [OUT] - Contains TRUE if Winsock is currently installed
  275. //
  276. // Returns: HRESULT, S_OK on success
  277. //
  278. HRESULT
  279. HrIsWinsockInstalled (
  280. BOOL * pfInstalled)
  281. {
  282. HRESULT hr;
  283. HKEY hkey;
  284. tstring strBuf;
  285. strBuf = c_szServices;
  286. strBuf += c_szBackslash;
  287. strBuf += c_szWinsockName;
  288. strBuf += c_szBackslash;
  289. strBuf += c_szParameters;
  290. hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(), KEY_READ,
  291. &hkey );
  292. if (S_OK == hr)
  293. {
  294. RegCloseKey(hkey);
  295. // Now check to make sure AFD is installed
  296. strBuf = c_szServices;
  297. strBuf += c_szBackslash;
  298. strBuf += c_szAFDServiceName;
  299. hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(), KEY_READ,
  300. &hkey );
  301. if (S_OK == hr)
  302. {
  303. RegCloseKey(hkey);
  304. *pfInstalled = TRUE;
  305. }
  306. }
  307. if (S_OK != hr)
  308. {
  309. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  310. {
  311. hr = S_OK;
  312. }
  313. *pfInstalled = FALSE;
  314. }
  315. TraceError("HrIsWinsockInstalled", hr);
  316. return hr;
  317. }
  318. //
  319. // Function: HrUpdateWinsockTransportList
  320. //
  321. // Purpose: Update the contents of Winsock's Transport property by
  322. // adding/removing the specified transport
  323. //
  324. // Parameters: pszTransport [IN] - Name of the transport to add/remove
  325. // fInstall [IN] - If TRUE, install, otherwise remove
  326. //
  327. // Returns: HRESULT, S_OK on success
  328. //
  329. HRESULT
  330. HrUpdateWinsockTransportList (
  331. PCWSTR pszTransport,
  332. BOOL fInstall)
  333. {
  334. HKEY hkey = NULL;
  335. HRESULT hr;
  336. tstring strBuf;
  337. strBuf = c_szServices;
  338. strBuf += c_szBackslash;;
  339. strBuf += c_szWinsockName;
  340. strBuf += c_szBackslash;
  341. strBuf += c_szParameters;
  342. hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(),
  343. KEY_READ_WRITE, &hkey );
  344. if (S_OK != hr)
  345. {
  346. // Handle registry key not found. When installing a component with
  347. // a winsock dependancy an in memory state can exist such that winsock
  348. // is not literally installed yet (Apply has not been pressed). If
  349. // the user removes this added component, the current removal code
  350. // processes the services removal section, which includes winsock
  351. // removal. Since we haven't actually gotten as a far as installing
  352. // winsock yet accessing the winsock parameters key is not possible.
  353. // Safely consume the error.
  354. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  355. {
  356. hr = S_OK;
  357. }
  358. goto Done;
  359. }
  360. if (fInstall)
  361. {
  362. hr = HrRegAddStringToMultiSz(pszTransport, hkey, NULL, c_szTransports,
  363. STRING_FLAG_ENSURE_AT_END, 0);
  364. }
  365. else
  366. {
  367. hr = HrRegRemoveStringFromMultiSz(pszTransport, hkey, NULL,
  368. c_szTransports,
  369. STRING_FLAG_REMOVE_ALL);
  370. }
  371. Done:
  372. RegSafeCloseKey(hkey);
  373. TraceError("HrUpdateWinsockTransport", hr);
  374. return hr;
  375. }
  376. #define WSHWINSOCKMAPPING "WSHGetWinsockMapping"
  377. #define WSH_MAX_MAPPING_DATA 8192
  378. //
  379. // Function: HrWriteWinsockMapping
  380. //
  381. // Purpose: To extract the magic binary data from the winsock helper dll.
  382. // This code was extracted from nt\private\net\ui\ncpa1.1\netcfg\setup.cpp
  383. //
  384. // Parameters: pszDllName - Name of the Winsock helper DLL
  385. // hkey - Key where the "Mapping" value is to be written
  386. //
  387. // Returns: HRESULT, S_OK on success
  388. //
  389. HRESULT
  390. HrWriteWinsockMapping (
  391. PCWSTR pszDllName,
  392. HKEY hkey)
  393. {
  394. INT cb;
  395. DWORD cbMapping;
  396. HRESULT hr;
  397. HMODULE hDll = NULL;
  398. PWSH_GET_WINSOCK_MAPPING pMapFunc = NULL;
  399. PWINSOCK_MAPPING pMapTriples = NULL;
  400. WCHAR tchExpandedName [MAX_PATH+1];
  401. do // Pseudo-loop
  402. {
  403. pMapTriples = (PWINSOCK_MAPPING) MemAlloc(WSH_MAX_MAPPING_DATA);
  404. if ( pMapTriples == NULL)
  405. {
  406. hr = E_OUTOFMEMORY;
  407. break ;
  408. }
  409. // Expand any environment strings in the DLL path string.
  410. cb = ExpandEnvironmentStrings( pszDllName,
  411. tchExpandedName,
  412. MAX_PATH+1 ) ;
  413. if ( cb == 0 || cb > (MAX_PATH+1) )
  414. {
  415. hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  416. break ;
  417. }
  418. // Located the mapping function
  419. hr = HrLoadLibAndGetProc(tchExpandedName, WSHWINSOCKMAPPING, &hDll,
  420. reinterpret_cast<FARPROC*>(&pMapFunc));
  421. // Bind to the DLL
  422. if (FAILED(hr))
  423. {
  424. break ;
  425. }
  426. // Call the export to return the mapping table
  427. cbMapping = (*pMapFunc)( pMapTriples, WSH_MAX_MAPPING_DATA ) ;
  428. if ( cbMapping > WSH_MAX_MAPPING_DATA )
  429. {
  430. hr = E_OUTOFMEMORY;
  431. break ;
  432. }
  433. // Store the mapping info into the Registry
  434. hr = HrRegSetBinary(hkey, c_szWinsockMapping,
  435. (LPBYTE) pMapTriples, cbMapping);
  436. }
  437. while (FALSE);
  438. MemFree(pMapTriples);
  439. if (hDll)
  440. {
  441. FreeLibrary(hDll);
  442. }
  443. TraceError("HrWriteWinsockMapping",hr);
  444. return hr;
  445. }
  446. //
  447. // Function: HrWriteWinsockInfo
  448. //
  449. // Purpose: Commit the Winsock information to the component's Winsock
  450. // section, and also to the Winsock section.
  451. //
  452. // Parameters: strTransport - Name of the transport to be installed
  453. // strDllHelper - Name of the Winsock helper dll
  454. // dwMaxSockAddrLength - ?
  455. // dwMinSockAddrLength - ?
  456. //
  457. // Returns: HRESULT, S_OK on success
  458. //
  459. HRESULT HrWriteWinsockInfo (
  460. tstring& strTransport,
  461. tstring& strDllHelper,
  462. DWORD dwMaxSockAddrLength,
  463. DWORD dwMinSockAddrLength)
  464. {
  465. DWORD dwDisposition;
  466. HKEY hkey;
  467. HRESULT hr;
  468. int i;
  469. WRITEREGDW regdata[2];
  470. tstring strBuf;
  471. // Create/Open the component's Winsock Key
  472. // Verify we don't need an intermediate step to create the key
  473. strBuf = c_szServices;
  474. strBuf += c_szBackslash;
  475. strBuf += strTransport;
  476. strBuf += c_szBackslash;
  477. strBuf += c_szParameters;
  478. strBuf += c_szBackslash;
  479. strBuf += c_szWinsockName;
  480. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
  481. REG_OPTION_NON_VOLATILE,
  482. KEY_READ_WRITE, NULL, &hkey, &dwDisposition);
  483. if (S_OK != hr)
  484. {
  485. goto Done;
  486. }
  487. // Initialize the information to write
  488. hr = HrRegSetValueEx(hkey, c_szHelperDllName, REG_EXPAND_SZ,
  489. (LPBYTE)(LPBYTE)strDllHelper.c_str(),
  490. strDllHelper.length() * sizeof(WCHAR));
  491. if (S_OK != hr)
  492. {
  493. goto Done;
  494. }
  495. // Initialize the information to write
  496. regdata[0].pszVal = c_szMaxSockAddrLength;
  497. regdata[0].dwData = dwMaxSockAddrLength;
  498. regdata[1].pszVal = c_szMinSockAddrLength;
  499. regdata[1].dwData = dwMinSockAddrLength;
  500. // Write the data to the components Winsock subkey
  501. for (i=0; i<celems(regdata); i++)
  502. {
  503. hr = HrRegSetDword(hkey, regdata[i].pszVal, regdata[i].dwData);
  504. if (S_OK != hr)
  505. {
  506. goto Done;
  507. }
  508. }
  509. // Write the Winsock DLL Mapping information
  510. hr = HrWriteWinsockMapping(strDllHelper.c_str(), hkey);
  511. if (S_OK != hr)
  512. {
  513. goto Done;
  514. }
  515. // Update the Winsock transport list
  516. hr = HrUpdateWinsockTransportList(strTransport.c_str(), TRUE);
  517. Done:
  518. RegSafeCloseKey(hkey);
  519. TraceError("HrWriteWinsockInfo",hr);
  520. return hr;
  521. }
  522. //
  523. // Function: HrInstallWinsockDependancy
  524. //
  525. // Purpose: Examine the current components .inf file and determine whether
  526. // or not a winsock dependancy exists. If the current component
  527. // requires interaction with Winsock, this code will first verify
  528. // if Winsock is already installed. If it is not, then both the
  529. // Winsock and afd services will be installed via a call to the
  530. // function FInstallWinsock. Once that is accomplished, the code
  531. // will update Winsock to be aware of this component and will
  532. // write Winsock specific info to this components Services
  533. // registry section via the function FWriteWinsockInfo. If the
  534. // current component does not have a Winsock dependancy no action
  535. // is taken.
  536. //
  537. // Parameters: hinfInstallFile [IN] - Handle to the current component's
  538. // .inf file.
  539. // szSectionName [IN] - The name of the install/remove section
  540. //
  541. // Returns: HRESULT, S_OK if the component had a Winsock dependancy and
  542. // the registry was updated successfully with the information.
  543. //
  544. HRESULT
  545. HrInstallWinsockDependancy (
  546. HINF hinfInstallFile,
  547. PCWSTR pszSectionName)
  548. {
  549. DWORD dwMaxSockAddrLength;
  550. DWORD dwMinSockAddrLength;
  551. DWORD dwSupportedNameSpace;
  552. DWORD dwVersion = 1;
  553. tstring strDllHelper;
  554. tstring strTransport;
  555. tstring strLibraryPath;
  556. tstring strDisplayString;
  557. tstring strProviderId;
  558. BOOL fSuccess = FALSE;
  559. BOOL fWinsockInstalled;
  560. BOOL fWinsockInfoComplete = FALSE;
  561. BOOL fNamespaceInfoComplete = FALSE;
  562. HRESULT hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  563. // Search for the "TransportService" property.
  564. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  565. c_szTransportService, &strTransport);
  566. if (S_OK == hr)
  567. {
  568. // Retrieve the path to the helper DLL
  569. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  570. c_szHelperDllName, &strDllHelper);
  571. if (FAILED(hr))
  572. {
  573. goto Error;
  574. }
  575. // Retrieve the MaxSockAddrLength
  576. hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
  577. c_szMaxSockAddrLength, &dwMaxSockAddrLength);
  578. if (FAILED(hr))
  579. {
  580. goto Error;
  581. }
  582. // Retrieve the MinSockAddrLength
  583. hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
  584. c_szMinSockAddrLength, &dwMinSockAddrLength);
  585. if (FAILED(hr))
  586. {
  587. goto Error;
  588. }
  589. fWinsockInfoComplete = TRUE;
  590. }
  591. else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
  592. {
  593. goto Error;
  594. }
  595. // Retrieve the Provider ID, if not present then don't registry a
  596. // namespace provider
  597. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  598. c_szProviderId, &strProviderId);
  599. if (S_OK == hr)
  600. {
  601. // Retrieve the path to Library
  602. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  603. c_szLibraryName, &strLibraryPath);
  604. if (FAILED(hr))
  605. {
  606. goto Error;
  607. }
  608. // Retrieve the transport providers display string
  609. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  610. c_szDisplayString, &strDisplayString);
  611. if (FAILED(hr))
  612. {
  613. goto Error;
  614. }
  615. // Retrieve the ID of the supported namespace
  616. hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
  617. c_szSupportedNameSpace, &dwSupportedNameSpace);
  618. if (FAILED(hr))
  619. {
  620. goto Error;
  621. }
  622. // Retrieve Version (optional, defaults to 1)
  623. (VOID)HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
  624. c_szVersion, &dwVersion);
  625. fNamespaceInfoComplete = TRUE;
  626. }
  627. else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
  628. {
  629. goto Error;
  630. }
  631. // Check for Winsock installation (if required)
  632. if (fWinsockInfoComplete || fNamespaceInfoComplete)
  633. {
  634. // Check if winsock is installed
  635. hr = HrIsWinsockInstalled(&fWinsockInstalled);
  636. if (FAILED(hr))
  637. {
  638. goto Error;
  639. }
  640. // Is Winsock already installed? If not, install
  641. // the bloke...
  642. if (!fWinsockInstalled)
  643. {
  644. hr = HrInstallWinsock();
  645. if (FAILED(hr))
  646. {
  647. goto Error;
  648. }
  649. }
  650. }
  651. // Write the data we've collect to the correct
  652. // spots in the registry
  653. if (fWinsockInfoComplete)
  654. {
  655. hr = HrWriteWinsockInfo(strTransport, strDllHelper,
  656. dwMaxSockAddrLength, dwMinSockAddrLength);
  657. if (FAILED(hr))
  658. {
  659. goto Error;
  660. }
  661. }
  662. // Write the namespace provider information if we read the namespace
  663. // provider information
  664. if (fNamespaceInfoComplete)
  665. {
  666. IID guid;
  667. hr = IIDFromString((PWSTR)strProviderId.c_str(), &guid);
  668. if (FAILED(hr))
  669. {
  670. goto Error;
  671. }
  672. hr = HrAddNameSpaceProvider(strDisplayString.c_str(),
  673. strLibraryPath.c_str(),
  674. dwSupportedNameSpace,
  675. dwVersion,
  676. &guid);
  677. if (FAILED(hr))
  678. {
  679. goto Error;
  680. }
  681. }
  682. if (fWinsockInfoComplete || fNamespaceInfoComplete)
  683. {
  684. (void)HrRunWinsock2Migration();
  685. }
  686. Error:
  687. TraceError("HrInstallWinsockDependancy",hr);
  688. return hr;
  689. }
  690. //
  691. // Function: HrRemoveWinsockDependancy
  692. //
  693. // Purpose: Remove the current component from the Winsock
  694. // transport list, if present.
  695. //
  696. // Parameters: hinfInstallFile [IN] - Handle to the current component's
  697. // .inf file.
  698. // pszSectionName [IN] - The name of the install/remove section
  699. //
  700. // Returns: HRESULT, S_OK on success
  701. //
  702. HRESULT HrRemoveWinsockDependancy(HINF hinfInstallFile,
  703. PCWSTR pszSectionName)
  704. {
  705. HRESULT hr;
  706. tstring str;
  707. tstring strTransport;
  708. BOOL fRunWinsockMigration = FALSE;
  709. // Search for the "TransportService" property
  710. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  711. c_szTransportService, &strTransport);
  712. if (S_OK == hr)
  713. {
  714. HKEY hkey;
  715. // Remove the Transport from the Winsock transport list
  716. hr = HrUpdateWinsockTransportList(strTransport.c_str(), FALSE);
  717. if (FAILED(hr))
  718. {
  719. goto Error;
  720. }
  721. fRunWinsockMigration = TRUE;
  722. // Remove the Winsock subkey under the specified transport
  723. // But ignore failures, as we're just trying to be tidy
  724. str = c_szServices;
  725. str += c_szBackslash;
  726. str += strTransport.c_str();
  727. str += c_szBackslash;
  728. str += c_szParameters;
  729. if (S_OK == HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, str.c_str(),
  730. KEY_READ_WRITE_DELETE, &hkey))
  731. {
  732. HrRegDeleteKeyTree(hkey, c_szWinsockName);
  733. RegCloseKey(hkey);
  734. }
  735. }
  736. else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
  737. {
  738. goto Error;
  739. }
  740. // Remove the Winsock Namespace provider
  741. hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
  742. c_szProviderId, &str);
  743. if (S_OK == hr)
  744. {
  745. IID guid;
  746. hr = IIDFromString((PWSTR)str.c_str(), &guid);
  747. if (FAILED(hr))
  748. {
  749. goto Error;
  750. }
  751. // Don't fail, the name space may not have been successfully registered.
  752. // Especially if the component installation failed.
  753. HrRemoveNameSpaceProvider(&guid);
  754. fRunWinsockMigration = TRUE;
  755. }
  756. else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
  757. {
  758. goto Error;
  759. }
  760. if (fRunWinsockMigration)
  761. {
  762. (void)HrRunWinsock2Migration();
  763. }
  764. hr = S_OK; // Normalize return
  765. Error:
  766. TraceError("HrRemoveWinsockDependancy",hr);
  767. return hr;
  768. }
  769. //
  770. // Function: HrAddOrRemoveWinsockDependancy
  771. //
  772. // Purpose: To add or remove Winsock dependancies for components
  773. //
  774. // Parameters: hinfInstallFile [IN] - The handle to the inf file to install
  775. // from
  776. // pszSectionName [IN] - The Base install section name.
  777. // (The prefix for the .Services section)
  778. //
  779. // Returns: HRESULT, S_OK on success
  780. //
  781. HRESULT
  782. HrAddOrRemoveWinsockDependancy (
  783. HINF hinfInstallFile,
  784. PCWSTR pszSectionName)
  785. {
  786. Assert(IsValidHandle(hinfInstallFile));
  787. HRESULT hr;
  788. hr = HrProcessInfExtension(hinfInstallFile, pszSectionName,
  789. c_szWinsockName, c_szAddSecLabel,
  790. c_szRemoveSecLabel, HrInstallWinsockDependancy,
  791. HrRemoveWinsockDependancy);
  792. if (SPAPI_E_LINE_NOT_FOUND == hr)
  793. {
  794. // .Winsock section is not required
  795. hr = S_OK;
  796. }
  797. TraceError("HrAddOrRemoveWinsockDependancy",hr);
  798. return hr;
  799. }