1472 lines
31 KiB
C
1472 lines
31 KiB
C
|
/*++
|
|||
|
|
|||
|
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
|
|||
|
|