windows-nt/Source/XPSP1/NT/net/config/netcfg/engine/ncwins.cpp
2020-09-26 16:20:57 +08:00

898 lines
26 KiB
C++

//
// File: ncwins.cpp
//
// Purpose: Manage the creation and maintanence of the Winsock service.
//
// Entry Point:
// HrAddOrRemoveWinsockDependancy
//
// Changes: 18-Mar-97 Created scottbri
//
#include "pch.h"
#pragma hdrstop
#include "nceh.h"
#include "ncxbase.h"
#include "ncinf.h"
#include "ncreg.h"
#include "ncsetup.h"
#include "ncsvc.h"
#include "resource.h"
#include <winsock2.h>
#include <ws2spi.h>
extern "C"
{
#include <wsasetup.h>
}
extern const WCHAR c_szBackslash[];
extern const WCHAR c_szParameters[];
static const WCHAR c_szWinsockName[] = L"Winsock";
static const WCHAR c_szLibraryName[] = L"LibraryPath";
static const WCHAR c_szDisplayString[] = L"DisplayString";
static const WCHAR c_szSupportedNameSpace[] = L"SupportedNameSpace";
static const WCHAR c_szProviderId[] = L"ProviderId";
static const WCHAR c_szVersion[] = L"Version";
static const WCHAR c_szTransportService[] = L"TransportService";
static const WCHAR c_szHelperDllName[] = L"HelperDllName";
static const WCHAR c_szMaxSockAddrLength[] = L"MaxSockAddrLength";
static const WCHAR c_szMinSockAddrLength[] = L"MinSockAddrLength";
static const WCHAR c_szWinsockMapping[] = L"Mapping";
static const WCHAR c_szErrorControl[] = L"ErrorControl";
static const WCHAR c_szStartType[] = L"Start";
static const WCHAR c_szServiceType[] = L"Type";
static const WCHAR c_szTransports[] = L"Transports";
static const WCHAR c_szAFDServiceName[] = L"AFD";
static const WCHAR c_szTDI[] = L"TDI";
static const WCHAR c_szAddSecLabel[] = L"AddSock";
static const WCHAR c_szRemoveSecLabel[] = L"DelSock";
static const WCHAR c_szServices[] = L"System\\CurrentControlSet\\Services";
static const WCHAR c_szAfdSrvImagePath[] = L"\\SystemRoot\\System32\\drivers\\afd.sys";
typedef struct {
PCWSTR pszVal;
DWORD dwData;
} WRITEREGDW;
// Begin - Stolen from nt\private\inc\wsahelp.h
// Not exposed in public sdk header files, only documented in MSDN
// so the structure is unlikely to change
typedef struct _WINSOCK_MAPPING {
DWORD Rows;
DWORD Columns;
struct {
DWORD AddressFamily;
DWORD SocketType;
DWORD Protocol;
} Mapping[1];
} WINSOCK_MAPPING, *PWINSOCK_MAPPING;
typedef
DWORD
(WINAPI * PWSH_GET_WINSOCK_MAPPING) (
OUT PWINSOCK_MAPPING Mapping,
IN DWORD MappingLength
);
DWORD
WINAPI
WSHGetWinsockMapping (
OUT PWINSOCK_MAPPING Mapping,
IN DWORD MappingLength
);
// End - Stolen from nt\private\inc\wsahelp.h
HRESULT HrRunWinsock2Migration()
{
HRESULT hr;
NC_TRY
{
WSA_SETUP_DISPOSITION Disposition;
DWORD dwErr = MigrateWinsockConfiguration (&Disposition, NULL, 0);
hr = HRESULT_FROM_WIN32(dwErr);
}
NC_CATCH_ALL
{
hr = E_UNEXPECTED;
}
TraceHr (ttidError, FAL, hr, FALSE, "HrRunWinsock2Migration");
return hr;
}
//
// Function: HrRemoveNameSpaceProvider
//
// Purpose: Remove a Winsock namespace
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrRemoveNameSpaceProvider (
const GUID *pguidProvider)
{
DWORD dwErr;
// Ignore any WSAEINVAL error. It occurs when the name space provider was
// already removed.
//
dwErr = WSCUnInstallNameSpace((GUID *)pguidProvider);
if ((0 != dwErr) && (WSAEINVAL != GetLastError()))
{
TraceError("HrRemoveNameSpaceProvider", HrFromLastWin32Error());
return HrFromLastWin32Error();
}
#ifdef _WIN64
// Uninstall 32 bit name space as well.
//
dwErr = WSCUnInstallNameSpace32((GUID *)pguidProvider);
if ((0 != dwErr) && (WSAEINVAL != GetLastError()))
{
TraceError("HrRemoveNameSpaceProvider", HrFromLastWin32Error());
return HrFromLastWin32Error();
}
#endif
return S_OK;
}
//
// Function: HrAddNameSpaceProvider
//
// Purpose: Create a Winsock namespace
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrAddNameSpaceProvider (
PCWSTR pszDisplayName,
PCWSTR pszPathDLLName,
DWORD dwNameSpace,
BOOL fSchemaSupport,
const GUID * pguidProvider)
{
// Call the Winsock API to create a namespace
if (WSCInstallNameSpace((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
dwNameSpace, fSchemaSupport,
(GUID *)pguidProvider))
{
// They namespace provider may already be registered
TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
"Name space provider may already be registered.");
TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
"Trying to unregister and then re-register.");
// Try unregistering it, and then give one more try at registering it.
HrRemoveNameSpaceProvider(pguidProvider);
if (WSCInstallNameSpace((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
dwNameSpace, fSchemaSupport,
(GUID *)pguidProvider))
{
TraceError("HrAddNameSpaceProvider - Second attempt failed, returning error", HrFromLastWin32Error());
return HrFromLastWin32Error();
}
}
#ifdef _WIN64
// Call the Winsock API to create a 32 namespace
if (WSCInstallNameSpace32((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
dwNameSpace, fSchemaSupport,
(GUID *)pguidProvider))
{
// They namespace provider may already be registered
TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
"32 bit Name space provider may already be registered.");
TraceTag(ttidNetcfgBase, "HrAddNameSpaceProvider - "
"Trying to unregister and then re-register 32 bit name space.");
// Try unregistering it, and then give one more try at registering it.
// Use direct call to ws2_32 to avoid unregistering 64 bit provider.
WSCUnInstallNameSpace32((GUID *)pguidProvider);
if (WSCInstallNameSpace32((PWSTR)pszDisplayName, (PWSTR)pszPathDLLName,
dwNameSpace, fSchemaSupport,
(GUID *)pguidProvider))
{
TraceError("HrAddNameSpaceProvider - Second attempt failed (32 bit), returning error", HrFromLastWin32Error());
return HrFromLastWin32Error();
}
}
#endif
return S_OK;
}
//
// Function: HrInstallWinsock
//
// Purpose: Copy winsock and afd related files, and setup the appropriate
// registry values
//
// Parameters: none
//
// Returns: HRESULT, S_OK if afd and winsock are installed successfully
//
HRESULT HrInstallWinsock()
{
DWORD dwDisposition;
HKEY hkeyParameters = NULL;
HKEY hkeyWinsock = NULL;
HRESULT hr;
INT i;
WRITEREGDW regdata[3];
tstring strBuf;
CService srvc;
CServiceManager sm;
hr = sm.HrCreateService( &srvc, c_szAFDServiceName,
SzLoadIds(IDS_NETCFG_AFD_SERVICE_DESC),
0x1, 0x2, 0x1, c_szAfdSrvImagePath,
NULL, c_szTDI, NULL, SERVICE_ALL_ACCESS,
NULL, NULL, NULL);
if (SUCCEEDED(hr))
{
// For VadimE, start AFD as soon as it is installed
//
(VOID)sm.HrStartServiceNoWait(c_szAFDServiceName);
srvc.Close();
}
// Close the service control manager.
sm.Close();
if (FAILED(hr) && (HRESULT_FROM_WIN32 (ERROR_SERVICE_EXISTS) != hr))
{
goto Done;
}
// Create/Open the Services\Winsock key
strBuf = c_szServices;
strBuf += c_szBackslash;
strBuf += c_szWinsockName;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
&hkeyWinsock, &dwDisposition);
if (S_OK != hr)
{
goto Done;
}
// Create/Open the Services\Winsock\Parameters key
strBuf += c_szBackslash;
strBuf += c_szParameters;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
REG_OPTION_NON_VOLATILE, KEY_READ_WRITE, NULL,
&hkeyParameters, &dwDisposition);
if (S_OK != hr)
{
goto Done;
}
// Populate the Winsock key
regdata[0].pszVal = c_szErrorControl;
regdata[0].dwData = 0x1; // ErrorControl
regdata[1].pszVal = c_szStartType;
regdata[1].dwData = 0x3; // Start Type
regdata[2].pszVal = c_szServiceType;
regdata[2].dwData = 0x4; // Service Type
// Write the data to the components Winsock subkey
for (i=0; i<3; i++)
{
hr = HrRegSetDword(hkeyWinsock, regdata[i].pszVal, regdata[i].dwData);
if (S_OK != hr)
{
goto Done;
}
}
Done:
TraceError("HrInstallWinsock",hr);
RegSafeCloseKey(hkeyParameters);
RegSafeCloseKey(hkeyWinsock);
return hr;
}
//
// Function: FIsWinsockInstalled
//
// Purpose: Verify whether winsock is installed
//
// Parameters: pfInstalled [OUT] - Contains TRUE if Winsock is currently installed
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrIsWinsockInstalled (
BOOL * pfInstalled)
{
HRESULT hr;
HKEY hkey;
tstring strBuf;
strBuf = c_szServices;
strBuf += c_szBackslash;
strBuf += c_szWinsockName;
strBuf += c_szBackslash;
strBuf += c_szParameters;
hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(), KEY_READ,
&hkey );
if (S_OK == hr)
{
RegCloseKey(hkey);
// Now check to make sure AFD is installed
strBuf = c_szServices;
strBuf += c_szBackslash;
strBuf += c_szAFDServiceName;
hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(), KEY_READ,
&hkey );
if (S_OK == hr)
{
RegCloseKey(hkey);
*pfInstalled = TRUE;
}
}
if (S_OK != hr)
{
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
{
hr = S_OK;
}
*pfInstalled = FALSE;
}
TraceError("HrIsWinsockInstalled", hr);
return hr;
}
//
// Function: HrUpdateWinsockTransportList
//
// Purpose: Update the contents of Winsock's Transport property by
// adding/removing the specified transport
//
// Parameters: pszTransport [IN] - Name of the transport to add/remove
// fInstall [IN] - If TRUE, install, otherwise remove
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrUpdateWinsockTransportList (
PCWSTR pszTransport,
BOOL fInstall)
{
HKEY hkey = NULL;
HRESULT hr;
tstring strBuf;
strBuf = c_szServices;
strBuf += c_szBackslash;;
strBuf += c_szWinsockName;
strBuf += c_szBackslash;
strBuf += c_szParameters;
hr = HrRegOpenKeyEx( HKEY_LOCAL_MACHINE, strBuf.c_str(),
KEY_READ_WRITE, &hkey );
if (S_OK != hr)
{
// Handle registry key not found. When installing a component with
// a winsock dependancy an in memory state can exist such that winsock
// is not literally installed yet (Apply has not been pressed). If
// the user removes this added component, the current removal code
// processes the services removal section, which includes winsock
// removal. Since we haven't actually gotten as a far as installing
// winsock yet accessing the winsock parameters key is not possible.
// Safely consume the error.
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
{
hr = S_OK;
}
goto Done;
}
if (fInstall)
{
hr = HrRegAddStringToMultiSz(pszTransport, hkey, NULL, c_szTransports,
STRING_FLAG_ENSURE_AT_END, 0);
}
else
{
hr = HrRegRemoveStringFromMultiSz(pszTransport, hkey, NULL,
c_szTransports,
STRING_FLAG_REMOVE_ALL);
}
Done:
RegSafeCloseKey(hkey);
TraceError("HrUpdateWinsockTransport", hr);
return hr;
}
#define WSHWINSOCKMAPPING "WSHGetWinsockMapping"
#define WSH_MAX_MAPPING_DATA 8192
//
// Function: HrWriteWinsockMapping
//
// Purpose: To extract the magic binary data from the winsock helper dll.
// This code was extracted from nt\private\net\ui\ncpa1.1\netcfg\setup.cpp
//
// Parameters: pszDllName - Name of the Winsock helper DLL
// hkey - Key where the "Mapping" value is to be written
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrWriteWinsockMapping (
PCWSTR pszDllName,
HKEY hkey)
{
INT cb;
DWORD cbMapping;
HRESULT hr;
HMODULE hDll = NULL;
PWSH_GET_WINSOCK_MAPPING pMapFunc = NULL;
PWINSOCK_MAPPING pMapTriples = NULL;
WCHAR tchExpandedName [MAX_PATH+1];
do // Pseudo-loop
{
pMapTriples = (PWINSOCK_MAPPING) MemAlloc(WSH_MAX_MAPPING_DATA);
if ( pMapTriples == NULL)
{
hr = E_OUTOFMEMORY;
break ;
}
// Expand any environment strings in the DLL path string.
cb = ExpandEnvironmentStrings( pszDllName,
tchExpandedName,
MAX_PATH+1 ) ;
if ( cb == 0 || cb > (MAX_PATH+1) )
{
hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
break ;
}
// Located the mapping function
hr = HrLoadLibAndGetProc(tchExpandedName, WSHWINSOCKMAPPING, &hDll,
reinterpret_cast<FARPROC*>(&pMapFunc));
// Bind to the DLL
if (FAILED(hr))
{
break ;
}
// Call the export to return the mapping table
cbMapping = (*pMapFunc)( pMapTriples, WSH_MAX_MAPPING_DATA ) ;
if ( cbMapping > WSH_MAX_MAPPING_DATA )
{
hr = E_OUTOFMEMORY;
break ;
}
// Store the mapping info into the Registry
hr = HrRegSetBinary(hkey, c_szWinsockMapping,
(LPBYTE) pMapTriples, cbMapping);
}
while (FALSE);
MemFree(pMapTriples);
if (hDll)
{
FreeLibrary(hDll);
}
TraceError("HrWriteWinsockMapping",hr);
return hr;
}
//
// Function: HrWriteWinsockInfo
//
// Purpose: Commit the Winsock information to the component's Winsock
// section, and also to the Winsock section.
//
// Parameters: strTransport - Name of the transport to be installed
// strDllHelper - Name of the Winsock helper dll
// dwMaxSockAddrLength - ?
// dwMinSockAddrLength - ?
//
// Returns: HRESULT, S_OK on success
//
HRESULT HrWriteWinsockInfo (
tstring& strTransport,
tstring& strDllHelper,
DWORD dwMaxSockAddrLength,
DWORD dwMinSockAddrLength)
{
DWORD dwDisposition;
HKEY hkey;
HRESULT hr;
int i;
WRITEREGDW regdata[2];
tstring strBuf;
// Create/Open the component's Winsock Key
// Verify we don't need an intermediate step to create the key
strBuf = c_szServices;
strBuf += c_szBackslash;
strBuf += strTransport;
strBuf += c_szBackslash;
strBuf += c_szParameters;
strBuf += c_szBackslash;
strBuf += c_szWinsockName;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, strBuf.c_str(),
REG_OPTION_NON_VOLATILE,
KEY_READ_WRITE, NULL, &hkey, &dwDisposition);
if (S_OK != hr)
{
goto Done;
}
// Initialize the information to write
hr = HrRegSetValueEx(hkey, c_szHelperDllName, REG_EXPAND_SZ,
(LPBYTE)(LPBYTE)strDllHelper.c_str(),
strDllHelper.length() * sizeof(WCHAR));
if (S_OK != hr)
{
goto Done;
}
// Initialize the information to write
regdata[0].pszVal = c_szMaxSockAddrLength;
regdata[0].dwData = dwMaxSockAddrLength;
regdata[1].pszVal = c_szMinSockAddrLength;
regdata[1].dwData = dwMinSockAddrLength;
// Write the data to the components Winsock subkey
for (i=0; i<celems(regdata); i++)
{
hr = HrRegSetDword(hkey, regdata[i].pszVal, regdata[i].dwData);
if (S_OK != hr)
{
goto Done;
}
}
// Write the Winsock DLL Mapping information
hr = HrWriteWinsockMapping(strDllHelper.c_str(), hkey);
if (S_OK != hr)
{
goto Done;
}
// Update the Winsock transport list
hr = HrUpdateWinsockTransportList(strTransport.c_str(), TRUE);
Done:
RegSafeCloseKey(hkey);
TraceError("HrWriteWinsockInfo",hr);
return hr;
}
//
// Function: HrInstallWinsockDependancy
//
// Purpose: Examine the current components .inf file and determine whether
// or not a winsock dependancy exists. If the current component
// requires interaction with Winsock, this code will first verify
// if Winsock is already installed. If it is not, then both the
// Winsock and afd services will be installed via a call to the
// function FInstallWinsock. Once that is accomplished, the code
// will update Winsock to be aware of this component and will
// write Winsock specific info to this components Services
// registry section via the function FWriteWinsockInfo. If the
// current component does not have a Winsock dependancy no action
// is taken.
//
// Parameters: hinfInstallFile [IN] - Handle to the current component's
// .inf file.
// szSectionName [IN] - The name of the install/remove section
//
// Returns: HRESULT, S_OK if the component had a Winsock dependancy and
// the registry was updated successfully with the information.
//
HRESULT
HrInstallWinsockDependancy (
HINF hinfInstallFile,
PCWSTR pszSectionName)
{
DWORD dwMaxSockAddrLength;
DWORD dwMinSockAddrLength;
DWORD dwSupportedNameSpace;
DWORD dwVersion = 1;
tstring strDllHelper;
tstring strTransport;
tstring strLibraryPath;
tstring strDisplayString;
tstring strProviderId;
BOOL fSuccess = FALSE;
BOOL fWinsockInstalled;
BOOL fWinsockInfoComplete = FALSE;
BOOL fNamespaceInfoComplete = FALSE;
HRESULT hr = HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
// Search for the "TransportService" property.
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szTransportService, &strTransport);
if (S_OK == hr)
{
// Retrieve the path to the helper DLL
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szHelperDllName, &strDllHelper);
if (FAILED(hr))
{
goto Error;
}
// Retrieve the MaxSockAddrLength
hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
c_szMaxSockAddrLength, &dwMaxSockAddrLength);
if (FAILED(hr))
{
goto Error;
}
// Retrieve the MinSockAddrLength
hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
c_szMinSockAddrLength, &dwMinSockAddrLength);
if (FAILED(hr))
{
goto Error;
}
fWinsockInfoComplete = TRUE;
}
else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
{
goto Error;
}
// Retrieve the Provider ID, if not present then don't registry a
// namespace provider
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szProviderId, &strProviderId);
if (S_OK == hr)
{
// Retrieve the path to Library
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szLibraryName, &strLibraryPath);
if (FAILED(hr))
{
goto Error;
}
// Retrieve the transport providers display string
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szDisplayString, &strDisplayString);
if (FAILED(hr))
{
goto Error;
}
// Retrieve the ID of the supported namespace
hr = HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
c_szSupportedNameSpace, &dwSupportedNameSpace);
if (FAILED(hr))
{
goto Error;
}
// Retrieve Version (optional, defaults to 1)
(VOID)HrSetupGetFirstDword(hinfInstallFile, pszSectionName,
c_szVersion, &dwVersion);
fNamespaceInfoComplete = TRUE;
}
else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
{
goto Error;
}
// Check for Winsock installation (if required)
if (fWinsockInfoComplete || fNamespaceInfoComplete)
{
// Check if winsock is installed
hr = HrIsWinsockInstalled(&fWinsockInstalled);
if (FAILED(hr))
{
goto Error;
}
// Is Winsock already installed? If not, install
// the bloke...
if (!fWinsockInstalled)
{
hr = HrInstallWinsock();
if (FAILED(hr))
{
goto Error;
}
}
}
// Write the data we've collect to the correct
// spots in the registry
if (fWinsockInfoComplete)
{
hr = HrWriteWinsockInfo(strTransport, strDllHelper,
dwMaxSockAddrLength, dwMinSockAddrLength);
if (FAILED(hr))
{
goto Error;
}
}
// Write the namespace provider information if we read the namespace
// provider information
if (fNamespaceInfoComplete)
{
IID guid;
hr = IIDFromString((PWSTR)strProviderId.c_str(), &guid);
if (FAILED(hr))
{
goto Error;
}
hr = HrAddNameSpaceProvider(strDisplayString.c_str(),
strLibraryPath.c_str(),
dwSupportedNameSpace,
dwVersion,
&guid);
if (FAILED(hr))
{
goto Error;
}
}
if (fWinsockInfoComplete || fNamespaceInfoComplete)
{
(void)HrRunWinsock2Migration();
}
Error:
TraceError("HrInstallWinsockDependancy",hr);
return hr;
}
//
// Function: HrRemoveWinsockDependancy
//
// Purpose: Remove the current component from the Winsock
// transport list, if present.
//
// Parameters: hinfInstallFile [IN] - Handle to the current component's
// .inf file.
// pszSectionName [IN] - The name of the install/remove section
//
// Returns: HRESULT, S_OK on success
//
HRESULT HrRemoveWinsockDependancy(HINF hinfInstallFile,
PCWSTR pszSectionName)
{
HRESULT hr;
tstring str;
tstring strTransport;
BOOL fRunWinsockMigration = FALSE;
// Search for the "TransportService" property
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szTransportService, &strTransport);
if (S_OK == hr)
{
HKEY hkey;
// Remove the Transport from the Winsock transport list
hr = HrUpdateWinsockTransportList(strTransport.c_str(), FALSE);
if (FAILED(hr))
{
goto Error;
}
fRunWinsockMigration = TRUE;
// Remove the Winsock subkey under the specified transport
// But ignore failures, as we're just trying to be tidy
str = c_szServices;
str += c_szBackslash;
str += strTransport.c_str();
str += c_szBackslash;
str += c_szParameters;
if (S_OK == HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, str.c_str(),
KEY_READ_WRITE_DELETE, &hkey))
{
HrRegDeleteKeyTree(hkey, c_szWinsockName);
RegCloseKey(hkey);
}
}
else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
{
goto Error;
}
// Remove the Winsock Namespace provider
hr = HrSetupGetFirstString(hinfInstallFile, pszSectionName,
c_szProviderId, &str);
if (S_OK == hr)
{
IID guid;
hr = IIDFromString((PWSTR)str.c_str(), &guid);
if (FAILED(hr))
{
goto Error;
}
// Don't fail, the name space may not have been successfully registered.
// Especially if the component installation failed.
HrRemoveNameSpaceProvider(&guid);
fRunWinsockMigration = TRUE;
}
else if ((SPAPI_E_SECTION_NOT_FOUND != hr) && (SPAPI_E_LINE_NOT_FOUND != hr))
{
goto Error;
}
if (fRunWinsockMigration)
{
(void)HrRunWinsock2Migration();
}
hr = S_OK; // Normalize return
Error:
TraceError("HrRemoveWinsockDependancy",hr);
return hr;
}
//
// Function: HrAddOrRemoveWinsockDependancy
//
// Purpose: To add or remove Winsock dependancies for components
//
// Parameters: hinfInstallFile [IN] - The handle to the inf file to install
// from
// pszSectionName [IN] - The Base install section name.
// (The prefix for the .Services section)
//
// Returns: HRESULT, S_OK on success
//
HRESULT
HrAddOrRemoveWinsockDependancy (
HINF hinfInstallFile,
PCWSTR pszSectionName)
{
Assert(IsValidHandle(hinfInstallFile));
HRESULT hr;
hr = HrProcessInfExtension(hinfInstallFile, pszSectionName,
c_szWinsockName, c_szAddSecLabel,
c_szRemoveSecLabel, HrInstallWinsockDependancy,
HrRemoveWinsockDependancy);
if (SPAPI_E_LINE_NOT_FOUND == hr)
{
// .Winsock section is not required
hr = S_OK;
}
TraceError("HrAddOrRemoveWinsockDependancy",hr);
return hr;
}