windows-nt/Source/XPSP1/NT/base/cluster/setup/common/removenetworkprovider.cpp
2020-09-26 16:20:57 +08:00

241 lines
8.3 KiB
C++

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <tchar.h>
extern "C" {
#include <wsasetup.h>
}
/////////////////////////////////////////////////////////////////////////////
//++
//
// RemoveNetworkProvider
//
// Routine Description:
// This routine uninstalls the Clustering Service Network Provider.
//
// Arguments:
// None
//
// Return Value:
// (DWORD) ERROR_SUCCESS - indicates success
// Any other value is a Win32 error code.
//
// Note:
// This function was adapted from removeNetworkProvider in the NT 4.0
// Cluster "setup" program.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD RemoveNetworkProvider( void )
{
DWORD dwReturnValue;
LONG lReturnValue;
//
// The inf file will take care of deleting the clusnet winsock key.
// We just need to delete clusnet from the list of winsock transports.
//
//
// Open the winsock service parameters key.
//
HKEY hWinsockParametersRegKey;
lReturnValue = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Services\\WinSock\\Parameters"),
(DWORD) 0L, // reserved
MAXIMUM_ALLOWED,
(PHKEY) &hWinsockParametersRegKey );
dwReturnValue = (DWORD) lReturnValue;
if ( lReturnValue == (LONG) ERROR_SUCCESS )
{
//
// Update the winsock transports list.
//
// Allocate memory into which to read the Winsock Transports List.
LPBYTE pWinsockTransportsList;
DWORD dwWinsockTransportsListSize = 200; // arbitrary size
pWinsockTransportsList = (LPBYTE) LocalAlloc( LPTR, dwWinsockTransportsListSize );
// Was the buffer for the Winsock Transports List allocated?
if ( pWinsockTransportsList != (LPBYTE) NULL )
{
// Read the Winsock Transports List from the registry.
DWORD dwRegKeyType;
lReturnValue = RegQueryValueEx( hWinsockParametersRegKey,
TEXT("Transports"),
(LPDWORD) NULL,
&dwRegKeyType,
pWinsockTransportsList,
&dwWinsockTransportsListSize );
// Was the Winsock Transports List read on the first attempt?
if ( lReturnValue != (LONG) ERROR_SUCCESS )
{
// Was the buffer too small?
if ( lReturnValue == (LONG) ERROR_MORE_DATA )
{
// The Winsock Transports List was not read form the registry because
// the buffer was too small. Increase the size of the buffer.
pWinsockTransportsList = (LPBYTE) LocalReAlloc( pWinsockTransportsList,
(UINT) dwWinsockTransportsListSize,
(UINT) LMEM_ZEROINIT );
// Was the buffer reallocation successfull?
if ( pWinsockTransportsList != (LPBYTE) NULL )
{
// Attempt to read the Wincosk Transports List a second time.
lReturnValue = RegQueryValueEx( hWinsockParametersRegKey,
TEXT("Transports"),
(LPDWORD) NULL,
&dwRegKeyType,
pWinsockTransportsList,
&dwWinsockTransportsListSize );
// Was the Winsock Transports List read on the second attempt?
if ( lReturnValue != (LONG) ERROR_SUCCESS )
{
dwReturnValue = (DWORD) lReturnValue;
} // Was the Winsock Transports List read on the second attempt?
} // Was the buffer reallocation successfull?
else
{
dwReturnValue = GetLastError();
} // Was the buffer reallocation successfull?
} // Was the buffer too small?
} // Was the Winsock Transports List read on the first attempt?
// At this point variable lReturnValue indicates whether the Winsock
// Transports List was read from the registry.
if ( lReturnValue == (LONG) ERROR_SUCCESS )
{
// Is the type of the registry value correct?
if ( dwRegKeyType == (DWORD) REG_MULTI_SZ )
{
LPTSTR ptszOldTransportsList;
ptszOldTransportsList = (LPTSTR) pWinsockTransportsList;
LPTSTR ptszNewTransportList;
ptszNewTransportList = (LPTSTR) LocalAlloc( LMEM_FIXED, dwWinsockTransportsListSize );
// Was the buffer for the new Winsock Transports List allocated successfully?
if ( ptszNewTransportList != (LPTSTR) NULL )
{
// Start building a list of Winsock Transports that does not include
// the Clustering Service Network Provider.
LPTSTR ptszNextTransport;
ptszNextTransport = ptszNewTransportList;
// Initialize the size of the new Winsock Transports List to zero.
dwWinsockTransportsListSize = (DWORD) 0L;
DWORD dwIndividualTransportLength;
while ( *ptszOldTransportsList != UNICODE_NULL )
{
dwIndividualTransportLength = _tcslen(ptszOldTransportsList) + 1;
// This comparison is case insensitive, like registry values.
if ( _tcsicmp( ptszOldTransportsList, TEXT("ClusNet") ) != 0 )
{
_tcscpy( ptszNextTransport, ptszOldTransportsList );
ptszNextTransport += dwIndividualTransportLength;
dwWinsockTransportsListSize += dwIndividualTransportLength * sizeof(WCHAR);
};
ptszOldTransportsList += dwIndividualTransportLength;
} // end of while loop
*ptszNextTransport = UNICODE_NULL;
dwWinsockTransportsListSize += sizeof( UNICODE_NULL );
// Save the new Winsock Transports List in the registry.
ASSERT( dwWinsockTransportsListSize != 0L );
lReturnValue = RegSetValueEx( hWinsockParametersRegKey,
TEXT("Transports"),
NULL,
dwRegKeyType,
(CONST BYTE *) ptszNewTransportList,
dwWinsockTransportsListSize );
if ( lReturnValue == (LONG) ERROR_SUCCESS )
{
//
// Poke winsock to update the Winsock2 config
//
WSA_SETUP_DISPOSITION disposition;
dwReturnValue = MigrateWinsockConfiguration( &disposition, NULL, NULL );
}
else
{
dwReturnValue = (DWORD) lReturnValue;
}
// Free the buffer for the new Winsock Transports List.
LocalFree( ptszNewTransportList );
}
else
{
dwReturnValue = GetLastError();
} // Was the buffer for the new Winsock Transports List allocated successfully?
}
else
{
dwReturnValue = ERROR_INVALID_PARAMETER;
} // Is the type of the registry value correct?
} // Did one of the attempts to read the Winsock Transports List succeed?
// Free the buffer for the Winsock Transports List.
if ( pWinsockTransportsList != (LPBYTE) NULL )
{
LocalFree( pWinsockTransportsList );
}
} // Was the buffer for the Winsock Transports List allocated?
else
{
dwReturnValue = GetLastError();
} // Was the buffer for the Winsock Transports List allocated?
} // Was the Winsock Parameters key opened?
return ( dwReturnValue );
}