Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

733 lines
12 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
ws2setup
Abstract:
This module contains a simple setup application for NT WinSock 2.0.
This application migrates the existing WinSock 1.1 information stored
in the registry to WinSock 2.0.
Author:
Keith Moore (keithmo) 9-Oct-1995
Revision History:
--*/
#include "precomp.h"
//
// Private constants.
//
#define MAX_REGISTRY_NAME 256
#define SERVICES_KEY "System\\CurrentControlSet\\Services"
#define WINSOCK_SUBKEY "WinSock"
#define MIGRATION_SUBKEY "Setup Migration"
#define WINSOCK2_SUBKEY "WinSock2"
#define WINSOCK2_PARAM_SUBKEY "WinSock2\\Parameters"
#define MAX_CATALOG_NAME_LENGTH 32 // stolen from dll\include\wsautil.h
//
// Private prototypes.
//
BOOL
CALLBACK
MigrationCallback(
WSA_SETUP_OPCODE Opcode,
LPVOID Parameter,
DWORD Context
);
DWORD
CleanWinsock2Tree(
VOID
);
DWORD
OpenServicesRoot(
PHKEY ServicesKey
);
DWORD
OpenWinsockRoot(
HKEY ServicesKey,
PHKEY WinsockKey
);
DWORD
OpenWinsock2ParametersRoot(
HKEY ServicesKey,
PHKEY Winsock2ParametersKey
);
DWORD
RecursivelyDeleteRegistryTree(
HKEY RootKey,
LPSTR TargetKeyName
);
//
// Public functions.
//
INT
_CRTAPI1
main(
INT argc,
CHAR * argv[]
)
{
DWORD error;
WSA_SETUP_DISPOSITION disposition;
BOOL cleanFirst;
HMODULE winsockDllHandle;
LPFN_MIGRATE_WINSOCK_CONFIGURATION migrateWinsockConfiguration;
//
// Interpret the command line arguments.
//
cleanFirst = FALSE;
if( argc != 1 ) {
if( argc == 2 &&
_stricmp( argv[1], "clean" ) == 0 ) {
cleanFirst = TRUE;
} else {
printf( "Use: ws2setup [clean]\n" );
return 1;
}
}
//
// If necessary, blow away the old WinSock 2.0 tree before continuing.
// If this fails, tell the user but press on regardless.
//
if( cleanFirst ) {
printf( "Cleaning WinSock 2.0 Protocol Catalog..." );
error = CleanWinsock2Tree();
if( error == NO_ERROR ) {
printf( "done\n" );
} else {
printf( "error %lu\n", error );
}
}
//
// Load WSOCK32.DLL. Note that we must dynamically load it; otherwise,
// it will cache registry data that we may want to delete.
//
winsockDllHandle = LoadLibrary( "WSOCK32.DLL" );
if( winsockDllHandle == NULL ) {
error = GetLastError();
printf( "Cannot load WSOCK32.DLL, error %lu\n", error );
return 1;
}
migrateWinsockConfiguration = (PVOID)GetProcAddress(
winsockDllHandle,
"MigrateWinsockConfiguration"
);
if( migrateWinsockConfiguration == NULL ) {
error = GetLastError();
printf( "Cannot find MigrateWinsockConfiguration(), error %lu\n", error );
return 1;
}
//
// Do it.
//
printf( "Updating configuration info...\n" );
error = migrateWinsockConfiguration(
&disposition,
&MigrationCallback,
0 );
if( error != 0 ) {
printf( "MigrateWinsockConfiguration() failed, error %lu\n", error );
return 1;
}
switch( disposition ) {
case WsaSetupNoChangesMade:
printf( "No configuration changes necessary\n" );
break;
case WsaSetupChangesMadeRebootNotNecessary:
case WsaSetupChangesMadeRebootRequired:
printf( "Configuration changes made successfully\n" );
break;
default:
printf(
"MigrateWinsockConfiguration() returned invalid disposition %d\n",
disposition
);
break;
}
return 0;
} // main
//
// Private functions.
//
BOOL
CALLBACK
MigrationCallback(
WSA_SETUP_OPCODE Opcode,
LPVOID Parameter,
DWORD Context
)
{
switch( Opcode ) {
case WsaSetupInstallingProvider :
printf( " Installing %ls\n", Parameter );
break;
case WsaSetupRemovingProvider :
printf( " Removing %ls\n", Parameter );
break;
case WsaSetupValidatingProvider :
printf( " Validating %ls\n", Parameter );
break;
case WsaSetupUpdatingProvider :
printf( " Updating %ls\n", Parameter );
break;
default :
printf( "MigrationCallback(): unknown opcode %d\n", Opcode );
break;
}
return TRUE;
} // MigrationCallback
DWORD
CleanWinsock2Tree(
VOID
)
{
DWORD error;
HKEY servicesKey;
HKEY winsockKey;
HKEY winsock2ParametersKey;
DWORD valueType;
DWORD valueLength;
CHAR currentProtocolCatalog[MAX_CATALOG_NAME_LENGTH];
//
// Setup locals so we know how to cleanup on exit.
//
servicesKey = NULL;
winsockKey = NULL;
winsock2ParametersKey = NULL;
//
// Open the services registry key.
//
error = OpenServicesRoot(
&servicesKey
);
if( error != NO_ERROR ) {
goto exit;
}
//
// Open the winsock registry key.
//
error = OpenWinsockRoot(
servicesKey,
&winsockKey
);
if( error != NO_ERROR ) {
goto exit;
}
//
// Open the winsock2 parameters registry key.
//
error = OpenWinsock2ParametersRoot(
servicesKey,
&winsock2ParametersKey
);
if( error != NO_ERROR ) {
goto exit;
}
//
// Determine the current protocol catalog key name.
//
valueLength = sizeof(currentProtocolCatalog);
error = RegQueryValueEx(
winsock2ParametersKey,
WINSOCK_CURRENT_PROTOCOL_CATALOG_NAME,
NULL,
&valueType,
currentProtocolCatalog,
&valueLength
);
if( error == NO_ERROR ) {
//
// Delete the WinSock 2.0 protocol catalog key.
//
error = RecursivelyDeleteRegistryTree(
winsock2ParametersKey,
currentProtocolCatalog
);
if( error != NO_ERROR ) {
goto exit;
}
} else {
//
// This system's registry does not have the "current catalog"
// value, so try all catalog names used prior to the introduction
// of this value.
//
// Note that, since we're not taking the trouble to find out
// exactly which registry key is being used for the protocol
// catalog, we'll ignore any errors generated by these operations.
//
(VOID)RecursivelyDeleteRegistryTree(
winsock2ParametersKey,
"Protocol_Catalog"
);
(VOID)RecursivelyDeleteRegistryTree(
winsock2ParametersKey,
"Protocol_Catalog0"
);
(VOID)RecursivelyDeleteRegistryTree(
winsock2ParametersKey,
"Protocol_Catalog4"
);
(VOID)RecursivelyDeleteRegistryTree(
winsock2ParametersKey,
"Protocol_Catalog5"
);
error = NO_ERROR;
}
//
// Delete the setup migration key.
//
error = RecursivelyDeleteRegistryTree(
winsockKey,
MIGRATION_SUBKEY
);
if( error != NO_ERROR ) {
goto exit;
}
//
// Success!
//
exit:
if( servicesKey != NULL ) {
(VOID)RegCloseKey( servicesKey );
}
if( winsockKey != NULL ) {
(VOID)RegCloseKey( winsockKey );
}
if( winsock2ParametersKey != NULL ) {
(VOID)RegCloseKey( winsock2ParametersKey );
}
return error;
} // CleanWinsock2Tree
DWORD
OpenServicesRoot(
PHKEY ServicesKey
)
/*++
Routine Description:
Opens the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
registry key.
Arguments:
ServicesKey - Will receive a handle to the registry key if successful.
Return Value:
DWORD - A Win32 status code, 0 if successful, !0 otherwise.
--*/
{
DWORD error;
//
// Open the key.
//
error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
SERVICES_KEY,
0,
KEY_ALL_ACCESS,
ServicesKey
);
return error;
} // OpenServicesRoot
DWORD
OpenWinsockRoot(
HKEY ServicesKey,
PHKEY WinsockKey
)
/*++
Routine Description:
Opens the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\WinSock
registry key.
Arguments:
ServicesKey - The handle to the ...\Services key.
WinsockKey - Will receive a handle to the WinSock key if successful.
Return Value:
DWORD - A Win32 status code, 0 if successful, !0 otherwise.
--*/
{
DWORD error;
//
// Open the WinSock key.
//
error = RegOpenKeyEx(
ServicesKey,
WINSOCK_SUBKEY,
0,
KEY_ALL_ACCESS,
WinsockKey
);
return error;
} // OpenWinsockRoot
DWORD
OpenWinsock2ParametersRoot(
HKEY ServicesKey,
PHKEY Winsock2ParametersKey
)
/*++
Routine Description:
Opens the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\...
...\WinSock2\Parameters registry key.
Arguments:
ServicesKey - The handle to the ...\Services key.
Winsock2ParametersKey - Will receive a handle to the WinSock2
parameters key if successful.
Return Value:
DWORD - A Win32 status code, 0 if successful, !0 otherwise.
--*/
{
DWORD error;
//
// Open the WinSock2 parameters key.
//
error = RegOpenKeyEx(
ServicesKey,
WINSOCK2_PARAM_SUBKEY,
0,
KEY_ALL_ACCESS,
Winsock2ParametersKey
);
return error;
} // OpenWinsock2ParametersRoot
DWORD
RecursivelyDeleteRegistryTree(
HKEY RootKey,
LPSTR TargetKeyName
)
/*++
Routine Description:
Deletes the specified registry key and all subkeys.
Arguments:
RootKey - A handle to the registry key containing the key to delete.
TargetKeyName - The name of the key to delete.
Return Value:
DWORD - A Win32 status code, 0 if successful, !0 otherwise.
--*/
{
DWORD error;
HKEY targetKey;
FILETIME lastWriteTime;
DWORD subkeyIndex;
DWORD subkeyNameLength;
CHAR subkeyName[MAX_REGISTRY_NAME];
//
// Setup locals so we know how to cleanup on exit.
//
targetKey = NULL;
//
// Open the target key.
//
error = RegOpenKeyEx(
RootKey,
TargetKeyName,
0,
KEY_ALL_ACCESS,
&targetKey
);
if( error == ERROR_FILE_NOT_FOUND ) {
error = NO_ERROR;
goto exit;
} else if( error != NO_ERROR ) {
goto exit;
}
//
// Enumerate & recursively delete the subkeys.
//
subkeyIndex = 0;
for( ; ; ) {
subkeyNameLength = sizeof(subkeyName);
error = RegEnumKeyEx(
targetKey,
subkeyIndex,
subkeyName,
&subkeyNameLength,
NULL,
NULL,
NULL,
&lastWriteTime
);
if( error != NO_ERROR ) {
break;
}
error = RecursivelyDeleteRegistryTree(
targetKey,
subkeyName
);
if( error != NO_ERROR ) {
break;
}
//
// Note that since we just totally blew away the current subkey
// in the enumeration, we do not want to increment the subkey
// index.
//
}
if( error != ERROR_NO_MORE_ITEMS ) {
goto exit;
}
//
// Close the target key.
//
error = RegCloseKey( targetKey );
targetKey = NULL;
if( error != NO_ERROR ) {
goto exit;
}
//
// Delete the target key.
//
error = RegDeleteKey(
RootKey,
TargetKeyName
);
if( error != NO_ERROR ) {
goto exit;
}
//
// Success!
//
exit:
if( targetKey != NULL ) {
(VOID)RegCloseKey( targetKey );
}
return error;
} // RecursivelyDeleteRegistryTree