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

684 lines
20 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
NBCPL.CXX: Netbios LANAnum handling interface
*/
#include "pchncpa.hxx" // Precompiled header
#include "ncpacpl.hxx"
#define DLG_NM_LANANUM MAKEINTRESOURCE(IDD_DLG_NM_LANANUM)
extern "C"
{
// exported functions
BOOL FAR PASCAL CPlAddMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL CPlDeleteMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL CPlBROWSER( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL CPlNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL CPlSetupLanaMap( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL EqualToXnsRoute( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL SetEnumExport( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL RemoveRouteFromNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
BOOL FAR PASCAL ConvertEndPointString( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
}
/* Global return buffer */
static CHAR achBuff[2000];
/*******************************************************************
NAME: RunNETBIOS
SYNOPSIS: Start the NETBIOS configuration dialog.
ENTRY: HWND hwnd - window handler from parent window
RETURN: APIERR - NERR_Success if okay.
HISTORY:
terryk 11-Nov-1992 Created
********************************************************************/
APIERR RunNETBIOS( HWND hwnd )
{
APIERR err ;
UINT errDlg ;
NETBIOS_DLG dlgNetbios( DLG_NM_LANANUM, hwnd );
do
{
if ( err = dlgNetbios.QueryError() )
break ;
if ( dlgNetbios.QueryNumRoute() == 0 )
{
MsgPopup( hwnd, IDS_NO_NETBIOS_INFO, MPSEV_WARNING, MP_OK );
break;
}
if ( err = dlgNetbios.Process( & errDlg ) )
break ;
err = errDlg ;
}
while ( FALSE ) ;
return err;
}
/*******************************************************************
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 CPlNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
APIERR err = NERR_Success ;
HWND hWnd = NULL;
TCHAR **patchArgs;
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = achBuff;
return FALSE;
}
// get window handle
if ( nArgs > 0 && patchArgs[0][0] != TCH('\0') )
{
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
}
else
{
hWnd = ::GetActiveWindow() ;
}
err = RunNETBIOS( hWnd ) ;
wsprintfA( achBuff, "{\"%d\"}", err );
*ppszResult = 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 CPlSetupLanaMap( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
wsprintfA( achBuff, "{\"0\"}" );
*ppszResult = 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 EqualToXnsRoute( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
BOOL fReturn = FALSE;
wsprintfA( achBuff, "0" );
if ( nArgs > 0 && apszArgs[0][0] != TCH('\0') )
{
fReturn = ((_strnicmp( apszArgs[0], "\"Xns", 4 ) == 0)||
(_strnicmp( apszArgs[0], "\"Ubnb", 5 ) == 0));
wsprintfA( achBuff, "%d", fReturn?1:0 );
}
*ppszResult = 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 SetEnumExport( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
TCHAR **patchArgs;
if (( nArgs != 2 ) || (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL ))
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = achBuff;
return FALSE;
}
SetEnum( patchArgs[0], patchArgs[1] );
wsprintfA( achBuff, "{\"0\"}" );
*ppszResult = 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 RemoveRouteFromNETBIOS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
TCHAR **patchArgs;
if (( nArgs != 1 ) || (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL ))
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = achBuff;
return FALSE;
}
RemoveRoute( patchArgs[0] );
wsprintfA( achBuff, "{\"0\"}" );
*ppszResult = achBuff;
FreeArgs( patchArgs, nArgs );
return TRUE;
}
/*******************************************************************
NAME: RunBROWSER
SYNOPSIS: Start the BROWSER configuration dialog.
ENTRY: HWND hwnd - window handler from parent window
RETURN: APIERR - NERR_Success if okay.
HISTORY:
terryk 11-Nov-1992 Created
********************************************************************/
APIERR RunBROWSER( HWND hwnd, BOOL *pfCancel )
{
APIERR err;
BROWSER_CONFIG_DIALOG dlgBrowser( hwnd );
BOOL fReturn;
if (( err = dlgBrowser.QueryError()) == NERR_Success )
{
if (( err = dlgBrowser.Process( & fReturn )) == NERR_Success )
{
if ( err != NERR_Success )
{
// dialog error
}
}
}
*pfCancel = !fReturn;
return err;
}
/*******************************************************************
NAME: CPlBROWSER
SYNOPSIS: Wrapper routine for calling RunBROWSER. 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 CPlBROWSER( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
APIERR err = NERR_Success ;
HWND hWnd = NULL;
TCHAR **patchArgs;
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = achBuff;
return FALSE;
}
// get window handle
if ( nArgs > 0 && patchArgs[0][0] != TCH('\0') )
{
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
}
else
{
hWnd = ::GetActiveWindow() ;
}
BOOL fCancel;
err = RunBROWSER( hWnd, &fCancel ) ;
if ( fCancel )
err = 1;
wsprintfA( achBuff, "{\"%d\"}", err );
*ppszResult = achBuff;
FreeArgs( patchArgs, nArgs );
return err == NERR_Success;
}
BOOL FAR PASCAL ConvertEndPointString( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
if ( nArgs != 2 )
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = 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( achBuff, "\"%s\" %s", apszArgs[0], achComponent );
*ppszResult = 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 CPlAddMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
NLS_STR nlsMonitorName;
MONITOR_INFO_2 MonitorInfo2;
APIERR err = NERR_Success;
do {
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( achBuff, "{\"%d\"}", err );
*ppszResult = achBuff;
return TRUE;
}
BOOL FAR PASCAL CPlDeleteMonitor( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
{
NLS_STR nlsMonitorName;
APIERR err = NERR_Success;
do {
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( achBuff, "{\"%d\"}", err );
*ppszResult = achBuff;
return TRUE;
}