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.
973 lines
26 KiB
973 lines
26 KiB
/****************************************************************************
|
|
*
|
|
* icfg32.cpp
|
|
*
|
|
* Microsoft Confidential
|
|
* Copyright (c) Microsoft Corporation 1992-1997
|
|
* 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
|
|
* 7/3/97 ShaunCo Modfied for NT5
|
|
* 5/1/98 donaldm Brought over from NT tree to ICW tree as part of NTCFG95.DLL
|
|
***************************************************************************/
|
|
#define INITGUID
|
|
#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"
|
|
#include "icwunicd.h"
|
|
|
|
#include <netcfgx.h>
|
|
|
|
|
|
#define REG_DATA_EXTRA_SPACE 255
|
|
|
|
DWORD g_dwLastError = ERROR_SUCCESS;
|
|
|
|
|
|
ULONG ReleaseObj
|
|
(
|
|
IUnknown* punk
|
|
)
|
|
{
|
|
return (punk) ? punk->Release () : 0;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrCreateAndInitializeINetCfg
|
|
//
|
|
// Purpose: Cocreate and initialize the root INetCfg object. This will
|
|
// optionally initialize COM for the caller too.
|
|
//
|
|
// Arguments:
|
|
// pfInitCom [in,out] TRUE to call CoInitialize before creating.
|
|
// returns TRUE if COM was successfully
|
|
// initialized FALSE if not. If NULL, means
|
|
// don't initialize COM.
|
|
// ppnc [out] The returned INetCfg object.
|
|
// fGetWriteLock [in] TRUE if a writable INetCfg is needed
|
|
// cmsTimeout [in] See INetCfg::AcquireWriteLock
|
|
// szwClientDesc [in] See INetCfg::AcquireWriteLock
|
|
// ppszwClientDesc [out] See INetCfg::AcquireWriteLock
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 7 May 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT HrCreateAndInitializeINetCfg
|
|
(
|
|
BOOL* pfInitCom,
|
|
INetCfg** ppnc,
|
|
BOOL fGetWriteLock,
|
|
DWORD cmsTimeout,
|
|
LPCWSTR szwClientDesc,
|
|
LPWSTR* ppszwClientDesc
|
|
)
|
|
{
|
|
Assert (ppnc);
|
|
|
|
// Initialize the output parameter.
|
|
*ppnc = NULL;
|
|
|
|
if (ppszwClientDesc)
|
|
{
|
|
*ppszwClientDesc = NULL;
|
|
}
|
|
|
|
// Initialize COM if the caller requested.
|
|
HRESULT hr = S_OK;
|
|
if (pfInitCom && *pfInitCom)
|
|
{
|
|
hr = CoInitializeEx( NULL,
|
|
COINIT_DISABLE_OLE1DDE | COINIT_MULTITHREADED );
|
|
if (RPC_E_CHANGED_MODE == hr)
|
|
{
|
|
hr = S_OK;
|
|
if (pfInitCom)
|
|
{
|
|
*pfInitCom = FALSE;
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Create the object implementing INetCfg.
|
|
//
|
|
INetCfg* pnc;
|
|
hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_INetCfg, reinterpret_cast<void**>(&pnc));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgLock * pnclock = NULL;
|
|
if (fGetWriteLock)
|
|
{
|
|
// Get the locking interface
|
|
hr = pnc->QueryInterface(IID_INetCfgLock,
|
|
reinterpret_cast<LPVOID *>(&pnclock));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Attempt to lock the INetCfg for read/write
|
|
hr = pnclock->AcquireWriteLock(cmsTimeout, szwClientDesc,
|
|
ppszwClientDesc);
|
|
if (S_FALSE == hr)
|
|
{
|
|
// Couldn't acquire the lock
|
|
hr = NETCFG_E_NO_WRITE_LOCK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Initialize the INetCfg object.
|
|
//
|
|
hr = pnc->Initialize(NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppnc = pnc;
|
|
pnc->AddRef ();
|
|
}
|
|
else
|
|
{
|
|
if (pnclock)
|
|
{
|
|
pnclock->ReleaseWriteLock();
|
|
}
|
|
}
|
|
// Transfer reference to caller.
|
|
}
|
|
ReleaseObj(pnclock);
|
|
|
|
ReleaseObj(pnc);
|
|
}
|
|
|
|
// If we failed anything above, and we've initialized COM,
|
|
// be sure an uninitialize it.
|
|
//
|
|
if (FAILED(hr) && pfInitCom && *pfInitCom)
|
|
{
|
|
CoUninitialize ();
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUninitializeAndUnlockINetCfg
|
|
//
|
|
// Purpose: Uninitializes and unlocks the INetCfg object
|
|
//
|
|
// Arguments:
|
|
// pnc [in] INetCfg to uninitialize and unlock
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 13 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
//+---------------------------------------------------------------------------
|
|
HRESULT HrUninitializeAndUnlockINetCfg
|
|
(
|
|
INetCfg* pnc
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = pnc->Uninitialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgLock * pnclock;
|
|
|
|
// Get the locking interface
|
|
hr = pnc->QueryInterface(IID_INetCfgLock,
|
|
reinterpret_cast<LPVOID *>(&pnclock));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Attempt to lock the INetCfg for read/write
|
|
hr = pnclock->ReleaseWriteLock();
|
|
|
|
ReleaseObj(pnclock);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUninitializeAndReleaseINetCfg
|
|
//
|
|
// Purpose: Unintialize and release an INetCfg object. This will
|
|
// optionally uninitialize COM for the caller too.
|
|
//
|
|
// Arguments:
|
|
// fUninitCom [in] TRUE to uninitialize COM after the INetCfg is
|
|
// uninitialized and released.
|
|
// pnc [in] The INetCfg object.
|
|
// fHasLock [in] TRUE if the INetCfg was locked for write and
|
|
// must be unlocked.
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 7 May 1997
|
|
//
|
|
// Notes: The return value is the value returned from
|
|
// INetCfg::Uninitialize. Even if this fails, the INetCfg
|
|
// is still released. Therefore, the return value is for
|
|
// informational purposes only. You can't touch the INetCfg
|
|
// object after this call returns.
|
|
//
|
|
//+---------------------------------------------------------------------------
|
|
HRESULT HrUninitializeAndReleaseINetCfg
|
|
(
|
|
BOOL fUninitCom,
|
|
INetCfg* pnc,
|
|
BOOL fHasLock
|
|
)
|
|
{
|
|
Assert (pnc);
|
|
HRESULT hr = S_OK;
|
|
|
|
if (fHasLock)
|
|
{
|
|
hr = HrUninitializeAndUnlockINetCfg(pnc);
|
|
}
|
|
else
|
|
{
|
|
hr = pnc->Uninitialize ();
|
|
}
|
|
|
|
ReleaseObj (pnc);
|
|
|
|
if (fUninitCom)
|
|
{
|
|
CoUninitialize ();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrInstallComponent
|
|
//
|
|
// Purpose: Install the component with a specified id.
|
|
//
|
|
// Arguments:
|
|
// pnc [in] INetCfg pointer.
|
|
// pguidClass [in] Class guid of the component to install.
|
|
// pszwComponentId [in] Component id to install.
|
|
// ppncc [out] (Optional) Returned component that was
|
|
// installed.
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 4 Jan 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
//+---------------------------------------------------------------------------
|
|
HRESULT HrInstallComponent
|
|
(
|
|
INetCfg* pnc,
|
|
const GUID* pguidClass,
|
|
LPCWSTR pszwComponentId,
|
|
INetCfgComponent** ppncc
|
|
)
|
|
{
|
|
Assert (pnc);
|
|
Assert (pszwComponentId);
|
|
|
|
// Initialize output parameter.
|
|
//
|
|
if (ppncc)
|
|
{
|
|
*ppncc = NULL;
|
|
}
|
|
|
|
// Get the class setup object.
|
|
//
|
|
INetCfgClassSetup* pncclasssetup;
|
|
HRESULT hr = pnc->QueryNetCfgClass (pguidClass, IID_INetCfgClassSetup,
|
|
reinterpret_cast<void**>(&pncclasssetup));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
OBO_TOKEN OboToken;
|
|
ZeroMemory (&OboToken, sizeof(OboToken));
|
|
OboToken.Type = OBO_USER;
|
|
|
|
|
|
hr = pncclasssetup->Install (pszwComponentId,
|
|
&OboToken, 0, 0, NULL, NULL, ppncc);
|
|
|
|
ReleaseObj (pncclasssetup);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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(LPTSTR lpszSourcePath)
|
|
{
|
|
TraceMsg(TF_GENERAL, "ICFGNT: IcfgSetInstallSourcePath\n");
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: ValidateProductSuite
|
|
//
|
|
// Synopsis: Check registry for a particular Product Suite string
|
|
//
|
|
// Arguments: SuiteName - name of product suite to look for
|
|
//
|
|
// Returns: TRUE - the suite exists
|
|
//
|
|
// History: 6/5/97 ChrisK Inherited
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
ValidateProductSuite(LPTSTR SuiteName)
|
|
{
|
|
BOOL rVal = FALSE;
|
|
LONG Rslt;
|
|
HKEY hKey = NULL;
|
|
DWORD Type = 0;
|
|
DWORD Size = 0;
|
|
LPTSTR ProductSuite = NULL;
|
|
LPTSTR p;
|
|
|
|
TraceMsg(TF_GENERAL, "ICFGNT: ValidateProductSuite\n");
|
|
//
|
|
// Determine the size required to read registry values
|
|
//
|
|
Rslt = RegOpenKeyA(
|
|
HKEY_LOCAL_MACHINE,
|
|
"System\\CurrentControlSet\\Control\\ProductOptions",
|
|
&hKey
|
|
);
|
|
if (Rslt != ERROR_SUCCESS)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
Rslt = RegQueryValueExA(
|
|
hKey,
|
|
"ProductSuite",
|
|
NULL,
|
|
&Type,
|
|
NULL,
|
|
&Size
|
|
);
|
|
if (Rslt != ERROR_SUCCESS)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if (!Size)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
ProductSuite = (LPTSTR) GlobalAlloc( GPTR, Size );
|
|
if (!ProductSuite)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Read ProductSuite information
|
|
//
|
|
Rslt = RegQueryValueExA(
|
|
hKey,
|
|
"ProductSuite",
|
|
NULL,
|
|
&Type,
|
|
(LPBYTE) ProductSuite,
|
|
&Size
|
|
);
|
|
if (Rslt != ERROR_SUCCESS)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
if (Type != REG_MULTI_SZ)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// Look for a particular string in the data returned
|
|
// Note: data is terminiated with two NULLs
|
|
//
|
|
p = ProductSuite;
|
|
while (*p) {
|
|
if (_tcsstr( p, SuiteName ))
|
|
{
|
|
rVal = TRUE;
|
|
break;
|
|
}
|
|
p += (lstrlen( p ) + 1);
|
|
}
|
|
|
|
exit:
|
|
if (ProductSuite)
|
|
{
|
|
GlobalFree( ProductSuite );
|
|
}
|
|
|
|
if (hKey)
|
|
{
|
|
RegCloseKey( hKey );
|
|
}
|
|
|
|
return rVal;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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, LPTSTR lpValueName, LPBYTE *lpData)
|
|
{
|
|
LONG dwError;
|
|
DWORD cbData;
|
|
|
|
TraceMsg(TF_GENERAL, "ICFGNT: GetRegValue\n");
|
|
dwError = RegQueryValueEx(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 = RegQueryValueEx(hKey,
|
|
lpValueName,
|
|
NULL,
|
|
NULL,
|
|
*lpData,
|
|
&cbData);
|
|
if(dwError != ERROR_SUCCESS)
|
|
{
|
|
GlobalFree(*lpData);
|
|
}
|
|
|
|
return(dwError);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
|
|
TraceMsg(TF_GENERAL, "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: 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
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT WINAPI
|
|
IcfgNeedModem (DWORD dwfOptions, LPBOOL lpfNeedModem)
|
|
{
|
|
//
|
|
// Ras is installed, and ICW wants to know if it needs to
|
|
// install a modem.
|
|
//
|
|
*lpfNeedModem = TRUE;
|
|
|
|
// Get the device info set for modems.
|
|
//
|
|
HDEVINFO hdevinfo = SetupDiGetClassDevs((GUID*)&GUID_DEVCLASS_MODEM,
|
|
NULL,
|
|
NULL,
|
|
DIGCF_PRESENT);
|
|
if (hdevinfo)
|
|
{
|
|
SP_DEVINFO_DATA diData;
|
|
diData.cbSize = sizeof(diData);
|
|
|
|
// Look for at least one modem.
|
|
//
|
|
if (SetupDiEnumDeviceInfo(hdevinfo, 0, &diData))
|
|
{
|
|
*lpfNeedModem = FALSE;
|
|
}
|
|
|
|
SetupDiDestroyDeviceInfoList (hdevinfo);
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
IcfgInstallModem (HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsStart)
|
|
{
|
|
//$ BUGBUG (shaunco) 3 Jul 1997: See if we need to install a modem, or
|
|
// just install it?
|
|
|
|
//
|
|
// Fire up the modem install wizard
|
|
//
|
|
if (!CallModemInstallWizard(hwndParent))
|
|
{
|
|
return(g_dwLastError = GetLastError());
|
|
}
|
|
|
|
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
|
|
IcfgNeedInetComponents(DWORD dwfOptions, LPBOOL lpfNeedComponents)
|
|
{
|
|
TraceMsg(TF_GENERAL, "ICFGNT: IcfgNeedInetComponents\n");
|
|
|
|
//
|
|
// Assume we have what we need.
|
|
//
|
|
*lpfNeedComponents = FALSE;
|
|
|
|
HRESULT hr = S_OK;
|
|
INetCfg* pnc = NULL;
|
|
BOOL fInitCom = TRUE;
|
|
|
|
// If the optiona are such that we need an INetCfg interface pointer,
|
|
// get one.
|
|
//
|
|
if ((dwfOptions & ICFG_INSTALLTCP) ||
|
|
(dwfOptions & ICFG_INSTALLRAS))
|
|
{
|
|
hr = HrCreateAndInitializeINetCfg (&fInitCom, &pnc,
|
|
FALSE, 0, NULL, NULL);
|
|
}
|
|
|
|
// Look for TCP/IP using the INetCfg interface.
|
|
//
|
|
if (SUCCEEDED(hr) && (dwfOptions & ICFG_INSTALLTCP))
|
|
{
|
|
Assert (pnc);
|
|
|
|
hr = pnc->FindComponent (NETCFG_TRANS_CID_MS_TCPIP, NULL);
|
|
if (S_FALSE == hr)
|
|
{
|
|
*lpfNeedComponents = TRUE;
|
|
}
|
|
}
|
|
|
|
// We no longer need the INetCfg interface pointer, so release it.
|
|
//
|
|
if (pnc)
|
|
{
|
|
(void) HrUninitializeAndReleaseINetCfg (fInitCom, pnc, FALSE);
|
|
}
|
|
|
|
if (dwfOptions & ICFG_INSTALLMAIL)
|
|
{
|
|
// How do we do this?
|
|
Assert (0);
|
|
}
|
|
|
|
// Normalize the HRESULT.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
IcfgInstallInetComponents(HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsRestart)
|
|
{
|
|
TraceMsg(TF_GENERAL, "ICFGNT: IcfgInstallInetComponents\n");
|
|
|
|
//
|
|
// Assume don't need restart
|
|
//
|
|
*lpfNeedsRestart = FALSE;
|
|
|
|
HRESULT hr = S_OK;
|
|
INetCfg* pnc = NULL;
|
|
BOOL fInitCom = TRUE;
|
|
|
|
// If the optiona are such that we need an INetCfg interface pointer,
|
|
// get one.
|
|
//
|
|
if ((dwfOptions & ICFG_INSTALLTCP) ||
|
|
(dwfOptions & ICFG_INSTALLRAS))
|
|
{
|
|
BSTR bstrClient;
|
|
hr = HrCreateAndInitializeINetCfg (&fInitCom, &pnc, TRUE,
|
|
0, L"", &bstrClient);
|
|
}
|
|
|
|
// Install TCP/IP on behalf of the user.
|
|
//
|
|
if (SUCCEEDED(hr) && (dwfOptions & ICFG_INSTALLTCP))
|
|
{
|
|
hr = HrInstallComponent (pnc, &GUID_DEVCLASS_NETTRANS,
|
|
NETCFG_TRANS_CID_MS_TCPIP, NULL);
|
|
}
|
|
|
|
// We no longer need the INetCfg interface pointer, so release it.
|
|
//
|
|
if (pnc)
|
|
{
|
|
// Apply the changes if everything was successful.
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pnc->Apply ();
|
|
|
|
if (NETCFG_S_REBOOT == hr)
|
|
{
|
|
*lpfNeedsRestart = TRUE;
|
|
}
|
|
}
|
|
(void) HrUninitializeAndReleaseINetCfg (fInitCom, pnc, TRUE);
|
|
}
|
|
|
|
if (dwfOptions & ICFG_INSTALLMAIL)
|
|
{
|
|
// How do we do this?
|
|
Assert (0);
|
|
}
|
|
|
|
// Normalize the HRESULT.
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IcfgGetLastInstallErrorText
|
|
//
|
|
// Synopsis: Format error message for most recent error
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: DWORD - win32 error code
|
|
// lpszErrorDesc - string containing error message
|
|
// cbErrorDesc - size of lpszErrorDesc
|
|
//
|
|
// History: 6/5/97 ChrisK Inherited
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD WINAPI
|
|
IcfgGetLastInstallErrorText(LPTSTR lpszErrorDesc, DWORD cbErrorDesc)
|
|
{
|
|
TraceMsg(TF_GENERAL, "ICFGNT: IcfgGetLastInstallErrorText\n");
|
|
return(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
g_dwLastError,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
|
|
lpszErrorDesc,
|
|
cbErrorDesc,
|
|
NULL));
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IcfgIsFileSharingTurnedOn
|
|
//
|
|
// Synopsis: Always returns false for NT 5 because file sharing is controlled
|
|
// at the RAS connectoid level, and is always turned off for ICW
|
|
// generated connectoids
|
|
//
|
|
// Arguments: dwfDriverType -
|
|
//
|
|
// Returns: HRESULT - S_OK is success
|
|
// lpfSharingOn - TRUE if sharing is bound
|
|
//
|
|
// History: 6/5/97 ChrisK Inherited
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT WINAPI IcfgIsFileSharingTurnedOn
|
|
(
|
|
DWORD dwfDriverType,
|
|
LPBOOL lpfSharingOn
|
|
)
|
|
{
|
|
HRESULT hr = ERROR_SUCCESS;
|
|
|
|
TraceMsg(TF_GENERAL, "ICFGNT: IcfgIsFileSharingTurnedOn\n");
|
|
Assert(lpfSharingOn);
|
|
if (NULL == lpfSharingOn)
|
|
{
|
|
hr = ERROR_INVALID_PARAMETER;
|
|
goto IcfgIsFileSharingTurnedOnExit;
|
|
}
|
|
|
|
*lpfSharingOn = FALSE;
|
|
|
|
IcfgIsFileSharingTurnedOnExit:
|
|
return hr;
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IcfgTurnOffFileSharing
|
|
//
|
|
// Synopsis; For NT 5, this is handed as a RAS property, so we just return
|
|
// success here.
|
|
//
|
|
//
|
|
// Arguments: dwfDriverType -
|
|
// hwndParent - parent window
|
|
//
|
|
// Returns: HRESULT - ERROR_SUCCESS
|
|
//
|
|
// History: 6/5/97 ChrisK Inherited
|
|
// 07/21/98 donaldm
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT WINAPI IcfgTurnOffFileSharing
|
|
(
|
|
DWORD dwfDriverType,
|
|
HWND hwndParent
|
|
)
|
|
{
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IcfgStartServices
|
|
//
|
|
// Synopsis: Start all services required by system
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: HRESULT - S_OK if success
|
|
//
|
|
// History: 6/5/97 ChrisK Iherited
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT WINAPI IcfgStartServices()
|
|
{
|
|
//This stuff is handled auto-magically by the RAS API.
|
|
//but since there so much code that calls this function we'll
|
|
//be simple and fake success
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: IcfgIsGlobalDNS
|
|
//
|
|
// Note: these functions are not needed on an NT system and it therefore not
|
|
// implemented
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT WINAPI
|
|
IcfgIsGlobalDNS(LPBOOL lpfGlobalDNS)
|
|
{
|
|
*lpfGlobalDNS = FALSE;
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
IcfgRemoveGlobalDNS()
|
|
{
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
InetGetSupportedPlatform(LPDWORD pdwPlatform)
|
|
{
|
|
*pdwPlatform = VER_PLATFORM_WIN32_NT;
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
InetSetAutodial(BOOL fEnable, LPCTSTR lpszEntryName) {
|
|
return(ERROR_INVALID_FUNCTION);
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
InetGetAutodial(LPBOOL lpfEnable, LPSTR lpszEntryName, DWORD cbEntryName) {
|
|
return(ERROR_INVALID_FUNCTION);
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
InetSetAutodialAddress(DWORD dwDialingLocation, LPTSTR szEntry) {
|
|
return(ERROR_SUCCESS);
|
|
}
|