mirror of https://github.com/lianthony/NT4.0
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.
5317 lines
148 KiB
5317 lines
148 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// File: Setup.cpp
|
|
//
|
|
// Contents: This file contains the Setup entry points and support functions
|
|
//
|
|
// Entry Points:
|
|
// CplSetup - The main setup entry point
|
|
//
|
|
//
|
|
// Notes:
|
|
//
|
|
// History:
|
|
// April 21, 1995 MikeMi - Created
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.hxx" // Precompiled header
|
|
#pragma hdrstop
|
|
|
|
static const int MAX_TEMP = 1024;
|
|
|
|
// Access rights required for using Service Controller, et al.
|
|
|
|
#define SVC_CTRL_ACCESS (GENERIC_ALL)
|
|
#define SVC_CTRL_START_ACCESS (GENERIC_READ | GENERIC_EXECUTE)
|
|
#define LSA_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE)
|
|
|
|
#define ARGMAX 8000 // note that getparams has returned over 3800
|
|
static CHAR g_achBuff [ ARGMAX ] ; // N.B. Must be static for use as
|
|
// return value to SETUP.
|
|
#define DLG_NM_LANANUM MAKEINTRESOURCE(IDD_DLG_NM_LANANUM)
|
|
|
|
|
|
|
|
enum ESETUP_ARGS { ESARG_HWND, ESARG_FUNC, ESARG_1ST };
|
|
enum ESETUP_FUNC
|
|
{ // (N.B.: asterisk means it uses a window handle)
|
|
ESFUNC_NONE, // None
|
|
ESFUNC_NCPA, // *Run NCPA, OEM Setup, etc.
|
|
ESFUNC_DOMAIN, // *Perform domain setup
|
|
ESFUNC_CONNECT, // Connect to network sharepoint
|
|
ESFUNC_CREATE_SERVICE, // Create a Service Controller Service
|
|
ESFUNC_DELETE_SERVICE, // Delete " " " "
|
|
ESFUNC_START_SERVICE, // Start " " " "
|
|
ESFUNC_SECURE_REG_KEY, // Change security on a registry key
|
|
ESFUNC_WINSOCK_MAPPING, // Retrieve and store WinSock mapping info
|
|
ESFUNC_ERROR_MESSAGE, // Translate an APIERR to an error message
|
|
ESFUNC_DETECT_START, // Start netcard detection
|
|
ESFUNC_DETECT_END, // Terminate netcard detection
|
|
ESFUNC_DETECT_RESET, // Reset detection iteration
|
|
ESFUNC_DETECT_CARD, // Detect a netcard
|
|
ESFUNC_DETECT_VERIFY, // Verify the setting of a netcard
|
|
ESFUNC_DETECT_PARAMS, // Return netcard type parameter info
|
|
ESFUNC_DETECT_QUERY, // Return netcard instance paramter info
|
|
ESFUNC_DETECT_STRING, // Return option data string
|
|
ESFUNC_DETECT_PNAME, // Return parameter name string
|
|
ESFUNC_DETECT_CLAIM, // Claim new resources
|
|
ESFUNC_DETECT_OPEN, // Open a handle to an existing card
|
|
ESFUNC_SECURE_SERVICE, // Set service security info
|
|
ESFUNC_TCPIP_CFG_CHECK, // See if TCP/IP needs reconfiguration
|
|
ESFUNC_MCS_CFG_CHECK, // See if MCS needs reconfiguration
|
|
ESFUNC_ROUTE_TO_INF_LIST, // Convert imbedded quoted string to list
|
|
ESFUNC_BINDINGS_ONLY, // *Run NCPA for bindings only
|
|
ESFUNC_ACTIVATE_BINDINGS, // Given a list of bindings, activate them
|
|
ESFUNC_BDC_REPLICATE, // Wait for the BDC replication to complete
|
|
ESFUNC_MAX
|
|
};
|
|
|
|
|
|
static struct SETUP_FUNC_INDEX
|
|
{
|
|
ESETUP_FUNC esFunc ;
|
|
TCHAR * pszToken ;
|
|
BOOL fUsesHwnd ;
|
|
BOOL fStillSupported ;
|
|
} setupFuncIndex [] =
|
|
{ // who uses this
|
|
{ ESFUNC_NCPA, SZ("NCPA") , TRUE , TRUE }, // setup only
|
|
{ ESFUNC_DOMAIN, SZ("DOMAIN") , TRUE , FALSE }, // setup only
|
|
{ ESFUNC_CONNECT, SZ("CONNECT") , FALSE , FALSE }, // not used
|
|
{ ESFUNC_CREATE_SERVICE, SZ("CREATESVC") , FALSE , TRUE }, // utility
|
|
{ ESFUNC_DELETE_SERVICE, SZ("DELETESVC") , FALSE , TRUE }, // oem, utility
|
|
{ ESFUNC_START_SERVICE, SZ("STARTSVC") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_SECURE_REG_KEY, SZ("SECUREKEY") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_WINSOCK_MAPPING, SZ("WINSOCKMAP"), FALSE , TRUE }, // utility
|
|
{ ESFUNC_ERROR_MESSAGE, SZ("ERRORMSG") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_DETECT_START, SZ("DTSTART") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_END, SZ("DTEND") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_RESET, SZ("DTRESET") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_CARD, SZ("DTCARD") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_PARAMS, SZ("DTPARAMS") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_QUERY, SZ("DTQUERY") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_VERIFY, SZ("DTVERIFY") , FALSE , TRUE }, // oem (ncparam)
|
|
{ ESFUNC_DETECT_STRING, SZ("DTSTRING") , FALSE , TRUE }, // not used (doc'ed)
|
|
{ ESFUNC_DETECT_PNAME, SZ("DTPNAME") , FALSE , TRUE }, // not used (doc'ed)
|
|
{ ESFUNC_DETECT_CLAIM, SZ("DTCLAIM") , FALSE , TRUE }, // ncparam
|
|
{ ESFUNC_DETECT_OPEN, SZ("DTOPEN") , FALSE , FALSE }, // not used
|
|
{ ESFUNC_SECURE_SERVICE, SZ("SECURESVC") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_TCPIP_CFG_CHECK, SZ("TCPCFGCHK") , FALSE , FALSE }, // not used
|
|
{ ESFUNC_MCS_CFG_CHECK, SZ("MCSCFGCHK") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_ROUTE_TO_INF_LIST, SZ("ROUTETOLIST"), FALSE, TRUE }, // oem (nbinfo)
|
|
{ ESFUNC_BINDINGS_ONLY, SZ("BINDONLY") , TRUE , FALSE }, // not used
|
|
{ ESFUNC_ACTIVATE_BINDINGS, SZ("ACTIVBIND") , FALSE , TRUE }, // oem
|
|
{ ESFUNC_BDC_REPLICATE, SZ("DOBDCREPL") , TRUE , FALSE }, // setup
|
|
{ ESFUNC_NONE, NULL , FALSE , FALSE }
|
|
};
|
|
|
|
/*
|
|
* Merge the contents of *pslOther onto *pslMain.
|
|
* Each string is fully duplicated.
|
|
*/
|
|
static APIERR mergeStrLists ( STRLIST * pslMain, STRLIST * pslOther )
|
|
{
|
|
APIERR err = 0 ;
|
|
ITER_STRLIST islOther( *pslOther ) ;
|
|
NLS_STR * pnlsNext,
|
|
* pnlsDup = NULL ;
|
|
|
|
// This unfortunate code is based on the fact that STRLIST
|
|
// iteration/removal is not reliable.
|
|
|
|
while ( pnlsNext = islOther.Next() )
|
|
{
|
|
pnlsDup = new NLS_STR( *pnlsNext ) ;
|
|
|
|
err = pnlsDup == NULL
|
|
? ERROR_NOT_ENOUGH_MEMORY
|
|
: pnlsDup->QueryError() ;
|
|
|
|
if ( err )
|
|
break ;
|
|
|
|
err = pslMain->Append( pnlsDup ) ;
|
|
|
|
pnlsDup = NULL ;
|
|
|
|
if ( err )
|
|
break ;
|
|
}
|
|
|
|
delete pnlsDup ; // Precaution if failure.
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: appendToInfList
|
|
|
|
SYNOPSIS: Add a string (or number) to an INF-style list.
|
|
Prefix or suffix with comma separator as requested.
|
|
|
|
ENTRY: NLS_STR * pnlsList result
|
|
TCHAR * pszData data to append
|
|
INFSEPCTL separator control flags
|
|
|
|
EXIT: APIERR err != 0 if failure
|
|
|
|
RETURNS:
|
|
|
|
NOTES: Has overloaded variant for numbers.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
|
|
enum INFSEPCTL { ISC_None, ISC_Before, ISC_After, ISC_Both } ;
|
|
|
|
static APIERR appendToInfList (
|
|
NLS_STR * pnlsList, // List a-building
|
|
const TCHAR * pszData, // Data to append
|
|
INFSEPCTL iSepCtl = ISC_None ) // Add separators?
|
|
{
|
|
#define CHQUOTE ((TCHAR)TCH('\"'))
|
|
#define CHSEP ((TCHAR)TCH(','))
|
|
#define CHSPACE ((TCHAR)TCH(' '))
|
|
|
|
APIERR err = 0 ;
|
|
do
|
|
{
|
|
if ( iSepCtl & ISC_Before )
|
|
{
|
|
if ( err = pnlsList->AppendChar( CHSEP ) )
|
|
break ;
|
|
}
|
|
if ( err = pnlsList->AppendChar( CHQUOTE ) )
|
|
break ;
|
|
if ( err = pnlsList->Append( pszData ) )
|
|
break ;
|
|
if ( err = pnlsList->AppendChar( CHQUOTE ) )
|
|
break ;
|
|
if ( ! (iSepCtl & ISC_After) )
|
|
break ;
|
|
if ( err = pnlsList->AppendChar( CHSEP ) )
|
|
break ;
|
|
|
|
} while ( FALSE ) ;
|
|
return err ;
|
|
}
|
|
|
|
static APIERR appendToInfList (
|
|
NLS_STR * pnlsList, // List a-building
|
|
INT iArg, // Integer to add
|
|
INFSEPCTL iSepCtl = ISC_None ) // Add separators?
|
|
{
|
|
TCHAR chBuffer [ 20 ] ;
|
|
|
|
IntToStr( iArg, chBuffer, 10 ) ;
|
|
return appendToInfList( pnlsList, chBuffer, iSepCtl ) ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunCreateService
|
|
|
|
SYNOPSIS: Create a new Win32 service in the Service Controller
|
|
|
|
ENTRY: TCHAR * pszParms [] command line parameters from SETUP
|
|
|
|
pszParms [0] String: Name of Service
|
|
pszParms [1] String: Display Name of Service
|
|
pszParms [2] Decimal: Start code
|
|
pszParms [3] Decimal: Type code
|
|
pszParms [4] Decimal: Error control value
|
|
pszParms [5] String: Path\exename
|
|
pszParms [6] String: Load order group name
|
|
pszParms [7] String: Dependency names
|
|
optional pszParms [8] String: account start name
|
|
optional pszParms [9] String: Password
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
If the account name is not passed, "LocalSystem" is used
|
|
as the default.
|
|
|
|
The dependency names should be constructed as a SETUP
|
|
list with {}; for example:
|
|
|
|
{ "dependency 1","dependency 2" }
|
|
|
|
HISTORY: DavidHov 5/24/92 Created
|
|
|
|
********************************************************************/
|
|
APIERR RunCreateService ( const TCHAR * pszParms [], INT cArgs )
|
|
{
|
|
|
|
// Definition stolen from SVCCTRL\SERVER\ACCOUNT.H
|
|
#define LOCAL_SYSTEM_USER_NAME SZ("LocalSystem")
|
|
|
|
APIERR err = 0 ;
|
|
TCHAR szDependencies [ 500 ] ;
|
|
|
|
enum ECSVCPARM
|
|
{
|
|
ECSP_NAME,
|
|
ECSP_DISPLAY_NAME,
|
|
ECSP_START,
|
|
ECSP_TYPE,
|
|
ECSP_ERROR_CONTROL,
|
|
ECSP_BINARY_PATH,
|
|
ECSP_GROUP_NAME,
|
|
ECSP_DEPENDENCIES,
|
|
ECSP_START_NAME, // optional
|
|
ECSP_PASSWORD // optional
|
|
};
|
|
|
|
if ( cArgs < ECSP_START_NAME )
|
|
{
|
|
return ERROR_INVALID_PARAMETER ;
|
|
}
|
|
|
|
const TCHAR * pszName = pszParms[ ECSP_NAME ] ;
|
|
|
|
const TCHAR * pszDisplayName = pszParms[ ECSP_DISPLAY_NAME ] ;
|
|
|
|
const TCHAR * pszPath = pszParms[ ECSP_BINARY_PATH ] ;
|
|
const TCHAR * pszDependencies = CvtList( pszParms[ ECSP_DEPENDENCIES ],
|
|
szDependencies,
|
|
sizeof szDependencies ) ;
|
|
const TCHAR * pszAccount = cArgs > ECSP_START_NAME
|
|
? pszParms[ ECSP_START_NAME ]
|
|
: NULL ;
|
|
const TCHAR * pszPassword = cArgs > ECSP_PASSWORD
|
|
? pszParms[ ECSP_PASSWORD ]
|
|
: NULL ;
|
|
const TCHAR * pszGroup = pszParms[ ECSP_GROUP_NAME ] ;
|
|
|
|
// NULL the account and password parameters if necessary,
|
|
// then default them.
|
|
|
|
if ( pszAccount != NULL )
|
|
{
|
|
if ( ::strlenf( pszAccount ) == 0 )
|
|
pszAccount = NULL ;
|
|
}
|
|
if ( pszPassword != NULL )
|
|
{
|
|
if ( ::strlenf( pszPassword ) == 0 )
|
|
pszPassword = NULL ;
|
|
}
|
|
|
|
UINT uiStart = CvtDec( pszParms[ ECSP_START ] ) ;
|
|
UINT uiType = CvtDec( pszParms[ ECSP_TYPE ] ) ;
|
|
UINT uiError = CvtDec( pszParms[ ECSP_ERROR_CONTROL ] ) ;
|
|
|
|
//
|
|
// See if the "ObjectName" must be defaulted. It's interpreted
|
|
// as "account context in which to run process" for services,
|
|
// and as "NT object name" for drivers.
|
|
//
|
|
if ( pszAccount == NULL && ! (uiType & SERVICE_DRIVER) )
|
|
{
|
|
pszAccount = LOCAL_SYSTEM_USER_NAME ;
|
|
}
|
|
|
|
SC_MANAGER * pScManager = NULL ;
|
|
SC_SERVICE * pScService = NULL ;
|
|
|
|
do // Pseudo-loop for error breakuot
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: Create service named: ") << pszName ) ;
|
|
|
|
// Construct an SC_MANAGER to handle the request
|
|
|
|
pScManager = new SC_MANAGER( NULL, SVC_CTRL_ACCESS ) ;
|
|
|
|
if ( pScManager == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
if ( err = pScManager->QueryError() )
|
|
break ;
|
|
|
|
// Create the new service object
|
|
|
|
#if defined(DEBUG)
|
|
TRACEEOL( SZ("NCPA/SETP: service type: ") << uiType
|
|
<< SZ(" start: ") << uiStart
|
|
<< SZ(" error: ") << uiError
|
|
<< SZ(" path: [") << pszPath << SZ("]") ) ;
|
|
if ( pszGroup && ::strlenf( pszGroup ) )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: service group: ") << pszGroup ) ;
|
|
}
|
|
TRACEEOL( SZ("NCPA/SETP: service dependencies: [")
|
|
<< pszDependencies << SZ("]") ) ;
|
|
#endif
|
|
|
|
if ( err = pScManager->Lock())
|
|
break;
|
|
|
|
pScService = new SC_SERVICE ( *pScManager,
|
|
pszName,
|
|
pszDisplayName,
|
|
uiType,
|
|
uiStart,
|
|
uiError,
|
|
pszPath,
|
|
pszGroup,
|
|
pszDependencies,
|
|
pszAccount,
|
|
pszPassword,
|
|
SVC_CTRL_ACCESS );
|
|
|
|
if ( err = pScManager->Unlock())
|
|
break;
|
|
|
|
if ( pScService == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
if ( err = pScService->QueryError() )
|
|
break ;
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
delete pScService ;
|
|
delete pScManager ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDeleteService
|
|
|
|
SYNOPSIS: Delete a Win32 service from the Service Controller
|
|
|
|
ENTRY: TCHAR * pszService Name of Service
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
|
|
HISTORY: DavidHov 5/26/92 Created
|
|
|
|
********************************************************************/
|
|
APIERR RunDeleteService ( const TCHAR * pszService )
|
|
{
|
|
APIERR err ;
|
|
|
|
// Create the Service Controller access object
|
|
|
|
TRACEEOL( SZ("NCPA/SETP: Delete service named: ") << pszService ) ;
|
|
|
|
SC_MANAGER scMgr( NULL, SVC_CTRL_ACCESS );
|
|
|
|
if ( err = scMgr.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
if ( err = scMgr.Lock())
|
|
return err;
|
|
|
|
SC_SERVICE scSvc( scMgr, pszService, SVC_CTRL_ACCESS );
|
|
|
|
if ( err = scSvc.QueryError() )
|
|
{
|
|
scMgr.Unlock();
|
|
return err ;
|
|
}
|
|
|
|
err = scSvc.Delete() ;
|
|
|
|
if ( err = scMgr.Unlock())
|
|
return err;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunStartService
|
|
|
|
SYNOPSIS: Start a service
|
|
|
|
ENTRY: TCHAR * pszParms [] command line parameters from SETUP
|
|
|
|
pszParms [0] String: Name of Service
|
|
pszParms [1] Decimal: MS to sleep after starting
|
|
pszParms [2] String: passed to service; all
|
|
subsequent parms are also
|
|
passed to the service
|
|
|
|
INT cArgs Number of arguments passed
|
|
|
|
BOOL fStartOk If TRUE, service is checked to
|
|
see if it's already running.
|
|
If so, it's not an error.
|
|
|
|
EXIT: nothing
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunStartService (
|
|
const TCHAR * pszParms [],
|
|
INT cArgs,
|
|
BOOL fStartOk = FALSE )
|
|
{
|
|
APIERR err = 0 ;
|
|
DWORD dwPostStartSleep = 0 ;
|
|
|
|
INT cSvcArgs = cArgs - 2 ;
|
|
|
|
// Maximum time to wait for service to attain "running" state
|
|
const DWORD dwSvcMaxSleep = 60000 ;
|
|
|
|
if ( cSvcArgs < 0 )
|
|
cSvcArgs = 0 ;
|
|
|
|
// Must have at least the name of the service
|
|
|
|
if ( cArgs < 1 )
|
|
{
|
|
return ERROR_INVALID_PARAMETER ;
|
|
}
|
|
|
|
// Check to see if starting an individual service or a group
|
|
|
|
if ( *pszParms[0] == L'+' )
|
|
{
|
|
const TCHAR * pszTmp = pszParms[0];
|
|
|
|
// Skip the '+'
|
|
pszTmp++;
|
|
|
|
// Starting a group.
|
|
err = NcpaStartGroup( pszTmp, NULL, TRUE );
|
|
}
|
|
else
|
|
{
|
|
// Starting a service
|
|
// If extra sleep desired, convert and constrain it.
|
|
|
|
if ( cArgs >= 2 )
|
|
{
|
|
dwPostStartSleep = CvtDec( pszParms[1] ) ;
|
|
if ( dwPostStartSleep > dwSvcMaxSleep )
|
|
dwPostStartSleep = dwSvcMaxSleep ;
|
|
}
|
|
|
|
if ( (err = NcpaStartService( pszParms[0], NULL, TRUE, cSvcArgs, & pszParms[2] )) == 0 )
|
|
{
|
|
// If an extra delay is desired after starting the service,
|
|
// do it.
|
|
|
|
if ( dwPostStartSleep )
|
|
{
|
|
::Sleep( dwPostStartSleep ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
TRACEEOL( SZ("NCPA/SETP: Start service returned: ") << err ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunSecureKey
|
|
|
|
SYNOPSIS: Change the security on a Registry key. This
|
|
function is very limited; it uses the SETUP form
|
|
of a Registry handle (a string prefixed with a '|'
|
|
character) and allows the security descriptor to be
|
|
changed to one of the limited range defined in
|
|
..\NCPA\NCPAACL.CXX.
|
|
|
|
This routine was written to support changed ACLs
|
|
on the keys associated with the Replicator service,
|
|
which require "replicator alias all" in addition
|
|
to the standard SETUP/NCPA process DACL settings.
|
|
|
|
ENTRY: TCHAR * pszHandle SETUP-formatted string handle
|
|
to open registry key
|
|
TCHAR * pszIndex string decimal number of
|
|
security to apply
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunSecureKey ( const TCHAR * pszHandle, const TCHAR * pszIndex )
|
|
{
|
|
HKEY hKey = CvtRegHandle( pszHandle ) ;
|
|
INT iSec = CvtDec( pszIndex ) ;
|
|
PSECURITY_ATTRIBUTES pSecAttr = NULL ;
|
|
APIERR err ;
|
|
|
|
if ( ! hKey )
|
|
return ERROR_INVALID_HANDLE ;
|
|
if ( iSec >= NCSA_MAX )
|
|
return ERROR_INVALID_PARAMETER ;
|
|
|
|
err = ::NcpaCreateSecurityAttributes( & pSecAttr, iSec ) ;
|
|
if ( err == 0 )
|
|
{
|
|
err = ::RegSetKeySecurity( hKey,
|
|
DACL_SECURITY_INFORMATION,
|
|
pSecAttr->lpSecurityDescriptor ) ;
|
|
}
|
|
|
|
::NcpaDestroySecurityAttributes( pSecAttr ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunSecureService
|
|
|
|
SYNOPSIS: Change the security on a Win32 Service. See the
|
|
limitations described for RunSecureKey() above.
|
|
|
|
ENTRY: TCHAR * pszService name of service to be modified
|
|
|
|
TCHAR * pszIndex string decimal number of
|
|
security to apply
|
|
EXIT: Nothing
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunSecureService (
|
|
const TCHAR * pszService,
|
|
const TCHAR * pszIndex )
|
|
{
|
|
APIERR err ;
|
|
PSECURITY_ATTRIBUTES pSecAttr = NULL ;
|
|
|
|
// Convert the ACL index to decimal
|
|
|
|
INT iSec = CvtDec( pszIndex ) ;
|
|
if ( iSec >= NCSA_MAX )
|
|
return ERROR_INVALID_PARAMETER ;
|
|
|
|
// Create the Service Controller access object
|
|
|
|
TRACEEOL( SZ("NCPA/SETP: Change security on service named: ")
|
|
<< pszService ) ;
|
|
|
|
SC_MANAGER scMgr( NULL, SVC_CTRL_ACCESS );
|
|
|
|
if ( err = scMgr.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
// Create the Service object
|
|
if ( err = scMgr.Lock())
|
|
return err;
|
|
|
|
SC_SERVICE scSvc( scMgr, pszService, SVC_CTRL_ACCESS );
|
|
|
|
if ( err = scSvc.QueryError() )
|
|
{
|
|
scMgr.Unlock();
|
|
return err ;
|
|
}
|
|
|
|
err = ::NcpaCreateSecurityAttributes( & pSecAttr, iSec ) ;
|
|
if ( err == 0 )
|
|
{
|
|
err = scSvc.SetSecurity( DACL_SECURITY_INFORMATION,
|
|
pSecAttr->lpSecurityDescriptor ) ;
|
|
}
|
|
|
|
::NcpaDestroySecurityAttributes( pSecAttr ) ;
|
|
|
|
if ( err = scMgr.Unlock())
|
|
return err;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunWinsockMapping
|
|
|
|
SYNOPSIS: Extract Winsock mapping information from a transport's
|
|
companion DLL and store it into the Registry.
|
|
|
|
ENTRY: TCHAR * pszParms [] command line parameters from SETUP
|
|
|
|
pszParms [0] String: name of DLL
|
|
pszParms [1] String: SETUP-format Registry key
|
|
handle.
|
|
|
|
EXIT: nothing
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
#define WSHWINSOCKMAPPING "WSHGetWinsockMapping"
|
|
#define WSH_MappingValueName SZ("Mapping")
|
|
#define WSH_MAX_MAPPING_DATA 8192
|
|
|
|
APIERR RunWinsockMapping ( const TCHAR * pszDllName, const TCHAR * pszHandle )
|
|
{
|
|
HKEY hKey = NULL ;
|
|
HMODULE hDll = NULL ;
|
|
APIERR err = 0 ;
|
|
PWINSOCK_MAPPING pMapTriples = NULL ;
|
|
PWSH_GET_WINSOCK_MAPPING pMapFunc = NULL ;
|
|
DWORD cbMapping ;
|
|
TCHAR tchExpandedName [MAX_PATH+1] ;
|
|
INT cb ;
|
|
|
|
do // Pseudo-loop
|
|
{
|
|
pMapTriples = (PWINSOCK_MAPPING) (new CHAR [WSH_MAX_MAPPING_DATA]);
|
|
if ( ! pMapTriples )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Convert the SETUP-fprmatted Registry key handle
|
|
|
|
if ( (hKey = CvtRegHandle( pszHandle )) == NULL )
|
|
{
|
|
err = ERROR_INVALID_HANDLE ;
|
|
break ;
|
|
}
|
|
|
|
// Expand any environment strings in the DLL path string.
|
|
|
|
cb = ::ExpandEnvironmentStrings( pszDllName,
|
|
tchExpandedName,
|
|
sizeof tchExpandedName ) ;
|
|
|
|
if ( cb == 0 || cb > sizeof tchExpandedName )
|
|
{
|
|
err = ERROR_INVALID_NAME ;
|
|
break ;
|
|
}
|
|
|
|
// Bind to the DLL
|
|
|
|
if ( (hDll = ::LoadLibrary( tchExpandedName )) == NULL )
|
|
{
|
|
err = ::GetLastError() ;
|
|
break ;
|
|
}
|
|
|
|
// Get the address of the export
|
|
|
|
pMapFunc = (PWSH_GET_WINSOCK_MAPPING) ::GetProcAddress( hDll,
|
|
WSHWINSOCKMAPPING ) ;
|
|
if ( ! pMapFunc )
|
|
{
|
|
err = ERROR_INVALID_FUNCTION ;
|
|
break ;
|
|
}
|
|
|
|
// Call the export to return the mapping table
|
|
|
|
cbMapping = (*pMapFunc)( pMapTriples, WSH_MAX_MAPPING_DATA ) ;
|
|
if ( cbMapping > WSH_MAX_MAPPING_DATA )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Store the mapping info into the Registry
|
|
|
|
err = ::RegSetValueEx( hKey,
|
|
WSH_MappingValueName,
|
|
0,
|
|
REG_BINARY,
|
|
(LPBYTE) pMapTriples,
|
|
cbMapping ) ;
|
|
}
|
|
while ( FALSE );
|
|
|
|
if ( pMapTriples )
|
|
{
|
|
delete (CHAR *) pMapTriples ;
|
|
}
|
|
|
|
if ( hDll )
|
|
{
|
|
::FreeLibrary( hDll ) ;
|
|
}
|
|
return err ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunErrorMessage
|
|
|
|
SYNOPSIS: Convert an error message to text.
|
|
|
|
ENTRY: TCHAR * pszParms [] error message number in ASCII decimal
|
|
NLS_STR * pnlsResult string in which to store text.
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: This function is only called through the CPlSetup()
|
|
export function.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunErrorMessage ( const TCHAR * pszError, NLS_STR * pnlsResult )
|
|
{
|
|
NLS_STR nlsTemp ;
|
|
APIERR err = 0; // nlsTemp.Load( CvtDec( pszError ) ) ;
|
|
|
|
{
|
|
WCHAR pszTemp[MAX_TEMP+1];
|
|
|
|
LoadString( g_hinst, CvtDec( pszError ), pszTemp, MAX_TEMP );
|
|
nlsTemp = pszTemp;
|
|
}
|
|
|
|
if ( err == 0 )
|
|
{
|
|
err = appendToInfList( pnlsResult, nlsTemp, ISC_Before ) ;
|
|
}
|
|
return err ;
|
|
}
|
|
|
|
/*************************************************************************
|
|
|
|
NAME: DETECTION_CONTROL
|
|
|
|
SYNOPSIS: Interger-based wrapper for DETECTION_MANAGER
|
|
|
|
INTERFACE: Normal construction
|
|
|
|
PARENT: DETECTION_MANAGER
|
|
|
|
USES: SLIST_OF_CARD_REFERENCE
|
|
|
|
CAVEATS:
|
|
|
|
|
|
NOTES: This is a simple wrapper for DETECTION_MANAGER which
|
|
maintains an SLIST of the CARD_REFERENCEs returned
|
|
by the detection algorithm. This allows the caller
|
|
to deal with simple (and easily verifiable) integers
|
|
as indexes into the card list.
|
|
|
|
|
|
HISTORY: DavidHov 11/4/92 Created
|
|
|
|
|
|
**************************************************************************/
|
|
|
|
class DETECTION_CONTROL : public DETECTION_MANAGER
|
|
{
|
|
public:
|
|
DETECTION_CONTROL() ;
|
|
~ DETECTION_CONTROL () ;
|
|
|
|
// Return (externally opaque) detected card reference.
|
|
APIERR DetectCard ( INT * piCard,
|
|
BOOL fFirst = TRUE,
|
|
BOOL fSingleStep = FALSE ) ;
|
|
|
|
// Release a CARD_REFERENCE index created by DetectCard
|
|
|
|
VOID ReleaseCard ( INT iCard ) ;
|
|
|
|
// Return the object pointer corresponding to the list index
|
|
|
|
CARD_REFERENCE * NthCard ( INT iIndex ) ;
|
|
|
|
VOID ReleaseAllCards () ;
|
|
|
|
INT OpenCard ( const TCHAR * pszOptionName,
|
|
INT iBus,
|
|
INTERFACE_TYPE ifType ) ;
|
|
|
|
private:
|
|
SLIST_OF_CARD_REFERENCE _slCardRef ;
|
|
};
|
|
|
|
|
|
// Try to start the netcard detection service; ignore any errors.
|
|
|
|
DETECTION_CONTROL :: DETECTION_CONTROL ()
|
|
{
|
|
const TCHAR * apszParams [2] = { SZ("NETDETECT"), NULL } ;
|
|
|
|
RunStartService( (const TCHAR **)apszParams, 1, TRUE ) ;
|
|
}
|
|
|
|
DETECTION_CONTROL :: ~ DETECTION_CONTROL ()
|
|
{
|
|
}
|
|
|
|
CARD_REFERENCE * DETECTION_CONTROL :: NthCard ( INT iIndex )
|
|
{
|
|
ITER_SL_OF(CARD_REFERENCE) islCard( _slCardRef ) ;
|
|
|
|
CARD_REFERENCE * pResult = NULL ;
|
|
|
|
for ( INT i = 0 ;
|
|
(pResult = islCard.Next()) && i < iIndex ;
|
|
i++ ) ;
|
|
|
|
return pResult ;
|
|
}
|
|
|
|
// This is the global instance pointer for DETECTION_CONTROL
|
|
|
|
DETECTION_CONTROL * pDtCtl = NULL ;
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: DETECTION_CONTROL::DetectCard
|
|
|
|
SYNOPSIS: Perform DETECTION_MANAGER::DetectCard(), but
|
|
convert the resulting CARD_REFERENCE to an
|
|
index into the list.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR DETECTION_CONTROL :: DetectCard (
|
|
INT * piCard,
|
|
BOOL fFirst,
|
|
BOOL fSingleStep )
|
|
{
|
|
CARD_REFERENCE * pCardRef = NULL ;
|
|
APIERR err = DETECTION_MANAGER::DetectCard( & pCardRef,
|
|
fFirst,
|
|
fSingleStep ) ;
|
|
|
|
// If successful, append the card to the list.
|
|
|
|
if ( err == 0 )
|
|
{
|
|
if ( (err = _slCardRef.Append( pCardRef )) == 0 )
|
|
*piCard = _slCardRef.QueryNumElem() - 1 ;
|
|
}
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: DETECTION_CONTROL::ReleaseCard
|
|
|
|
SYNOPSIS: Perform DETECTION_CONTROL::ReleaseCard() using
|
|
a list index.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
VOID DETECTION_CONTROL :: ReleaseCard ( INT iCard )
|
|
{
|
|
ITER_SL_OF(CARD_REFERENCE) islCardRef( _slCardRef ) ;
|
|
CARD_REFERENCE * pCardRef ;
|
|
|
|
for ( ; islCardRef.Next() && iCard ; --iCard ) ;
|
|
|
|
if ( pCardRef = _slCardRef.Remove( islCardRef ) )
|
|
{
|
|
DETECTION_MANAGER::ReleaseCard( pCardRef ) ;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: DETECTION_CONTROL::ReleaseAllCards
|
|
|
|
SYNOPSIS: Release all detected card instances.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
VOID DETECTION_CONTROL :: ReleaseAllCards ()
|
|
{
|
|
while ( _slCardRef.QueryNumElem() )
|
|
{
|
|
ReleaseCard( 0 ) ;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: DETECTION_CONTROL::OpenCard
|
|
|
|
SYNOPSIS: Open a card handle given the option name
|
|
and bus parameters.
|
|
|
|
ENTRY: const TCHAR * name of option
|
|
INT iBus bus index
|
|
INTERFACE_TYPE ifType bus type
|
|
|
|
EXIT: -1 if failure; else, the card index
|
|
for this card.
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
INT DETECTION_CONTROL :: OpenCard (
|
|
const TCHAR * pszOptionName,
|
|
INT iBus,
|
|
INTERFACE_TYPE ifType )
|
|
{
|
|
INT iCard = -1 ;
|
|
|
|
CARD_REFERENCE * pCardRef =
|
|
DETECTION_MANAGER::OpenCard( pszOptionName, iBus, ifType ) ;
|
|
|
|
if ( pCardRef != NULL
|
|
&& _slCardRef.Append( pCardRef ) == 0 )
|
|
{
|
|
iCard = _slCardRef.QueryNumElem() - 1 ;
|
|
}
|
|
return iCard ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectEnd
|
|
|
|
SYNOPSIS: Destroy the single instance of a DETECTION_CONTROL
|
|
object.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectEnd ()
|
|
{
|
|
// call temporary free resource
|
|
if ( pDtCtl )
|
|
{
|
|
pDtCtl->FreeParameterSet( PCMCIABus, 0, NULL, TRUE );
|
|
// pDtCtl->FreeParameterSet( Isa, 0, NULL, TRUE );
|
|
}
|
|
delete pDtCtl ;
|
|
pDtCtl = NULL ;
|
|
return 0 ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectReset
|
|
|
|
SYNOPSIS: Reset iteration against the DETECTION_MANAGER object.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES: Discards all current CARD_REFERENCE instances
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectReset ()
|
|
{
|
|
APIERR err = 0 ;
|
|
|
|
if ( pDtCtl )
|
|
{
|
|
// call temporary free resource
|
|
pDtCtl->FreeParameterSet( PCMCIABus, 0, NULL, TRUE );
|
|
// pDtCtl->FreeParameterSet( Isa, 0, NULL, TRUE );
|
|
pDtCtl->ReleaseAllCards() ;
|
|
pDtCtl->ResetIteration() ;
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
}
|
|
return err ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectStart
|
|
|
|
SYNOPSIS: Allocate the DETECTION_CONTROL object.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectStart ()
|
|
{
|
|
if ( pDtCtl != NULL )
|
|
{
|
|
return NO_ERROR ;
|
|
}
|
|
|
|
pDtCtl = new DETECTION_CONTROL() ;
|
|
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
|
|
APIERR err = pDtCtl->QueryError() ;
|
|
|
|
// If an error occurred, delete the bogus object
|
|
|
|
if ( err )
|
|
{
|
|
RunDetectEnd() ;
|
|
}
|
|
return err ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectCard
|
|
|
|
SYNOPSIS: Attempt to detect a netcard.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR if failure
|
|
|
|
NOTES: After help from CPlSetup(), output appears as:
|
|
|
|
{ <error code>,
|
|
OPTIONNAME,
|
|
<card index>,
|
|
<numeric card type code>,
|
|
<detection confidence level>,
|
|
<bus interface type>,
|
|
<bus number>
|
|
}
|
|
|
|
The outer braces and error code are inserted by
|
|
the caller, CPlSetup().
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectCard ( NLS_STR * pnlsResult )
|
|
{
|
|
INT iCard ;
|
|
CARD_REFERENCE * pCardRef ;
|
|
APIERR err = 0 ;
|
|
WCHAR chBuffer[ 4000 ];
|
|
|
|
do
|
|
{
|
|
// Check to see if there's a DETECTION_CONTROL object
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Detect the next card
|
|
if ( err = pDtCtl->DetectCard( & iCard ) )
|
|
break ;
|
|
|
|
// Get the corresponding card reference.
|
|
pCardRef = pDtCtl->NthCard( iCard ) ;
|
|
|
|
ASSERT( pCardRef != NULL ) ;
|
|
|
|
// Output appears as:
|
|
// {"<error code>","CARDOPTIONNAME","<card handle>"}
|
|
|
|
if ( err = appendToInfList( pnlsResult,
|
|
pCardRef->QueryCardType()->QueryOptionName(),
|
|
ISC_Both ) )
|
|
break ;
|
|
|
|
// Append card index to result
|
|
if ( err = appendToInfList( pnlsResult, iCard, ISC_After ) )
|
|
break ;
|
|
|
|
// Append numeric card type to result
|
|
if ( err = appendToInfList( pnlsResult,
|
|
pCardRef->QueryCardType()->QueryType(),
|
|
ISC_After ) )
|
|
break ;
|
|
|
|
// Append overall detection confidence level to list
|
|
if ( err = appendToInfList( pnlsResult,
|
|
pCardRef->QueryConfidence(),
|
|
ISC_After ) )
|
|
break ;
|
|
|
|
// Append interface type to result
|
|
if ( err = appendToInfList( pnlsResult,
|
|
(INT) pCardRef->QueryIfType(),
|
|
ISC_After ) )
|
|
break ;
|
|
|
|
// Append bus number to result
|
|
if ( err = appendToInfList( pnlsResult,
|
|
pCardRef->QueryBus() ))
|
|
break ;
|
|
|
|
if ( pCardRef->QueryIfType() == PCMCIABus)
|
|
// ||
|
|
// pCardRef->QueryIfType() == Isa )
|
|
{
|
|
// call temporary claim the resource for PCMCIA
|
|
pCardRef->QueryCardType()->Dll()->QueryCfg( pCardRef->QueryHandle(), chBuffer, sizeof chBuffer );
|
|
|
|
pDtCtl->ClaimParameterSet( pCardRef->QueryIfType(), pCardRef->QueryBus(), chBuffer, TRUE, TRUE );
|
|
}
|
|
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
APIERR RunDetectCardEx( CARD_REFERENCE*& pCardRef, INT& iCard, BOOL fFirst )
|
|
{
|
|
APIERR err = 0 ;
|
|
WCHAR chBuffer[ 4000 ];
|
|
|
|
do
|
|
{
|
|
// Check to see if there's a DETECTION_CONTROL object
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Detect the next card
|
|
if ( err = pDtCtl->DetectCard( & iCard, fFirst ) )
|
|
break ;
|
|
|
|
// Get the corresponding card reference.
|
|
pCardRef = pDtCtl->NthCard( iCard ) ;
|
|
|
|
ASSERT( pCardRef != NULL ) ;
|
|
|
|
if ( pCardRef->QueryIfType() == PCMCIABus )
|
|
// ||
|
|
// pCardRef->QueryIfType() == Isa )
|
|
{
|
|
// call temporary claim the resource for PCMCIA
|
|
pCardRef->QueryCardType()->Dll()->QueryCfg( pCardRef->QueryHandle(), chBuffer, sizeof chBuffer );
|
|
|
|
pDtCtl->ClaimParameterSet( pCardRef->QueryIfType(), pCardRef->QueryBus(), chBuffer, TRUE, TRUE );
|
|
}
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectGetParams
|
|
|
|
SYNOPSIS: Given the name of a netcard option, return the
|
|
SETUP INF list describing its parameters, their
|
|
constraints and possible legal values.
|
|
|
|
ENTRY: const TCHAR * name of netcard option;
|
|
e.g., "DEC201".
|
|
|
|
EXIT: APIERR if failure
|
|
|
|
RETURNS: pnlsResult contains list of lists
|
|
of paramters, etc.
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectGetParams (
|
|
const TCHAR * pszOptionName,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
TCHAR * pszParams = NULL ;
|
|
CARDTYPE_REFERENCE * pCardType = NULL ;
|
|
APIERR err = 0 ;
|
|
CFG_RULE_SET crsParams ;
|
|
TEXT_BUFFER txBuff ;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your breakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
pCardType = pDtCtl->FindOptionName( pszOptionName ) ;
|
|
if ( pCardType == NULL )
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND ;
|
|
break ;
|
|
}
|
|
|
|
pszParams = pCardType->QueryConfigurationOptions() ;
|
|
if ( pszParams == NULL )
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND ;
|
|
break ;
|
|
}
|
|
|
|
if ( err = crsParams.Parse( pszParams, PARSE_CTL_FULL_SYNTAX ) )
|
|
break ;
|
|
|
|
// Convert the parameter list to an INF-style list at a
|
|
// nesting level of 1.
|
|
|
|
if ( err = crsParams.TextifyInf( & txBuff, 1 ) )
|
|
break ;
|
|
|
|
if ( err = appendToInfList( pnlsResult, txBuff, ISC_Before ) )
|
|
break ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
delete pszParams ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectQueryCard
|
|
|
|
SYNOPSIS: Given the index of a previously detected card,
|
|
return its detectable configuration parameters.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectQueryCard (
|
|
const TCHAR * pszCardIndex,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
INT iCard = (INT) CvtDec( pszCardIndex ) ;
|
|
CARD_REFERENCE * pCard = NULL ;
|
|
APIERR err = 0 ;
|
|
TCHAR * pszConfig = NULL ;
|
|
CFG_RULE_SET crsParams ;
|
|
TEXT_BUFFER txBuff ;
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
pCard = pDtCtl->NthCard( iCard ) ;
|
|
if ( pCard == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
pszConfig = pCard->QueryConfiguration() ;
|
|
if ( pszConfig == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
// Parse the resulting SProlog-style list.
|
|
if ( err = crsParams.Parse( pszConfig, PARSE_CTL_FULL_SYNTAX ) )
|
|
break ;
|
|
|
|
// Convert the parameter list to an INF-style list at a
|
|
// nesting level of 1.
|
|
if ( err = crsParams.TextifyInf( & txBuff, 1 ) )
|
|
break ;
|
|
|
|
if ( err = appendToInfList( pnlsResult, txBuff, ISC_Before ) )
|
|
break ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
delete pszConfig ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectVerifyCard
|
|
|
|
SYNOPSIS: Given the index of a previously detected card,
|
|
return the SETUP INF list describing its
|
|
detected parameters.
|
|
|
|
ENTRY: const TCHAR * pszCardIndex ASCII decimal numeric card index
|
|
const TCHAR * pszConfigData INF nested lists of confiuration
|
|
parameters.
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES: If the card index is 1000, this is a special value
|
|
indicating that NULL should be passed to
|
|
DETECTION_MANAGER::VerifyConfiguration(). This allows
|
|
resource claiming to occur for non-detected cards.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectVerifyCard (
|
|
const TCHAR * pszCardIndex,
|
|
const TCHAR * pszConfigData )
|
|
{
|
|
const INT iCardNotDetected = 1000 ;
|
|
|
|
INT iCard = (INT) CvtDec( pszCardIndex ) ;
|
|
CARD_REFERENCE * pCard = NULL ;
|
|
APIERR err = 0 ;
|
|
CFG_RULE_SET crsParams ;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Place your breakpoints now...", L"Helpful Hint", MB_ICONINFORMATION | MB_OK );
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
if ( iCard != iCardNotDetected
|
|
&& (pCard = pDtCtl->NthCard( iCard )) == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
if ( err = crsParams.ParseInfList( pszConfigData ) )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: DTVERIFY: cfg param INF list parse failed") ) ;
|
|
break ;
|
|
}
|
|
|
|
err = pDtCtl->VerifyConfiguration( pCard, & crsParams, TRUE ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectOpen
|
|
|
|
SYNOPSIS: Open a card handle given the necessary data.
|
|
|
|
ENTRY: const TCHAR * * Data arguments
|
|
|
|
arg[0] netcard option name
|
|
arg[1] bus type
|
|
arg[2] bus number
|
|
|
|
EXIT: NLS_STR * pnlsResult contains numeric card index
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectOpen (
|
|
const TCHAR * pszNetcardOption,
|
|
const TCHAR * pszBusType,
|
|
const TCHAR * pszBusNumber,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
INT iCard = 0 ;
|
|
INT iBusType = CvtDec( pszBusType ) ;
|
|
INT iBusNum = CvtDec( pszBusNumber ) ;
|
|
CARD_REFERENCE * pCard = NULL ;
|
|
APIERR err = 0 ;
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
iCard = pDtCtl->OpenCard( pszNetcardOption,
|
|
iBusType,
|
|
(INTERFACE_TYPE) iBusNum ) ;
|
|
if ( iCard < 0 )
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND ;
|
|
break ;
|
|
}
|
|
|
|
// Append numeric card type to result
|
|
err = appendToInfList( pnlsResult, iCard ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectClaim
|
|
|
|
SYNOPSIS: Claim the list of resources given.
|
|
|
|
ENTRY: const TCHAR * pszConfigData INF nested lists of confiuration
|
|
parameters.
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectClaim ( const TCHAR * pszConfigData )
|
|
{
|
|
APIERR err = 0 ;
|
|
CFG_RULE_SET crsParams ;
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
if ( err = crsParams.ParseInfList( pszConfigData ) )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: DTVERIFY: cfg param INF list parse failed") ) ;
|
|
break ;
|
|
}
|
|
|
|
err = pDtCtl->VerifyConfiguration( NULL, & crsParams, TRUE ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectGetString
|
|
|
|
SYNOPSIS: Given the name of a netcard option and a
|
|
numeric string index, return the corresponding
|
|
string data.
|
|
|
|
ENTRY: const TCHAR * name of netcard option;
|
|
e.g., "DE201".
|
|
const TCHAR * string index in character form
|
|
|
|
EXIT: APIERR if failure
|
|
|
|
RETURNS: pnlsResult contains list of lists
|
|
of paramters, etc.
|
|
|
|
NOTES: This function returns information strings
|
|
relative to a particular netcard type and
|
|
the DLL which supports it.
|
|
|
|
Such strings include the displayable name of the
|
|
card, its manufacturer, etc.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectGetString (
|
|
const TCHAR * pszOptionName,
|
|
const TCHAR * pszStringIndex,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
INT iString = (INT) CvtDec( pszStringIndex ) ;
|
|
APIERR err = 0 ;
|
|
CARDTYPE_REFERENCE * pCardType ;
|
|
TCHAR chBuffer [ 200 ] ;
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
pCardType = pDtCtl->FindOptionName( pszOptionName ) ;
|
|
if ( pCardType == NULL )
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND ;
|
|
break ;
|
|
}
|
|
|
|
err = pCardType->Dll()->Identify( pCardType->QueryType() + iString,
|
|
chBuffer,
|
|
sizeof chBuffer ) ;
|
|
if ( err )
|
|
break ;
|
|
|
|
err = appendToInfList( pnlsResult, chBuffer, ISC_Before ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunDetectGetParamName
|
|
|
|
SYNOPSIS: Given the name of a netcard option and a
|
|
numeric string index, return the corresponding
|
|
string data.
|
|
|
|
ENTRY: const TCHAR * name of netcard option;
|
|
e.g., "DE201".
|
|
const TCHAR * name of parameter to retrieve
|
|
|
|
EXIT: APIERR if failure
|
|
|
|
RETURNS: pnlsResult contains list of lists
|
|
of paramters, etc.
|
|
|
|
NOTES: This function returns the displayable name
|
|
of the parameter whose symbolic name is given
|
|
in the pszParamName parameter.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunDetectGetParamName (
|
|
const TCHAR * pszOptionName,
|
|
const TCHAR * pszParamName,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
APIERR err = 0 ;
|
|
CARDTYPE_REFERENCE * pCardType ;
|
|
TCHAR chBuffer [ 200 ] ;
|
|
|
|
do
|
|
{
|
|
if ( pDtCtl == NULL )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
break ;
|
|
}
|
|
|
|
pCardType = pDtCtl->FindOptionName( pszOptionName ) ;
|
|
if ( pCardType == NULL )
|
|
{
|
|
err = ERROR_FILE_NOT_FOUND ;
|
|
break ;
|
|
}
|
|
|
|
err = pCardType->Dll()->QueryParamName(
|
|
pszParamName,
|
|
chBuffer,
|
|
sizeof chBuffer ) ;
|
|
if ( err )
|
|
break ;
|
|
|
|
err = appendToInfList( pnlsResult, chBuffer, ISC_Before ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: getAdapterList
|
|
|
|
SYNOPSIS: Given the name of a service, return a STRLIST
|
|
consisting of the names of the adapters to which
|
|
the service is currently bound.
|
|
|
|
ENTRY: REG_KEY * prkMachine REG_KEY for
|
|
HKEY_LOCAL_MACHINE
|
|
const TCHAR * name of service
|
|
STRLIST * * location to store ptr
|
|
to created STRLIST
|
|
|
|
EXIT: STRLIST * * updated
|
|
|
|
RETURNS: APIERR if failure
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
static APIERR getAdapterList (
|
|
REG_KEY * prkMachine,
|
|
const TCHAR * pszServiceName,
|
|
STRLIST * * ppslResult )
|
|
{
|
|
APIERR err ;
|
|
TCHAR tchKeyName [ MAX_PATH ] ;
|
|
NLS_STR nlsKeyName ;
|
|
|
|
*ppslResult = NULL ;
|
|
|
|
wsprintf( tchKeyName,
|
|
SZ("%s%c%s%c%s"),
|
|
RGAS_SERVICES_HOME,
|
|
TCH('\\'),
|
|
pszServiceName,
|
|
TCH('\\'),
|
|
RGAS_LINKAGE_NAME ) ;
|
|
|
|
if ( err = nlsKeyName.CopyFrom( tchKeyName ) )
|
|
return err ;
|
|
|
|
REG_KEY rkLinkage( *prkMachine, nlsKeyName ) ;
|
|
|
|
if ( err = rkLinkage.QueryError() )
|
|
return err ;
|
|
|
|
err = rkLinkage.QueryValue( RGAS_ROUTE_VALUE_NAME, ppslResult ) ;
|
|
|
|
if ( err == 0 )
|
|
{
|
|
ITER_STRLIST isl( **ppslResult ) ;
|
|
NLS_STR * pnlsNext ;
|
|
|
|
// Iterate over the strings. Locate the last double-quoted
|
|
// substring; remove all but the enclosed substring from each
|
|
// string.
|
|
|
|
for ( ; (err == 0) && (pnlsNext = isl.Next()) ; )
|
|
{
|
|
INT cQuote = 0,
|
|
i = 0 ;
|
|
const TCHAR * pch = pnlsNext->QueryPch(),
|
|
* pch2 = NULL ;
|
|
TCHAR tchAdapterName [MAX_PATH] ;
|
|
|
|
// Iterate over the string, remembering the start of the
|
|
// last sub-string enclosed in double quotes.
|
|
|
|
for ( ; *pch ; pch++ )
|
|
{
|
|
if ( *pch == TCH('\"') )
|
|
{
|
|
if ( ++cQuote & 1 )
|
|
pch2 = pch ;
|
|
}
|
|
}
|
|
|
|
// Extact just the adapter name from the string; if not
|
|
// found, leave the string empty.
|
|
|
|
if ( pch2 )
|
|
{
|
|
for ( pch2++ ; *pch2 && *pch2 != TCH('\"') ; )
|
|
{
|
|
tchAdapterName[i++] = *pch2++ ;
|
|
if ( i >= sizeof tchAdapterName - 1 )
|
|
break ;
|
|
}
|
|
}
|
|
tchAdapterName[i] = 0 ;
|
|
|
|
TRACEEOL("NCPA/SETP: adapter name ["
|
|
<< tchAdapterName
|
|
<< SZ("] extracted from ")
|
|
<< pnlsNext->QueryPch() );
|
|
|
|
err = pnlsNext->CopyFrom( tchAdapterName ) ;
|
|
}
|
|
}
|
|
|
|
if ( err )
|
|
{
|
|
delete *ppslResult ;
|
|
*ppslResult = NULL ;
|
|
}
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunMCSAlteredCheck
|
|
|
|
SYNOPSIS: See if MCS products need to recall during binding phase.
|
|
|
|
ENTRY: const TCHAR * name of service
|
|
|
|
EXIT: Nothing.
|
|
|
|
RETURNS: APIERR: 0 (NO_ERROR) implies no reconfiguration
|
|
required; any other value causes IP Address
|
|
configuration dialog to appear.
|
|
|
|
NOTES: THIS FUNCTION IS HIGHLY SPECIFIC TO THE REGISTRY FORMATS
|
|
USED BY MCS for XNS and IPX.
|
|
|
|
The criteria are as follows (XXX is the product name):
|
|
1) system\currentcontrolset\services\XXX\Netconfig\Driver01
|
|
must exist.
|
|
2) The adaptername string must exist.
|
|
3) system\currentcontrolset\services\$(adaptername)
|
|
must exist.
|
|
4) make sure that the card is bound to the service.
|
|
5) make sure that the service is bound to only one adapter.
|
|
|
|
|
|
HISTORY: terryk 4-7-93 Created
|
|
|
|
********************************************************************/
|
|
APIERR RunMCSAlteredCheck( const TCHAR * pszArg1 )
|
|
{
|
|
APIERR err = NERR_Success;
|
|
|
|
REG_KEY rkMachine( HKEY_LOCAL_MACHINE ) ;
|
|
|
|
do
|
|
{
|
|
if ( err = rkMachine.QueryError() )
|
|
break;
|
|
|
|
NLS_STR nlsMCSLocation = RGAS_SERVICES_HOME;
|
|
nlsMCSLocation.strcat( SZ("\\"));
|
|
nlsMCSLocation.strcat( pszArg1 );
|
|
nlsMCSLocation.strcat( SZ("\\NetConfig\\Driver01") );
|
|
REG_KEY regMCS( rkMachine, nlsMCSLocation );
|
|
if ( err = regMCS.QueryError() )
|
|
break;
|
|
|
|
NLS_STR nlsAdapter;
|
|
|
|
// get adapter name from Driver01
|
|
|
|
if ( err = regMCS.QueryValue( SZ("AdapterName"), &nlsAdapter ))
|
|
break;
|
|
|
|
if ( nlsAdapter.QueryNumChar() == 0 )
|
|
{
|
|
// no adapter name currently assigned...
|
|
err = 3;
|
|
break;
|
|
}
|
|
|
|
NLS_STR nlsCard = RGAS_SERVICES_HOME;
|
|
nlsCard.strcat( SZ("\\") );
|
|
nlsCard.strcat( nlsAdapter );
|
|
|
|
// make sure the card exists in the registry
|
|
|
|
REG_KEY regAdapter( rkMachine, nlsCard );
|
|
|
|
if ( err = regAdapter.QueryError())
|
|
break;
|
|
|
|
STRLIST * pslAdapters = NULL;
|
|
NLS_STR * pnlsNext = NULL;
|
|
|
|
// Get a STRLIST of adapter names.
|
|
if ( err = getAdapterList( & rkMachine, pszArg1, & pslAdapters ) )
|
|
break ;
|
|
|
|
ITER_STRLIST isl( *pslAdapters ) ;
|
|
|
|
// Attempt to match the primary adapter to (one of)
|
|
// the current binding(s).
|
|
|
|
for ( ; pnlsNext = isl.Next() ; )
|
|
{
|
|
if ( pnlsNext->_stricmp( nlsAdapter ) == 0 )
|
|
break;
|
|
}
|
|
|
|
// If > 1 active binding or no match on current adapter,
|
|
// reconfiguration is necessary.
|
|
|
|
if ( pslAdapters->QueryNumElem() > 1 || pnlsNext == NULL )
|
|
err = 3 ;
|
|
|
|
delete pslAdapters;
|
|
}
|
|
while ( FALSE );
|
|
|
|
return err;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: ActivateBindings
|
|
|
|
SYNOPSIS: Given a list of bindings to preserve,
|
|
activate them and disable all other bindings.
|
|
|
|
ENTRY: REG_KEY * prkNbtLinkage pointer to NBT linkage
|
|
registry key
|
|
-- or --
|
|
const TCHAR * pszServiceName name of service to
|
|
fiddle with
|
|
|
|
const TCHAR * apszBinds NULL-terminated list
|
|
of binding names
|
|
|
|
EXIT: Nothing
|
|
|
|
RETURNS: APIERR if failure or zero if successful
|
|
|
|
NOTES: Enabled (active) bindings are listed under the "Linkage"
|
|
key; disabled (inactive) bindings are listed under
|
|
the "Linkage\Disabled" key.
|
|
|
|
Due to the fact that iterating a STRLIST while removing
|
|
items is not reliable, this code does more string
|
|
duplication than would seem necessary at first glance.
|
|
|
|
The algorithm is:
|
|
|
|
Query the active and inactive binding data from
|
|
the Registry.
|
|
|
|
Merge active and inactive bindings into a new set
|
|
of STRLISTs; clear the disabled STRLISTs.
|
|
|
|
Iterate over the merged lists, duplicating each
|
|
set of strings. If the Bind value matches the
|
|
function argument, make it active; all others
|
|
become inactive.
|
|
|
|
Set all Registry values.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR ActivateBindings (
|
|
REG_KEY * prkNbtLinkage,
|
|
const TCHAR * * apszBinds )
|
|
{
|
|
APIERR err = 0 ;
|
|
NLS_STR nlsDisabled( RGAS_DISABLED_KEY_NAME ) ;
|
|
STRLIST * pslActBind = NULL,
|
|
* pslActExport = NULL,
|
|
* pslActRoute = NULL,
|
|
* pslDisBind = NULL,
|
|
* pslDisExport = NULL,
|
|
* pslDisRoute = NULL,
|
|
* pslMergeBind = NULL,
|
|
* pslMergeExport = NULL,
|
|
* pslMergeRoute = NULL ;
|
|
|
|
if ( err = nlsDisabled.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
REG_KEY rkDisabled ( *prkNbtLinkage, nlsDisabled, MAXIMUM_ALLOWED ) ;
|
|
|
|
if ( err = rkDisabled.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
do // Pseudo-loop
|
|
{
|
|
// Suck in all the values.
|
|
// Allocate an empty list for anything not found.
|
|
|
|
if ( prkNbtLinkage->QueryValue( RGAS_BIND_VALUE_NAME, & pslMergeBind ) )
|
|
pslMergeBind = new STRLIST ;
|
|
|
|
if ( prkNbtLinkage->QueryValue( RGAS_EXPORT_VALUE_NAME, & pslMergeExport ) )
|
|
pslMergeExport = new STRLIST ;
|
|
|
|
if ( prkNbtLinkage->QueryValue( RGAS_ROUTE_VALUE_NAME, & pslMergeRoute ) )
|
|
pslMergeRoute = new STRLIST ;
|
|
|
|
if ( rkDisabled.QueryValue( RGAS_BIND_VALUE_NAME, & pslDisBind ) )
|
|
pslDisBind = new STRLIST ;
|
|
|
|
if ( rkDisabled.QueryValue( RGAS_EXPORT_VALUE_NAME, & pslDisExport ) )
|
|
pslDisExport = new STRLIST ;
|
|
|
|
if ( rkDisabled.QueryValue( RGAS_ROUTE_VALUE_NAME, & pslDisRoute ) )
|
|
pslDisRoute = new STRLIST ;
|
|
|
|
// Allocate new "active" STRLISTs
|
|
|
|
pslActBind = new STRLIST ;
|
|
pslActExport = new STRLIST ;
|
|
pslActRoute = new STRLIST ;
|
|
|
|
if ( pslActBind == NULL
|
|
|| pslActExport == NULL
|
|
|| pslActRoute == NULL
|
|
|| pslDisBind == NULL
|
|
|| pslDisExport == NULL
|
|
|| pslDisRoute == NULL
|
|
|| pslMergeBind == NULL
|
|
|| pslMergeExport == NULL
|
|
|| pslMergeRoute == NULL
|
|
)
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Merge the active and inactive lists; clear the inactive lists.
|
|
|
|
if ( err = mergeStrLists( pslMergeBind, pslDisBind ) )
|
|
break ;
|
|
if ( err = mergeStrLists( pslMergeExport, pslDisExport ) )
|
|
break ;
|
|
if ( err = mergeStrLists( pslMergeRoute, pslDisRoute ) )
|
|
break ;
|
|
|
|
pslDisBind->Clear() ;
|
|
pslDisExport->Clear() ;
|
|
pslDisRoute->Clear() ;
|
|
|
|
// Loop through the merged lists. When we find the target, make it
|
|
// active; make all others inactive.
|
|
|
|
NLS_STR * pnlsBind,
|
|
* pnlsExport,
|
|
* pnlsRoute,
|
|
* pnlsDupBind = NULL,
|
|
* pnlsDupExport = NULL,
|
|
* pnlsDupRoute = NULL ;
|
|
|
|
ITER_STRLIST islBind( *pslMergeBind ) ;
|
|
ITER_STRLIST islExport( *pslMergeExport ) ;
|
|
ITER_STRLIST islRoute( *pslMergeRoute ) ;
|
|
|
|
for ( ; pnlsBind = islBind.Next() ; )
|
|
{
|
|
pnlsExport = islExport.Next() ;
|
|
pnlsRoute = islRoute.Next() ;
|
|
|
|
if ( pnlsExport == NULL || pnlsRoute == NULL )
|
|
{
|
|
// BOGUS: the lists are internally out of sync!
|
|
err = ERROR_GEN_FAILURE ;
|
|
}
|
|
|
|
// Duplicate this set of strings. This method of
|
|
// operation is due to problems in removing SLIST
|
|
// items while iterating.
|
|
|
|
pnlsDupBind = new NLS_STR( *pnlsBind ) ;
|
|
pnlsDupExport = new NLS_STR( *pnlsExport ) ;
|
|
pnlsDupRoute = new NLS_STR( *pnlsRoute ) ;
|
|
|
|
if ( pnlsDupBind == NULL
|
|
|| pnlsDupExport == NULL
|
|
|| pnlsDupRoute == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
delete pnlsDupBind ;
|
|
delete pnlsDupExport ;
|
|
delete pnlsDupRoute ;
|
|
break ;
|
|
}
|
|
|
|
// If this is an active binding, make it so;
|
|
// otherwise, add it to the inactive set
|
|
|
|
for ( INT iBind = 0 ; apszBinds[iBind] ; iBind++ )
|
|
{
|
|
if ( ::stricmpf( pnlsBind->QueryPch(), apszBinds[iBind] ) == 0 )
|
|
break ;
|
|
}
|
|
|
|
if ( apszBinds[iBind] )
|
|
{
|
|
pslActBind->Append( pnlsDupBind ) ;
|
|
pslActExport->Append( pnlsDupExport ) ;
|
|
pslActRoute->Append( pnlsDupRoute ) ;
|
|
|
|
TRACEEOL( SZ("NCPA/TCPIP: ActivateBindings; binding found: ")
|
|
<< apszBinds[iBind] ) ;
|
|
}
|
|
else
|
|
{
|
|
pslDisBind->Append( pnlsDupBind ) ;
|
|
pslDisExport->Append( pnlsDupExport ) ;
|
|
pslDisRoute->Append( pnlsDupRoute ) ;
|
|
}
|
|
}
|
|
|
|
// Write out the modified REG_MULTI_SZs
|
|
|
|
prkNbtLinkage->SetValue( RGAS_BIND_VALUE_NAME, pslActBind ) ;
|
|
|
|
prkNbtLinkage->SetValue( RGAS_EXPORT_VALUE_NAME, pslActExport ) ;
|
|
|
|
prkNbtLinkage->SetValue( RGAS_ROUTE_VALUE_NAME, pslActRoute ) ;
|
|
|
|
rkDisabled.SetValue( RGAS_BIND_VALUE_NAME, pslDisBind ) ;
|
|
|
|
rkDisabled.SetValue( RGAS_EXPORT_VALUE_NAME, pslDisExport ) ;
|
|
|
|
rkDisabled.SetValue( RGAS_ROUTE_VALUE_NAME, pslDisRoute ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
|
|
delete pslActBind ;
|
|
delete pslActRoute ;
|
|
delete pslActExport ;
|
|
delete pslDisBind ;
|
|
delete pslDisExport ;
|
|
delete pslDisRoute ;
|
|
delete pslMergeBind ;
|
|
delete pslMergeRoute ;
|
|
delete pslMergeExport ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
// Variant which opens the Linkage key given the
|
|
// name of the service.
|
|
|
|
APIERR ActivateBindings (
|
|
const TCHAR * pszServiceName,
|
|
const TCHAR * * apszBinds )
|
|
{
|
|
APIERR err ;
|
|
TCHAR achLinkage [MAX_PATH] ;
|
|
|
|
::wsprintf( achLinkage, SZ("%s\\%s\\%s"),
|
|
RGAS_SERVICES_HOME,
|
|
pszServiceName,
|
|
RGAS_LINKAGE_NAME ) ;
|
|
|
|
ALIAS_STR nlsLinkageKeyName( achLinkage ) ;
|
|
|
|
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
|
|
|
|
if ( err = rkLocalMachine.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
REG_KEY rkLinkage( rkLocalMachine,
|
|
nlsLinkageKeyName ) ;
|
|
|
|
if ( err = rkLinkage.QueryError() )
|
|
{
|
|
return err ;
|
|
}
|
|
|
|
return ActivateBindings( & rkLinkage, apszBinds ) ;
|
|
}
|
|
|
|
// Activate a single binding.
|
|
|
|
APIERR ActivateBinding (
|
|
REG_KEY * prkLinkage,
|
|
const TCHAR * pszBind )
|
|
{
|
|
const TCHAR * apszBinds [2] ;
|
|
|
|
apszBinds[0] = pszBind ;
|
|
apszBinds[1] = NULL ;
|
|
return ActivateBindings( prkLinkage, apszBinds ) ;
|
|
}
|
|
|
|
|
|
// Exported versions: UNICODE and ANSI.
|
|
|
|
LONG FAR PASCAL NetSetupActivateBindingsW (
|
|
const TCHAR * pszServiceName,
|
|
const TCHAR * * apszBinds )
|
|
{
|
|
return ActivateBindings( pszServiceName, apszBinds ) ;
|
|
}
|
|
|
|
LONG FAR PASCAL NetSetupActivateBindingsA (
|
|
const CHAR * pszServiceName,
|
|
const CHAR * * apszBinds )
|
|
{
|
|
NLS_STR nlsServiceName ;
|
|
const TCHAR * * apwchBinds = NULL ;
|
|
INT cBind ;
|
|
APIERR err ;
|
|
|
|
do
|
|
{
|
|
if ( err = nlsServiceName.QueryError() )
|
|
break ;
|
|
if ( err = nlsServiceName.MapCopyFrom( pszServiceName ) )
|
|
break ;
|
|
|
|
// Count the number of bindings given; use the
|
|
// ANSI string vector to create a UNICODE vector.
|
|
|
|
for ( cBind = 0 ; apszBinds[cBind++] ; ) ;
|
|
|
|
if ( (apwchBinds = (const TCHAR **) CvtArgs( (const LPSTR *) apszBinds, cBind )) == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Call the worker function
|
|
|
|
err = ActivateBindings( nlsServiceName.QueryPch(), apwchBinds ) ;
|
|
|
|
FreeArgs( (TCHAR **) apwchBinds, cBind ) ;
|
|
}
|
|
while ( FALSE ) ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RunActivateBindings
|
|
|
|
SYNOPSIS: Given a service name and a list of bindings,
|
|
activate the bindings listed.
|
|
|
|
ENTRY: const TCHAR * pszServiceName name of service
|
|
const TCHAR * pszInfList INF list of bindings
|
|
|
|
EXIT:
|
|
|
|
RETURNS: APIERR
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
APIERR RunActivateBindings (
|
|
const TCHAR * pszServiceName,
|
|
const TCHAR * pszInfList )
|
|
{
|
|
APIERR err = 0 ;
|
|
CFG_RULE_SET crsParams ;
|
|
CFG_RULE_NODE * pcrnTop,
|
|
* pcrnTemp ;
|
|
|
|
INT cBinds = 0 ;
|
|
const TCHAR * * apszBinds = NULL ;
|
|
|
|
do
|
|
{
|
|
if ( err = crsParams.ParseInfList( pszInfList ) )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: ACTIVBIND: INF list parse failed") ) ;
|
|
break ;
|
|
}
|
|
|
|
// Walk the parse tree, extracting the information
|
|
// necessary. Parse tree looks like this:
|
|
//
|
|
// ( ) enclosing list (CFG_RULE_SET)
|
|
// |
|
|
// ( ) enclosing list from braces {}
|
|
// |
|
|
// "string" "string" "string"...
|
|
|
|
if ( (pcrnTop = crsParams.QueryList()) == NULL
|
|
|| pcrnTop->QueryType() != CRN_NIL
|
|
|| (pcrnTop = pcrnTop->QueryNext()) == NULL
|
|
|| pcrnTop->QueryType() != CRN_LIST
|
|
|| (pcrnTop = pcrnTop->QueryList()) == NULL )
|
|
{
|
|
err = ERROR_GEN_FAILURE ;
|
|
break ;
|
|
}
|
|
|
|
// First, walk the parsed list to determine the number
|
|
// of elements.
|
|
|
|
for ( pcrnTemp = pcrnTop ; pcrnTemp = pcrnTemp->QueryNext() ; )
|
|
{
|
|
// Ignore anything that's not a string
|
|
|
|
cBinds += pcrnTemp->QueryType() == CRN_STR ;
|
|
}
|
|
|
|
// Allocate the array of pointers to active binding strings
|
|
|
|
apszBinds = new const TCHAR * [cBinds + 1] ;
|
|
if ( apszBinds == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Then, walk the list to extract pointers to the strings,
|
|
// building the TCHAR * array.
|
|
|
|
for ( cBinds = 0, pcrnTemp = pcrnTop ;
|
|
pcrnTemp = pcrnTemp->QueryNext() ; )
|
|
{
|
|
if ( pcrnTemp->QueryType() == CRN_STR )
|
|
{
|
|
apszBinds[cBinds++] = pcrnTemp->QueryAtom().QueryText() ;
|
|
}
|
|
}
|
|
apszBinds[cBinds] = NULL ;
|
|
|
|
// Finally, call the activation routine.
|
|
|
|
err = ActivateBindings( pszServiceName, apszBinds ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
delete (TCHAR **) apszBinds ;
|
|
|
|
return err ;
|
|
}
|
|
//-------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
// History:
|
|
// April 21, 1995 MikeMi -
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR RunNcpa( HWND hwndParent )
|
|
{
|
|
NCP ncp;
|
|
APIERR err = 0;
|
|
|
|
if ( ncp.Initialize( hwndParent ) )
|
|
{
|
|
ncp.SetUseInprocInterp( FALSE );
|
|
ncp.SetFrameHwnd( hwndParent );
|
|
do
|
|
{
|
|
err = ncp.QueryError();
|
|
if (err) break;
|
|
|
|
ncp.SetBindState( BND_OUT_OF_DATE_NO_REBOOT );
|
|
err = ncp.QueryError();
|
|
if (err) break;
|
|
|
|
ncp.SaveBindingChanges();
|
|
err = ncp.QueryError();
|
|
} while (FALSE);
|
|
ncp.DeInitialize();
|
|
}
|
|
else
|
|
{
|
|
err = ncp.QueryError();
|
|
}
|
|
return( err );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR NetSetupReviewBindings( HWND hwndParent, DWORD dwBindFlags )
|
|
{
|
|
NCP ncp;
|
|
APIERR err = 0;
|
|
|
|
do
|
|
{
|
|
if ( !::IsWindow( hwndParent ) )
|
|
{
|
|
err = ERROR_INVALID_WINDOW_HANDLE;
|
|
break;
|
|
}
|
|
|
|
// dwBindFlags is a reserved value for future expansion
|
|
// of this call. A thought is that it might be used to
|
|
// set the bind state before calling SaveBindingChanges
|
|
//
|
|
if (0 != dwBindFlags)
|
|
{
|
|
err = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
|
|
}
|
|
|
|
if (!ncp.Initialize( hwndParent ) )
|
|
{
|
|
err = ncp.QueryError();
|
|
break;
|
|
}
|
|
ncp.SetFrameHwnd( hwndParent );
|
|
err = ncp.QueryError();
|
|
if (err) break;
|
|
|
|
ncp.SetBindState( BND_OUT_OF_DATE_NO_REBOOT );
|
|
err = ncp.QueryError();
|
|
if (err) break;
|
|
|
|
ncp.SaveBindingChanges();
|
|
err = ncp.QueryError();
|
|
|
|
ncp.DeInitialize();
|
|
|
|
} while (FALSE);
|
|
|
|
return( err );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR NetSetupFindSoftwareComponent( PCWSTR pszInfOption,
|
|
PWSTR pszInfName, PDWORD pcchInfName,
|
|
PWSTR pszRegBase, PDWORD pcchRegBase )
|
|
{
|
|
BOOL fLoop = TRUE;
|
|
APIERR dwError = ERROR_SUCCESS;
|
|
do
|
|
{
|
|
if ( (NULL == pszInfOption) ||
|
|
(NULL == pszInfName) ||
|
|
(NULL == pcchInfName) ||
|
|
((NULL == pszRegBase) && (NULL != pcchRegBase)) ||
|
|
((NULL != pszRegBase) && (NULL == pcchRegBase)) )
|
|
{
|
|
dwError = ERROR_INVALID_PARAMETER ;
|
|
break;
|
|
}
|
|
|
|
HKEY hkeySoftware;
|
|
WCHAR pszTemp[MAX_PATH];
|
|
DWORD cchTemp;
|
|
DWORD cbTemp;
|
|
|
|
FILETIME ftLastWriteTime;
|
|
|
|
//
|
|
// search the registry for a component with the option name given
|
|
//
|
|
|
|
// start at software key
|
|
//
|
|
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
RGAS_SOFTWARE_HOME,
|
|
0,
|
|
KEY_READ,
|
|
&hkeySoftware );
|
|
if (dwError)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// enumerate all manufacturers
|
|
//
|
|
WCHAR pszManufacturer[MAX_PATH];
|
|
DWORD iManufacturers = 0;
|
|
HKEY hkeyManufacturer;
|
|
do
|
|
{
|
|
cchTemp = MAX_PATH;
|
|
dwError = RegEnumKeyEx( hkeySoftware,
|
|
iManufacturers++,
|
|
pszManufacturer,
|
|
&cchTemp,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ftLastWriteTime );
|
|
if (ERROR_NO_MORE_ITEMS == dwError)
|
|
{
|
|
break;
|
|
}
|
|
if (ERROR_SUCCESS != dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// open the manufacturer key
|
|
//
|
|
dwError = RegOpenKeyEx( hkeySoftware,
|
|
pszManufacturer,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyManufacturer );
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// enumerate all possible components
|
|
//
|
|
WCHAR pszComponent[MAX_PATH];
|
|
DWORD iComponents = 0;
|
|
HKEY hkeyComponent;
|
|
HKEY hkeyCurrentVersion;
|
|
HKEY hkeyNetRules;
|
|
DWORD dwRegType;
|
|
do
|
|
{
|
|
cchTemp = MAX_PATH;
|
|
dwError = RegEnumKeyEx( hkeyManufacturer,
|
|
iComponents++,
|
|
pszComponent,
|
|
&cchTemp,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ftLastWriteTime );
|
|
if (ERROR_NO_MORE_ITEMS == dwError)
|
|
{
|
|
break;
|
|
}
|
|
if (ERROR_SUCCESS != dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// open the component key
|
|
//
|
|
dwError = RegOpenKeyEx( hkeyManufacturer,
|
|
pszComponent,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyComponent );
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check if the current version key is present
|
|
//
|
|
dwError = RegOpenKeyEx( hkeyComponent,
|
|
RGAS_CURRENT_VERSION,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyCurrentVersion );
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check if the netrules key is present, thus making this a
|
|
// network component
|
|
//
|
|
dwError = RegOpenKeyEx( hkeyCurrentVersion,
|
|
RGAS_NETRULES_NAME,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyNetRules );
|
|
RegCloseKey( hkeyCurrentVersion );
|
|
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Get the option value
|
|
//
|
|
cbTemp = MAX_PATH * sizeof( WCHAR );
|
|
dwError = RegQueryValueEx( hkeyNetRules,
|
|
RGAS_INF_OPTION,
|
|
NULL,
|
|
&dwRegType,
|
|
(PBYTE)pszTemp,
|
|
&cbTemp );
|
|
if (REG_SZ != dwRegType)
|
|
{
|
|
dwError = ERROR_BADKEY;
|
|
}
|
|
if (dwError)
|
|
{
|
|
RegCloseKey( hkeyNetRules );
|
|
continue;
|
|
}
|
|
|
|
// does the option name match the given search option name
|
|
//
|
|
if (0 == lstrcmpi( pszInfOption, pszTemp ))
|
|
{
|
|
fLoop = FALSE;
|
|
// get the inf name
|
|
cbTemp = *pcchInfName * sizeof( WCHAR );
|
|
dwError = RegQueryValueEx( hkeyNetRules,
|
|
RGAS_INF_FILE_NAME,
|
|
NULL,
|
|
&dwRegType,
|
|
(PBYTE)pszInfName,
|
|
&cbTemp );
|
|
|
|
if (REG_SZ != dwRegType)
|
|
{
|
|
dwError = ERROR_BADKEY;
|
|
}
|
|
|
|
if (dwError)
|
|
{
|
|
*pcchInfName = cbTemp / sizeof( WCHAR );
|
|
RegCloseKey( hkeyNetRules );
|
|
break;
|
|
}
|
|
|
|
// get the complete reg path to the item, if the user wanted it
|
|
//
|
|
if (NULL != pcchRegBase)
|
|
{
|
|
// confirm buffer size, complete path plus slashes
|
|
// between and null termination
|
|
cchTemp = lstrlen( RGAS_SOFTWARE_HOME ) + 1 +
|
|
lstrlen( pszManufacturer ) + 1 +
|
|
lstrlen( pszComponent ) + 1 +
|
|
lstrlen( RGAS_CURRENT_VERSION ) + 1;
|
|
if (*pcchRegBase < cchTemp)
|
|
{
|
|
*pcchRegBase = cchTemp;
|
|
RegCloseKey( hkeyNetRules );
|
|
dwError = ERROR_MORE_DATA;
|
|
break;
|
|
}
|
|
lstrcpy( pszRegBase, RGAS_SOFTWARE_HOME );
|
|
lstrcat( pszRegBase, L"\\" );
|
|
lstrcat( pszRegBase, pszManufacturer );
|
|
lstrcat( pszRegBase, L"\\" );
|
|
lstrcat( pszRegBase, pszComponent );
|
|
lstrcat( pszRegBase, L"\\" );
|
|
lstrcat( pszRegBase, RGAS_CURRENT_VERSION );
|
|
}
|
|
|
|
}
|
|
RegCloseKey( hkeyNetRules );
|
|
|
|
} while (fLoop);
|
|
RegCloseKey( hkeyManufacturer );
|
|
|
|
} while (fLoop);
|
|
RegCloseKey( hkeySoftware );
|
|
|
|
} while (FALSE);
|
|
return( dwError );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR NetSetupFindHardwareComponent( PCWSTR pszInfOption,
|
|
PWSTR pszInfName, PDWORD pcchInfName,
|
|
PWSTR pszRegBase, PDWORD pcchRegBase )
|
|
{
|
|
BOOL fLoop = TRUE;
|
|
APIERR dwError = ERROR_SUCCESS;
|
|
|
|
do
|
|
{
|
|
if ( (NULL == pszInfOption) ||
|
|
(NULL == pszInfName) ||
|
|
(NULL == pcchInfName) ||
|
|
((NULL == pszRegBase) && (NULL != pcchRegBase)) ||
|
|
((NULL != pszRegBase) && (NULL == pcchRegBase)) )
|
|
{
|
|
dwError = ERROR_INVALID_PARAMETER ;
|
|
break;
|
|
}
|
|
|
|
HKEY hkeyNetCards;
|
|
WCHAR pszTemp[MAX_PATH];
|
|
DWORD cchTemp;
|
|
DWORD cbTemp;
|
|
|
|
FILETIME ftLastWriteTime;
|
|
|
|
//
|
|
// search the registry for a component with the option name given
|
|
//
|
|
|
|
// start at netcards home key
|
|
//
|
|
dwError = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
RGAS_ADAPTER_HOME,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyNetCards );
|
|
if (dwError)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// enumerate all netcards
|
|
//
|
|
WCHAR pszNetCard[MAX_PATH];
|
|
DWORD iNetCard = 0;
|
|
HKEY hkeyNetCard;
|
|
HKEY hkeyNetRules;
|
|
DWORD dwRegType;
|
|
do
|
|
{
|
|
cchTemp = MAX_PATH;
|
|
dwError = RegEnumKeyEx( hkeyNetCards,
|
|
iNetCard++,
|
|
pszNetCard,
|
|
&cchTemp,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ftLastWriteTime );
|
|
if (ERROR_NO_MORE_ITEMS == dwError)
|
|
{
|
|
break;
|
|
}
|
|
if (ERROR_SUCCESS != dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// open the netcard key
|
|
//
|
|
dwError = RegOpenKeyEx( hkeyNetCards,
|
|
pszNetCard,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyNetCard );
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check if the netrules key is present, thus making this a
|
|
// valid network adapter
|
|
//
|
|
dwError = RegOpenKeyEx( hkeyNetCard,
|
|
RGAS_NETRULES_NAME,
|
|
0,
|
|
KEY_READ,
|
|
&hkeyNetRules );
|
|
RegCloseKey( hkeyNetCard );
|
|
if (dwError)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Get the option value
|
|
//
|
|
cbTemp = MAX_PATH * sizeof( WCHAR );
|
|
dwError = RegQueryValueEx( hkeyNetRules,
|
|
RGAS_INF_OPTION,
|
|
NULL,
|
|
&dwRegType,
|
|
(PBYTE)pszTemp,
|
|
&cbTemp );
|
|
if (REG_SZ != dwRegType)
|
|
{
|
|
dwError = ERROR_BADKEY;
|
|
}
|
|
if (dwError)
|
|
{
|
|
RegCloseKey( hkeyNetRules );
|
|
continue;
|
|
}
|
|
|
|
// does the option name match the given search option name
|
|
//
|
|
if (0 == lstrcmpi( pszInfOption, pszTemp ))
|
|
{
|
|
fLoop = FALSE;
|
|
// get the inf name
|
|
cbTemp = *pcchInfName * sizeof( WCHAR );
|
|
dwError = RegQueryValueEx( hkeyNetRules,
|
|
RGAS_INF_FILE_NAME,
|
|
NULL,
|
|
&dwRegType,
|
|
(PBYTE)pszInfName,
|
|
&cbTemp );
|
|
|
|
if (REG_SZ != dwRegType)
|
|
{
|
|
dwError = ERROR_BADKEY;
|
|
}
|
|
if (dwError)
|
|
{
|
|
*pcchInfName = cbTemp / sizeof( WCHAR );
|
|
RegCloseKey( hkeyNetRules );
|
|
break;
|
|
}
|
|
|
|
// get the complete reg path to the item, if the user wanted it
|
|
//
|
|
if (NULL != pcchRegBase)
|
|
{
|
|
// confirm buffer size, complete path plus slashes
|
|
// between and null termination
|
|
cchTemp = lstrlen( RGAS_ADAPTER_HOME ) + 1 +
|
|
lstrlen( pszNetCard ) + 1;
|
|
if (*pcchRegBase < cchTemp)
|
|
{
|
|
*pcchRegBase = cchTemp;
|
|
RegCloseKey( hkeyNetRules );
|
|
dwError = ERROR_MORE_DATA;
|
|
break;
|
|
}
|
|
lstrcpy( pszRegBase, RGAS_ADAPTER_HOME );
|
|
lstrcat( pszRegBase, L"\\" );
|
|
lstrcat( pszRegBase, pszNetCard );
|
|
}
|
|
|
|
}
|
|
RegCloseKey( hkeyNetRules );
|
|
|
|
} while (fLoop);
|
|
RegCloseKey( hkeyNetCards );
|
|
|
|
} while (FALSE);
|
|
return( dwError );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
const DWORD INFINSTALL_PRIMARYINSTALL = 0x00000001;
|
|
const DWORD INFINSTALL_INPROCINTERP = 0x00000002;
|
|
const DWORD INFINSTALL_SUPPORTED = 0x00000003;
|
|
|
|
APIERR NetSetupComponentInstall( HWND hwndParent,
|
|
PCWSTR pszInfOption,
|
|
PCWSTR pszInfName,
|
|
PCWSTR pszInstallPath,
|
|
PCWSTR plszInfSymbols,
|
|
DWORD dwInstallFlags,
|
|
PDWORD pdwReturn )
|
|
{
|
|
APIERR dwError = ERROR_SUCCESS;
|
|
|
|
do
|
|
{
|
|
if ( !::IsWindow( hwndParent ) )
|
|
{
|
|
dwError = ERROR_INVALID_WINDOW_HANDLE;
|
|
break;
|
|
}
|
|
|
|
if (NULL == pszInfOption)
|
|
{
|
|
|
|
dwError = ERROR_INVALID_PARAMETER ;
|
|
break;
|
|
}
|
|
|
|
if (NULL == pszInfName)
|
|
{
|
|
dwError = ERROR_INVALID_NAME ;
|
|
break;
|
|
}
|
|
|
|
if (INFINSTALL_SUPPORTED != (dwInstallFlags | INFINSTALL_SUPPORTED))
|
|
{
|
|
dwError = ERROR_INVALID_FLAG_NUMBER ;
|
|
break;
|
|
}
|
|
|
|
dwError = ERROR_NOT_ENOUGH_MEMORY ;
|
|
SetupInterpreter siConfig( (dwInstallFlags & INFINSTALL_INPROCINTERP) );
|
|
|
|
if (!siConfig.Initialize( hwndParent ))
|
|
{
|
|
break;
|
|
}
|
|
if (!siConfig.SetNetShellModes( SIM_INSTALL ))
|
|
{
|
|
break;
|
|
}
|
|
if (dwError = siConfig.SetNetComponent( pszInfOption, pszInfName ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwError = ERROR_NOT_ENOUGH_MEMORY ;
|
|
// if the path is filled in, use it
|
|
if (NULL != pszInstallPath)
|
|
{
|
|
if (!siConfig.IncludeSymbol( PSZ_NETSRCPATH, pszInstallPath, TRUE ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwInstallFlags & INFINSTALL_PRIMARYINSTALL)
|
|
{
|
|
if (!siConfig.IncludeSymbol( PSZ_NETOVERIDEPHASE, L"primary" ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// if passed a list of symbol value pairs, then add them to
|
|
// the available list
|
|
//
|
|
if (NULL != plszInfSymbols)
|
|
{
|
|
// include private symbols
|
|
PWSTR pszSymbol = (PWSTR)plszInfSymbols;
|
|
PWSTR pszValue;
|
|
|
|
while (L'\0' != *pszSymbol)
|
|
{
|
|
pszValue = pszSymbol + lstrlen( pszSymbol ) + 1;
|
|
if (!siConfig.IncludeSymbol( pszSymbol, pszValue ))
|
|
{
|
|
break;
|
|
}
|
|
pszSymbol = pszValue + lstrlen( pszValue ) + 1;
|
|
}
|
|
}
|
|
|
|
|
|
if (dwError = siConfig.Run())
|
|
{
|
|
break;
|
|
}
|
|
dwError = ERROR_SUCCESS;
|
|
*pdwReturn = siConfig.QueryReturnValue();
|
|
} while(FALSE);
|
|
return( dwError );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR NetSetupComponentRemove( HWND hwndParent,
|
|
PCWSTR pszInfOption,
|
|
DWORD dwInstallFlags,
|
|
PDWORD pdwReturn )
|
|
{
|
|
APIERR dwError = ERROR_SUCCESS;
|
|
WCHAR pszInfName[MAX_PATH+1];
|
|
WCHAR pszRegBase[MAX_PATH+1];
|
|
|
|
do
|
|
{
|
|
if ( !::IsWindow( hwndParent ) )
|
|
{
|
|
dwError = ERROR_INVALID_WINDOW_HANDLE;
|
|
break;
|
|
}
|
|
|
|
if (NULL == pszInfOption)
|
|
{
|
|
dwError = ERROR_INVALID_PARAMETER ;
|
|
break;
|
|
}
|
|
|
|
if (INFINSTALL_SUPPORTED != (dwInstallFlags | INFINSTALL_SUPPORTED))
|
|
{
|
|
dwError = ERROR_INVALID_FLAG_NUMBER ;
|
|
break;
|
|
}
|
|
dwError = ERROR_NOT_ENOUGH_MEMORY ;
|
|
|
|
SetupInterpreter siConfig( (dwInstallFlags & INFINSTALL_INPROCINTERP) );
|
|
if (!siConfig.Initialize( hwndParent ))
|
|
{
|
|
break;
|
|
}
|
|
if (!siConfig.SetNetShellModes( SIM_DEINSTALL ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
DWORD cchInfName = MAX_PATH;
|
|
DWORD cchRegBase = MAX_PATH;
|
|
|
|
dwError = NetSetupFindHardwareComponent( pszInfOption, pszInfName, &cchInfName, pszRegBase, &cchRegBase );
|
|
if (dwError)
|
|
{
|
|
dwError = NetSetupFindSoftwareComponent( pszInfOption, pszInfName, &cchInfName, pszRegBase, &cchRegBase );
|
|
if (dwError)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwError = siConfig.SetNetComponent( pszInfOption, pszInfName, pszRegBase ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (dwInstallFlags & INFINSTALL_PRIMARYINSTALL)
|
|
{
|
|
if (!siConfig.IncludeSymbol( PSZ_NETOVERIDEPHASE, L"primary" ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwError = siConfig.Run())
|
|
{
|
|
break;
|
|
}
|
|
dwError = ERROR_SUCCESS;
|
|
*pdwReturn = siConfig.QueryReturnValue();
|
|
} while(FALSE);
|
|
return( dwError );
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR NetSetupComponentProperties( HWND hwndParent,
|
|
PCWSTR pszInfOption,
|
|
DWORD dwInstallFlags,
|
|
PDWORD pdwReturn )
|
|
{
|
|
APIERR dwError = ERROR_SUCCESS;
|
|
WCHAR pszInfName[MAX_PATH+1];
|
|
WCHAR pszRegBase[MAX_PATH+1];
|
|
|
|
do
|
|
{
|
|
if ( !::IsWindow( hwndParent ) )
|
|
{
|
|
dwError = ERROR_INVALID_WINDOW_HANDLE;
|
|
break;
|
|
}
|
|
|
|
if (NULL == pszInfOption)
|
|
{
|
|
dwError = ERROR_INVALID_PARAMETER ;
|
|
break;
|
|
}
|
|
|
|
if (INFINSTALL_SUPPORTED != (dwInstallFlags | INFINSTALL_SUPPORTED))
|
|
{
|
|
dwError = ERROR_INVALID_FLAG_NUMBER ;
|
|
break;
|
|
}
|
|
dwError = ERROR_NOT_ENOUGH_MEMORY ;
|
|
|
|
SetupInterpreter siConfig( (dwInstallFlags & INFINSTALL_INPROCINTERP) );
|
|
|
|
if (!siConfig.Initialize( hwndParent ))
|
|
{
|
|
break;
|
|
}
|
|
if (!siConfig.SetNetShellModes( SIM_CONFIGURE ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
DWORD cchInfName = MAX_PATH;
|
|
DWORD cchRegBase = MAX_PATH;
|
|
|
|
dwError = NetSetupFindHardwareComponent( pszInfOption, pszInfName, &cchInfName, pszRegBase, &cchRegBase );
|
|
if (dwError)
|
|
{
|
|
dwError = NetSetupFindSoftwareComponent( pszInfOption, pszInfName, &cchInfName, pszRegBase, &cchRegBase );
|
|
if (dwError)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwError = siConfig.SetNetComponent( pszInfOption, pszInfName, pszRegBase ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (dwInstallFlags & INFINSTALL_PRIMARYINSTALL)
|
|
{
|
|
if (!siConfig.IncludeSymbol( PSZ_NETOVERIDEPHASE, L"primary" ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwError = siConfig.Run())
|
|
{
|
|
break;
|
|
}
|
|
dwError = ERROR_SUCCESS;
|
|
*pdwReturn = siConfig.QueryReturnValue();
|
|
} while (FALSE);
|
|
return( dwError );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
// History:
|
|
// April 21, 1995 MikeMi -
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
APIERR RouteToInfList (
|
|
const TCHAR * pszRoute,
|
|
NLS_STR * pnlsResult )
|
|
{
|
|
NLS_STR nls ;
|
|
INT cQuote ;
|
|
|
|
for ( cQuote = 0 ; *pszRoute ; pszRoute++ )
|
|
{
|
|
if ( *pszRoute == CHQUOTE )
|
|
{
|
|
if ( cQuote++ & 1 ) // If it's a closing quote...
|
|
{
|
|
if ( nls.QueryTextLength() )
|
|
appendToInfList( pnlsResult, nls.QueryPch(), ISC_Before ) ;
|
|
}
|
|
nls = SZ("") ;
|
|
}
|
|
else
|
|
{
|
|
nls.AppendChar( *pszRoute ) ;
|
|
}
|
|
}
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlSetup
|
|
|
|
SYNOPSIS: Exported function to cause NCPA to run in "main
|
|
installation" mode.
|
|
|
|
ENTRY: DWORD nArgs
|
|
LPSTR apszArgs []
|
|
LPSTR * ppszResult
|
|
|
|
apszArgs[0] window handle
|
|
apszArgs[1] symbolic name of function
|
|
to be executed
|
|
|
|
See enumeration info for
|
|
list of currently supported values.
|
|
|
|
apszArgs[2] command line to be passed to
|
|
function (see RunNcpa()).
|
|
|
|
apszArgs[n] other arguments to other functions
|
|
|
|
|
|
EXIT: nothing
|
|
|
|
RETURNS: SETUP INF list form, starting with error code
|
|
E.g.:
|
|
"{ 0 }"
|
|
|
|
NOTES: The called function can return more variables into
|
|
the list by appending them onto the passed NLS_STR.
|
|
|
|
HISTORY:
|
|
beng 05-May-1992 wsprintf -> wsprintfA
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupFunctions(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
APIERR err = 0 ;
|
|
HWND hWnd = 0 ;
|
|
UINT iFunc ;
|
|
TCHAR * * patchArgs ;
|
|
ESETUP_FUNC esFunc ;
|
|
NLS_STR nlsResult ;
|
|
BOOL fWasDisabled ;
|
|
BOOL fSupported;
|
|
|
|
// Sanity Check
|
|
|
|
if ( nArgs < 2 )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: Invalid number of arguments to CPlSetup().") ) ;
|
|
return FALSE ;
|
|
}
|
|
|
|
// Check that we can convert the arguments to a usable form
|
|
|
|
if ( (patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
|
|
// Convert the second argument from a string to an enum
|
|
|
|
TRACEEOL( SZ("NCPA/SETP: requested function is: ")
|
|
<< patchArgs[ESARG_FUNC] );
|
|
|
|
for ( iFunc = 0 ; setupFuncIndex[iFunc].pszToken ; iFunc++ )
|
|
{
|
|
if ( ::stricmpf( patchArgs[ESARG_FUNC],
|
|
setupFuncIndex[iFunc].pszToken ) == 0 )
|
|
|
|
{
|
|
break ;
|
|
}
|
|
}
|
|
|
|
esFunc = setupFuncIndex[iFunc].esFunc ;
|
|
fSupported = setupFuncIndex[iFunc].fStillSupported;
|
|
|
|
if (fSupported)
|
|
{
|
|
// If the function references the window handle,
|
|
// convert it and control window dis/enabling.
|
|
|
|
if ( setupFuncIndex[iFunc].fUsesHwnd )
|
|
{
|
|
// Convert the first argment to a window handle.
|
|
|
|
if ( patchArgs[ESARG_HWND][0] != TCH('\0') )
|
|
{
|
|
hWnd = (HWND) CvtHex( patchArgs[ESARG_HWND] ) ;
|
|
}
|
|
|
|
// If desperate, grab any old window handle at all
|
|
|
|
if ( hWnd == 0 || ! ::IsWindow( hWnd ) )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: window handle passed was invalid") ) ;
|
|
hWnd = ::GetActiveWindow() ;
|
|
}
|
|
|
|
// Perform window disable/enable like the dialog manager...
|
|
|
|
fWasDisabled = ::EnableWindow( hWnd, FALSE ) ;
|
|
|
|
TRACEEOL( SZ("NCPA/SETP: EnableWindow() returned: " << fWasDisabled ) ) ;
|
|
}
|
|
|
|
switch ( esFunc )
|
|
{
|
|
case ESFUNC_NCPA:
|
|
err = RunNcpa( hWnd );
|
|
/*
|
|
TRUE,
|
|
nArgs >= ESARG_1ST
|
|
? patchArgs[ESARG_1ST]
|
|
: NULL ) ;
|
|
*/
|
|
break ;
|
|
|
|
/* case entries commented out below are not supported anymore
|
|
case ESFUNC_DOMAIN:
|
|
err = RunDomain( hWnd,
|
|
patchArgs[ESARG_1ST],
|
|
& nlsResult );
|
|
break ;
|
|
|
|
case ESFUNC_CONNECT:
|
|
err = RunConnect( (const TCHAR * *) & patchArgs[ESARG_1ST],
|
|
nArgs - ESARG_1ST ) ;
|
|
break;
|
|
*/
|
|
case ESFUNC_CREATE_SERVICE:
|
|
err = RunCreateService( (const TCHAR * *) & patchArgs[ESARG_1ST],
|
|
nArgs - ESARG_1ST ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DELETE_SERVICE:
|
|
err = RunDeleteService( patchArgs[ESARG_1ST] ) ;
|
|
break ;
|
|
|
|
case ESFUNC_START_SERVICE:
|
|
err = RunStartService( (const TCHAR * *) & patchArgs[ESARG_1ST],
|
|
nArgs - ESARG_1ST ) ;
|
|
break;
|
|
|
|
case ESFUNC_SECURE_SERVICE:
|
|
err = RunSecureService( patchArgs[ ESARG_1ST ],
|
|
patchArgs[ ESARG_1ST + 1 ] );
|
|
break;
|
|
|
|
case ESFUNC_SECURE_REG_KEY:
|
|
err = RunSecureKey( patchArgs[ ESARG_1ST ],
|
|
patchArgs[ ESARG_1ST + 1 ] );
|
|
break ;
|
|
|
|
case ESFUNC_WINSOCK_MAPPING:
|
|
err = RunWinsockMapping( patchArgs[ ESARG_1ST ],
|
|
patchArgs[ ESARG_1ST + 1 ] );
|
|
break ;
|
|
|
|
case ESFUNC_ERROR_MESSAGE:
|
|
err = RunErrorMessage( patchArgs[ ESARG_1ST ],
|
|
& nlsResult );
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_START:
|
|
err = RunDetectStart() ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_END:
|
|
err = RunDetectEnd() ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_RESET:
|
|
err = RunDetectReset() ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_CARD:
|
|
err = RunDetectCard( & nlsResult ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_VERIFY:
|
|
err = RunDetectVerifyCard( patchArgs[ ESARG_1ST ],
|
|
patchArgs[ ESARG_1ST + 1 ] ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_QUERY:
|
|
err = RunDetectQueryCard( patchArgs[ ESARG_1ST ],
|
|
& nlsResult ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_PARAMS:
|
|
err = RunDetectGetParams( patchArgs[ ESARG_1ST ],
|
|
& nlsResult ) ;
|
|
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_STRING:
|
|
err = RunDetectGetString( patchArgs[ ESARG_1ST],
|
|
patchArgs[ ESARG_1ST + 1 ],
|
|
& nlsResult ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_PNAME:
|
|
err = RunDetectGetParamName( patchArgs[ ESARG_1ST],
|
|
patchArgs[ ESARG_1ST + 1 ],
|
|
& nlsResult ) ;
|
|
break ;
|
|
|
|
case ESFUNC_DETECT_CLAIM:
|
|
err = RunDetectClaim( patchArgs[ ESARG_1ST] ) ;
|
|
break ;
|
|
/*
|
|
case ESFUNC_DETECT_OPEN:
|
|
|
|
if ( nArgs < ESARG_1ST + 2 )
|
|
{
|
|
err = ERROR_INVALID_PARAMETER ;
|
|
}
|
|
else
|
|
{
|
|
err = RunDetectOpen( patchArgs[ESARG_1ST],
|
|
patchArgs[ESARG_1ST+1],
|
|
patchArgs[ESARG_1ST+2],
|
|
& nlsResult ) ;
|
|
}
|
|
break;
|
|
*/
|
|
case ESFUNC_MCS_CFG_CHECK:
|
|
err = RunMCSAlteredCheck( (const TCHAR * ) patchArgs[ESARG_1ST] );
|
|
break;
|
|
/*
|
|
case ESFUNC_TCPIP_CFG_CHECK:
|
|
err = RunTcpipAlteredCheck() ;
|
|
break ;
|
|
*/
|
|
case ESFUNC_ROUTE_TO_INF_LIST:
|
|
err = RouteToInfList( patchArgs[ ESARG_1ST ],
|
|
& nlsResult ) ;
|
|
break ;
|
|
/*
|
|
case ESFUNC_BINDINGS_ONLY:
|
|
err = RunNcpaBindingsOnly( hWnd ) ;
|
|
break ;
|
|
*/
|
|
case ESFUNC_ACTIVATE_BINDINGS:
|
|
err = RunActivateBindings( patchArgs[ ESARG_1ST ],
|
|
patchArgs[ ESARG_1ST+1 ] ) ;
|
|
break ;
|
|
/*
|
|
case ESFUNC_BDC_REPLICATE:
|
|
err = RunBDCReplWait( hWnd );
|
|
break ;
|
|
*/
|
|
case ESFUNC_NONE:
|
|
case ESFUNC_MAX:
|
|
default:
|
|
err = ERROR_INVALID_FUNCTION ;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = ERROR_INVALID_FUNCTION ;
|
|
}
|
|
#if defined(DEBUG)
|
|
|
|
if ( err == ERROR_INVALID_FUNCTION )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: requested function was invalid") ) ;
|
|
}
|
|
else if ( err )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SETP: requested function [")
|
|
<< patchArgs[ESARG_FUNC]
|
|
<< SZ("] returned error: ")
|
|
<< err ) ;
|
|
}
|
|
#endif
|
|
|
|
// If the routine used the window handle, control en/disabling.
|
|
|
|
if ( hWnd )
|
|
{
|
|
::EnableWindow( hWnd, ! fWasDisabled ) ;
|
|
}
|
|
|
|
// Generate the non-UNICODE result. Since SETUP is always
|
|
// ANSI, return an 8-bit character result. It's formatted as
|
|
// as a SETUP list variable whose first element is a numeric
|
|
// error code. The remainder of the variables are function-
|
|
// specific.
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"", err ) ;
|
|
|
|
// See if the subfunction appended any data; if so, add it
|
|
// as-is to the string, just converting from UNICODE to ANSI.
|
|
|
|
if ( nlsResult.QueryError() == 0
|
|
&& nlsResult.QueryTextLength() > 0 )
|
|
{
|
|
// This code assumes that MapCopyTo() moves the
|
|
// string terminator as well as the data. Note that
|
|
// MapCopyTo() will fail if buffer is insufficient.
|
|
|
|
INT cchBuff = ::strlen( g_achBuff ) ;
|
|
|
|
if ( nlsResult.MapCopyTo( g_achBuff + cchBuff,
|
|
sizeof g_achBuff - 1 - cchBuff ) )
|
|
{
|
|
g_achBuff[cchBuff] = 0 ;
|
|
}
|
|
}
|
|
|
|
::strcat( g_achBuff, "}" );
|
|
|
|
// This (sometimes huge) output seems to kill NTSD
|
|
// TRACEEOL( SZ("NCPA/SETP: return string is: ") << g_achBuff ) ;
|
|
//
|
|
TRACEEOL( SZ("NCPA/SETP: return result is: ") << err ) ;
|
|
|
|
*ppszResult = g_achBuff ;
|
|
|
|
FreeArgs( patchArgs, nArgs ) ;
|
|
|
|
return err == 0 ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CplSetupCleanup
|
|
|
|
SYNOPSIS: Clean up possible memory remnants at
|
|
DLL detatch time.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
LONG FAR PASCAL NetSetupRunDetectEnd()
|
|
{
|
|
RunDetectEnd() ;
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlNETBIOS
|
|
|
|
SYNOPSIS: Wrapper routine for calling RunNETBIOS. It should be called
|
|
from inf file.
|
|
|
|
ENTRY: The first parameter must be the parent window handle.
|
|
|
|
RETURN: BOOL - TRUE for okay.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
APIERR err = ERROR_SUCCESS ;
|
|
HWND hWnd = NULL;
|
|
TCHAR **patchArgs;
|
|
|
|
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
|
|
{
|
|
wsprintfA( g_achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
|
|
*ppszResult = g_achBuff;
|
|
return FALSE;
|
|
}
|
|
|
|
// get window handle
|
|
if ( nArgs > 0 && patchArgs[0][0] != TCH('\0') )
|
|
{
|
|
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
|
|
}
|
|
else
|
|
{
|
|
hWnd = ::GetActiveWindow() ;
|
|
}
|
|
|
|
if (!RaiseNetBiosDialog( hWnd ))
|
|
{
|
|
err = ERROR_CANCELLED;
|
|
}
|
|
|
|
wsprintfA( g_achBuff, "{\"%d\"}", err );
|
|
*ppszResult = g_achBuff;
|
|
|
|
FreeArgs( patchArgs, nArgs );
|
|
return err == NERR_Success;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlSetupLanaMap
|
|
|
|
SYNOPSIS: This is a wrapper routine for called SetupLanaMap. It should be
|
|
called from inf file. SetupLanaMap will setup the LanaMax
|
|
variable and LanaMap variable in NETBIOS section of the
|
|
registry.
|
|
|
|
ENTRY: NONE from inf file.
|
|
|
|
RETURN: BOOL - TRUE for success.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupLanaMap( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
wsprintfA( g_achBuff, "{\"0\"}" );
|
|
*ppszResult = g_achBuff;
|
|
return SetupLanaMap() == NERR_Success;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: EqualToXnsRoute
|
|
|
|
SYNOPSIS: Compare whether the first arg is started with ["Xns].
|
|
It should be called from an inf file.
|
|
|
|
ENTRY: The first argument should contain the Route string.
|
|
|
|
RETURN: ppszResult will contian either ASCII 0 or ASCII 1. 0 for
|
|
FALSE and 1 for TRUE.
|
|
TRUE means the given string is started with "Xns
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
#define RGAS_MCSXNS_PATH SZ("SYSTEM\\CurrentControlSet\\Services\\Mcsxns\\NetConfig\\Driver01")
|
|
#define RGAS_ADAPTERNAME SZ("AdapterName")
|
|
|
|
BOOL FAR PASCAL NetSetupEqualToXnsRoute( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
|
|
BOOL fReturn = FALSE;
|
|
wsprintfA( g_achBuff, "0" );
|
|
|
|
if ( nArgs > 0 && apszArgs[0][0] != TCH('\0') )
|
|
{
|
|
fReturn = ((_strnicmp( apszArgs[0], "\"Xns", 4 ) == 0)||
|
|
(_strnicmp( apszArgs[0], "\"Ubnb", 5 ) == 0));
|
|
wsprintfA( g_achBuff, "%d", fReturn?1:0 );
|
|
}
|
|
*ppszResult = g_achBuff;
|
|
return fReturn;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SetEnum
|
|
|
|
SYNOPSIS: Worker function for SetEnumExport. This function will
|
|
look at the given Route string and search the adapter
|
|
section of the route string. For example, if the route
|
|
string is:
|
|
"NBF" "Elnkii" "Elnkii01"
|
|
The routine will look at:
|
|
System\CurrentControlSet\Services\Elnkii01\Parameters
|
|
If this section contain a variable called "EnumExportPref",
|
|
the subroutine will set the:
|
|
System\CurrentControlSet\Services\NETBIOSInformation\
|
|
Parameters\EnumExport[POS]
|
|
to the same value. ( POS is the first parameter of this
|
|
subroutine.) Otherwise, it will just return to the caller.
|
|
|
|
ENTRY: TCHAR * pszPos - position number in string format.
|
|
TCHAR * pszRoute - route string. i.e., NBF Elnkii Elnkii01
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
#define RGAS_PARAMETERS SZ("\\Parameters")
|
|
#define RGAS_ROUTE SZ("Route")
|
|
#define RGAS_LANANUM SZ("LanaNum")
|
|
#define RGAS_ENUMEXPORT SZ("EnumExport")
|
|
#define RGAS_ENUMEXPORTPREF SZ("EnumExportPref")
|
|
#define RG_NETBIOSINFO_PATH SZ("\\NetBIOSInformation\\Parameters")
|
|
|
|
void SetEnum( TCHAR *pszPos, TCHAR * pszRoute )
|
|
{
|
|
APIERR err = NERR_Success;
|
|
NLS_STR nlsRoute = pszRoute;
|
|
DWORD dwPref = 1;
|
|
|
|
// get the service name from the route
|
|
ISTR istrLastQuote( nlsRoute );
|
|
ISTR istrStart( nlsRoute );
|
|
|
|
nlsRoute.strrchr( & istrLastQuote, '"' );
|
|
|
|
NLS_STR *pnlsTmp = nlsRoute.QuerySubStr( istrStart, istrLastQuote );
|
|
|
|
ISTR istrSecLastQuote( *pnlsTmp );
|
|
|
|
pnlsTmp->strrchr( & istrSecLastQuote, '"' );
|
|
|
|
++istrSecLastQuote;
|
|
|
|
NLS_STR *pnlsServiceName = pnlsTmp->QuerySubStr( istrSecLastQuote );
|
|
|
|
delete pnlsTmp;
|
|
|
|
// get the EnumExportPref value
|
|
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE );
|
|
|
|
NLS_STR nlsService = RGAS_SERVICES_HOME;
|
|
nlsService.AppendChar( TCHAR('\\' ));
|
|
nlsService.strcat( *pnlsServiceName );
|
|
nlsService.strcat( RGAS_PARAMETERS );
|
|
|
|
REG_KEY regService( rkLocalMachine, nlsService );
|
|
if (((( err = regService.QueryError())) != NERR_Success ) ||
|
|
((err = regService.QueryValue( RGAS_ENUMEXPORTPREF, & dwPref )) != NERR_Success ))
|
|
{
|
|
delete pnlsServiceName;
|
|
return;
|
|
}
|
|
|
|
delete pnlsServiceName;
|
|
|
|
// set the NETBIOSInformation\Parameters\EnumExportXX
|
|
NLS_STR nlsNetbiosInfo = RGAS_SERVICES_HOME;
|
|
nlsNetbiosInfo.strcat( RG_NETBIOSINFO_PATH );
|
|
|
|
NLS_STR nlsExport( RGAS_ENUMEXPORT );
|
|
nlsExport.strcat( pszPos );
|
|
|
|
REG_KEY regExport( rkLocalMachine, nlsNetbiosInfo );
|
|
|
|
if (((( err = regExport.QueryError())) != NERR_Success ) ||
|
|
((err = regExport.SetValue( nlsExport, dwPref )) != NERR_Success ))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SetEnumExport
|
|
|
|
SYNOPSIS: Wrapper function for SetEnum. The nbinfo.inf file will call
|
|
this function to reset all the EnumExport values under
|
|
NETBIOSInformation.
|
|
|
|
ENTRY: The first parameter is the position string for the EnumExport
|
|
value.i.e., "1", "12", ...
|
|
The second parameter is the route string.i.e.,
|
|
"NBF" "ELNKII" ELNK01"
|
|
|
|
RETURN: BOOL - TRUE for success. FALSE for failure.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupSetEnumExport( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
TCHAR **patchArgs;
|
|
|
|
if (( nArgs != 2 ) || (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL ))
|
|
{
|
|
wsprintfA( g_achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
|
|
*ppszResult = g_achBuff;
|
|
return FALSE;
|
|
}
|
|
|
|
SetEnum( patchArgs[0], patchArgs[1] );
|
|
wsprintfA( g_achBuff, "{\"0\"}" );
|
|
*ppszResult = g_achBuff;
|
|
FreeArgs( patchArgs, nArgs );
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RemoveRoute
|
|
|
|
SYNOPSIS: Worker function for RemoveRouteFromNETBIOS. This function will
|
|
receive a device name. It will look through all the route
|
|
string under NETBIOSInformation\Parameters\Route, if it
|
|
finds the route string which contains the device name, it
|
|
will remove it from the route list. It will also remove
|
|
the related LanaNum and EnumExport variables. After it
|
|
removes the LanaNum and EnumExport variables, it will move
|
|
all the LanaNum and EnumExport value names down 1 position.
|
|
|
|
ENTRY: TCHAR * pszDeviceName - device name string, i.e., "Elnkii01"
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
void RemoveRoute ( TCHAR * pszDeviceName )
|
|
{
|
|
APIERR err = NERR_Success;
|
|
NLS_STR nlsDeviceName ( pszDeviceName );
|
|
|
|
STRLIST * pstrlstRoute = NULL;
|
|
|
|
NLS_STR nlsNetbiosInfo = RGAS_SERVICES_HOME;
|
|
nlsNetbiosInfo.strcat( RG_NETBIOSINFO_PATH );
|
|
|
|
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE );
|
|
|
|
REG_KEY regNetbios( rkLocalMachine, nlsNetbiosInfo );
|
|
|
|
// get the original route strings list
|
|
|
|
if (((( err = regNetbios.QueryError())) != NERR_Success ) ||
|
|
((err = regNetbios.QueryValue( RGAS_ROUTE, &pstrlstRoute )) != NERR_Success ))
|
|
{
|
|
delete pstrlstRoute;
|
|
return;
|
|
}
|
|
|
|
INT nNumRoute = pstrlstRoute->QueryNumElem();
|
|
INT nNewNumRoute = nNumRoute;
|
|
ITER_STRLIST iterRoute( *pstrlstRoute );
|
|
NLS_STR *pnlsRoute = iterRoute.Next();
|
|
STRLIST strlstNewRoute;
|
|
INT nNextAvail = 1;
|
|
NLS_STR * pnlsTmp ;
|
|
|
|
for ( INT i = 1; i <= nNumRoute; i++, pnlsRoute = iterRoute.Next() )
|
|
{
|
|
ISTR istrRoute( *pnlsRoute );
|
|
if ( pnlsRoute->strstr( &istrRoute, nlsDeviceName ))
|
|
{
|
|
// found it
|
|
nNewNumRoute --;
|
|
} else if (( pnlsTmp = new NLS_STR( *pnlsRoute ) ) != NULL )
|
|
{
|
|
// cannot find it; must have been deleted
|
|
strlstNewRoute.Append( pnlsTmp );
|
|
if ( nNewNumRoute != nNumRoute )
|
|
{
|
|
// if we have already removed the route string from the route list,
|
|
// we will move the LanaNum and EnumExport variables up
|
|
DWORD nLanaNum;
|
|
DWORD nEnumExport;
|
|
|
|
DEC_STR nlsOldPos( i );
|
|
DEC_STR nlsNewPos( nNextAvail );
|
|
NLS_STR nlsOldLanaNum( RGAS_LANANUM );
|
|
NLS_STR nlsOldEnumExport( RGAS_ENUMEXPORT );
|
|
NLS_STR nlsNewLanaNum( RGAS_LANANUM );
|
|
NLS_STR nlsNewEnumExport( RGAS_ENUMEXPORT );
|
|
|
|
nlsOldLanaNum.strcat( nlsOldPos );
|
|
nlsOldEnumExport.strcat( nlsOldPos );
|
|
nlsNewLanaNum.strcat( nlsNewPos );
|
|
nlsNewEnumExport.strcat( nlsNewPos );
|
|
|
|
regNetbios.QueryValue( nlsOldLanaNum, &nLanaNum );
|
|
regNetbios.QueryValue( nlsOldEnumExport, &nEnumExport );
|
|
regNetbios.SetValue( nlsNewLanaNum, nLanaNum );
|
|
regNetbios.SetValue( nlsNewEnumExport, nEnumExport );
|
|
}
|
|
nNextAvail ++;
|
|
}
|
|
}
|
|
|
|
if ( nNewNumRoute != nNumRoute )
|
|
{
|
|
|
|
// remove extra LanaNum and EnumExport
|
|
|
|
for ( i = nNewNumRoute ; i < nNumRoute; i++ )
|
|
{
|
|
DEC_STR nlsPos( i + 1 );
|
|
NLS_STR nlsLanaNum( RGAS_LANANUM );
|
|
NLS_STR nlsEnumExport( RGAS_ENUMEXPORT );
|
|
|
|
nlsLanaNum.strcat( nlsPos );
|
|
nlsEnumExport.strcat( nlsPos );
|
|
|
|
regNetbios.DeleteValue( nlsLanaNum );
|
|
regNetbios.DeleteValue( nlsEnumExport );
|
|
}
|
|
|
|
// save the new route list
|
|
regNetbios.SetValue( RGAS_ROUTE, &strlstNewRoute );
|
|
}
|
|
|
|
delete pstrlstRoute;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: RemoveRouteFromNETBIOS
|
|
|
|
SYNOPSIS: Wrapper function for RemoveRoute. This subroutine is called
|
|
from utility.inf. When the user removes an adapter card from
|
|
NCPA, utility.inf will call this routine to remove the related
|
|
information from the NETBIOSInformation section of the registry.
|
|
|
|
ENTRY: The first parameter is the device name.
|
|
|
|
RETURN: BOOL - TRUE for success.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupRemoveRouteFromNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
TCHAR **patchArgs;
|
|
|
|
if (( nArgs != 1 ) || (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL ))
|
|
{
|
|
wsprintfA( g_achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
|
|
*ppszResult = g_achBuff;
|
|
return FALSE;
|
|
}
|
|
|
|
RemoveRoute( patchArgs[0] );
|
|
wsprintfA( g_achBuff, "{\"0\"}" );
|
|
*ppszResult = g_achBuff;
|
|
FreeArgs( patchArgs, nArgs );
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlBROWSER
|
|
|
|
SYNOPSIS: It should be called
|
|
from inf file.
|
|
|
|
ENTRY: The first parameter must be the parent window handle.
|
|
|
|
RETURN: BOOL - TRUE for okay.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
BOOL FAR PASCAL NetSetupBROWSER( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
APIERR err = NERR_Success ;
|
|
HWND hWnd = NULL;
|
|
TCHAR **patchArgs;
|
|
|
|
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
|
|
{
|
|
wsprintfA( g_achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
|
|
*ppszResult = g_achBuff;
|
|
return FALSE;
|
|
}
|
|
|
|
// get window handle
|
|
if ( nArgs > 0 && patchArgs[0][0] != TCH('\0') )
|
|
{
|
|
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
|
|
}
|
|
else
|
|
{
|
|
hWnd = ::GetActiveWindow() ;
|
|
}
|
|
|
|
if (!RaiseBrowserDialog( hWnd ))
|
|
{
|
|
err = 1;
|
|
}
|
|
|
|
wsprintfA( g_achBuff, "{\"%d\"}", err );
|
|
*ppszResult = g_achBuff;
|
|
|
|
FreeArgs( patchArgs, nArgs );
|
|
return err == NERR_Success;
|
|
}
|
|
|
|
|
|
BOOL FAR PASCAL NetSetupConvertEndPointString( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
|
|
if ( nArgs != 2 )
|
|
{
|
|
wsprintfA( g_achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
|
|
*ppszResult = g_achBuff;
|
|
return FALSE;
|
|
}
|
|
|
|
CHAR achComponent[200] ;
|
|
CHAR * pcTmp = achComponent,
|
|
* pcTmpMax = & achComponent [ sizeof achComponent - 1 ],
|
|
* pcPos ;
|
|
for ( pcPos = apszArgs[1] ;
|
|
pcTmp < pcTmpMax && *pcPos != 0 && *pcPos != ' ' ;
|
|
pcPos++ )
|
|
{
|
|
*pcTmp++ = *pcPos;
|
|
}
|
|
*pcTmp = '\0';
|
|
|
|
wsprintfA( g_achBuff, "\"%s\" %s", apszArgs[0], achComponent );
|
|
*ppszResult = g_achBuff;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: CPlAddMonitor
|
|
|
|
SYNOPSIS: This is a wrapper routine for called AddMonitor. It should be
|
|
called from inf file if the user installs DLC or Token Ring.
|
|
|
|
ENTRY: NONE from inf file.
|
|
|
|
RETURN: BOOL - TRUE for success.
|
|
|
|
HISTORY:
|
|
terryk 11-Nov-1992 Created
|
|
|
|
********************************************************************/
|
|
|
|
typedef BOOL (WINAPI *T_AddMonitor)(LPWSTR pName,DWORD Level,LPBYTE pMonitors);
|
|
typedef BOOL (WINAPI *T_DeleteMonitor)(LPWSTR pName,LPWSTR pEnv, LPWSTR pMon);
|
|
|
|
|
|
BOOL FAR PASCAL NetSetupAddMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
NLS_STR nlsMonitorName;
|
|
MONITOR_INFO_2 MonitorInfo2;
|
|
|
|
APIERR err = NERR_Success;
|
|
do
|
|
{
|
|
{
|
|
WCHAR pszTemp[MAX_TEMP+1];
|
|
|
|
LoadString( g_hinst, IDS_HP_MONITOR_NAME, pszTemp, MAX_TEMP );
|
|
nlsMonitorName = pszTemp;
|
|
}
|
|
/*
|
|
if (( err = nlsMonitorName.Load( IDS_HP_MONITOR_NAME )) != NERR_Success )
|
|
{
|
|
break;
|
|
}
|
|
*/
|
|
MonitorInfo2.pName = (LPWSTR)nlsMonitorName.QueryPch();
|
|
MonitorInfo2.pEnvironment = NULL;
|
|
MonitorInfo2.pDLLName = SZ("hpmon.dll");
|
|
|
|
HINSTANCE hDll = ::LoadLibraryA( "winspool.drv" );
|
|
if ( hDll == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
break;
|
|
}
|
|
|
|
FARPROC pAddMonitor = ::GetProcAddress( hDll, "AddMonitorW" );
|
|
|
|
if ( pAddMonitor == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
}
|
|
else if ( !(*(T_AddMonitor)pAddMonitor)(NULL,2,(LPBYTE)&MonitorInfo2))
|
|
{
|
|
err = ::GetLastError();
|
|
}
|
|
|
|
if ( hDll )
|
|
::FreeLibrary( hDll );
|
|
|
|
} while (FALSE);
|
|
wsprintfA( g_achBuff, "{\"%d\"}", err );
|
|
*ppszResult = g_achBuff;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL FAR PASCAL NetSetupDeleteMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
NLS_STR nlsMonitorName;
|
|
APIERR err = NERR_Success;
|
|
|
|
do {
|
|
{
|
|
WCHAR pszTemp[MAX_TEMP+1];
|
|
|
|
LoadString( g_hinst, IDS_HP_MONITOR_NAME, pszTemp, MAX_TEMP );
|
|
nlsMonitorName = pszTemp;
|
|
}
|
|
/*
|
|
if (( err = nlsMonitorName.Load( IDS_HP_MONITOR_NAME )) != NERR_Success )
|
|
{
|
|
break;
|
|
}
|
|
*/
|
|
HINSTANCE hDll = ::LoadLibraryA( "winspool.drv" );
|
|
if ( hDll == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
break;
|
|
}
|
|
|
|
FARPROC pDeleteMonitor = ::GetProcAddress( hDll, "DeleteMonitorW" );
|
|
|
|
if ( pDeleteMonitor == NULL )
|
|
{
|
|
err = ::GetLastError();
|
|
} else if ( !(*(T_DeleteMonitor)pDeleteMonitor)(NULL,NULL,(LPWSTR)nlsMonitorName.QueryPch()))
|
|
{
|
|
err = ::GetLastError();
|
|
}
|
|
|
|
if ( hDll )
|
|
::FreeLibrary ( hDll );
|
|
|
|
} while (FALSE);
|
|
wsprintfA( g_achBuff, "{\"%d\"}", err );
|
|
*ppszResult = g_achBuff;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: GetBusTypeDialog
|
|
|
|
SYNOPSIS: Wrapper routine for calling RunGetBusDlg. The inf file
|
|
should call this function into to display the Bus Location
|
|
dialog.
|
|
|
|
ENTRY: The first parameter must be the parent window handle.
|
|
The second parameter must be the network card description name.
|
|
The third parameter is the bus type
|
|
The fourth parameter is the bus number
|
|
|
|
RETURN: BOOL - TRUE for okay.
|
|
|
|
HISTORY:
|
|
terryk 03-Aug-1993 Created
|
|
|
|
********************************************************************/
|
|
|
|
CHAR PSZ_RTCANCEL[] = "CANCEL";
|
|
CHAR PSZ_RTOK[] = "OK";
|
|
|
|
BOOL FAR PASCAL NetSetupGetBusTypeDialog( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
|
|
{
|
|
APIERR err = NERR_Success ;
|
|
HWND hWnd = NULL;
|
|
BOOL fReturn = TRUE;
|
|
TCHAR **patchArgs;
|
|
INT nBusType = 0;
|
|
INT nBusNum = 0;
|
|
|
|
wsprintfA( g_achBuff, "{\"%d\",\"%d\",\"%d\"}", ERROR_INVALID_PARAMETER, nBusType, nBusNum );
|
|
*ppszResult = g_achBuff;
|
|
|
|
do
|
|
{
|
|
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
|
|
{
|
|
fReturn = FALSE;
|
|
break;
|
|
}
|
|
|
|
// get window handle
|
|
if ( nArgs > 0 && patchArgs[0][0] != TCH('\0') )
|
|
{
|
|
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
|
|
}
|
|
else
|
|
{
|
|
hWnd = ::GetActiveWindow() ;
|
|
}
|
|
|
|
if (( nArgs > 2 ) && ( patchArgs[2][0] != TCH('\0') ))
|
|
{
|
|
NLS_STR nlsTmp = patchArgs[2];
|
|
if ( nlsTmp.QueryError() != NERR_Success )
|
|
{
|
|
fReturn = FALSE;
|
|
break;
|
|
}
|
|
|
|
nBusType = nlsTmp.atoi();
|
|
}
|
|
else
|
|
{
|
|
nBusType = 1; // assume it is ISA
|
|
}
|
|
if (( nArgs > 3 ) && ( patchArgs[3][0] != TCH('\0') ))
|
|
{
|
|
NLS_STR nlsTmp = patchArgs[3];
|
|
if ( nlsTmp.QueryError() != NERR_Success )
|
|
{
|
|
fReturn = FALSE;
|
|
break;
|
|
}
|
|
|
|
nBusNum = nlsTmp.atoi();
|
|
}
|
|
else
|
|
{
|
|
nBusNum = 0; // assume it is bus 0
|
|
}
|
|
|
|
// Call the worker function by passing the window handle and the
|
|
// network card description name
|
|
BOOL fUserCancel;
|
|
LPCSTR pszRt = NULL;
|
|
|
|
err = RunGetBusTypeDlg( hWnd , patchArgs[1], &nBusType, &nBusNum, fUserCancel ) ;
|
|
|
|
if (!fUserCancel)
|
|
{
|
|
pszRt = PSZ_RTOK;
|
|
}
|
|
else
|
|
{
|
|
pszRt = PSZ_RTCANCEL;
|
|
}
|
|
|
|
wsprintfA( g_achBuff, "{\"%d\",\"%d\",\"%d\",\"%s\"}", err, nBusType, nBusNum, pszRt );
|
|
*ppszResult = g_achBuff;
|
|
|
|
fReturn = err == NERR_Success;
|
|
|
|
} while ( FALSE );
|
|
|
|
FreeArgs( patchArgs, nArgs );
|
|
return fReturn;
|
|
}
|
|
|
|
/*
|
|
Upgrdsna.cxx
|
|
Upgrade SNA.
|
|
1. See whether SNA is installed or not
|
|
2. If yes, look for all the snadlcX keys
|
|
3. changed the snadlcX\Parameters\ExtraParameters\AdapterName by
|
|
removing the extra 0 (if necessary).
|
|
|
|
FILE HISTORY:
|
|
terryk 5/20/94 Created
|
|
|
|
*/
|
|
|
|
|
|
// Registry keys
|
|
|
|
#define RGAS_SNADLC SZ("SnaDLC")
|
|
#define RGAS_SNASERVER SZ("Software\\Microsoft\\SNA Server")
|
|
#define RGAS_SNA_PARAMETERS SZ("\\Parameters\\ExtraParameters")
|
|
#define RGAS_SNA_ADAPTERNAME SZ("AdapterName")
|
|
|
|
//
|
|
// UpgradeSNA()
|
|
//
|
|
|
|
BOOL FAR PASCAL NetSetupUpgradeSNA (
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
APIERR err = NERR_Success;
|
|
|
|
do {
|
|
|
|
NLS_STR nlsServices = RGAS_SERVICES_HOME;
|
|
|
|
// Open Local Machine and Service Key
|
|
|
|
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
|
|
REG_KEY regServices( rkLocalMachine, nlsServices );
|
|
|
|
if ((( err = rkLocalMachine.QueryError()) != NERR_Success ) ||
|
|
(( err = regServices.QueryError()) != NERR_Success ))
|
|
{
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("Cannot open service key.\n\r"));
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Make sure Sna Server Exist
|
|
//
|
|
|
|
NLS_STR nlsSnaServer = RGAS_SNASERVER;
|
|
REG_KEY regSnaServer( rkLocalMachine, nlsSnaServer );
|
|
if ( regSnaServer.QueryError() != NERR_Success )
|
|
{
|
|
// SNA Server does not exist
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("Cannot open SNA Server key.\n\r"));
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
// Enumerate all the Services and look for SNADLCX where X
|
|
// is a number or a letter from A to U
|
|
|
|
REG_ENUM regEnumServices( regServices );
|
|
|
|
if (( err = regEnumServices.QueryError()) != NERR_Success )
|
|
{
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("Cannot open Enum Services key.\n\r"));
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
REG_KEY_INFO_STRUCT regKeyInfo;
|
|
NLS_STR nlsSNADLC = RGAS_SNADLC;
|
|
ISTR istrEndSNADLC( nlsSNADLC );
|
|
UINT nLenSNADLC = nlsSNADLC.QueryNumChar();
|
|
istrEndSNADLC += nLenSNADLC;
|
|
|
|
while ( regEnumServices.NextSubKey( & regKeyInfo ) == NERR_Success )
|
|
{
|
|
// Looking for SNADLCX
|
|
|
|
if ( nlsSNADLC._strnicmp( regKeyInfo.nlsName, istrEndSNADLC ) == 0 )
|
|
{
|
|
if ( regKeyInfo.nlsName.QueryNumChar() == ( nLenSNADLC + 1 ))
|
|
{
|
|
// SnaDLCX services
|
|
// 1. Open SnaDLCX\Parameters
|
|
NLS_STR nlsSnaParameters = regKeyInfo.nlsName;
|
|
nlsSnaParameters += RGAS_SNA_PARAMETERS;
|
|
|
|
REG_KEY regSnaServices( regServices, nlsSnaParameters );
|
|
if ( regSnaServices.QueryError() != NERR_Success )
|
|
{
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("Cannot open Parameter key.\n"));
|
|
#endif
|
|
// if no ExtraParameters Key exist, look for next one
|
|
continue;
|
|
}
|
|
|
|
// 2. change the adapterName
|
|
NLS_STR nlsAdapterName;
|
|
NLS_STR nlsNewAdapterName;
|
|
|
|
regSnaServices.QueryValue( RGAS_SNA_ADAPTERNAME, &nlsAdapterName );
|
|
nlsNewAdapterName = nlsAdapterName;
|
|
|
|
ISTR istrStartAdapterName( nlsNewAdapterName );
|
|
ISTR istrEndAdapterName( nlsNewAdapterName );
|
|
istrStartAdapterName += nlsNewAdapterName.QueryNumChar() - 2;
|
|
istrEndAdapterName += nlsNewAdapterName.QueryNumChar() - 1;
|
|
if ( *(nlsNewAdapterName.QueryPch( istrStartAdapterName )) == TCH('0'))
|
|
{
|
|
nlsNewAdapterName.DelSubStr( istrStartAdapterName, istrEndAdapterName );
|
|
|
|
// check whether device exists or not
|
|
|
|
ISTR istrBackSlash( nlsNewAdapterName );
|
|
if ( nlsNewAdapterName.strrchr( &istrBackSlash, TCHAR('\\')))
|
|
{
|
|
++istrBackSlash;
|
|
NLS_STR *pnlsServices = nlsNewAdapterName.QuerySubStr( istrBackSlash );
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("\n\rNew Adapter Name:"));
|
|
OutputDebugString( pnlsServices->QueryPch());
|
|
#endif
|
|
|
|
REG_KEY regNewService( regServices, *pnlsServices );
|
|
if ( regNewService.QueryError() == NERR_Success )
|
|
{
|
|
// set the new adapter name if and only if the service exists
|
|
#ifdef DEBUG
|
|
OutputDebugString(SZ("\n\rWrite New Adapter Name for:"));
|
|
OutputDebugString( pnlsServices->QueryPch());
|
|
#endif
|
|
regSnaServices.SetValue( RGAS_SNA_ADAPTERNAME, nlsNewAdapterName );
|
|
}
|
|
delete pnlsServices;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( err != NERR_Success )
|
|
break;
|
|
|
|
} while (FALSE);
|
|
|
|
wsprintfA( g_achBuff, "{\"0\"}" );
|
|
*ppszResult = g_achBuff;
|
|
|
|
return err == NERR_Success;
|
|
}
|
|
|
|
/*
|
|
Upgrade.cxx
|
|
Upgrade the network component call out.
|
|
|
|
FILE HISTORY:
|
|
terryk 11/30/92 Created
|
|
|
|
*/
|
|
|
|
#define VALUEEXTRASIZE 100
|
|
|
|
APIERR CopyReg( REG_KEY &src, REG_KEY &dest )
|
|
{
|
|
REG_KEY_INFO_STRUCT rni ;
|
|
REG_KEY_CREATE_STRUCT regCreate;
|
|
REG_VALUE_INFO_STRUCT rvi ;
|
|
REG_ENUM regEnum( src ) ;
|
|
BYTE * pbValueData = NULL ;
|
|
APIERR errIter,
|
|
err = NERR_Success;
|
|
REG_KEY * pRnNew = NULL,
|
|
* pRnSub = NULL ;
|
|
|
|
LONG cbMaxValue ;
|
|
|
|
err = src.QueryInfo( & rni ) ;
|
|
if ( err )
|
|
return err ;
|
|
|
|
regCreate.dwTitleIndex = 0;
|
|
regCreate.ulOptions = REG_OPTION_NON_VOLATILE;
|
|
regCreate.nlsClass = RGAS_GENERIC_CLASS;
|
|
regCreate.regSam = MAXIMUM_ALLOWED;
|
|
regCreate.pSecAttr = NULL;
|
|
regCreate.ulDisposition = 0;
|
|
|
|
cbMaxValue = rni.ulMaxValueLen + VALUEEXTRASIZE ;
|
|
pbValueData = new BYTE [ cbMaxValue ] ;
|
|
|
|
if ( pbValueData == NULL )
|
|
return ERROR_NOT_ENOUGH_MEMORY ;
|
|
|
|
// Next, copy all value items to the new node.
|
|
|
|
rvi.pwcData = pbValueData ;
|
|
rvi.ulDataLength = cbMaxValue ;
|
|
|
|
err = errIter = 0 ;
|
|
while ( (errIter = regEnum.NextValue( & rvi )) == NERR_Success )
|
|
{
|
|
rvi.ulDataLength = rvi.ulDataLengthOut ;
|
|
if ( err = dest.SetValue( & rvi ) )
|
|
break ;
|
|
rvi.ulDataLength = cbMaxValue ;
|
|
}
|
|
|
|
// BUGBUG: Check for iteration errors other than 'finished'.
|
|
|
|
if ( err == 0 )
|
|
{
|
|
// Finally, recursively copy the subkeys.
|
|
|
|
regEnum.Reset() ;
|
|
|
|
err = errIter = 0 ;
|
|
|
|
while ( (errIter = regEnum.NextSubKey( & rni )) == NERR_Success )
|
|
{
|
|
// Open the subkey.
|
|
|
|
REG_KEY RegSubKey( dest, rni.nlsName, ®Create );
|
|
|
|
pRnSub = new REG_KEY( src, rni.nlsName );
|
|
|
|
if ( pRnSub == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
}
|
|
else
|
|
if ( (err = pRnSub->QueryError()) == 0 )
|
|
{
|
|
// Recurse
|
|
err = CopyReg( *pRnSub, RegSubKey ) ;
|
|
}
|
|
|
|
// Delete the subkey object and continue
|
|
|
|
delete pRnSub ;
|
|
|
|
if ( err )
|
|
break ;
|
|
}
|
|
}
|
|
|
|
delete pRnNew ;
|
|
delete pbValueData ;
|
|
|
|
return err ;
|
|
}
|
|
|
|
#define RGAS_SZ_NETWORK_CARD SZ("Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards")
|
|
#define RGAS_SZ_TITLE SZ("Title")
|
|
#define RGAS_SZ_SERVICE SZ("ServiceName")
|
|
#define RGAS_SZ_BINDFORM SZ("bindform")
|
|
#define RGAS_SZ_NETRULES SZ("NetRules")
|
|
#define RGAS_DLC_PARAMETERS SZ("DLC\\Parameters\\")
|
|
|
|
BOOL FAR PASCAL NetSetupUpgradeCardNum (
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
APIERR err = NERR_Success;
|
|
// static CHAR g_achBuff[200];
|
|
|
|
REG_KEY_CREATE_STRUCT regCreate;
|
|
|
|
regCreate.dwTitleIndex = 0;
|
|
regCreate.ulOptions = REG_OPTION_NON_VOLATILE;
|
|
regCreate.nlsClass = RGAS_GENERIC_CLASS;
|
|
regCreate.regSam = MAXIMUM_ALLOWED;
|
|
regCreate.pSecAttr = NULL;
|
|
regCreate.ulDisposition = 0;
|
|
|
|
do {
|
|
|
|
NLS_STR nlsNetworkCards = RGAS_SZ_NETWORK_CARD;
|
|
|
|
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
|
|
REG_KEY regNetworkCards( rkLocalMachine, nlsNetworkCards );
|
|
|
|
if ((( err = rkLocalMachine.QueryError()) != NERR_Success ) ||
|
|
(( err = regNetworkCards.QueryError()) != NERR_Success ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
REG_ENUM regEnumCards( regNetworkCards );
|
|
|
|
if (( err = regEnumCards.QueryError()) != NERR_Success )
|
|
{
|
|
break;
|
|
}
|
|
|
|
REG_KEY_INFO_STRUCT regKeyInfo;
|
|
STRLIST strCardList;
|
|
NLS_STR *pnlsCard = NULL;
|
|
|
|
while ( regEnumCards.NextSubKey( & regKeyInfo ) == NERR_Success )
|
|
{
|
|
pnlsCard = new NLS_STR( regKeyInfo.nlsName );
|
|
if ( pnlsCard != NULL )
|
|
{
|
|
strCardList.Append( pnlsCard );
|
|
} else
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( err != NERR_Success )
|
|
break;
|
|
|
|
ITER_STRLIST istrNetCard( strCardList );
|
|
|
|
while ( ( pnlsCard = istrNetCard.Next()) != NULL )
|
|
{
|
|
// check to see if the name is start with a 0
|
|
if ( *(pnlsCard->QueryPch()) == TCH('0') )
|
|
{
|
|
// do something about it
|
|
TCHAR szNewNum[3];
|
|
wsprintf( szNewNum, SZ("%s"), (pnlsCard->QueryPch() + 1) );
|
|
NLS_STR nlsNewNum = szNewNum;
|
|
|
|
REG_KEY regCard( regNetworkCards, *pnlsCard );
|
|
REG_KEY regNewCard( regNetworkCards, nlsNewNum, ®Create );
|
|
|
|
if ((( err = regNewCard.QueryError()) != NERR_Success ) ||
|
|
(( err = regCard.QueryError()) != NERR_Success ) ||
|
|
(( err = CopyReg( regCard, regNewCard )) != NERR_Success ) ||
|
|
// delete NetworkCards\0X
|
|
(( err = regCard.DeleteTree()) != NERR_Success ))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// change 0X\ServiceName
|
|
NLS_STR nlsServiceName;
|
|
NLS_STR nlsNewServiceName;
|
|
|
|
regNewCard.QueryValue( RGAS_SZ_SERVICE, &nlsServiceName );
|
|
|
|
nlsNewServiceName = nlsServiceName;
|
|
|
|
ISTR istrStartServiceName( nlsNewServiceName );
|
|
ISTR istrEndServiceName( nlsNewServiceName );
|
|
istrStartServiceName += nlsNewServiceName.QueryNumChar() - 2;
|
|
istrEndServiceName += nlsNewServiceName.QueryNumChar() - 1;
|
|
nlsNewServiceName.DelSubStr( istrStartServiceName, istrEndServiceName );
|
|
|
|
regNewCard.SetValue( RGAS_SZ_SERVICE, nlsNewServiceName );
|
|
|
|
// change 0X\Title
|
|
NLS_STR nlsTitle;
|
|
|
|
regNewCard.QueryValue( RGAS_SZ_TITLE, &nlsTitle );
|
|
ISTR istrStartTitle( nlsTitle );
|
|
ISTR istrEndTitle( nlsTitle );
|
|
istrStartTitle += 1;
|
|
istrEndTitle += 2;
|
|
|
|
nlsTitle.DelSubStr( istrStartTitle, istrEndTitle );
|
|
|
|
regNewCard.SetValue( RGAS_SZ_TITLE, nlsTitle );
|
|
|
|
// change 0x\NetRules\bindform
|
|
NLS_STR nlsNetRules = RGAS_SZ_NETRULES;
|
|
|
|
REG_KEY regNetRules( regNewCard, nlsNetRules );
|
|
if (( err = regNetRules.QueryError()) != NERR_Success )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
NLS_STR nlsBindForm;
|
|
|
|
regNetRules.QueryValue( RGAS_SZ_BINDFORM, &nlsBindForm );
|
|
|
|
ISTR istrStartBindForm( nlsBindForm );
|
|
ISTR istrEndBindForm( nlsBindForm );
|
|
ISTR istrTmp( nlsBindForm ); // temporary storage
|
|
ISTR istrHead( nlsBindForm ); // starting position for search
|
|
|
|
while (nlsBindForm.strstr( & istrTmp, *pnlsCard, istrHead ))
|
|
{
|
|
// advance to the next starting position
|
|
istrHead += pnlsCard->QueryNumChar();
|
|
|
|
// remember the last found
|
|
istrStartBindForm = istrTmp;
|
|
}
|
|
|
|
istrEndBindForm = istrStartBindForm;
|
|
istrEndBindForm += 1;
|
|
nlsBindForm.DelSubStr( istrStartBindForm, istrEndBindForm );
|
|
|
|
regNetRules.SetValue( RGAS_SZ_BINDFORM, nlsBindForm );
|
|
|
|
// change System\CurrentControlSet\Services\<ServiceName>
|
|
NLS_STR nlsServices = RGAS_SERVICES_HOME;
|
|
|
|
REG_KEY regServices( rkLocalMachine, nlsServices );
|
|
|
|
if (( err = regServices.QueryError()) != NERR_Success )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
REG_KEY regServiceName( regServices, nlsServiceName );
|
|
REG_KEY regNewServiceName( regServices, nlsNewServiceName, ®Create );
|
|
|
|
if ((( err = regServiceName.QueryError()) != NERR_Success ) ||
|
|
(( err = regNewServiceName.QueryError()) != NERR_Success ) ||
|
|
(( err = CopyReg( regServiceName, regNewServiceName )) != NERR_Success ) ||
|
|
// delete nlsServiceName
|
|
(( err = regServiceName.DeleteTree()) != NERR_Success ))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check whether DLC is installed or not
|
|
// if yes, update it
|
|
|
|
NLS_STR nlsOldDLCName = RGAS_DLC_PARAMETERS;
|
|
nlsOldDLCName += nlsServiceName;
|
|
NLS_STR nlsNewDLCName = RGAS_DLC_PARAMETERS;
|
|
nlsNewDLCName += nlsNewServiceName;
|
|
|
|
REG_KEY regOldDLCName( regServices, nlsOldDLCName );
|
|
REG_KEY regNewDLCName( regServices, nlsNewDLCName, ®Create );
|
|
|
|
|
|
if ((( err = regOldDLCName.QueryError()) != NERR_Success ) ||
|
|
(( err = regNewDLCName.QueryError()) != NERR_Success ) ||
|
|
(( err = CopyReg( regOldDLCName, regNewDLCName )) != NERR_Success ) ||
|
|
// delete nlsOldDLCName
|
|
(( err = regOldDLCName.DeleteTree()) != NERR_Success ))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
wsprintfA( g_achBuff, "{\"0\"}" );
|
|
*ppszResult = g_achBuff;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
PWSTR StrPathCleanW( PWSTR pszDest )
|
|
{
|
|
WCHAR pszSrc[MAX_PATH+1];
|
|
int iSrc = 0;
|
|
int iDest = 0;
|
|
|
|
// copy the buffer
|
|
lstrcpyW( pszSrc, pszDest );
|
|
|
|
// start writing over old buffer, could be null
|
|
// no need to do this since it was just a copy
|
|
// pszDest[iDest] = pszSrc[iSrc];
|
|
|
|
while (L'\0' != pszSrc[iSrc])
|
|
{
|
|
// remove double slashes only after the first two
|
|
while ( (iSrc > 0) &&
|
|
(L'\\' == pszSrc[iSrc]) &&
|
|
(L'\\' == pszSrc[iSrc+1]) )
|
|
{
|
|
iSrc++;
|
|
}
|
|
iSrc++;
|
|
iDest++;
|
|
|
|
pszDest[iDest] = pszSrc[iSrc];
|
|
}
|
|
return( pszDest );
|
|
}
|
|
//-------------------------------------------------------------------
|
|
|
|
PWSTR StrExstractNameW( PWSTR pszName, PWSTR pszSrc )
|
|
{
|
|
INT iSrc = lstrlenW( pszSrc ) - 1;
|
|
PWSTR pszTemp;
|
|
|
|
// from the end, find the first slash
|
|
pszTemp = wcsrchr( pszSrc, L'\\' );
|
|
|
|
if (NULL == pszTemp)
|
|
{
|
|
// no path
|
|
pszTemp = pszSrc;
|
|
}
|
|
else
|
|
{
|
|
// some path
|
|
// terminate the path
|
|
*pszTemp = L'\0';
|
|
pszTemp++;
|
|
|
|
}
|
|
// copy the name
|
|
lstrcpyW( pszName, pszTemp );
|
|
|
|
return( pszName );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
BOOL FAR PASCAL NetSetupCopySingleFile(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
BOOL frt = FALSE;
|
|
DWORD err = ERROR_BAD_ARGUMENTS;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your breakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
*ppszResult = g_achBuff;
|
|
|
|
if (nArgs == 3)
|
|
{
|
|
HWND hwnd = (HWND)strtoul( apszArgs[0], '\0', 16 ) ;
|
|
|
|
if (!IsWindow( hwnd ))
|
|
{
|
|
err = ERROR_INVALID_WINDOW_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
UINT errCopy = DPROMPT_CANCEL;
|
|
WCHAR pszSrc[MAX_PATH+1];
|
|
WCHAR pszDest[MAX_PATH+1];
|
|
WCHAR pszName[MAX_PATH+1];
|
|
|
|
// retrieve and convert the src and destination names, paths
|
|
MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[1], -1, pszSrc, MAX_PATH );
|
|
MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[2], -1, pszDest, MAX_PATH );
|
|
// lstrcpyA( pszSrc, apszArgs[1] );
|
|
// lstrcpyA( pszDest, apszArgs[2] );
|
|
|
|
// remove double slashes if present, but not if the first chars
|
|
StrPathCleanW( pszDest );
|
|
|
|
// all errors are user handled from here on
|
|
frt = TRUE;
|
|
|
|
do
|
|
{
|
|
// remove double slashes if present, but not if the first chars
|
|
StrPathCleanW( pszSrc );
|
|
|
|
err = SetupDecompressOrCopyFileW( pszSrc, pszDest, NULL );
|
|
if (ERROR_SUCCESS != err)
|
|
{
|
|
DWORD dwRequired;
|
|
|
|
// exstract just the filename from the src and modify
|
|
// src to be just the path
|
|
StrExstractNameW( pszName, pszSrc );
|
|
|
|
errCopy = SetupCopyErrorW( hwnd,
|
|
NULL,
|
|
NULL,
|
|
pszSrc,
|
|
pszName,
|
|
pszDest,
|
|
err,
|
|
0,
|
|
pszSrc,
|
|
MAX_PATH,
|
|
&dwRequired );
|
|
if (DPROMPT_SUCCESS == errCopy)
|
|
{
|
|
// replace filename on src
|
|
//
|
|
lstrcatW( pszSrc, L"\\" );
|
|
lstrcatW( pszSrc, pszName );
|
|
}
|
|
}
|
|
} while (DPROMPT_SUCCESS == errCopy);
|
|
}
|
|
}
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"}", err ) ;
|
|
return(frt);
|
|
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
LONG RegCopyKeyTree( HKEY hkeyDest, HKEY hkeySrc )
|
|
{
|
|
LONG lrt;
|
|
FILETIME ftLastWrite;
|
|
|
|
DWORD cchMaxSubKeyLen;
|
|
DWORD cchMaxClassLen;
|
|
DWORD cchMaxValueNameLen;
|
|
DWORD cbMaxValueLen;
|
|
|
|
DWORD iItem;
|
|
PWSTR pszName;
|
|
PWSTR pszClass;
|
|
PBYTE pbData;
|
|
|
|
DWORD cchName;
|
|
DWORD cchClass;
|
|
DWORD cbData;
|
|
|
|
HKEY hkeyChildDest;
|
|
HKEY hkeyChildSrc;
|
|
|
|
DWORD dwDisposition;
|
|
|
|
|
|
// find out the longest name and data field and create the buffers
|
|
// to store enumerations in
|
|
//
|
|
lrt = RegQueryInfoKey( hkeySrc,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&cchMaxSubKeyLen,
|
|
&cchMaxClassLen,
|
|
NULL,
|
|
&cchMaxValueNameLen,
|
|
&cbMaxValueLen,
|
|
NULL,
|
|
&ftLastWrite );
|
|
|
|
do
|
|
{
|
|
if (ERROR_SUCCESS != lrt)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// use only one buffer for all names, values or keys
|
|
cchMaxValueNameLen = max( cchMaxSubKeyLen, cchMaxValueNameLen );
|
|
|
|
|
|
// allocate buffers
|
|
lrt = ERROR_NOT_ENOUGH_MEMORY;
|
|
pszName = new WCHAR[ cchMaxValueNameLen + 1 ];
|
|
if (NULL == pszName)
|
|
{
|
|
break;
|
|
}
|
|
|
|
pszClass = new WCHAR[ cchMaxClassLen + 1 ];
|
|
if (NULL == pszClass)
|
|
{
|
|
delete [] pszName;
|
|
break;
|
|
}
|
|
|
|
pbData = new BYTE[ cbMaxValueLen ];
|
|
if (NULL == pbData)
|
|
{
|
|
delete [] pszName;
|
|
delete [] pszClass;
|
|
break;
|
|
}
|
|
|
|
lrt = ERROR_SUCCESS;
|
|
|
|
// enum all sub keys and copy them
|
|
//
|
|
iItem = 0;
|
|
do
|
|
{
|
|
cchName = cchMaxValueNameLen + 1;
|
|
cchClass = cchMaxClassLen + 1;
|
|
lrt = RegEnumKeyEx( hkeySrc, iItem, pszName, &cchName, NULL, pszClass, &cchClass, &ftLastWrite );
|
|
iItem++;
|
|
if (ERROR_SUCCESS == lrt)
|
|
{
|
|
// create key at destination
|
|
lrt = RegCreateKeyEx( hkeyDest,
|
|
pszName,
|
|
0,
|
|
pszClass,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyChildDest,
|
|
&dwDisposition );
|
|
if (ERROR_SUCCESS != lrt)
|
|
{
|
|
break;
|
|
}
|
|
// open the key at source
|
|
lrt = RegOpenKeyEx( hkeySrc, pszName, 0, KEY_ALL_ACCESS, &hkeyChildSrc );
|
|
if (ERROR_SUCCESS != lrt)
|
|
{
|
|
RegCloseKey( hkeyChildDest );
|
|
break;
|
|
}
|
|
|
|
// copy this sub-tree
|
|
lrt = RegCopyKeyTree( hkeyChildDest, hkeyChildSrc );
|
|
|
|
RegCloseKey( hkeyChildDest );
|
|
RegCloseKey( hkeyChildSrc );
|
|
}
|
|
|
|
} while (ERROR_SUCCESS == lrt);
|
|
|
|
|
|
if (ERROR_NO_MORE_ITEMS == lrt)
|
|
{
|
|
// enum completed, no errors
|
|
//
|
|
|
|
DWORD dwType;
|
|
// enum all values and copy them
|
|
//
|
|
iItem = 0;
|
|
do
|
|
{
|
|
cchName = cchMaxValueNameLen + 1;
|
|
cbData = cbMaxValueLen;
|
|
lrt = RegEnumValue( hkeySrc, iItem, pszName, &cchName, NULL, &dwType, pbData, &cbData );
|
|
iItem++;
|
|
if (ERROR_SUCCESS == lrt)
|
|
{
|
|
// write the value to the destination
|
|
lrt = RegSetValueEx( hkeyDest, pszName, 0, dwType, pbData, cbData );
|
|
}
|
|
} while (ERROR_SUCCESS == lrt);
|
|
|
|
if (ERROR_NO_MORE_ITEMS == lrt)
|
|
{
|
|
// if we hit the end of the enum without error
|
|
// reset error code to success
|
|
//
|
|
lrt = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
// free our buffers
|
|
delete [] pszName;
|
|
delete [] pszClass;
|
|
delete [] pbData;
|
|
} while ( FALSE );
|
|
return( lrt );
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
// [0] - handle to source key
|
|
// [1] - handle to destination key
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
const int MAXLEN_HANDLE = 32;
|
|
|
|
BOOL FAR PASCAL NetSetupRegCopyTree(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
DWORD err = ERROR_BAD_ARGUMENTS;
|
|
WCHAR pszHandle[MAXLEN_HANDLE+1];
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your breakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
*ppszResult = g_achBuff;
|
|
|
|
if (nArgs == 2)
|
|
{
|
|
mbstowcs( pszHandle, apszArgs[0], MAXLEN_HANDLE );
|
|
HKEY hkeySrc = CvtRegHandle( pszHandle ) ;
|
|
mbstowcs( pszHandle, apszArgs[1], MAXLEN_HANDLE );
|
|
HKEY hkeyDest = CvtRegHandle( pszHandle ) ;
|
|
|
|
if ( (NULL != hkeySrc) && (NULL != hkeyDest) )
|
|
{
|
|
err = RegCopyKeyTree( hkeyDest, hkeySrc );
|
|
}
|
|
}
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"}", err ) ;
|
|
return( 0 == err );
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
// apszArgs[0] - hwndNotify (hex)
|
|
// apszArgs[1] - message (decimal)
|
|
// apszArgs[2] - wParam Type 'A' - atom string, 'S' - string, 'D' - decimal, 'H' - hex
|
|
// apszArgs[3] - wParam, string containing wParam to convert as defined in type and pass in wParam
|
|
// apszArgs[4] - lParam Type 'A' - atom string, 'S' - string, 'D' - decimal, 'H' - hex
|
|
// apszArgs[5] - lParam, string containing lParam to convert as defined in type and pass in wParam
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
BOOL CreateParam( DWORD& dwParam, PSTR pszType, PSTR pszParam )
|
|
{
|
|
WCHAR pszText[MAX_PATH+1];
|
|
BOOL frt = TRUE;
|
|
|
|
switch (toupper( *pszType ))
|
|
{
|
|
case 'A':
|
|
MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, pszParam, -1, pszText, MAX_PATH );
|
|
dwParam = (DWORD)AddAtom( pszText );
|
|
break;
|
|
|
|
case 'S':
|
|
{
|
|
PWSTR pszTemp;
|
|
INT cchTemp;
|
|
cchTemp = lstrlenA( pszParam );
|
|
pszTemp = new WCHAR[ cchTemp + 1 ];
|
|
MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, pszParam, -1, pszTemp, cchTemp );
|
|
dwParam = (DWORD)pszTemp;
|
|
}
|
|
break;
|
|
|
|
case 'D':
|
|
dwParam = (DWORD)strtoul( pszParam, '\0', 10 ) ;
|
|
break;
|
|
|
|
case 'H':
|
|
dwParam = (DWORD)strtoul( pszParam, '\0', 16 ) ;
|
|
break;
|
|
|
|
default:
|
|
frt = FALSE;
|
|
break;
|
|
}
|
|
return( frt );
|
|
}
|
|
|
|
|
|
BOOL FAR PASCAL NetSetupSendProgressMessage(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
BOOL frt = FALSE;
|
|
DWORD err = ERROR_BAD_ARGUMENTS;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your breakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
*ppszResult = g_achBuff;
|
|
|
|
if (nArgs == 6)
|
|
{
|
|
HWND hwnd = (HWND)strtoul( apszArgs[1], '\0', 16 ) ;
|
|
|
|
if (!IsWindow( hwnd ))
|
|
{
|
|
err = ERROR_INVALID_WINDOW_HANDLE;
|
|
}
|
|
else
|
|
{
|
|
UINT msg = (UINT)strtoul( apszArgs[0], '\0', 10 ) ;
|
|
WCHAR pszwParam[MAX_PATH+1];
|
|
WCHAR pszlParam[MAX_PATH+1];
|
|
DWORD wParam;
|
|
DWORD lParam;
|
|
|
|
err = ERROR_BAD_ARGUMENTS;
|
|
do
|
|
{
|
|
if (!CreateParam( wParam, apszArgs[2], apszArgs[3] ))
|
|
{
|
|
break;
|
|
}
|
|
if (!CreateParam( lParam, apszArgs[4], apszArgs[5] ))
|
|
{
|
|
break;
|
|
}
|
|
PostMessage( hwnd, msg, wParam, lParam );
|
|
frt = TRUE;
|
|
err = 0;
|
|
|
|
} while (FALSE);
|
|
|
|
}
|
|
}
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"}", err ) ;
|
|
return(frt);
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
BOOL FAR PASCAL NetSetupAddNameSpaceProvider(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
BOOL frt = FALSE;
|
|
DWORD err = ERROR_BAD_ARGUMENTS;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your bz;reakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
*ppszResult = g_achBuff;
|
|
|
|
if (nArgs == 5)
|
|
{
|
|
do
|
|
{
|
|
GUID guidProvider;
|
|
WCHAR pszGuid[MAX_TEMP+1];
|
|
WCHAR pszDisplayName[MAX_TEMP+1];
|
|
WCHAR pszPathDLLName[MAX_TEMP+1];
|
|
DWORD dwNameSpace;
|
|
BOOL fSchemaSupport;
|
|
|
|
|
|
if (0 == MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[4], -1, pszGuid, MAX_TEMP ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (S_OK != IIDFromString( pszGuid, &guidProvider ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (0 == MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[0], -1, pszDisplayName, MAX_TEMP ))
|
|
{
|
|
break;
|
|
}
|
|
if (0 == MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[1], -1, pszPathDLLName, MAX_TEMP ))
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwNameSpace = (DWORD)strtoul( apszArgs[2], '\0', 10 ) ;
|
|
fSchemaSupport = (0 == lstrcmpiA( apszArgs[3], "TRUE" ));
|
|
|
|
err = WSCInstallNameSpace(pszDisplayName,
|
|
pszPathDLLName,
|
|
dwNameSpace,
|
|
fSchemaSupport,
|
|
&guidProvider);
|
|
} while (FALSE);
|
|
|
|
}
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"}", err ) ;
|
|
return(frt);
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
BOOL FAR PASCAL NetSetupRemoveNameSpaceProvider(
|
|
DWORD nArgs, // Number of string arguments
|
|
LPSTR apszArgs[], // The arguments, NULL-terminated
|
|
LPSTR * ppszResult ) // Result variable storage
|
|
{
|
|
BOOL frt = FALSE;
|
|
DWORD err = ERROR_BAD_ARGUMENTS;
|
|
|
|
// this can be used to debug the verify code
|
|
// MessageBox( NULL, L"Set your breakpoints now!", L"Helper Message", MB_APPLMODAL | MB_OK );
|
|
|
|
*ppszResult = g_achBuff;
|
|
|
|
if (nArgs == 1)
|
|
{
|
|
GUID guidProvider;
|
|
WCHAR pszGuid[MAX_TEMP+1];
|
|
|
|
if (0 != MultiByteToWideChar( CP_ACP ,MB_PRECOMPOSED, apszArgs[0], -1, pszGuid, MAX_TEMP ))
|
|
{
|
|
|
|
if (S_OK == IIDFromString( pszGuid, &guidProvider ))
|
|
{
|
|
if (ERROR_SUCCESS == WSCUnInstallNameSpace(&guidProvider))
|
|
{
|
|
err = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
::wsprintfA( g_achBuff, "{\"%ld\"}", err ) ;
|
|
return(frt);
|
|
|
|
}
|