windows-nt/Source/XPSP1/NT/net/sockets/winsock2/util/ws2inst/ws2inst.c

1472 lines
31 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
ws2inst.c
Abstract:
This is a temporary WinSock 2 transport & namespace service provider
installation utility.
The command line arguments for this utility are:
ws2inst operation file.ini [options]
Where operation is one of the following:
install - Installs the service provider[s] specified in the
.INI file.
remove - Removes the service provider[s] specified in the .INI
file.
And options may be one or more of the following:
-t - Install/remove transport provider only.
-n - Install/remove namespace provider only.
-b - Install/remove transport and namespace providers (default).
-e - Ignore errors.
The layout of the .INI file is:
[WinSock 2 Transport Service Providers]
ProviderCount = N
Provider0 = Transport_Provider_0_Section_Name
Provider1 = Transport_Provider_1_Section_Name
Provider2 = Transport_Provider_2_Section_Name
.
.
.
ProviderN-1 = Transport_Provider_N-1_Section_Name
[Transport_Provider_X_Section_Name]
ProviderName = Provider_Name
ProviderPath = Path_To_Providers_Dll
ProviderId = Provider_Guid
ProtocolCount = M
[Transport_Provider_X_Section_Name Protocol M]
dwServiceFlags1 = x
dwServiceFlags2 = x
dwServiceFlags3 = x
dwServiceFlags4 = x
dwProviderFlags = x
iVersion = x
iAddressFamily = x
iMaxSockAddr = x
iMinSockAddr = x
iSocketType = x
iProtocol = x
iProtocolMaxOffset = x
iNetworkByteOrder = x
iSecurityScheme = x
dwMessageSize = x
dwProviderReserved = x
szProtocol = Protocol_Name
[WinSock 2 Name Space Providers]
ProviderCount = N
Provider0 = Name_Space_Provider_0_Section_Name
Provider1 = Name_Space_Provider_1_Section_Name
Provider2 = Name_Space_Provider_2_Section_Name
.
.
.
ProviderN-1 = Name_Space_Provider_N-1_Section_Name
[Name_Space_Provider_X_Section_Name]
ProviderName = Provider_Name
ProviderPath = Path_To_Providers_DLL
ProviderId = Provider_Guid
NameSpaceId = Name_Space_ID
Author:
Keith Moore (keithmo) 17-Jun-1996
Revision History:
--*/
#include "precomp.h"
//
// Private constants.
//
#define MAX_INIFILE_LINE 256
#define TRANSPORT_SECTION_NAME TEXT("WinSock 2 Transport Service Providers")
#define NAMESPACE_SECTION_NAME TEXT("WinSock 2 Name Space Providers")
#define OPTION_FLAG_TRANSPORT 0x00000001
#define OPTION_FLAG_NAMESPACE 0x00000002
#define OPTION_FLAG_BOTH 0x00000003 // transport and namespace
#define OPTION_FLAG_IGNORE_ERRORS 0x00000004
//
// Private types.
//
typedef
BOOL
(CALLBACK * LPFN_ENUM_SECTION_CALLBACK)(
LPTSTR IniFile,
LPTSTR ProviderSectionName,
DWORD Context
);
//
// Private prototypes.
//
VOID
Usage(
VOID
);
VOID
InstallFromIniFile(
LPTSTR IniFile,
DWORD Options
);
VOID
RemoveFromIniFile(
LPTSTR IniFile,
DWORD Options
);
VOID
EnumProviderSections(
LPTSTR IniFile,
LPTSTR SectionName,
LPFN_ENUM_SECTION_CALLBACK Callback,
DWORD Context
);
BOOL
InstallTransportProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
);
BOOL
RemoveTransportProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
);
BOOL
InstallNameSpaceProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
);
BOOL
RemoveNameSpaceProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
);
//
// Public functions.
//
INT
__cdecl
_tmain(
INT argc,
LPTSTR argv[]
)
/*++
Routine Description:
Main program entrypoint.
Arguments:
argc - Number of command line arguments.
argv - Array of pointers to command line arguments.
Return Value:
INT - Completion status.
--*/
{
LPTSTR opCode;
LPTSTR iniFile;
LPTSTR arg;
DWORD options;
INT i;
//
// Interpret the command line arguments.
//
if( argc < 3 ) {
Usage();
return 1;
}
opCode = argv[1];
iniFile = argv[2];
options = 0;
for( i = 3 ; i < argc ; i++ ) {
arg = argv[i];
if( *arg != TEXT('-') ) {
Usage();
return 1;
}
arg++;
while( *arg != TEXT('\0') ) {
switch( *arg++ ) {
case TEXT('t') :
case TEXT('T') :
options |= OPTION_FLAG_TRANSPORT;
break;
case TEXT('n') :
case TEXT('N') :
options |= OPTION_FLAG_NAMESPACE;
break;
case TEXT('b') :
case TEXT('B') :
options |= OPTION_FLAG_BOTH;
break;
case TEXT('e') :
case TEXT('E') :
options |= OPTION_FLAG_IGNORE_ERRORS;
break;
default :
Usage();
return 1;
}
}
}
//
// Default == install transports and namespaces.
//
if( ( options & ( OPTION_FLAG_BOTH ) ) == 0 ) {
options |= OPTION_FLAG_BOTH;
}
if( _tcsicmp( opCode, TEXT("install") ) == 0 ) {
InstallFromIniFile(
iniFile,
options
);
} else if( _tcsicmp( opCode, TEXT("remove") ) == 0 ) {
RemoveFromIniFile(
iniFile,
options
);
} else {
Usage();
return 1;
}
return 0;
} // main
//
// Private functions.
//
VOID
Usage(
VOID
)
/*++
Routine Description:
Displays this utility's proper command line parameters.
Arguments:
None.
Return Value:
None.
--*/
{
_ftprintf(
stderr,
TEXT("WS2INST 0.03 by Keith Moore %hs\n")
TEXT("use: WS2INST Operation file.ini [Options]\n")
TEXT("where Operation may be one of the following:\n")
TEXT(" install - Installs service providers specified in .INI file\n")
TEXT(" remove - Removes service providers specified in .INI file\n")
TEXT("and Options may be one or more of the following:\n")
TEXT(" -t - Install/remove transport providers only\n")
TEXT(" -n - Install/remove namespace providers only\n")
TEXT(" -b - Install/remove both (default)\n")
TEXT(" -i - Ignore errors\n"),
__DATE__
);
} // Usage
VOID
InstallFromIniFile(
LPTSTR IniFile,
DWORD Options
)
/*++
Routine Description:
Installs transports and/or namespace providers specified in the
given .INI file.
Arguments:
IniFile - The .INI file describing the providers to install.
Options - Behaviour control options (OPTION_FLAG_*).
Return Value:
None.
--*/
{
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Installing from %s\n"),
IniFile
);
//
// Install transport providers if so requested.
//
if( Options & OPTION_FLAG_TRANSPORT ) {
EnumProviderSections(
IniFile,
TRANSPORT_SECTION_NAME,
InstallTransportProviderCallback,
Options
);
}
//
// Install namespace providers if so requested.
//
if( Options & OPTION_FLAG_NAMESPACE ) {
EnumProviderSections(
IniFile,
NAMESPACE_SECTION_NAME,
InstallNameSpaceProviderCallback,
Options
);
}
} // InstallFromIniFile
VOID
RemoveFromIniFile(
LPTSTR IniFile,
DWORD Options
)
/*++
Routine Description:
Removes transports and/or namespace providers specified in the
given .INI file.
Arguments:
IniFile - The .INI file describing the providers to remove.
Options - Behaviour control options (OPTION_FLAG_*).
Return Value:
None.
--*/
{
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Removing from %s\n"),
IniFile
);
//
// Remove transport providers if so requested.
//
if( Options & OPTION_FLAG_TRANSPORT ) {
EnumProviderSections(
IniFile,
TRANSPORT_SECTION_NAME,
RemoveTransportProviderCallback,
Options
);
}
//
// Remove namespace providers if so requested.
//
if( Options & OPTION_FLAG_NAMESPACE ) {
EnumProviderSections(
IniFile,
NAMESPACE_SECTION_NAME,
RemoveNameSpaceProviderCallback,
Options
);
}
} // RemoveFromIniFile
VOID
EnumProviderSections(
LPTSTR IniFile,
LPTSTR SectionName,
LPFN_ENUM_SECTION_CALLBACK Callback,
DWORD Context
)
/*++
Routine Description:
Enumerates the provider sections in the specified .INI file. The
sections must be in the following format:
[section_name]
ProviderCount=N
Provider0=provider_0_name
Provider1=provider_1_name
Provider2=provider_2_name
.
.
.
ProviderN-1=provider_N-1_name
Arguments:
IniFile - The .INI file containing the sections to enumerate.
SectionName - The name of the section to enumerate.
Callback - Pointer to a callback routine. The callback is invoked
once for each section. The prototype for the callback is:
BOOL
CALLBACK
EnumSectionProc(
LPTSTR IniFile,
LPTSTR ProviderSectionName,
DWORD Context
);
Where:
IniFile - The .INI filename passed into EnumProviderSections().
ProviderSectionName - The name of the current section.
Context - The context value passed into EnumProviderSections().
If the callback routine returns FALSE, then the enumeration is
aborted. If the callback routine returns TRUE, then the enumeration
is continued.
Context - An uninterpreted context value passed to the callback function.
Return Value:
None.
--*/
{
TCHAR providerSectionName[MAX_INIFILE_LINE];
TCHAR keyName[MAX_INIFILE_LINE];
DWORD length;
UINT providerCount;
UINT i;
BOOL result;
//
// Get the provider count.
//
providerCount = GetPrivateProfileInt(
SectionName,
TEXT("ProviderCount"),
0,
IniFile
);
if( providerCount == 0 ) {
return;
}
//
// Do that enumeration thang.
//
for( i = 0 ; i < providerCount ; i++ ) {
wsprintf(
keyName,
TEXT("Provider%u"),
i
);
length = GetPrivateProfileString(
SectionName,
keyName,
TEXT(""),
providerSectionName,
sizeof(providerSectionName) / sizeof(providerSectionName[0]),
IniFile
);
if( length > 0 ) {
result = (Callback)(
IniFile,
providerSectionName,
Context
);
if( !result ) {
break;
}
}
}
} // EnumProviderSections
BOOL
InstallTransportProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
)
/*++
Routine Description:
Callback routine for EnumProviderSections() that installs the
transport service provider described by the given .INI file section.
Arguments:
IniFile - The name of the .INI file describing the transport provider.
SectionName - The name of the .INI file section for this provider.
Context - Actually contains behaviour control options (OPTION_FLAG_*).
Return Value:
BOOL - TRUE if successful, FALSE otherwise.
--*/
{
TCHAR providerName[MAX_INIFILE_LINE];
TCHAR providerPath[MAX_INIFILE_LINE];
TCHAR providerIdString[MAX_INIFILE_LINE];
TCHAR protocolSectionName[MAX_INIFILE_LINE];
UINT protocolCount;
UINT i;
DWORD length;
LPWSAPROTOCOL_INFO protocolInfo;
INT result;
INT error;
GUID providerId;
RPC_STATUS status;
BOOL ignoreErrors;
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Installing %s\n"),
SectionName
);
//
// Determine if we should ignore errors. If so, then this routine
// will always return TRUE.
//
ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
//
// Read the fixed information.
//
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderName"),
TEXT(""),
providerName,
sizeof(providerName) / sizeof(providerName[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderName key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderPath"),
TEXT(""),
providerPath,
sizeof(providerPath) / sizeof(providerPath[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderPath key\n")
);
return ignoreErrors;
}
protocolCount = GetPrivateProfileInt(
SectionName,
TEXT("ProtocolCount"),
0,
IniFile
);
if( protocolCount == 0 ) {
_tprintf(
TEXT("ERROR: missing ProtocolCount key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderId"),
TEXT(""),
providerIdString,
sizeof(providerIdString) / sizeof(providerIdString[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderId key\n")
);
return ignoreErrors;
}
//
// Build the GUID.
//
status = UuidFromString(
providerIdString,
&providerId
);
if( status != RPC_S_OK ) {
_tprintf(
TEXT("ERROR: invalid ProviderId %s\n"),
providerIdString
);
return ignoreErrors;
}
//
// Allocate the space for the protocol info structures.
//
protocolInfo = malloc( protocolCount * sizeof(*protocolInfo) );
if( protocolInfo == NULL ) {
_tprintf(
TEXT("ERROR: out of memory\n")
);
return ignoreErrors;
}
//
// Enumerate the protocols.
//
for( i = 0 ; i < protocolCount ; i++ ) {
//
// Build the section name for this protocol.
//
wsprintf(
protocolSectionName,
TEXT("%s Protocol %u"),
SectionName,
i
);
//
// Read the individual protocol info.
//
protocolInfo[i].dwServiceFlags1 = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwServiceFlags1"),
0,
IniFile
);
protocolInfo[i].dwServiceFlags2 = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwServiceFlags2"),
0,
IniFile
);
protocolInfo[i].dwServiceFlags3 = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwServiceFlags3"),
0,
IniFile
);
protocolInfo[i].dwServiceFlags4 = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwServiceFlags4"),
0,
IniFile
);
protocolInfo[i].dwProviderFlags = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwProviderFlags"),
0,
IniFile
);
protocolInfo[i].iVersion = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iVersion"),
0,
IniFile
);
protocolInfo[i].iAddressFamily = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iAddressFamily"),
0,
IniFile
);
protocolInfo[i].iMaxSockAddr = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iMaxSockAddr"),
0,
IniFile
);
protocolInfo[i].iMinSockAddr = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iMinSockAddr"),
0,
IniFile
);
protocolInfo[i].iSocketType = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iSocketType"),
0,
IniFile
);
protocolInfo[i].iProtocol = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iProtocol"),
0,
IniFile
);
protocolInfo[i].iProtocolMaxOffset = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iProtocolMaxOffset"),
0,
IniFile
);
protocolInfo[i].iNetworkByteOrder = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iNetworkByteOrder"),
0,
IniFile
);
protocolInfo[i].iSecurityScheme = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("iSecurityScheme"),
0,
IniFile
);
protocolInfo[i].dwMessageSize = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwMessageSize"),
0,
IniFile
);
protocolInfo[i].dwProviderReserved = (DWORD)GetPrivateProfileInt(
protocolSectionName,
TEXT("dwProviderReserved"),
0,
IniFile
);
length = GetPrivateProfileString(
protocolSectionName,
TEXT("szProtocol"),
TEXT(""),
protocolInfo[i].szProtocol,
sizeof(protocolInfo[i].szProtocol) / sizeof(protocolInfo[i].szProtocol[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing szProtocol key\n")
);
free( protocolInfo );
return ignoreErrors;
}
}
//
// OK, we've got the protocol data, now just ask WS2_32.DLL to
// install 'em.
//
result = WSCInstallProvider(
&providerId,
providerPath,
protocolInfo,
(DWORD)protocolCount,
&error
);
free( protocolInfo );
if( result == SOCKET_ERROR ) {
_tprintf(
TEXT("Cannot install %s, error %d\n"),
providerName,
error
);
return ignoreErrors;
}
return TRUE;
} // InstallTransportProviderCallback
BOOL
RemoveTransportProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
)
/*++
Routine Description:
Callback routine for EnumProviderSections() that removes the
transport service provider described by the given .INI file section.
Arguments:
IniFile - The name of the .INI file describing the transport provider.
SectionName - The name of the .INI file section for this provider.
Context - Actually contains behaviour control options (OPTION_FLAG_*).
Return Value:
BOOL - TRUE if successful, FALSE otherwise.
--*/
{
TCHAR providerName[MAX_INIFILE_LINE];
TCHAR providerIdString[MAX_INIFILE_LINE];
DWORD length;
INT result;
INT error;
GUID providerId;
RPC_STATUS status;
BOOL ignoreErrors;
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Removing %s\n"),
SectionName
);
//
// Determine if we should ignore errors. If so, then this routine
// will always return TRUE.
//
ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
//
// Read the provider name & ID.
//
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderName"),
TEXT(""),
providerName,
sizeof(providerName) / sizeof(providerName[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderName key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderId"),
TEXT(""),
providerIdString,
sizeof(providerIdString) / sizeof(providerIdString[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderId key\n")
);
return ignoreErrors;
}
//
// Build the GUID.
//
status = UuidFromString(
providerIdString,
&providerId
);
if( status != RPC_S_OK ) {
_tprintf(
TEXT("ERROR: invalid ProviderId %s\n"),
providerIdString
);
return ignoreErrors;
}
//
// Remove it.
//
result = WSCDeinstallProvider(
&providerId,
&error
);
if( result == SOCKET_ERROR ) {
_tprintf(
TEXT("Cannot remove %s, error %d\n"),
providerName,
error
);
return ignoreErrors;
}
return TRUE;
} // RemoveTransportProviderCallback
BOOL
InstallNameSpaceProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
)
/*++
Routine Description:
Callback routine for EnumProviderSections() that installs the
namespace service provider described by the given .INI file section.
Arguments:
IniFile - The name of the .INI file describing the namespace provider.
SectionName - The name of the .INI file section for this provider.
Context - Actually contains behaviour control options (OPTION_FLAG_*).
Return Value:
BOOL - TRUE if successful, FALSE otherwise.
--*/
{
TCHAR providerName[MAX_INIFILE_LINE];
TCHAR providerPath[MAX_INIFILE_LINE];
TCHAR providerIdString[MAX_INIFILE_LINE];
UINT i;
DWORD length;
INT result;
INT error;
GUID providerId;
DWORD nameSpaceId;
RPC_STATUS status;
BOOL ignoreErrors;
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Installing %s\n"),
SectionName
);
//
// Determine if we should ignore errors. If so, then this routine
// will always return TRUE.
//
ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
//
// Read the fixed information.
//
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderName"),
TEXT(""),
providerName,
sizeof(providerName) / sizeof(providerName[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderName key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderPath"),
TEXT(""),
providerPath,
sizeof(providerPath) / sizeof(providerPath[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderPath key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderId"),
TEXT(""),
providerIdString,
sizeof(providerIdString) / sizeof(providerIdString[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderId key\n")
);
return ignoreErrors;
}
//
// Build the GUID.
//
status = UuidFromString(
providerIdString,
&providerId
);
if( status != RPC_S_OK ) {
_tprintf(
TEXT("ERROR: invalid ProviderId %s\n"),
providerIdString
);
return ignoreErrors;
}
nameSpaceId = GetPrivateProfileInt(
SectionName,
TEXT("NameSpaceId"),
0,
IniFile
);
if( nameSpaceId == 0 ) {
_tprintf(
TEXT("ERROR: missing NameSpaceId key\n")
);
return ignoreErrors;
}
//
// Install it.
//
result = WSCInstallNameSpace(
providerName,
providerPath,
nameSpaceId,
2,
&providerId
);
if( result == SOCKET_ERROR ) {
error = GetLastError();
_tprintf(
TEXT("Cannot install %s, error %d\n"),
providerName,
error
);
return ignoreErrors;
}
return TRUE;
} // InstallNameSpaceProviderCallback
BOOL
RemoveNameSpaceProviderCallback(
LPTSTR IniFile,
LPTSTR SectionName,
DWORD Context
)
/*++
Routine Description:
Callback routine for EnumProviderSections() that removes the
namespace service provider described by the given .INI file section.
Arguments:
IniFile - The name of the .INI file describing the namespace provider.
SectionName - The name of the .INI file section for this provider.
Context - Actually contains behaviour control options (OPTION_FLAG_*).
Return Value:
BOOL - TRUE if successful, FALSE otherwise.
--*/
{
TCHAR providerName[MAX_INIFILE_LINE];
TCHAR providerIdString[MAX_INIFILE_LINE];
DWORD length;
INT result;
INT error;
GUID providerId;
RPC_STATUS status;
BOOL ignoreErrors;
//
// Let the user know what we're up to.
//
_tprintf(
TEXT("Removing %s\n"),
SectionName
);
//
// Determine if we should ignore errors. If so, then this routine
// will always return TRUE.
//
ignoreErrors = ( ( Context & OPTION_FLAG_IGNORE_ERRORS ) != 0 );
//
// Read the provider name & ID.
//
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderName"),
TEXT(""),
providerName,
sizeof(providerName) / sizeof(providerName[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderName key\n")
);
return ignoreErrors;
}
length = GetPrivateProfileString(
SectionName,
TEXT("ProviderId"),
TEXT(""),
providerIdString,
sizeof(providerIdString) / sizeof(providerIdString[0]),
IniFile
);
if( length == 0 ) {
_tprintf(
TEXT("ERROR: missing ProviderId key\n")
);
return ignoreErrors;
}
//
// Build the GUID.
//
status = UuidFromString(
providerIdString,
&providerId
);
if( status != RPC_S_OK ) {
_tprintf(
TEXT("ERROR: invalid ProviderId %s\n"),
providerIdString
);
return ignoreErrors;
}
//
// Remove it.
//
result = WSCUnInstallNameSpace(
&providerId
);
if( result == SOCKET_ERROR ) {
error = GetLastError();
_tprintf(
TEXT("Cannot remove %s, error %d\n"),
providerName,
error
);
return ignoreErrors;
}
return TRUE;
} // RemoveNameSpaceProviderCallback