|
|
/*++
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
|