|
|
/****************************************************************************
* * icfg32.cpp * * Microsoft Confidential * Copyright (c) 1992-1998 Microsoft Corporation * All rights reserved * * This module provides the implementation of the methods for * the NT specific functionality of inetcfg * * 6/5/97 ChrisK Inherited from AmnonH * ***************************************************************************/
#define INITGUID
#include <windows.h>
#include <wtypes.h>
#include <cfgapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <setupapi.h>
#include <basetyps.h>
#include <devguid.h>
#include <lmsname.h>
#include "debug.h"
const DWORD INFINSTALL_PRIMARYINSTALL = 0x00000001; const DWORD INFINSTALL_INPROCINTERP = 0x00000002;
#define REG_DATA_EXTRA_SPACE 255
#define CELEMS(x) ((sizeof(x))/(sizeof(x[0])))
DWORD (WINAPI *pfnNetSetupReviewBindings)(HWND hwndParent, DWORD dwBindFlags); DWORD (WINAPI *pfnNetSetupComponentInstall)(HWND hwndParent, PCWSTR pszInfOption, PCWSTR pszInfName, PCWSTR pszInstallPath, PCWSTR plszInfSymbols, DWORD dwInstallFlags, PDWORD dwReturn); DWORD (WINAPI *pfnNetSetupComponentRemove)(HWND hwndParent, PCWSTR pszInfOption, DWORD dwInstallFlags, PDWORD pdwReturn); DWORD (WINAPI *pfnNetSetupComponentProperties)(HWND hwndParent, PCWSTR pszInfOption, DWORD dwInstallFlags, PDWORD pdwReturn); DWORD (WINAPI *pfnNetSetupFindHardwareComponent)(PCWSTR pszInfOption, PWSTR pszInfName, PDWORD pcchInfName, PWSTR pszRegBase, // optional, may be NULL
PDWORD pcchRegBase ); // optional, NULL if pszRegBase is NULL
DWORD (WINAPI *pfnNetSetupFindSoftwareComponent)(PCWSTR pszInfOption, PWSTR pszInfName, PDWORD pcchInfName, PWSTR pszRegBase /*= NULL*/, PDWORD pcchRegBase /*= NULL*/); DWORD (WINAPI *pfnRegCopyTree)();
HINSTANCE g_hNetcfgInst = NULL; LPWSTR g_wszInstallPath = 0; DWORD g_dwLastError = ERROR_SUCCESS; extern DWORD EnumerateTapiModemPorts(DWORD dwBytes, LPSTR szPortsBuf, BOOL bWithDelay = FALSE);
typedef struct tagFunctionTableEntry { LPVOID *pfn; LPSTR szEntryPoint; } FunctionTableEntry;
#define REGISTRY_NT_CURRENTVERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CurrentVersion"
FunctionTableEntry NetcfgTable[] = { { (LPVOID *) &pfnNetSetupComponentInstall, "NetSetupComponentInstall" }, { (LPVOID *) &pfnNetSetupFindSoftwareComponent, "NetSetupFindSoftwareComponent" }, { (LPVOID *) &pfnNetSetupReviewBindings, "NetSetupReviewBindings" }, { (LPVOID *) &pfnNetSetupComponentRemove, "NetSetupComponentRemove" }, { (LPVOID *) &pfnNetSetupComponentProperties, "NetSetupComponentProperties" }, { (LPVOID *) &pfnNetSetupFindHardwareComponent, "NetSetupFindHardwareComponent" }, { 0, 0 } };
typedef struct tagNetSetup { WCHAR szOption[16]; WCHAR szInfName[16]; } NETSETUP;
NETSETUP g_netsetup[] = { L"WKSTA", L"OEMNSVWK.INF", L"SRV", L"OEMNSVSV.INF", L"NETBIOS", L"OEMNSVNB.INF", L"RPCLOCATE", L"OEMNSVRP.INF" };
#define NSERVICES (sizeof g_netsetup / sizeof g_netsetup[0])
inline stricmp(LPSTR s1, LPSTR s2) { while(*s1 && *s2) { char c1, c2; c1 = islower(*s1) ? toupper(*s1) : *s1; c2 = islower(*s2) ? toupper(*s2) : *s2; if(c1 != c2) { break; } s1++; s2++; }
return(*s1 - *s2); }
//+----------------------------------------------------------------------------
//
// Function: LoadLibraryToFunctionTable
//
// Synopsis: Load structure with function pointers from FunctionTable
//
// Arguments: pTab - array of function to be loaded
// szDLL - name of DLL to load function from
//
// Returns: Handle to szDLL (NULL indicates failure)
//
// History: 6/5/97 Chrisk Inherited
//
//-----------------------------------------------------------------------------
HINSTANCE LoadLibraryToFunctionTable(FunctionTableEntry *pTab, LPSTR szDLL) { HINSTANCE hInst;
Dprintf("ICFGNT: LoadLibraryToFunctionTable\n"); hInst = LoadLibrary(szDLL); if(hInst == 0) { return(hInst); }
while(pTab->pfn) { *pTab->pfn = (LPVOID) GetProcAddress(hInst, pTab->szEntryPoint); if(*pTab->pfn == 0) { FreeLibrary(hInst); return(0); } pTab++; }
return(hInst); }
//+----------------------------------------------------------------------------
//
// Function: LoadNetcfg
//
// Synopsis: Load netcfg.dll and function poiners
//
// Arguments: none
//
// Returns: ERROR_SUCCESS if sucessfull and !ERROR_SUCCESS otherwise
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
DWORD LoadNetcfg() { if(g_hNetcfgInst == NULL) { g_hNetcfgInst = LoadLibraryToFunctionTable(NetcfgTable, "NETCFG.DLL"); }
if(g_hNetcfgInst == NULL) { return(!ERROR_SUCCESS); } else { return(ERROR_SUCCESS); } }
//+----------------------------------------------------------------------------
//
// Function: IcfgSetInstallSourcePath
//
// Synopsis: Set the path that will be used to install system components
//
// Arguments: lpszSourcePath - path to be used as install source (ANSI)
//
// Returns: HRESULT - S_OK is success
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
HRESULT WINAPI IcfgSetInstallSourcePath(LPSTR lpszSourcePath) { Dprintf("ICFGNT: IcfgSetInstallSourcePath\n"); if(g_wszInstallPath) { HeapFree(GetProcessHeap(), 0, (LPVOID) g_wszInstallPath); }
DWORD dwLen = lstrlen(lpszSourcePath); g_wszInstallPath = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwLen * 2 + 2); if(g_wszInstallPath == 0) { return(g_dwLastError = ERROR_OUTOFMEMORY); }
mbstowcs(g_wszInstallPath, lpszSourcePath, dwLen + 1); return(ERROR_SUCCESS); }
//+----------------------------------------------------------------------------
//
// Function: GetLocationOfSetupFiles
//
// Synopsis: Get the location of the files used to install windows.
//
// Arguments: hwndParent - handle of parent window
//
// Returns: win32 error code
//
// History: ChrisK 6/30/97 Created
//-----------------------------------------------------------------------------
DWORD GetLocationOfSetupFiles(HWND hwndParent) { DWORD dwRC = ERROR_SUCCESS; HKEY hkey = NULL; HINF hInf = INVALID_HANDLE_VALUE; UINT DiskId = 0; CHAR TagFile[128]; CHAR lpBuffer[MAX_PATH]; DWORD dwLen = MAX_PATH; lpBuffer[0] = '\0';
if( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, REGISTRY_NT_CURRENTVERSION, &hkey)) {
hInf = SetupOpenMasterInf(); if (hInf == INVALID_HANDLE_VALUE) { dwRC = GetLastError(); goto GetLocationOfSetupFilesExit; }
if (!SetupGetSourceFileLocation(hInf,NULL,"RASCFG.DLL",&DiskId,NULL,0,NULL)) { dwRC = GetLastError(); goto GetLocationOfSetupFilesExit; }
if (!SetupGetSourceInfo(hInf,DiskId,SRCINFO_TAGFILE,TagFile,MAX_PATH,NULL)) { dwRC = GetLastError(); goto GetLocationOfSetupFilesExit; }
SetupCloseInfFile(hInf); hInf = INVALID_HANDLE_VALUE;
if( RegQueryValueEx( hkey, "SourcePath", NULL, NULL, (LPBYTE)lpBuffer, &dwLen) == 0) { RegCloseKey( hkey ); hkey = NULL;
// Ask the user to provide the drive\path of the sources. We pass this information
// down to NetSetupComponentInstall so that the user is not prompted several times
// for the same information. If the path is correct (IDF_CHECKFIRST) then the user
// is not prompted at all.
if( (dwRC = SetupPromptForDisk(hwndParent, NULL, NULL, lpBuffer, "RASCFG.DLL", TagFile, // tag file
IDF_CHECKFIRST, lpBuffer, MAX_PATH, &dwLen )) != DPROMPT_SUCCESS ) { Dprintf("ICFG: Install: SetupPromptForDisk failed.\n"); dwRC = GetLastError(); goto GetLocationOfSetupFilesExit; } }
// If we failed to get SourcePath from registry, then prompt the user once and use
// this information for subsequent installs.
else { if( (dwRC = SetupPromptForDisk(hwndParent, NULL, NULL, NULL, "RASCFG.DLL", TagFile, // tag file
IDF_CHECKFIRST, lpBuffer, MAX_PATH, &dwLen )) != DPROMPT_SUCCESS ) { Dprintf("ICFG: Install: SetupPromptForDisk failed.\n"); dwRC = GetLastError(); goto GetLocationOfSetupFilesExit; } } } GetLocationOfSetupFilesExit: if (ERROR_SUCCESS == dwRC) { IcfgSetInstallSourcePath(lpBuffer); } if (INVALID_HANDLE_VALUE != hInf) { SetupCloseInfFile(hInf); hInf = NULL; }
if (NULL != hkey) { RegCloseKey(hkey); } return dwRC; }
//+----------------------------------------------------------------------------
//
// Function: InstallNTNetworking
//
// Synopsis: Install NT Server, workstation, netbios, and RPC locator
// services as needed
//
// Arguemtns: hwndParent - parent window
//
// Returns: win32 error code
//
// History: ChrisK 6/27/97 Created
//
//-----------------------------------------------------------------------------
DWORD InstallNTNetworking(HWND hwndParent) { DWORD dwRC = ERROR_SUCCESS; UINT index = 0; DWORD cchInfName = MAX_PATH; WCHAR pszInfName[MAX_PATH+1]; SC_HANDLE hscman, hsvc; DWORD dwReturn;
Dprintf("ICFGNT.DLL: InstallNTNetworking.\n");
Assert(NULL == hwndParent || IsWindow(hwndParent));
if(ERROR_SUCCESS != (dwRC = LoadNetcfg())) { Dprintf("ICFGNT.DLL: Failed load Netcfg API's, error %d\n",dwRC); goto InstallNTNetworkingExit; }
//
// Check for and install services
//
for (index = 0; index < NSERVICES; index++) { Dprintf("ICFGNT.DLL: Check service %d\n",index);
//
// Install service if it is not installed
//
if(pfnNetSetupFindSoftwareComponent( g_netsetup[index].szOption, // OPTION
pszInfName, // INF Name
&cchInfName, NULL, NULL) != ERROR_SUCCESS ) {
if (0 == g_wszInstallPath || 0 == lstrlenW(g_wszInstallPath)) { GetLocationOfSetupFiles(hwndParent); }
Dprintf("ICFGNT.DLL: Need service %d.\n",index); if((dwRC = pfnNetSetupComponentInstall( hwndParent, g_netsetup[index].szOption, // OPTION
g_netsetup[index].szInfName, // INF Name
g_wszInstallPath, // Install path optional
NULL, // symbols, optional
2, // INFINSTALL_INPROCINTERP
&dwReturn)) != ERROR_SUCCESS ) { Dprintf("ICFGNT.DLL: Installing service %d failed with error %d.\n", index, dwRC); goto InstallNTNetworkingExit; }
// Since this is downlevel, we can just use the MAKELCID macro
//
if (CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, g_netsetup[index].szOption, -1, L"WKSTA", -1)) { // if we installed the Workstation service, then we should disable
// Netlogon service. We need to do this because netlogon service should
// not be set to autostart if the user has not joined a domain.
//
hscman = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS | GENERIC_WRITE ); if( hscman == NULL) { dwRC = GetLastError(); Dprintf("ICFGNT.DLL: Failed to open serviceManager, error %d\n",dwRC); goto InstallNTNetworkingExit; }
hsvc = OpenService( hscman, SERVICE_NETLOGON, SERVICE_CHANGE_CONFIG ); if ( hsvc == NULL) { dwRC = GetLastError(); Dprintf("ICFGNT.DLL: Failed to open service, error %d\n",dwRC); goto InstallNTNetworkingExit; } ChangeServiceConfig( hsvc, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); CloseServiceHandle(hsvc); CloseServiceHandle(hscman); } } } InstallNTNetworkingExit:
return dwRC; }
//+----------------------------------------------------------------------------
//
// Function: GetRegValue
//
// Synopsis: Dynamically allocate memory and read value from registry
//
// Arguments: hKey - handle to key to be read
// lpValueName - pointer to value name to be read
// lpData - pointer to pointer to data
//
// Returns: Win32 error, ERROR_SUCCESS is it worked
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
inline LONG GetRegValue(HKEY hKey, LPSTR lpValueName, LPBYTE *lpData) { LONG dwError; DWORD cbData;
Dprintf("ICFGNT: GetRegValue\n"); dwError = RegQueryValueExA(hKey, lpValueName, NULL, NULL, NULL, &cbData); if(dwError != ERROR_SUCCESS) { return(dwError); }
//
// Allocate space and buffer incase we need to add more info later
// see turn off the printing binding
//
*lpData = (LPBYTE) GlobalAlloc(GPTR,cbData + REG_DATA_EXTRA_SPACE); if(*lpData == 0) { return(ERROR_OUTOFMEMORY); }
dwError = RegQueryValueExA(hKey, lpValueName, NULL, NULL, *lpData, &cbData); if(dwError != ERROR_SUCCESS) { GlobalFree(*lpData); }
return(dwError); }
//+----------------------------------------------------------------------------
//
// Function: ParseNetSetupReturn
//
// Synopsis: Interprit return values from NetSetup* functions
//
// Arguments: dwReturn - return value from NetSetup* function
//
// Returns: fReboot - TRUE means reboot required
// fBindReview - TRUE means binding review is required
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
inline void ParseNetSetupReturn(DWORD dwReturn, BOOL &fReboot, BOOL &fBindReview) { Dprintf("ICFGNT: ParseNetSetupReturn\n"); if(dwReturn == 0 || dwReturn == 4) { fBindReview = TRUE; } if(dwReturn == 0 || dwReturn == 5) { fReboot = TRUE; } }
//+----------------------------------------------------------------------------
//
// Function: ReviewBindings
//
// Synopsis: Force WinNT to review network bindings
//
// Arguments: hwndParent - handle to parent window
//
// Returns: win32 error code (ERROR_SUCCESS means it worked)
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
DWORD ReviewBindings(HWND hwndParent) { DWORD dwErr;
Dprintf("ICFGNT: ReviewBindings\n"); dwErr = LoadNetcfg(); if(dwErr != ERROR_SUCCESS) { return(dwErr); }
return(pfnNetSetupReviewBindings(hwndParent, 0)); }
//+----------------------------------------------------------------------------
//
// Function: CallModemInstallWizard
//
// Synopsis: Invoke modem install wizard via SetupDi interfaces
//
// Arguments: hwnd - handle to parent window
//
// Returns: TRUE - success, FALSE - failed
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
//
// The following code was stolen from RAS
//
BOOL CallModemInstallWizard(HWND hwnd) /* call the Modem.Cpl install wizard to enable the user to install one or more modems
** ** Return TRUE if the wizard was successfully invoked, FALSE otherwise ** */ { HDEVINFO hdi; BOOL fReturn = FALSE; // Create a modem DeviceInfoSet
Dprintf("ICFGNT: CallModemInstallWizard\n"); hdi = SetupDiCreateDeviceInfoList((LPGUID)&GUID_DEVCLASS_MODEM, hwnd); if (hdi) { SP_INSTALLWIZARD_DATA iwd;
// Initialize the InstallWizardData
ZeroMemory(&iwd, sizeof(iwd)); iwd.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); iwd.ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD; iwd.hwndWizardDlg = hwnd;
// Set the InstallWizardData as the ClassInstallParams
if (SetupDiSetClassInstallParams(hdi, NULL, (PSP_CLASSINSTALL_HEADER)&iwd, sizeof(iwd))) { // Call the class installer to invoke the installation
// wizard.
if (SetupDiCallClassInstaller(DIF_INSTALLWIZARD, hdi, NULL)) { // Success. The wizard was invoked and finished.
// Now cleanup.
fReturn = TRUE;
SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA, hdi, NULL); } }
// Clean up
SetupDiDestroyDeviceInfoList(hdi); } return fReturn; }
//+----------------------------------------------------------------------------
//
// Function: IsDialableISDNAdapters
//
// Synopsis: Some ISDN adapters can be installed as RAS devices, but not as
// unimodem devices, so we have to walk through the rest of the
// TAPI devices looking for these.
//
// Arguments: None
//
// Returns: TRUE - there is a device available
//
// History: 7/22/97 ChrisK Created
//
//-----------------------------------------------------------------------------
#define REG_TAPIDEVICES "software\\microsoft\\ras\\tapi devices"
LPSTR szAddress = "Address"; LPSTR szUsage = "Usage"; LPSTR szMediaType = "Media Type"; BOOL IsDialableISDNAdapters() { BOOL bRC = FALSE;
HKEY hkey = NULL, hsubkey = NULL; DWORD dwIdx = 0; CHAR szBuffer[MAX_PATH + 1]; CHAR szSubKey[MAX_PATH + 1]; LPBYTE lpData = NULL; LPSTR lpsUsage = NULL; szBuffer[0] = '\0';
//
// Open TAPI device key
//
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, REG_TAPIDEVICES, &hkey)) { Dprintf("ICFGNT Can not open TAPI key.\n"); goto IsDialableISDNAdaptersExit; }
//
// Scan for non unimodem device
//
while (FALSE == bRC) { szBuffer[0] = '\0'; if (ERROR_SUCCESS != RegEnumKey(hkey,dwIdx,szBuffer,MAX_PATH)) { goto IsDialableISDNAdaptersExit; } Dprintf("ICFGNT sub key (%s) found.\n",szBuffer);
if (CSTR_EQUAL != CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, szBuffer, -1, "unimodem", -1)) { //
// Open other TAPI device reg key
//
szSubKey[0] = '\0'; wsprintf(szSubKey,"%s\\%s",REG_TAPIDEVICES,szBuffer); Dprintf("ICFGNT opening (%s).\n",szSubKey); if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, szSubKey, &hsubkey)) { Dprintf("ICFGNT Can not open TAPI SUB key.\n"); goto IsDialableISDNAdaptersExit; }
if (ERROR_SUCCESS != GetRegValue(hsubkey,szUsage,&lpData)) { Dprintf("ICFGNT Can not get TAPI SUB key.\n"); goto IsDialableISDNAdaptersExit; }
//
// Scan for "client"
//
lpsUsage = (LPSTR)lpData; while (*lpsUsage != '\0') { if(NULL != strstr(lpsUsage, "Client")) { Dprintf("ICFGNT client found for device.\n"); //
// We found a client device, now check that it is ISDN
//
GlobalFree(lpData); lpData = NULL; if (ERROR_SUCCESS != GetRegValue(hsubkey,szMediaType,&lpData)) { Dprintf("ICFGNT Can not get TAPI SUB value key.\n"); goto IsDialableISDNAdaptersExit; } if (CSTR_EQUAL == CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), NORM_IGNORECASE, (LPSTR)lpData, -1, "ISDN", -1)) { Dprintf("ICFGNT ISDN media type found.\n"); //
// This is a valid dial-out ISDN device!!! Wahoo!!
//
bRC = TRUE; } else { Dprintf("ICFGNT ISDN media type NOT found.\n"); } } else { lpsUsage += lstrlen(lpsUsage)+1; } }
if (lpData) { GlobalFree(lpData); lpData = NULL; lpsUsage = NULL; } }
//
// Move to the next REG key
//
dwIdx++; }
IsDialableISDNAdaptersExit: if (hkey) { RegCloseKey(hkey); hkey = NULL; } if (hsubkey) { RegCloseKey(hsubkey); hsubkey = NULL; } if (lpData) { GlobalFree(lpData); lpData = NULL; lpsUsage = NULL; }
return bRC; }
//+----------------------------------------------------------------------------
//
// Function: IcfgNeedModem
//
// Synopsis: Check system configuration to determine if there is at least
// one physical modem installed
//
// Arguments: dwfOptions - currently not used
//
// Returns: HRESULT - S_OK if successfull
// lpfNeedModem - TRUE if no modems are available
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
LPSTR szRasUnimodemSubKey = "Software\\Microsoft\\ras\\TAPI DEVICES\\Unimodem";
HRESULT WINAPI IcfgNeedModemNT4 (DWORD dwfOptions, LPBOOL lpfNeedModem) { //
// Ras is insatlled, and ICW wants to know if it needs to
// install a modem.
//
*lpfNeedModem = TRUE;
//
// ChrisK 7/22/97
// Added return code in order to provide centralized place to check
// for ISDN installations
//
HRESULT hRC = ERROR_SUCCESS;
//
// Check what modems are available to RAS
//
HKEY hUnimodem; LONG dwError;
Dprintf("ICFGNT: IcfgNeedModem\n");
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRasUnimodemSubKey, 0, KEY_READ, &hUnimodem);
if(dwError != ERROR_SUCCESS) { goto IcfgNeedModemExit; } else { LPBYTE lpData;
dwError = GetRegValue(hUnimodem, szUsage, &lpData); if(dwError != ERROR_SUCCESS) goto IcfgNeedModemExit;
LPBYTE lpData2; dwError = GetRegValue(hUnimodem, szAddress, &lpData2); if(dwError != ERROR_SUCCESS) { hRC = dwError; goto IcfgNeedModemExit; } else { //
// Try finding a Client or ClientAndServer Modem
// Also, make sure all modems have corresponding TAPI devices
//
LPSTR pUsage = (LPSTR) lpData; LPSTR pAddress = (LPSTR) lpData2; char portsbuf[1000];
dwError = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf); if(dwError) { hRC = dwError; goto IcfgNeedModemExit; }
while(*pUsage != '\0') { if(lstrcmp(pUsage, "Client") == 0 || lstrcmp(pUsage, "ClientAndServer") == 0 || lstrcmp(pUsage, "ClientAndServerAndRouter") == 0)
{ *lpfNeedModem = FALSE; }
//
// Make sure a corresponding TAPI port exists
//
LPSTR pPorts = portsbuf; while(*pPorts != '\0') if(stricmp(pAddress, pPorts) == 0) { break; } else { pPorts += lstrlen(pPorts) + 1; }
if(*pPorts == '\0') { hRC = ERROR_INTERNAL_ERROR; goto IcfgNeedModemExit; }
pUsage += lstrlen(pUsage) + 1; pAddress += lstrlen(pAddress) + 1; } } }
IcfgNeedModemExit: //
// If there was some problem finding a typical dial out device,
// then try again and check for dialing ISDN devices.
//
if (ERROR_SUCCESS != hRC || FALSE != *lpfNeedModem) { if (IsDialableISDNAdapters()) { hRC = ERROR_SUCCESS; *lpfNeedModem = FALSE; } }
return(hRC); }
//+----------------------------------------------------------------------------
//
// Function: IcfgInstallModem
//
// Synopsis:
// This function is called when ICW verified that RAS is installed,
// but no modems are avilable. It needs to make sure a modem is availble.
// There are two possible scenarios:
//
// a. There are no modems installed. This happens when someone deleted
// a modem after installing RAS. In this case we need to run the modem
// install wizard, and configure the newly installed modem to be a RAS
// dialout device.
//
// b. There are modems installed, but non of them is configured as a dial out
// device. In this case, we silently convert them to be DialInOut devices,
// so ICW can use them.
//
// Arguments: hwndParent - handle to parent window
// dwfOptions - not used
//
// Returns: lpfNeedsStart - not used
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
HRESULT WINAPI IcfgInstallModemNT4 (HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsStart) { //
// Check what modems are available to RAS
//
HKEY hUnimodem; LONG dwError; BOOL fInstallModem = FALSE;
Dprintf("ICFGNT: IcfgInstallModem\n");
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRasUnimodemSubKey, 0, KEY_READ, &hUnimodem);
if(dwError != ERROR_SUCCESS) { fInstallModem = TRUE; } else { LPBYTE lpData;
dwError = GetRegValue(hUnimodem, szUsage, &lpData); if(dwError != ERROR_SUCCESS) { fInstallModem = TRUE; } else { // Make sure at least one modem exists
if(*lpData == '\0') { fInstallModem = TRUE; } } }
if(fInstallModem) { //
// Fire up the modem install wizard
//
if(!CallModemInstallWizard(hwndParent)) { return(g_dwLastError = GetLastError()); }
//
// Now configure the new modem to be a dial out device.
//
//
// Install ras again with unattneded file!
//
return(ERROR_SUCCESS);
} else { //
// We need to reconfigure dial in devices to be dialinout
//
//
// install ras again with unattended file!
//
return(ERROR_SUCCESS); } }
//+----------------------------------------------------------------------------
//
// Function: IcfgNeedInetComponets
//
// Synopsis: Check to see if the components marked in the options are
// installed on the system
//
// Arguements: dwfOptions - set of bit flag indicating which components to
// check for
//
// Returns; HRESULT - S_OK if successfull
// lpfNeedComponents - TRUE is some components are not installed
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
HRESULT WINAPI IcfgNeedInetComponentsNT4(DWORD dwfOptions, LPBOOL lpfNeedComponents) { DWORD dwErr;
//
// Assume need nothing
//
*lpfNeedComponents = FALSE;
Dprintf("ICFGNT: IcfgNeedInetComponents\n"); dwErr = LoadNetcfg(); if(dwErr != ERROR_SUCCESS) { return(g_dwLastError = dwErr); // Shouldn't we map to hResult?
}
WCHAR wszInfNameBuf[512]; DWORD cchInfName = sizeof(wszInfNameBuf) / sizeof(WCHAR);
if(dwfOptions & ICFG_INSTALLTCP) { dwErr = pfnNetSetupFindSoftwareComponent(L"TC", wszInfNameBuf, &cchInfName, 0, 0); if(dwErr != ERROR_SUCCESS) *lpfNeedComponents = TRUE; }
if(dwfOptions & ICFG_INSTALLRAS) { dwErr = pfnNetSetupFindSoftwareComponent(L"RAS", wszInfNameBuf, &cchInfName, 0, 0); if(dwErr != ERROR_SUCCESS) *lpfNeedComponents = TRUE; }
if(dwfOptions & ICFG_INSTALLMAIL) { // How do we do this?
}
return(ERROR_SUCCESS); }
//+----------------------------------------------------------------------------
//
// Function: GenerateRasUnattendedFile
//
// Synopsis: Create the file that will provide RAS setup the necessary
// setting to install in an unattended mode
//
// Arguments: wszTmpFile - name of file to create
// szPortsBuf
//
// Returns: FALSE - failure, TRUE - success
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
BOOL GenerateRasUnattendedFile(LPWSTR wszTmpFile, LPSTR szPortsBuf) { WCHAR wszTmpPath[MAX_PATH+1]; WCHAR wszTmpShortPath[MAX_PATH+1];
//
// Create temporary file name and convert to non-wide form
//
Dprintf("ICFGNT: GenerateRasUnattendedFile\n");
if (GetTempPathW(MAX_PATH, wszTmpPath) == 0) { return(FALSE); }
//
// always attempt to create the temp dir as the temp dir may not exist if
// the user logs in with a roaming profile
//
CreateDirectoryW(wszTmpPath, NULL);
//
// need to convert this to a short path since pfnNetSetupComponentInstall()
// doesn't like to have a long path in the InfSymbols param.
//
if (!GetShortPathNameW(wszTmpPath, wszTmpShortPath, MAX_PATH)) { return FALSE; }
if (GetTempFileNameW(wszTmpPath, L"icw", 0, wszTmpFile) == 0) { return(FALSE); }
//
// need to convert the temp filename to shortpath too!
//
if (!GetShortPathNameW(wszTmpFile, wszTmpShortPath, MAX_PATH)) { return FALSE; } wcscpy(wszTmpFile, wszTmpShortPath);
char szTmpFile[MAX_PATH+1]; wcstombs(szTmpFile, wszTmpFile, wcslen(wszTmpFile) + 1);
#if 0
/*
FILE *fp = fopen(szTmpFile, "w");
if(fp == 0) { return(FALSE); }
fprintf(fp, "[RemoteAccessParameters]\n"); fprintf(fp, "PortSections = ");
LPSTR szPorts = szPortsBuf;
while(*szPorts) { if(szPorts != szPortsBuf) { fprintf(fp, ","); } fprintf(fp, "%s", szPorts); szPorts += lstrlen(szPorts) + 1; }
fprintf(fp, "\n"); fprintf(fp, "DialoutProtocols = TCP/IP\n"); fprintf(fp, "\n"); fprintf(fp, "[Modem]\n"); fprintf(fp, "InstallModem=ModemSection\n"); fprintf(fp, "\n");
szPorts = szPortsBuf;
while(*szPorts) { fprintf(fp, "[%s]\n", szPorts); fprintf(fp, "PortName = %s\n", szPorts); fprintf(fp, "DeviceType = Modem\n"); fprintf(fp, "PortUsage = DialOut\n"); fprintf(fp, "\n"); szPorts += lstrlen(szPorts) + 1; }
fprintf(fp, "[ModemSection]\n");
fclose(fp); */
#else
//
// Open the file for writing, bail on fail.
//
BOOL bRet = FALSE;
HANDLE hFile = CreateFile(szTmpFile,GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
if (INVALID_HANDLE_VALUE == hFile) { return FALSE; }
LPSTR szPorts = szPortsBuf; char szFileBuf[MAX_PATH]={0}; DWORD dwWrite; lstrcpy(szFileBuf, "[RemoteAccessParameters]\nPortSections = ");
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
while (*szPorts) { //
// Delimit each item with a comma
//
if (szPorts != szPortsBuf) { lstrcpy(szFileBuf, ","); if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; } }
//
// Write each port
//
lstrcpyn(szFileBuf, szPorts, CELEMS(szFileBuf));
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; } szPorts += lstrlen(szPorts) + 1; } //
// Write DialoutProtocol TCP/IP and InstallModem
//
lstrcpy(szFileBuf, "\nDialoutProtocols = TCP/IP\n\n[Modem]\nInstallModem=ModemSection\n\n");
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
//
// Enumerate ports again
//
szPorts = szPortsBuf;
while (*szPorts) { //
// Write PortName section and entry
//
wsprintf(szFileBuf, "[%s]\n", szPorts);
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
wsprintf(szFileBuf, "PortName = %s\n", szPorts);
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
//
// Write DeviceType and PortUsage entry for each port
//
lstrcpy(szFileBuf, "DeviceType = Modem\nPortUsage = DialOut\n\n");
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
szPorts += lstrlen(szPorts) + 1; }
lstrcpy(szFileBuf, "[ModemSection]\n");
if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL)) { goto closefile; }
bRet = TRUE;
closefile:
CloseHandle(hFile);
#endif
return(bRet); }
//+----------------------------------------------------------------------------
//
// Function: InstallRAS
//
// Synopsis: Invoke unattended RAS installation
//
// Arguments: hwndParent - handle to parent window
// szFile - name of unattended settings file
// szSection -
//
// Returns: DWORD - win32 error
// pdwReturn - return code from last parameter of
// pfnNetSetupComponentInstall
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
DWORD InstallRAS(HWND hwndParent, LPWSTR szFile, LPWSTR szSection, LPDWORD pdwReturn) { WCHAR InfSymbols[1024]; LPWSTR szInfSymbols = InfSymbols;
Dprintf("ICFGNT: InstallRAS\n");
DWORD dwRC = InstallNTNetworking(hwndParent); if (ERROR_SUCCESS != dwRC) { return dwRC; }
LPWSTR szString1 = L"!STF_GUI_UNATTENDED"; wcscpy(szInfSymbols, szString1); szInfSymbols += wcslen(szString1) + 1;
LPWSTR szString2 = L"YES"; wcscpy(szInfSymbols, szString2); szInfSymbols += wcslen(szString2) + 1;
LPWSTR szString3 = L"!STF_UNATTENDED"; wcscpy(szInfSymbols, szString3); szInfSymbols += wcslen(szString3) + 1;
//
// Unattneded file.
//
wcscpy(szInfSymbols, szFile); szInfSymbols += wcslen(szFile) + 1;
LPWSTR szString4 = L"!STF_UNATTENDED_SECTION"; wcscpy(szInfSymbols, szString4); szInfSymbols += wcslen(szString4) + 1;
//
// Unattnded section
//
wcscpy(szInfSymbols, szSection); szInfSymbols += wcslen(szSection) + 1;
*szInfSymbols++ = 0; *szInfSymbols++ = 0;
return(pfnNetSetupComponentInstall(hwndParent, L"RAS", L"OEMNSVRA.INF", g_wszInstallPath, InfSymbols, INFINSTALL_INPROCINTERP, // Install Flags
pdwReturn)); }
//+----------------------------------------------------------------------------
//
// Function: IcfgInstallInetComponents
//
// Synopsis: Install the components as specified by the dwfOptions values
//
// Arguments hwndParent - handle to parent window
// dwfOptions - set of bit flags indicating which components to
// install
//
// Returns: HRESULT - S_OK if success
// lpfNeedsReboot - TRUE if reboot is required
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
HRESULT WINAPI IcfgInstallInetComponentsNT4(HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsRestart) { DWORD dwErr; DWORD dwReturn; BOOL fNeedsReview; BOOL fNeedsRestart; BOOL fDoReview = FALSE; WCHAR wszInfNameBuf[512]; DWORD cchInfName = sizeof(wszInfNameBuf) / sizeof(WCHAR);
Dprintf("ICFGNT: IcfgInstallInetComponents\n"); //
// Assume don't need restart
//
*lpfNeedsRestart = FALSE;
dwErr = LoadNetcfg(); if(dwErr != ERROR_SUCCESS) { return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
}
if(dwfOptions & ICFG_INSTALLTCP) { dwErr = pfnNetSetupFindSoftwareComponent(L"TC", wszInfNameBuf, &cchInfName, 0, 0); if(dwErr != ERROR_SUCCESS) { dwErr = pfnNetSetupComponentInstall(hwndParent, L"TC", L"OEMNXPTC.INF", g_wszInstallPath, L"\0\0", INFINSTALL_INPROCINTERP, // Install Flags
&dwReturn); if(dwErr != ERROR_SUCCESS) { return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
}
ParseNetSetupReturn(dwReturn, fNeedsRestart, fNeedsReview); if(fNeedsRestart) { *lpfNeedsRestart = TRUE; } if(fNeedsReview) { fDoReview = TRUE; } } }
if(dwfOptions & ICFG_INSTALLRAS) { dwErr = pfnNetSetupFindSoftwareComponent(L"RAS", wszInfNameBuf, &cchInfName, 0, 0); if(dwErr != ERROR_SUCCESS) { //
// Before we install RAS, we have to make have to make sure a modem
// is installed, because RAS will try to run the modem detection wizard
// in unattneded mode if there are no modems, and we don't want that.
//
// The way we do that is we enumerate devices through TAPI, and if there are
// no modems installed, we call the modem install wizard. Only after
// we make sure a modem was installed, we call ras install.
//
DWORD DoTapiModemsExist(LPBOOL pfTapiModemsExist); char portsbuf[1000];
dwErr = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf); if(dwErr) return(g_dwLastError = dwErr);
if(*portsbuf == 0) { if(!CallModemInstallWizard(hwndParent)) { //
// if CallModemInstallWizard returned FALSE and
// GetLastError() is ERROR_SUCCESS, it is actually
// a user cancelled case
//
if (ERROR_SUCCESS == (g_dwLastError = GetLastError())) g_dwLastError = ERROR_CANCELLED; return(g_dwLastError); }
//
// In this invocation of EnumerateTapiModemPorts
// we have to wait for a 1 second before we start
// enumerating the modems - hence set the last parameter
// to TRUE -- VetriV
//
dwErr = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf, TRUE); if(dwErr) { return(g_dwLastError = dwErr); }
if(*portsbuf == 0) { return(g_dwLastError = ERROR_CANCELLED); } }
WCHAR wszUnattFile[MAX_PATH];
if(!GenerateRasUnattendedFile(wszUnattFile, portsbuf)) { return(g_dwLastError = GetLastError()); }
dwErr = InstallRAS(hwndParent, wszUnattFile, L"RemoteAccessParameters", &dwReturn); DeleteFileW(wszUnattFile);
if(dwErr != ERROR_SUCCESS) { return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
}
ParseNetSetupReturn(dwReturn, fNeedsRestart, fNeedsReview); if(fNeedsRestart) { *lpfNeedsRestart = TRUE; } if(fNeedsReview) { fDoReview = TRUE; } } }
if(fDoReview) { return(g_dwLastError = ReviewBindings(hwndParent)); // Review: Shouldn't we map to hresult?
} else { return(ERROR_SUCCESS); } }
//+----------------------------------------------------------------------------
//
// Function: IcfgIsFileSharingTurnedOn
//
// Synopsis: Check network bindings to determine if "Server" service is
// bound to ndiswan adapter
//
// Arguments: dwfDriverType -
//
// Returns: HRESULT - S_OK is success
// lpfSharingOn - TRUE if sharing is bound
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
LPSTR szLanManServerSubKey = "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Linkage"; LPSTR szBind = "Bind"; LPSTR szExport = "Export"; LPSTR szRoute = "Route"; LPSTR szLanManServerDisabledSubKey = "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Linkage\\Disabled"; LPSTR szNdisWan4 = "NdisWan"; struct BINDDATA { CHAR *startb; CHAR *currb; CHAR *starte; CHAR *curre; CHAR *startr; CHAR *currr; } net_bindings;
HRESULT WINAPI IcfgIsFileSharingTurnedOn(DWORD dwfDriverType, LPBOOL lpfSharingOn) { HRESULT hr = ERROR_SUCCESS; HKEY hKey = NULL; LPBYTE lpData = NULL; CHAR *p;
Dprintf("ICFGNT: IcfgIsFileSharingTurnedOn\n"); Assert(lpfSharingOn); if (NULL == lpfSharingOn) { hr = ERROR_INVALID_PARAMETER; goto IcfgIsFileSharingTurnedOnExit; }
*lpfSharingOn = FALSE;
//
// Open lanmanServer registry key
//
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, szLanManServerSubKey, &hKey)) { Dprintf("ICFGNT: Failed to open lanmanServer key\n"); goto IcfgIsFileSharingTurnedOnExit; }
if (ERROR_SUCCESS != GetRegValue(hKey, szBind, &lpData)) { Dprintf("ICFGNT: Failed to read binding information\n"); goto IcfgIsFileSharingTurnedOnExit; } Assert(lpData); //
// Look for a particular string in the data returned
// Note: data is terminiated with two NULLs
//
p = (CHAR *)lpData; while (*p) { if (strstr( p, szNdisWan4)) { Dprintf("ICFGNT: NdisWan4 binding found in %s\n",p); *lpfSharingOn = TRUE; break; } p += (lstrlen( p ) + 1); }
IcfgIsFileSharingTurnedOnExit: if (hKey) { RegCloseKey(hKey); hKey = NULL; }
if (lpData) { GlobalFree(lpData); lpData = NULL; } return hr; }
//+----------------------------------------------------------------------------
//
// Function: MoveNextBinding
//
// Synopsis: Move to the next string in a MULTISZ data buffer
//
// Arguments: lpcBinding - pointer to address of current buffer position
//
// Returns: lpcBinding - pointer to next string
//
// History: 6/5/97 ChrisK Created
//
//-----------------------------------------------------------------------------
inline void MoveNextBinding(CHAR **lplpcBinding) { Dprintf("ICFGNT: MoveNextBinding\n"); Assert(lplpcBinding && *lplpcBinding); if (lplpcBinding && *lplpcBinding) { *lplpcBinding += (lstrlen(*lplpcBinding)+1); } else { Dprintf("ICFGNT: MoveNextBinding received invalid parameter\n"); } }
//+----------------------------------------------------------------------------
//
// Function: CompactLinkage
//
// Synopsis: Compact a list of Multi_SZ data
//
// Arguments: lpBinding - point to the string of an Multi_Sz list that should
// be over written
//
// Returns: none
//
// History: 6/5/97 ChrisK Created
//
//-----------------------------------------------------------------------------
inline void CompactLinkage(CHAR *lpBinding) { Dprintf("ICFGNT: CompactLinkage\n"); Assert(lpBinding && *lpBinding); CHAR *lpLast = lpBinding; BOOL fNULLChar = FALSE;
MoveNextBinding(&lpBinding);
//
// ChrisK Olympus 6311 6/11/97
// Do not compact on a per string basis. This causes the data to become
// corrupted if the string being removed is shorter than the string being
// added. Instead compact on a per character basis, since those are always
// the same size (on a given machine).
//
while (!fNULLChar || *lpBinding) { if (NULL == *lpBinding) { fNULLChar = TRUE; } else { fNULLChar = FALSE; } *lpLast++ = *lpBinding++; }
//while (*lpBinding)
//{
// lstrcpy(lpLast,lpBinding);
// lpLast = lpBinding;
// MoveNextBinding(&lpBinding);
//}
//
// Add second terminating NULL
//
*lpLast = '\0'; }
//+----------------------------------------------------------------------------
//
// Function: SizeOfMultiSz
//
// Synopsis: determine the total size of a Multi_sz list, including
// terminating NULLs
//
// Arguments: s - pointer to list
//
// Returns: DWORD - size of s
//
// History: 6/5/97 ChrisK created
//
//-----------------------------------------------------------------------------
DWORD SizeOfMultiSz(CHAR *s) { Dprintf("ICFGNT: SizeOfMultiSz\n"); Assert(s); DWORD dwLen = 0; //
// total size of all strings
//
//
// ChrisK Olympus 6311 6/11/97
// Add special case for empty MultiSZ strings
//
//
// Special case for empty MultiSz.
// Note: even "empty" MultiSZ strings still have the two null terminating characters
//
if (!(*s)) { //
// Make sure we actually have two terminating NULLs in this case.
//
Assert(s[1] == '\0'); //
// Count terminating NULL.
//
dwLen = 1; }
while (*s) { dwLen += lstrlen(s) + 1; s += lstrlen(s) + 1; } //
// plus one for the extra terminating NULL
//
dwLen++; Dprintf("ICFGNT: SizeOfMultiSz returns %d\n", dwLen);
return dwLen; }
//+----------------------------------------------------------------------------
//
// Function: WriteBindings
//
// Synopsis: Write the data from a BINDDATA structure to the key given
//
// Arguments: bd - BINDDATA structure with data to be written
// hKey - handle of registry key to get data
//
// Returns: win32 error code
//
// History: 6/5/97 ChrisK created
//
//-----------------------------------------------------------------------------
DWORD WriteBindings(BINDDATA bd, HKEY hKey) { DWORD dwRC = ERROR_SUCCESS; DWORD dwSize;
Assert (hKey && bd.startb && bd.starte && bd.startr);
Dprintf("ICFGNT: WriteBindings\n");
//
// Bind
//
dwSize = SizeOfMultiSz(bd.startb); if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey, szBind, NULL, REG_MULTI_SZ, (LPBYTE)bd.startb, dwSize))) { Dprintf("ICFGNT: Failed to write Bind key\n"); goto WriteBindingsExit; } //
// Export
//
dwSize = SizeOfMultiSz(bd.starte); if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey, szExport, NULL, REG_MULTI_SZ, (LPBYTE)bd.starte, dwSize))) { Dprintf("ICFGNT: Failed to write export key\n"); goto WriteBindingsExit; }
//
// Route
//
dwSize = SizeOfMultiSz(bd.startr); if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey, szRoute, NULL, REG_MULTI_SZ, (LPBYTE)bd.startr, dwSize))) { Dprintf("ICFGNT: Failed to write route key\n"); goto WriteBindingsExit; }
WriteBindingsExit: return dwRC; }
//+----------------------------------------------------------------------------
//
// Function: IcfgTurnOffFileSharing
//
// Synopsis; Disable the binding between the "server" net service and the
// ndiswan4 device
//
// Arguments: dwfDriverType -
// hwndParent - parent window
//
// Returns: HRESULT - S_OK if success
//
// History: 6/5/97 ChrisK Inherited
//
//-----------------------------------------------------------------------------
HRESULT WINAPI IcfgTurnOffFileSharing(DWORD dwfDriverType, HWND hwndParent) { BINDDATA LinkData = {NULL, NULL, NULL, NULL, NULL, NULL}; BINDDATA DisData = {NULL, NULL, NULL, NULL, NULL, NULL}; HKEY hKeyLink = NULL; HKEY hKeyDis = NULL; HRESULT hr = ERROR_SUCCESS; BOOL bUpdateReg = FALSE;
Dprintf("ICFGNT: IcfgTurnOffFileSharing\n"); Assert(hwndParent); if (NULL == hwndParent) { hr = ERROR_INVALID_PARAMETER; goto IcfgTurnOffFileSharingExit; }
//
// Open Keys and read binding data
//
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, szLanManServerSubKey, &hKeyLink)) { Dprintf("ICFGNT: failed to open linkdata key\n"); goto IcfgTurnOffFileSharingExit; }
if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, szLanManServerDisabledSubKey, &hKeyDis)) { Dprintf("ICFGNT: failed to open linkdata key\n"); goto IcfgTurnOffFileSharingExit; }
GetRegValue(hKeyLink,szBind,(LPBYTE*)&LinkData.startb); GetRegValue(hKeyLink,szExport,(LPBYTE*)&LinkData.starte); GetRegValue(hKeyLink,szRoute,(LPBYTE*)&LinkData.startr); GetRegValue(hKeyDis,szBind,(LPBYTE*)&DisData.startb); GetRegValue(hKeyDis,szExport,(LPBYTE*)&DisData.starte); GetRegValue(hKeyDis,szRoute,(LPBYTE*)&DisData.startr);
//
// Initialize all current pointers
//
LinkData.currb = LinkData.startb; LinkData.curre = LinkData.starte; LinkData.currr = LinkData.startr;
DisData.currb = DisData.startb; while (*DisData.currb) { MoveNextBinding(&DisData.currb); }
DisData.curre = DisData.starte; while (*DisData.curre) { MoveNextBinding(&DisData.curre); }
DisData.currr = DisData.startr; while (*DisData.currr) { MoveNextBinding(&DisData.currr); }
//
// Scan linkages for NdisWan4 bindings
//
while (*LinkData.currb) { if (strstr(LinkData.currb, szNdisWan4)) { Dprintf("ICFGNT: server binding found in %s\n",LinkData.currb);
//
// move binding to disabled list
//
lstrcpy(DisData.currb,LinkData.currb); lstrcpy(DisData.curre,LinkData.curre); lstrcpy(DisData.currr,LinkData.currr);
//
// Advanve current pointers in DisData
//
MoveNextBinding(&DisData.currb); MoveNextBinding(&DisData.curre); MoveNextBinding(&DisData.currr);
//
// Compact remaining linkage
//
CompactLinkage(LinkData.currb); CompactLinkage(LinkData.curre); CompactLinkage(LinkData.currr);
bUpdateReg = TRUE; } else { //
// Advance to next binding
//
MoveNextBinding(&LinkData.currb); MoveNextBinding(&LinkData.curre); MoveNextBinding(&LinkData.currr); } } if (bUpdateReg) { WriteBindings(LinkData,hKeyLink); WriteBindings(DisData,hKeyDis);
RegCloseKey(hKeyDis); hKeyDis = NULL;
RegCloseKey(hKeyLink); hKeyLink = NULL;
#if defined(_DEBUG)
Dprintf("ICFGNT: ReviewBindings returnded %d\n",ReviewBindings(hwndParent)); #else
ReviewBindings(hwndParent); #endif
}
IcfgTurnOffFileSharingExit: if (hKeyDis) { RegCloseKey(hKeyDis); hKeyDis = NULL; }
if (hKeyLink) { RegCloseKey(hKeyLink); hKeyLink = NULL; }
return hr; }
|