From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/nw/nwscript/attach.c | 235 +++ private/nw/nwscript/break.c | 85 + private/nw/nwscript/capture.c | 1067 ++++++++++ private/nw/nwscript/common.c | 400 ++++ private/nw/nwscript/date.c | 78 + private/nw/nwscript/dbcs.c | 98 + private/nw/nwscript/display.c | 101 + private/nw/nwscript/drive.c | 327 +++ private/nw/nwscript/drvstat.c | 268 +++ private/nw/nwscript/env.c | 352 ++++ private/nw/nwscript/helpers.c | 96 + private/nw/nwscript/inc/common.h | 195 ++ private/nw/nwscript/inc/dbcs.h | 26 + private/nw/nwscript/inc/ntnw.h | 46 + private/nw/nwscript/inc/nwlibs.h | 371 ++++ private/nw/nwscript/inc/nwscript.h | 321 +++ private/nw/nwscript/lsparse.c | 315 +++ private/nw/nwscript/makefile | 6 + private/nw/nwscript/maplist.c | 252 +++ private/nw/nwscript/ncp.c | 356 ++++ private/nw/nwscript/nds.c | 1505 ++++++++++++++ private/nw/nwscript/nt.c | 617 ++++++ private/nw/nwscript/ntcap.c | 329 +++ private/nw/nwscript/ntnw.c | 163 ++ private/nw/nwscript/ntscript.c | 304 +++ private/nw/nwscript/nwapi1.c | 47 + private/nw/nwscript/nwapi2.c | 49 + private/nw/nwscript/nwapi3.c | 1457 +++++++++++++ private/nw/nwscript/nwscript.c | 84 + private/nw/nwscript/nwscript.rc | 243 +++ private/nw/nwscript/parspath.c | 341 ++++ private/nw/nwscript/ps40db.c | 597 ++++++ private/nw/nwscript/psdb.c | 396 ++++ private/nw/nwscript/script.c | 3968 ++++++++++++++++++++++++++++++++++++ private/nw/nwscript/sources | 85 + private/nw/nwscript/strings.c | 132 ++ private/nw/nwscript/time.c | 184 ++ private/nw/nwscript/unc.c | 142 ++ private/nw/nwscript/version.c | 68 + private/nw/nwscript/wide.c | 149 ++ 40 files changed, 15855 insertions(+) create mode 100644 private/nw/nwscript/attach.c create mode 100644 private/nw/nwscript/break.c create mode 100644 private/nw/nwscript/capture.c create mode 100644 private/nw/nwscript/common.c create mode 100644 private/nw/nwscript/date.c create mode 100644 private/nw/nwscript/dbcs.c create mode 100644 private/nw/nwscript/display.c create mode 100644 private/nw/nwscript/drive.c create mode 100644 private/nw/nwscript/drvstat.c create mode 100644 private/nw/nwscript/env.c create mode 100644 private/nw/nwscript/helpers.c create mode 100644 private/nw/nwscript/inc/common.h create mode 100644 private/nw/nwscript/inc/dbcs.h create mode 100644 private/nw/nwscript/inc/ntnw.h create mode 100644 private/nw/nwscript/inc/nwlibs.h create mode 100644 private/nw/nwscript/inc/nwscript.h create mode 100644 private/nw/nwscript/lsparse.c create mode 100644 private/nw/nwscript/makefile create mode 100644 private/nw/nwscript/maplist.c create mode 100644 private/nw/nwscript/ncp.c create mode 100644 private/nw/nwscript/nds.c create mode 100644 private/nw/nwscript/nt.c create mode 100644 private/nw/nwscript/ntcap.c create mode 100644 private/nw/nwscript/ntnw.c create mode 100644 private/nw/nwscript/ntscript.c create mode 100644 private/nw/nwscript/nwapi1.c create mode 100644 private/nw/nwscript/nwapi2.c create mode 100644 private/nw/nwscript/nwapi3.c create mode 100644 private/nw/nwscript/nwscript.c create mode 100644 private/nw/nwscript/nwscript.rc create mode 100644 private/nw/nwscript/parspath.c create mode 100644 private/nw/nwscript/ps40db.c create mode 100644 private/nw/nwscript/psdb.c create mode 100644 private/nw/nwscript/script.c create mode 100644 private/nw/nwscript/sources create mode 100644 private/nw/nwscript/strings.c create mode 100644 private/nw/nwscript/time.c create mode 100644 private/nw/nwscript/unc.c create mode 100644 private/nw/nwscript/version.c create mode 100644 private/nw/nwscript/wide.c (limited to 'private/nw/nwscript') diff --git a/private/nw/nwscript/attach.c b/private/nw/nwscript/attach.c new file mode 100644 index 000000000..fa6cacc75 --- /dev/null +++ b/private/nw/nwscript/attach.c @@ -0,0 +1,235 @@ +/************************************************************************* +* +* ATTACH.C +* +* NT Attach routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\ATTACH.C $ +* +* Rev 1.2 10 Apr 1996 14:21:30 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:52:08 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:23:32 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:26 terryt +* Initial revision. +* +* Rev 1.1 23 May 1995 19:36:30 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:10 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "inc/common.h" +#include "ntnw.h" + +/******************************************************************** + + GetDefaultConnectionID + +Routine Description: + + Return the default connection ID ( the "preferred server" ) + +Arguments: + + phNewConn - pointer to connection number + +Return Value: + 0 = success + else NetWare error number + + *******************************************************************/ +unsigned int +GetDefaultConnectionID( + unsigned int *phNewConn + ) +{ + VERSION_INFO VerInfo; + unsigned int Result; + + if ( fNDS ) + { + Result = NTAttachToFileServer( NDSTREE, phNewConn ); + } + else + { + // + // "*" is the name for the preferred server + // + Result = NTAttachToFileServer( "*", phNewConn ); + if ( Result ) + return Result; + + Result = NWGetFileServerVersionInfo( (NWCONN_HANDLE)*phNewConn, + &VerInfo ); + if ( Result ) + return Result; + + NWDetachFromFileServer( (NWCONN_HANDLE)*phNewConn ); + + Result = NTAttachToFileServer( VerInfo.szName, phNewConn ); + } + return Result; + +} + +/******************************************************************** + + NTAttachToFileServer + +Routine Description: + + Given a server name, return a connection handle. + We need our own because NWAPI32 does it's own mapping + of errors. + +Arguments: + + pszServerName - Ascii server name + phNewConn - pointer to connection handle + +Return Value: + 0 = success + else NetWare error number + + *******************************************************************/ +unsigned int +NTAttachToFileServer( + unsigned char *pszServerName, + unsigned int *phNewConn + ) +{ + return ( NWAttachToFileServer( pszServerName, 0, + (NWCONN_HANDLE *)phNewConn ) ); +} + + +/******************************************************************** + + NTIsConnected + +Routine Description: + + Given a server name, is there already a connection to it? + +Arguments: + + pszServerName - ascii server name + +Return Value: + TRUE - a connection to the server exists + FALSE - a connection to the server does not exist + + *******************************************************************/ +unsigned int +NTIsConnected( unsigned char * pszServerName ) +{ + LPBYTE Buffer ; + DWORD dwErr ; + HANDLE EnumHandle ; + DWORD Count ; + LPWSTR pszServerNameW; + INT nSize; + DWORD BufferSize = 4096; + + nSize = (strlen( pszServerName ) + 1 + 2) * sizeof( WCHAR ); + + // + // allocate memory and open the enumeration + // + if (!(pszServerNameW = LocalAlloc( LPTR, nSize ))) { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + wcscpy( pszServerNameW, L"\\\\" ); + szToWide( pszServerNameW + 2, pszServerName, nSize ); + + // + // allocate memory and open the enumeration + // + if (!(Buffer = LocalAlloc( LPTR, BufferSize ))) { + (void) LocalFree((HLOCAL) pszServerNameW) ; + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memset( Buffer, 0, BufferSize ); + + dwErr = NPOpenEnum(RESOURCE_CONNECTED, 0, 0, NULL, &EnumHandle) ; + if (dwErr != WN_SUCCESS) { + (void) LocalFree((HLOCAL) pszServerNameW) ; + (void) LocalFree((HLOCAL) Buffer) ; + return FALSE; + } + + do { + + Count = 0xFFFFFFFF ; + BufferSize = 4096; + dwErr = NwEnumConnections(EnumHandle, &Count, Buffer, &BufferSize, TRUE) ; + + if ((dwErr == WN_SUCCESS || dwErr == WN_NO_MORE_ENTRIES) + && ( Count != 0xFFFFFFFF) ) + { + LPNETRESOURCE lpNetResource ; + DWORD i ; + DWORD ServerLen; + + ServerLen = wcslen( pszServerNameW ); + lpNetResource = (LPNETRESOURCE) Buffer ; + // + // search for our server + // + for ( i = 0; i < Count; lpNetResource++, i++ ) + { + if ( lpNetResource->lpProvider ) + if ( _wcsicmp( lpNetResource->lpProvider, NW_PROVIDER ) ) { + continue; + } + if ( lpNetResource->lpRemoteName ) { + if ( wcslen(lpNetResource->lpRemoteName) > ServerLen ) { + if ( lpNetResource->lpRemoteName[ServerLen] == L'\\' ) + lpNetResource->lpRemoteName[ServerLen] = L'\0'; + } + if ( !_wcsicmp(lpNetResource->lpRemoteName, pszServerNameW )) { + (void) WNetCloseEnum(EnumHandle) ; + (void) LocalFree((HLOCAL) pszServerNameW) ; + (void) LocalFree((HLOCAL) Buffer) ; + return TRUE; + } + } + } + + } + + } while (dwErr == WN_SUCCESS) ; + + (void ) WNetCloseEnum(EnumHandle) ; + (void) LocalFree((HLOCAL) pszServerNameW) ; + (void) LocalFree((HLOCAL) Buffer) ; + + return FALSE; +} diff --git a/private/nw/nwscript/break.c b/private/nw/nwscript/break.c new file mode 100644 index 000000000..30af584db --- /dev/null +++ b/private/nw/nwscript/break.c @@ -0,0 +1,85 @@ +/************************************************************************* +* +* BREAK.C +* +* Control-C and Control-Break routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\BREAK.C $ +* +* Rev 1.2 10 Apr 1996 14:21:38 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:52:16 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:23:38 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:28 terryt +* Initial revision. +* +* Rev 1.0 15 May 1995 19:10:14 terryt +* Initial revision. +* +*************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nwscript.h" +#include "ntnw.h" + + +/* + * Handler for console events + */ +BOOL WINAPI +Handler( DWORD CtrlType ) +{ + if ( CtrlType & ( CTRL_C_EVENT | CTRL_BREAK_EVENT ) ) + return TRUE; /* don't execute default handler */ +} + +/* + * NTBreakOn + * + * Routine Description: + * + * Allow Ctrl+C and Ctrl+Break during logon script + * + * Arguments: + * none + * + * Return Value: + * none + */ +void NTBreakOn( void ) +{ + (void) SetConsoleCtrlHandler( &Handler, FALSE ); +} + +/* + * NTBreakOff + * + * Routine Description: + * + * Prevent Ctrl+C and Ctrl+Break during logon script + * + * Arguments: + * none + * + * Return Value: + * none + */ +void NTBreakOff( void ) +{ + (void) SetConsoleCtrlHandler( &Handler, TRUE ); +} diff --git a/private/nw/nwscript/capture.c b/private/nw/nwscript/capture.c new file mode 100644 index 000000000..b89df1480 --- /dev/null +++ b/private/nw/nwscript/capture.c @@ -0,0 +1,1067 @@ +/* + * Module Name: + * capture.c + * Copyright (c) 1995 Microsoft Corporation + * + * Abstract: + * + * SYNTAX (Command line) + * - Usage: Capture [/Options] + * + * Author : Congpa You (Congpay) + * + * Revision history : + * - 05/24/94 congpay Created + */ + +#include "common.h" + +extern char *RemoveSpaces (char * buffer); + +typedef struct _CAPTURE_PARAMS { + UCHAR nLPT; + char serverName[MAX_NAME_LEN]; + char queueName[MAX_QUEUE_NAME_LEN]; + char bannerUserName[MAX_BANNER_USER_NAME]; + char filePath[_MAX_PATH]; + unsigned int NDSCapture; + NETWARE_CAPTURE_FLAGS_RW captureFlagsRW; +}CAPTURE_PARAMS, *PCAPTURE_PARAMS; + +/* Local Functions*/ +void UpcaseArg(int argc, char ** argv); +int IsShowOption (int argc, char ** argv); +int IsServerSpecified (int argc, char ** argv); +int IsNoOption (char * option); +int IsQuestionMark (int argc, char ** argv); +int IsValidOption (char *input, char *option, char *shortoption); +void ShowCapture(void); + +void GetJobNameFromArg (int argc, char ** argv, char *jobName); + +int InitCaptureParams (unsigned int conn, + char *jobName, + PCAPTURE_PARAMS pCaptureParams); + +int ReadArguments (int argc, + char ** argv, + char *jobName, + PCAPTURE_PARAMS pCaptureParams); + +int CStartCapture(unsigned int conn, + PCAPTURE_PARAMS pCaptureParams); + +int GetPrinterDefaultQueue( PCAPTURE_PARAMS, PBYTE ); + +void +Capture (char ** argv, unsigned int argc) +{ + char jobName[MAX_JOB_NAME_LEN]=""; + CAPTURE_PARAMS captureParams; + unsigned int conn; + + UpcaseArg(argc, argv); + + memset( (PBYTE)&captureParams, 0, sizeof(captureParams) ); + + captureParams.nLPT = 0; + captureParams.serverName[0] = 0; + captureParams.queueName[0] = 0; + captureParams.bannerUserName[0] = 0; + captureParams.filePath[0] = 0; + + if ( fNDS ) + { + captureParams.NDSCapture = TRUE; + } + else + { + captureParams.NDSCapture = FALSE; + } + + if ( IsServerSpecified( argc, argv ) ) + captureParams.NDSCapture = FALSE; + + // If the option is show, show the current capture settings. + if (IsShowOption (argc, argv)) + { + ShowCapture(); + return; + } + + // If the option is ?, show the usage. + if (IsQuestionMark(argc, argv)) + { + DisplayMessage(IDR_CAPTURE_USAGE); + return; + } + + // If /Job=jobname is in the parameter, get the jobname. + GetJobNameFromArg (argc, argv, jobName); + + if (!CGetDefaultConnectionID (&conn) || + !InitCaptureParams (conn, jobName, &captureParams) || + !ReadArguments (argc, + argv, + jobName, + &captureParams)) + return; + + // Terminate old capture. + EndCapture ((unsigned char) captureParams.nLPT); + + (void) CStartCapture(conn, &captureParams); + return; +} + +void UpcaseArg(int argc, char ** argv) +{ + int i; + for (i = 0; i < argc ; i++) + _strupr (argv[i]); +} + +/* + Return TRUE if input is /Show option. + FALSE otherwise. + */ +int IsShowOption (int argc,char ** argv) +{ + int bIsShowOption = FALSE; + char * p; + + if (argc == 2) + { + p = argv[1]; + while ((*p == '/') || (*p == '\\') || (*p == '-')) + p++; + + if (!strncmp (p, __SHOW__, max (2, strlen(p)))) + bIsShowOption = TRUE; + } + + return(bIsShowOption); +} + +/* + Return TRUE if input is /? option. + FALSE otherwise. + */ +int IsQuestionMark (int argc, char ** argv) +{ + int bIsQuestionMark = FALSE; + char * p; + + if (argc == 2) + { + p = argv[1]; + while ((*p == '/') || (*p == '\\') || (*p == '-')) + p++; + + if (*p == '?') + bIsQuestionMark = TRUE; + } + + return(bIsQuestionMark); +} + +int IsNoOption (char * option) +{ + int bIsNoOption = FALSE; + char * p; + + p = option; + while ((*p == '/') || (*p == '\\') || (*p == '-')) + p++; + + if (!strncmp (p, __OPT_NO__, max (1, strlen(p)))) + bIsNoOption = TRUE; + + return(bIsNoOption); +} + +/* + Return TRUE if the input match option or shortoption. + FALSE otherwise. + */ +int IsValidOption (char *input, char *option, char *shortoption) +{ + int bValideInput = FALSE; + + while ((*input == '/') || (*input == '\\') || (*input == '-')) + input++; + + if (!strcmp (input, shortoption)) + { + bValideInput = TRUE; + } + else if (!strcmp (input, option)) + { + bValideInput = TRUE; + } + + return(bValideInput); +} + +void GetJobNameFromArg (int argc, char ** argv, char *jobName) +{ + int i; + char *pEqual; + + for (i = 0; i < argc; i++) + { + if (pEqual = strchr (argv[i], '=')) + { + *pEqual = 0; + + if (IsValidOption (argv[i], __JOB__, __SHORT_FOR_JOB__) && + *(pEqual+1) != 0 && + strlen (pEqual+1) < MAX_JOB_NAME_LEN) + strcpy (jobName, pEqual+1); + + *pEqual = '='; + } + } + + return; +} + +int IsServerSpecified (int argc, char ** argv) +{ + int i; + + for (i = 0; i < argc; i++) + { + if (IsValidOption (argv[i], __SERVER__, __SHORT_FOR_SERVER__)) + return TRUE; + } + + return FALSE; + +} + +/* + Initialize the capture flags with job config or default value. + */ +int InitCaptureParams (unsigned int conn, + char *jobName, + PCAPTURE_PARAMS pCaptureParams) +{ + PS_JOB_RECORD psJobRecord; + unsigned int iRet = 0; + + // Get job configuration. + if (jobName[0] == 0) + { + // Get Default Job Name. + if ( Is40Server( conn ) ) + { + iRet = PS40JobGetDefault( pCaptureParams->NDSCapture, + 0, + NULL, + jobName, + &psJobRecord ); + } + else + { + iRet = PSJobGetDefault( conn, + 0, + NULL, + jobName, + &psJobRecord ); + } + + if ( iRet ) + { + if (iRet == PS_ERR_OPENING_DB || iRet == PS_ERR_GETTING_DEFAULT) + { + pCaptureParams->nLPT = 1; + pCaptureParams->bannerUserName[0]=0; + pCaptureParams->serverName[0]=0; + pCaptureParams->queueName[0]=0; + pCaptureParams->filePath[0]=0; + + pCaptureParams->captureFlagsRW.JobControlFlags = 0; + pCaptureParams->captureFlagsRW.TabSize = 8; + pCaptureParams->captureFlagsRW.NumCopies = 1; + pCaptureParams->captureFlagsRW.PrintFlags = DEFAULT_PRINT_FLAGS; + pCaptureParams->captureFlagsRW.FormName[0] = 0; + pCaptureParams->captureFlagsRW.FormType = 0; + pCaptureParams->captureFlagsRW.FlushCaptureTimeout = 0; + pCaptureParams->captureFlagsRW.FlushCaptureOnClose = 0; + + strcpy (pCaptureParams->captureFlagsRW.BannerText, DEFAULT_BANNER_TEXT); + return(TRUE); + } + else + { + DisplayError (iRet, "PSJobGetDefault"); + return(FALSE); + } + } + } + else + { + if ( Is40Server( conn ) ) + { + iRet = PS40JobRead( pCaptureParams->NDSCapture, + NULL, + jobName, + &psJobRecord); + } + else + { + iRet = PSJobRead(conn, + NULL, + jobName, + &psJobRecord); + } + if ( iRet ) + { + if ( ( iRet == PS_ERR_READING_RECORD) || + ( iRet == PS_ERR_OPENING_DB) ) + DisplayMessage(IDR_JOB_NOT_FOUND, jobName); + else + DisplayError (iRet, "PSJobRead"); + return(FALSE); + } + } + + pCaptureParams->captureFlagsRW.JobControlFlags = 0; + pCaptureParams->captureFlagsRW.TabSize = psJobRecord.TabSize; + pCaptureParams->captureFlagsRW.NumCopies = psJobRecord.Copies; + + pCaptureParams->captureFlagsRW.PrintFlags = + ((psJobRecord.PrintJobFlag & PS_JOB_EXPAND_TABS)? 0 : CAPTURE_FLAG_EXPAND_TABS) + +((psJobRecord.PrintJobFlag & PS_JOB_NO_FORMFEED)? CAPTURE_FLAG_NO_FORMFEED : 0) + +((psJobRecord.PrintJobFlag & PS_JOB_NOTIFY)? CAPTURE_FLAG_NOTIFY : 0) + +((psJobRecord.PrintJobFlag & PS_JOB_PRINT_BANNER)? CAPTURE_FLAG_PRINT_BANNER : 0); + + pCaptureParams->captureFlagsRW.FormType = 0; + pCaptureParams->captureFlagsRW.FlushCaptureTimeout = psJobRecord.TimeOutCount; + pCaptureParams->captureFlagsRW.FlushCaptureOnClose = !(psJobRecord.PrintJobFlag & PS_JOB_AUTO_END); + + strcpy (pCaptureParams->captureFlagsRW.FormName, psJobRecord.FormName); + strcpy (pCaptureParams->captureFlagsRW.BannerText, (psJobRecord.BannerName[0] == 0)? DEFAULT_BANNER_TEXT : psJobRecord.BannerName); + + pCaptureParams->nLPT = psJobRecord.LocalPrinter; + strcpy (pCaptureParams->bannerUserName, psJobRecord.Name); + if ( psJobRecord.PrintJobFlag & PS_JOB_ENV_DS ) { + strcpy (pCaptureParams->serverName, ""); + if ( psJobRecord.PrintJobFlag & PS_JOB_DS_PRINTER ) + GetPrinterDefaultQueue( pCaptureParams, psJobRecord.u.DSObjectName ); + else + strcpy (pCaptureParams->queueName, psJobRecord.u.DSObjectName ); + } + else { + strcpy (pCaptureParams->serverName, psJobRecord.u.NonDS.FileServer); + strcpy (pCaptureParams->queueName, psJobRecord.u.NonDS.PrintQueue); + } + pCaptureParams->filePath[0]=0; + + return(TRUE); +} + +int ReadArguments (int argc, + char ** argv, + char *jobName, + PCAPTURE_PARAMS pCaptureParams) +{ + int i, fValidOption = TRUE, fValidParam = TRUE; + char *pEqual = NULL; + + for (i = 1; i < argc; i++) + { + if (IsNoOption(argv[i])) + { + if (i != argc - 1) + { + i++; + + if (IsValidOption (argv[i], __NOTIFY__, __SHORT_FOR_NOTIFY__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF-CAPTURE_FLAG_NOTIFY); + } + else if (IsValidOption (argv[i], __AUTOENDCAP__, __SHORT_FOR_AUTOENDCAP__)) + { + pCaptureParams->captureFlagsRW.FlushCaptureOnClose = 1; + } + else if (IsValidOption (argv[i], __TABS__, __SHORT_FOR_TABS__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_EXPAND_TABS); + } + else if (IsValidOption (argv[i], __BANNER__, __SHORT_FOR_BANNER__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_PRINT_BANNER); + } + else if (IsValidOption (argv[i], __FORMFEED__, __SHORT_FOR_FORMFEED__)) + { + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_NO_FORMFEED; + } + else + { + i--; + fValidOption = FALSE; + break; + } + } + else + { + fValidOption = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __NOTIFY__, __SHORT_FOR_NOTIFY__)) + { + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_NOTIFY; + } + else if (IsValidOption (argv[i], __NONOTIFY__, __SHORT_FOR_NONOTIFY__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_NOTIFY); + } + else if (IsValidOption (argv[i], __AUTOENDCAP__, __SHORT_FOR_AUTOENDCAP__)) + { + pCaptureParams->captureFlagsRW.FlushCaptureOnClose = 0; + } + else if (IsValidOption (argv[i], __NOAUTOENDCAP__, __SHORT_FOR_NOAUTOENDCAP__)) + { + pCaptureParams->captureFlagsRW.FlushCaptureOnClose = 1; + } + else if (IsValidOption (argv[i], __NOTABS__, __SHORT_FOR_NOTABS__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_EXPAND_TABS); + } + else if (IsValidOption (argv[i], __NOBANNER__, __SHORT_FOR_NOBANNER__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_PRINT_BANNER); + } + else if (IsValidOption (argv[i], __FORMFEED__, __SHORT_FOR_FORMFEED__)) + { + pCaptureParams->captureFlagsRW.PrintFlags &= (0xFF - CAPTURE_FLAG_NO_FORMFEED); + } + else if (IsValidOption (argv[i], __NOFORMFEED__, __SHORT_FOR_NOFORMFEED__)) + { + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_NO_FORMFEED; + } + else if (IsValidOption (argv[i], __KEEP__, __SHORT_FOR_KEEP__)) + { + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_KEEP; + } + else + { + // All other valid options should have '=' sign in it. + // Except for LX LPX LPTX + // + pEqual = strchr (argv[i], '='); + + // Optionally a ':' works too + if (pEqual == NULL ) { + pEqual = strchr (argv[i], ':'); + } + + if (pEqual != NULL) + *pEqual = 0; + + if (IsValidOption (argv[i], __TIMEOUT__, __SHORT_FOR_TIMEOUT__)) + { + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_TIME_OUT_EXPECTED); + fValidParam = FALSE; + break; + } + + pCaptureParams->captureFlagsRW.FlushCaptureTimeout = atoi (pEqual+1); + + if (pCaptureParams->captureFlagsRW.FlushCaptureTimeout > 1000) + { + DisplayMessage(IDR_TIMEOUT_OUTOF_RANGE); + fValidParam = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __LOCAL__, __SHORT_FOR_LOCAL__)) + { + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_LPT_NUMBER_EXPECTED); + fValidParam = FALSE; + break; + } + + pCaptureParams->nLPT = (unsigned char) atoi (pEqual+1); + + if (pCaptureParams->nLPT < 1 || pCaptureParams->nLPT > 3) + { + DisplayMessage(IDR_INVALID_LPT_NUMBER); + fValidParam = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __LOCAL_3__, __LOCAL_2__)) + { + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_LPT_NUMBER_EXPECTED); + fValidParam = FALSE; + break; + } + + pCaptureParams->nLPT = (unsigned char) atoi (pEqual+1); + + if (pCaptureParams->nLPT < 1 || pCaptureParams->nLPT > 3) + { + DisplayMessage(IDR_INVALID_LPT_NUMBER); + fValidParam = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __JOB__, __SHORT_FOR_JOB__)) + { + if (pEqual == NULL || + *(pEqual+1) == 0 || + strlen (pEqual+1) > MAX_JOB_NAME_LEN - 1) + { + fValidOption = FALSE; + break; + } + strcpy (jobName, pEqual+1); + } + else if (IsValidOption (argv[i], __SERVER__, __SHORT_FOR_SERVER__)) + { + if (pEqual == NULL || + *(pEqual+1) == 0 || + strlen (pEqual+1) > MAX_NAME_LEN - 1) + { + fValidOption = FALSE; + break; + } + pCaptureParams->NDSCapture = FALSE; + strcpy (pCaptureParams->serverName, pEqual+1); + } + else if (IsValidOption (argv[i], __QUEUE__, __SHORT_FOR_QUEUE__)) + { + if (pEqual == NULL || + *(pEqual+1) == 0 || + strlen (pEqual+1) > MAX_QUEUE_NAME_LEN - 1) //compatible. + { + fValidOption = FALSE; + break; + } + strcpy (pCaptureParams->queueName, pEqual+1); + } + else if (IsValidOption (argv[i], __PRINTER__, __SHORT_FOR_PRINTER__)) + { + if (pEqual == NULL || + *(pEqual+1) == 0 || + !pCaptureParams->NDSCapture || + strlen (pEqual+1) > MAX_QUEUE_NAME_LEN - 1) //compatible. + { + fValidOption = FALSE; + break; + } + GetPrinterDefaultQueue( pCaptureParams, pEqual+1 ); + } + else if (IsValidOption (argv[i], __CREATE__, __SHORT_FOR_CREATE__)) + { + if (pEqual != NULL) //compatible. + { + if (strlen (pEqual+1) > _MAX_PATH - 1) + { + DisplayMessage(IDR_INVALID_PATH_NAME, pEqual+1); + fValidParam = FALSE; + break; + } + strcpy (pCaptureParams->filePath, pEqual+1); + } + } + else if (IsValidOption (argv[i], __FORM__, __SHORT_FOR_FORM__)) + { + int j = 1; + int bAllNumbers = TRUE; + + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_FORM_EXPECTED); + fValidParam = FALSE; + break; + } + + if (strlen (pEqual+1) > 3) // Only allow 3 digits number. + { + DisplayMessage(IDR_INVALID_FORM_NAME, pEqual+1); + fValidParam = FALSE; + break; + } + + while (*(pEqual+j) != 0) + { + if (!isdigit (*(pEqual+j))) + { + bAllNumbers = FALSE; + break; + } + j++; + } + + if (bAllNumbers) + { + pCaptureParams->captureFlagsRW.FormType = atoi (pEqual+1); + + if (pCaptureParams->captureFlagsRW.FormType > 255) + { + DisplayMessage(IDR_INVALID_FORM_TYPE); + fValidParam = FALSE; + break; + } + } + else + { + DisplayMessage(IDR_INVALID_FORM_NAME, pEqual+1); + fValidParam = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __COPIES__, __SHORT_FOR_COPIES__)) + { + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_COPIES_EXPECTED); + fValidParam = FALSE; + break; + } + + pCaptureParams->captureFlagsRW.NumCopies = atoi (pEqual+1); + + if (pCaptureParams->captureFlagsRW.NumCopies < 1 || + pCaptureParams->captureFlagsRW.NumCopies > 255) + { + DisplayMessage(IDR_COPIES_OUTOF_RANGE); + fValidParam = FALSE; + break; + } + } + else if (IsValidOption (argv[i], __TABS__, __SHORT_FOR_TABS__)) + { + if (pEqual == NULL || *(pEqual+1) == 0) + { + DisplayMessage(IDR_TAB_SIZE_EXPECTED); + fValidParam = FALSE; + break; + } + + pCaptureParams->captureFlagsRW.TabSize = (BYTE) atoi (pEqual+1); + + if (pCaptureParams->captureFlagsRW.TabSize < 1 || + pCaptureParams->captureFlagsRW.TabSize > 18) + { + DisplayMessage(IDR_TABSIZE_OUTOF_RANGE); + fValidParam = FALSE; + break; + } + + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_EXPAND_TABS; + } + else if (IsValidOption (argv[i], __NAME__, __SHORT_FOR_NAME__)) + { + if (pEqual == NULL || + *(pEqual+1) == 0 || + strlen (pEqual+1) > MAX_BANNER_USER_NAME - 1) + { + fValidOption = FALSE; + break; + } + strcpy (pCaptureParams->bannerUserName, pEqual+1); + } + else if (IsValidOption (argv[i], __BANNER__, __SHORT_FOR_BANNER__)) + { + if (pEqual != NULL) + { + if (strlen (pEqual+1) > MAX_BANNER_USER_NAME - 1) + { + DisplayMessage(IDR_INVALID_BANNER, pEqual+1); + fValidParam = FALSE; + break; + } + strcpy (pCaptureParams->captureFlagsRW.BannerText, pEqual+1); + pCaptureParams->captureFlagsRW.PrintFlags |= CAPTURE_FLAG_PRINT_BANNER; + } + } + // + // Kludge for LX LPX LPTX parameters + // Note that L:X L=X, etc are also valid + // + else if ( ( pEqual == NULL ) && ( *(argv[i]) == 'L' ) ) { + pEqual = argv[i]; + pEqual++; + if ( *pEqual == 'P' ) { + pEqual++; + if ( *pEqual == 'T' ) { + pEqual++; + } + } + pCaptureParams->nLPT = (unsigned char) atoi (pEqual); + + if (pCaptureParams->nLPT < 1 || pCaptureParams->nLPT > 3) + { + DisplayMessage(IDR_INVALID_LPT_NUMBER); + fValidParam = FALSE; + break; + } + + } + else + { + fValidOption = FALSE; + break; + } + } + } + + if (fValidOption && fValidParam) + { + sprintf (pCaptureParams->captureFlagsRW.JobDescription, __JOB_DESCRIPTION__, pCaptureParams->nLPT); + return(TRUE); + } + else + { + if (!fValidOption) + { + if (pEqual) + *pEqual = '='; + DisplayMessage(IDR_UNKNOW_FLAG, argv[i]); + } + DisplayMessage(IDR_CAPTURE_USAGE); + return(FALSE); + } +} + +/* + Show the capture setting. + */ +void ShowCapture(void) +{ + unsigned int iRet = 0; + int i; + char * queueName; + + for (i = 1; i <= 3; i++ ) + { + NETWARE_CAPTURE_FLAGS_RW captureFlagsRW; + NETWARE_CAPTURE_FLAGS_RO captureFlagsRO; + + if (iRet = GetCaptureFlags ((unsigned char)i, + &captureFlagsRW, + &captureFlagsRO)) + { + DisplayError (iRet, "GetCaptureFlags"); + } + else + { + char *serverName; + WCHAR timeOut[256]; + WCHAR tabs[256]; + + if (captureFlagsRO.LPTCaptureFlag == 0) + { + DisplayMessage(IDR_NOT_ACTIVE, i); + } + else + { + serverName = captureFlagsRO.ServerName; + + if ( !CaptureStringsLoaded ) { + (void) LoadString( NULL, IDR_DISABLED, __DISABLED__, 256 ); + (void) LoadString( NULL, IDR_ENABLED, __ENABLED__, 256 ); + (void) LoadString( NULL, IDR_YES, __YES__, 256 ); + (void) LoadString( NULL, IDR_NO, __NO__, 256 ); + (void) LoadString( NULL, IDR_SECONDS, __SECONDS__, 256 ); + (void) LoadString( NULL, IDR_CONVERT_TO_SPACE, __CONVERT_TO_SPACE__, 256 ); + (void) LoadString( NULL, IDR_NO_CONVERSION, __NO_CONVERSION__, 256 ); + (void) LoadString( NULL, IDR_NOTIFY_USER, __NOTIFY_USER__, 256 ); + (void) LoadString( NULL, IDR_NOT_NOTIFY_USER, __NOT_NOTIFY_USER__, 256 ); + (void) LoadString( NULL, IDR_NONE, __NONE__, 256 ); + } + + if (captureFlagsRW.FlushCaptureTimeout) + wsprintf (timeOut, __SECONDS__, captureFlagsRW.FlushCaptureTimeout); + else + (void) LoadString( NULL, IDR_DISABLED, timeOut, 256 ); + + if (captureFlagsRW.PrintFlags & CAPTURE_FLAG_EXPAND_TABS) + wsprintf(tabs, __CONVERT_TO_SPACE__, captureFlagsRW.TabSize); + else + (void) LoadString( NULL, IDR_NO_CONVERSION, tabs, 256 ); + + + queueName = captureFlagsRO.QueueName; + + if ( fNDS ) + { + if ( captureFlagsRW.PrintFlags & CAPTURE_FLAG_PRINT_BANNER ) + { + DisplayMessage(IDR_LPT_STATUS_NDS, i, queueName, + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NOTIFY? __NOTIFY_USER__ : __NOT_NOTIFY_USER__, //Notify + __DISABLED__, //Capture Defaults + captureFlagsRW.FlushCaptureOnClose? __DISABLED__ : __ENABLED__, //AutoEndCap + captureFlagsRW.BannerText, //Banner + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NO_FORMFEED? __NO__ : __YES__, //Form Feed + captureFlagsRW.NumCopies, //Copies + tabs, //Tabs + captureFlagsRW.FormType, timeOut); //Timeout Counts + } + else + { + DisplayMessage(IDR_LPT_STATUS_NO_BANNER_NDS, i, queueName, + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NOTIFY? __NOTIFY_USER__ : __NOT_NOTIFY_USER__, //Notify + __DISABLED__, //Capture Defaults + captureFlagsRW.FlushCaptureOnClose? __DISABLED__ : __ENABLED__, //AutoEndCap + __NONE__, //Banner + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NO_FORMFEED? __NO__ : __YES__, //Form Feed + captureFlagsRW.NumCopies, //Copies + tabs, //Tabs + captureFlagsRW.FormType, timeOut); //Timeout Counts + } + } + else + { + if ( captureFlagsRW.PrintFlags & CAPTURE_FLAG_PRINT_BANNER ) + { + DisplayMessage(IDR_LPT_STATUS, i, serverName, queueName, + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NOTIFY? __NOTIFY_USER__ : __NOT_NOTIFY_USER__, //Notify + __DISABLED__, //Capture Defaults + captureFlagsRW.FlushCaptureOnClose? __DISABLED__ : __ENABLED__, //AutoEndCap + captureFlagsRW.BannerText, //Banner + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NO_FORMFEED? __NO__ : __YES__, //Form Feed + captureFlagsRW.NumCopies, //Copies + tabs, //Tabs + captureFlagsRW.FormType, timeOut); //Timeout Counts + } + else + { + DisplayMessage(IDR_LPT_STATUS_NO_BANNER, i, serverName, queueName, + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NOTIFY? __NOTIFY_USER__ : __NOT_NOTIFY_USER__, //Notify + __DISABLED__, //Capture Defaults + captureFlagsRW.FlushCaptureOnClose? __DISABLED__ : __ENABLED__, //AutoEndCap + __NONE__, //Banner + captureFlagsRW.PrintFlags & CAPTURE_FLAG_NO_FORMFEED? __NO__ : __YES__, //Form Feed + captureFlagsRW.NumCopies, //Copies + tabs, //Tabs + captureFlagsRW.FormType, timeOut); //Timeout Counts + } + } + } + } + } +} + +int CStartCapture(unsigned int conn, + PCAPTURE_PARAMS pCaptureParams) +{ + unsigned int iRet = 0; + unsigned char FullPath[255 + NCP_VOLUME_LENGTH]; + unsigned char DirPath[255]; + unsigned char VolumeName[NCP_VOLUME_LENGTH]; + WORD status; + + // Get connection handle. + if ( !pCaptureParams->NDSCapture ) + { + if ( pCaptureParams->serverName[0] == 0 ) + { + if (iRet = GetFileServerName (conn, pCaptureParams->serverName)) + { + DisplayError (iRet, "GetFileServerName"); + return (1); + } + } + else + { + if (iRet = GetConnectionHandle (pCaptureParams->serverName, &conn)) + { + if ( iRet = NTLoginToFileServer( pCaptureParams->serverName, "GUEST", "" ) ) { + switch ( iRet ) { + case ERROR_INVALID_PASSWORD: + case ERROR_NO_SUCH_USER: + case ERROR_CONNECTION_COUNT_LIMIT: + case ERROR_LOGIN_TIME_RESTRICTION: + case ERROR_LOGIN_WKSTA_RESTRICTION: + case ERROR_ACCOUNT_DISABLED: + case ERROR_PASSWORD_EXPIRED: + case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: + DisplayMessage( IDR_CAPTURE_FAILED, pCaptureParams->queueName ); + DisplayMessage( IDR_ACCESS_DENIED ); + break; + default: + DisplayMessage(IDR_SERVER_NOT_FOUND, pCaptureParams->serverName); + } + return (1); + } + else { + if (iRet = GetConnectionHandle (pCaptureParams->serverName, &conn)) { + DisplayMessage(IDR_SERVER_NOT_FOUND, pCaptureParams->serverName); + return (1); + } + } + } + } + } + + if (pCaptureParams->filePath[0] != 0) + { + DisplayMessage(IDR_FILE_CAPTURE_UNSUPPORTED); + return (1); + } + else + { + if (pCaptureParams->queueName[0] == 0) + { + if ( pCaptureParams->NDSCapture ) + { + DisplayMessage(IDR_NO_QUEUE); + return (1); + } + else + { + // Try to get the default queue ID and name. + if (iRet = GetDefaultPrinterQueue (conn, pCaptureParams->serverName, pCaptureParams->queueName)) + { + DisplayMessage(IDR_NO_PRINTERS, pCaptureParams->serverName); + return (1); + } + } + } + // Start queue capture. + if ( pCaptureParams->NDSCapture ) + { + char szCanonName[MAX_QUEUE_NAME_LEN]; + + // Get the full name of the printer queue + // The redirectory wants root based names for + // everything. + + iRet = NDSCanonicalizeName( pCaptureParams->queueName, + szCanonName, + NDS_NAME_CHARS, + TRUE ); + + if ( iRet && ( pCaptureParams->queueName[0] != '.' ) ) + { + // If that didn't work, see if it's a root + // based name without the leading period. + + strcpy( szCanonName, "." ); + strcat( szCanonName, pCaptureParams->queueName ); + + iRet = NDSCanonicalizeName( szCanonName, + szCanonName, + MAX_QUEUE_NAME_LEN, + TRUE ); + } + + if ( iRet ) + iRet = ERROR_BAD_NETPATH; + else + iRet = StartQueueCapture ( conn, + pCaptureParams->nLPT, + NDSTREE, + szCanonName ); + } + else + { + iRet = StartQueueCapture (conn, + pCaptureParams->nLPT, + pCaptureParams->serverName, + pCaptureParams->queueName); + } + + if ( iRet ) + { + switch ( iRet ) { + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_PASSWORD: + DisplayMessage (IDR_CAPTURE_FAILED, pCaptureParams->queueName); + DisplayMessage (IDR_ACCESS_DENIED); + break; + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + break; + case ERROR_BAD_NET_NAME: + case ERROR_BAD_NETPATH: + if ( pCaptureParams->NDSCapture ) + DisplayMessage (IDR_NDSQUEUE_NOT_EXIST, + pCaptureParams->queueName, + pCaptureParams->serverName ); + else + DisplayMessage (IDR_QUEUE_NOT_EXIST, + pCaptureParams->queueName, + pCaptureParams->serverName ); + break; + default: + DisplayError (iRet, "StartQueueCapture"); + break; + } + return (1); + } + } + + if (pCaptureParams->captureFlagsRW.FlushCaptureOnClose == 1) + DisplayMessage(IDR_NO_AUTOENDCAP); + + if ( pCaptureParams->NDSCapture ) + DisplayMessage(IDR_NDSSUCCESS_QUEUE, pCaptureParams->nLPT, + pCaptureParams->queueName); + else + DisplayMessage(IDR_SUCCESS_QUEUE, pCaptureParams->nLPT, + pCaptureParams->queueName, pCaptureParams->serverName); + + return(0); +} + +/* + * Given an NDS printer name, fill in the default queue name + * + */ +int +GetPrinterDefaultQueue( PCAPTURE_PARAMS pCaptureParams, + PBYTE PrinterName ) +{ + BYTE Fixup[ MAX_QUEUE_NAME_LEN]; + PBYTE ptr; + unsigned int iRet; + + iRet = NDSGetProperty ( PrinterName, "Default Queue", + pCaptureParams->queueName, + MAX_QUEUE_NAME_LEN, + NULL ); + if ( iRet ) + { + /* + * Strip off the . in front and add context at end + */ + ptr = RemoveSpaces (PrinterName); + if ( *ptr == '.' ) + { + ptr++; + strncpy( Fixup, ptr, MAX_QUEUE_NAME_LEN ); + } + else + { + strncpy( Fixup, ptr, MAX_QUEUE_NAME_LEN ); + if ( Fixup[strlen(Fixup)-1] != '.' ) + { + strcat( Fixup, "." ); + } + (void) NDSGetContext( Fixup + strlen(Fixup), + MAX_QUEUE_NAME_LEN - strlen(Fixup) ); + } + iRet = NDSGetProperty ( Fixup, "Default Queue", + pCaptureParams->queueName, + MAX_QUEUE_NAME_LEN, + NULL ); + if ( !iRet ) + ConvertUnicodeToAscii( pCaptureParams->queueName ); + } + + return iRet; +} diff --git a/private/nw/nwscript/common.c b/private/nw/nwscript/common.c new file mode 100644 index 000000000..019ff87e5 --- /dev/null +++ b/private/nw/nwscript/common.c @@ -0,0 +1,400 @@ + +/************************************************************************* +* +* COMMON.C +* +* Miscellaneous routines for scripts, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\COMMON.C $ +* +* Rev 1.3 10 Apr 1996 14:21:52 terryt +* Hotfix for 21181hq +* +* Rev 1.3 12 Mar 1996 19:52:40 terryt +* Relative NDS names and merge +* +* Rev 1.2 24 Jan 1996 17:14:54 terryt +* Common read string routine +* +* Rev 1.1 22 Dec 1995 14:23:56 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:36 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:22:18 terryt +* Capture support +* +* Rev 1.1 26 Jul 1995 14:17:06 terryt +* Clean up comments +* +* Rev 1.0 15 May 1995 19:10:18 terryt +* Initial revision. +* +*************************************************************************/ +#include "common.h" + +/* + Used by DisplayMapping() only. + Return search number if the drive is a search drive. + Return 0 if the drive is not a search drive. + */ +int IsSearchDrive(int driveNum) +{ + int searchNum = 1; + char *path; + + path = NWGetPath(); + + while (*path != 0) + { + if ((*path - 'A' + 1 == driveNum) && + (*(path+1) == ':')) + { + return searchNum; + } + + if (path = strchr (path, ';')) + { + path++; + searchNum++; + } + else + return(0); + } + + return(0); +} + + +/* + Get path enviroment variable. This returns the pointer to the + path in the parent enviroment segment. + */ +char * NWGetPath(void) +{ + // + // On NT we can't change or get the parent's environment this way + // + return( getenv("PATH") ); +} + +/* + Return TRUE if the memory block is large enough for adding new + search path. FALSE otherwise. + */ +int MemorySegmentLargeEnough (int nInsertByte) +{ + return TRUE; +} + +/* + Display drive maps info. + */ +void DisplayMapping(void) +{ + unsigned int iRet = 0; + int i; + WORD status; + char rootPath[MAX_PATH_LEN], relativePath[MAX_PATH_LEN]; + char *envPath, *tokenPath; + char *path; + DWORD LocalDrives; + DWORD NonSearchDrives; + char sLocalDrives[26*2+5]; + char * sptr; + + // Don't delete this line. This is for fixing bug 1176. + DisplayMessage(IDR_NEWLINE); + + LocalDrives = 0; + NonSearchDrives = 0; + + // Collect local drives and search drives + for (i = 1; i <= 26; i++) { + status = NTNetWareDriveStatus( (unsigned short)(i-1) ); + if ((status & NETWARE_LOCAL_DRIVE) && !(status & NETWARE_NETWORK_DRIVE)) + LocalDrives |= ( 1 << (i-1) ); + else if ((status & NETWARE_NETWORK_DRIVE) && (!IsSearchDrive(i)) ) + { + if (status & NETWARE_NETWARE_DRIVE) + NonSearchDrives |= ( 1 << (i-1) ); + else + { + //For NetWare compatibility + LocalDrives |= ( 1 << (i-1) ); + } + } + } + + // Print out local drives + if ( LocalDrives ) { + sptr = &sLocalDrives[0]; + for (i = 1; i <= 26; i++) + { + if ( LocalDrives & ( 1 << (i - 1) ) ) { + *sptr++ = 'A' + i - 1; + *sptr++ = ','; + } + } + sptr--; + *sptr = '\0'; + DisplayMessage(IDR_ALL_LOCAL_DRIVES, sLocalDrives); + } + + // Print out non search drives. + for (i = 1; i <= 26; i++) + { + if ( NonSearchDrives & ( 1 << (i - 1) ) ) { + + if (iRet = GetDriveStatus ((unsigned short)i, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL)) + { + DisplayError (iRet, "GetDriveStatus"); + } + else + { + DisplayMessage(IDR_NETWARE_DRIVE, 'A'+i-1, rootPath, relativePath); + } + } + } + + // Print out dashed line as seperator between non search drives + // and search drives. + DisplayMessage(IDR_DASHED_LINE); + + // Get the PATH environment variable. + path = NWGetPath(); + if ((envPath = malloc (strlen (path) + 1)) == NULL) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + + strcpy (envPath, path); + + tokenPath = strtok (envPath, PATH_SEPERATOR); + + // Print out search drvies. + for (i = 1; tokenPath != NULL; i++) + { + if (tokenPath[1] == ':') + { + if (iRet = GetDriveStatus ((unsigned short)(toupper(tokenPath[0])-'A'+1), + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL)) + { + DisplayError (iRet, "GetDriveStatus"); + } + else + { + if (status & NETWARE_NETWARE_DRIVE) + DisplayMessage(IDR_NETWARE_SEARCH, i, tokenPath, rootPath, relativePath); + else + DisplayMessage(IDR_LOCAL_SEARCH, i, tokenPath); + } + } + else + { + // Path is specified without drive letter. + DisplayMessage(IDR_LOCAL_SEARCH, i, tokenPath); + } + + tokenPath = strtok (NULL, PATH_SEPERATOR); + } + + free (envPath); +} + +/***************************************************************************** + * * + * GetString * + * * + * * + * entry: pointer to buffer * + * length of buffer * + * * + * exit: length of string * + * * + *****************************************************************************/ + +int +GetString( char * pBuffer, int ByteCount ) +{ + char * pString = pBuffer; + char ch; + + if ( ByteCount > 0 ) + ByteCount--; + + for( ;; ) { + + switch ( ch = (char) _getch() ) { + + case '\r' : + *pString++ = '\0'; + putchar( '\n' ); + return( strlen( pBuffer ) ); + + case '\b' : + if ( pString != pBuffer ) { + ByteCount++; + pString--; + printf( "\b \b" ); + } + break; + + default : + if ( ByteCount > 0 && ch >= 0x20 && ch < 0x80 ) { + *pString++ = ch; + ByteCount--; + putchar( ch ); + } + break; + } + + } + fflush(stdin); +} + +/* + Read user or server name from the keyboard input. + Return TRUE if user typed in a username + FALSE otherwise. + */ +int ReadName (char * Name) +{ + memset( Name, 0, MAX_NAME_LEN ); + + if ( 0 == GetString( Name, MAX_NAME_LEN ) ) + return FALSE; + + _strupr(Name); + return TRUE; +} + + + +/* + Try to log the user in. + Return error code. 0 is success. + */ +int Login( char *UserName, + char *ServerName, + char *Password, + int bReadPassword) +{ + unsigned int iRet = 0; + + // Try log the user in with no password first. + iRet = NTLoginToFileServer( ServerName, + UserName, + Password); + + if (iRet == ERROR_INVALID_PASSWORD && bReadPassword) + { + // wrong password. ask for passowrd. and try login with + // the input password. + DisplayMessage(IDR_PASSWORD, UserName, ServerName); + + ReadPassword (Password); + + iRet = NTLoginToFileServer( ServerName, + UserName, + Password); + } + + switch(iRet) + { + case NO_ERROR: // ok + DisplayMessage(IDR_ATTACHED, ServerName); + break; + + case ERROR_INVALID_PASSWORD: // wrong password. + case ERROR_NO_SUCH_USER: // no such user. + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_ACCESS_DENIED); + break; + + case ERROR_CONNECTION_COUNT_LIMIT: // concurrent connection restriction. + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_LOGIN_DENIED_NO_CONNECTION); + break; + + case ERROR_LOGIN_TIME_RESTRICTION: // time restriction. + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_UNAUTHORIZED_LOGIN_TIME); + break; + + case ERROR_LOGIN_WKSTA_RESTRICTION: // station restriction. + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_UNAUTHORIZED_LOGIN_STATION); + break; + + case ERROR_ACCOUNT_DISABLED: + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_ACCOUNT_DISABLED); + break; + + case ERROR_PASSWORD_EXPIRED: // password expired and no grace login left. + DisplayMessage(IDR_SERVER_USER, ServerName, UserName); + DisplayMessage(IDR_PASSWORD_EXPRIED_NO_GRACE); + break; + + case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: + // Server rejected access + DisplayMessage(IDR_CONNECTION_REFUSED); + break; + + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + break; + + default : + DisplayError(iRet,"LoginToFileServer"); + break; + } + + return(iRet); +} + +int CAttachToFileServer(char *ServerName, unsigned int *pConn, int * pbAlreadyAttached) +{ + unsigned int iRet = 0; + + if (pbAlreadyAttached != NULL) + *pbAlreadyAttached = FALSE; + + // Validate the server name. + iRet = AttachToFileServer(ServerName,pConn); + + switch (iRet) + { + case 0: // OK + break; + + case 0x8800 : // Already atached. + if (pbAlreadyAttached != NULL) + *pbAlreadyAttached = TRUE; + + iRet = GetConnectionHandle (ServerName, pConn); + break; + + default: + DisplayMessage(IDR_NO_RESPONSE, ServerName); + break; + } + + return(iRet); +} diff --git a/private/nw/nwscript/date.c b/private/nw/nwscript/date.c new file mode 100644 index 000000000..1533d1f19 --- /dev/null +++ b/private/nw/nwscript/date.c @@ -0,0 +1,78 @@ +/************************************************************************* +* +* DATE.C +* +* NT date routine +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\DATE.C $ +* +* Rev 1.2 10 Apr 1996 14:22:00 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:52:56 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:04 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:40 terryt +* Initial revision. +* +* Rev 1.0 15 May 1995 19:10:22 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nwscript.h" + + +/* + ******************************************************************* + + NTGetTheDate + +Routine Description: + + Return the current date + +Arguments: + + yearCurrent pointer to current year + 1980-2099 + monthCurrent pointer to current month + 1-12 + dayCurrent pointer to current day + 1-31 + +Return Value: + + + + ******************************************************************* + */ +void NTGetTheDate( unsigned int * yearCurrent, + unsigned char * monthCurrent, + unsigned char * dayCurrent ) +{ + time_t timedat; + struct tm * p_tm; + + (void) time( &timedat ); + p_tm = localtime( &timedat ); + + *yearCurrent = p_tm->tm_year + 1900; + *monthCurrent = p_tm->tm_mon + 1; + *dayCurrent = p_tm->tm_mday; +} diff --git a/private/nw/nwscript/dbcs.c b/private/nw/nwscript/dbcs.c new file mode 100644 index 000000000..f37beacb6 --- /dev/null +++ b/private/nw/nwscript/dbcs.c @@ -0,0 +1,98 @@ + +/************************************************************************* +* +* DBCS.C +* +* DBCS routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\DBCS.C $ +* +* Rev 1.1 22 Dec 1995 14:24:10 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:44 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:22:26 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:10:24 terryt +* Initial revision. +* +*************************************************************************/ +/* +** dbcs.c - DBCS functions for DOS apps. +** +** Written by RokaH and DavidDi. +*/ + + +/* Headers +**********/ + +// IsDBCSLeadByte taken out of NT because there is one built in. +// I left the Next and Prev in because I don't know whether this +// algorithm is "safer" than the built in code. + +#include "common.h" + +/* +** unsigned char *NWAnsiNext(unsigned char *puch); +** +** Moves to the next character in a string. +** +** Arguments: puch - pointer to current location in string +** +** Returns: char * - Pointer to next character in string. +** +** Globals: none +** +** N.b., if puch points to a null character, NWAnsiNext() will return puch. +*/ +unsigned char *NWAnsiNext(unsigned char *puch) +{ + if (*puch == '\0') + return(puch); + else if (IsDBCSLeadByte(*puch)) + puch++; + + puch++; + + return(puch); +} + + +/* +** unsigned char *NWAnsiPrev(unsigned char *psz, unsigned char *puch); +** +** Moves back one character in a string. +** +** Arguments: psz - pointer to start of string +** puch - pointer to current location in string +** +** Returns: char * - Pointer to previous character in string. +** +** Globals: none +** +** N.b., if puch <= psz, NWAnsiPrev() will return psz. +** +** This function is implemented in a very slow fashion because we do not wish +** to trust that the given string is necessarily DBCS "safe," i.e., contains +** only single-byte characters and valid DBCS characters. So we start from +** the beginning of the string and work our way forward. +*/ +unsigned char *NWAnsiPrev(unsigned char *psz, unsigned char *puch) +{ + unsigned char *puchPrevious; + + do + { + puchPrevious = psz; + psz = NWAnsiNext(psz); + } while (*psz != '\0' && psz < puch); + + return(puchPrevious); +} + diff --git a/private/nw/nwscript/display.c b/private/nw/nwscript/display.c new file mode 100644 index 000000000..ddd44e3d7 --- /dev/null +++ b/private/nw/nwscript/display.c @@ -0,0 +1,101 @@ + +/************************************************************************* +* +* DISPLAY.C +* +* NetWare script routines for displaying information, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\DISPLAY.C $ +* +* Rev 1.2 10 Apr 1996 14:22:06 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:53:04 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:18 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:48 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:22:32 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:10:26 terryt +* Initial revision. +* +*************************************************************************/ +/* + File name: display.c + Do not add any other functions to this file. + Otherwise many exes size will increase. + */ + + +#include "common.h" + +/* + Display error report. + */ +void DisplayError(int error ,char *functionName) +{ + DisplayMessage(IDR_ERROR, error ,functionName); +} + +void xstrupr(char *buffer) +{ + for (; *buffer; buffer++) + { + if (IsDBCSLeadByte(*buffer)) + buffer++; + else if (*buffer == 0xff80) + *buffer = (char)0xff87; + else if (*buffer == 0xff81) + *buffer = (char)0xff9a; + else if (*buffer == 0xff82) + *buffer = (char)0xff90; + else if (*buffer == 0xff84) + *buffer = (char)0xff8e; + else if (*buffer == 0xff88) + *buffer = (char)0xff9f; + else if (*buffer == 0xff91) + *buffer = (char)0xff92; + else if (*buffer == 0xff94) + *buffer = (char)0xff99; + else if (*buffer == 0xffa4) + *buffer = (char)0xffa5; + } + + _strupr (buffer); +} + +/* + Read password from the keyboard input. + */ +void ReadPassword(char * Password) +{ + int i = 0; + char c; + + do + { c=(char)_getch(); + + if (c == '\b') + { + if (i > 0) + i--; + } + else + { + Password[i]=c; + i++; + } + }while((c!='\r') && i< MAX_PASSWORD_LEN ); + Password[i-1]='\0'; + xstrupr(Password); + DisplayMessage(IDR_NEWLINE); +} + diff --git a/private/nw/nwscript/drive.c b/private/nw/nwscript/drive.c new file mode 100644 index 000000000..b6539185d --- /dev/null +++ b/private/nw/nwscript/drive.c @@ -0,0 +1,327 @@ +/************************************************************************* +* +* DRIVE.C +* +* NT drive routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\DRIVE.C $ +* +* Rev 1.2 10 Apr 1996 14:22:12 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:53:22 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:24 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:52 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:22:38 terryt +* Capture support +* +* Rev 1.1 23 May 1995 19:36:46 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:30 terryt +* Initial revision. +* +*************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "nwscript.h" +#include "ntnw.h" +#include "inc/nwlibs.h" + +#include "..\..\..\inc\mpr.h" + +extern unsigned char NW_PROVIDERA[]; + +/******************************************************************** + + GetFirstDrive + +Routine Description: + + Return the first non-local drive + +Arguments: + + pFirstDrive = pointer to drive + 1-26 + +Return Value: + 0 = success + F = failure + + ********************************************************************/ +unsigned int +GetFirstDrive( unsigned short *pFirstDrive ) +{ + int i; + char DriveName[10]; + unsigned int drivetype; + + strcpy( DriveName, "A:\\" ); + + for ( i = 2; i < 26; i++ ) { + DriveName[0] = 'A' + i; + drivetype = GetDriveTypeA( DriveName ); + if ( ( ( drivetype == DRIVE_REMOTE ) && + ( NTIsNetWareDrive( i ) ) ) || + ( drivetype == DRIVE_NO_ROOT_DIR ) ) { + *pFirstDrive = i + 1; + return 0x0000; + } + } + + return 0x000F; +} + +/******************************************************************** + + IsDriveRemote + +Routine Description: + + Is the given drive remote? + +Arguments: + + DriveNumber 1-26 + pRemote 0x1000 = remote, 0x0000 = local + +Return Value: + 0 = success + F = invalid drive + + ********************************************************************/ +unsigned int +IsDriveRemote( + unsigned char DriveNumber, + unsigned int *pRemote + ) +{ + char DriveName[10]; + unsigned int drivetype; + + strcpy( DriveName, "A:\\" ); + DriveName[0] = 'A' + DriveNumber; + + drivetype = GetDriveTypeA( DriveName ); + + if ( drivetype == DRIVE_REMOTE ) { + *pRemote = 0x1000; + return 0; + } + else if ( drivetype == DRIVE_NO_ROOT_DIR ) { + return 0xF; + } + else { + *pRemote = 0; + return 0; + } +} + + +/******************************************************************** + + NTNetWareDriveStatus + +Routine Description: + + Return the type of drive + +Arguments: + + DriveNumber - Number of drive 0-25 + +Return Value: + + Combination of: + NETWARE_NETWORK_DRIVE + NETWARE_NETWARE_DRIVE + NETWARE_LOCAL_FREE_DRIVE + NETWARE_LOCAL_DRIVE + + + + *******************************************************************/ +unsigned short +NTNetWareDriveStatus( unsigned short DriveNumber ) +{ + char DriveName[10]; + unsigned int drivetype; + unsigned int Status = 0; + + strcpy( DriveName, "A:\\" ); + DriveName[0] = 'A' + DriveNumber; + drivetype = GetDriveTypeA( DriveName ); + + if ( drivetype == DRIVE_REMOTE ) { + Status |= NETWARE_NETWORK_DRIVE; + if ( NTIsNetWareDrive( (unsigned int)DriveNumber ) ) + Status |= NETWARE_NETWARE_DRIVE; + } + else if ( drivetype == DRIVE_NO_ROOT_DIR ) { + Status = NETWARE_LOCAL_FREE_DRIVE; + } + else { + Status = NETWARE_LOCAL_DRIVE; + } + return Status; +} + + +/******************************************************************** + + NTGetNWDrivePath + +Routine Description: + + Return the server name and path of the specified drive + +Arguments: + DriveNumber - Number of drive 0-25 + ServerName - Name of file server + Path - Volume:\Path + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int NTGetNWDrivePath( + unsigned short DriveNumber, + unsigned char * ServerName, + unsigned char * Path ) +{ + static char localname[] = "A:"; + unsigned int Result; + char * p; + char * volume; + char remotename[1024]; + int length = 1024; + + if ( ServerName != NULL ) + *ServerName = 0; + + if ( Path != NULL ); + *Path = 0; + + localname[0] = 'A' + DriveNumber; + + Result = WNetGetConnectionA ( localname, remotename, &length ); + + if ( Result != NO_ERROR ) { + Result = GetLastError(); + if ( Result == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + return Result; + } + + p = strchr (remotename + 2, '\\'); + if ( !p ) + return 0xffffffff; + + *p++ = '\0'; + volume = p; + + if ( ServerName != NULL ) { + strcpy( ServerName, remotename + 2 ); + _strupr( ServerName ); + } + + if ( Path != NULL ) { + p = strchr (volume, '\\'); + if ( !p ) { + strcpy( Path, volume ); + strcat( Path, ":" ); + } + else { + *p = ':'; + strcpy( Path, volume ); + } + _strupr( Path ); + } + + return NO_ERROR; +} + + +/******************************************************************** + + NTIsNetWareDrive + +Routine Description: + + Returns TRUE if the drive is a netware mapped drive + +Arguments: + + DriveNumber - Number of drive 0-25 + +Return Value: + TRUE - drive is NetWare + FALSE - drive is not NetWare + + *******************************************************************/ +unsigned int +NTIsNetWareDrive( unsigned int DriveNumber ) +{ + LPBYTE Buffer ; + DWORD dwErr ; + HANDLE EnumHandle ; + char DriveName[10]; + DWORD BufferSize = 4096; + LPWNET_CONNECTIONINFOA pConnectionInfo; + + strcpy( DriveName, "A:" ); + + DriveName[0] = 'A' + DriveNumber; + + // + // allocate memory and open the enumeration + // + if (!(Buffer = LocalAlloc( LPTR, BufferSize ))) { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + dwErr = WNetGetConnection2A( DriveName, Buffer, &BufferSize ); + if (dwErr != WN_SUCCESS) { + dwErr = GetLastError(); + if ( dwErr == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + (void) LocalFree((HLOCAL) Buffer) ; + return FALSE; + } + + pConnectionInfo = (LPWNET_CONNECTIONINFOA) Buffer; + + if ( !_strcmpi ( pConnectionInfo->lpProvider, NW_PROVIDERA ) ) { + (void) LocalFree((HLOCAL) Buffer) ; + return TRUE; + } + else { + (void) LocalFree((HLOCAL) Buffer) ; + return FALSE; + } + + return FALSE; +} diff --git a/private/nw/nwscript/drvstat.c b/private/nw/nwscript/drvstat.c new file mode 100644 index 000000000..908359d79 --- /dev/null +++ b/private/nw/nwscript/drvstat.c @@ -0,0 +1,268 @@ + +/************************************************************************* +* +* DRVSTAT.C +* +* Drive status routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\DRVSTAT.C $ +* +* Rev 1.2 10 Apr 1996 14:22:20 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:53:36 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:32 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:54 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:22:44 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:10:32 terryt +* Initial revision. +* +*************************************************************************/ + +/*++ + +Copyright (c) 1994 Micro Computer Systems, Inc. + +Module Name: + + nwlibs\drvstat.c + +Abstract: + + Directory APIs. + +Author: + + Shawn Walker (v-swalk) 10-10-1994 + +Revision History: + +--*/ +#include "common.h" + + +/*++ +******************************************************************* + + GetDriveStatus + +Routine Description: + + Get the drive status. + +Arguments: + + DriveNumber = The drive to number to use. (1=A,2=B,C=3,...) + PathFormat = Format for the return path. + NW_FORMAT_NETWARE - volume:path + NW_FORMAT_SERVER_VOLUME - server\volume:path + NW_FORMAT_DRIVE - G:\path + NW_FORMAT_UNC - \\server\volume\path + pStatus = A pointer to return the status of the drive. + pConnectionHandle = A pointer to return the connection handle + for the drive. + pRootPath = The pointer to return the base root path. OPTIONAL + pRelativePath = The pointer to return the relative to root path. + pFullPath = The pointer to return the full path. + +Return Value: + + 0x0000 SUCCESSFUL + 0x00FF INVALID_DRIVE + +******************************************************************* +--*/ +unsigned int +GetDriveStatus( + unsigned short DriveNumber, + unsigned short PathFormat, + unsigned short *pStatus, + unsigned int *pConnectionHandle, + unsigned char *pRootPath, + unsigned char *pRelativePath, + unsigned char *pFullPath + ) +{ + unsigned char *p; + unsigned int Result; + unsigned short Status; + unsigned char Path[NCP_MAX_PATH_LENGTH + 1]; + unsigned char WorkPath[NCP_MAX_PATH_LENGTH + 1]; + unsigned char ServerName[NCP_SERVER_NAME_LENGTH + 1]; + + /** Make sure the drive number is valid **/ + + if (DriveNumber < 1 || DriveNumber > 32) { + return 0x000F; /* INVALID_DRIVE */ + } + + Status = 0; + + DriveNumber--; + + + if (pConnectionHandle) { + /* + * This should never occur. + */ + DisplayError (0xff, "GetDriveStatus"); + return 0xff; + } + + /** Get the directory path from the server **/ + Result = NTGetNWDrivePath( DriveNumber, ServerName, Path ); + if ( Result ) { + *Path = 0; + *ServerName = 0; + } + + /** Convert the / in the path to \ **/ + for (p = Path; *p != 0 ; p++) + { + if (*p == '/') + *p = '\\'; + } + + /** Get the status of the drive if we need to **/ + Status = NTNetWareDriveStatus( DriveNumber ); + + /** Get the status of the drive if we need to **/ + + if (pStatus) { + *pStatus = Status; + } + + /** Get the full path if we need to **/ + + if (pFullPath) { + + if (Status & NETWARE_LOCAL_FREE_DRIVE) { + *pFullPath = 0; + } + else { + strcpy(WorkPath, Path); + + /** Build the NetWare path format (volume:path) **/ + + if (PathFormat == NETWARE_FORMAT_NETWARE) { + strcpy(pFullPath, WorkPath); + } + + /** Build the server volume path (server\volume:path) **/ + + else if (PathFormat == NETWARE_FORMAT_SERVER_VOLUME) { + sprintf(pFullPath, "%s\\%s", ServerName, WorkPath); + } + + /** Build the drive path (G:\path) **/ + + else if (PathFormat == NETWARE_FORMAT_DRIVE) { + + p = WorkPath; + while (*p != ':' && *p) { + p++; + } + + if (*p == ':') { + p++; + } + + sprintf(pFullPath, "%c:\\%s", DriveNumber + 'A', p); + } + + /** Build the UNC path (\\server\volume\path) **/ + + else if (PathFormat == NETWARE_FORMAT_UNC) { + + p = WorkPath; + while (*p != ':' && *p) { + p++; + } + + if (*p == ':') { + *p = '\\'; + } + + sprintf(pFullPath, "\\\\%s\\%s", ServerName, WorkPath); + } + } + } + + strcpy(WorkPath, Path); + /* + * Path does not have the relative path (current directory) in it. + */ + + /** Get the root path if we need to **/ + + if (pRootPath) { + + if (Status & NETWARE_LOCAL_FREE_DRIVE) { + *pRootPath = 0; + } + else { + + /** Build the NetWare root path format (volume:) **/ + + if (PathFormat == NETWARE_FORMAT_NETWARE) { + sprintf(pRootPath, strchr(WorkPath, ':')? "%s" : "%s:", WorkPath); + } + + /** Build the server volume root path (server\volume:) **/ + + else if (PathFormat == NETWARE_FORMAT_SERVER_VOLUME) { + if ( fNDS && !_strcmpi( ServerName, NDSTREE) ) + sprintf(pRootPath, strchr (WorkPath, ':')? "%s" : "%s:", WorkPath); + else + sprintf(pRootPath, strchr (WorkPath, ':')? "%s\\%s" : "%s\\%s:", ServerName, WorkPath); + } + + /** Build the drive root path (G:\) **/ + + else if (PathFormat == NETWARE_FORMAT_DRIVE) { + sprintf(pRootPath, "%c:\\", DriveNumber + 'A'); + } + + /** Build the UNC root path (\\server\volume) **/ + + else if (PathFormat == NETWARE_FORMAT_UNC) { + sprintf(pRootPath, "\\\\%s\\%s", ServerName, WorkPath); + } + } + } + + /** Get the relative path if we need to **/ + + if (pRelativePath) { + + if (Status & NETWARE_LOCAL_FREE_DRIVE) { + *pRelativePath = 0; + } + else { + int i; + NTGetCurrentDirectory( (unsigned char)DriveNumber, pRelativePath ); + /* + * Skip the drive letter + */ + if ( pRelativePath[0] ) { + for ( i = 0; ;i++ ) { + pRelativePath[i] = pRelativePath[i+3]; + if ( !pRelativePath[i] ) + break; + } + } + } + } + + return 0x0000; +} diff --git a/private/nw/nwscript/env.c b/private/nw/nwscript/env.c new file mode 100644 index 000000000..dfece205b --- /dev/null +++ b/private/nw/nwscript/env.c @@ -0,0 +1,352 @@ +/************************************************************************* +* +* ENV.C +* +* Environment export routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\ENV.C $ +* +* Rev 1.2 10 Apr 1996 14:22:28 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:53:48 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:40 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:06:58 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:22:50 terryt +* Capture support +* +* Rev 1.1 23 May 1995 19:36:54 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:34 terryt +* Initial revision. +* +*************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nwscript.h" + +#define MAX_PATH_LEN 2048 +#define PATH "Path" +#define LIBPATH "LibPath" +#define OS2LIBPATH "Os2LibPath" + +unsigned char * Path_Value = NULL; +unsigned char * LibPath_Value = NULL; +unsigned char * Os2LibPath_Value = NULL; + + +/******************************************************************** + + GetOldPaths + +Routine Description: + + Save the orginal paths for + Path + LibPath + Os2LibPath + +Arguments: + none + +Return Value: + none + + *******************************************************************/ +void +GetOldPaths( void ) +{ + if (!(Path_Value = (unsigned char *)LocalAlloc( LPTR, MAX_PATH_LEN ))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + GetEnvironmentVariableA( PATH, Path_Value, MAX_PATH_LEN ); + if (!(LibPath_Value = (unsigned char *)LocalAlloc( LPTR, MAX_PATH_LEN))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + GetEnvironmentVariableA( LIBPATH, LibPath_Value, MAX_PATH_LEN ); + if (!(Os2LibPath_Value = (unsigned char *)LocalAlloc( LPTR, MAX_PATH_LEN))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + GetEnvironmentVariableA( OS2LIBPATH, Os2LibPath_Value, MAX_PATH_LEN ); +} + + +/******************************************************************** + + AdjustPath + +Routine Description: + + Given an old path and a new path, merge the two togther. + Basically, the Adjusted path is the old path with the + new values at the end, minus any duplicates. + +Arguments: + + Value - New path + OldPath_Value - Old path + AdjustedValue - New value (allocated) + +Return Value: + none + + *******************************************************************/ +void +AdjustPath( unsigned char * Value, + unsigned char * OldPath_Value, + unsigned char ** AdjustedValue ) +{ + unsigned char * tokenPath; + unsigned char * clipStart; + unsigned char * clipEnd; + unsigned char * tokenSearch; + unsigned char * tokenNext; + + if (!(*AdjustedValue = (unsigned char *)LocalAlloc( LPTR, MAX_PATH_LEN))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + strncpy( *AdjustedValue, Value, MAX_PATH_LEN ); + + if (!(tokenSearch = (unsigned char *)LocalAlloc( LPTR, MAX_PATH_LEN))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + (void) LocalFree((HLOCAL) *AdjustedValue) ; + return; + } + strncpy( tokenSearch, OldPath_Value, MAX_PATH_LEN ); + + tokenNext = tokenSearch; + + if ( !tokenNext || !tokenNext[0] ) + tokenPath = NULL; + else { + tokenPath = tokenNext; + tokenNext = strchr( tokenPath, ';' ); + if ( tokenNext ) { + *tokenNext++ = 0; + } + } + + while ( tokenPath != NULL ) + { + if ( clipStart = strstr( *AdjustedValue, tokenPath ) ) { + if ( clipEnd = strchr( clipStart, ';' ) ) { + memmove( clipStart, clipEnd + 1, strlen( clipEnd + 1 ) + 1 ); + } + else { + clipStart[0] = 0; + } + } + + if ( !tokenNext || !tokenNext[0] ) + tokenPath = NULL; + else { + tokenPath = tokenNext; + tokenNext = strchr( tokenPath, ';' ); + if ( tokenNext ) { + *tokenNext++ = 0; + } + } + } + (void) LocalFree((HLOCAL) tokenSearch) ; + +} + +/******************************************************************** + + ExportEnv + +Routine Description: + + Export environment value to the registry + +Arguments: + + EnvString - Environment string + +Return Value: + none + + *******************************************************************/ +void +ExportEnv( unsigned char * EnvString ) +{ + HKEY ScriptEnvironmentKey; + NTSTATUS Status; + unsigned char * Value; + unsigned char * ValueName; + unsigned char * AdjustedValue = NULL; + + ValueName = EnvString; + Value = strchr( EnvString, '=' ); + + if ( Value == NULL ) { + wprintf(L"Bad Environment string\n"); + + return; + } + Value++; + + if (!(ValueName = (unsigned char *)LocalAlloc( LPTR, Value-EnvString + 1))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return; + } + strncpy( ValueName, EnvString, Value-EnvString - 1 ); + + if ( !_strcmpi( ValueName, PATH ) ) { + AdjustPath( Value, Path_Value, &AdjustedValue ); + Value = AdjustedValue; + } + else if ( !_strcmpi( ValueName, LIBPATH ) ) { + AdjustPath( Value, LibPath_Value, &AdjustedValue ); + Value = AdjustedValue; + } + else if ( !_strcmpi( ValueName, OS2LIBPATH ) ) { + AdjustPath( Value, Os2LibPath_Value, &AdjustedValue ); + Value = AdjustedValue; + } + + Status = RegCreateKeyExW( HKEY_CURRENT_USER, + SCRIPT_ENVIRONMENT_VALUENAME, + 0, + WIN31_CLASS, + REG_OPTION_VOLATILE, + KEY_WRITE, + NULL, // security attr + &ScriptEnvironmentKey, + NULL + ); + + if ( NT_SUCCESS(Status)) { + + Status = RegSetValueExA( ScriptEnvironmentKey, + ValueName, + 0, + REG_SZ, + (LPVOID) Value, + strlen( Value ) + 1 + ); + } + else { + wprintf(L"Cannot create registry key\n"); + } + + (void) LocalFree((HLOCAL) ValueName) ; + + if ( AdjustedValue ) + (void) LocalFree((HLOCAL) AdjustedValue) ; + + RegCloseKey( ScriptEnvironmentKey ); +} + +/******************************************************************** + + ExportCurrentDirectory + +Routine Description: + + Return the first non-local drive + +Arguments: + + DriveNum - Number of drive 1-26 + +Return Value: + none + + *******************************************************************/ +void +ExportCurrentDirectory( int DriveNum ) +{ + char DriveName[10]; + HKEY ScriptEnvironmentKey; + NTSTATUS Status; + char CurrentPath[MAX_PATH_LEN]; + + strcpy( DriveName, "=A:" ); + + DriveName[1] += (DriveNum - 1); + + if ( NTGetCurrentDirectory( (unsigned char)(DriveNum - 1), CurrentPath ) ) + return; + + Status = RegCreateKeyExW( HKEY_CURRENT_USER, + SCRIPT_ENVIRONMENT_VALUENAME, + 0, + WIN31_CLASS, + REG_OPTION_VOLATILE, + KEY_WRITE, + NULL, // security attr + &ScriptEnvironmentKey, + NULL + ); + + if ( NT_SUCCESS(Status)) { + + Status = RegSetValueExA( ScriptEnvironmentKey, + DriveName, + 0, + REG_SZ, + (LPVOID) CurrentPath, + strlen( CurrentPath ) + 1 + ); + } + else { + wprintf(L"Cannot open registry key\n"); + } + + RegCloseKey( ScriptEnvironmentKey ); + +} + + +/******************************************************************** + + ExportCurrentDrive + +Routine Description: + + Export current drive to registry + NOT IMPLEMENTED + +Arguments: + + DriveNum - drive number + +Return Value: + none + + *******************************************************************/ +void +ExportCurrentDrive( int DriveNum ) +{ + /* + * Don't know if we want to do this or how. + */ +} diff --git a/private/nw/nwscript/helpers.c b/private/nw/nwscript/helpers.c new file mode 100644 index 000000000..9f504490f --- /dev/null +++ b/private/nw/nwscript/helpers.c @@ -0,0 +1,96 @@ +/****************************************************************************** +* +* HELPERS.C +* +* Various helper functions. +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\HELPERS.C $ +* +* Rev 1.1 22 Dec 1995 14:24:48 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:02 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:22:56 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:10:38 terryt +* Initial revision. +* +* +*******************************************************************************/ + +#include +#include +#include + +#include + +#include +#include +#include + +#include "nwscript.h" + + +/******************************************************************************* + * + * DisplayMessage + * Display a message with variable arguments. Message + * format string comes from the application resources. + * + * ENTRY: + * nID (input) + * Resource ID of the format string to use in the message. + * ... (input) + * Optional additional arguments to be used with format string. + * + * EXIT: + * + ******************************************************************************/ + +VOID +DisplayMessage( unsigned int nID, ... ) +{ + WCHAR sz1[512]; + + va_list args; + va_start( args, nID ); + + if ( LoadString( NULL, nID, sz1, 512 ) ) { + + setlocale(LC_ALL,".ACP") ; + vwprintf( sz1, args ); + setlocale(LC_ALL,".OCP") ; + + } + + va_end(args); + +} /* DisplayMessage() */ + + +/******************************************************************************* + * + * DisplayOemString + * Display an OEM string + * + * ENTRY: + * string: string to display + * + * EXIT: + * + ******************************************************************************/ + +VOID +DisplayOemString( char *string ) +{ + // this will print % in strings correctly. + printf( "%s", string ); + +} /* DisplayAnsiString() */ + + diff --git a/private/nw/nwscript/inc/common.h b/private/nw/nwscript/inc/common.h new file mode 100644 index 000000000..14764853d --- /dev/null +++ b/private/nw/nwscript/inc/common.h @@ -0,0 +1,195 @@ + +/************************************************************************* +* +* COMMON.H +* +* Common header file +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\INC\VCS\COMMON.H $ +* +* Rev 1.3 22 Dec 1995 14:20:06 terryt +* Add Microsoft headers +* +* Rev 1.2 22 Nov 1995 15:44:26 terryt +* Use proper NetWare user name call +* +* Rev 1.1 20 Nov 1995 15:18:46 terryt +* Context and capture changes +* +* Rev 1.0 15 Nov 1995 18:05:30 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 17:03:32 terryt +* CAPTURE support +* +* Rev 1.1 26 Jul 1995 16:01:12 terryt +* Get rid of unneccessary externs +* +* Rev 1.0 15 May 1995 19:09:28 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbcs.h" +#include "inc\nwlibs.h" + +#include "nwscript.h" + + +#define MAX_NAME_LEN 48 +#define MAX_PASSWORD_LEN 128 +#define MAX_PATH_LEN 304 //From NW programmer's guide p268. + +/* for map only */ +#define MAX_VOLUME_LEN 256 // 17 for 3X +#define MAX_DIR_PATH_LEN 256 + +/* for capture only */ +#define MAX_JOB_NAME_LEN 32 +#define MAX_QUEUE_NAME_LEN 1024 +#define MAX_BANNER_USER_NAME 13 + +/* for common only */ +#define PATH_SEPERATOR ";" + + +/* + Function definations + */ +/* used by login.c and script.c */ +void BreakOff(void); +void BreakOn(void); + +/* used by common setpass*/ +void xstrupr(char *buffer); +void ReadPassword(char * Password); + +/* used by map attach login*/ +int CAttachToFileServer(char *ServerName, unsigned int *pConn, int * pbAlreadyAttached); +int Login(char *UserName, char *ServerName, char *Password, int bReadPassword); + +/* used by map attach login*/ +int ReadName (char * Name); + +/* used by map login */ +void DisplayError(int error ,char *functionName); +char * GetDosEnv1(void); +char * NWGetPath(void); +int GetRestEnvLen (char *lpRest); + +int MemorySegmentLargeEnough (int nInsertByte); +int IsSearchDrive(int driveNum); +int GetDriveFromSearchNumber (int searchNumber); + +/* used by login logout*/ +void SetLoginDirectory (PBYTE); + +/* used by all */ +int Map (char * buffer); +void DisplayMapping(void); +int CGetDefaultConnectionID ( unsigned int * pConn ); +int GetConnectionInfo (unsigned int conn, + char * serverName, + char * userName, + unsigned int * pconnNum, + unsigned char * loginTime); + +extern char * LOGIN_NAME; +extern char *NDS_FULL_NAME; +extern char *REQUESTER_CONTEXT; +extern char *TYPED_USER_NAME; +extern PWCHAR TYPED_USER_NAME_w; +extern PBYTE NDSTREE; +extern PWCHAR NDSTREE_w; +extern UNICODE_STRING NDSTREE_u; +extern PBYTE PREFERRED_SERVER; + +/* + String definitions. + */ +extern char *__Day__[7]; +extern char *__Month__[12]; +extern char *__AMPM__[2]; +extern char *__GREETING__[3]; + +extern char __DEL__[]; +extern char __REM__[]; +extern char __INS__[]; +extern char __ROOT__[]; +extern char __NEXT__[]; + +extern char __AUTOENDCAP__[]; +extern char __BANNER__[]; +extern char __COPIES__[]; +extern char __CREATE__[]; +extern WCHAR __DISABLED__[]; +extern WCHAR __ENABLED__[]; +extern WCHAR __YES__[]; +extern WCHAR __NO__[]; +extern WCHAR __SECONDS__[]; +extern WCHAR __CONVERT_TO_SPACE__[]; +extern WCHAR __NO_CONVERSION__[]; +extern WCHAR __NOTIFY_USER__[]; +extern WCHAR __NOT_NOTIFY_USER__[]; +extern WCHAR __NONE__[]; +extern char __FORMFEED__[]; +extern char __FORM__[]; +extern char __JOB_DESCRIPTION__[]; +extern char __JOB__[]; +extern char __KEEP__[]; +extern char __LOCAL__[]; +extern char __LOCAL_2__[]; +extern char __LOCAL_3__[]; +extern char __NAME__[]; +extern char __NOAUTOENDCAP__[]; +extern char __NOBANNER__[]; +extern char __NOFORMFEED__[]; +extern char __NONOTIFY__[]; +extern char __NOTABS__[]; +extern char __NOTIFY__[]; +extern char __QUEUE__[]; +extern char __PRINTER__[]; +extern char __OPT_NO__[]; +extern char __SERVER__[]; +extern char __SHORT_FOR_AUTOENDCAP__[]; +extern char __SHORT_FOR_BANNER__[]; +extern char __SHORT_FOR_COPIES__[]; +extern char __SHORT_FOR_CREATE__[]; +extern char __SHORT_FOR_FORMFEED__[]; +extern char __SHORT_FOR_FORM__[]; +extern char __SHORT_FOR_JOB__[]; +extern char __SHORT_FOR_KEEP__[]; +extern char __SHORT_FOR_LOCAL__[]; +extern char __SHORT_FOR_NAME__[]; +extern char __SHORT_FOR_NOAUTOENDCAP__[]; +extern char __SHORT_FOR_NOBANNER__[]; +extern char __SHORT_FOR_NOFORMFEED__[]; +extern char __SHORT_FOR_NONOTIFY__[]; +extern char __SHORT_FOR_NOTABS__[]; +extern char __SHORT_FOR_NOTIFY__[]; +extern char __SHORT_FOR_QUEUE__[]; +extern char __SHORT_FOR_PRINTER__[]; +extern char __SHORT_FOR_SERVER__[]; +extern char __SHORT_FOR_TABS__[]; +extern char __SHORT_FOR_TIMEOUT__[]; +extern char __SHOW__[]; +extern char __TABS__[]; +extern char __TIMEOUT__[]; + +extern unsigned int CaptureStringsLoaded; +extern unsigned int fNDS; diff --git a/private/nw/nwscript/inc/dbcs.h b/private/nw/nwscript/inc/dbcs.h new file mode 100644 index 000000000..2fb4a5b5b --- /dev/null +++ b/private/nw/nwscript/inc/dbcs.h @@ -0,0 +1,26 @@ + +/************************************************************************* +* +* DBCS.H +* +* DBCS header file +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\INC\VCS\DBCS.H $ +* +* Rev 1.1 22 Dec 1995 14:20:14 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:05:32 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 17:03:40 terryt +* CAPTURE support +* +* Rev 1.0 15 May 1995 19:09:32 terryt +* Initial revision. +* +*************************************************************************/ +unsigned char *NWAnsiNext(unsigned char *puch); +unsigned char *NWAnsiPrev(unsigned char *psz, unsigned char *puch); diff --git a/private/nw/nwscript/inc/ntnw.h b/private/nw/nwscript/inc/ntnw.h new file mode 100644 index 000000000..a89e15720 --- /dev/null +++ b/private/nw/nwscript/inc/ntnw.h @@ -0,0 +1,46 @@ + +/************************************************************************* +* +* NTNW.H +* +* NT specific NetWare defines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\INC\VCS\NTNW.H $ +* +* Rev 1.1 22 Dec 1995 14:20:20 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:05:34 terryt +* Initial revision. +* +* Rev 1.0 15 May 1995 19:09:36 terryt +* Initial revision. +* +*************************************************************************/ + +/* + * This must be kept in sync with the NWAPI32 library. This are + * internal data structures and routines. + */ +typedef struct _NWC_SERVER_INFO { + HANDLE hConn ; + UNICODE_STRING ServerString ; +} NWC_SERVER_INFO, *PNWC_SERVER_INFO ; + +extern NTSTATUS +NwlibMakeNcp( + IN HANDLE DeviceHandle, + IN ULONG FsControlCode, + IN ULONG RequestBufferSize, + IN ULONG ResponseBufferSize, + IN PCHAR FormatString, + ... // Arguments to FormatString + ); + +DWORD szToWide( LPWSTR lpszW, LPCSTR lpszC, INT nSize ); +DWORD WideTosz( LPSTR lpszC, LPWSTR lpszW, INT nSize ); + +extern TCHAR NW_PROVIDER[60]; + diff --git a/private/nw/nwscript/inc/nwlibs.h b/private/nw/nwscript/inc/nwlibs.h new file mode 100644 index 000000000..64a187e52 --- /dev/null +++ b/private/nw/nwscript/inc/nwlibs.h @@ -0,0 +1,371 @@ + +/************************************************************************* +* +* NWLIBS.H +* +* Prototypes +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\INC\VCS\NWLIBS.H $ +* +* Rev 1.1 22 Dec 1995 14:20:28 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:05:36 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 17:03:46 terryt +* CAPTURE support +* +* Rev 1.0 15 May 1995 19:09:40 terryt +* Initial revision. +* +*************************************************************************/ + +/*++ + +Copyright (c) 1994 Micro Computer Systems, Inc. + +Module Name: + + nwlibs\nwlibs.h + +Abstract: + + NW Libs prototypes. + +Author: + + Shawn Walker (v-swalk) 10-10-1994 + +Revision History: + +--*/ + +#ifndef _NWLIBS_H_ +#define _NWLIBS_H_ + + +/*++ +******************************************************************* + NetWare defaults +******************************************************************* +--*/ +#define NCP_BINDERY_OBJECT_NAME_LENGTH 48 +#define NCP_SERVER_NAME_LENGTH NCP_BINDERY_OBJECT_NAME_LENGTH + +#define NCP_MAX_PATH_LENGTH 255 +#define NCP_VOLUME_LENGTH 256 // 16 in 3X + + +/*++ +******************************************************************* + Defines for GetDrive Status +******************************************************************* +--*/ + +#define NETWARE_UNMAPPED_DRIVE 0x0000 +#define NETWARE_FREE_DRIVE 0x0000 +#define NETWARE_LOCAL_FREE_DRIVE 0x0800 +#define NETWARE_LOCAL_DRIVE 0x1000 +#define NETWARE_NETWORK_DRIVE 0x2000 +#define NETWARE_LITE_DRIVE 0x4000 +#define NETWARE_PNW_DRIVE 0x4000 +#define NETWARE_NETWARE_DRIVE 0x8000 + +#define NETWARE_FORMAT_NETWARE 0 +#define NETWARE_FORMAT_SERVER_VOLUME 1 +#define NETWARE_FORMAT_DRIVE 2 +#define NETWARE_FORMAT_UNC 3 + +#define NCP_JOB_DESCRIPTION_LENGTH 50 +#define NCP_BANNER_TEXT_LENGTH 13 +#define NCP_FORM_NAME_LENGTH 13 +#define NCP_QUEUE_NAME_LENGTH 65 + +#define CAPTURE_FLAG_PRINT_BANNER 0x80 +#define CAPTURE_FLAG_EXPAND_TABS 0x40 +#define CAPTURE_FLAG_NOTIFY 0x10 +#define CAPTURE_FLAG_NO_FORMFEED 0x08 +#define CAPTURE_FLAG_KEEP 0x04 +#define DEFAULT_PRINT_FLAGS 0xC0 +#define DEFAULT_BANNER_TEXT "LPT:" + +typedef struct _NETWARE_CAPTURE_FLAGS_RW { + unsigned char JobDescription[NCP_JOB_DESCRIPTION_LENGTH]; + unsigned char JobControlFlags; + unsigned char TabSize; + unsigned short NumCopies; + unsigned short PrintFlags; + unsigned short MaxLines; + unsigned short MaxChars; + unsigned char FormName[NCP_FORM_NAME_LENGTH]; + unsigned char Reserved1[9]; + unsigned short FormType; + unsigned char BannerText[NCP_BANNER_TEXT_LENGTH]; + unsigned char Reserved2; + unsigned short FlushCaptureTimeout; + unsigned char FlushCaptureOnClose; +} NETWARE_CAPTURE_FLAGS_RW, *PNETWARE_CAPTURE_FLAGS_RW, *LPNETWARE_CAPTURE_FLAGS_RW; + +typedef struct _NETWARE_CAPTURE_FLAGS_RO { + unsigned short ConnectionID; + unsigned short SetupStringMaxLen; + unsigned short ResetStringMaxLen; + unsigned char LPTCaptureFlag; + unsigned char FileCaptureFlag; + unsigned char TimingOutFlag; + unsigned char InProgress; + unsigned char PrintQueueFlag; + unsigned char PrintJobValid; + unsigned char QueueName[NCP_QUEUE_NAME_LENGTH]; + unsigned char ServerName[NCP_SERVER_NAME_LENGTH]; +} NETWARE_CAPTURE_FLAGS_RO, *PNETWARE_CAPTURE_FLAGS_RO, *LPNETWARE_CAPTURE_FLAGS_RO; + +#define NETWARE_CAPTURE_FLAGS_RO_SIZE sizeof(NETWARE_CAPTURE_FLAGS_RO) +#define NETWARE_CAPTURE_FLAGS_RW_SIZE sizeof(NETWARE_CAPTURE_FLAGS_RW) + +#define PS_FORM_NAME_SIZE 12 +#define PS_BANNER_NAME_SIZE 12 +#define PS_BANNER_FILE_SIZE 12 +#define PS_DEVICE_NAME_SIZE 32 +#define PS_MODE_NAME_SIZE 32 + +#define PS_BIND_NAME_SIZE NCP_BINDERY_OBJECT_NAME_LENGTH +#define PS_MAX_NAME_SIZE 514 + +/** Flags for the PS_JOB_REC structure PrintJobFlag field **/ + +#define PS_JOB_EXPAND_TABS 0x00000001 /* File type:0=Stream 1=Tab */ +#define PS_JOB_NO_FORMFEED 0x00000002 /* Formfeed tail:0=Yes 1=No */ +#define PS_JOB_NOTIFY 0x00000004 /* Notify:0=No 1=Yes */ +#define PS_JOB_PRINT_BANNER 0x00000008 /* Banner:0=No 1=Yes */ +#define PS_JOB_AUTO_END 0x00000010 /* Auto endcap:0=No 1=Yes */ +#define PS_JOB_TIMEOUT 0x00000020 /* Enable T.O.:0=No 1=Yes */ + +#define PS_JOB_ENV_DS 0x00000040 /* Use D.S. Environment */ +#define PS_JOB_ENV_MASK 0x000001C0 /* Bindery vs. D.S. Mask */ + +#define PS_JOB_DS_PRINTER 0x00000200 /* D.S. Printer not Queue */ +#define PS_JOB_PRINTER_MASK 0x00000E00 /* D.S. Printer vs. Queue */ + +/** Default Flags **/ + +#define PS_JOB_DEFAULT (NWPS_JOB_PRINT_BANNER | NWPS_JOB_AUTO_END) +#define PS_JOB_DEFAULT_COPIES 1 /* Default Number of Copies */ +#define PS_JOB_DEFAULT_TAB 8 /* Default Tab Expansion */ + +typedef struct _PS_JOB_RECORD { + DWORD PrintJobFlag; + SHORT Copies; + SHORT TimeOutCount; + UCHAR TabSize; + UCHAR LocalPrinter; + CHAR FormName[PS_FORM_NAME_SIZE + 2]; + CHAR Name[PS_BANNER_NAME_SIZE + 2]; + CHAR BannerName[PS_BANNER_FILE_SIZE + 2]; + CHAR Device[PS_DEVICE_NAME_SIZE + 2]; + CHAR Mode[PS_MODE_NAME_SIZE + 2]; + union { + struct { + /** Pad structures on even boundries **/ + + CHAR FileServer[PS_BIND_NAME_SIZE + 2]; + CHAR PrintQueue[PS_BIND_NAME_SIZE + 2]; + CHAR PrintServer[PS_BIND_NAME_SIZE + 2]; + } NonDS; + CHAR DSObjectName[PS_MAX_NAME_SIZE]; + } u; + UCHAR Reserved[392]; +} PS_JOB_RECORD, *PPS_JOB_RECORD; + +#define PS_JOB_RECORD_SIZE sizeof(PS_JOB_RECORD) + + +/*++ +******************************************************************* + FUCNTION PROTOTYPES +******************************************************************* +--*/ + +/** ATTACH.C **/ + +unsigned int +AttachToFileServer( + unsigned char *pServerName, + unsigned int *pNewConnectionId + ); + +unsigned int +DetachFromFileServer( + unsigned int ConnectionId + ); + +/** NCP.C **/ + +unsigned int +GetBinderyObjectID( + unsigned int ConnectionHandle, + char *pObjectName, + unsigned short ObjectType, + unsigned long *pObjectId + ); + + +/** CONNECT.C **/ + +unsigned int +GetDefaultConnectionID( + unsigned int *pConnectionHandle + ); + +unsigned int +GetConnectionHandle( + unsigned char *pServerName, + unsigned int *pConnectionHandle + ); + +unsigned int +GetConnectionNumber( + unsigned int ConnectionHandle, + unsigned int *pConnectionNumber + ); + +unsigned int +GetFileServerName( + unsigned int ConnectionHandle, + char *pServerName + ); + +unsigned int +GetInternetAddress( + unsigned int ConnectionHandle, + unsigned int ConnectionNumber, + unsigned char *pInternetAddress + ); + +/** DRIVE.C **/ + +unsigned int +GetDriveStatus( + unsigned short DriveNumber, + unsigned short PathFormat, + unsigned short *pStatus, + unsigned int *pConnectionHandle, + unsigned char *pRootPath, + unsigned char *pRelativePath, + unsigned char *pFullPath + ); + +unsigned int +GetFirstDrive( + unsigned short *pFirstDrive + ); + +unsigned int +ParsePath( + unsigned char *pPath, + unsigned char *pServerName, //OPTIONAL + unsigned char *pVolumeName, //OPTIONAL + unsigned char *pDirPath //OPTIONAL + ); + +unsigned int +SetDriveBase( + unsigned short DriveNumber, + unsigned char *ServerName, + unsigned int DirHandle, + unsigned char *pDirPath + ); + +unsigned int +DeleteDriveBase( + unsigned short DriveNumber + ); + +unsigned int +GetDirectoryPath( + unsigned char ConnectionHandle, + unsigned char Handle, + unsigned char *pPath + ); + +unsigned int +IsDriveRemote( + unsigned char DriveNumber, + unsigned int *pRemote + ); + +/** CAPTURE.C **/ + +unsigned int +EndCapture( + unsigned char LPTDevice + ); + +#define PS_ERR_BAD_VERSION 0x7770 +#define PS_ERR_GETTING_DEFAULT 0x7773 +#define PS_ERR_OPENING_DB 0x7774 +#define PS_ERR_READING_DB 0x7775 +#define PS_ERR_READING_RECORD 0x7776 +#define PS_ERR_INTERNAL_ERROR 0x7779 +#define PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + +unsigned int +PSJobGetDefault( + unsigned int ConnectionHandle, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ); + +unsigned int +PSJobRead( + unsigned int ConnectionHandle, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ); + +unsigned int +PS40JobGetDefault( + unsigned int NDSCaptureFlag, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ); + +unsigned int +PS40JobRead( + unsigned int NDSCaptureFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ); + +unsigned int +GetCaptureFlags( + unsigned char LPTDevice, + PNETWARE_CAPTURE_FLAGS_RW pCaptureFlagsRW, + PNETWARE_CAPTURE_FLAGS_RO pCaptureFlagsRO + ); + +unsigned int +StartQueueCapture( + unsigned int ConnectionHandle, + unsigned char LPTDevice, + unsigned char *pServerName, + unsigned char *pQueueName + ); + +unsigned int +GetDefaultPrinterQueue ( + unsigned int ConnectionHandle, + unsigned char *pServerName, + unsigned char *pQueueName + ); + +#endif /* _NWLIBS_H_ */ diff --git a/private/nw/nwscript/inc/nwscript.h b/private/nw/nwscript/inc/nwscript.h new file mode 100644 index 000000000..d930e7818 --- /dev/null +++ b/private/nw/nwscript/inc/nwscript.h @@ -0,0 +1,321 @@ +/****************************************************************************** +* +* NWSCRIPT.H +* +* This module contains typedefs and defines required for the +* NetWare script utility. +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\INC\VCS\NWSCRIPT.H $ +* +* Rev 1.10 18 Apr 1996 16:53:02 terryt +* Various enhancements +* +* Rev 1.9 10 Apr 1996 14:22:36 terryt +* Hotfix for 21181hq +* +* Rev 1.10 12 Mar 1996 19:42:52 terryt +* Relative NDS name support +* +* Rev 1.9 07 Mar 1996 18:34:46 terryt +* Misc fixes +* +* Rev 1.8 22 Jan 1996 16:44:02 terryt +* Add automatic map attaches +* +* Rev 1.7 08 Jan 1996 13:58:34 terryt +* Correct NDS Preferred Server +* +* Rev 1.6 05 Jan 1996 17:19:08 terryt +* Ensure context is the correct login default +* +* Rev 1.5 04 Jan 1996 18:58:34 terryt +* Bug fixes reported by MS +* +* Rev 1.4 22 Dec 1995 14:20:34 terryt +* Add Microsoft headers +* +* Rev 1.3 28 Nov 1995 17:13:56 terryt +* Cleanup resource file +* +* Rev 1.2 22 Nov 1995 15:44:34 terryt +* Use proper NetWare user name call +* +* Rev 1.1 20 Nov 1995 16:11:34 terryt +* Context and capture changes +* +* Rev 1.0 15 Nov 1995 18:05:38 terryt +* Initial revision. +* +* Rev 1.5 25 Aug 1995 17:03:52 terryt +* CAPTURE support +* +* Rev 1.4 18 Jul 1995 16:07:52 terryt +* Screen out capture commands +* +* Rev 1.3 17 Jul 1995 09:43:02 terryt +* Use Microsoft name for environment +* +* Rev 1.2 23 Jun 1995 09:49:58 terryt +* Add error message for mapping over MS network drive +* +* Rev 1.1 23 May 1995 19:38:14 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:09:42 terryt +* Initial revision. +* +******************************************************************************/ + + +#define SCRIPT_ENVIRONMENT_VALUENAME L"Volatile Environment" +#define REGISTRY_PROVIDER L"System\\CurrentControlSet\\Services\\NWCWorkstation\\networkProvider" +#define REGISTRY_PROVIDERNAME L"Name" + +typedef enum SYNTAX +{ + NDSI_UNKNOWN, /* 0 */ + NDSI_DIST_NAME, /* 1 */ + NDSI_CE_STRING, /* 2 */ + NDSI_CI_STRING, /* 3 */ + NDSI_PR_STRING, /* 4 */ + NDSI_NU_STRING, /* 5 */ + NDSI_CI_LIST, /* 6 */ + NDSI_BOOLEAN, /* 7 */ + NDSI_INTEGER, /* 8 */ + NDSI_OCTET_STRING, /* 9 */ + NDSI_TEL_NUMBER, /* 10 */ + NDSI_FAX_NUMBER, /* 11 */ + NDSI_NET_ADDRESS, /* 12 */ + NDSI_OCTET_LIST, /* 13 */ + NDSI_EMAIL_ADDRESS, /* 14 */ + NDSI_PATH, /* 15 */ + NDSI_REPLICA_POINTER, /* 16 */ + NDSI_OBJECT_ACL, /* 17 */ + NDSI_PO_ADDRESS, /* 18 */ + NDSI_TIMESTAMP, /* 19 */ + NDSI_CLASS_NAME, /* 20 */ + NDSI_STREAM, /* 21 */ + NDSI_COUNTER, /* 22 */ + NDSI_BACK_LINK, /* 23 */ + NDSI_TIME, /* 24 */ + NDSI_TYPED_NAME, /* 25 */ + NDSI_HOLD, /* 26 */ + NDSI_INTERVAL, /* 27 */ + NDSI_TAX_COUNT /* 28 */ +} SYNTAX; + +#define DSCL_AFP_SERVER "AFP Server" +#define DSCL_ALIAS "Alias" +#define DSCL_BINDERY_OBJECT "Bindery Object" +#define DSCL_BINDERY_QUEUE "Bindery Queue" +#define DSCL_COMPUTER "Computer" +#define DSCL_COUNTRY "Country" +#define DSCL_DEVICE "Device" +#define DSCL_DIRECTORY_MAP "Directory Map" +#define DSCL_EXTERNAL_ENTITY "External Entity" +#define DSCL_GROUP "Group" +#define DSCL_LIST "List" +#define DSCL_LOCALITY "Locality" +#define DSCL_MESSAGE_ROUTING_GROUP "Message Routing Group" +#define DSCL_MESSAGING_SERVER "Messaging Server" +#define DSCL_NCP_SERVER "NCP Server" +#define DSCL_ORGANIZATION "Organization" +#define DSCL_ORGANIZATIONAL_PERSON "Organizational Person" +#define DSCL_ORGANIZATIONAL_ROLE "Organizational Role" +#define DSCL_ORGANIZATIONAL_UNIT "Organizational Unit" +#define DSCL_PARTITION "Partition" +#define DSCL_PERSON "Person" +#define DSCL_PRINT_SERVER "Print Server" +#define DSCL_PRINTER "Printer" +#define DSCL_PROFILE "Profile" +#define DSCL_QUEUE "Queue" +#define DSCL_RESOURCE "Resource" +#define DSCL_SERVER "Server" +#define DSCL_TOP "Top" +#define DSCL_UNKNOWN "Unknown" +#define DSCL_USER "User" +#define DSCL_VOLUME "Volume" + +#define DSAT_HOST_SERVER "Host Server" +#define DSAT_HOST_RESOURCE_NAME "Host Resource Name" +#define DSAT_PATH "Path" + +void ConvertUnicodeToAscii( PVOID ); + +void NTGetTheDate( unsigned int *, unsigned char *, unsigned char * ); +void NTGetVersionOfShell( char *, unsigned char *, unsigned char *, unsigned char * ); +void NTBreakOff( void ); +void NTBreakOn( void ); +unsigned short NTNetWareDriveStatus( unsigned short ); +unsigned int NTGetNWDrivePath( unsigned short, unsigned char *, unsigned char * ); +char * NTNWtoUNCFormat( char * ); +unsigned int NTLoginToFileServer( char *, char *, char * ); +unsigned int NTAttachToFileServer( unsigned char *, unsigned int * ); +unsigned int NTIsConnected( unsigned char * ); +unsigned int NTSetDriveBase( unsigned char *, unsigned char *, unsigned char * ); +unsigned int NTGetUserID( unsigned int, unsigned long * ); +unsigned int NTIsNetWareDrive( unsigned int ); +void NTInitProvider( void ); +void DisplayMessage( unsigned int, ... ); +void DisplayOemString( char * ); +void ExportEnv( unsigned char * ); +void ExportCurrentDirectory( int ); +void ExportCurrentDrive( int ); +void GetOldPaths( void ); +void NTPrintExtendedError( void ); +unsigned int NTGetCurrentDirectory( unsigned char, unsigned char * ); +void Capture( char ** argv, unsigned int ); +unsigned int ConverNDSPathToNetWarePathA(char *, char *, char *); + +#define CONTEXT_MAX 256 +#define ATTRBUFSIZE 2048 +#define NDS_NAME_CHARS 1024 + + +unsigned int NDSInitUserProperty( void ); +unsigned int NDSGetUserProperty( PBYTE, PBYTE Data, unsigned int, SYNTAX *, unsigned int * ); +void NDSGetVar ( PBYTE, PBYTE, unsigned int ); +unsigned int NDSChangeContext( PBYTE ); +unsigned int NDSGetContext( PBYTE, unsigned int ); +unsigned int Is40Server( unsigned int ); +unsigned int NDSfopenStream ( PBYTE, PBYTE, PHANDLE, unsigned int * ); +unsigned int IsMemberOfNDSGroup( PBYTE ); +unsigned int NDSGetProperty ( PBYTE, PBYTE, PBYTE, unsigned int, unsigned int * ); +unsigned int NDSTypeless( LPSTR, LPSTR ); +void CleanupExit( int ); +void NDSCleanup( void ); +int NTGetNWUserName( PWCHAR, PWCHAR, int ); +unsigned int NDSGetClassName( LPSTR, LPSTR ); + +unsigned int NDSCanonicalizeName( PBYTE, PBYTE, int, int ); + +#define LIST_3X_SERVER 1 +#define LIST_4X_SERVER 2 + +BOOL IsServerInAttachList( char *, unsigned int ); +void AddServerToAttachList( char *, unsigned int ); +int DoAttachProcessing( char * ); + +#define FLAGS_LOCAL_CONTEXT 0x1 +#define FLAGS_NO_CONTEXT 0x2 +#define FLAGS_TYPED_NAMES 0x4 + +unsigned int NDSAbbreviateName( DWORD, LPSTR, LPSTR ); + +/* + * Resource string IDs + */ +#define IDR_ERROR 100 +#define IDR_NO_DEFAULT_CONNECTION 101 +#define IDR_NO_KNOWN_FILE_SERVER 102 +#define IDR_LOCAL_DRIVE 103 +#define IDR_NETWARE_DRIVE 104 +#define IDR_DASHED_LINE 105 +#define IDR_LOCAL_SEARCH 106 +#define IDR_NETWARE_SEARCH 107 +#define IDR_NOT_ENOUGH_MEMORY 108 +#define IDR_PASSWORD 109 +#define IDR_ATTACHED 110 +#define IDR_ACCESS_DENIED 111 +#define IDR_UNAUTHORIZED_LOGIN_TIME 112 +#define IDR_LOGIN_DENIED_NO_CONNECTION 113 +#define IDR_UNAUTHORIZED_LOGIN_STATION 114 +#define IDR_ACCOUNT_DISABLED 115 +#define IDR_PASSWORD_EXPRIED_NO_GRACE 116 +#define IDR_MAP_NOT_ATTACHED_SERVER 117 +#define IDR_MAP_USAGE 118 +#define IDR_UNDEFINED 119 +#define IDR_DIRECTORY_NOT_FOUND 120 +#define IDR_VOLUME_NOT_EXIST 121 +#define IDR_WRONG_DRIVE 122 +#define IDR_DEL_DRIVE 123 +#define IDR_DEL_SEARCH_DRIVE 124 +#define IDR_SEARCH_DRIVE_NOT_EXIST 125 +#define IDR_NOT_NETWORK_DRIVE 126 +#define IDR_NO_DRIVE_AVAIL 127 +#define IDR_INVALID_PATH 128 +#define IDR_CAN_NOT_CHANGE_DRIVE 129 +#define IDR_MAP_INVALID_PATH 130 +#define IDR_MAP_FAILED 131 +#define IDR_NO_SCRIPT_FILE 132 +#define IDR_STRIKE_KEY 133 +#define IDR_CANNOT_EXECUTE 134 +#define IDR_ENOENT 135 +#define IDR_EXIT_NOT_SUPPORTED 136 +#define IDR_IF_TOO_DEEP 137 +#define IDR_SCRIPT_ERROR 138 +#define IDR_ORIGINAL_LINE_WAS 139 +#define IDR_BAD_COMMAND 140 +#define IDR_LABEL_NOT_FOUND 141 +#define IDR_NO_VOLUME 142 +#define IDR_ERROR_DURING 143 +#define IDR_MAP_ERROR 144 +#define IDR_ENTER_SERVER_NAME 145 +#define IDR_ENTER_LOGIN_NAME 146 +#define IDR_ERROR_SET_DEFAULT_DRIVE 147 +#define IDR_ERROR_OPEN_SCRIPT 148 +#define IDR_DIVIDE_BY_ZERO 149 +#define IDR_NEWLINE 150 +#define IDR_SERVER_USER 151 +#define IDR_NON_NETWARE_NETWORK_DRIVE 152 +#define IDR_CAPTURE_USAGE 153 +#define IDR_COPIES_EXPECTED 154 +#define IDR_COPIES_OUTOF_RANGE 155 +#define IDR_FILE_CAPTURE_UNSUPPORTED 156 +#define IDR_FORM_EXPECTED 157 +#define IDR_INVALID_BANNER 158 +#define IDR_INVALID_FORM_NAME 159 +#define IDR_INVALID_FORM_TYPE 160 +#define IDR_INVALID_LPT_NUMBER 161 +#define IDR_INVALID_PATH_NAME 162 +#define IDR_JOB_NOT_FOUND 163 +#define IDR_LPT_NUMBER_EXPECTED 164 +#define IDR_LPT_STATUS 165 +#define IDR_NOT_ACTIVE 166 +#define IDR_NO_AUTOENDCAP 167 +#define IDR_NO_PRINTERS 168 +#define IDR_LPT_STATUS_NO_BANNER 169 +#define IDR_QUEUE_NOT_EXIST 170 +#define IDR_SERVER_NOT_FOUND 171 +#define IDR_SUCCESS_QUEUE 172 +#define IDR_TABSIZE_OUTOF_RANGE 173 +#define IDR_TAB_SIZE_EXPECTED 174 +#define IDR_TIMEOUT_OUTOF_RANGE 175 +#define IDR_TIME_OUT_EXPECTED 176 +#define IDR_UNKNOW_FLAG 177 +#define IDR_DISABLED 178 +#define IDR_ENABLED 179 +#define IDR_YES 180 +#define IDR_NO 181 +#define IDR_SECONDS 182 +#define IDR_CONVERT_TO_SPACE 183 +#define IDR_NO_CONVERSION 184 +#define IDR_NOTIFY_USER 185 +#define IDR_NOT_NOTIFY_USER 186 +#define IDR_NONE 187 +#define IDR_CONNECTION_REFUSED 188 +#define IDR_LASTLOGIN_PM 189 +#define IDR_LASTLOGIN_AM 190 +#define IDR_ALL_LOCAL_DRIVES 191 +#define IDR_CHANGE_CONTEXT_ERROR 192 +#define IDR_GET_CONTEXT_ERROR 193 +#define IDR_DISPLAY_CONTEXT 194 +#define IDR_LPT_STATUS_NDS 195 +#define IDR_LPT_STATUS_NO_BANNER_NDS 196 +#define IDR_NO_QUEUE 197 +#define IDR_LASTLOGIN 198 +#define IDR_TREE_OPEN_FAILED 199 +#define IDR_NDS_CONTEXT_INVALID 200 +#define IDR_NDS_USERNAME_FAILED 201 +#define IDR_QUERY_INFO_FAILED 202 +#define IDR_NO_RESPONSE 203 +#define IDR_NDSQUEUE_NOT_EXIST 204 +#define IDR_NDSSUCCESS_QUEUE 205 +#define IDR_CAPTURE_FAILED 206 +#define IDR_CURRENT_TREE 207 +#define IDR_CURRENT_SERVER 208 +#define IDR_CURRENT_CONTEXT 209 +#define IDR_AUTHENTICATING_SERVER 210 +#define IDR_NO_END_QUOTE 211 diff --git a/private/nw/nwscript/lsparse.c b/private/nw/nwscript/lsparse.c new file mode 100644 index 000000000..1b0e67fd1 --- /dev/null +++ b/private/nw/nwscript/lsparse.c @@ -0,0 +1,315 @@ +/* + * LSPARSE.C - NetWare Login Script processing routines for our Win32 + * NetWare 3.x LOGIN clone. + * + * Based on code contained in NWPARSE.C, written by Xiao Ying Ding. + * + * Modified and re-written for Win32 by J. SOUZA, February 1994. + * + * Modified for NT by Terry Treder + * + * Copyright (C)1994 Microsoft Corporation. + * + */ + +#include + +/******************************************************************** + + ConverNDSPathToNetWarePathA + +Routine Description: + + Convert a NDS path to a Netware format path + +Arguments: + ndspath - origninal NDS path + objclass - type of NDS object, NULL if unknown + nwpath - Netware format path + +Return Value: + error + + *******************************************************************/ +unsigned int +ConverNDSPathToNetWarePathA(char *ndspath, char *objclass, char *nwpath) +{ + CHAR szDN[MAX_PATH]; + CHAR szObjName[MAX_PATH]; + CHAR cSave; + CHAR className[MAX_PATH]; + + LPSTR lpDelim = NULL; + LPSTR lpFilePath = ""; + LPSTR lpszValue; + LPSTR path; + LPSTR volume; + + DWORD dwRet; + DWORD length; + UINT NWStatus; + char bufAttribute[2048]; + + // optimize for path beginning with drive letter + // This assumes NDS volume and dir map names are at least 2 chars + + if (ndspath[1] == ':') + return 1; + // strip ':' from path before this call + if ( ( lpDelim = strchr(ndspath,':') ) != NULL + || ((lpDelim = strchr(ndspath,'\\')) != NULL)) { + cSave = *lpDelim; + *lpDelim = '\0'; + lpFilePath = lpDelim+1; + } + + if ( objclass == NULL ) { + + NWStatus = NDSCanonicalizeName( ndspath, szObjName, MAX_PATH, TRUE ); + + if ( NWStatus != 0 ) { +#ifdef DEBUG + printf("can't canonicalize [%s] (0x%x)\n", + ndspath, NWStatus ); +#endif + + if (lpDelim) { + *lpDelim = cSave; + } + + return 1; + } + + + NWStatus = NDSGetClassName( szObjName, className ); + + if ( NWStatus != 0 || + strcmp ( className, DSCL_SERVER ) && + strcmp ( className, DSCL_NCP_SERVER ) && + strcmp ( className, DSCL_VOLUME ) && + strcmp ( className, DSCL_QUEUE ) && + strcmp ( className, DSCL_DIRECTORY_MAP )) { + +#ifdef DEBUG + printf("no path DSOBJ: %d (%s) (%s)\n", + NWStatus, szObjName, className ); +#endif + + if (lpDelim) { + *lpDelim = cSave; + } + + return 1; + } + + objclass = className; + } + else + strcpy ( szObjName, ndspath ); + + if (lpDelim) { + *lpDelim = cSave; + } + +#ifdef DEBUG + printf("ConvertNDSPath BEFORE [%s]\n", szObjName); +#endif + + // + // Is f this is the server class object , we only need + // to extract it's common name and put into netware format + // + if ((strcmp(objclass,DSCL_SERVER) == 0 ) || + (strcmp(objclass,DSCL_NCP_SERVER) == 0 )) { + + // Abbreaviate first to remove type qualifiers + *szDN = '\0'; + if (0 != NDSAbbreviateName(FLAGS_LOCAL_CONTEXT,(LPSTR)szObjName,szDN)) { + return 1; + } + + // BUGBUG THis code should be separated as tokenizing function + lpDelim = strchr(szDN,'.'); + if (lpDelim) { + *lpDelim = '\0'; + } + + strcpy(nwpath,szDN); + +#ifdef DEBUG + printf("Returning Netware path:%s\n",nwpath); +#endif + + return 0; + + } /* endif server class */ + + // + // If this is share class object ( volume or queue), we need + // to find it's host server name and host resource name + // + if ((strcmp(objclass,DSCL_VOLUME) == 0 ) || + (strcmp(objclass,DSCL_QUEUE) == 0 ) + ) { + + // + // Read host server name first. It comes back as distinguished + // directory name, so we will need to extract server name from it + // + + NWStatus = NDSGetProperty ( szObjName, + DSAT_HOST_SERVER, + bufAttribute, + sizeof(bufAttribute), + NULL ); + + if (NWStatus != 0) { +#ifdef DEBUG + printf("Get host server failed. err=0x%x\n",NWStatus); +#endif + return 1; + } + + lpszValue = bufAttribute; + ConvertUnicodeToAscii( lpszValue ); + + // + // Now copy server distinguished name into temporary buffer + // and call ourselves to convert it to Netware + // + strcpy(szDN,lpszValue); + + dwRet = ConverNDSPathToNetWarePathA(szDN, DSCL_SERVER, nwpath); + if (dwRet) { +#ifdef DEBUG + printf("Resolving server DN failed\n"); +#endif + //Break(); + return 1; + } + + // + // Get volume name itself + // + NWStatus = NDSGetProperty ( szObjName, + DSAT_HOST_RESOURCE_NAME, + bufAttribute, + sizeof(bufAttribute), + NULL ); + + if (NWStatus != 0) { +#ifdef DEBUG + printf("Get host resource name failed. err=0x%x\n",NWStatus); +#endif + return 1; + } + + lpszValue = bufAttribute; + ConvertUnicodeToAscii( lpszValue ); + + // + // Now we already have server name in the user buffer, + // append share name to it + strcat(nwpath,"/"); + strcat(nwpath,lpszValue); + strcat(nwpath,":"); + strcat(nwpath, lpFilePath ); + +#ifdef DEBUG + printf("Returning Netware path:%s\n",nwpath); +#endif + + return 0; + + } /* endif Volume class */ + + // + // For directory maps we need to find host volume NDS name and + // append relative directory path + // + if (strcmp(objclass,DSCL_DIRECTORY_MAP) == 0 ) { + + // + // First get NDS name for host volume object + // + + NWStatus = NDSGetProperty ( szObjName, + DSAT_PATH, + bufAttribute, + sizeof(bufAttribute), + NULL ); + + if (NWStatus != 0) { +#ifdef DEBUG + printf("Get path %s failed. err=0x%x\n", szObjName, NWStatus); +#endif + return 1; + } + + volume = bufAttribute; + volume += sizeof(DWORD); + volume += sizeof(DWORD); + ConvertUnicodeToAscii( volume ); + + // Path is next + + path = bufAttribute; + path += sizeof(DWORD); + length = ROUNDUP4(*(DWORD *)path); + path += sizeof(DWORD); + path += length; + + // + // Check for 0 length paths + // + if ( *(DWORD *)path == 0 ) { + path = ""; + } + else { + path += sizeof(DWORD); + ConvertUnicodeToAscii( path ); + } + +#ifdef DEBUG + printf("path is %s\n",path); +#endif + + // + // Now copy volume distinguished name into temporary buffer + // and call ourselves to convert it to NetWare + // + strcpy(szDN,volume); + + dwRet = ConverNDSPathToNetWarePathA(szDN, DSCL_VOLUME, nwpath); + if (dwRet) { +#ifdef DEBUG + printf("Resolving volume DN failed\n"); +#endif + //Break(); + return 1; + } + + // + // Now we already have NetWare server\volume name in the user buffer, + // append directory path to it + //strcat(nwpath,"\\"); + // we want only one '\' + if (path[0] == '\\' || path[0] == '/') path++; + strcat(nwpath,path); + // append non-NDS part of path, if any + if (*lpFilePath) { + strcat(nwpath,"/"); + strcat(nwpath, lpFilePath ); + } + +#ifdef DEBUG + printf("Returning NetWare path:%s\n",nwpath); +#endif + + return 0; + + } /* endif DirectoryMap class */ + + return(1); +} + diff --git a/private/nw/nwscript/makefile b/private/nw/nwscript/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/nw/nwscript/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/nw/nwscript/maplist.c b/private/nw/nwscript/maplist.c new file mode 100644 index 000000000..5dbe8a132 --- /dev/null +++ b/private/nw/nwscript/maplist.c @@ -0,0 +1,252 @@ + +/************************************************************************* +* +* QATTACH.C +* +* Do any neccessary attach user queries +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\MAPLIST.C $ +* +* Rev 1.1 10 Apr 1996 14:22:42 terryt +* Hotfix for 21181hq +* +* Rev 1.1 12 Mar 1996 19:53:58 terryt +* Relative NDS names and merge +* +* Rev 1.0 22 Jan 1996 16:49:24 terryt +* Initial revision. +* +*************************************************************************/ +#include "common.h" + +// +// 4X login script behavior for map commands to servers not in the +// logged in NDS tree that have not been ATTACH'ed is different from +// the 3X behavior. +// +// The 4X behavior is to always ask for a user name and password for +// these servers, doing the attach at that point. The user gets +// two trys. +// +// Since NT doesn't have an list of attached servers, and will try +// to connect to a volume with the default user name and password, +// a wrapper must be put around the MAP commands. This code +// must determine that a bindery connection will be made and that +// this server has not previously been MAP'ed or ATTACH'ed. +// The user will be always prompted for user name and password. +// The server will then be logged into with those credentials. +// +// One problem with the below is that it's not easy to tell that +// a connection "will be" made with the bindery, this is done in +// the redirector. So to simplify things the assumption is that +// only 3X servers use bindery connections. This means that +// 4X servers using bindery emulation on a different NDS tree will +// not always be asked for the user name and password. +// +// Already processed servers are kept in a list and marked as 4X or 3X +// for possible future use. +// +// The behavior for a 3X login depends on the LOGIN.EXE version. +// The old behavior is that you must always ATTACH before mapping. +// However, if you login to a 3X server with a 4X version LOGIN.EXE +// it will try to authenticate using your user name (and password) +// on the first attempt and ask for a password if that fails. The +// second attempt will ask for your user name. Since this 4X behavior +// is more forgiving (more scripts "work") that is the one being +// emulated. +// + +typedef struct _SERVERLIST +{ + char * ServerName; + unsigned int ServerType; + struct _SERVERLIST *pNextServer; +} SERVERLIST, *PSERVERLIST; + +PSERVERLIST pMainList = NULL; + +BOOL IsServerInAttachList( char *, unsigned int ); +void AddServerToAttachList( char *, unsigned int ); +int DoAttachProcessing( char * ); + +/* + * Scan the list for the server + */ +BOOL +IsServerInAttachList( char * Server, unsigned int ServerType ) +{ + PSERVERLIST pServerList = pMainList; + + while ( pServerList != NULL ) + { + if ( !_strcmpi( Server, pServerList->ServerName ) && + ( ServerType & pServerList->ServerType ) ) + return TRUE; + pServerList = pServerList->pNextServer; + } + + return FALSE; +} + +/* + * Add the server to the list of attached servers + * + * This is used during MAP's and ATTACH's + */ +void +AddServerToAttachList( char * Server, unsigned int ServerType ) +{ + PSERVERLIST pServerList; + + pServerList = (PSERVERLIST) malloc( sizeof( SERVERLIST ) ); + + if ( pServerList == NULL ) + { + DisplayMessage( IDR_NOT_ENOUGH_MEMORY ); + return; + } + + pServerList->ServerName = _strdup( Server ); + pServerList->ServerType = ServerType; + pServerList->pNextServer = pMainList; + pMainList = pServerList; +} + +/* + * Do any Attach processing + * Return error code. 0 is success. + * 880F is the special "attached failed" error + */ + +int +DoAttachProcessing( char * PossibleServer ) +{ + unsigned int iRet = 0; + unsigned int conn; + char userName[MAX_NAME_LEN] = ""; + char password[MAX_PASSWORD_LEN] = ""; + BOOL AlreadyConnected = FALSE; + + // + // Must have a server to process + // + if ( !*PossibleServer ) + return iRet; + + // See if this server has been processed before + // No since in doing a 4X server twice, and you only ask + // for the user name and password once. + + if ( IsServerInAttachList( PossibleServer, + LIST_4X_SERVER | LIST_3X_SERVER ) ) + return iRet; + + // See if there is already a connection to the server + + if ( NTIsConnected( PossibleServer ) ) + AlreadyConnected = TRUE; + else + AlreadyConnected = FALSE; + + // Try and attach to the server + + iRet = NTAttachToFileServer( PossibleServer, &conn ); + + // If attach failed, return + + if ( iRet ) + return iRet; + + // If this is a 4X server then add it to the list of attached + // servers. We don't want to do this again. 4X servers must + // use the NDS attachment anyway (or at least I don't see a + // way of telling that it's going to be a bindery emulation + // connection ahead of time). + + if ( fNDS && Is40Server( conn ) ) + { + AddServerToAttachList( PossibleServer, LIST_4X_SERVER ); + DetachFromFileServer ( conn ); + return iRet; + } + + // Close that first connection + + DetachFromFileServer ( conn ); + + // If we are already connected, don't mess with things + // The credentials can't be changed anyway + + if ( AlreadyConnected ) + { + AddServerToAttachList( PossibleServer, LIST_3X_SERVER ); + return iRet; + } + + // Ask for user name on an NDS login + // + // Use the current login name for a 3X login on the first attempt + + if ( fNDS ) + { + DisplayMessage(IDR_ENTER_LOGIN_NAME, PossibleServer); + if (!ReadName(userName)) + return 0x880F; + } + else + { + strncpy( userName, LOGIN_NAME, sizeof( userName ) ); + } + + // Try to log the user in, asking for a password + + iRet = Login( userName, + PossibleServer, + password, + TRUE ); + + // Clear out the password + // We don't need it again + + memset( password, 0, sizeof( password ) ); + + // If failed, give the user one more chance + + if ( iRet ) + { + // Ask for user name + + DisplayMessage(IDR_ENTER_LOGIN_NAME, PossibleServer); + if (!ReadName(userName)) + return 0x880F; + + // Try to log the user in + + iRet = Login( userName, + PossibleServer, + password, + TRUE ); + + // Clear out the password + + memset( password, 0, sizeof( password ) ); + + } + + // Add servername to list of attached servers, marked as 3X + + if ( !iRet ) + { + AddServerToAttachList( PossibleServer, LIST_3X_SERVER ); + } + else + { + iRet = 0x880F; // Special I am not attached error + } + + return iRet; + +} + diff --git a/private/nw/nwscript/ncp.c b/private/nw/nwscript/ncp.c new file mode 100644 index 000000000..72b453350 --- /dev/null +++ b/private/nw/nwscript/ncp.c @@ -0,0 +1,356 @@ + +/************************************************************************* +* +* NCP.C +* +* All routines doing direct NCPs or filecontrol operations +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NCP.C $ +* +* Rev 1.2 10 Apr 1996 14:22:50 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:54:06 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:24:56 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:10 terryt +* Initial revision. +* +*************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "nwscript.h" +#include "ntnw.h" +#include "inc/nwlibs.h" + + +/******************************************************************** + + NTGetUserID + +Routine Description: + + Given a connection handle, return the user ID + +Arguments: + + ConnectionHandle - Connection Handle + UserID - returned User ID + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int +NTGetUserID( + unsigned int ConnectionHandle, + unsigned long *pUserID + ) +{ + NTSTATUS NtStatus ; + unsigned int ObjectType; + unsigned char LoginTime[7]; + unsigned char UserName[48]; + VERSION_INFO VerInfo; + unsigned int Version; + unsigned int ConnectionNum; + PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)ConnectionHandle ; + + NtStatus = GetConnectionNumber( ConnectionHandle, &ConnectionNum ); + + if (!NT_SUCCESS(NtStatus)) + return NtStatus; + + NtStatus = NWGetFileServerVersionInfo( (NWCONN_HANDLE)ConnectionHandle, + &VerInfo ); + + if (!NT_SUCCESS(NtStatus)) + return NtStatus; + + Version = VerInfo.Version * 1000 + VerInfo.SubVersion * 10; + + if ( ( Version >= 3110 ) || ( Version < 2000 ) ) { + NtStatus = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + FSCTL_NWR_NCP_E3H, // Bindery function + 8, // Max request packet size + 63, // Max response packet size + "br|rrrr", // Format string + // === REQUEST ================================ + 0x1c, // b Get Connection Information + &ConnectionNum, 4, // r Connection Number + // === REPLY ================================== + pUserID, 4, // r Object ID + &ObjectType, 2, // r Object Type + UserName, 48, // r UserName + LoginTime, 7 // r Login Time + ); + } + else { + NtStatus = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + FSCTL_NWR_NCP_E3H, // Bindery function + 4, // Max request packet size + 63, // Max response packet size + "bb|rrrr", // Format string + // === REQUEST ================================ + 0x16, // b Get Connection Information + ConnectionNum, // b Connection Number + // === REPLY ================================== + pUserID, 4, // r Object ID + &ObjectType, 2, // r Object Type + UserName, 48, // r UserName + LoginTime, 7 // r Login Time + ); + } + + return NtStatus; +} + +/******************************************************************** + + GetConnectionNumber + +Routine Description: + + Given a ConnectionHandle, return the NetWare Connection number + +Arguments: + + ConnectionHandle - Connection Handle + pConnectionNumber - pointer to returned connection number + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int +GetConnectionNumber( + unsigned int ConnectionHandle, + unsigned int * pConnectionNumber ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + NWR_GET_CONNECTION_DETAILS Details; + PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)ConnectionHandle ; + + Status = NtFsControlFile( + pServerInfo->hConn, // Connection Handle + NULL, + NULL, + NULL, + &IoStatusBlock, + FSCTL_NWR_GET_CONN_DETAILS, + NULL, + 0, + (PVOID) &Details, + sizeof(Details)); + + if (Status == STATUS_SUCCESS) { + Status = IoStatusBlock.Status; + } + + if (NT_SUCCESS(Status)) { + *pConnectionNumber = 256 * Details.ConnectionNumberHi + + Details.ConnectionNumberLo; + } + + return Status; +} + +/******************************************************************** + + GetInternetAddress + +Routine Description: + + Return the address of the current system + +Arguments: + + ConnectionHandle - Connection Handle + ConnectionNum - Connection Number + pAddress - returned address + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int +GetInternetAddress( + unsigned int ConnectionHandle, + unsigned int ConnectionNum, + unsigned char *pAddress + ) +{ + NTSTATUS NtStatus ; + VERSION_INFO VerInfo; + unsigned int Version; + unsigned char Address[12]; + PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)ConnectionHandle ; + + NtStatus = NWGetFileServerVersionInfo( (NWCONN_HANDLE)ConnectionHandle, + &VerInfo ); + + if (!NT_SUCCESS(NtStatus)) + return NtStatus; + + Version = VerInfo.Version * 1000 + VerInfo.SubVersion * 10; + + if ( ( Version >= 3110 ) || ( Version < 2000 ) ) { + NtStatus = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + FSCTL_NWR_NCP_E3H, // Bindery function + 7, // Max request packet size + 14, // Max response packet size + "br|r", // Format string + // === REQUEST ================================ + 0x1a, // b Get Connection Information + &ConnectionNum, 4, // r Connection Number + // === REPLY ================================== + Address, 12 // r Login Time + ); + } + else { + NtStatus = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + FSCTL_NWR_NCP_E3H, // Bindery function + 4, // Max request packet size + 14, // Max response packet size + "bb|r", // Format string + // === REQUEST ================================ + 0x13, // b Get Connection Information + (unsigned char)ConnectionNum, // b Connection Number + // === REPLY ================================== + Address, 12 // r Login Time + ); + } + memcpy( pAddress, Address, 10 ); + + return NtStatus; +} + + +/******************************************************************** + + GetBinderyObjectID + +Routine Description: + + Get the object ID of a named object in the bindery + +Arguments: + + ConnectionHandle - Server connection handle + pObjectName - Name of object + ObjectType - Object type + pObjectId - returned object ID + + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int +GetBinderyObjectID( + unsigned int ConnectionHandle, + char *pObjectName, + unsigned short ObjectType, + unsigned long *pObjectId ) +{ + PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)ConnectionHandle ; + unsigned int reply; + + reply = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + FSCTL_NWR_NCP_E3H, // Directory function + 54, // Max request packet size + 56, // Max response packet size + "brp|r", // Format string + // === REQUEST ================================ + 0x35, // b Get object ID + &ObjectType, W_SIZE, // r Object type HI-LO + pObjectName, // p UserName + // === REPLY ================================== + pObjectId, 4 // 4 bytes of raw data + ); + return reply; +} + +/******************************************************************** + + GetDefaultPrinterQueue + +Routine Description: + + Get the default printer queue. + +Arguments: + ConnectionHandle - IN + Handle to server + pServerName - IN + File server name + pQueueName - OUT + Default printer queue name + + +Return Value: + + *******************************************************************/ +unsigned int +GetDefaultPrinterQueue ( + unsigned int ConnectionHandle, + unsigned char *pServerName, + unsigned char *pQueueName + ) +{ + unsigned long ObjectID; + NTSTATUS NtStatus ; + PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)ConnectionHandle ; + NWOBJ_TYPE ObjectType; + NWCCODE Nwcode; + + NtStatus = NwlibMakeNcp( + pServerInfo->hConn, // Connection Handle + NWR_ANY_F2_NCP(0x11), // F2 Function function + 4, // Max request packet size + 4, // Max response packet size + "wbb|d", // Format string + // === REQUEST ================================ + 0x2, // w Length + 0xA, // b Subfunction + 0, // b printer number + // === REPLY ================================== + &ObjectID // d Object ID of Queue + ); + + if ( !NT_SUCCESS( NtStatus ) ) + return ( NtStatus & 0xFF ); + + Nwcode = NWGetObjectName( (NWCONN_HANDLE) ConnectionHandle, + ObjectID, + pQueueName, + &ObjectType ); + + return Nwcode; +} diff --git a/private/nw/nwscript/nds.c b/private/nw/nwscript/nds.c new file mode 100644 index 000000000..1b73643f5 --- /dev/null +++ b/private/nw/nwscript/nds.c @@ -0,0 +1,1505 @@ +/************************************************************************* +* +* NDS.C +* +* NT NetWare NDS routines +* +* Copyright (c) 1995 Microsoft Corporation +* +*************************************************************************/ +#include + +DWORD GUserObjectID; +HANDLE GhRdr; + + +WCHAR * NDSTREE_w = NULL; +UNICODE_STRING NDSTREE_u; + +/******************************************************************** + + ExpandRelativeName + +Routine Description: + + If the name is a relative NDS name append the proper context + to the end. A relative name has periods on the end. Each + period represents one level up the NDS tree. + +Arguments: + +Return Value: + + *******************************************************************/ +void +ExpandRelativeName( LPSTR RelativeName, LPSTR AbsoluteName, unsigned int Len, + LPSTR Context ) +{ + + PBYTE ptr; + unsigned int i; + unsigned int count = 0; + + strncpy( AbsoluteName, RelativeName, Len ); + + if ( ( AbsoluteName[0] == '.' ) && + ( AbsoluteName[ strlen( AbsoluteName ) - 1 ] != '.' ) ) + return; + + if ( ( strlen( AbsoluteName ) + strlen( Context ) ) > Len ) + { + DisplayMessage( IDR_NOT_ENOUGH_MEMORY ); + return; + } + + if ( AbsoluteName[0] == '\0' ) + { + return; + } + + ptr = &AbsoluteName[ strlen( AbsoluteName ) - 1 ]; + + // Count the number of periods and back up over them. + + if ( *ptr != '.' ) + { + // + // No periods at the end + // Assume this is a relative name and append the context + // + strcat( AbsoluteName, "." ); + strcat( AbsoluteName + strlen( AbsoluteName ), Context ); + return; + } + + while ( *ptr == '.' ) + { + ptr--; + count++; + } + + ptr++; + *ptr = '\0'; + + // ptr now points to where the copy of the rest of the context should start + // skip the first "count" entries in the context + + ptr = Context; + + for ( i = 0; i < count; i++ ) + { + ptr = strchr( ptr, '.' ); + if ( ptr == NULL ) + { + return; + } + ptr++; + } + ptr--; + + // Now append + + strcat( AbsoluteName, ptr ); + +} + + + +/******************************************************************** + + NDSGetNameContext + +Routine Description: + + Get the current context + +Arguments: + none + +Return Value: + none + + *******************************************************************/ +NTSTATUS +NDSGetNameContext( LPSTR Context, BOOLEAN flag ) +{ + // + // For NdsResolveName. + // + + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + HANDLE hReferredServer; + DWORD dwHandleType; + + NTSTATUS Status; + + OEM_STRING oemStr; + UNICODE_STRING defaultcontext; + DWORD ThisObjectID; + BYTE Buffer[2048]; + WCHAR NdsStr[1024]; + PBYTE ptr; + + defaultcontext.Length = 0; + defaultcontext.MaximumLength = sizeof( NdsStr ); + defaultcontext.Buffer = NdsStr; + + Status = NwNdsGetTreeContext( GhRdr, &NDSTREE_u, &defaultcontext ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( GhRdr, + &defaultcontext, + &ThisObjectID, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // should change the global handle. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_NDS_USERNAME_FAILED); + return Status; + } + + CloseHandle( GhRdr ); + GhRdr = hReferredServer; + } + + Status = NwNdsReadObjectInfo( GhRdr, ThisObjectID, Buffer, 2048 ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + ptr = Buffer + sizeof( NDS_RESPONSE_GET_OBJECT_INFO ); + ptr += ROUNDUP4(*(DWORD *)ptr); + ptr += sizeof(DWORD); + ptr += sizeof(DWORD); + + defaultcontext.Length = wcslen( (WCHAR *)ptr ) * 2; + defaultcontext.MaximumLength = defaultcontext.Length; + defaultcontext.Buffer = (WCHAR *)ptr; + + oemStr.Length = 0; + oemStr.MaximumLength = NDS_NAME_CHARS; + oemStr.Buffer = Context; + + RtlUnicodeStringToOemString( &oemStr, &defaultcontext, FALSE ); + + return 0; +} + +/******************************************************************** + + NDSTypeless + +Routine Description: + + Change name to typelese + +Arguments: + none + +Return Value: + none + + *******************************************************************/ +unsigned int +NDSTypeless( LPSTR OrigName , LPSTR TypelessName ) +{ + int i,j; + PBYTE p; + + i = 0; + j = 0; + + if ( !_strnicmp( "CN=", OrigName, 3 ) || + !_strnicmp( "OU=", OrigName, 3 ) ) + { + i += 3; + } + else if ( !_strnicmp( "C=", OrigName, 2 ) || + !_strnicmp( "O=", OrigName, 2 ) ) + { + i += 2; + } + + for ( ; (( i < NDS_NAME_CHARS ) && ( OrigName[i] ) ); i++ ) + { + if ( !_strnicmp( ".CN=", &OrigName[i], 4 ) || + !_strnicmp( ".OU=", &OrigName[i], 4 ) ) + { + TypelessName[j++]= '.'; + i += 3; + continue; + } + if ( !_strnicmp( ".C=", &OrigName[i], 3 ) || + !_strnicmp( ".O=", &OrigName[i], 3 ) ) + { + TypelessName[j++]= '.'; + i += 2; + continue; + } + /* + * Strip out multiple blanks + */ + if ( !_strnicmp( " ", &OrigName[i], 2 ) ) + { + continue; + } + TypelessName[j++] = OrigName[i]; + } + + TypelessName[j] = '\0'; + + return 0; +} + +/******************************************************************** + + NDSAbbreviateName + +Routine Description: + + Abbreviate name + +Arguments: + none + +Return Value: + none + + *******************************************************************/ +unsigned int +NDSAbbreviateName( DWORD Flags, LPSTR OrigName , LPSTR AbbrevName ) +{ + BYTE Buffer[NDS_NAME_CHARS]; + BYTE CurrentContext[NDS_NAME_CHARS]; + PBYTE p; + PBYTE c; + NTSTATUS Status; + + if ( OrigName[0] == '.' ) + NDSTypeless( OrigName + 1, Buffer ); + else + NDSTypeless( OrigName, Buffer ); + + /* + * We want a relative name + */ + if ( Flags & FLAGS_LOCAL_CONTEXT ) + { + p = &Buffer[strlen(Buffer)-strlen(REQUESTER_CONTEXT)]; + if ( !_strcmpi( REQUESTER_CONTEXT, p ) ) + { + // The name is below us + + if ( ( *(p-1) == '.' ) && ( p > Buffer ) ) + p--; + *p = '\0'; + strcpy( AbbrevName, Buffer ); + } + else + { + // + // Going from back to front for each section of context + // in common with AbbrevName + // truncate both + // Going from back to front for each section of context + // left over + // concatonate a period to AbbrevName + // + // Example + // + // Name: w.x.y.z Context: a.b.z => w.x.y.. + // + + strcpy( CurrentContext, REQUESTER_CONTEXT ); + strcpy( AbbrevName, Buffer ); + + if ( CurrentContext[0] && AbbrevName[0] ) + { + c = &CurrentContext[ strlen( CurrentContext ) ] - 1; + p = &AbbrevName[ strlen( AbbrevName ) ] - 1; + + // + // Strip off the matching names from end to front + // + for ( ;; ) + { + if ( ( c == CurrentContext ) && ( *p == '.' ) ) + { + *c = '\0'; + *p = '\0'; + break; + } + + if ( *c != *p ) + break; + + if ( ( *c == '.' ) && ( *p == '.' ) ) + { + *c = '\0'; + *p = '\0'; + } + + if ( ( c == CurrentContext ) || ( p == AbbrevName ) ) + { + break; + } + + c--; p--; + } + + // + // Count the remaining sections of the context and + // add that number of periods to the end of the buffer. + // That is how far we need to back up before getting + // to a matching branch of the tree. + // + + if ( CurrentContext[0] ) { + strcat( AbbrevName, "." ); + for ( c = CurrentContext; *c; c++ ) { + if ( *c == '.' ) + strcat( AbbrevName, "." ); + } + } + } + + } + } + else + strcpy( AbbrevName, Buffer ); + + return 0; +} + + +/******************************************************************** + + NDSInitUserProperty + +Routine Description: + + none + +Arguments: + none + +Return Value: + 0 = no error + + *******************************************************************/ +unsigned int +NDSInitUserProperty( ) +{ + NTSTATUS Status; + UNICODE_STRING ObjectName; + PWCHAR lpT; + UNICODE_STRING defaultcontext; + + // + // For NdsResolveName. + // + + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + HANDLE hReferredServer; + DWORD dwHandleType; + + // + // Get a handle to the redirector. + // + + Status = NwNdsOpenTreeHandle( &NDSTREE_u, &GhRdr ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_TREE_OPEN_FAILED); + return 1; + } + + // + // Resolve the name that we have to an object id. + // + + RtlInitUnicodeString( &ObjectName, TYPED_USER_NAME_w ); + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( GhRdr, + &ObjectName, + &GUserObjectID, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_NDS_USERNAME_FAILED); + return 1; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // should change the global handle. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_NDS_USERNAME_FAILED); + return 1; + } + + CloseHandle( GhRdr ); + GhRdr = hReferredServer; + } + + // + // Set the current context to what we think it should be + // (At the user's location.) + // + + lpT = wcschr( TYPED_USER_NAME_w, L'.' ); + if ( lpT ) + { + RtlInitUnicodeString( &defaultcontext, lpT+1 ); + } + else + { + RtlInitUnicodeString( &defaultcontext, L"" ); + } + + Status = NwNdsSetTreeContext( GhRdr, &NDSTREE_u, &defaultcontext ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_NDS_CONTEXT_INVALID); + return 1; + } + + return 0; + + +} + +/******************************************************************** + + NDSCanonicalizeName + +Routine Description: + + return a canonicalized version of a name + +Arguments: + Name - original name + CanonName - Canonicalized name + Len - length of CanonName + fCurrentContext - TRUE => use current contex, FALSE use + requester context + +Return Value: + status error + + *******************************************************************/ +unsigned int +NDSCanonicalizeName( PBYTE Name, PBYTE CanonName, int Len, int fCurrentContext ) +{ + NTSTATUS Status; + int ccode = -1; + DWORD ThisObjectID; + OEM_STRING oemStr; + UNICODE_STRING ObjectName; + BYTE Buffer[2048]; + BYTE FullName[NDS_NAME_CHARS]; + PBYTE ptr; + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + DWORD dwHandleType; + HANDLE hReferredServer; + unsigned char CurrentContext[NDS_NAME_CHARS]; + + // + // Cope with relative names + // + if ( fCurrentContext ) + { + Status = NDSGetNameContext( CurrentContext, TRUE ); + if ( !NT_SUCCESS( Status ) ) + return Status; + ExpandRelativeName( Name, FullName, NDS_NAME_CHARS, CurrentContext ); + } + else + ExpandRelativeName( Name, FullName, NDS_NAME_CHARS, REQUESTER_CONTEXT ); + + // + // Fill it in in case we have an error + // + strncpy( CanonName, FullName, Len); + + // + // Resolve the name that we have to an object id. + // + // Unfortuneately, the name resolver doesn't understand periods at the + // front or end (absolute or relative names) + // + + if ( FullName[0] == '.' ) + { + oemStr.Length = strlen( FullName + 1 ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = FullName + 1; + } + else + { + oemStr.Length = strlen( FullName ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = FullName; + } + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(Buffer); + ObjectName.Buffer = (WCHAR *)Buffer; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( GhRdr, + &ObjectName, + &ThisObjectID, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // should change the global handle. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + CloseHandle( GhRdr ); + GhRdr = hReferredServer; + } + + Status = NwNdsReadObjectInfo( GhRdr, ThisObjectID, Buffer, 2048 ); + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + ptr = Buffer + sizeof( NDS_RESPONSE_GET_OBJECT_INFO ); + ptr += ROUNDUP4(*(DWORD *)ptr); + ptr += sizeof(DWORD); + ptr += sizeof(DWORD); + + RtlInitUnicodeString( &ObjectName, (PWCHAR)ptr ); + + oemStr.Length = 0; + oemStr.MaximumLength = Len; + oemStr.Buffer = CanonName; + + RtlUnicodeStringToOemString( &oemStr, &ObjectName, FALSE ); + + return 0; +} + +/******************************************************************** + + NDSGetUserProperty + +Routine Description: + + Return the NDS property for the object + +Arguments: + Property - property name + Data - data buffer + Size - size of data buffer + +Return Value: + 0 no error + + *******************************************************************/ +unsigned int +NDSGetUserProperty( PBYTE Property, + PBYTE Data, + unsigned int Size, + SYNTAX * pSyntaxID, + unsigned int * pActualSize ) +{ + NTSTATUS Status; + int ccode = -1; + + OEM_STRING oemStr; + UNICODE_STRING PropertyName; + WCHAR NdsStr[1024]; + DWORD iterhandle = INITIAL_ITERATION; + + BYTE Buffer[2048]; + DWORD BufferSize = 2048; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttribute; + PNDS_ATTRIBUTE pAttribute; + PBYTE pAttribValue; + + // + // Read the User property + // + + memset(Buffer, 0, BufferSize); + + oemStr.Length = strlen( Property ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Property; + + PropertyName.Length = 0; + PropertyName.MaximumLength = sizeof(NdsStr); + PropertyName.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &PropertyName, &oemStr, FALSE ); + + Status = NwNdsReadAttribute ( GhRdr, + GUserObjectID, + &iterhandle, + &PropertyName, + Buffer, + BufferSize ); + + if ( NT_SUCCESS(Status) ) + { + int i; + pReadAttribute = (PNDS_RESPONSE_READ_ATTRIBUTE)Buffer; + pAttribute = (PNDS_ATTRIBUTE)(Buffer + + sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + if ( pSyntaxID ) + { + *pSyntaxID = pAttribute->SyntaxID; + } + + pAttribValue = (PBYTE)(pAttribute->AttribName) + + ROUNDUP4(pAttribute->AttribNameLength) + + sizeof(DWORD); + + if ( pActualSize ) + { + *pActualSize = *(DWORD *)pAttribValue; + } + + memcpy( Data, pAttribValue + sizeof(DWORD), + min(*(DWORD *)pAttribValue, Size) ); + + } + + return Status; +} + + +/******************************************************************** + + NDSGetVar + +Routine Description: + + Return value of user property + + Get the syntax type of the property + Retrieve the data + Do any data conversion + +Arguments: + Name - of NDS property IN + Value - value buffer OUT + Size - size of value buffer IN + +Return Value: + none + + *******************************************************************/ +void +NDSGetVar ( PBYTE Name, PBYTE Value, unsigned int Size) +{ + unsigned int err; + SYNTAX Syntax; + BYTE Buffer[ATTRBUFSIZE]; + DWORD ActualSize; + + Value[0] = 0; + + err = NDSGetUserProperty( Name, Buffer, ATTRBUFSIZE, &Syntax, &ActualSize ); + + if ( err ) + { + return; + } + + switch ( Syntax ) + { + case NDSI_BOOLEAN: + if ( *(PBYTE)Buffer ) + { + strcpy( Value, "Y" ); + } + else + { + strcpy( Value, "N" ); + } + break; + case NDSI_DIST_NAME: + case NDSI_CE_STRING: + case NDSI_CI_STRING: + case NDSI_OCTET_STRING: + case NDSI_PR_STRING: + case NDSI_NU_STRING: + case NDSI_TEL_NUMBER: + case NDSI_CLASS_NAME: + ConvertUnicodeToAscii( Buffer ); + if ( Syntax == NDSI_DIST_NAME ) + NDSAbbreviateName(FLAGS_LOCAL_CONTEXT, Buffer, Buffer); + strncpy( Value, Buffer, Size ); + break; + case NDSI_CI_LIST: + ConvertUnicodeToAscii( Buffer+8 ); + strncpy( Value, Buffer+8, Size ); + break; + break; + case NDSI_INTEGER: + case NDSI_COUNTER: + case NDSI_TIME: + case NDSI_INTERVAL: + case NDSI_TIMESTAMP: + sprintf( Value, "%d", *(int *)Buffer ); + break; + case NDSI_PO_ADDRESS: + { + // 6 null terminated lines + int line,len; + PBYTE ptr = Buffer + 4; + + // Stop if not 6 lines + if ( *(int *)Buffer != 6 ) + break; + + for (line = 0; line <= 5; line++) { + len = ROUNDUP4(*(int *)ptr); + ptr += 4; + if ( !len ) + break; + ConvertUnicodeToAscii( ptr ); + strcat( Value, ptr ); + strcat( Value, "\n" ); + ptr += len; + } + } + break; + case NDSI_FAX_NUMBER: + if ( *(int *)Buffer == 0 ) + return; + ConvertUnicodeToAscii( Buffer+4 ); + strncpy( Value, Buffer+4, Size ); + break; + case NDSI_EMAIL_ADDRESS: + if ( *(int *)(Buffer+4) == 0 ) + return; + ConvertUnicodeToAscii( Buffer+8 ); + strncpy( Value, Buffer+8, Size ); + break; + case NDSI_PATH: + { + int len; + + len = *(int *)(Buffer+4); + if ( len == 0 ) + break; + len = ROUNDUP4( len ); + ConvertUnicodeToAscii( Buffer+8 ); + strcpy( Value, Buffer+8 ); + NDSAbbreviateName(FLAGS_LOCAL_CONTEXT, Value, Value); + strcat( Value, ":" ); + if ( *(int *)(Buffer + 8 + len) == 0 ) + break; + ConvertUnicodeToAscii( Buffer+8+len+4 ); + strcat( Value, Buffer+8+len+4 ); + break; + } + case NDSI_NET_ADDRESS: + case NDSI_OCTET_LIST: + case NDSI_OBJECT_ACL: + case NDSI_STREAM: + case NDSI_UNKNOWN: + case NDSI_REPLICA_POINTER: + case NDSI_BACK_LINK: + case NDSI_TYPED_NAME: + case NDSI_HOLD: + case NDSI_TAX_COUNT: + default: + Value[0] = '\0'; + Value[1] = '\0'; + break; + } + +} + +/******************************************************************** + + NDSChangeContext + +Routine Description: + + Change the current context + +Arguments: + Context - context string IN + +Return Value: + error number + + *******************************************************************/ +unsigned int +NDSChangeContext( PBYTE Context ) +{ + NTSTATUS Status; + + OEM_STRING oemStr; + UNICODE_STRING defaultcontext; + WCHAR NdsStr[1024]; + + oemStr.Length = strlen( Context ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Context; + + defaultcontext.Length = 0; + defaultcontext.MaximumLength = sizeof(NdsStr); + defaultcontext.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &defaultcontext, &oemStr, FALSE ); + + Status = NwNdsSetTreeContext( GhRdr, &NDSTREE_u, &defaultcontext ); + + return Status; +} + +/******************************************************************** + + NDSGetContext + +Routine Description: + + Retrieve the current context + +Arguments: + Buffer - data buffer for context string OUT + len - length of data buffer IN + +Return Value: + error number + + *******************************************************************/ +unsigned int +NDSGetContext( PBYTE Buffer, + unsigned int len ) +{ + NTSTATUS Status; + + Status = NDSGetNameContext( Buffer, TRUE ); + if ( !NT_SUCCESS( Status ) ) + return Status; + NDSAbbreviateName(FLAGS_NO_CONTEXT, Buffer, Buffer); + return 0; +} + +/******************************************************************** + + NDSfopenStream + +Routine Description: + + Open a file handle to an NDS stream property + +Arguments: + Object - name of object IN + Property - name of property IN + pStream - pointer to file handle OUT + pFileSize - pointer to file size OUT + +Return Value: + error + + *******************************************************************/ +unsigned int +NDSfopenStream ( PBYTE Object, + PBYTE Property, + PHANDLE pStream, + unsigned int * pFileSize ) +{ + // + // Status variables. + // + + NTSTATUS Status; + int ccode = -1; + + // + // For NwNdsOpenTreeHandle. + // + + HANDLE hRdr; + OEM_STRING oemStr; + UNICODE_STRING ObjectName; + WCHAR NdsStr[1024]; + + // + // For NwNdsResolveName. + // + + DWORD dwOid; + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + DWORD dwHandleType; + HANDLE hReferredServer; + + // + // Get a handle to the redirector. + // + + Status = NwNdsOpenTreeHandle( &NDSTREE_u, &hRdr ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_TREE_OPEN_FAILED); + return ccode; + } + + // + // Resolve the name that we have to an object id. + // + + if ( !Object ) + { + return 1; + } + + oemStr.Length = strlen( Object ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Object; + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(NdsStr); + ObjectName.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( hRdr, + &ObjectName, + &dwOid, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + return 0xffffffff; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // must jump to that server before continuing. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + return 0xffffffff; + } + + CloseHandle( hRdr ); + hRdr = hReferredServer; + } + + // + // Open the file stream. + // + + oemStr.Length = strlen( Property ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Property; + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(NdsStr); + ObjectName.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + // + // Try to open a file stream for read access. + // + + Status = NwNdsOpenStream( hRdr, + dwOid, + &ObjectName, + 1, // Read access. + pFileSize ); + + if ( !NT_SUCCESS( Status ) ) { + return 0xffffffff; + } + + *pStream = hRdr; + + return 0; +} + +/* + * IsMemberOfNDSGroup + * ------------------ + * + * Returns true if currently logged in user object is member of group with given name + * + */ +unsigned int +IsMemberOfNDSGroup( + PBYTE nwGroup + ) +{ + NTSTATUS Status; + UINT nwRet; + BYTE szCanonTargetGroupName[NDS_NAME_CHARS+1]; + UINT syntaxid; + UINT actualsize; + LPSTR szBuffer; + LPSTR pProp; + UINT i; + DWORD iterhandle = INITIAL_ITERATION; + UINT fFoundGroup = FALSE; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttribute; + PNDS_ATTRIBUTE pAttribute; + PBYTE pAttribValue; + UNICODE_STRING PropertyName; + UINT numvalues = 0; + + + szBuffer = (BYTE *)malloc(ATTRBUFSIZE); + + if ( !szBuffer ) { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memset( szBuffer, 0, ATTRBUFSIZE ); + + // Canonicalize name according to current context + + strcpy( szCanonTargetGroupName, nwGroup ); + + nwRet = NDSCanonicalizeName( szCanonTargetGroupName, + szCanonTargetGroupName, + NDS_NAME_CHARS, + TRUE ); + if (nwRet) { + + if ( nwGroup[0] != '.' ) { + + // Try an absolute name + + strcpy( szCanonTargetGroupName, "." ); + strcat( szCanonTargetGroupName, nwGroup ); + + nwRet = NDSCanonicalizeName( szCanonTargetGroupName, + szCanonTargetGroupName, + NDS_NAME_CHARS, + TRUE ); + } + + if ( nwRet ) + goto CleanRet; + } + + // Should check class name of object + + RtlInitUnicodeString( &PropertyName, L"Group Membership" ); + + Status = NwNdsReadAttribute ( GhRdr, + GUserObjectID, + &iterhandle, + &PropertyName, + szBuffer, + ATTRBUFSIZE ); + + if ( !NT_SUCCESS(Status) ) + { + return FALSE; + } + + pReadAttribute = (PNDS_RESPONSE_READ_ATTRIBUTE)szBuffer; + + pAttribute = (PNDS_ATTRIBUTE)(szBuffer + + sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + pAttribute->SyntaxID; + + pAttribValue = (PBYTE)(pAttribute->AttribName) + + ROUNDUP4(pAttribute->AttribNameLength) + + sizeof(DWORD); + + numvalues = *(PUINT)((PBYTE)(pAttribute->AttribName) + + ROUNDUP4(pAttribute->AttribNameLength)); + + if ( *(DWORD *)pAttribValue == 0 ) + { + return FALSE; + } + + for ( i = 0; i < numvalues; i++ ) { + ConvertUnicodeToAscii( pAttribValue+sizeof(DWORD) ); + if (!_stricmp(pAttribValue+sizeof(DWORD),szCanonTargetGroupName)) { + fFoundGroup = TRUE; + break; + } + pAttribValue += ROUNDUP4(*(PUINT)pAttribValue) + sizeof(DWORD); + } + + + +CleanRet: + if (szBuffer ) { + free (szBuffer); + } + return fFoundGroup; +} + +/******************************************************************** + + NDSGetProperty + +Routine Description: + + Return the NDS property for the object + +Arguments: + Object - name of object IN + Property - property name IN + Data - data buffer OUT + Size - size of data buffer IN + pActualSize - real data size OUT + +Return Value: + error + + *******************************************************************/ +unsigned int +NDSGetProperty ( PBYTE Object, + PBYTE Property, + PBYTE Data, + unsigned int Size, + unsigned int * pActualSize ) +{ + // + // Status variables. + // + + NTSTATUS Status; + int ccode = -1; + + // + // For NwNdsOpenTreeHandle. + // + + HANDLE hRdr; + OEM_STRING oemStr; + UNICODE_STRING ObjectName; + WCHAR NdsStr[1024]; + + // + // For NwNdsResolveName. + // + + DWORD dwOid; + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + DWORD dwHandleType; + HANDLE hReferredServer; + + // + // For NwNdsReadAttribute + // + BYTE Buffer[2048]; + DWORD BufferSize = 2048; + DWORD iterhandle = INITIAL_ITERATION; + PNDS_RESPONSE_READ_ATTRIBUTE pReadAttribute; + PNDS_ATTRIBUTE pAttribute; + PBYTE pAttribValue; + + // + // Get a handle to the redirector. + // + + Status = NwNdsOpenTreeHandle( &NDSTREE_u, &hRdr ); + + if ( !NT_SUCCESS( Status ) ) { + DisplayMessage(IDR_TREE_OPEN_FAILED); + return ccode; + } + + // + // Resolve the name that we have to an object id. + // + + if ( !Object ) + { + return 1; + } + + oemStr.Length = strlen( Object ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Object; + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(NdsStr); + ObjectName.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( hRdr, + &ObjectName, + &dwOid, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + return 0xffffffff; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // must jump to that server before continuing. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + return 0xffffffff; + } + + CloseHandle( hRdr ); + hRdr = hReferredServer; + } + + // + // Get the attribute + // + + oemStr.Length = strlen( Property ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = Property; + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(NdsStr); + ObjectName.Buffer = NdsStr; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + Status = NwNdsReadAttribute ( hRdr, + dwOid, + &iterhandle, + &ObjectName, + Buffer, + BufferSize ); + + if ( NT_SUCCESS(Status) ) + { + int i; + pReadAttribute = (PNDS_RESPONSE_READ_ATTRIBUTE)Buffer; + pAttribute = (PNDS_ATTRIBUTE)(Buffer + + sizeof(NDS_RESPONSE_READ_ATTRIBUTE)); + + pAttribValue = (PBYTE)(pAttribute->AttribName) + + ROUNDUP4(pAttribute->AttribNameLength) + + sizeof(DWORD); + + if ( pActualSize ) + { + *pActualSize = *(DWORD *)pAttribValue; + } + + memcpy( Data, pAttribValue + sizeof(DWORD), + min(*(DWORD *)pAttribValue, Size) ); + + } + + NtClose( hRdr ); + + return Status; +} + + +/******************************************************************** + + NDSCleanup + +Routine Description: + + Does any NDS cleanup + +Arguments: + none + +Return Value: + none + + *******************************************************************/ +void +NDSCleanup ( void ) +{ + NtClose( GhRdr ); +} + +/******************************************************************** + + NDSGetClassName + +Routine Description: + + return a class name for an object + +Arguments: + szObjectName + ClassName + +Return Value: + none + + *******************************************************************/ +unsigned int +NDSGetClassName( LPSTR szObjectName, LPSTR ClassName ) +{ + NTSTATUS Status; + int ccode = -1; + DWORD ThisObjectID; + OEM_STRING oemStr; + UNICODE_STRING ObjectName; + BYTE Buffer[2048]; + BYTE FullName[NDS_NAME_CHARS]; + PBYTE ptr; + UNICODE_STRING ReferredServer; + WCHAR ServerStr[MAX_NAME_LEN]; + DWORD dwHandleType; + HANDLE hReferredServer; + DWORD Length; + + // + // Resolve the name that we have to an object id. + // + + oemStr.Length = strlen( szObjectName ); + oemStr.MaximumLength = oemStr.Length; + oemStr.Buffer = szObjectName; + + ObjectName.Length = 0; + ObjectName.MaximumLength = sizeof(Buffer); + ObjectName.Buffer = (WCHAR *)Buffer; + + RtlOemStringToUnicodeString( &ObjectName, &oemStr, FALSE ); + + ReferredServer.Buffer = ServerStr; + ReferredServer.Length = 0; + ReferredServer.MaximumLength = sizeof( ServerStr ); + + Status = NwNdsResolveName ( GhRdr, + &ObjectName, + &ThisObjectID, + &ReferredServer, + NULL, + 0 ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + if ( ReferredServer.Length > 0 ) { + + // + // We've been referred to another server, so we + // should change the global handle. + // + + Status = NwNdsOpenGenericHandle( &ReferredServer, + &dwHandleType, + &hReferredServer ); + + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + CloseHandle( GhRdr ); + GhRdr = hReferredServer; + } + + Status = NwNdsReadObjectInfo( GhRdr, ThisObjectID, Buffer, 2048 ); + if ( !NT_SUCCESS( Status ) ) { + return Status; + } + + ptr = Buffer + sizeof( NDS_RESPONSE_GET_OBJECT_INFO ) + sizeof( DWORD ); + + RtlInitUnicodeString( &ObjectName, (PWCHAR)ptr ); + + oemStr.Length = 0; + oemStr.MaximumLength = NDS_NAME_CHARS; + oemStr.Buffer = ClassName; + + RtlUnicodeStringToOemString( &oemStr, &ObjectName, FALSE ); + + return 0; +} diff --git a/private/nw/nwscript/nt.c b/private/nw/nwscript/nt.c new file mode 100644 index 000000000..ebf7d4bb1 --- /dev/null +++ b/private/nw/nwscript/nt.c @@ -0,0 +1,617 @@ +/************************************************************************* +* +* NT.C +* +* NT NetWare routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NT.C $ +* +* Rev 1.4 22 Dec 1995 14:25:12 terryt +* Add Microsoft headers +* +* Rev 1.3 28 Nov 1995 17:13:28 terryt +* Cleanup resource file +* +* Rev 1.2 22 Nov 1995 15:43:44 terryt +* Use proper NetWare user name call +* +* Rev 1.1 20 Nov 1995 16:10:00 terryt +* Close open NDS handles +* +* Rev 1.0 15 Nov 1995 18:07:18 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:23:02 terryt +* Capture support +* +* Rev 1.1 23 May 1995 19:37:02 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:40 terryt +* Initial revision. +* +*************************************************************************/ +#include + +#include +#include + +#include "ntnw.h" +/* + * Name of NetWare provider + */ +TCHAR NW_PROVIDER[60]; +unsigned char NW_PROVIDERA[60]; + +/******************************************************************** + + NTPrintExtendedError + +Routine Description: + + Print any extended errors from WNet routines + +Arguments: + None + +Return Value: + None + + *******************************************************************/ +void +NTPrintExtendedError( void ) +{ + DWORD ExError; + wchar_t provider[32]; + wchar_t description[1024]; + + if ( !WNetGetLastErrorW( &ExError, description, 1024, provider, 32 ) ) + wprintf(L"%s\n", description); +} + + +/******************************************************************** + + NTInitProvider + +Routine Description: + + Retrieve provider name and save old paths + +Arguments: + None + +Return Value: + None + + *******************************************************************/ +void +NTInitProvider( void ) +{ + HKEY hKey; + DWORD dwType, dwSize; + LONG Status; + BOOL ret = FALSE; + + dwSize = sizeof(NW_PROVIDER); + if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_PROVIDER, 0, KEY_READ, &hKey)) == ERROR_SUCCESS) { + (void) RegQueryValueEx(hKey, REGISTRY_PROVIDERNAME, NULL, &dwType, (LPBYTE) NW_PROVIDER, &dwSize); + WideTosz( NW_PROVIDERA, NW_PROVIDER, sizeof(NW_PROVIDERA) ); + } + + RegCloseKey(hKey); + + GetOldPaths(); +} + +/******************************************************************** + + DeleteDriveBase + +Routine Description: + + Disconnect drive from network + +Arguments: + + DriveNumber - number of drive 1-26 + +Return Value: + 0 - success + else NetWare error + + *******************************************************************/ +unsigned int +DeleteDriveBase( unsigned short DriveNumber) +{ + static char drivename[] = "A:"; + unsigned int dwRes; + + drivename[0] = 'A' + DriveNumber - 1; + + dwRes = WNetCancelConnection2A( drivename, 0, TRUE ); + + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + + if ( dwRes == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + + return dwRes; +} + +/******************************************************************** + + DetachFromFileServer + +Routine Description: + + Break connection from a file server + +Arguments: + + ConnectionId - Connection handle + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +unsigned int +DetachFromFileServer( unsigned int ConnectionId ) +{ + return ( NWDetachFromFileServer( (NWCONN_HANDLE)ConnectionId ) ); +} + + +/******************************************************************** + + NTLoginToFileServer + +Routine Description: + + Login to a file server given a user name and password. + + If a NULL password is passed in, the default password should + be tried if no password failed. + +Arguments: + + pszServerName - Server name + pszUserName - User name + pszPassword - Password + +Return Value: + 0 = success + else NetWare error + + *******************************************************************/ +unsigned int +NTLoginToFileServer( + char *pszServerName, + char *pszUserName, + char *pszPassword + ) +{ + NETRESOURCEA NetResource; + DWORD dwRes; + + // + // validate parameters + // + if (!pszServerName || !pszUserName || !pszPassword) { + DisplayMessage(IDR_ERROR_DURING, "NTLoginToFileServer"); + return 0xffffffff ; + } + + NetResource.dwScope = 0 ; + NetResource.dwUsage = 0 ; + NetResource.dwType = RESOURCETYPE_ANY; + NetResource.lpLocalName = NULL; + NetResource.lpRemoteName = pszServerName; + NetResource.lpComment = NULL; + NetResource.lpProvider = NW_PROVIDERA ; + + // + // make the connection + // + dwRes=WNetAddConnection2A ( &NetResource, + pszPassword, + pszUserName, + 0 ); + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + + // + // Try default password if no password was specified + // + // The error numbers aren't (or weren't) reliable (ERROR_INVALID_PASSWORD) + // + if ( ( dwRes != NO_ERROR ) && ( pszPassword[0] == '\0' ) ) { + dwRes=WNetAddConnection2A ( &NetResource, + NULL, + pszUserName, + 0 ); + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + } + + return( dwRes ); +} + +/******************************************************************** + + GetFileServerName + +Routine Description: + + Return the server name associated with the connection ID + +Arguments: + + ConnectionId - Connection ID to a server + pServerName - Returned server name + +Return Value: + 0 - success + else NT error + + *******************************************************************/ +unsigned int +GetFileServerName( + unsigned int ConnectionId, + char * pServerName + ) +{ + unsigned int Result; + VERSION_INFO VerInfo; + + *pServerName = '\0'; + + Result = NWGetFileServerVersionInfo( (NWCONN_HANDLE) ConnectionId, + &VerInfo ); + if ( !Result ) + { + strcpy( pServerName, VerInfo.szName ); + } + + return Result; +} + +/******************************************************************** + + SetDriveBase + +Routine Description: + + Connect a drive to a NetWare volume + +Arguments: + + DriveNumber - number of drive 1-26 + ServerName - server name + DirHandle - not used + pDirPath - Volume:\Path + +Return Value: + 0 = success + else NetWare error + + *******************************************************************/ +unsigned int +SetDriveBase( + unsigned short DriveNumber, + unsigned char *ServerName, + unsigned int DirHandle, + unsigned char *pDirPath + ) +{ + unsigned int Result = 0; + static char driveName[] = "A:" ; + + /* + * DirHandle is never used + */ + + driveName[0]= 'A' + DriveNumber - 1; + + if ( ( ServerName[0] == '\0' ) && fNDS ) { + + /* + * Assume its an NDS volume name, if that fails, then + * try a default file server volume. + */ + Result = NTSetDriveBase( driveName, NDSTREE, pDirPath ); + + if ( !Result ) + return Result; + + Result = NTSetDriveBase( driveName, PREFERRED_SERVER, pDirPath ); + + return Result; + } + + Result = NTSetDriveBase( driveName, ServerName, pDirPath ); + + return Result; +} + + +/******************************************************************** + + NTSetDriveBase + +Routine Description: + + Connect a local name to a NetWare volume and path + +Arguments: + + pszLocalName - local name to connect + pszServerName - name of file server + pszDirPath - Volume:\Path + +Return Value: + 0 = success + else NetWare error + + *******************************************************************/ +unsigned int +NTSetDriveBase( unsigned char * pszLocalName, + unsigned char * pszServerName, + unsigned char * pszDirPath ) +{ + NETRESOURCEA NetResource; + DWORD dwRes, dwSize; + unsigned char * pszRemoteName = NULL; + char * p; + + // + // validate parameters + // + if (!pszLocalName || !pszServerName || !pszDirPath) { + DisplayMessage(IDR_ERROR_DURING, "NTSetDriveBase"); + return 0xffffffff ; + } + + // + // allocate memory for string + // + dwSize = strlen(pszDirPath) + strlen(pszServerName) + 5 ; + if (!(pszRemoteName = (unsigned char *)LocalAlloc( + LPTR, + dwSize))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + dwRes = 0xffffffff; + goto ExitPoint ; + } + + // + // The requester understands + // server\volume:dir + // but not + // server\volume:\dir + // + // So just convert it to UNC + // + + strcpy( pszRemoteName, "\\\\" ); + strcat( pszRemoteName, pszServerName ); + strcat( pszRemoteName, "\\" ); + strcat( pszRemoteName, pszDirPath ); + + p = strchr( pszRemoteName, ':' ); + if ( !p ) { + DisplayMessage(IDR_NO_VOLUME); + dwRes = 0xffffffff; + goto ExitPoint ; + } + *p++ = '\\'; + + if ( *p == '\\' ) { + /* Don't want a double backslash */ + *p = '\0'; + p = strchr( pszDirPath, ':' ); + p++; + p++; + strcat( pszRemoteName, p ); + } + + // + // strip off trailing backslash + // + if (pszRemoteName[strlen(pszRemoteName)-1] == '\\') + pszRemoteName[strlen(pszRemoteName)-1] = '\0'; + + NetResource.dwScope = 0 ; + NetResource.dwUsage = 0 ; + NetResource.dwType = RESOURCETYPE_DISK; + NetResource.lpLocalName = pszLocalName; + NetResource.lpRemoteName = pszRemoteName; + NetResource.lpComment = NULL; + NetResource.lpProvider = NW_PROVIDERA ; + + // + // make the connection + // + dwRes=WNetAddConnection2A ( &NetResource, NULL, NULL, 0 ); + + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + +ExitPoint: + + if (pszRemoteName) + (void) LocalFree((HLOCAL) pszRemoteName) ; + + return( dwRes ); +} + + +/******************************************************************** + + Is40Server + +Routine Description: + + Returns TRUE if 4X server + +Arguments: + + ConnectionHandle - Connection Handle + +Return Value: + TRUE = 4X server + FALSE = pre-4X server + + *******************************************************************/ +unsigned int +Is40Server( + unsigned int ConnectionHandle + ) +{ + NTSTATUS NtStatus ; + VERSION_INFO VerInfo; + unsigned int Version; + + NtStatus = NWGetFileServerVersionInfo( (NWCONN_HANDLE)ConnectionHandle, + &VerInfo ); + + if (!NT_SUCCESS(NtStatus)) + FALSE; + + Version = VerInfo.Version * 1000 + VerInfo.SubVersion * 10; + + if ( Version >= 4000 ) { + return TRUE; + } + else { + return FALSE; + } +} + +/******************************************************************** + + CleanupExit + +Routine Description: + + Does any cleanup and exits + +Arguments: + + ExitCode - exit code for exit() + +Return Value: + does not return + + *******************************************************************/ +void +CleanupExit ( int ExitCode ) +{ + if ( fNDS ) + NDSCleanup(); + + exit( ExitCode ); +} + +/******************************************************************** + + NTGetNWUserName + +Routine Description: + + Get NetWare user name + +Arguments: + + TreeBuffer IN - wide string for server or tree + UserName OUT - user name + Length IN - length of user name + +Return Value: + error message + + *******************************************************************/ +int +NTGetNWUserName( PWCHAR TreeBuffer, PWCHAR UserName, int Length ) +{ + + NTSTATUS ntstatus; + IO_STATUS_BLOCK IoStatusBlock; + OBJECT_ATTRIBUTES ObjectAttributes; + ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY; + HANDLE hRdr; + + WCHAR DevicePreamble[] = L"\\Device\\Nwrdr\\"; + UINT PreambleLength = 14; + + WCHAR NameStr[64]; + UNICODE_STRING OpenName; + UINT i; + + UNICODE_STRING NdsTree; + + // + // Copy over the preamble. + // + + OpenName.MaximumLength = sizeof( NameStr ); + + for ( i = 0; i < PreambleLength ; i++ ) + NameStr[i] = DevicePreamble[i]; + + RtlInitUnicodeString( &NdsTree, TreeBuffer ); + + // + // Copy the server or tree name. + // + + for ( i = 0 ; i < ( NdsTree.Length / sizeof( WCHAR ) ) ; i++ ) { + NameStr[i + PreambleLength] = NdsTree.Buffer[i]; + } + + OpenName.Length = ( i * sizeof( WCHAR ) ) + + ( PreambleLength * sizeof( WCHAR ) ); + OpenName.Buffer = NameStr; + + // + // Set up the object attributes. + // + + InitializeObjectAttributes( &ObjectAttributes, + &OpenName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL ); + + ntstatus = NtOpenFile( &hRdr, + DesiredAccess, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_VALID_FLAGS, + FILE_SYNCHRONOUS_IO_NONALERT ); + + if ( !NT_SUCCESS(ntstatus) ) + return ntstatus; + + ntstatus = NtFsControlFile( hRdr, + NULL, + NULL, + NULL, + &IoStatusBlock, + FSCTL_NWR_GET_USERNAME, + (PVOID) TreeBuffer, + NdsTree.Length, + (PVOID) UserName, + Length ); + + UserName[(USHORT)IoStatusBlock.Information/2] = 0; + + NtClose( hRdr ); + return ntstatus; + +} diff --git a/private/nw/nwscript/ntcap.c b/private/nw/nwscript/ntcap.c new file mode 100644 index 000000000..64dc75648 --- /dev/null +++ b/private/nw/nwscript/ntcap.c @@ -0,0 +1,329 @@ +/************************************************************************* +* +* NTCAP.C +* +* NT NetWare routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NTCAP.C $ +* +* Rev 1.2 10 Apr 1996 14:23:04 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:54:36 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:25:20 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:20 terryt +* Initial revision. +* +* Rev 1.0 25 Aug 1995 15:41:14 terryt +* Initial revision. +* +* +*************************************************************************/ + +#include "common.h" +#include +#include +#include +#include "ntnw.h" + +extern unsigned char NW_PROVIDERA[]; + +/******************************************************************** + + EndCapture + +Routine Description: + + Remove the local printer redirection + +Arguments: + LPTDevice - IN + 1, 2, or 3 - the local printer # + +Return Value: + Error + + *******************************************************************/ +unsigned int +EndCapture( + unsigned char LPTDevice + ) +{ + char LPTname[] = "LPT1"; + unsigned int dwRes; + + LPTname[3] = '1' + LPTDevice - 1; + + /* + * Should we check for non-NetWare printers? + */ + + dwRes = WNetCancelConnection2A( LPTname, 0, TRUE ); + + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + + if ( dwRes == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + + return dwRes; +} + + +/******************************************************************** + + GetCaptureFlags + +Routine Description: + + Return info about the printer capture status. Note that the only + options set on NT are on a per-user basis and can be changed with + the control panel. + +Arguments: + LPTDevice - IN + LPT device 1, 2 or 3 + pCaptureFlagsRW - OUT + Capture options + pCaptureFlagsRO - OUT + Capture options + +Return Value: + + *******************************************************************/ +unsigned int +GetCaptureFlags( + unsigned char LPTDevice, + PNETWARE_CAPTURE_FLAGS_RW pCaptureFlagsRW, + PNETWARE_CAPTURE_FLAGS_RO pCaptureFlagsRO + ) +{ + LPBYTE Buffer ; + DWORD dwErr ; + HANDLE EnumHandle ; + DWORD Count ; + char LPTName[10]; + DWORD BufferSize = 4096; + char *remotename; + char *p; + DWORD dwPrintOptions ; + LPTSTR pszPreferred ; + + strcpy( LPTName, "LPT1" ); + + LPTName[3] = '1' + LPTDevice - 1; + + pCaptureFlagsRO->LPTCaptureFlag = 0; + + // + // allocate memory and open the enumeration + // + if (!(Buffer = LocalAlloc( LPTR, BufferSize ))) { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return 0xFFFF; + } + + dwErr = WNetOpenEnum(RESOURCE_CONNECTED, 0, 0, NULL, &EnumHandle) ; + if (dwErr != WN_SUCCESS) { + dwErr = GetLastError(); + if ( dwErr == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + (void) LocalFree((HLOCAL) Buffer) ; + return 0xFFFF; + } + + do { + + Count = 0xFFFFFFFF ; + BufferSize = 4096; + dwErr = WNetEnumResourceA(EnumHandle, &Count, Buffer, &BufferSize) ; + + if ((dwErr == WN_SUCCESS || dwErr == WN_NO_MORE_ENTRIES) + && ( Count != 0xFFFFFFFF) ) + { + LPNETRESOURCEA lpNetResource ; + DWORD i ; + + lpNetResource = (LPNETRESOURCEA) Buffer ; + + // + // search for our printer + // + for ( i = 0; i < Count; lpNetResource++, i++ ) + { + if ( lpNetResource->lpLocalName ) + { + if ( !_strcmpi(lpNetResource->lpLocalName, LPTName )) + { + if ( lpNetResource->lpProvider ) + { + if ( _strcmpi( lpNetResource->lpProvider, + NW_PROVIDERA ) ) + { + + pCaptureFlagsRO->LPTCaptureFlag = 0; + } + else + { + remotename = lpNetResource->lpRemoteName; + p = strchr (remotename + 2, '\\'); + if ( !p ) + return 0xffffffff; + *p++ = '\0'; + _strupr( remotename+2 ); + _strupr( p ); + strcpy( pCaptureFlagsRO->ServerName, remotename+2 ); + strcpy( pCaptureFlagsRO->QueueName, p ); + pCaptureFlagsRO->LPTCaptureFlag = 1; + + pCaptureFlagsRW->JobControlFlags = 0; + pCaptureFlagsRW->TabSize = 8; + pCaptureFlagsRW->NumCopies = 1; + // + // query NW wksta for print options + // & preferred server + // + if ( NwQueryInfo(&dwPrintOptions, + &pszPreferred)) { + pCaptureFlagsRW->PrintFlags = + CAPTURE_FLAG_NOTIFY | + CAPTURE_FLAG_PRINT_BANNER ; + } + else { + pCaptureFlagsRW->PrintFlags = 0; + if ( dwPrintOptions & NW_PRINT_PRINT_NOTIFY ) + pCaptureFlagsRW->PrintFlags |= + CAPTURE_FLAG_NOTIFY; + if ( dwPrintOptions & NW_PRINT_SUPPRESS_FORMFEED) + pCaptureFlagsRW->PrintFlags |= + CAPTURE_FLAG_NO_FORMFEED; + if ( dwPrintOptions & NW_PRINT_PRINT_BANNER ) + pCaptureFlagsRW->PrintFlags |= + CAPTURE_FLAG_PRINT_BANNER; + } + pCaptureFlagsRW->FormName[0] = 0; + pCaptureFlagsRW->FormType = 0; + pCaptureFlagsRW->BannerText[0] = 0; + pCaptureFlagsRW->FlushCaptureTimeout = 0; + pCaptureFlagsRW->FlushCaptureOnClose = 1; + } + } + else + { + pCaptureFlagsRO->LPTCaptureFlag = 0; + } + + (void) WNetCloseEnum(EnumHandle) ; + (void) LocalFree((HLOCAL) Buffer) ; + return 0; + } + } + } + } + + } while (dwErr == WN_SUCCESS) ; + + if ( ( dwErr != WN_SUCCESS ) && ( dwErr != WN_NO_MORE_ENTRIES ) ) + { + dwErr = GetLastError(); + if ( dwErr == ERROR_EXTENDED_ERROR ) + NTPrintExtendedError(); + } + + (void ) WNetCloseEnum(EnumHandle) ; + (void) LocalFree((HLOCAL) Buffer) ; + + return 0; +} + +/******************************************************************** + + StartQueueCapture + +Routine Description: + + Attach local name to the queue. + + +Arguments: + ConnectionHandle - IN + Handle to file server + LPTDevice - IN + LPT 1, 2 or 3 + pServerName - IN + Server name + pQueueName - IN + Printer queue name + +Return Value: + + *******************************************************************/ +unsigned int +StartQueueCapture( + unsigned int ConnectionHandle, + unsigned char LPTDevice, + unsigned char *pServerName, + unsigned char *pQueueName + ) +{ + NETRESOURCEA NetResource; + DWORD dwRes, dwSize; + unsigned char * pszRemoteName = NULL; + unsigned char pszLocalName[10]; + char * p; + + // + // validate parameters + // + if (!pServerName || !pQueueName || !LPTDevice) { + DisplayMessage(IDR_ERROR_DURING, "StartQueueCapture"); + return 0xffffffff ; + } + + // + // allocate memory for string + // + dwSize = strlen(pServerName) + strlen(pQueueName) + 5 ; + if (!(pszRemoteName = (unsigned char *)LocalAlloc( + LPTR, + dwSize))) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + dwRes = 0xffffffff; + goto ExitPoint ; + } + + sprintf(pszRemoteName, "\\\\%s\\%s", pServerName, pQueueName); + sprintf(pszLocalName, "LPT%d", LPTDevice ); + + NetResource.dwScope = 0 ; + NetResource.dwUsage = 0 ; + NetResource.dwType = RESOURCETYPE_PRINT; + NetResource.lpLocalName = pszLocalName; + NetResource.lpRemoteName = pszRemoteName; + NetResource.lpComment = NULL; + NetResource.lpProvider = NW_PROVIDERA ; + + // + // make the connection + // + dwRes=WNetAddConnection2A ( &NetResource, NULL, NULL, 0 ); + + if ( dwRes != NO_ERROR ) + dwRes = GetLastError(); + +ExitPoint: + + if (pszRemoteName) + (void) LocalFree((HLOCAL) pszRemoteName) ; + + return( dwRes ); +} + + diff --git a/private/nw/nwscript/ntnw.c b/private/nw/nwscript/ntnw.c new file mode 100644 index 000000000..00cf54057 --- /dev/null +++ b/private/nw/nwscript/ntnw.c @@ -0,0 +1,163 @@ +/************************************************************************* +* +* NTNW.C +* +* Dos NetWare to NT NetWare translation +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NTNW.C $ +* +* Rev 1.1 22 Dec 1995 14:25:28 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:24 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:23:08 terryt +* Capture support +* +* Rev 1.1 23 May 1995 19:37:10 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:44 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include "common.h" + +extern int CONNECTION_ID; + +/******************************************************************** + + NTGetCurrentDirectory + +Routine Description: + + Return the current directory. + +Arguments: + + DriveNumber = The drive to get the directory from. + (0 = A, 1 = B, 2 = C, etc) + pPath = A pointer to a 64 byte buffer to return the + current directory. + +Return Value: + + 0 Success + else Error + + ********************************************************************/ + +unsigned int +NTGetCurrentDirectory( + unsigned char DriveNumber, + unsigned char *pPath + ) +{ + char * CurPath; + int currentDrive = _getdrive() ; + + // + // Change to the drive and get its current working directory. + // Default to root if fail to get cwd. DriveNumber is from 0. + // + + _chdrive (DriveNumber+1); + + CurPath = _getcwd(NULL,MAX_PATH) ; + + if ( CurPath != NULL ) { + + strcpy( pPath, CurPath ); + free(CurPath) ; + } + else { + + strcpy( pPath, "A:\\" ); + pPath[0] += DriveNumber; + } + + _chdrive (currentDrive); + + return 0; +} + +/******************************************************************** + + AttachToFileServer + +Routine Description: + + Attach to a named file server + +Arguments: + + pServerName - Name of server + pNewConnectionId - returned connection handle + +Return Value: + 0 = success + else NetWare error + + *******************************************************************/ +unsigned int +AttachToFileServer( + unsigned char *pServerName, + unsigned int *pNewConnectionId + ) +{ + unsigned int Result; + + if ( NTIsConnected( pServerName ) ) { + return 0x8800; // Already atached. + } + + Result = NTAttachToFileServer( pServerName, pNewConnectionId ); + + return Result; +} + +/******************************************************************** + + GetConnectionHandle + +Routine Description: + + Given a server name, return the connection handle. + The server should already be attached + Note that this is not called for 4X servers. It's used + for attaches and bindery connections. + +Arguments: + + pServerName - Name of server + pConnectionHandle - pointer to returned connection handle + +Return Value: + 0 = success + else NetWare error + + *******************************************************************/ +unsigned int +GetConnectionHandle( + unsigned char *pServerName, + unsigned int *pConnectionHandle + ) +{ + unsigned int Result; + + if ( !NTIsConnected( pServerName ) ) { + return 0xFFFF; // not already connected + } + + Result = NTAttachToFileServer( pServerName, pConnectionHandle ); + + return Result; +} + diff --git a/private/nw/nwscript/ntscript.c b/private/nw/nwscript/ntscript.c new file mode 100644 index 000000000..b29d9beba --- /dev/null +++ b/private/nw/nwscript/ntscript.c @@ -0,0 +1,304 @@ +/************************************************************************* +* +* NTSCRIPT.C +* +* Process all login scripts +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NTSCRIPT.C $ +* +* Rev 1.8 10 Apr 1996 14:23:12 terryt +* Hotfix for 21181hq +* +* Rev 1.9 12 Mar 1996 19:54:58 terryt +* Relative NDS names and merge +* +* Rev 1.8 07 Mar 1996 18:36:56 terryt +* Misc fixes +* +* Rev 1.7 22 Jan 1996 16:48:26 terryt +* Add automatic attach query during map +* +* Rev 1.6 08 Jan 1996 13:57:58 terryt +* Correct NDS Preferred Server +* +* Rev 1.5 05 Jan 1996 17:18:26 terryt +* Ensure context is the correct login default +* +* Rev 1.4 04 Jan 1996 18:56:48 terryt +* Bug fixes reported by MS +* +* Rev 1.3 22 Dec 1995 11:08:16 terryt +* Fixes +* +* Rev 1.2 22 Nov 1995 15:43:52 terryt +* Use proper NetWare user name call +* +* Rev 1.1 20 Nov 1995 15:09:38 terryt +* Context and capture changes +* +* Rev 1.0 15 Nov 1995 18:07:28 terryt +* Initial revision. +* +* Rev 1.2 25 Aug 1995 16:23:14 terryt +* Capture support +* +* Rev 1.1 26 Jul 1995 16:02:00 terryt +* Allow deletion of current drive +* +* Rev 1.0 15 May 1995 19:10:46 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "inc/ntnw.h" + +#include + +void ProcessLoginScripts(unsigned int conn, char * UserName, int argc, char **argv, char *lpScript); + +extern int SafeDisk; + +extern unsigned int ConvertNDSPathToNetWarePath(char *, char *, char *); + +/************************************************************************* +* +* NTNetWareLoginScripts +* Main logon script processor +* +* ENTRY: +* +* EXIT +* +*************************************************************************/ + +int +NTNetWareLoginScripts( int argc, char ** argv ) +{ + unsigned int defConn; + char UserName[MAX_NAME_LEN]=""; + WCHAR UserName_w[MAX_NAME_LEN * sizeof(WCHAR)]=L""; + char MessageServer[NDS_NAME_CHARS]=""; + char *lpScript = NULL; + DWORD PrintOptions; + LPTSTR pszPreferredSrv; + LPTSTR ptreeW; + LPTSTR pcontextW; + NTSTATUS ntstatus; + char * lpC1; + char * lpC2; + unsigned int NewConn; + unsigned int Result; + + if ( NwQueryInfo( &PrintOptions, &pszPreferredSrv ) || !pszPreferredSrv ) + { + DisplayMessage(IDR_QUERY_INFO_FAILED); + return( FALSE ); + } + + // + // nwscript /S filename + // + // can be used to pass a local script file for testing + // + if ( ( argc >= 3 ) && !_strcmpi(argv[1], "/S") ) + { + lpScript = argv[2]; + argc -= 2; + argv += 2; + } + + // + // NDS preferred server format is: + // *\ + + fNDS = ( *pszPreferredSrv == L'*' ); + + if ( fNDS ) + { + + // Get the NDS tree name + + ptreeW = pszPreferredSrv + 1; + + pcontextW = wcschr( pszPreferredSrv, L'\\' ); + + if ( pcontextW ) + { + *pcontextW++ = L'\0'; + } + + NDSTREE = malloc ( CONTEXT_MAX ); + NDSTREE_w = malloc ( CONTEXT_MAX * sizeof(WCHAR) ); + if ( ptreeW ) + { + wcscpy( NDSTREE_w, ptreeW ); + RtlInitUnicodeString( &NDSTREE_u, NDSTREE_w ); + WideTosz( NDSTREE, ptreeW, CONTEXT_MAX ); + _strupr( NDSTREE ); + } + else + { + strcpy( NDSTREE, "" ); + wcscpy( NDSTREE_w, L"" ); + } + + // Get the fully typed user name + + TYPED_USER_NAME_w = malloc ( sizeof(WCHAR) * NDS_NAME_CHARS ); + TYPED_USER_NAME = malloc ( NDS_NAME_CHARS ); + + ntstatus = NTGetNWUserName( NDSTREE_w, TYPED_USER_NAME_w, + sizeof(WCHAR) * NDS_NAME_CHARS ); + if ( !NT_SUCCESS( ntstatus ) ) { + DisplayMessage(IDR_QUERY_INFO_FAILED); + return ( FALSE ); + } + + WideTosz( TYPED_USER_NAME, TYPED_USER_NAME_w, NDS_NAME_CHARS ); + + // Get the user name stripped of context and type + + lpC1 = strchr( TYPED_USER_NAME, '=' ); + if ( lpC1 ) + lpC1++; + else + lpC1 = TYPED_USER_NAME; + + lpC2 = strchr( TYPED_USER_NAME, '.' ); + + if ( lpC2 ) + strncpy( UserName, lpC1, lpC2 - lpC1 ); + else + strcpy( UserName, lpC1 ); + + // Get the default context + // This should be where the user is + + REQUESTER_CONTEXT = malloc( CONTEXT_MAX ); + + if ( lpC2 ) + { + strcpy( REQUESTER_CONTEXT, lpC2+1 ); + } + else + { + strcpy( REQUESTER_CONTEXT, "" ); + } + NDSTypeless( REQUESTER_CONTEXT, REQUESTER_CONTEXT ); + + // + // This finishes the NDS initialization + // + if ( NDSInitUserProperty () ) + return ( FALSE ); + + } + else + { + ntstatus = NTGetNWUserName( pszPreferredSrv, UserName_w, + MAX_NAME_LEN * sizeof(WCHAR) ); + if ( !NT_SUCCESS( ntstatus ) ) { + DisplayMessage(IDR_QUERY_INFO_FAILED); + return ( FALSE ); + } + WideTosz( UserName, UserName_w, MAX_NAME_LEN ); + _strupr( UserName ); + } + + // + // If we map over a drive, the SafeDisk is used. + // + SafeDisk = _getdrive(); + + NTInitProvider(); + + // + // Get the default connection handle. + // + // This is used to get the preferred server! + + if ( !CGetDefaultConnectionID (&defConn) ) + return( FALSE ); + + PREFERRED_SERVER = malloc( NDS_NAME_CHARS ); + + GetFileServerName(defConn, PREFERRED_SERVER); + + // + // By default we are "attached" to the default server + // + if ( fNDS ) + AddServerToAttachList( PREFERRED_SERVER, LIST_4X_SERVER ); + else + AddServerToAttachList( PREFERRED_SERVER, LIST_3X_SERVER ); + + // + // Print out status + // + if ( fNDS ) + { + DisplayMessage( IDR_CURRENT_CONTEXT, REQUESTER_CONTEXT ); + DisplayMessage( IDR_CURRENT_TREE, NDSTREE_w ); + } + + DisplayMessage( IDR_CURRENT_SERVER, PREFERRED_SERVER ); + + // + // We may want to change the Preferred Server based on the DS. + // "MESSAGE_SERVER" should be the Preferred Server (if possible). + // + if ( fNDS ) + { + NDSGetVar ( "MESSAGE_SERVER", MessageServer, NDS_NAME_CHARS ); + if ( strlen( MessageServer ) ) + { + NDSAbbreviateName(FLAGS_NO_CONTEXT, MessageServer, MessageServer); + lpC1 = strchr( MessageServer, '.' ); + if ( lpC1 ) + *lpC1 = '\0'; + if ( strcmp( MessageServer, PREFERRED_SERVER) ) + { + DisplayMessage( IDR_AUTHENTICATING_SERVER, MessageServer ); + Result = NTAttachToFileServer( MessageServer, &NewConn ); + if ( Result ) + { + DisplayMessage( IDR_SERVER_NOT_FOUND, MessageServer ); + } + else + { + NWDetachFromFileServer( (NWCONN_HANDLE)NewConn ); + strncpy( PREFERRED_SERVER, MessageServer, NDS_NAME_CHARS); + DisplayMessage( IDR_CURRENT_SERVER, PREFERRED_SERVER ); + + // By default we are "attached" to the preferred server + + AddServerToAttachList( PREFERRED_SERVER, LIST_4X_SERVER ); + } + } + } + } + + // + // Just like login we ignore any errors from setting the login + // directory. + // + SetLoginDirectory (PREFERRED_SERVER); + + // Process login scripts. + + ProcessLoginScripts(defConn, UserName, argc, argv, lpScript); + + return( TRUE ); +} diff --git a/private/nw/nwscript/nwapi1.c b/private/nw/nwscript/nwapi1.c new file mode 100644 index 000000000..a7a8c30c6 --- /dev/null +++ b/private/nw/nwscript/nwapi1.c @@ -0,0 +1,47 @@ + +/************************************************************************* +* +* NWAPI1.C +* +* NetWare routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NWAPI1.C $ +* +* Rev 1.1 22 Dec 1995 14:25:48 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:32 terryt +* Initial revision. +* +* Rev 1.0 15 May 1995 19:10:48 terryt +* Initial revision. +* +*************************************************************************/ +#include "common.h" + +/* + Get default connection handle. + return TRUE if succeeded, FALSE otherwise. + */ +int CGetDefaultConnectionID ( unsigned int * pConn ) +{ + unsigned int iRet = GetDefaultConnectionID(pConn); + + switch (iRet) + { + case 0: + break; + + case 0x880f: + DisplayMessage(IDR_NO_KNOWN_FILE_SERVER); + break; + default: + DisplayMessage(IDR_NO_DEFAULT_CONNECTION); + break; + } + + return(iRet == 0); +} + diff --git a/private/nw/nwscript/nwapi2.c b/private/nw/nwscript/nwapi2.c new file mode 100644 index 000000000..31e0d669b --- /dev/null +++ b/private/nw/nwscript/nwapi2.c @@ -0,0 +1,49 @@ + +/************************************************************************* +* +* NWAPI2.C +* +* NetWare routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NWAPI2.C $ +* +* Rev 1.1 22 Dec 1995 14:25:54 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:07:34 terryt +* Initial revision. +* +* Rev 1.0 15 May 1995 19:10:50 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include "common.h" + +/* + Set the current drive to the login directory + of the default server. + */ +void SetLoginDirectory( PBYTE serverName ) +{ + unsigned int iRet = 0; + WORD firstDrive; + + if(iRet = GetFirstDrive (&firstDrive)) + { + DisplayError(iRet,"GetFirstDrive"); + return; + } + + // Nothing we can do if SetDriveBase failed. + // Don't report the error. + + if ( !( SetDriveBase (firstDrive, serverName, 0, "SYS:LOGIN") ) ) + { + _chdrive (firstDrive); + ExportCurrentDrive( firstDrive ); + } +} diff --git a/private/nw/nwscript/nwapi3.c b/private/nw/nwscript/nwapi3.c new file mode 100644 index 000000000..5408d286e --- /dev/null +++ b/private/nw/nwscript/nwapi3.c @@ -0,0 +1,1457 @@ +/************************************************************************* +* +* NWAPI3.C +* +* NetWare routines ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NWAPI3.C $ +* +* Rev 1.4 18 Apr 1996 16:52:14 terryt +* Various enhancements +* +* Rev 1.3 10 Apr 1996 14:23:20 terryt +* Hotfix for 21181hq +* +* Rev 1.5 13 Mar 1996 18:49:28 terryt +* Support directory maps +* +* Rev 1.4 12 Mar 1996 19:55:10 terryt +* Relative NDS names and merge +* +* Rev 1.2 22 Dec 1995 14:26:02 terryt +* Add Microsoft headers +* +* Rev 1.1 22 Nov 1995 15:41:56 terryt +* Fix MAP ROOT of search drives +* +* Rev 1.0 15 Nov 1995 18:07:38 terryt +* Initial revision. +* +* Rev 1.3 25 Aug 1995 16:23:22 terryt +* Capture support +* +* Rev 1.2 26 Jul 1995 16:02:08 terryt +* Allow deletion of current drive +* +* Rev 1.1 23 Jun 1995 09:49:22 terryt +* Add error message for mapping over MS network drive +* +* Rev 1.0 15 May 1995 19:10:54 terryt +* Initial revision. +* +*************************************************************************/ + +/* +Module Name: + nwapi3.c + +Abstract: + can : + - view current mapping + - create/change a drive mapping + - create/change a search drive mapping + - map a drive to a fake root + - map the next available drive + + SYNTAX (Command line) + View current mapping. + MAP [drive:] + Create or change network drive mappings + MAP path + MAP drive:=[drive:|path] + MAP [DEL[ete] | REM[ove]] drive: + Create or change search dirve mappings + MAP [INS[ert]] drive:=[drive:|path] + Map a drive to a fake root directory + MAP ROOT drive:=[drive:|path] + Map the next available dirve + MAP N[ext] [drive:|path] + + + +Author : Thierry TABARD (thierryt) + +Revision history : + - 03/10/94 thierryt started + - 05/13/94 congpay rewrote. +*/ + +#include +#include +#include "common.h" + +/* Local functions*/ +int IsDrive( char * input); +int GetSearchNumber( char * input); +int IsNetwareDrive (int driveNum); +int IsLocalDrive (int driveNum); +int IsNonNetwareNetworkDrive (int driveNum); +int GetDriveFromSearchNumber (int searchNumber); + +void DisplayDriveMapping(WORD drive); +void DisplaySearchDriveMapping(int searchNumber); + +int ParseMapPath(char * mapPath, char * volName, char * dirPath, char * serverName, int fMapErrorsOn, char *lpCommand); +int MapDrive (int driveNum, int searchNum, char * mapPath, int bRoot, int bInsert, int fMapErrorsOn, char *lpCommand); +int MapNonSearchDrive (int driveNum, char *mapPath, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); +int MapSearchDrive (int searchNum, int driveNum, char *mapPath, int bInsert, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); +int MapNextAvailableDrive (char *mapPath, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand); + +void RemoveDriveFromPath(int searchNumber, int fMapErrorsOn); +int RemoveDrive (WORD drive, int fMapDisplayOn, int fMapErrorsOn); +void RemoveSearchDrive (int searchNumber, int fMapDisplayOn, int fMapErrorsOn); +int InsertSearchDrive(int searchNum, int driveNum, int bInsert, char * insertPath); + +#define CM_MAP 0 +#define CM_DEL 1 +#define CM_NEXT 2 +#define CM_HELP 3 +#define MAX_INPUT_PATH_LEN 128 + +int fMapDisplayOn = TRUE; +int fMapErrorsOn = TRUE; +int SafeDisk = 2; + +int GetFlag (char *buffer, int *pfInsert, int *pfRoot, char **ppPath) +{ + int nFlag, nLen; + char *lpSpace, *lpTemp; + + if (((*buffer == '/') || (*buffer == '-') || (*buffer == '\\')) && + (*(buffer+1) == '?')) + return CM_HELP; + + lpSpace = strchr (buffer, ' '); + + nFlag = CM_MAP; // A bug! + + if (lpSpace == NULL) + { + *ppPath = buffer; + return CM_MAP; + } + + nLen = lpSpace - buffer; + lpSpace++; + + if (!strncmp(buffer, __DEL__, max (3, nLen)) || + !strncmp(buffer, __REM__, max (3, nLen))) + nFlag = CM_DEL; + else if (!strncmp(buffer, __NEXT__, nLen)) + nFlag = CM_NEXT; + else if (!strncmp(buffer, __INS__, max (3, nLen))) + { + *pfInsert = TRUE; + if (lpTemp = strchr (lpSpace, ' ')) + { + nLen = lpTemp - lpSpace; + if (!strncmp(lpSpace, __ROOT__, nLen)) + { + *pfRoot = TRUE; + lpSpace = lpTemp+1; + } + } + } + else if (!strncmp(buffer, __ROOT__, nLen)) + { + *pfRoot = TRUE; + if (lpTemp = strchr (lpSpace, ' ')) + { + nLen = lpTemp - lpSpace; + if (!strncmp(lpSpace, __INS__, max (3, nLen))) + { + *pfInsert = TRUE; + lpSpace = lpTemp+1; + } + } + } + else + lpSpace = buffer; + + *ppPath = lpSpace; + + return(nFlag); +} + +int Map (char * buffer) +{ + WORD status, driveNum; + char *lpCommand, *inputPath, *lpEqual; + int fRoot, fInsert, fSpace, fCommandHandled; + int nFlag, searchNumber, iRet; + + // Fix for NWCS. + // NWGetDriveStatus() always returns 1800 on first call for non-Network + // drives on NWCS. So we call with c: first to pass the first call. + GetDriveStatus (3, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + + lpCommand = strtok (buffer, ";"); + + if (lpCommand == NULL) + { + DisplayMapping(); + return(0); + } + + do + { + fRoot = FALSE; + fInsert = FALSE; + fSpace = FALSE; + fCommandHandled = TRUE; + + // Make sure first and last char of the command are not spaces. + if (*lpCommand == ' ') + lpCommand++; + + if (*(lpCommand+strlen (lpCommand)-1) == ' ') + *(lpCommand+strlen (lpCommand)-1) = 0; + + if (!strcmp (lpCommand, "DISPLAY ON")) + { + fMapDisplayOn = TRUE; + continue; + } + else if (!strcmp (lpCommand, "DISPLAY OFF")) + { + fMapDisplayOn = FALSE; + continue; + } + else if (!strcmp (lpCommand, "ERROR ON") || !strcmp (lpCommand, "ERRORS ON")) + { + fMapErrorsOn = TRUE; + continue; + } + else if (!strcmp (lpCommand, "ERROR OFF") || !strcmp (lpCommand, "ERRORS OFF")) + { + fMapErrorsOn = FALSE; + continue; + } + + nFlag = GetFlag (lpCommand, &fInsert, &fRoot, &inputPath); + + /* + * The 4X login program is much more forgiving about spaces + * in the map command. + */ + { + char *lpTemp; + char *lpCur; + int inquote = FALSE; + + lpTemp = inputPath; + lpCur = inputPath; + + /* + * Compress blanks unless the string is quoted + */ + while ( *lpTemp ) + { + if ( *lpTemp == '\"' ) + { + if ( inquote ) + inquote = FALSE; + else + inquote = TRUE; + } + else if ( !inquote && + (( *lpTemp == ' ' ) || + ( *lpTemp == '\t' ) ) ) + { + } + else + { + *lpCur++ = *lpTemp; + } + lpTemp = NWAnsiNext(lpTemp); + } + *lpCur = '\0'; + } + + + if (nFlag == CM_HELP && fMapErrorsOn) + DisplayMessage(IDR_MAP_USAGE); + else if (nFlag == CM_NEXT) + { + if (strchr (inputPath, '=') || + strchr (inputPath, ' ') || + strchr (inputPath, '\t')) + fCommandHandled = FALSE; + else + iRet = MapNextAvailableDrive (inputPath, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else if (nFlag == CM_DEL) + { + if (driveNum = IsDrive (inputPath)) + iRet = RemoveDrive (driveNum, fMapDisplayOn, fMapErrorsOn); + else if (searchNumber = GetSearchNumber(inputPath)) + RemoveSearchDrive (searchNumber, fMapDisplayOn, fMapErrorsOn); + else + fCommandHandled = FALSE; + } + else //nFlag = CM_MAP + { + if (driveNum = IsDrive (inputPath)) + { + if (fInsert) + fCommandHandled = FALSE; + else if (fRoot) + iRet = MapNonSearchDrive (0, inputPath, TRUE, fMapDisplayOn, fMapErrorsOn, lpCommand); + else + DisplayDriveMapping(driveNum); + } + else if (searchNumber = GetSearchNumber (inputPath)) + { + if (fInsert || fRoot) + fCommandHandled = FALSE; + else + DisplaySearchDriveMapping(searchNumber); + } + else if ((lpEqual = strchr (inputPath, '=')) == NULL) + { + if (fInsert || strchr (inputPath, ' ')) + fCommandHandled = FALSE; + else + { + /* + * We must cope with MAP K:DIR which means change the + * directory on K: + */ + driveNum = 0; + if (isalpha(inputPath[0]) && (inputPath[1] == ':')) + { + driveNum = toupper(inputPath[0]) - 'A' + 1; + if ( !IsNetwareDrive(driveNum) ) + { + driveNum = 0; + } + } + iRet = MapNonSearchDrive (driveNum, inputPath, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + } + else + { + if ( ( !fNDS && strchr (lpEqual+2, ' ') ) + || lpEqual == inputPath) { + fCommandHandled = FALSE; + } + else + { + if (*AnsiPrev(inputPath, lpEqual) == ' ') + { + fSpace = TRUE; + *(lpEqual-1) = 0; + } + else + *lpEqual = 0; + + if (*(lpEqual+1) == ' ') + lpEqual++; + + driveNum = IsDrive (inputPath); + searchNumber = GetSearchNumber (inputPath); + *(inputPath+strlen(inputPath)) = fSpace? ' ' : '='; + + /* + * This is to handle the cases: + * + * map x:=s3:=sys:public + * map s3:=x:=sys:public + * + * Unfortuneatly the underlying parsing routines + * want everything null terminated, so we need + * to do the following shuffle. + * + */ + if ( driveNum || searchNumber ) + { + if ((strchr (lpEqual+1, '=')) != NULL) + { + char * lpEqual2; + char *tmpPath = _strdup( lpEqual+1 ); + + lpEqual2 = strchr (tmpPath, '='); + + if (*AnsiPrev(tmpPath, lpEqual2) == ' ') + { + fSpace = TRUE; + *(lpEqual2-1) = 0; + } + else + *lpEqual2 = 0; + + if (*(lpEqual2+1) == ' ') + lpEqual2++; + + if ( searchNumber ) + { + driveNum = IsDrive (tmpPath); + } + else + { + searchNumber = GetSearchNumber (tmpPath); + } + + if ( driveNum && searchNumber ) + { + lpEqual += (lpEqual2 - tmpPath) + 1; + } + + free (tmpPath); + + } + } + + if (searchNumber) + { + iRet = MapSearchDrive (searchNumber, driveNum, lpEqual+1, fInsert, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else if (driveNum) + { + if (fInsert) + fCommandHandled = FALSE; + else + iRet = MapNonSearchDrive (driveNum, lpEqual+1, fRoot, fMapDisplayOn, fMapErrorsOn, lpCommand); + } + else + fCommandHandled = FALSE; + } + } + } + + if (!fCommandHandled && fMapErrorsOn) + { + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + } + }while ((lpCommand = strtok (NULL, ";")) != NULL); + + return(iRet & 0xFF); +} + +/* Return drive number if input is a drive specified as a letter followed + by ':' for example if input is "A:", return 1 + or netware drive could be specified as *1: for example. + Otherwise, return 0. + */ +int IsDrive( char * input) +{ + unsigned short driveNum = 0, n; + + if (isalpha(input[0]) && (input[1] == ':') && (input[2] == 0)) + driveNum = toupper(input[0]) - 'A' + 1; + else if (input[0] == '*' && isdigit (input[1]) && input[1] != '0') + { + if (isdigit (input[2]) && input[3] == ':' && input[4] == 0) + n = (input[1]-'0')*10+(input[2]-'0'); + else if (input[2] == ':' && input[3] == 0) + n = input[1]-'0'; + + if (n) + { + GetFirstDrive (&driveNum); + driveNum += (n-1); + if (driveNum < 1 || driveNum > 26) + driveNum = 0; + } + } + + return driveNum; +} + +/* + If the input is "Sn:", return n, where n > 0 && n <= 16. + Otherwise return 0. + */ +int GetSearchNumber( char * input) +{ + int searchNumber = 0; + char *lpTemp; + + if (input[0] != 'S') + return(0); + + lpTemp = input+1; + while (*lpTemp && isalpha(*lpTemp)) + lpTemp++; + + if (strncmp (input, "SEARCH", lpTemp-input)) + return(0); + + if ((lpTemp[0] > '0') && + (lpTemp[0] <= '9')) + { + if ((lpTemp[1] == ':') && + (lpTemp[2] == 0)) + { + searchNumber = lpTemp[0] - '0'; + } + else if ((lpTemp[0] == '1') && + (lpTemp[1] >= '0') && + (lpTemp[1] <= '6') && + (lpTemp[2] == ':') && + (lpTemp[3] == 0)) + { + searchNumber = 10 + lpTemp[1] - '0'; + } + } + + return(searchNumber); +} + +/* + Return TRUE if the drive is a NetWare drive. + FALSE otherwise. + */ +int IsNetwareDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return (status & NETWARE_NETWARE_DRIVE); +} + +/* + Return TRUE if the drive is a local drive. + FALSE otherwise. + */ +int IsLocalDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return ((status & NETWARE_LOCAL_DRIVE) && !(status & NETWARE_NETWORK_DRIVE)); +} + +/* + Return TRUE if the drive is a network drive that is not netware + FALSE otherwise. + */ +int IsNonNetwareNetworkDrive (int driveNum) +{ + unsigned int iRet=0; + WORD status; + + if (iRet = GetDriveStatus ((unsigned short)driveNum, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL)) + { + return FALSE; + } + + return ((status & NETWARE_NETWORK_DRIVE) && !(status & NETWARE_NETWARE_DRIVE)); +} + +/* + Return the drive number of search drive n. + Return 0 if search drive n does not exist. + */ +int GetDriveFromSearchNumber (int searchNumber) +{ + char *path; + int i; + + path = getenv("PATH"); + + for (i = 1; i < searchNumber; i++) + { + path =strchr (path, ';'); + + if (path == NULL || *(path+1) == 0) + return(0); + + path++; + } + + return(toupper(*path) - 'A' + 1); +} + +/* + Display a specific drive's mapping. + */ +void DisplayDriveMapping(WORD drive) +{ + unsigned int iRet = 0; + WORD status = 0; + char rootPath[MAX_PATH_LEN], relativePath[MAX_PATH_LEN]; + + iRet = GetDriveStatus (drive, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL); + if (iRet) + { + DisplayError (iRet, "GetDriveStatus"); + return; + } + + if (status & NETWARE_NETWARE_DRIVE) + DisplayMessage(IDR_NETWARE_DRIVE, 'A'+drive-1, rootPath, relativePath); + else if ((status & NETWARE_NETWORK_DRIVE) || (status & NETWARE_LOCAL_DRIVE)) + DisplayMessage(IDR_LOCAL_DRIVE, 'A'+drive-1); + else + DisplayMessage(IDR_UNDEFINED, 'A'+drive-1); +} + +/* + Display a specific search drive's mapping. + */ +void DisplaySearchDriveMapping(int searchNumber) +{ + unsigned int iRet = 0; + char *p, *searchPath; + int i; + WORD status; + char path[MAX_PATH_LEN], rootPath[MAX_PATH_LEN], relativePath[MAX_PATH_LEN]; + + searchPath = NWGetPath(); + + for (i = 0; i < searchNumber-1; i++) + { + searchPath = strchr (searchPath, ';'); + if (searchPath != NULL) + searchPath++; + else + return; + } + + p = strchr (searchPath, ';'); + if (p != NULL) + { + i= p-searchPath; + strncpy (path, searchPath, i); + path[i] = 0; + } + else + strcpy (path, searchPath); + + if (isalpha(*path) && *(path+1) == ':') + { + iRet = GetDriveStatus ((unsigned short)(toupper(*path)-'A'+1), + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + rootPath, + relativePath, + NULL); + + if (iRet) + { + DisplayError (iRet, "GetDriveStatus"); + return; + } + else + { + if (status & NETWARE_NETWARE_DRIVE) + DisplayMessage(IDR_NETWARE_SEARCH, searchNumber, path, rootPath, relativePath); + else + DisplayMessage(IDR_LOCAL_SEARCH, searchNumber, path); + } + } + else + DisplayMessage(IDR_LOCAL_SEARCH, searchNumber, path); +} + +/* + Return TRUE if the mapPath is parsed, FALSE otherwise. + */ +int ParseMapPath(char * mapPath, char * volName, char * dirPath, char * serverName, int fMapErrorsOn, char * lpCommand) +{ + unsigned int iRet=0; + char *pColon, inputPath[MAX_PATH_LEN]; + int drive, nDriveNum; + + // fix g:=:sys:\public case. + if (*mapPath == ':') + mapPath++; + + if (strlen (mapPath) > MAX_INPUT_PATH_LEN) + { + if (fMapErrorsOn) + DisplayMessage(IDR_INVALID_PATH, mapPath); + return FALSE; + } + + // Get the drive or volume part if there is one. + if (pColon = strchr (mapPath, ':')) + { + char *directory = pColon+1; + int searchNumber; + + // Assing drive: part to input. + strncpy (inputPath, mapPath, directory-mapPath); + inputPath[directory-mapPath] = 0; + + if (nDriveNum = IsDrive (inputPath)) + { + if (*inputPath == '*') + { + *inputPath = 'A' + nDriveNum - 1; + *(inputPath+1) = ':'; + *(inputPath+2) = 0; + } + else if (!IsNetwareDrive(nDriveNum)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + } + else if (searchNumber = GetSearchNumber(inputPath)) + { + int drive = GetDriveFromSearchNumber (searchNumber); + + if (!drive) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + return FALSE; + } + + if (!IsNetwareDrive(drive)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + + inputPath[0] = 'A' + drive - 1; + inputPath[1] = ':'; + inputPath[2] = 0; + } + + strcat (inputPath, directory); + } + else + { + if ( fNDS ) + { + CHAR fullname[MAX_PATH]; + if ( !NDSCanonicalizeName( mapPath, fullname, MAX_PATH, TRUE ) ) + if ( !ConverNDSPathToNetWarePathA( fullname, DSCL_DIRECTORY_MAP, + inputPath ) ) + goto ParseThePath; + } + + // If drive is not specified, the current drive is used. + drive = _getdrive(); + if (!IsNetwareDrive(drive)) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_NETWORK_DRIVE); + return(FALSE); + } + + inputPath[0] = 'A'+drive-1; + inputPath[1] = ':'; + inputPath[2] = 0; + + strcat (inputPath, mapPath); + } + +ParseThePath: + + iRet = ParsePath (inputPath, + serverName, + volName, + dirPath); + if (iRet) + { + if (iRet == 0x880F) + { + DisplayMessage(IDR_MAP_NOT_ATTACHED_SERVER, lpCommand); + return(FALSE); + } + else + { + if (fMapErrorsOn) + DisplayMessage(IDR_INVALID_PATH, inputPath); + return(FALSE); + } + } + + return(TRUE); +} + +/* + Map drive to mapPath + */ +int MapDrive (int drive, int searchNum, char * mapPath, int bRoot, int bInsert, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet=0; + char volName[MAX_VOLUME_LEN+1]; //+1 for append ':'. + char dirPath[MAX_DIR_PATH_LEN]; + int currentDrive; + int OvermapDrive = -1; + char serverName[MAX_NAME_LEN]; + + if (!ParseMapPath(mapPath, volName, dirPath, serverName, fMapErrorsOn, lpCommand)) + return(3); + + if (IsNetwareDrive(drive)) + { + if ( drive == _getdrive() ) { + OvermapDrive = drive; + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase ((unsigned short)drive)) + { + if (fMapErrorsOn) { + /* Cannot delete the drive you are on */ + if (iRet == ERROR_DEVICE_IN_USE) + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + else + DisplayError (iRet, "DeleteDriveBase"); + } + return iRet; + } + } + else if ( IsNonNetwareNetworkDrive(drive) ) { + if (fMapErrorsOn) + DisplayMessage(IDR_NON_NETWARE_NETWORK_DRIVE, lpCommand); + return 3; + } + + if (bRoot) + { + // +2 is for strcat with ":". + char *fullPath = malloc( MAX_VOLUME_LEN + strlen (dirPath) + 2); + if (fullPath == NULL) + { + if (fMapErrorsOn) + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return 8; + } + + strcpy (fullPath, volName); + strcat (fullPath, ":"); + strcat (fullPath, dirPath); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + fullPath); + + // Relative names need to be expanded for the redirector + + if ( iRet && fNDS && ( volName[strlen(volName) - 1] == '.' ) ) + { + char canonName[MAX_VOLUME_LEN+1]; + if ( !NDSCanonicalizeName( volName, canonName, MAX_VOLUME_LEN, TRUE ) ) + { + strcpy (fullPath, canonName); + strcat (fullPath, ":"); + strcat (fullPath, dirPath); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + fullPath); + } + } + + if (iRet == 0) + { + if (searchNum) + searchNum = InsertSearchDrive(searchNum, drive, bInsert, NULL); + + currentDrive = _getdrive(); + _chdrive (drive); + _chdir( "\\" ); + _chdrive (currentDrive); + ExportCurrentDirectory( drive ); + + if (fMapDisplayOn) + { + if (searchNum) + DisplaySearchDriveMapping (searchNum); + else + DisplayDriveMapping((unsigned short)drive); + } + } + else + { + if (fMapErrorsOn) + { + switch ( iRet ) + { + case ERROR_DEVICE_IN_USE: + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + break; + case ERROR_BAD_NETPATH: + case ERROR_BAD_NET_NAME: + DisplayMessage(IDR_VOLUME_NOT_EXIST, volName); + iRet = 3; + break; + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + iRet = 3; + break; + default: + DisplayMessage(IDR_MAP_ERROR, iRet); + DisplayMessage(IDR_MAP_FAILED, lpCommand); + iRet = 3; + break; + } + } + } + + free (fullPath); + } + else + { + // NETX requires to end the volName with ':'. + strcat (volName, ":"); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + volName); + + // Relative names need to be expanded for the redirector + + if ( iRet && fNDS && ( volName[strlen(volName) - 2] == '.' ) ) + { + char canonName[MAX_VOLUME_LEN+1]; + + volName[strlen(volName)-1] = '\0'; + if ( !NDSCanonicalizeName( volName, canonName, MAX_VOLUME_LEN, TRUE ) ) + { + strcat (canonName, ":"); + + iRet = SetDriveBase ((unsigned short)drive, + serverName, + 0, + canonName); + } + } + + if (iRet) + { + if (fMapErrorsOn) + { + switch ( iRet ) + { + case ERROR_DEVICE_IN_USE: + DisplayMessage(IDR_CAN_NOT_CHANGE_DRIVE); + break; + case ERROR_EXTENDED_ERROR: + NTPrintExtendedError(); + iRet = 3; + break; + case ERROR_BAD_NETPATH: + case ERROR_BAD_NET_NAME: + default: + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + iRet = 3; + break; + } + } + } + else + { + // Succeed. + + if (searchNum) + searchNum = InsertSearchDrive(searchNum, drive, bInsert, NULL); + + currentDrive = _getdrive(); + _chdrive (drive); + if (!iRet && *dirPath) + { + iRet = _chdir( "\\" ); + if ( !iRet ) + iRet = _chdir (dirPath); + if ( iRet ) { + if (fMapErrorsOn) + { + DisplayMessage(IDR_MAP_INVALID_PATH, lpCommand); + } + + iRet = 3; + } + + } + else + { + _chdir( "\\" ); + } + _chdrive (currentDrive); + ExportCurrentDirectory( drive ); + + if (iRet == 0 && fMapDisplayOn) + { + if (searchNum) + DisplaySearchDriveMapping (searchNum); + else + DisplayDriveMapping((unsigned short)drive); + } + + } + } + + if ( OvermapDrive != -1 ) + _chdrive (OvermapDrive); + + return(iRet); +} + +/* + Map drive secified by driveNum to mapPath. + If bRoot is TRUE, use mapPath as the drive base. + */ +int MapNonSearchDrive (int driveNum, char *mapPath, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + int driveLetter, iRet = 0; + + if ((driveNum == 0) && (!strchr(mapPath, ':') && !bRoot)) + { + // map current drive to different directory. + if (_chdir(mapPath) && fMapErrorsOn) + { + DisplayMessage(IDR_DIRECTORY_NOT_FOUND, mapPath); + iRet = 3; + } + else { + ExportCurrentDirectory( _getdrive() ); + if (fMapDisplayOn) + DisplayDriveMapping((unsigned short)driveNum); + } + return(iRet); + } + else if ( (driveNum) && (isalpha(mapPath[0]) && (mapPath[1] == ':'))) + { + int mapdriveNum = toupper(mapPath[0]) - 'A' + 1; + + if ( driveNum == mapdriveNum ) + { + // map drive to different directory. + // map k:=k:\dir + + WORD currentDrive; + currentDrive = _getdrive(); + _chdrive (driveNum); + if (_chdir(mapPath) && fMapErrorsOn) + { + DisplayMessage(IDR_DIRECTORY_NOT_FOUND, mapPath); + iRet = 3; + } + else + { + ExportCurrentDirectory( _getdrive() ); + if (fMapDisplayOn) + DisplayDriveMapping((unsigned short)driveNum); + } + _chdrive (currentDrive); + return(iRet); + } + } + + if (driveNum == 0) + driveNum = _getdrive(); + + driveLetter = 'A' + driveNum -1; + + return MapDrive (driveNum, 0, mapPath, bRoot, 0, fMapErrorsOn, lpCommand); +} + +/* + Map the last free drive to mapPath and put it in the search path. + If bInsert is TRUE, don't replace search drive n, otherwise, + replace. + If bRoot is TRUE, use mapPath as the drive base. + */ +int MapSearchDrive (int searchNum, int driveNum, char *mapPath, int bInsert, int bRoot, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet=0; + int i; + WORD status; + char * lpEqual; + + /* + * Handle syntax map s2:=w:=volume: + * Handle syntax map w:=s2:=volume: + */ + if ( driveNum ) + { + return MapDrive (driveNum, searchNum, mapPath, bRoot, bInsert, fMapErrorsOn, lpCommand); + } + + // Check if mapPath is local path. + if (mapPath[1] == ':' && + IsLocalDrive (toupper(mapPath[0])-'A'+1)) + { + i = 0; // a bug? + searchNum = InsertSearchDrive(searchNum, i, bInsert, mapPath); + if ((searchNum != 0) && fMapDisplayOn) + DisplayMessage(IDR_LOCAL_SEARCH, searchNum, mapPath); + return 0; + } + + // Try to find the last available drive. + for (i = 26; i >= 1; i--) + { + iRet = GetDriveStatus ((unsigned short)i, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + if (iRet) + continue; + + if (!(status & NETWARE_LOCAL_DRIVE) && + !(status & NETWARE_NETWORK_DRIVE)) + { + // Found. Map it to the path. + return MapDrive (i, searchNum, mapPath, bRoot, bInsert, fMapErrorsOn, lpCommand); + } + } + + if (fMapErrorsOn) + DisplayMessage (IDR_NO_DRIVE_AVAIL); + return(0); +} + +/* + Map the next available drive to the mapPath. + */ +int MapNextAvailableDrive (char *mapPath, int fMapDisplayOn, int fMapErrorsOn, char *lpCommand) +{ + unsigned int iRet = 0; + int i; + WORD status; + + // Find a free drive that is not mapped. + // Then map it to the mapPath. + for (i = 1; i <= 26; i++) + { + iRet = GetDriveStatus ((unsigned short)i, + NETWARE_FORMAT_SERVER_VOLUME, + &status, + NULL, + NULL, + NULL, + NULL); + if (iRet) + { + if (fMapErrorsOn) + DisplayError (iRet, "GetDriveStatus"); + return iRet; + } + + if (!(status & NETWARE_LOCAL_DRIVE) && + !(status & NETWARE_NETWORK_DRIVE)) + { + iRet = MapNonSearchDrive (i, mapPath, FALSE, fMapDisplayOn, fMapErrorsOn, lpCommand); + return iRet; + } + } + + if (fMapErrorsOn) + DisplayMessage(IDR_NO_DRIVE_AVAIL); + + return(0); +} + +/* + Remove a drive mapping. + */ +int RemoveDrive (WORD drive, int fMapDisplayOn, int fMapErrorsOn) +{ + unsigned int iRet=0; + int searchNum; + + if (IsNetwareDrive (drive)) + { + if (searchNum = IsSearchDrive(drive)) + { + RemoveSearchDrive (searchNum, fMapDisplayOn, fMapErrorsOn); + } + else + { + /* + * Can't delete current drive on NT + */ + if ( drive == _getdrive() ) { + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase (drive)) + { + if (fMapErrorsOn) + DisplayError (iRet, "DeleteDriveBase"); + } + else + { + if (fMapDisplayOn) + DisplayMessage(IDR_DEL_DRIVE, 'A'+drive-1); + } + } + } + else + { + if (fMapErrorsOn) + DisplayMessage(IDR_WRONG_DRIVE, 'A'+drive-1); + + return(50); //error level. + } + + return(0); +} + +/* + Remove a search drive. + */ +void RemoveSearchDrive (int searchNumber, int fMapDisplayOn, int fMapErrorsOn) +{ + WORD drive; + + // Get the drive number. + drive = GetDriveFromSearchNumber (searchNumber); + + if (!drive) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + return; + } + + // If the drive is a netware drive, remove the drive mapping. + if (IsNetwareDrive (drive)) + { + unsigned int iRet=0; + /* + * Can't delete current drive on NT + */ + if ( drive == _getdrive() ) { + _chdrive (SafeDisk); + } + if (iRet = DeleteDriveBase (drive)) + { + if (fMapErrorsOn) + DisplayError (iRet, "DeleteDriveBase"); + return; + } + } + + RemoveDriveFromPath (searchNumber, fMapErrorsOn); + + if (fMapDisplayOn) + DisplayMessage(IDR_DEL_SEARCH_DRIVE, 'A'+drive-1); + + // If the drive is not a local drive, remove all reference + // to the drive in the path. + if (!IsLocalDrive (drive)) + { + while (searchNumber = IsSearchDrive (drive)) + { + RemoveDriveFromPath (searchNumber, fMapErrorsOn); + } + } +} + +/* + Remove a search drive from the path. + */ +void RemoveDriveFromPath(int searchNumber, int fMapErrorsOn) +{ + char *pOldPath, *pNewPath, *restEnvSeg, *pPath, *Path; + int i, n; + + // Move pOldPath to where we want to put the new path string. + pOldPath = NWGetPath(); + pPath = malloc( strlen(pOldPath) + 5 + 1 + 1 ); + strcpy(pPath, "PATH="); + strcat(pPath, pOldPath); + pOldPath = pPath + 5; + + for (i = 1; i < searchNumber; i++) + { + pOldPath=strchr (pOldPath, ';'); + + if (pOldPath == NULL) + { + if (fMapErrorsOn) + DisplayMessage(IDR_SEARCH_DRIVE_NOT_EXIST, searchNumber); + free( pPath ); + return; + } + + pOldPath++; + } + + // Move pNewPath to the beginning of the path string that + // needs to be moved. + if (pNewPath = strchr (pOldPath, ';')) + pNewPath++ ; + else + pNewPath = pOldPath + strlen (pOldPath); + + // Calculate the number of characters needs to be moved. + n = strlen (pNewPath) + 1; + restEnvSeg = pNewPath + n; + + n++; + + // Move the path string to overwrite the search drive. + memmove (pOldPath, pNewPath, n); + + Path = malloc (strlen (pPath)+1); + strcpy (Path, pPath); + _putenv (Path); + ExportEnv( pPath ); + free( pPath ); +} + + +/* + If bInsert is TRUE, insert dirve specified by driveNum as search + drive specified by searchNum. Otherwise replace search drive + specified by searchNum with drive specified by driveNum. + */ +int InsertSearchDrive(int searchNum, int driveNum, int bInsert, char * insertPath) +{ + char *pOldPath, *pNewPath, *restEnvSeg, *pPath, *Path; + int i, n = 0, bSemiColon, nInsertChar; + + nInsertChar = (insertPath == NULL)? 3 : strlen (insertPath); + + // Check if memory block is large enough. + if (!MemorySegmentLargeEnough (nInsertChar+1)) + return 0; + + // Move pNewPath to where we put the new drive. + pNewPath = NWGetPath(); + pPath = malloc( strlen(pNewPath) + 5 + 1 + nInsertChar + 1 + 1 ); + strcpy(pPath, "PATH="); + strcat(pPath, pNewPath); + pNewPath = pPath + 5; + + for (i = 1; i < searchNum; i++) + { + if (strchr (pNewPath, ';')) + { + pNewPath = strchr (pNewPath, ';'); + } + else + { + pNewPath += strlen (pNewPath); + bInsert = TRUE; + i++; + break; + } + + pNewPath++; + } + + // Move pOldPath to the begining of the path string that needs + // to be moved. + if (bInsert) + pOldPath = pNewPath; + else + { + if ((pOldPath = strchr (pNewPath, ';')) == NULL) + pOldPath = pNewPath + strlen (pNewPath); + else + pOldPath++; + } + + // Figure out the number of characters that need to be moved. + n = strlen (pOldPath) + 1; + restEnvSeg = pOldPath + strlen (pOldPath) + 1; + + n++; + + // If we insert a new drive to the end of the path which ends with + // a ';', or if we replace the last search drive, no ';' is needed. + bSemiColon = bInsert ? (*(pNewPath-1) != ';' || *pOldPath != 0) + : (*pOldPath != 0); + + // Move the old path so that we will have space for the new search drive. + memmove (pNewPath + (bSemiColon? nInsertChar+1:nInsertChar), pOldPath, n); + + if ((*pNewPath == 0)&& bSemiColon) + { + // Insert as the last one to the path. + // Put ';' at the begining. + *pNewPath = ';'; + if (insertPath == NULL) + { + *(pNewPath+1) = 'A' + driveNum - 1; + *(pNewPath+2) = ':'; + *(pNewPath+3) = '.'; + } + else + memcpy (pNewPath+1, insertPath, nInsertChar); + } + else + { + if (insertPath == NULL) + { + *pNewPath = 'A' + driveNum - 1; + *(pNewPath+1) = ':'; + *(pNewPath+2) = '.'; + } + else + memcpy (pNewPath, insertPath, nInsertChar); + if (bSemiColon) + *(pNewPath+nInsertChar) = ';'; + } + + Path = malloc (strlen (pPath)+1); + strcpy (Path, pPath); + _putenv (Path); + ExportEnv( pPath ); + free( pPath ); + + return (i); +} + +/* + * Used by SetEnv(). + * Return the number of bytes of environment variable pointed by lpRest + */ +int GetRestEnvLen (char *lpRest) +{ + int nTotal = 1; + nTotal += strlen (lpRest); + + return(nTotal); +} diff --git a/private/nw/nwscript/nwscript.c b/private/nw/nwscript/nwscript.c new file mode 100644 index 000000000..f56e23ff0 --- /dev/null +++ b/private/nw/nwscript/nwscript.c @@ -0,0 +1,84 @@ +/************************************************************************* +* +* NWSCRIPT.C +* +* This module is the NetWare Logon Script utility. +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NWSCRIPT.C $ +* +* Rev 1.3 22 Jan 1996 16:48:32 terryt +* Add automatic attach query during map +* +* Rev 1.2 22 Dec 1995 14:26:08 terryt +* Add Microsoft headers +* +* Rev 1.1 20 Nov 1995 16:10:38 terryt +* Close open NDS handles +* +* Rev 1.0 15 Nov 1995 18:07:42 terryt +* Initial revision. +* +* Rev 1.1 23 May 1995 19:37:18 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:10:58 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nwscript.h" + +int NTNetWareLoginScripts( int argc, char ** argv ); + +unsigned int fNDS = FALSE; + +/************************************************************************* +* +* main +* Main function and entry point +* +* ENTRY: +* argc (input) +* count of the command line arguments. +* argv (input) +* vector of strings containing the command line arguments; +* (not used due to always being ANSI strings). +* +* EXIT +* (int) exit code: SUCCESS for success; FAILURE for error. +* +*************************************************************************/ + +int _CRTAPI1 +main( int argc, + char **argv ) +{ + // + // Call wksta to reset the sync login script flag if it did set it. + // This flag is set and reset everytime so that if nw login scripts + // are not used, user does not need wait. + // Ignore any errors. + // + (void) NwSetLogonScript(RESET_SYNC_LOGONSCRIPT) ; + + (void)NTNetWareLoginScripts( argc, argv ); + + CleanupExit( 0 ); + + return 0; + +} /* main() */ + + diff --git a/private/nw/nwscript/nwscript.rc b/private/nw/nwscript/nwscript.rc new file mode 100644 index 000000000..96c646176 --- /dev/null +++ b/private/nw/nwscript/nwscript.rc @@ -0,0 +1,243 @@ +#ifdef NOMINMAX +#undef NOMINMAX +#endif + +#include +#include +#include "nwscript.h" + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "NetWare Logon Script Utility" +#define VER_INTERNALNAME_STR "nwscript" +#define VER_ORIGINALFILENAME_STR "nwscript.exe" + +// #define VER_LEGALCOPYRIGHT_STR VER_LEGALCOPYRIGHT_STR +#undef VER_ADDITIONALCOPYRIGHT_STR + +#include "common.ver" + +STRINGTABLE +BEGIN + IDR_ERROR + "Error: unexpected error 0x%x during %S\n" + IDR_NO_DEFAULT_CONNECTION + "Error: Unable to get default connection.\n\a" + IDR_NO_KNOWN_FILE_SERVER + "No known file server.\n" + IDR_LOCAL_DRIVE + "Drive %C: maps to a local disk.\n" + IDR_NETWARE_DRIVE + "Drive %C: = %S \\%S\n" + IDR_DASHED_LINE + " ----- Search Drives -----\n" + IDR_LOCAL_SEARCH + "S%d: = %S\n" + IDR_NETWARE_SEARCH + "S%d: = %S [%S \\%S]\n" + IDR_NOT_ENOUGH_MEMORY + "Error: Not enough memory.\n" + IDR_NO_RESPONSE + "No response from file server %S.\n" + IDR_PASSWORD + "Enter the password for user %S on server %S: " + IDR_ATTACHED + "You are attached to server %S.\n\n" + IDR_ACCESS_DENIED + "Access denied.\n" + IDR_UNAUTHORIZED_LOGIN_TIME + "Attempt to login during an unauthorized time period.\nThe supervisor has limited the times that you can login to this server.\n" + IDR_LOGIN_DENIED_NO_CONNECTION + "Attempting to simultaneously login to too many work stations.\nThe supervisor has limited the number of active connections you may have.\n" + IDR_UNAUTHORIZED_LOGIN_STATION + "Attempting to login from an unapproved station.\nThe supervisor has limited the stations that you are allowed to login on.\n" + IDR_ACCOUNT_DISABLED + "This account has expired or been disabled by the supervisor.\n" + IDR_PASSWORD_EXPRIED_NO_GRACE + "Password has expired and all grace logins have been used.\n" + IDR_MAP_NOT_ATTACHED_SERVER + "Attempt to map drive to server to which you are not currently attached.\nThe map command was ""%S"".\n" + IDR_MAP_USAGE + "Microsoft (R) MAP Utility\nCopyright (C) Microsoft Corporation 1994. All rights reserved.\n\n View current mapping.\n\tMAP [drive:]\nCreate or change network drive mappings\n\tMAP path\n\tMAP drive:=[drive:|path]\n\tMAP [DEL[ete] | REM[ove]] drive:\n Create or change search drive mappings\n\tMAP [INS[ert]] drive:=[drive:|path]\nMap a drive to a fake root directory\n\tMAP ROOT drive:=[drive:|path]\nMap the next available drive\n\tMAP N[ext] [drive:|path]\n" + IDR_UNDEFINED + "Drive %C: is not defined.\n" + IDR_DIRECTORY_NOT_FOUND + "Directory ""%S"" is not locatable.\n" + IDR_VOLUME_NOT_EXIST + "Volume ""%S"" does not exist.\n" + IDR_WRONG_DRIVE + "Attempted operation on invalid drive %C:\n" + IDR_DEL_DRIVE + "Mapping for drive %C: has been deleted.\n" + IDR_DEL_SEARCH_DRIVE + "The search mapping for drive %C: has been deleted.\n" + IDR_SEARCH_DRIVE_NOT_EXIST + "Search%d: does not exist.\n" + IDR_NOT_NETWORK_DRIVE + "Attempt to map network drive to unmapped drive or local drive.\n" + IDR_NO_DRIVE_AVAIL + "All Drives are in use.\n" + IDR_INVALID_PATH + """%S"" Invalid path.\n" + IDR_CAN_NOT_CHANGE_DRIVE + "Can not change the drive mapping.\n" + IDR_MAP_INVALID_PATH + "Attempt to map drive to invalid path in map command ""%S"".\n" + IDR_MAP_FAILED + "Following drive mapping operation could not be completed.\r\n ""%S""\r\n" + IDR_NO_SCRIPT_FILE + "Cannot open this script file: %S\n" + IDR_STRIKE_KEY + "Strike any key when ready . . ." + IDR_CANNOT_EXECUTE + "Could not execute external program ""%S"".\n" + IDR_ENOENT + "Could not execute external program ""%S"", program not found.\n" + IDR_EXIT_NOT_SUPPORTED + "The EXIT command followed by a string is not supported on this machine.\n" + IDR_IF_TOO_DEEP + "Script Error: ""IF"" statements nested too deeply. The nesting limit is 9 levels.\n" + IDR_SCRIPT_ERROR + "Script Error: Could not interpret line.\n" + IDR_ORIGINAL_LINE_WAS + "The original line was:\r\n%S\n\n" + IDR_BAD_COMMAND + "Bad command or file name.\n" + IDR_LABEL_NOT_FOUND + "Could not find label ""%S"".\n" + IDR_NO_VOLUME + "Error: No volume found.\n" + IDR_ERROR_DURING + "Error: unexpected error during %S\n" + IDR_MAP_ERROR + "%x\n" + IDR_ENTER_SERVER_NAME + "Enter the server name: " + IDR_ENTER_LOGIN_NAME + "Enter login name for server %S: " + IDR_ERROR_SET_DEFAULT_DRIVE + "Could not set the default drive to drive %C:.\n\n" + IDR_ERROR_OPEN_SCRIPT + "Cannot open this script file: %S\n" + IDR_DIVIDE_BY_ZERO + "Attempted to divide by zero\n" + IDR_NEWLINE + "\n" + IDR_SERVER_USER + "%S/%S: " + IDR_NON_NETWARE_NETWORK_DRIVE + "Following drive mapping operation was attempted on a non-NetWare network drive.\r\n ""%S""\r\n" + IDR_CAPTURE_USAGE + "Microsoft (R) CAPTURE Utility\nCopyright (C) Microsoft Corporation 1994. All rights reserved.\n\n USAGE: CAPTURE /SHow /Server=fileserver /Queue=queuename /Local=n\n /Form=form or n /CReate=path /Copies=n (1-255) /TImeout=n /Keep /Tabs=n (1-18) /No Tabs /Banner=bannername /NAMe=name /No Banner /FormFeed /No FormFeed\n /AUtoendcap /No Autoend /NOTIfy /No NOTIfy\n" + + IDR_NOT_ACTIVE + "\nLPT%d: Capturing Is Not Currently Active.\n" + IDR_LPT_STATUS + "\n LPT%d: Capturing data to server %S queue %S.\n %s\n Capture Defaults:%-15sAutomatic Endcap:%s\n Banner :%-24SForm Feed :%s\n Copies :%-24dTabs :%s\n Form :%-24dTimeout Count :%s\n" + IDR_LPT_STATUS_NO_BANNER + "\n LPT%d: Capturing data to server %S queue %S.\n %s\n Capture Defaults:%-15sAutomatic Endcap:%s\n Banner :%-24sForm Feed :%s\n Copies :%-24dTabs :%s\n Form :%-24dTimeout Count :%s\n" + IDR_UNKNOW_FLAG + "An unknown flag %S was encountered.\n" + IDR_INVALID_LPT_NUMBER + "Local printer number (1, 2, or 3) expected.\n" + IDR_SERVER_NOT_FOUND + "Unable to attach to server %S.\n" + IDR_TIMEOUT_OUTOF_RANGE + "Timeout value (0-1000) expected.\n" + IDR_TABSIZE_OUTOF_RANGE + "Tab size must be 1 - 18.\n" + IDR_COPIES_OUTOF_RANGE + "Number of copies (1-255) expected.\n" + IDR_INVALID_BANNER + "%S is invalid banner.\n" + IDR_INVALID_FORM_NAME + "%S is invalid form name.\n" + IDR_INVALID_FORM_TYPE + "Form type (0-255) expected.\n" + IDR_SUCCESS_QUEUE + "Device LPT%d: re-routed to queue %S on server %S.\n" + IDR_NO_PRINTERS + "No default queue name can be found on server %S.\n" + IDR_QUEUE_NOT_EXIST + "Queue %S does not exist on server %S.\n" + IDR_TIME_OUT_EXPECTED + "Timeout value (0-1000) expected.\n" + IDR_LPT_NUMBER_EXPECTED + "Local printer number (1, 2, or 3) expected.\n" + IDR_FORM_EXPECTED + "Form number expected.\n" + IDR_COPIES_EXPECTED + "Number of copies (1-255) expected.\n" + IDR_TAB_SIZE_EXPECTED + "Tab size expected.\n" + IDR_JOB_NOT_FOUND + "%S is not a valid PrintCon job definition.\n" + IDR_FILE_CAPTURE_UNSUPPORTED + "File Capture is unsupported.\n" + IDR_DISABLED + "Disabled" + IDR_ENABLED + "Enabled" + IDR_YES + "Yes" + IDR_NO + "No"; + IDR_SECONDS + "%d seconds"; + IDR_CONVERT_TO_SPACE + "Converted to %d spaces"; + IDR_NO_CONVERSION + "No conversion"; + IDR_NOTIFY_USER + "User will be notified after the files are printed."; + IDR_NOT_NOTIFY_USER + "User will not be notified after the files are printed."; + IDR_NONE + "(None)"; + IDR_CONNECTION_REFUSED + "Server refused the login; too many sessions.\n"; + IDR_LASTLOGIN_PM + "Last login occurred at: %d-%02d-%02d %d:%02d:%02d pm.\n"; + IDR_LASTLOGIN_AM + "Last login occurred at: %d-%02d-%02d %d:%02d:%02d am.\n"; + IDR_ALL_LOCAL_DRIVES + "Drives %S map to a local disk.\n"; + IDR_CHANGE_CONTEXT_ERROR + "The context you want to change to does not exist.\nYou tried to change to:\n[%S]\nYour context will be left unchanged.\n"; + IDR_GET_CONTEXT_ERROR + "Error accessing the current context.\n"; + IDR_DISPLAY_CONTEXT + "Your context has been changed to: %S\n"; + IDR_LPT_STATUS_NDS + "\n LPT%d: Capturing data to print queue %S.\n %s\n Capture Defaults:%-15sAutomatic Endcap:%s\n Banner :%-24SForm Feed :%s\n Copies :%-24dTabs :%s\n Form :%-24dTimeout Count :%s\n" + IDR_LPT_STATUS_NO_BANNER_NDS + "\n LPT%d: Capturing data to print queue %S.\n %s\n Capture Defaults:%-15sAutomatic Endcap:%s\n Banner :%-24sForm Feed :%s\n Copies :%-24dTabs :%s\n Form :%-24dTimeout Count :%s\n" + IDR_NO_QUEUE + "No printer queue was specified\n"; + IDR_LASTLOGIN + "Last login occurred at: %s %s.\n"; + IDR_TREE_OPEN_FAILED + "Cannot open NDS tree\n"; + IDR_NDS_CONTEXT_INVALID + "NDS context is invalid\n"; + IDR_NDS_USERNAME_FAILED + "NDS user name could not be accessed\n"; + IDR_QUERY_INFO_FAILED + "NetWare information query failed\n"; + IDR_NDSQUEUE_NOT_EXIST + "Queue %S does not exist.\n" + IDR_NDSSUCCESS_QUEUE + "Device LPT%d: re-routed to queue %S.\n" + IDR_CAPTURE_FAILED + "Capture of queue %S failed.\n" + IDR_CURRENT_TREE + "Your current tree is: %s\n" + IDR_CURRENT_SERVER + "You are attached to server %S.\n" + IDR_CURRENT_CONTEXT + "Your current context is %S\n" + IDR_AUTHENTICATING_SERVER + "Authenticating to server %S.\n" + IDR_NO_END_QUOTE + "Script Error: The line contains no end quote.\n" +END diff --git a/private/nw/nwscript/parspath.c b/private/nw/nwscript/parspath.c new file mode 100644 index 000000000..77f3a250c --- /dev/null +++ b/private/nw/nwscript/parspath.c @@ -0,0 +1,341 @@ + +/************************************************************************* +* +* PARSPATH.C +* +* NetWare parsing routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\PARSPATH.C $ +* +* Rev 1.3 22 Jan 1996 16:48:38 terryt +* Add automatic attach query during map +* +* Rev 1.2 22 Dec 1995 14:26:16 terryt +* Add Microsoft headers +* +* Rev 1.1 22 Dec 1995 11:08:50 terryt +* Fixes +* +* Rev 1.0 15 Nov 1995 18:07:48 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:23:34 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:11:00 terryt +* Initial revision. +* +*************************************************************************/ + +/*++ + +Copyright (c) 1994 Micro Computer Systems, Inc. + +Module Name: + + nwlibs\parspath.c + +Abstract: + + Directory APIs. + +Author: + + Shawn Walker (v-swalk) 10-10-1994 + +Revision History: + +--*/ +#include "common.h" +#include +#include +#include "inc\nwlibs.h" + + +/*++ +******************************************************************* + + ParsePath + +Routine Description: + + Parse the path string. + +Arguments: + + pPath = The pointer to the path to parse. + pServerName = The pointer to return the server name. + pVolumeName = The pointer to return the volume name. + pDirPath = The pointer to return the directory path. + +Return Value: + + 0x0000 SUCCESSFUL + 0x000F INVALID_DRIVE + 0x8800 Unknown error + +******************************************************************* +--*/ +unsigned int +ParsePath( + unsigned char *pPath, + unsigned char *pServerName, //OPTIONAL + unsigned char *pVolumeName, //OPTIONAL + unsigned char *pDirPath //OPTIONAL + ) +{ + unsigned char *p, *p2; + unsigned int Result; + unsigned int Remote; + unsigned int NcpError = 0; + unsigned char DriveNumber = (unsigned char)-1; + unsigned char CurrentPath[64]; + unsigned char RootPath[NCP_MAX_PATH_LENGTH]; + unsigned char ServerName[NCP_MAX_PATH_LENGTH]; + unsigned char *pRootDir; + unsigned char NetWarePath[NCP_MAX_PATH_LENGTH]; + unsigned char VolumeName[NCP_VOLUME_LENGTH]; + unsigned int LocalDriveForce = FALSE; + + RootPath[0] = 0; + VolumeName[0] = 0; + ServerName[0] = 0; + + if ( pServerName ) + *pServerName = '\0'; + + /** See if there is a volume on the path **/ + + p = pPath; + while (*p != ':' && *p) { + p++; + } + + if (*p == ':') { + *p = 0; + + /** + Check to see if this is a drive letter. The volume must + be 2 characters or more. + **/ + + if ((p - pPath) == 1) { + + /** Make sure it is a valid alpha char **/ + + if (!isalpha((int) *pPath)) { + return 0x000F; + } + + *pPath = (unsigned char) toupper((int) *pPath); + + /** Make it a drive number **/ + + DriveNumber = (unsigned char) (*pPath - 'A'); + GetDriveStatus ((unsigned short)(DriveNumber+1), + NETWARE_FORMAT_SERVER_VOLUME, + NULL, + NULL, + RootPath, + NULL, + NULL); + pRootDir = strchr (RootPath, ':'); + if (pRootDir) + { + /* + * Setup the pServerName here + */ + + pRootDir[0] = '\0'; + p2 = RootPath; + while (*p2) + { + if (*p2 == '\\' || *p2 == '/') + { + *p2++ = 0; + strcpy(ServerName, RootPath); + if (pServerName) { + strcpy(pServerName, RootPath); + } + break; + } + p2++; + } + strcpy (RootPath, pRootDir+1); + } + else + RootPath[0] = 0; + } + else { + + DriveNumber = 0; + LocalDriveForce = TRUE; + + /** + If there is a server name, save the server name + and set the error code to 0x880F but still parse + the path. This just means that there is no connection + for this server. Even if we do have one. + **/ + + p2 = pPath; + while (*p2) { + if (*p2 == '\\' || *p2 == '/') { + *p2++ = 0; + + strcpy(ServerName, pPath); + if (pServerName) { + strcpy(pServerName, pPath); + } + pPath = p2; + + NcpError = 0x880F; + break; + } + p2++; + } + + if (NcpError == 0x880F) { + /** + Do any attach processing. + **/ + + NcpError = DoAttachProcessing( ServerName ); + + } + + strcpy(VolumeName, pPath); + } + + /** Get the directory **/ + + p++; + pPath = p; + } + + /** + If we did not get the drive letter of volume name + from above, then get the current drive we are on. + **/ + + if (DriveNumber == (unsigned char) -1) { + DriveNumber = _getdrive(); + } + + /* + * Use the PREFERRED_SERVER for 3X logins if no server name + * was specified. + */ + if (pServerName && !fNDS && !pServerName[0] ) { + strcpy( pServerName, PREFERRED_SERVER ); + } + + if (pVolumeName) { + + /** + Check if the drive is remote, if so, then go get the path + from the server. + **/ + if ( LocalDriveForce ) { + Result = 0; + Remote = 0; + } + else { + Result = IsDriveRemote(DriveNumber, &Remote); + + } + + if (NcpError != 0x880F && !VolumeName[0] && (Result || !Remote)) { + pVolumeName[0] = (unsigned char) (DriveNumber + 'A'); + pVolumeName[1] = 0; + } + else { + if (VolumeName[0]) { + strcpy(pVolumeName, VolumeName); + } + else { + Result = NTGetNWDrivePath( DriveNumber, NULL, NetWarePath ); + if (Result) { + return Result; + } + + p = NetWarePath; + while (*p != ':' && *p) { + p++; + } + + if (*p == ':') { + *p = 0; + } + strcpy(pVolumeName, NetWarePath); + } + } + } + + if (pDirPath) { + + memset(CurrentPath, 0, sizeof(CurrentPath)); + + if (VolumeName[0]) { + strcpy(pDirPath, pPath); + } + else { + Result = NTGetCurrentDirectory(DriveNumber, CurrentPath); + if (Result) { + CurrentPath[0] = 0; + } + else { + /* + * Skip the drive letter + */ + if ( CurrentPath[0] ) { + int i; + for ( i = 0; ;i++ ) { + CurrentPath[i] = CurrentPath[i+3]; + if ( !CurrentPath[i] ) + break; + } + } + } + + if (CurrentPath[0] == 0) { + if ( (*pPath == '\\') || ( *pPath == '/' ) ) { + sprintf(pDirPath, "%s%s", RootPath, pPath); + } + else if ( !(*pPath) ) { + sprintf(pDirPath, "%s", RootPath); + } + else { + sprintf(pDirPath, "%s\\%s", RootPath, pPath); + } + } + else { + if (*pPath) { + if ( (*pPath == '\\') || ( *pPath == '/' ) ) { + strcpy (pDirPath, RootPath); + if (pPath[1]) { + strcat(pDirPath, pPath); + } + } + else { + sprintf(pDirPath, "%s\\%s\\%s", RootPath, CurrentPath, pPath); + } + } + else { + sprintf(pDirPath, "%s\\%s", RootPath, CurrentPath); + } + } + } + + /** Convert the / in the path to \ **/ + for (p = pDirPath; ( p && ( *p != 0 ) ) ; p++) + { + if (*p == '/') + *p = '\\'; + } + } + + return NcpError; +} diff --git a/private/nw/nwscript/ps40db.c b/private/nw/nwscript/ps40db.c new file mode 100644 index 000000000..9eae6aa09 --- /dev/null +++ b/private/nw/nwscript/ps40db.c @@ -0,0 +1,597 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + psndsdb.c + +Abstract: + + Read the Print Configuration Attributes + + $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\PS40DB.C $ +* +* Rev 1.4 10 Apr 1996 14:23:28 terryt +* Hotfix for 21181hq +* +* Rev 1.4 12 Mar 1996 19:55:22 terryt +* Relative NDS names and merge +* +* Rev 1.3 04 Jan 1996 18:57:36 terryt +* Bug fixes reported by MS +* +* Rev 1.2 22 Dec 1995 14:26:22 terryt +* Add Microsoft headers +* +* Rev 1.1 20 Nov 1995 15:09:46 terryt +* Context and capture changes +* +* Rev 1.0 15 Nov 1995 18:07:52 terryt +* Initial revision. + +--*/ +#include "common.h" + +extern DWORD SwapLong(DWORD number); +extern char *TYPED_USER_NAME; + +unsigned int +PS40GetJobName( + unsigned int NDSCaptureFlag, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord, + unsigned char GetDefault + ); + +#include +#define NWPS_JOB_NAME_SIZE 32 /* 31 bytes and a '\0' */ +#define NWPS_FORM_NAME_SIZE 12 /* 12 bytes and a '\0' */ +#define NWPS_BANNER_NAME_SIZE 12 /* 12 bytes and a '\0' */ +#define NWPS_BANNER_FILE_SIZE 12 /* 12 bytes and a '\0' */ +#define NWPS_DEVI_NAME_SIZE 32 /* 32 bytes and a '\0' */ +#define NWPS_MODE_NAME_SIZE 32 /* 32 bytes and a '\0' */ +#define NWPS_BIND_NAME_SIZE 48 +#define NWPS_MAX_NAME_SIZE 514 +/* +// NWPS_Job_Old_Db_Hdr is the first record in the 4.0 PrnConDB database. +// It contains the following information about the database: +// The version number, +// the number of NWPS_Job_Rec records in PrnConDB, +// the name of the default print job configuration and +// the name of the job record owner. +*/ +typedef struct { + char text[ 76 ]; /* Printcon database. Version 4.0 */ + char DefaultJobName[ 32 ]; /* Name of default Job */ + char Owner[ 256 ]; /* owner of the job record */ + WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */ + WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */ + BYTE MajorVersion; /* 4 */ + BYTE MinorVersion; /* 0 */ +} PRINTCON_40_HEADER; + +#define PRINTCON_40_HEADER_SIZE sizeof(PRINTCON_40_HEADER) + +/* +// NWPS_Job_41_Db_Hdr is the first record in the 4.1 PrnConDB database. +// It contains the following information about the database: +// The version number, +// the number of NWPS_Job_Rec records in PrnConDB, +// the name of the default print job configuration and +// the name of the job record owner IN UNICODE. +*/ +typedef struct { + char text[ 76 ]; /* Printcon database. Version 4.1 */ + char DefaultJobName[ 32 ]; /* Name of default Job */ + char unused[ 256 ]; /* no longer used. */ + WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */ + WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */ + BYTE MajorVersion; /* 4 */ + BYTE MinorVersion; /* 1 unicode defaultPJOwner etc. */ + WORD Owner[ 256 ]; /* owner of the default job record */ +} PRINTCON_41_HEADER; + +#define PRINTCON_41_HEADER_SIZE sizeof(PRINTCON_41_HEADER) + +/* +// NWPS_Job_Name_Rec is the type of record found in the +// second section of the PrnConDB database. Each one of +// these records contains the name of each NWPS_Job_Rec +// and a pointer to their location in the third section of +// the database. There is space set aside in this second +// section for fifty NWPS_Job_Name_Rec records; if this +// limit is exceeded then another fifty-record block following +// the first one is allocated after the third section of the +// database is moved down to make room for the expansion. +*/ +typedef struct { + char JobName[ NWPS_JOB_NAME_SIZE ]; /* 1 - 31 chars long + 0 */ + long JobRecordOffset; /* Offset of the record + // (from the beginning + // of the 3rd section for 4.0 + // databases and from the start + // of the file for pre-4.0) + */ +} JOB_NAME_AREA; + +#define JOB_NAME_AREA_SIZE sizeof(JOB_NAME_AREA) + +typedef struct { + union { + struct { + DWORD DataType : 1; /* 0=Byte stream 1 = Text */ + DWORD FormFeed : 1; /* 0 = FF; 1 = suppress FF */ + DWORD NotifyWhenDone : 1; /* 0 = no, 1 = yes */ + DWORD BannerFlag : 1; /* 0 = no, 1 = yes */ + DWORD AutoEndCap : 1; /* 0 = no, 1 = yes */ + DWORD TimeOutFlag: 1; /* 0 = no, 1 = yes */ + DWORD SystemType : 3; /* 0 = bindery 1 = NDS */ + DWORD Destination: 3; /* 0 = queue 1 = printer */ + DWORD unknown : 20; + }; + DWORD PrintJobFlags; + }; + + WORD NumberOfCopies; /* 1 - 65,000 */ + WORD TimeoutCount; /* 1 - 1,000 */ + BYTE TabSize; /* 1 - 18 */ + BYTE LocalPrinter; /* 0=Lpt1, 1=Lpt2, 2=Lpt3 etc. */ + char FormName[ NWPS_FORM_NAME_SIZE + 2 ]; /* 1-12 chars */ + char Name[ NWPS_BANNER_NAME_SIZE + 2 ]; /* 1-12 chars */ + char BannerName[ NWPS_BANNER_FILE_SIZE + 2 ]; /* 1-12 chars */ + char Device[ NWPS_DEVI_NAME_SIZE + 2 ]; /* 1-32 chars */ + char Mode[ NWPS_MODE_NAME_SIZE + 2 ]; /* 1-32 chars */ + union { + struct { + /* pad structures on even boundries */ + char Server[ NWPS_BIND_NAME_SIZE + 2 ]; /* 2-48 chars */ + char QueueName[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */ + char PrintServer[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */ + } NonDS; + char DSObjectName[ NWPS_MAX_NAME_SIZE ]; + } u; + BYTE reserved[390]; /* Adds up to 1024 total (was 1026) */ +} JOB_RECORD_AREA; + +#define JOB_RECORD_AREA_SIZE sizeof(JOB_RECORD_AREA) + + +#include + + + +/*++ +******************************************************************* + + PS40JobGetDefault + +Routine Description: + + Get the default print job configuration from 40. + +Arguments: + NDSCaptureFlag + SearchFlag = + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PS40JobGetDefault( + unsigned int NDSCaptureFlag, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ) +{ + return PS40GetJobName( + NDSCaptureFlag, + SearchFlag, + pOwner, + pJobName, + pJobRecord, + TRUE); +} + + +/*++ +******************************************************************* + + PS40JobRead + +Routine Description: + + Get the print job configuration from 40. + +Arguments: + + NDSCaptureFlag = + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PS40JobRead( + unsigned int NDSCaptureFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ) +{ + return PS40GetJobName( + NDSCaptureFlag, + 0, + pOwner, + pJobName, + pJobRecord, + FALSE); +} + + +/*++ +******************************************************************* + + PS40GetJobName + +Routine Description: + + Common routine to get the print job configuration from 40. + +Arguments: + NDSCaptureFlag = + SearchFlag = + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + GetDefault = TRUE = get the default job name, FALSE = Don't get + the default job name. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PS40GetJobName( + unsigned int NDSCaptureFlag, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord, + unsigned char GetDefault + ) +{ + unsigned char *pSearchJobName; + unsigned long ObjectId; + HANDLE stream = NULL; + unsigned int Count; + unsigned int Bytes; + unsigned int RetCode = 0; + unsigned int ConnectionNumber; + JOB_NAME_AREA JobNameArea; + JOB_RECORD_AREA JobRecord; + PRINTCON_40_HEADER PrintConHeader; + unsigned int Version40 = FALSE; + unsigned int ConnectionHandle; + unsigned char MailDirPath[NCP_MAX_PATH_LENGTH]; + unsigned char TempJobName[32]; + PBYTE JobContext = NULL; + unsigned FileSize; + + // BUGBUG Printer names can be used instead of queues + // Must lookup "default print queue" if NT doesn't + + if ( NDSCaptureFlag ) { + + if ( !GetDefault ) { + JobContext = strchr( pJobName, ':' ); + if ( JobContext ) { + *JobContext = '\0'; + strncpy( TempJobName, pJobName, 32 ); + *JobContext++ = ':'; + pJobName = TempJobName; + } + } + + if ( JobContext ) { + if (NDSfopenStream ( JobContext, "Print Job Configuration", &stream, + &FileSize )) { + RetCode = PS_ERR_OPENING_DB; + goto CommonExit; + } + } + else { + if (NDSfopenStream ( TYPED_USER_NAME, "Print Job Configuration", + &stream, &FileSize)) { + PBYTE p; + + for ( p = TYPED_USER_NAME; p ; p = strchr ( p, '.' ) ) + { + p++; + + if ( *p == 'O' && *(p+1) == 'U' && *(p+2) == '=' ) + break; + + if ( *p == 'O' && *(p+1) == '=' ) + break; + } + if (NDSfopenStream ( p, "Print Job Configuration", &stream, + &FileSize)) { + RetCode = PS_ERR_OPENING_DB; + goto CommonExit; + } + } + } + } + else { + + if (!CGetDefaultConnectionID (&ConnectionHandle)) { + RetCode = PS_ERR_OPENING_DB; + goto CommonExit; + } + + RetCode = GetConnectionNumber(ConnectionHandle, &ConnectionNumber); + if (RetCode) { + goto CommonExit; + } + + RetCode = GetBinderyObjectID (ConnectionHandle, LOGIN_NAME, + OT_USER, &ObjectId); + if (RetCode) { + goto CommonExit; + } + + /** Build the path to open the file **/ + + sprintf(MailDirPath, "SYS:MAIL/%lX/PRINTJOB.DAT", SwapLong(ObjectId)); + stream = CreateFileA( NTNWtoUNCFormat( MailDirPath ), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + if (stream == INVALID_HANDLE_VALUE) { + + sprintf(MailDirPath, "SYS:PUBLIC/PRINTJOB.DAT"); + + stream = CreateFileA( NTNWtoUNCFormat(MailDirPath), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if (stream == INVALID_HANDLE_VALUE) { + RetCode = PS_ERR_OPENING_DB; + goto CommonExit; + } + } + } + + if ( !ReadFile( stream, (PBYTE) &PrintConHeader, PRINTCON_40_HEADER_SIZE, &Bytes, NULL ) ) { + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + + if (Bytes < PRINTCON_40_HEADER_SIZE) { + if ( !( NDSCaptureFlag && Bytes) ) { // BUGBUG + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + } + + /** Check the version number **/ + + if ( PrintConHeader.MajorVersion != 4 ) { + RetCode = PS_ERR_BAD_VERSION; + goto CommonExit; + } + + if ( PrintConHeader.MinorVersion == 0 ) { + Version40 = TRUE; + } + + /** Get the name we are looking for **/ + + if (GetDefault) { + if (PrintConHeader.DefaultJobName[0] == 0) { + RetCode = PS_ERR_GETTING_DEFAULT; + goto CommonExit; + } + pSearchJobName = PrintConHeader.DefaultJobName; + } + else { + pSearchJobName = pJobName; + } + + if ( !Version40 ) { + SetFilePointer( stream, PRINTCON_41_HEADER_SIZE, NULL, FILE_BEGIN ); + } + + Count = 0; + + /** Go through all of the job entry to look for the name **/ + + while (Count < PrintConHeader.NumberOfRecords) { + if ( !ReadFile( stream, (PBYTE) &JobNameArea, JOB_NAME_AREA_SIZE, &Bytes, NULL) ) { + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + + if (Bytes < JOB_NAME_AREA_SIZE) { + if ( !( NDSCaptureFlag && Bytes) ) { // BUGBUG + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + } + Count++; + + + /** Skip the entry with a null job name **/ + + if (JobNameArea.JobName[0] == 0) { + continue; + } + + /** Is this the job name we are looking for? **/ + + if (!_strcmpi(pSearchJobName, JobNameArea.JobName)) { + break; + } + } + + /** See if we found the job name **/ + + if (Count > PrintConHeader.NumberOfRecords) { + if (GetDefault) { + RetCode = PS_ERR_GETTING_DEFAULT; + } + else { + RetCode = PS_ERR_READING_RECORD; + } + goto CommonExit; + } + + /* + * The Job offset starts at the beginning of the third section. + * The third section starts after the Header and after the + * 50 record blocks. + */ + if ( Version40 ) { + SetFilePointer( stream, + PRINTCON_40_HEADER_SIZE + + ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE + + JobNameArea.JobRecordOffset, + NULL, + FILE_BEGIN ); + } + else { + SetFilePointer( stream, + PRINTCON_41_HEADER_SIZE + + ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE + + JobNameArea.JobRecordOffset, + NULL, + FILE_BEGIN ); + } + + memset((PBYTE)&JobRecord, 0, sizeof(JobRecord)); + + if ( !ReadFile( stream, (PBYTE) &JobRecord, JOB_RECORD_AREA_SIZE, &Bytes, NULL) ) { + RetCode = PS_ERR_READING_RECORD; + goto CommonExit; + } + + if (Bytes < JOB_RECORD_AREA_SIZE) { + if ( !( NDSCaptureFlag && Bytes) ) { // BUGBUG + RetCode = PS_ERR_READING_RECORD; + goto CommonExit; + } + } + + memset(pJobRecord, 0, PS_JOB_RECORD_SIZE); + + if (JobRecord.NotifyWhenDone) { + pJobRecord->PrintJobFlag |= PS_JOB_NOTIFY; + } + if (JobRecord.BannerFlag) { + pJobRecord->PrintJobFlag |= PS_JOB_PRINT_BANNER; + } + if (JobRecord.DataType) { + pJobRecord->PrintJobFlag |= PS_JOB_EXPAND_TABS; + } + if (JobRecord.FormFeed) { + pJobRecord->PrintJobFlag |= PS_JOB_NO_FORMFEED; + } + if (JobRecord.AutoEndCap) { + pJobRecord->PrintJobFlag |= PS_JOB_AUTO_END; + } + if (JobRecord.TimeoutCount) { + pJobRecord->PrintJobFlag |= PS_JOB_TIMEOUT; + } + if (JobRecord.Destination) { + pJobRecord->PrintJobFlag |= PS_JOB_DS_PRINTER; + } + if ( JobRecord.SystemType ) { + pJobRecord->PrintJobFlag |= PS_JOB_ENV_DS; + } + + pJobRecord->Copies = JobRecord.NumberOfCopies; + pJobRecord->TabSize = JobRecord.TabSize; + pJobRecord->TimeOutCount = JobRecord.TimeoutCount; + pJobRecord->LocalPrinter = JobRecord.LocalPrinter; + + strcpy(pJobRecord->Mode, JobRecord.Mode); + strcpy(pJobRecord->Device, JobRecord.Device); + strcpy(pJobRecord->FormName, JobRecord.FormName); + strcpy(pJobRecord->BannerName, JobRecord.BannerName); + + if ( JobRecord.SystemType ) { + ConvertUnicodeToAscii( JobRecord.u.DSObjectName ); + strcpy(pJobRecord->u.DSObjectName, JobRecord.u.DSObjectName); + } + else { + strcpy(pJobRecord->u.NonDS.PrintQueue, JobRecord.u.NonDS.QueueName); + strcpy(pJobRecord->u.NonDS.FileServer, JobRecord.u.NonDS.Server); + } + + if (GetDefault && pJobName) { + strcpy(pJobName, JobNameArea.JobName); + } + + if (pOwner) { + *pOwner = 0; + } + +CommonExit: + if (stream != NULL) { + if ( NDSCaptureFlag ) + CloseHandle( stream ); + else + fclose( stream ); + } + + return RetCode; +} diff --git a/private/nw/nwscript/psdb.c b/private/nw/nwscript/psdb.c new file mode 100644 index 000000000..713c1c4c4 --- /dev/null +++ b/private/nw/nwscript/psdb.c @@ -0,0 +1,396 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + nwlibs\psdb.c + +Abstract: + + Read the Print Con database file APIs. + +Author: + + Shawn Walker (v-swalk) 12-12-1994 + +Revision History: + +--*/ +#include "common.h" + +extern DWORD SwapLong(DWORD number); + +unsigned int +PSGetJobName( + unsigned int ConnectionHandle, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord, + unsigned char GetDefault + ); + +#define MAX_JOB_NAME_ENTRY 37 + +#define O_RDONLY 0x0000 /* open for reading only */ +#define O_WRONLY 0x0001 /* open for writing only */ +#define O_RDWR 0x0002 /* open for reading and writing */ +#define O_APPEND 0x0008 /* writes done at eof */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open and truncate */ +#define O_EXCL 0x0400 /* open only if file doesn't already exist */ +#define O_TEXT 0x4000 /* file mode is text (translated) */ +#define O_BINARY 0x8000 /* file mode is binary (untranslated) */ + +#define S_IEXEC 0000100 /* execute/search permission, owner */ +#define S_IWRITE 0000200 /* write permission, owner */ +#define S_IREAD 0000400 /* read permission, owner */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFREG 0100000 /* regular */ +#define S_IFMT 0170000 /* file type mask */ + +#include +typedef struct _PRINTCON_HEADER { + unsigned char Text[115]; + unsigned char MajorVersion; + unsigned char MinorVersion1; + unsigned char MinorVersion2; + unsigned char DefaultJobName[32]; +} PRINTCON_HEADER, *PPRINTCON_HEADER; + +#define PRINTCON_HEADER_SIZE sizeof(PRINTCON_HEADER) + +typedef struct _JOB_NAME_AREA { + unsigned char JobName[32]; + unsigned long JobRecordOffset; +} JOB_NAME_AREA, *PJOB_NAME_AREA; + +#define JOB_NAME_AREA_SIZE sizeof(JOB_NAME_AREA) + +typedef struct _JOB_RECORD_AREA { + unsigned char ServerName[NCP_BINDERY_OBJECT_NAME_LENGTH]; + unsigned char QueueName[NCP_BINDERY_OBJECT_NAME_LENGTH]; + unsigned char TabSize; + unsigned short NumberOfCopies; + unsigned char FormName[40]; + unsigned char NotifyWhenDone; //0=No, 1=Yes + unsigned long PrintServerID; + unsigned char Name[13]; + unsigned char BannerName[13]; + unsigned char Device[33]; + unsigned char Mode[33]; + unsigned char BannerFlag; //0=No Banner, 1=Banner + unsigned char DataType; //1=Byte,0=Stream + unsigned char FormFeed; //0=Don't Suppress FF, 1=Suppress FF + unsigned short TimeoutCount; + unsigned char LocalPrinter; //1=LPT1, 2=LPT2, 3=LPT3 + unsigned char AutoEndCap; //0=Don't Auto EndCap, 1=Do Auto EndCap +} JOB_RECORD_AREA, *PJOB_RECORD_AREA; +#include + +#define JOB_RECORD_AREA_SIZE sizeof(JOB_RECORD_AREA) + + +/*++ +******************************************************************* + + PSJobGetDefault + +Routine Description: + + Get the default print job configuration from the printcon.dat + file. + +Arguments: + + ConnectionHandle = The connection handle to use. + SearchFlag = + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PSJobGetDefault( + unsigned int ConnectionHandle, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ) +{ + return PSGetJobName( + ConnectionHandle, + SearchFlag, + pOwner, + pJobName, + pJobRecord, + TRUE); +} + + +/*++ +******************************************************************* + + PSJobRead + +Routine Description: + + Get the print job configuration from the printcon.dat file. + +Arguments: + + ConnectionHandle = The connection handle to use. + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PSJobRead( + unsigned int ConnectionHandle, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord + ) +{ + return PSGetJobName( + ConnectionHandle, + 0, + pOwner, + pJobName, + pJobRecord, + FALSE); +} + + +/*++ +******************************************************************* + + PSGetJobName + +Routine Description: + + Common routine to get the print job configuration from the + printcon.dat file. + +Arguments: + + ConnectionHandle = The connection handle to use. + SearchFlag = + pOwner = + pJobName = A pointer to return the default job configuration name. + pJobRecord = A pointer to return the default job configuration. + GetDefault = TRUE = get the default job name, FALSE = Don't get + the default job name. + +Return Value: + + SUCCESSFUL 0x0000 + PS_ERR_BAD_VERSION 0x7770 + PS_ERR_GETTING_DEFAULT 0x7773 + PS_ERR_OPENING_DB 0x7774 + PS_ERR_READING_DB 0x7775 + PS_ERR_READING_RECORD 0x7776 + PS_ERR_INTERNAL_ERROR 0x7779 + PS_ERR_NO_DEFAULT_SPECIFIED 0x777B + INVALID_CONNECTION 0x8801 + +******************************************************************* +--*/ +unsigned int +PSGetJobName( + unsigned int ConnectionHandle, + unsigned short SearchFlag, + unsigned char *pOwner, + unsigned char *pJobName, + PPS_JOB_RECORD pJobRecord, + unsigned char GetDefault + ) +{ + unsigned char *pSearchJobName; + unsigned long ObjectId; + FILE *stream = NULL; + unsigned int Count; + unsigned int Bytes; + unsigned int RetCode; + unsigned int ConnectionNumber; + JOB_NAME_AREA JobNameArea; + JOB_RECORD_AREA JobRecord; + PRINTCON_HEADER PrintConHeader; + unsigned char MailDirPath[NCP_MAX_PATH_LENGTH]; + + /** Get the connection number for this connection **/ + + RetCode = GetConnectionNumber(ConnectionHandle, &ConnectionNumber); + if (RetCode) { + goto CommonExit; + } + + RetCode = GetBinderyObjectID (ConnectionHandle, LOGIN_NAME, + OT_USER, &ObjectId); + if (RetCode) { + goto CommonExit; + } + + /** Build the path to open the file **/ + + sprintf(MailDirPath, "SYS:MAIL/%lX/PRINTCON.DAT", SwapLong(ObjectId)); + + stream = fopen(NTNWtoUNCFormat( MailDirPath), "rb"); + if (stream == NULL) { + RetCode = PS_ERR_OPENING_DB; + goto CommonExit; + } + + Bytes = fread( (unsigned char *) &PrintConHeader, sizeof( char), PRINTCON_HEADER_SIZE, stream); + if (Bytes < PRINTCON_HEADER_SIZE) { + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + + /** Check the version number **/ + + if ((PrintConHeader.MajorVersion != 3 && + PrintConHeader.MajorVersion != 1) || + PrintConHeader.MinorVersion1 != 1 || + PrintConHeader.MinorVersion2 != 1) { + + RetCode = PS_ERR_BAD_VERSION; + goto CommonExit; + } + /** Get the name we are looking for **/ + + if (GetDefault) { + if (PrintConHeader.DefaultJobName[0] == 0) { + RetCode = PS_ERR_NO_DEFAULT_SPECIFIED; + goto CommonExit; + } + pSearchJobName = PrintConHeader.DefaultJobName; + } + else { + pSearchJobName = pJobName; + } + + Count = 0; + + /** Go through all of the job entry to look for the name **/ + + while (Count < MAX_JOB_NAME_ENTRY) { + Bytes = fread( (unsigned char *) &JobNameArea, sizeof(unsigned char), JOB_NAME_AREA_SIZE, stream); + if (Bytes < JOB_NAME_AREA_SIZE) { + RetCode = PS_ERR_INTERNAL_ERROR; + goto CommonExit; + } + Count++; + + /** Skip the entry with a null job name **/ + + if (JobNameArea.JobName[0] == 0) { + continue; + } + + /** Is this the job name we are looking for? **/ + + if (!_strcmpi(pSearchJobName, JobNameArea.JobName)) { + break; + } + } + + /** See if we found the job name **/ + + if (Count > MAX_JOB_NAME_ENTRY) { + if (GetDefault) { + RetCode = PS_ERR_GETTING_DEFAULT; + } + else { + RetCode = PS_ERR_READING_RECORD; + } + goto CommonExit; + } + + fseek(stream, JobNameArea.JobRecordOffset, SEEK_SET); + + Bytes = fread( (unsigned char *) &JobRecord, sizeof(unsigned char), JOB_RECORD_AREA_SIZE, stream); + if (Bytes < JOB_RECORD_AREA_SIZE) { + RetCode = PS_ERR_READING_RECORD; + goto CommonExit; + } + + memset(pJobRecord, 0, PS_JOB_RECORD_SIZE); + + if (JobRecord.NotifyWhenDone) { + pJobRecord->PrintJobFlag |= PS_JOB_NOTIFY; + } + if (JobRecord.BannerFlag) { + pJobRecord->PrintJobFlag |= PS_JOB_PRINT_BANNER; + } + if (JobRecord.DataType) { + pJobRecord->PrintJobFlag |= PS_JOB_EXPAND_TABS; + } + if (JobRecord.FormFeed) { + pJobRecord->PrintJobFlag |= PS_JOB_NO_FORMFEED; + } + if (JobRecord.AutoEndCap) { + pJobRecord->PrintJobFlag |= PS_JOB_AUTO_END; + } + if (JobRecord.TimeoutCount) { + pJobRecord->PrintJobFlag |= PS_JOB_TIMEOUT; + } + + pJobRecord->Copies = JobRecord.NumberOfCopies; + pJobRecord->TabSize = JobRecord.TabSize; + pJobRecord->TimeOutCount = JobRecord.TimeoutCount; + pJobRecord->LocalPrinter = JobRecord.LocalPrinter; + + strcpy(pJobRecord->Mode, JobRecord.Mode); + strcpy(pJobRecord->Device, JobRecord.Device); + strcpy(pJobRecord->FormName, JobRecord.FormName); + strcpy(pJobRecord->BannerName, JobRecord.BannerName); + strcpy(pJobRecord->u.NonDS.PrintQueue, JobRecord.QueueName); + strcpy(pJobRecord->u.NonDS.FileServer, JobRecord.ServerName); + + if (GetDefault && pJobName) { + strcpy(pJobName, JobNameArea.JobName); + } + + if (pOwner) { + *pOwner = 0; + } + +CommonExit: + + if (stream != NULL) { + fclose( stream ); + } + + return RetCode; +} diff --git a/private/nw/nwscript/script.c b/private/nw/nwscript/script.c new file mode 100644 index 000000000..14df55b93 --- /dev/null +++ b/private/nw/nwscript/script.c @@ -0,0 +1,3968 @@ + +/************************************************************************* +* +* SCRIPT.C +* +* Script routines, ported from DOS +* +* Copyright (c) 1995 Microsoft Corporation +* +*************************************************************************/ + +#include "common.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern VOID nwShowLastLoginTime( VOID ); + +#define MAXLEN 256 +#define MAX_NUM_IF 10 + +#define NUMCOMMAND 44 + +#define CM_IF 20 +#define CM_ELSE 21 +#define CM_END 22 + +// +// 3X and 4X variables +// + +#define IDS_DAY_OF_WEEK 0 +#define IDS_DAY 1 +#define IDS_MONTH_NAME 2 +#define IDS_MONTH 3 +#define IDS_NDAY_OF_WEEK 4 +#define IDS_SHORT_YEAR 5 +#define IDS_YEAR 6 +#define IDS_AM_PM 7 +#define IDS_GREETING_TIME 8 +#define IDS_HOUR24 9 +#define IDS_HOUR 10 +#define IDS_MINUTE 11 +#define IDS_SECOND 12 +#define IDS_FULL_NAME 13 +#define IDS_LOGIN_NAME 14 +#define IDS_USER_ID 15 +#define IDS_PASSWORD_EXPIRES 16 +#define IDS_NETWORK_ADDRESS 17 +#define IDS_FILE_SERVER 18 +#define IDS_ACCESS_SERVER 19 +#define IDS_ERROR_LEVEL 20 +#define IDS_ERRORLEVEL 21 +#define IDS_MACHINE 22 +#define IDS_OS_VERSION 23 +#define IDS_OS 24 +#define IDS_SMACHINE 25 +#define IDS_SHELL_TYPE 26 +#define IDS_STATION 27 +#define IDS_P_STATION 28 +#define IDS_SHELL_VERSION 29 +#define NUMVAR_3X IDS_SHELL_VERSION + 1 + +#define IDS_LAST_NAME 30 +#define IDS_LOGIN_CONTEXT 31 +#define IDS_NETWARE_REQUESTER 32 +#define IDS_REQUESTER_CONTEXT 33 +#define IDS_ACCOUNT_BALANCE 34 +#define IDS_CN 35 +#define IDS_REQUESTER_VERSION 36 +#define IDS_SURNAME 37 +#define IDS_DOS_REQUESTER 38 +#define IDS_REQUESTER 39 +#define IDS_ADMINISTRATIVE_ASSISTANT 40 +#define IDS_ALLOW_UNLIMITED_CREDIT 41 +#define IDS_DESCRIPTION 42 +#define IDS_EMAIL_ADDRESS 43 +#define IDS_EMPLOYEE_ID 44 +#define IDS_FACSIMILE_TELEPHONE_NUMBER 45 +#define IDS_GROUP_MEMBERSHIP 46 +#define IDS_HIGHER_PRIVILEGES 47 +#define IDS_HOME_DIRECTORY 48 +#define IDS_INITIALS 49 +#define IDS_LANGUAGE 50 +#define IDS_LOCKED_BY_INTRUDER 51 +#define IDS_LOGIN_DISABLED 52 +#define IDS_LOGIN_GRACE_LIMIT 53 +#define IDS_LOGIN_GRACE_REMAINING 54 +#define IDS_LOGIN_INTRUDER_ATTEMPTS 55 +#define IDS_LOGIN_MAXIMUM_SIMULTANEOUS 56 +#define IDS_MAILSTOP 57 +#define IDS_MESSAGE_SERVER 58 +#define IDS_MINIMUM_ACCOUNT_BALANCE 59 +#define IDS_NETWORK 60 +#define IDS_OBJECT_CLASS 61 +#define IDS_OU 62 +#define IDS_PASSWORD_ALLOW_CHANGE 63 +#define IDS_PASSWORD_MINIMUM_LENGTH 64 +#define IDS_PASSWORD_REQUIRED 65 +#define IDS_PASSWORD_UNIQUE_REQUIRED 66 +#define IDS_PASSWORDS_USED 67 +#define IDS_PHYSICAL_DELIVERY_OFFICE_NAME 68 +#define IDS_POSTAL_ADDRESS 69 +#define IDS_POSTAL_CODE 70 +#define IDS_POSTAL_OFFICE_BOX 71 +#define IDS_PRIVATE_KEY 72 +#define IDS_PROFILE 73 +#define IDS_REVISION 74 +#define IDS_SECURITY_EQUALS 75 +#define IDS_SECURITY_FLAGS 76 +#define IDS_SEE_ALSO 77 +#define IDS_SERVER_HOLDS 78 +#define IDS_SUPERVISOR 79 +#define IDS_TELEPHONE_NUMBER 80 +#define IDS_TITLE 81 +#define IDS_CERTIFICATE_VALIDITY_INTERVAL 82 +#define IDS_EQUIVALENT_TO_ME 83 +#define IDS_GENERATIONAL_QUALIFIER 84 +#define IDS_GIVEN_NAME 85 +#define IDS_MAILBOX_ID 86 +#define IDS_MAILBOX_LOCATION 87 +#define IDS_PROFILE_MEMBERSHIP 88 +#define IDS_SA 89 +#define IDS_S 90 +#define IDS_L 91 +#define IDS_ACCESS 92 +#define NUMVAR IDS_ACCESS + 1 + +/* + * String constants. + */ + +/* + * Text for default Login Script. Don't change. + */ +BYTE DefaultLoginScript[] = + "WRITE \"Good %GREETING_TIME, %LOGIN_NAME.\\n\"\n" + "MAP DISPLAY OFF\n" + "MAP ERRORS OFF\n" + "Rem: Set 1st drive to most appropriate directory.\n" + "MAP *1:=%FILE_SERVER/SYS:;*1:=%FILE_SERVER/SYS:%LOGIN_NAME\n" + "If LOGIN_NAME=\"SUPERVISOR\" || LOGIN_NAME=\"ADMIN\" || LOGIN_NAME=\"SUPERVIS\" THEN MAP *1:=%FILE_SERVER/SYS:SYSTEM\n" + "Rem: Set search drives (S2 machine-OS dependent).\n" + "MAP INS S1:=%FILE_SERVER/SYS:PUBLIC\n" + "MAP INS S2:=%FILE_SERVER/SYS:\n" + "Rem: Now display all the current drive settings.\n" + "MAP DISPLAY ON\n" + "MAP\n" + "\0"; + +char *__SPACES__=" \t"; + +/* + * Do not change the order of this array. + */ +char * COMPARE_OPERATORS[] = +{ + "!=", + "<>", + "NOT EQUAL TO", + "DOES NOT EQUAL", + "NOT EQUAL", + "IS NOT EQUAL", + "#", + "IS NOT", // 7 + ">=", // 8 + "IS GREATER THAN OR EQUAL TO", + "IS GREATER THAN OR EQUAL", + "GREATER THAN OR EQUAL TO", + "GREATER THAN OR EQUAL", + ">", // 13 + "IS GREATER THAN", + "GREATER THAN", + "<=", // 16 + "IS LESS THAN OR EQUAL TO", + "IS LESS THAN OR EQUAL", + "LESS THAN OR EQUAL TO", + "LESS THAN OR EQUAL", + "<", // 21 + "IS LESS THAN", + "LESS THAN", + "==", // 24 + "=", + "EQUALS", + "EQUAL", + "IS", + "\0" +}; + +int IsNotEqual (int nIndex) +{ + return(nIndex < 8); +} + +int IsGreaterOrEqual (int nIndex) +{ + return(nIndex >= 8 && nIndex < 13); +} + +int IsGreater (int nIndex) +{ + return(nIndex >= 13 && nIndex < 16); +} + +int IsLessOrEqual (int nIndex) +{ + return(nIndex >= 16 && nIndex < 21); +} + +int IsLess (int nIndex) +{ + return(nIndex >= 21 && nIndex < 24); +} + +/* + * Type defs. + */ +typedef int (*PFCommandHandler) (char *lpParam); + +typedef struct tagCOMMANDTABLE +{ + char *commandStr0; + char *commandStr1; + char *commandStr2; + PFCommandHandler commandhandler; +}COMMANDTABLE; + +typedef struct tagLABEL_LIST +{ + char *pLabel; + char *pNextLine; + struct tagLABEL_LIST *pNext; +}LABEL_LIST, *PLABEL_LIST; + +/* + * Functions that are in command dispatch table. + */ +int AttachHandler (char *lpParam); +int BreakHandler (char *lpParam); +int ComspecHandler (char *lpParam); +int DisplayHandler (char *lpParam); +int DosBreakHandler (char *lpParam); +int SetHandler (char *lpParam); +int LocalSetHandler (char *lpParam); +int DosVerifyHandler (char *lpParam); +int DriveHandler (char *lpParam); +int FireHandler (char *lpParam); +int ExitHandler (char *lpParam); +int IfHandler (char *lpParam); +int ElseHandler (char *lpParam); +int EndHandler (char *lpParam); +int IncludeHandler (char *lpParam); +int MapHandler (char *lpParam); +int PauseHandler (char *lpParam); +int WriteHandler (char *lpParam); +int NullHandler (char *lpParam); +int GotoHandler (char *lpParam); +int ShiftHandler (char *lpParam); +int MachineHandler (char *lpParam); +int CompatibleHandler(char *lpParam); +int ClearHandler (char *lpParam); +int LastLoginTimeHandler(char *lpParam); +int ContextHandler (char *lpParam); +int ScriptServerHandler(char *lpParam); +int NoDefaultHandler (char *lpParam); + +/* + * Command dispatch table. Do not change. + * + * If you do, you must change CM_IF, CM_ELSE, and CM_END + */ +COMMANDTABLE nwCommand[NUMCOMMAND] = +{ + "LOCAL", "DOS", "SET", LocalSetHandler, + "TEMP", "DOS", "SET", LocalSetHandler, + "TEMPORARY", "DOS", "SET", LocalSetHandler, + "LOCAL", "SET", NULL, LocalSetHandler, + "TEMP", "SET", NULL, LocalSetHandler, + "TEMPORARY", "SET", NULL, LocalSetHandler, + "DOS", "SET", NULL, SetHandler, + "DOS", "VERIFY", NULL, DosVerifyHandler, + "DOS", "BREAK", NULL, DosBreakHandler, + "FIRE", "PHASERS", NULL, FireHandler, + "ATTACH", NULL, NULL, AttachHandler, + "BREAK", NULL, NULL, BreakHandler, + "COMSPEC", NULL, NULL, NullHandler, + "DISPLAY", NULL, NULL, DisplayHandler, + "SET_TIME", NULL, NULL, NullHandler, + "SET", NULL, NULL, SetHandler, + "DRIVE", NULL, NULL, DriveHandler, + "FDISPLAY", NULL, NULL, DisplayHandler, + "FIRE", NULL, NULL, FireHandler, + "EXIT", NULL, NULL, ExitHandler, + "IF", NULL, NULL, IfHandler, // CM_IF + "ELSE", NULL, NULL, ElseHandler, // CM_ELSE + "END", NULL, NULL, EndHandler, // CM_END + "INCLUDE", NULL, NULL, IncludeHandler, + "MACHINE", NULL, NULL, MachineHandler, + "MAP", NULL, NULL, MapHandler, + "PAUSE", NULL, NULL, PauseHandler, + "COMPATIBLE", NULL, NULL, CompatibleHandler, + "PCCOMPATIBLE", NULL, NULL, CompatibleHandler, + "REMARK", NULL, NULL, NullHandler, + "REM", NULL, NULL, NullHandler, + "SHIFT", NULL, NULL, ShiftHandler, + "WAIT", NULL, NULL, PauseHandler, + "WRITE", NULL, NULL, WriteHandler, + "GOTO", NULL, NULL, GotoHandler, + "CLS", NULL, NULL, ClearHandler, + "CLEAR", NULL, NULL, ClearHandler, + "SWAP", NULL, NULL, NullHandler, + "LASTLOGIN", NULL, NULL, LastLoginTimeHandler, // 38 + "CONTEXT", NULL, NULL, ContextHandler, // 39 + "SCRIPT_SERVER", NULL, NULL, ScriptServerHandler, // 40 + "NO_DEFAULT", NULL, NULL, NoDefaultHandler, // 41 + "CX", NULL, NULL, ContextHandler, // 42 + "PATH", NULL, NULL, MapHandler, // 43 +}; + +typedef struct tagVARTABLE +{ + char *VarName; +}VARTABLE; + +VARTABLE varTable[NUMVAR] = +{ + "DAY_OF_WEEK", + "DAY", + "MONTH_NAME", + "MONTH", + "NDAY_OF_WEEK", + "SHORT_YEAR", + "YEAR", + "AM_PM", + "GREETING_TIME", + "HOUR24", + "HOUR", + "MINUTE", + "SECOND", + "FULL_NAME", + "LOGIN_NAME", + "USER_ID", + "PASSWORD_EXPIRES", + "NETWORK_ADDRESS", + "FILE_SERVER", + "ACCESS_SERVER", + "ERROR_LEVEL", + "ERRORLEVEL", + "MACHINE", + "OS_VERSION", + "OS", + "SMACHINE", + "SHELL_TYPE", + "STATION", + "P_STATION", + "SHELL_VERSION", + "LAST_NAME", + "LOGIN_CONTEXT", + "NETWARE_REQUESTER", + "REQUESTER_CONTEXT", + "ACCOUNT_BALANCE", + "CN", + "REQUESTER_VERSION", + "SURNAME", + "DOS_REQUESTER", + "REQUESTER", + "ADMINISTRATIVE_ASSISTANT", + "ALLOW_UNLIMITED_CREDIT", + "DESCRIPTION", + "EMAIL_ADDRESS", + "EMPLOYEE_ID", + "FACSIMILE_TELEPHONE_NUMBER", + "GROUP_MEMBERSHIP", + "HIGHER_PRIVILEGES", + "HOME_DIRECTORY", + "INITIALS", + "LANGUAGE", + "LOCKED_BY_INTRUDER", + "LOGIN_DISABLED", + "LOGIN_GRACE_LIMIT", + "LOGIN_GRACE_REMAINING", + "LOGIN_INTRUDER_ATTEMPTS", + "LOGIN_MAXIMUM_SIMULTANEOUS", + "MAILSTOP", + "MESSAGE_SERVER", + "MINIMUM_ACCOUNT_BALANCE", + "NETWORK", + "OBJECT_CLASS", + "OU", + "PASSWORD_ALLOW_CHANGE", + "PASSWORD_MINIMUM_LENGTH", + "PASSWORD_REQUIRED", + "PASSWORD_UNIQUE_REQUIRED", + "PASSWORDS_USED", + "PHYSICAL_DELIVERY_OFFICE_NAME", + "POSTAL_ADDRESS", + "POSTAL_CODE", + "POSTAL_OFFICE_BOX", + "PRIVATE_KEY", + "PROFILE", + "REVISION", + "SECURITY_EQUALS", + "SECURITY_FLAGS", + "SEE_ALSO", + "SERVER_HOLDS", + "SUPERVISOR", + "TELEPHONE_NUMBER", + "TITLE", + "CERTIFICATE_VALIDITY_INTERVAL", + "EQUIVALENT_TO_ME", + "GENERATIONAL_QUALIFIER", + "GIVEN_NAME", + "MAILBOX_ID", + "MAILBOX_LOCATION", + "PROFILE_MEMBERSHIP", + "SA", + "S", + "L", + "ACCESS", +}; + +/* + * Local functions. + */ +void SmartCap(char *ptr); +int NWGetFileSize (char * lpFileName); +void LoadFile (char *lpFileName, char *lpFileBuffer, int nFileSize); +int ProcessLoginScriptFile (char *lpLoginScriptFile); +void ProcessLoginScript (char *lpLoginScript); +int ProcessLoginScriptProperty (unsigned char *); + +int CreateLabelList (PLABEL_LIST *ppLabelList, char *lpLoginScript); +void FreeLabelList (LABEL_LIST *pLabelList); + +void ExternalCmdHandler(char *lpCommand); +void BadCommandHandler (char *lpCommand); + +void CommandDispatch (char *lpCommand); +int GetTableIndex(char *lpCommand, char ** prestbuffer); + +DWORD SwapLong(DWORD number); +int EndOfLine (char *buffer); +char *RemoveSpaces (char * buffer); +int IsOn (char *lpParam); +int IsOff (char *lpParam); +int VarTranslate(char *vartext); +int QuotedStringTranslate (char *buffer); +void NotQuotedStringTranslate(char *buffer, BOOL remove_dbs); +void SetLocalEnv(char *buffer); +int SetEnv (char *lpEnvLine); +char *ConvertPercent (char *buffer); +void GetShellVersion(char *buffer, int index); + +/* + * Global Defines + */ +#define IsWhiteSpace(x) ((x==' ')||(x=='\t')||(x=='\n')||(x=='\r')||(x==0)) + +/* + * Global variables. + */ + +// +// The following globals are used for goto processing... this allows us +// to manipulate the line we're processing outside ProcessLoginScript. +// + +LABEL_LIST *pGlobalLabelList; +char *lpGlobalLine; +char *lpGlobalLineSeparator; +int fGlobalHaveNulledLineSeparator; +int fGlobalExitFlag; +int fGlobalIfTooDeep; + +int fBreakOn = TRUE; + +int nCondIndex; +int aCondVal[MAX_NUM_IF]; + +int ARGC; +char **ARGV; +int nGlobalShiftDelta = 0; +int fGlobalCompatible = FALSE; +int fNoDefaultLoginScript = FALSE; + +char *LOGIN_NAME; +char *LAST_NAME; +char *LOGIN_CONTEXT; +char *REQUESTER_CONTEXT; +char *COMMON_NAME; +char *TYPED_USER_NAME; +PWCHAR TYPED_USER_NAME_w; +PBYTE NDSTREE; +PBYTE PREFERRED_SERVER; + +HANDLE hconout = INVALID_HANDLE_VALUE; + +unsigned int CONNECTION_ID; +unsigned int CONNECTION_NUMBER; +unsigned int SCRIPT_ERROR = 0; + +#define REQUESTER_VERSION "V1.20" + +extern DWORD GUserObjectID; + +int IsEmptyFile (char *lpFile) +{ + while (*lpFile != 0) + { + if (*lpFile != ' ' && + *lpFile != '\t'&& + *lpFile != '\n'&& + *lpFile != '\r') + { + return(FALSE); + } + lpFile++; + } + + return(TRUE); +} + +/* + * Login was successful. Process both Login Scripts: the System Login + * Script and the User Login Script. If there is an EXIT command in the + * System Login Script, then we do not process the User Login Script. + * If there is no User Login Script, we process a default Login Script, + * which is hard-coded internally. See the Login Script appendix in + * the NetWare Installation guide for more info. + */ +void ProcessLoginScripts (unsigned int conn, char *UserName, int argc, char ** argv, char *lpScript) +{ + unsigned int iRet = 0; + unsigned long userID ; + char pchUserLoginScriptFile[24]; + + // Initalize LOGIN_NAME, CONNECTION_ID and CONNECTION_NUMBER. + ARGC = argc; + ARGV = argv; + LOGIN_NAME = UserName; + CONNECTION_ID = conn; + + // Initialize some 4X variables + if ( fNDS ) + { + COMMON_NAME = UserName; + + LOGIN_CONTEXT = malloc ( CONTEXT_MAX ); + strcpy( LOGIN_CONTEXT, REQUESTER_CONTEXT ); + + LAST_NAME = malloc( MAXLEN ); + NDSGetVar ( "SURNAME", LAST_NAME, MAXLEN ); + } + else { + LAST_NAME = UserName; + COMMON_NAME = UserName; + LOGIN_CONTEXT = ""; + REQUESTER_CONTEXT = ""; + } + + if (iRet = GetConnectionNumber (conn, &CONNECTION_NUMBER)) + { + DisplayError (iRet, "GetConnectionNumber"); + return; + } + + if (lpScript) + { + if (!ProcessLoginScriptFile(lpScript)) + DisplayMessage(IDR_NO_SCRIPT_FILE, lpScript); + } + else + { + if ( fNDS ) + { + unsigned char Object[128]; + unsigned char ProfileObject[256]; + PBYTE p; + int err; + + // Browse back from user's node to first occurrence + // or organizational unit or organization and look for + // system script there. If the nearest OU or O doesn't have + // a system script, don't run one. + + for ( p = TYPED_USER_NAME; p ; p = strchr ( p, '.' ) ) + { + + p++; + + if ( *p == 'O' && *(p+1) == 'U' && *(p+2) == '=' ) + break; + + if ( *p == 'O' && *(p+1) == '=' ) + break; + } + + if ( p != NULL ) + { + ProcessLoginScriptProperty( p ); + } + + // profile login script. + + if ( !NDSGetUserProperty ( "Profile", ProfileObject, 256, NULL, NULL) ) + { + ConvertUnicodeToAscii( ProfileObject ); + ProcessLoginScriptProperty( ProfileObject ); + } + + // user login script + + if ( (!ProcessLoginScriptProperty( TYPED_USER_NAME )) && + (!fNoDefaultLoginScript) ) + { + ProcessLoginScript (DefaultLoginScript); + } + } + else + { + static char SysLoginScriptFile[] = "SYS:PUBLIC/NET$LOG.DAT" ; + + // Process system login script file. + ProcessLoginScriptFile (SysLoginScriptFile); + + // Check if user login script exists. + if (iRet = GetBinderyObjectID (conn, UserName, OT_USER, + &userID)) + return; + + sprintf(pchUserLoginScriptFile, "SYS:MAIL/%lx/LOGIN", SwapLong(userID)); + + if ( (!ProcessLoginScriptFile (pchUserLoginScriptFile)) && + (!fNoDefaultLoginScript) ) + { + ProcessLoginScript (DefaultLoginScript); + } + } + } +} + +int ProcessLoginScriptFile (char *lpLoginScriptFile) +{ + int nFileSize = 0, bEmpty; + char *lpLoginScript; + + nFileSize = NWGetFileSize (lpLoginScriptFile); + + if (nFileSize <= 2) + return(FALSE); + + // system login script exists. + lpLoginScript = malloc (nFileSize); + if (lpLoginScript == NULL) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + LoadFile (lpLoginScriptFile, lpLoginScript, nFileSize); + + bEmpty = IsEmptyFile(lpLoginScript); + + if (!bEmpty) + ProcessLoginScript (lpLoginScript); + + free (lpLoginScript); + + return(!bEmpty); +} + + +/* + * Retrieve and process the Login Script property + */ +int ProcessLoginScriptProperty ( unsigned char * Object ) +{ + unsigned int nFileSize = 0; + unsigned int Actual = 0; + unsigned int bEmpty; + char *lpLoginScript; + HANDLE Stream; + int err; + unsigned int i,j; + + if ( NDSfopenStream ( Object, "Login Script", &Stream, &nFileSize ) ) + return(FALSE); + + if ( nFileSize <= 2) + return(FALSE); + + // login script exists. + lpLoginScript = malloc (nFileSize+2); + if (lpLoginScript == NULL) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return FALSE; + } + memset(lpLoginScript, 0, nFileSize+2); + + if ( !ReadFile ( Stream, lpLoginScript, nFileSize, &Actual, NULL ) ) + { + bEmpty = TRUE; + } +#ifdef BUGBUG // ReadFile is returning wrong lengths + else if ( Actual != nFileSize ) + { + bEmpty = TRUE; + } +#endif + else if ( IsEmptyFile(lpLoginScript) ) + bEmpty = TRUE; + else + bEmpty = FALSE; + + for ( i = 0, j = 0; i < nFileSize; i++, j++ ) + { + if (( lpLoginScript[i] == '\r' ) && + ( lpLoginScript[i+1] == '\n' ) ) + i++; + + lpLoginScript[j] = lpLoginScript[i]; + } + + while ( j < nFileSize ) + { + lpLoginScript[j++] = 0; + } + + CloseHandle( Stream ); + + if (!bEmpty) + ProcessLoginScript (lpLoginScript); + + free (lpLoginScript); + + return(!bEmpty); +} + +/* + * Return the size of the file. + */ +int NWGetFileSize (char * lpFileName) +{ + int nFileSize = 0; + FILE * stream; + + do + { + if ((stream = fopen (NTNWtoUNCFormat(lpFileName), "r")) == NULL) + break; + + while (feof (stream) == 0) + { + fgetc (stream); + nFileSize++; + } + + if (fclose (stream)) + nFileSize = 0; + }while (FALSE); + + + return(nFileSize); +} + +/* + * Read the file into memory pointed by lpFileBuffer. + */ +void LoadFile (char *lpFileName, char *lpFileBuffer, int nFileSize) +{ + FILE * stream; + + if ((stream = fopen (NTNWtoUNCFormat(lpFileName), "r")) != NULL) + { + fread (lpFileBuffer, sizeof (char), nFileSize, stream); + fclose (stream); + } + + *(lpFileBuffer+nFileSize-1) = 0; + +} + +/* + * Process Login Script that is in memory pointed by lpLoginScript + * line by line. + */ +void ProcessLoginScript (char *lpLoginScript) +{ + nCondIndex = -1; + fGlobalExitFlag = FALSE; + fGlobalIfTooDeep = FALSE; + + lpGlobalLine = lpLoginScript; // we start at the top of the login script + + if (!CreateLabelList (&pGlobalLabelList, lpLoginScript)) + { + if (pGlobalLabelList != NULL) { + + FreeLabelList (pGlobalLabelList); + pGlobalLabelList = NULL; + } + return; + } + + while (*lpGlobalLine != 0) { + + // + // search for the end of the current line and replace with a null + // + + if (lpGlobalLineSeparator = strchr(lpGlobalLine, '\n')) { + + // + // we may reset this manually in the goto handler, remember so that + // we don't trample anything needlessly. + // + + *lpGlobalLineSeparator = 0; + fGlobalHaveNulledLineSeparator = TRUE; + + } else { + + fGlobalHaveNulledLineSeparator = FALSE; + } + + // + // Now lpGlobalLine points to one line only. + // + + CommandDispatch (lpGlobalLine); + + if (fGlobalExitFlag) + { + if (fGlobalIfTooDeep) + DisplayMessage(IDR_ORIGINAL_LINE_WAS, lpGlobalLine); + break; + } + + if (lpGlobalLineSeparator) { + + if ( fGlobalHaveNulledLineSeparator ) { + + *lpGlobalLineSeparator = '\n'; // recover the changes made. + fGlobalHaveNulledLineSeparator = FALSE; + } + + lpGlobalLine = lpGlobalLineSeparator + 1; // next line please + + } else { + + break; + } + } + + if (pGlobalLabelList != NULL) { + FreeLabelList (pGlobalLabelList); + pGlobalLabelList = NULL; + } +} + +/* + * Scan the login script, put labels in a link list and comment out + * those label lines. + */ +int CreateLabelList (PLABEL_LIST *ppLabelList, char *lpLoginScript) +{ + char *lpLine = lpLoginScript, *lpEnd, *lpLabel, *lpTemp; + int nLen; + PLABEL_LIST *ppNext = ppLabelList; + + while (*lpLine != 0) + { + if (lpEnd = strchr (lpLine, '\n')) + *lpEnd = 0; + + // Now lpLine points to one line only. + lpLabel = RemoveSpaces (lpLine); + if (isalnum (*lpLabel) || (*lpLabel == '%')) + { + lpTemp = lpLabel; + nLen = 0; + while (*lpTemp != 0 && *lpTemp != ' ' && *lpTemp != '\t' && *lpTemp != ':') + { + if (IsDBCSLeadByte(*lpTemp)) + { + lpTemp++; + nLen++; + } + + lpTemp++; + nLen++; + } + + lpTemp = RemoveSpaces (lpTemp); + if (*lpTemp == ':' && EndOfLine (lpTemp+1)) + { + // The Line is label line. + if ((*ppNext = malloc (sizeof (LABEL_LIST))) == NULL || + ((*ppNext)->pLabel = malloc (nLen+1)) == NULL) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + return(FALSE); + } + + SmartCap(lpLabel); + strncpy ((*ppNext)->pLabel, lpLabel, nLen); + *((*ppNext)->pLabel+nLen) = 0; + (*ppNext)->pNextLine = lpEnd? lpEnd+1 : lpEnd; + (*ppNext)->pNext = NULL; + ppNext = &((*ppNext)->pNext); + + // Comment out the label line. + *(lpLine) = ';'; + } + } + + if (lpEnd) + { + *lpEnd = '\n'; // recover the changes made. + lpLine = lpEnd+1; + } + else + break; + } + + return(TRUE); +} + +/* + * Free up the memory allocated for the link list. + */ +void FreeLabelList (LABEL_LIST *pLabelList) +{ + LABEL_LIST *pNext = pLabelList; + + while (pLabelList) + { + pNext = pLabelList->pNext; + free (pLabelList->pLabel); + free (pLabelList); + pLabelList = pNext; + } +} + +/* + * Dispatch to command hander according to the command. + */ +void CommandDispatch (char *lpCommand) +{ + char buffer[MAXLEN]; + char *restBuffer; + int index, fCommandHandled = FALSE; + int nTemp = -1; + + // Get rid of leading spaces. + lpCommand = RemoveSpaces(lpCommand); + + // Don't do anything if it's a comment line or empty line. + if (*lpCommand == ';' || *lpCommand == '*' || *lpCommand == '\0' || + *lpCommand == '\r'|| *lpCommand == '\n') + return; + + do // FALSE loop. + { + // Make sure the command line is not too long to process. + if (strlen (lpCommand) > MAXLEN -1) { + break; + } + + // Make a copy of the command line to buffer. + strcpy (buffer, lpCommand); + + // external command line. + if (*buffer == '#') + { + ExternalCmdHandler (buffer); + return; + } + + // Get the command index in the command table. + if ((index = GetTableIndex(buffer, &restBuffer)) == -1) + break; + + // Dispatch to the corresponding command handler. + if (nCondIndex > -1 && + !aCondVal[nCondIndex] && + index != CM_IF && + index != CM_ELSE && + index != CM_END) + fCommandHandled = TRUE; + else + fCommandHandled = (*nwCommand[index].commandhandler)(restBuffer); + + } while (FALSE); + + if (!fCommandHandled) { + BadCommandHandler (lpCommand); + } +} + +/* + * Used by GetTableIndex(). + * This function should capitalize the entire command string except + * those in quotes. + */ +void SmartCap(char *ptr) +{ + int inquotes = (*ptr == '\"'); + char *pNext; + + while (*ptr) + { + if (!inquotes) + { + if (IsDBCSLeadByte(*ptr)) + *((int *)ptr) = toupper ((int)*ptr); + else + *ptr = (char) toupper((int)*ptr); + } + + pNext = NWAnsiNext(ptr); + + if (*pNext == '\"' && *ptr != '\\') + inquotes = !inquotes; + + ptr = pNext; + } +} + +/* + * Return the index of the command in the command dispatch table. + * Return -1 if the command is not found in the command dispatch table. + */ +int GetTableIndex(char *buffer, char **prestBuffer) +{ + int i, nStrLen; + + // Upcase every thing except those in quotes. + SmartCap (buffer); + + for (i=0; ipLabel, lpLabel)) + { + if ( fGlobalHaveNulledLineSeparator ) + { + + *lpGlobalLineSeparator = '\n'; // recover the changes made. + fGlobalHaveNulledLineSeparator = FALSE; + } + + lpGlobalLine = pLabelList->pNextLine; + + lpGlobalLineSeparator = lpGlobalLine ? (lpGlobalLine - 1) : NULL; + + fLabelFound = TRUE; + break; + } + + pLabelList = pLabelList->pNext; + } + + if (!fLabelFound) + { + DisplayMessage (IDR_LABEL_NOT_FOUND, lpLabel); + fGlobalExitFlag = TRUE; + } + + *lpEnd = chEnd; + return( TRUE ); +} + +/* + * Attach [FileServer[/UserName[;Password]]] + */ +int AttachHandler (char *lpParam) +{ + unsigned int iRet = 0; + int fCommandHandled = FALSE; + char serverName[MAX_NAME_LEN] = ""; + char userName[MAX_NAME_LEN] = ""; + char password[MAX_PASSWORD_LEN] = ""; + char *lpSlash, *lpSemiColon, *lpServerName, *lpUserName; + unsigned int conn; + int bAlreadyAttached = FALSE, bReadPassword = TRUE; + + do // FALSE loop. + { + NotQuotedStringTranslate (lpParam, TRUE); + + // Make sure that there is at most 1 slash. + lpSlash = strchr (lpParam, '\\'); + + if (lpSlash == NULL) + { + lpSlash = strchr (lpParam, '/'); + if (lpSlash != NULL && strchr (lpSlash+1, '/')) + break; + } + else + { + if (strchr (lpParam, '/') || + strchr (lpSlash+1, '/') || + strchr (lpSlash+1, '\\')) + break; + } + + // Break the string at slash. + if (lpSlash) + *lpSlash = 0; + + // Server name should not contain semicolon. + if (strchr (lpParam, ';')) + break; + + lpServerName = strtok (lpParam, __SPACES__); + + if (lpServerName = NULL) + { + if (lpSlash) + break; + } + else + { + // Make sure that there is only one name in front of the slash. + if (strtok (NULL, __SPACES__)) + break; + + // Copy the server name to the buffer. + if (strlen (lpParam) > MAX_NAME_LEN-1) + break; + + strcpy (serverName, lpParam); + + if (lpSlash) + { + lpSemiColon = strchr (lpSlash+1, ';'); + if (lpSemiColon) + *lpSemiColon = 0; + + lpUserName = strtok (lpSlash+1, __SPACES__); + if (lpUserName) + { + if ( strtok (NULL, __SPACES__)) + break; + + if (strlen (lpUserName) > MAX_NAME_LEN-1 ) + break; + + strcpy (userName, lpUserName); + } + + if (lpSemiColon) + { + if (strlen (lpSemiColon+1) > MAX_PASSWORD_LEN-1) + break; + strcpy (password, strtok (lpSemiColon+1, __SPACES__)); + xstrupr (password); + bReadPassword = FALSE; + } + } + } + + fCommandHandled = TRUE; + + if (serverName[0] == 0) + { + DisplayMessage(IDR_ENTER_SERVER_NAME); + if (!ReadName(serverName)) + break; + + DisplayMessage(IDR_ENTER_LOGIN_NAME, serverName); + if (!ReadName(userName)) + break; + } + else if (userName[0] == 0) + strcpy (userName, LOGIN_NAME); + + if (iRet = CAttachToFileServer(serverName, &conn, &bAlreadyAttached)) + { + if (!SCRIPT_ERROR) + SCRIPT_ERROR = iRet; + break; + } + + // Do not need this connection + DetachFromFileServer (conn); + +#ifdef BUGBUG // not reliable + if (bAlreadyAttached) + { + DisplayMessage(IDR_ATTACHED, serverName); + break; + } +#endif + + if (Login(userName, serverName, password, bReadPassword)) + { + // Clear out the password + memset( password, 0, sizeof( password ) ); + + // Ask for user name + + DisplayMessage(IDR_ENTER_LOGIN_NAME, serverName); + if (!ReadName(userName)) + break; + + if (Login(userName, serverName, password, bReadPassword)) + { + // Clear out the password + memset( password, 0, sizeof( password ) ); + break; + } + } + + // Clear out the password + + memset( password, 0, sizeof( password ) ); + + AddServerToAttachList( serverName, LIST_3X_SERVER ); + + } while (FALSE); + + return(fCommandHandled); +} + +/* + * BREAK ON, enable ctrl-c, ctrl-break + * BREAK OFF, disable ctrl-c, ctrl-break + */ +int BreakHandler (char *lpParam) +{ + int fCommandHandled = TRUE; + + if (IsOn(lpParam)) + { + if (!fBreakOn) + BreakOn(); + } + else if (IsOff(lpParam)) + { + if (fBreakOn) + BreakOff(); + } + else + fCommandHandled = FALSE; + + return(fCommandHandled); +} + + +/* + * DISPLAY [pathname]file + * FDISPLAY [pathname]file + */ +int DisplayHandler (char *lpParam) +{ + FILE * stream; + + NotQuotedStringTranslate (lpParam, TRUE); + + if ((stream = fopen (lpParam, "r")) != NULL) + { + while (feof (stream) == 0) + _fputchar(fgetc (stream)); + + fclose (stream); + DisplayMessage(IDR_NEWLINE); + } + + return(TRUE); +} + +/* + * DOS BREAK ON, enable ctrl-break checking for DOS + * DOS BREAK OFF, disable ctrl-break checking for DOS + */ +int DosBreakHandler (char *lpParam) +{ + int fCommandHandled = TRUE; + + if (IsOn (lpParam)) + system ("BREAK ON"); + else if(IsOff (lpParam)) + system ("BREAK OFF"); + else + fCommandHandled = FALSE; + + return(fCommandHandled); +} + +/* + * Used by SetHandler() and LocalSetHandler() + * Return TRUE if lpParam points to name = "value", and set + * lpParam to "name=value" on return. + * Return FALSE otherwise. + */ +int VerifySetFormat (char *lpParam) +{ + int fCorrect = FALSE; + char buffer[MAXLEN]; + char *lpBuffer = buffer; + + strcpy (buffer, lpParam); + + do + { + while (*lpBuffer != 0 && *lpBuffer != '=' && *lpBuffer != ' ' && *lpBuffer != '\t') + lpBuffer = NWAnsiNext(lpBuffer); + + lpParam[lpBuffer-buffer]=0; + strcat (lpParam, "="); + + if (*lpBuffer != '=') + lpBuffer = RemoveSpaces (lpBuffer); + + if (*lpBuffer != '=') + break; + + lpBuffer = RemoveSpaces (lpBuffer+1); + + if (*lpBuffer) + { + if (!QuotedStringTranslate (lpBuffer)) + break; + + strcat (lpParam, lpBuffer); + } + + fCorrect = TRUE; + }while (FALSE); + + return(fCorrect); +} + +/* + * Used by SetHandler() and LocalSetHandler() + * Set the local environment variable. + * Don't free the memory allocated because the environment variable will + * point to free space otherwise. + */ +void SetLocalEnv(char *buffer) +{ + char *lpEnvString; + lpEnvString = malloc(strlen (buffer) + 1); + + if (lpEnvString == NULL) + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + else + { + strcpy (lpEnvString, buffer); + _putenv (lpEnvString); + } +} + +/* + * Set Dos environment variable. + * [DOS] SET name = "value" + */ +int SetHandler (char *lpParam) +{ + + int fCommandHandled; + + fCommandHandled = VerifySetFormat(lpParam); + + if (fCommandHandled) + { + + if ( _strnicmp( "COMSPEC=", lpParam, strlen( "COMSPEC=" ) ) ) + { + SetLocalEnv(lpParam); + SetEnv (lpParam); + } + } + + return(fCommandHandled); +} + +/* + * Set local Dos environment variable. + * [OPTION] [DOS] SET name = "value" + */ +int LocalSetHandler (char *lpParam) +{ + int fCommandHandled; + + fCommandHandled = VerifySetFormat(lpParam); + + if (fCommandHandled) + if ( _strnicmp( "COMSPEC=", lpParam, strlen( "COMSPEC=" ) ) ) + { + SetLocalEnv (lpParam); + } + + return(fCommandHandled); +} + +/* + * Used by DosVerifyHandler(). + * Turn /V option of copy on. + */ +void DosVerifyOn(void) +{ +} + +/* + * Used by DosVerifyHandler(). + * Turn /V option of copy off. + */ +void DosVerifyOff(void) +{ +} + +/* + * DOS VERYFY [ON|OFF], Turn /V option of copy on or off. + */ +int DosVerifyHandler (char *lpParam) +{ + int fCommandHandled = TRUE; + + if (IsOn(lpParam)) + DosVerifyOn(); + else if (IsOff(lpParam)) + DosVerifyOff(); + else + fCommandHandled = FALSE; + + return(fCommandHandled); +} + +/* + * DRIVE [driveletter: | n*:], set the default drive to the one specified. + */ +int DriveHandler (char *lpParam) +{ + int fCommandHandled = FALSE; + WORD driveNum=0, n; + char *pColon; + + do // FALSE loop. + { + if ((pColon = strchr (lpParam, ':')) == NULL || + !EndOfLine (pColon + 1)) + break; + + if (*lpParam == '*') + { + *pColon = 0; + if ((n = atoi (lpParam+1)) < 1) + break; + + GetFirstDrive (&driveNum); + driveNum += (n-1); + } + else if (pColon == lpParam+1 && isupper(*lpParam)) + driveNum = *lpParam - 'A' + 1; + else + break; + + if (_chdrive (driveNum)) + DisplayMessage(IDR_ERROR_SET_DEFAULT_DRIVE, 'A'+driveNum-1); + else + ExportCurrentDrive( driveNum ); + + fCommandHandled = TRUE; + + } while (FALSE); + + return(fCommandHandled); +} + +/* + * Used by FireHandler() + * Return TRUE if lpTemp points to the legal end of fire statement, ie + * [TIMES][COMMENTS]. It also set the *lpTemp to 0 if lpTemp is not NULL. + * Return FALSE otherwise. + */ +int IsEndOfFireCmd (char *lpTemp) +{ + int fEnd = FALSE; + do + { + if (*lpTemp != 0) + { + if (*lpTemp != ' ' && *lpTemp != '\t' && *lpTemp != '\r') + break; + + *lpTemp = 0; + + lpTemp = RemoveSpaces (lpTemp+1); + + if (!strncmp (lpTemp, "TIMES", 5)) + lpTemp += 5; + + if (!EndOfLine (lpTemp)) + break; + } + + fEnd = TRUE; + }while (FALSE); + + return(fEnd); +} + +/* + * [FIRE | FIRE PHASERS] n TIMES. + */ +int FireHandler (char *lpParam) +{ + char *lpTemp, vartext[MAXLEN]; + int n = 0, nLen; + time_t ltimeStart, ltimeEnd; + + if (EndOfLine (lpParam)) + n = 1; + else if (isdigit(*lpParam)) + { + lpTemp = lpParam; + while (isdigit(*lpTemp)) + lpTemp++; + + if (IsEndOfFireCmd (lpTemp)) + n = atoi (lpParam); + } + else if (*lpParam == '%') + { + strcpy (vartext, lpParam+1); + if (((nLen = VarTranslate (lpParam)) != 0) && + EndOfLine (lpParam+1+nLen)) + n = atoi (vartext); + } + + if (n < 0) + return(FALSE); + else if (n == 0) // Compatible with NetWare. + n = 1; + + while (n--) + { + _beep( 610, 100 ); + _beep( 440, 50 ); + time(<imeStart); + do + { + time(<imeEnd); + }while (ltimeEnd-ltimeStart == 0); + } + + return(TRUE); +} + +/* + * EXIT, terminate login script processing. + */ +int ExitHandler (char *lpParam) +{ + int n; + char buffer[16], *argv[10]; + + if (EndOfLine (lpParam)) + CleanupExit(0); + else if (QuotedStringTranslate (lpParam)) + { + if (!fGlobalCompatible) + { + GetShellVersion (buffer, IDS_MACHINE); + if (_stricmp (buffer, "IBM_PC")) + { + DisplayMessage(IDR_EXIT_NOT_SUPPORTED); + return(TRUE); + } + } + + argv[0] = strtok (lpParam, __SPACES__); + + for (n = 1; n < 9; n++) + { + if ((argv[n] = strtok (NULL, __SPACES__)) == NULL) + break; + } + + argv[9] = NULL; + + if ((SCRIPT_ERROR = _spawnvp (P_WAIT, argv[0], argv)) == -1) + DisplayMessage(IDR_BAD_COMMAND); + + CleanupExit (0); + } + else + return(FALSE); +} + +BOOL nwVarNameCompare(LPCSTR src,LPCSTR target) +{ + CHAR szTempName[64]; + LPSTR pT = szTempName; + + if (!_strnicmp(src,target,strlen(target))) { + // + // try to reject obvious problems like + // %LJUNK where %L would be fine + // + if ( !isalpha(src[strlen(target)]) ) + return 0; + else + return 1; + } + + strcpy(szTempName,target); + + while (*pT) { + if (!IsDBCSLeadByte(*pT)) { + if ('_' == *pT) + *pT = ' '; + } + pT = NWAnsiNext(pT); + } + + if (!_strnicmp(src,szTempName,strlen(szTempName))) { + // + // try to reject obvious problems like + // %LJUNK where %L would be fine + // + if ( !isalpha(src[strlen(target)]) ) + return 0; + else + return 1; + } + + return 1; +} + + +/* + * Used by the EvalSingleCond() in IfHandler() + * Return TRUE if buffer is the right member of condition statement. + * *pfCondition is TRUE if the condition meet, FALSE if not. + * *ppRest points to the end of the condition statement. + * Return FALSE if buffer is not the right member of condition statement. + */ +int MemberOf (char *buffer, int *pfCondition, char **ppRest) +{ + int i, nChar, fSucceed = FALSE; + char *lpTemp; + BYTE dataBuffer[128]; + unsigned char moreFlag; + unsigned char propertyType; + unsigned long dwObjectId, *pdwGroups; + char GroupName[MAXLEN]; + unsigned char segment; + + *pfCondition = FALSE; + do + { + if ((buffer = strchr (buffer, '\"')) == NULL) + break; + + if ((lpTemp = strchr (buffer+1, '\"')) == NULL) + break; + + nChar = lpTemp - buffer + 1; + + if (nChar >= MAXLEN) + break; + + strncpy (GroupName, buffer, nChar); + GroupName[nChar] = 0; + if (!QuotedStringTranslate (GroupName)) + break; + + fSucceed = TRUE; + *pfCondition = FALSE; + *ppRest = RemoveSpaces (lpTemp+1); + + if (strlen(GroupName) > MAX_NAME_LEN) + break; + + if ( fNDS ) + { + if ( IsMemberOfNDSGroup( GroupName ) ) + { + *pfCondition = TRUE; + return(TRUE); + } + + } + else + { + if (GetBinderyObjectID (CONNECTION_ID, + _strupr(GroupName), + OT_USER_GROUP, + &dwObjectId) ) + goto done; + + // + // For all the group ID's, try and find a match + // + for ( segment = 1, moreFlag = TRUE; moreFlag && segment; segment++ ) + { + if ( NWReadPropertyValue ((NWCONN_HANDLE)CONNECTION_ID, + LOGIN_NAME, + OT_USER, + "GROUPS_I'M_IN", + segment, + dataBuffer, + &moreFlag, + &propertyType)) + goto done; + + pdwGroups = (unsigned long *) dataBuffer; + + for (i = 0; i < 32 && *(pdwGroups+i); i++) + { + if (*(pdwGroups+i) == dwObjectId) + { + *pfCondition = TRUE; + return(TRUE); + } + } + } + } + + *pfCondition = FALSE; + fSucceed = TRUE; + } while (FALSE); + +done: + + return(fSucceed); +} + +/* + * Used by IsCompare() in EvalSingleCond() in IfHandler() + * Return the next token. + */ +char *GetNextPart (char *lpTemp) +{ + INT i; + + if (strncmp (lpTemp, "VALUE", 5) == 0) + lpTemp = RemoveSpaces (lpTemp+5); + + if (*lpTemp == '\"') + { + lpTemp++; + while (*lpTemp != 0 && *lpTemp != '\"') + lpTemp = NWAnsiNext(lpTemp); + + if (*lpTemp == 0) + return(NULL); + else + lpTemp++; + } + else if (*lpTemp == '<') + { + while (*lpTemp != 0 && *lpTemp != '>') + lpTemp = NWAnsiNext(lpTemp); + + if (*lpTemp == 0) + return(NULL); + else + lpTemp++; + } + else + { + if (*lpTemp == '%') + lpTemp++; + + for (i = 0; i < (fNDS ? NUMVAR : NUMVAR_3X); i++) + { + if (!nwVarNameCompare(lpTemp, varTable[i].VarName)) + { + lpTemp += strlen(varTable[i].VarName); + break; + } + } + + if (i == (fNDS ? NUMVAR : NUMVAR_3X)) + return(NULL); + } + + return(lpTemp); +} + +/* + * Used by EvalSingleCond() in IfHandler() + * left part of buffer could be "...", <...>, or ... for variables. + * Return TRUE if buffer consists of + + * optional rest parts. + * Return FALSE otherwise. + */ +int IsCompare (char *buffer, char **ppright, + int *pnLeftLen, int *pnRightLen, + int *pindex, char **ppRest) +{ + int i, nLen; + char *lpTemp; + + if ((lpTemp = GetNextPart (buffer)) == NULL) + return (FALSE); + + *pnLeftLen = lpTemp-buffer; + lpTemp = RemoveSpaces (lpTemp); + + for (i = 0; COMPARE_OPERATORS[i][0]; i++) + { + nLen = strlen (COMPARE_OPERATORS[i]); + + if (!strncmp(lpTemp, COMPARE_OPERATORS[i], nLen)) + { + *lpTemp = 0; + lpTemp += nLen; + *ppright = RemoveSpaces (lpTemp); + *pindex = i; + *ppRest = GetNextPart (*ppright); + if ( *ppRest == NULL ) + return (FALSE); + *pnRightLen = *ppRest - *ppright; + *ppRest = RemoveSpaces (*ppRest); + return(TRUE); + } + } + + return(FALSE); +} + +/* + * Used by EvalSingleCond() in IfHandler() + * Evaluate lpLeft and lpRight and do the compare operation of index + * and put the result in *pfCondition. + * Return TRUE if succeed, FALSE otherwise. + */ +int Compare (char *lpLeft, char *lpRight, + int nLeftLen, int nRightLen, + int index, int *pfCondition) +{ + char szLeft[MAXLEN], szRight[MAXLEN], *lpTemp; + int nCompare, fValue = FALSE; + + if (strncmp (lpLeft, "VALUE", 5) == 0) + { + fValue = TRUE; + lpTemp = RemoveSpaces (lpLeft+5); + nLeftLen -= (lpTemp - lpLeft); + lpLeft = lpTemp; + } + if (strncmp (lpRight, "VALUE", 5) == 0) + { + fValue = TRUE; + lpTemp = RemoveSpaces (lpRight+5); + nRightLen -= (lpTemp - lpRight); + lpRight = lpTemp; + } + + strncpy (szLeft, lpLeft, nLeftLen); + strncpy (szRight, lpRight, nRightLen); + + szLeft[nLeftLen] = 0; + szRight[nRightLen] = 0; + + if (!QuotedStringTranslate (szLeft) || + !QuotedStringTranslate (szRight)) + return(FALSE); + + if (fValue) + nCompare = atoi(szLeft)-atoi(szRight); + else + nCompare = _stricmp (szLeft, szRight); + + if (IsNotEqual(index)) + *pfCondition = (nCompare != 0); + else if (IsGreaterOrEqual(index)) + *pfCondition = (nCompare >= 0); + else if (IsGreater(index)) + *pfCondition = (nCompare > 0); + else if (IsLessOrEqual(index)) + *pfCondition = (nCompare <= 0); + else if (IsLess(index)) + *pfCondition = (nCompare < 0); + else + *pfCondition = (nCompare == 0); + + return(TRUE); +} + +int IsMemberOf (char *buffer) +{ + int fIsMemberOf = FALSE; + + if (!strncmp (buffer, "MEMBER", 6)) + { + buffer += 6; + if (*buffer == ' ' || *buffer == '\t') + { + buffer = RemoveSpaces (buffer); + if (!strncmp (buffer, "OF", 2)) + { + buffer += 2; + if (*buffer == ' ' || *buffer == '\t') + buffer = RemoveSpaces (buffer); + } + } + + fIsMemberOf = (*buffer == '"'); + } + + return(fIsMemberOf); +} + +int NotMemberOf (char *buffer) +{ + int fNotMemberOf = FALSE; + if (!strncmp (buffer, "NOT", 3)) + { + buffer += 3; + if (*buffer == ' ' || *buffer == '\t') + { + buffer = RemoveSpaces (buffer); + fNotMemberOf = IsMemberOf (buffer); + } + } + + return(fNotMemberOf); +} + + +/* + * Used by IfHandler() + * Evaluate one condition clause and put result in *pfCondition, *ppRest + * points to the rest part of buffer. + * Return TRUE if succeed, FALSE otherwise. + */ +int EvalSingleCond (char *buffer, int *pfCondition) +{ + int index, fSuccess = FALSE, nLeftLen, nRightLen; + char *pright, *pRest; + + if (IsMemberOf(buffer)) + fSuccess = MemberOf (buffer, pfCondition, &pRest); + else if (NotMemberOf (buffer)) + { + fSuccess = MemberOf (buffer, pfCondition, &pRest); + *pfCondition = !(*pfCondition); + } + else if (IsCompare (buffer, &pright, &nLeftLen, &nRightLen, &index, &pRest)) + fSuccess = Compare (buffer, pright, nLeftLen, nRightLen, index, pfCondition); + else if ( !_strnicmp ("ACCESS_SERVER", buffer, strlen("ACCESS_SERVER")) ) + { + fSuccess = TRUE; + *pfCondition = FALSE; + pRest = buffer + strlen ("ACCESS_SERVER"); + } + + if (fSuccess) + memmove (buffer, pRest, strlen (pRest)+1); + + return(fSuccess); +} + +int EvaluateCondExpression(char *lpCondExpression, int *pfCondition) +{ + int fSuccess = FALSE, fCond; + char *lpRight, *lpLeft, *lpOp; + + if (lpRight = strchr (lpCondExpression, ')')) + { + *lpRight = 0; + if ((lpLeft = strrchr (lpCondExpression, '(')) == NULL || + !EvaluateCondExpression(lpLeft+1, pfCondition)) + return(FALSE); + + *lpLeft = (*pfCondition)? '1' : '0'; + memmove (lpLeft+1, lpRight+1, strlen (lpRight+1)+1); + return(EvaluateCondExpression (lpCondExpression, pfCondition)); + } + + if (lpOp = strrchr (lpCondExpression, '+')) + { + *lpOp = 0; + + if (!EvaluateCondExpression (lpCondExpression, pfCondition) || + !EvaluateCondExpression (lpOp+1, &fCond)) + return(FALSE); + + *pfCondition = (*pfCondition || fCond); + return(TRUE); + } + + if (lpOp = strrchr (lpCondExpression, '*')) + { + *lpOp = 0; + + if (!EvaluateCondExpression (lpCondExpression, pfCondition) || + !EvaluateCondExpression (lpOp+1, &fCond)) + return(FALSE); + + *pfCondition = (*pfCondition && fCond); + return(TRUE); + } + + if (lpOp = strrchr (lpCondExpression, '^')) + { + *lpOp = 0; + + if (!EvaluateCondExpression (lpCondExpression, pfCondition) || + !EvaluateCondExpression (lpOp+1, &fCond)) + return(FALSE); + + *pfCondition = !(*pfCondition && fCond); + return(TRUE); + } + + if (!strcmp (lpCondExpression, "1")) + { + *pfCondition = TRUE; + return(TRUE); + } + else if (!strcmp (lpCondExpression, "0")) + { + *pfCondition = FALSE; + return(TRUE); + } + else + return(FALSE); +} + +/* + * Used by IfHandler() + * Evaluate up to 10 conditions. + * Return TRUE if succeed, FALSE otherwise. + * On return, buffer stores whatever after conditional expressions + * without leading spaces. + */ +int EvaluateCond(char *buffer, int *pfCondition) +{ + int fCondition = TRUE, fCurrent, fSucceed = FALSE, nCount; + char CondExpression[MAXLEN], *lpCond = CondExpression, *lpBuffer = buffer; + + for (nCount = 0; nCount < 10; nCount++) + { + while (*lpBuffer == '(') + { + *lpCond = *lpBuffer; + lpCond++; + lpBuffer++; + } + + lpBuffer = RemoveSpaces (lpBuffer); + + if (!EvalSingleCond (lpBuffer, &fCurrent)) + break; + + *lpCond = fCurrent? '1' : '0'; + lpCond++; + + while (*lpBuffer == ')') + { + *lpCond = *lpBuffer; + lpCond++; + lpBuffer++; + } + + lpBuffer = RemoveSpaces (lpBuffer); + + if (*lpBuffer == ',') + { + *lpCond = '*'; + lpCond++; + + lpBuffer = RemoveSpaces (lpBuffer+1); + + if (!strncmp (lpBuffer, "AND", 3)) + lpBuffer = RemoveSpaces (lpBuffer+3); + } + else if (!strncmp (lpBuffer, "AND", 3)) + { + *lpCond = '*'; + lpCond++; + lpBuffer = RemoveSpaces (lpBuffer+3); + } + else if (!strncmp (lpBuffer, "&&", 2)) + { + *lpCond = '*'; + lpCond++; + lpBuffer = RemoveSpaces (lpBuffer+2); + } + else if ( (!strncmp (lpBuffer, "OR", 2)) || + (!strncmp (lpBuffer, "||", 2)) ) + { + *lpCond = '+'; + lpCond++; + lpBuffer = RemoveSpaces (lpBuffer+2); + } + /* + * A NOR expression is documented in some books, but isn't + * implemented in the 4X login.exe I have. + */ + else if (!strncmp (lpBuffer, "NOR", 3)) + { + *lpCond = '^'; + lpCond++; + lpBuffer = RemoveSpaces (lpBuffer+3); + } + else + { + fSucceed = TRUE; + *lpCond = 0; + lpBuffer = RemoveSpaces (lpBuffer); + memmove (buffer, lpBuffer, strlen (lpBuffer)+1); + break; + } + } + + if (fSucceed) + fSucceed = EvaluateCondExpression (CondExpression, pfCondition); + + return(fSucceed); +} + +/* + * If statement handler. + */ +int IfHandler (char *lpParam) +{ + int fCommandHandled = FALSE, fCondition; + + do + { + if (nCondIndex+1 == MAX_NUM_IF) + { + DisplayMessage(IDR_IF_TOO_DEEP); + fGlobalExitFlag = TRUE; + fGlobalIfTooDeep = TRUE; + return TRUE; + } + + if (EndOfLine (lpParam)) + break; + + if (!EvaluateCond (lpParam, &fCondition)) + break; + + if (!strncmp (lpParam, "THEN", 4)) + { + lpParam = RemoveSpaces (lpParam+4); + + if (!strncmp (lpParam, "BEGIN", 5)) + { + lpParam += 5; + + if (!EndOfLine (lpParam)) + break; + } + else if((!strncmp (lpParam, "DO", 2)) && + (strncmp (lpParam, "DOS", 3))) + { + lpParam += 2; + if (!EndOfLine (lpParam)) + break; + } + } + else if (!strncmp (lpParam, "BEGIN", 5)) + { + lpParam += 5; + + if (!EndOfLine (lpParam)) + break; + } + + if (EndOfLine (lpParam)) + { + nCondIndex++; + aCondVal[nCondIndex] = + (nCondIndex > 0 && !aCondVal[nCondIndex-1])? + FALSE : fCondition; + } + else + { + if (fCondition && (nCondIndex == -1 || aCondVal[nCondIndex])) + CommandDispatch (lpParam); + } + + fCommandHandled = TRUE; + + }while (FALSE); + + return(fCommandHandled); +} + +/* + * Else statement handler. + */ +int ElseHandler (char *lpParam) +{ + int fCommandHandled = FALSE; + + if (EndOfLine (lpParam)) + { + if (nCondIndex == 0 || + nCondIndex > 0 && aCondVal[nCondIndex-1]) + aCondVal[nCondIndex] = !aCondVal[nCondIndex]; + + fCommandHandled = TRUE; + } + + return(fCommandHandled); +} + +/* + * End statement handler. + */ +int EndHandler (char *lpParam) +{ + int fCommandHandled = FALSE; + + if (EndOfLine (lpParam)) + { + if (nCondIndex > -1) + nCondIndex--; + + fCommandHandled = TRUE; + } + + return(fCommandHandled); +} + +/* + * INCLUDE [pathname]filename + */ +int IncludeHandler (char *lpParam) +{ + int fCommandHandled = FALSE, nFileSize; + char *lpLoginScript, *lpTemp; + int i, nCondIndexCopy; + int aCondValCopy[MAX_NUM_IF]; + int iRet; + + // + // Save off the old globals that track where we are. + // + + LABEL_LIST *pLabelList = pGlobalLabelList; + char *lpLine = lpGlobalLine; + char *lpLineSeparator = lpGlobalLineSeparator; + int fHaveNulledLineSeparator = fGlobalHaveNulledLineSeparator; + + pGlobalLabelList = NULL; // so that we don't free it. + + do + { + if (strtok (lpParam, __SPACES__) == NULL) + break; + + lpTemp = strtok(NULL, __SPACES__); + if (lpTemp && !EndOfLine (lpTemp)) + break; + + fCommandHandled = TRUE; + NotQuotedStringTranslate(lpParam, TRUE); + + nCondIndexCopy = nCondIndex; + for (i = 0; i < MAX_NUM_IF; i++) + aCondValCopy[i] = aCondVal[i]; + + /* + * First we try a NDS object and then a file + */ + iRet = FALSE; + if ( fNDS ) + { + iRet = ProcessLoginScriptProperty( lpParam ); + if ( !iRet ) + { + char Fixup[MAXLEN]; + char * ptr; + /* + * Strip off the . in front and add context at end + */ + ptr = RemoveSpaces (lpParam); + if ( *ptr == '.' ) { + ptr++; + strncpy( Fixup, ptr, MAXLEN ); + } + else { + strncpy( Fixup, ptr, MAXLEN ); + if ( Fixup[strlen(Fixup)-1] != '.' ) + strcat( Fixup, "." ); + strcat( Fixup, LOGIN_CONTEXT ); + } + iRet = ProcessLoginScriptProperty( Fixup ); + } + } + + if ( !fNDS || !iRet ) + { + nFileSize = NWGetFileSize (lpParam); + if (nFileSize == 0) + { + DisplayMessage(IDR_ERROR_OPEN_SCRIPT, lpParam); + break; + } + + // user login script exists. + lpLoginScript = malloc (nFileSize); + if (lpLoginScript == NULL) + { + DisplayMessage(IDR_NOT_ENOUGH_MEMORY); + break; + } + + LoadFile (lpParam, lpLoginScript, nFileSize); + + ProcessLoginScript (lpLoginScript); + + free (lpLoginScript); + } + + fGlobalExitFlag = FALSE; + + nCondIndex = nCondIndexCopy; + for (i = 0; i < MAX_NUM_IF; i++) + aCondVal[i] = aCondValCopy[i]; + + }while (FALSE); + + // + // restore the globals that track where we are in the file. + // + + pGlobalLabelList = pLabelList; + lpGlobalLine = lpLine; + lpGlobalLineSeparator = lpLineSeparator; + fGlobalHaveNulledLineSeparator = fHaveNulledLineSeparator; + + + return(fCommandHandled); +} + +/* + * Map command handler. + */ +int MapHandler (char *lpParam) +{ + char buffer[MAXLEN]=""; + + strcpy( buffer, lpParam ); + + NotQuotedStringTranslate( buffer, TRUE ); + + Map( buffer ); + + return(TRUE); +} + +/* + * PAUSE or WAIT. + */ +int PauseHandler (char *lpParam) +{ + int fCommandHandled = FALSE; + + if (EndOfLine (lpParam)) + { + //Empty kb buffer first. + while (_kbhit()) + _getch(); + + DisplayMessage(IDR_STRIKE_KEY); + _getch(); + DisplayMessage(IDR_NEWLINE); + fCommandHandled = TRUE; + } + + return(fCommandHandled); +} + +/* + * Used by WriteHandler(). + * Return TRUE if buffer ends with ';'. Set it to 0 + * Return FALSE otherwise. + */ +int EndWithSemicolon (char *buffer) +{ + char *lpLastSemicolon, *lpRest; + lpLastSemicolon = strrchr (buffer, ';'); + if (lpLastSemicolon) + { + lpRest = RemoveSpaces (lpLastSemicolon+1); + if (*lpRest == 0) + { + *lpLastSemicolon = 0; + return(TRUE); + } + } + + return(FALSE); +} + +char *ConvertPercent (char *buffer) +{ + char *lpPercent, *lpBuffer = buffer; + int nPercent = 0; + + while (lpPercent = strchr (lpBuffer, '%')) + { + nPercent++; + lpBuffer = lpPercent+1; + } + + if (nPercent == 0) + return(NULL); + + lpBuffer = malloc (strlen(buffer)+nPercent+1); + if (lpBuffer == NULL) + return(NULL); + + strcpy (lpBuffer, buffer); + + lpPercent = strchr (lpBuffer, '%'); + + while (lpPercent) + { + memmove (lpPercent+1, lpPercent, strlen (lpPercent)+1); + lpPercent = strchr ( lpPercent+2, '%'); + } + + return(lpBuffer); +} + +/* + * WRITE text, display a text message on the screen. + */ +int WriteHandler (char *lpParam) +{ + int fNewLine; + char *lpBuffer; + + if (*lpParam == 0) + { + DisplayMessage(IDR_NEWLINE); + return(TRUE); + } + + fNewLine = !EndWithSemicolon (lpParam); + + if (!QuotedStringTranslate (lpParam)) + return FALSE; + + lpBuffer = ConvertPercent (lpParam); + if (lpBuffer == NULL) + { + DisplayOemString(lpParam); + } + else + { + DisplayOemString(lpBuffer); + free (lpBuffer); + } + + if (fNewLine) + DisplayMessage(IDR_NEWLINE); + + return(TRUE); +} + +/* + * Used by ShiftHandler(). + * Return TURE if the line is all numbers + [comments] + * Return FALSE otherwise. + */ +int AreAllNumbers(char *buffer) +{ + while (isdigit(*buffer)) + buffer++; + + return(EndOfLine (buffer)); +} + +/* + * Set the nGlobalShiftDelta variable. + */ +int ShiftHandler (char *lpParam) +{ + int fCommandHandled = TRUE; + + if (EndOfLine (lpParam)) + nGlobalShiftDelta++; + else if (*lpParam == '-') + { + lpParam = RemoveSpaces (lpParam+1); + if (!AreAllNumbers(lpParam)) + fCommandHandled = FALSE; + else + nGlobalShiftDelta -= atoi (lpParam); + } + else + { + if (*lpParam == '+') + lpParam = RemoveSpaces (lpParam+1); + + if (!AreAllNumbers(lpParam)) + fCommandHandled = FALSE; + else + nGlobalShiftDelta += atoi (lpParam); + } + + return(fCommandHandled); +} + +/* + * Set the machine name. + */ +int MachineHandler (char *lpParam) +{ + int nLen, i; + + if (*lpParam != '=') + return(FALSE); + + lpParam = RemoveSpaces (lpParam+1); + if (!QuotedStringTranslate(lpParam)) + return(FALSE); + + nLen = strlen (lpParam); + for (i = nLen; i < 15; i++) + *(lpParam+i) = ' '; + + *(lpParam+15) = 0; + + return(TRUE); +} + +/* + * Set the fGlobalCompatible variable. + */ +int CompatibleHandler(char *lpParam) +{ + if (!EndOfLine (lpParam)) + return(FALSE); + + fGlobalCompatible = TRUE; + return(TRUE); +} + +/* + * Clear the screen + */ +int ClearHandler(char *lpParam) +{ + CONSOLE_SCREEN_BUFFER_INFO coninfo; + COORD scrolltarget; + CHAR_INFO chinfo; + SMALL_RECT scrollrect; + + if ( hconout == INVALID_HANDLE_VALUE ) + { + hconout = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL ); + } + + if ( hconout == INVALID_HANDLE_VALUE ) + return TRUE; + + GetConsoleScreenBufferInfo( hconout, &coninfo ); + + scrolltarget.Y = (SHORT)(0 - coninfo.dwSize.Y); + scrolltarget.X = 0; + + scrollrect.Top = 0; + scrollrect.Left = 0; + scrollrect.Bottom = coninfo.dwSize.Y; + scrollrect.Right = coninfo.dwSize.X; + chinfo.Char.AsciiChar = ' '; + chinfo.Attributes = coninfo.wAttributes; + ScrollConsoleScreenBufferA( hconout, &scrollrect, NULL, + scrolltarget, &chinfo); + + coninfo.dwCursorPosition.X = 0; + coninfo.dwCursorPosition.Y = 0; + + SetConsoleCursorPosition( hconout, coninfo.dwCursorPosition ); + return(TRUE); +} + +/* + * Display the Last Login Time + */ +int LastLoginTimeHandler(char *lpParam) +{ + BYTE dataBuffer[128]; + unsigned char moreFlag; + unsigned char propertyType; + + if ( fNDS ) + { + nwShowLastLoginTime(); + } + else + { + NWReadPropertyValue ((NWCONN_HANDLE)CONNECTION_ID, + LOGIN_NAME, + OT_USER, + "MISC_LOGIN_INFO", + 1, + dataBuffer, + &moreFlag, + &propertyType); + /* + * 0 = year + * 1 = month + * 2 = day + * 3 = hour + * 4 = minute + * 5 = second + */ + + if ( dataBuffer[3] >= 12 ) + { + DisplayMessage( IDR_LASTLOGIN_PM, + dataBuffer[1], + dataBuffer[2], + dataBuffer[0], + dataBuffer[3] - 12, + dataBuffer[4], + dataBuffer[5] ); + } + else + { + DisplayMessage( IDR_LASTLOGIN_AM, + dataBuffer[1], + dataBuffer[2], + dataBuffer[0], + dataBuffer[3], + dataBuffer[4], + dataBuffer[5] ); + } + } + + return(TRUE); +} + + + +/* + * Change and/or display the current context. + */ +int ContextHandler (char *lpParam) +{ + unsigned char Buffer[MAXLEN]; + unsigned char * ptr; + unsigned char CurrentContext[MAXLEN]; + + if ( *lpParam ) + { + NotQuotedStringTranslate(lpParam, TRUE); + + ptr = RemoveSpaces (lpParam); + + if ( NDSCanonicalizeName( lpParam, Buffer, MAXLEN, TRUE ) ) + { + DisplayMessage(IDR_CHANGE_CONTEXT_ERROR, lpParam); + return(TRUE); + } + + if ( NDSChangeContext( Buffer ) ) + { + DisplayMessage(IDR_CHANGE_CONTEXT_ERROR, lpParam); + return(TRUE); + } + } + + if ( NDSGetContext( CurrentContext, MAXLEN ) ) + { + DisplayMessage(IDR_GET_CONTEXT_ERROR); + } + else + { + DisplayMessage(IDR_DISPLAY_CONTEXT, CurrentContext); + } + return(TRUE); +} + +/* + * Do nothing. Return TRUE so the the command will not + * be considered as bad. + */ +int ScriptServerHandler (char *lpParam) +{ + return(TRUE); +} + +/* + * If this is a 4X login, do not execute the default login script. + */ +int NoDefaultHandler (char *lpParam) +{ + if ( fNDS ) + fNoDefaultLoginScript = TRUE; + return(TRUE); +} + +/* + * Do nothing. Return TRUE so the the command will not + * be considered as bad. + */ +int NullHandler (char *lpParam) +{ + return(TRUE); +} + +#define NUMBER_ARGUMENTS 20 + +/* + * External commands start with '#', such as #command /c cls + */ +void ExternalCmdHandler (char *lpCommand) +{ + int n; + int i; + unsigned int CommandLength; + char *lpCmdName, *argv[NUMBER_ARGUMENTS]; + + for ( n = 0; n < NUMBER_ARGUMENTS; n++ ) + argv[n] = NULL; + + if ((nCondIndex == -1) || aCondVal[nCondIndex]) + { + //Convert variables first. + NotQuotedStringTranslate(lpCommand, FALSE); + + lpCommand = RemoveSpaces(lpCommand+1); + lpCmdName = strtok (lpCommand, __SPACES__); + + lpCmdName = NTNWtoUNCFormat(lpCmdName); + + argv[0] = lpCmdName; + + for (n = 1; n < NUMBER_ARGUMENTS - 1; n++) + { + if ((argv[n] = strtok (NULL, __SPACES__)) == NULL) + break; + } + + argv[9] = NULL; + + /* + * Capture command + */ + CommandLength = strlen( lpCommand ); + + /* + * First see if a COMMAND.COM is invoked + */ + if ( ( ( CommandLength >= strlen("COMMAND.COM") ) && + ( !_stricmp( &lpCommand[CommandLength-strlen("COMMAND.COM")], "COMMAND.COM") ) ) || + ( ( CommandLength >= strlen("COMMAND") ) && + ( !_stricmp( &lpCommand[CommandLength-strlen("COMMAND")], "COMMAND") ) ) ) + { + /* + * Search for the CAPTURE argument + */ + for ( i = 1; i < n; i++ ) + { + CommandLength = strlen( argv[i] ); + if ( ( ( CommandLength >= strlen("CAPTURE.EXE") ) && + ( !_stricmp( &(argv[i])[CommandLength-strlen("CAPTURE.EXE")], "CAPTURE.EXE") ) ) || + ( ( CommandLength >= strlen("CAPTURE") ) && + ( !_stricmp( &(argv[i])[CommandLength-strlen("CAPTURE")], "CAPTURE") ) ) ) { + Capture( argv + i, n - i ); + return; + } + } + } + else + { + /* + * Is this a CAPTURE command? + */ + if ( ( ( CommandLength >= strlen("CAPTURE.EXE") ) && + ( !_stricmp( &lpCommand[CommandLength-strlen("CAPTURE.EXE")], "CAPTURE.EXE") ) ) || + ( ( CommandLength >= strlen("CAPTURE") ) && + ( !_stricmp( &lpCommand[CommandLength-strlen("CAPTURE")], "CAPTURE") ) ) ) { + Capture( argv, n ); + return; + } + } + + if ((SCRIPT_ERROR = _spawnvp (P_WAIT, lpCmdName, argv)) == -1) + { + if (errno == ENOENT) + DisplayMessage(IDR_ENOENT, lpCommand); + else + DisplayMessage(IDR_CANNOT_EXECUTE, lpCommand); + } + } +} + +/* + * Printe out the bad command line. + */ +void BadCommandHandler (char *lpCommand) +{ + DisplayMessage(IDR_SCRIPT_ERROR); + DisplayMessage(IDR_ORIGINAL_LINE_WAS, lpCommand); +} + + +/* + * Swap the object id. + */ +DWORD SwapLong(DWORD number) +{ + BYTE *p, tmp[4]; + + p = (BYTE *)&number; + + tmp[0] = p[3]; + tmp[1] = p[2]; + tmp[2] = p[1]; + tmp[3] = p[0]; + + return(*(DWORD *)tmp); +} + +/* + * Remove leading spaces, including tabs. + */ +char *RemoveSpaces (char * buffer) +{ + while (*buffer == ' ' || *buffer == '\t') + buffer++; + return(buffer); +} + +/* + * Return TRUE if buffer points to the end of the lind, FALSE otherwise. + */ +int EndOfLine (char *buffer) +{ + int fEndOfLine = FALSE; + + buffer = RemoveSpaces (buffer); + + if (*buffer == '\0' || + *buffer == ';' || + *buffer == '*' || + *buffer == '\r') + fEndOfLine = TRUE; + + return(fEndOfLine); +} + +/* + * Return TRUE if lpParam points to "ON", FALSE otherwise. + */ +int IsOn (char *lpParam) +{ + int fOn = FALSE; + + if (!strncmp (lpParam, "ON", 2)) + { + lpParam += 2; + fOn = EndOfLine (lpParam); + } + + return(fOn); +} + +/* + * Return TRUE if lpParam points to "OFF", FALSE otherwise. + */ +int IsOff (char *lpParam) +{ + int fOff = FALSE; + + if (!strncmp (lpParam, "OFF", 3)) + { + lpParam += 3; + fOff = EndOfLine (lpParam); + } + + return(fOff); +} + +/* + * Used by VarTranslate(). + * Copy to buffer the value of time variable specified by index. + */ +void GetTime (char *buffer, int index) +{ + time_t currentTime; + struct tm *tmCurrentTime; + + time (¤tTime); + tmCurrentTime = localtime(¤tTime); + + switch (index) + { + case IDS_DAY: + sprintf (buffer, "%02d\0", tmCurrentTime->tm_mday); + break; + case IDS_DAY_OF_WEEK: + strcpy (buffer, __Day__[tmCurrentTime->tm_wday]); + break; + case IDS_MONTH: + sprintf (buffer, "%02d\0", tmCurrentTime->tm_mon+1); + break; + case IDS_MONTH_NAME: + strcpy (buffer, __Month__[tmCurrentTime->tm_mon]); + break; + case IDS_NDAY_OF_WEEK: + sprintf (buffer, "%d\0", tmCurrentTime->tm_wday+1); + break; + case IDS_SHORT_YEAR: + sprintf (buffer, "%04d\0", tmCurrentTime->tm_year+1900); + strcpy (buffer, buffer+2); + break; + case IDS_YEAR: + sprintf (buffer, "%04d\0", tmCurrentTime->tm_year+1900); + break; + case IDS_AM_PM: + strcpy (buffer, __AMPM__[tmCurrentTime->tm_hour > 12? 1:0]); + break; + case IDS_GREETING_TIME: + if (tmCurrentTime->tm_hour >= 6 && tmCurrentTime->tm_hour < 12) + index=0; + else if (tmCurrentTime->tm_hour >= 12 && tmCurrentTime->tm_hour < 18) + index=1; + else + index=2; + + strcpy (buffer, __GREETING__[index]); + break; + case IDS_HOUR: + if (tmCurrentTime->tm_hour > 12) + tmCurrentTime->tm_hour -= 12; + sprintf (buffer, "%d\0", tmCurrentTime->tm_hour); + break; + case IDS_HOUR24: + sprintf (buffer, "%02d\0", tmCurrentTime->tm_hour); + break; + case IDS_MINUTE: + sprintf (buffer, "%02d\0", tmCurrentTime->tm_min); + break; + case IDS_SECOND: + sprintf (buffer, "%02d\0", tmCurrentTime->tm_sec); + break; + default: + *buffer = 0; + } +} + +/* + * Used by VarTranslate(). + * Copy to buffer login user's full name. + */ +void GetFullName (char *buffer) +{ + unsigned int iRet = 0; + unsigned char moreFlag; + unsigned char propertyType; + + if ( fNDS ) + { + NDSGetVar ( "Full Name", buffer, 128 ); + if ( buffer[0] == '\0' ) + strcpy (buffer, "* Unknown *"); + } + else + { + iRet = NWReadPropertyValue ((NWCONN_HANDLE)CONNECTION_ID, + LOGIN_NAME, + OT_USER, + "IDENTIFICATION", + 1, + buffer, + &moreFlag, + &propertyType); + if (iRet) + strcpy (buffer, "* Unknown *"); + } +} + +/* + * Used by VarTranslate(). + * Copy to buffer login user's object id. + */ +void GetUserID (char *buffer) +{ + unsigned long dwObjectID = 0; + + if ( fNDS ) + dwObjectID = GUserObjectID; + else + NTGetUserID( CONNECTION_ID, &dwObjectID ); + sprintf (buffer, "%lx\0", SwapLong(dwObjectID)); + _strupr (buffer); +} + +unsigned int GetDays (unsigned int year, BYTE month, BYTE date) +{ + unsigned int i, days = 0; + + for (i = 1; i < month; i++) + { + if (i == 2) + days += (year%4)? 28 : 29; + else if (i == 4 || i == 6 || i == 9 || i == 11) + days += 30; + else + days += 31; + } + + days += date; + return(days); +} + +/* + * Used by VarTranslate(). + * Copy to buffer the days in which the password expires. + */ +void GetPasswordExpires (char *buffer) +{ + unsigned int iRet = 0; + unsigned int iRet2 = 0; + unsigned char moreFlag; + unsigned int yearCurrent, yearEnd, days; + BYTE monthCurrent, dayCurrent, monthEnd, dayEnd; + unsigned int exptime, logintime; + unsigned char propertyType; + + + if ( fNDS ) + { + iRet = NDSGetUserProperty ("Password Expiration Time", (PBYTE)&exptime, + 4, NULL, NULL); + iRet2 = NDSGetUserProperty ("Login Time", (PBYTE)&logintime, + 4, NULL, NULL); + + if ( ( exptime && logintime ) && !iRet && !iRet2 ) + { + if ( exptime <= logintime ) + strcpy( buffer, "0" ); + else + sprintf( buffer, "%u", ((exptime-logintime)/(60*60*24)) + 1 ); + } + else + { + sprintf( buffer, "%u", 0x7FFF ); + } + } + else + { + NTGetTheDate( &yearCurrent, &monthCurrent, &dayCurrent ); + NWReadPropertyValue ((NWCONN_HANDLE)CONNECTION_ID, + LOGIN_NAME, + OT_USER, + "LOGIN_CONTROL", + 1, + buffer, + &moreFlag, + &propertyType); + + yearEnd = 1900 + buffer[4]; + monthEnd = buffer[5]; + dayEnd = buffer[6]; + + if (monthEnd == 0) + days = (((yearCurrent%4)? 365 : 366) - GetDays (yearCurrent, monthCurrent, dayCurrent)); + else if (yearEnd == yearCurrent) + { + if (monthEnd < monthCurrent || + (monthEnd == monthCurrent && dayEnd <= dayCurrent)) + days = 0; + else + days = GetDays (yearEnd, monthEnd, dayEnd) - GetDays (yearCurrent, monthCurrent, dayCurrent) - 1; + } + else + days = ((yearCurrent%4)? 364 : 365) + GetDays (yearEnd, monthEnd, dayEnd) - GetDays (yearCurrent, monthCurrent, dayCurrent); + + sprintf (buffer, "%u", days); + } +} + +/* + * Used by VarTranslate(). + * Copy to buffer value of the dos environment variable. + * If the variable is not found, buffer is set to be empty string. + */ +void GetDosEnv (char *buffer) +{ + char *lpTemp; + + // This could be called from "%" where x is not upcase. capitalize + // the string first to be sure. + _strupr(buffer); + + lpTemp = strchr (buffer, '>'); + *lpTemp = 0; + + lpTemp = getenv (buffer+1); + + if (lpTemp && strlen (lpTemp) < MAXLEN ) + strcpy (buffer, lpTemp); + else + *buffer = 0; +} + +/* + * Used by VarTranslate(). + * Copy to buffer the 8 bytes network address. + */ +void GetNetWorkAddr (char *buffer) +{ + unsigned char internetAddress[10]; + + GetInternetAddress (CONNECTION_ID, + CONNECTION_NUMBER, + internetAddress); + + sprintf (buffer, + "%02X%02X%02X%02X\0", + internetAddress[0], + internetAddress[1], + internetAddress[2], + internetAddress[3] ); +} + + +/* + * Used by VarTranslate(). + * Copy to buffer the 12 bytes node address to buffer. + */ +void GetPStation (char *buffer) +{ + unsigned char internetAddress[10]; + + GetInternetAddress (CONNECTION_ID, + CONNECTION_NUMBER, + internetAddress); + + sprintf (buffer, + "%02X%02X%02X%02X%02X%02X\0", + internetAddress[4], + internetAddress[5], + internetAddress[6], + internetAddress[7], + internetAddress[8], + internetAddress[9]); +} + +/* + * Used by VarTranslate(). + * Copy to buffer the decimal string representing the remaining account + * balance + */ +void GetAccountBalance (char *buffer) +{ + DWORD balance; + BYTE dataBuffer[128]; + unsigned char moreFlag; + unsigned char propertyType; + unsigned int err; + + if ( fNDS ) + { + err = NDSGetUserProperty ("Account Balance", dataBuffer,128, NULL, NULL); + } + else + { + err = NWReadPropertyValue ((NWCONN_HANDLE)CONNECTION_ID, + LOGIN_NAME, + OT_USER, + "ACCOUNT_BALANCE", + 1, + dataBuffer, + &moreFlag, + &propertyType); + } + + if ( err ) + balance = 0; + else + balance = *((DWORD *)dataBuffer); + + sprintf (buffer, "%d", balance); +} + +/* + * Used by VarTranslate(). + * Copy to buffer MACHINE, SMACHINE, OS, OS_VERSION or SHELL_TYPE + * to buffer according to index. + */ +void GetShellVersion(char *buffer, int index) +{ + static char szTemp[40]; + char *lpTemp; + BYTE shellmajor, shellminor, shellnum; + + NTGetVersionOfShell( szTemp, &shellmajor, &shellminor, &shellnum ); + + lpTemp = szTemp; + + switch (index) + { + case IDS_OS: + strcpy (buffer, lpTemp); + break; + case IDS_OS_VERSION: + lpTemp += (strlen (lpTemp)+1); + strcpy (buffer, lpTemp); + break; + case IDS_MACHINE: + lpTemp += (strlen (lpTemp)+1); + lpTemp += (strlen (lpTemp)+1); + strcpy (buffer, lpTemp); + break; + case IDS_SMACHINE: + lpTemp += (strlen (lpTemp)+1); + lpTemp += (strlen (lpTemp)+1); + lpTemp += (strlen (lpTemp)+1); + strcpy (buffer, lpTemp); + break; + case IDS_SHELL_TYPE: + case IDS_SHELL_VERSION: + sprintf (buffer, "V%d.%d%d%c", shellmajor, shellminor/10, shellminor%10, 'A'+shellnum); + break; + default: + *buffer = 0; + break; + } +} + +void GetArgv(char *buffer) +{ + int n; + + n = atoi (buffer)+nGlobalShiftDelta; + + if (n == 0) + strcpy (buffer, PREFERRED_SERVER); + else if (n == 1) + strcpy (buffer, LOGIN_NAME); + else if (n > 1 && n < ARGC) + strcpy (buffer, ARGV[n]); + else + *buffer = 0; +} + +/* + * vartext is an array of size MAXLEN. + * vartext points to a string starts with a variable on enter. + * vartext stores the value of the variable on exit. + * Return the lenth of the variable. + */ +int VarTranslate(char *vartext) +{ + int i, nVarLen = 0; + + for (i = 0; i < (fNDS ? NUMVAR : NUMVAR_3X); i++) + { + if (!nwVarNameCompare(vartext, varTable[i].VarName)) + { + nVarLen = strlen(varTable[i].VarName); + + switch ( i ) + { + case IDS_DAY_OF_WEEK: + case IDS_DAY: + case IDS_MONTH_NAME: + case IDS_MONTH: + case IDS_NDAY_OF_WEEK: + case IDS_SHORT_YEAR: + case IDS_YEAR: + case IDS_AM_PM: + case IDS_GREETING_TIME: + case IDS_HOUR24: + case IDS_HOUR: + case IDS_MINUTE: + case IDS_SECOND: + GetTime (vartext, i); + break; + case IDS_FULL_NAME: + GetFullName (vartext); + break; + case IDS_LOGIN_NAME: + strcpy (vartext, LOGIN_NAME); + /* + * 4X LOGIN.EXE always truncates and replaces spaces + * with underscores. There was a report that some + * versions of 3X LOGIN.EXE do this also. + */ + if ( fNDS ) + { + int i; + vartext[8] = '\0'; + for ( i = 0; i < 8; i++ ) + if ( vartext[i] == ' ' ) + vartext[i] = '_'; + } + break; + case IDS_USER_ID: + GetUserID (vartext); + break; + case IDS_PASSWORD_EXPIRES: + GetPasswordExpires (vartext); + break; + case IDS_NETWORK_ADDRESS: + case IDS_NETWORK: + GetNetWorkAddr (vartext); + break; + case IDS_FILE_SERVER: + strcpy (vartext, PREFERRED_SERVER); + break; + case IDS_ACCESS_SERVER: + case IDS_ACCESS: + strcpy (vartext, "0"); + break; + case IDS_ERROR_LEVEL: + case IDS_ERRORLEVEL: + sprintf (vartext, "%u", SCRIPT_ERROR); + break; + case IDS_MACHINE: + case IDS_OS_VERSION: + case IDS_OS: + case IDS_SMACHINE: + case IDS_SHELL_TYPE: + case IDS_SHELL_VERSION: + GetShellVersion (vartext, i); + break; + case IDS_STATION: + sprintf (vartext, "%d", CONNECTION_NUMBER); + break; + case IDS_P_STATION: + GetPStation (vartext); + break; + case IDS_LAST_NAME: + case IDS_SURNAME: + strcpy (vartext, LAST_NAME); + break; + case IDS_LOGIN_CONTEXT: + strcpy (vartext, LOGIN_CONTEXT); + break; + case IDS_NETWARE_REQUESTER: + case IDS_REQUESTER_VERSION: + case IDS_DOS_REQUESTER: + case IDS_REQUESTER: + strcpy (vartext, REQUESTER_VERSION); + break; + case IDS_REQUESTER_CONTEXT: + strcpy (vartext, REQUESTER_CONTEXT); + break; + case IDS_ACCOUNT_BALANCE: + GetAccountBalance (vartext); + break; + case IDS_CN: + strcpy (vartext, COMMON_NAME); + break; + case IDS_HOME_DIRECTORY: + { + char buffer[MAXLEN]; + + vartext[0] = '\0'; + NDSGetVar ( varTable[i].VarName, buffer, MAXLEN ); + if ( buffer[0] ) + ConverNDSPathToNetWarePathA( buffer, NULL, vartext ); + } + break; + case IDS_ADMINISTRATIVE_ASSISTANT: + case IDS_ALLOW_UNLIMITED_CREDIT: + case IDS_DESCRIPTION: + case IDS_EMAIL_ADDRESS: + case IDS_EMPLOYEE_ID: + case IDS_FACSIMILE_TELEPHONE_NUMBER: + case IDS_GROUP_MEMBERSHIP: + case IDS_HIGHER_PRIVILEGES: + case IDS_INITIALS: + case IDS_LANGUAGE: + case IDS_LOCKED_BY_INTRUDER: + case IDS_LOGIN_DISABLED: + case IDS_LOGIN_GRACE_LIMIT: + case IDS_LOGIN_GRACE_REMAINING: + case IDS_LOGIN_INTRUDER_ATTEMPTS: + case IDS_LOGIN_MAXIMUM_SIMULTANEOUS: + case IDS_MAILSTOP: + case IDS_MESSAGE_SERVER: + case IDS_MINIMUM_ACCOUNT_BALANCE: + case IDS_OBJECT_CLASS: + case IDS_OU: + case IDS_PASSWORD_ALLOW_CHANGE: + case IDS_PASSWORD_MINIMUM_LENGTH: + case IDS_PASSWORD_REQUIRED: + case IDS_PASSWORD_UNIQUE_REQUIRED: + case IDS_PASSWORDS_USED: + case IDS_PHYSICAL_DELIVERY_OFFICE_NAME: + case IDS_POSTAL_ADDRESS: + case IDS_POSTAL_CODE: + case IDS_POSTAL_OFFICE_BOX: + case IDS_PRIVATE_KEY: + case IDS_PROFILE: + case IDS_REVISION: + case IDS_SECURITY_EQUALS: + case IDS_SECURITY_FLAGS: + case IDS_SEE_ALSO: + case IDS_SERVER_HOLDS: + case IDS_SUPERVISOR: + case IDS_TELEPHONE_NUMBER: + case IDS_TITLE: + case IDS_CERTIFICATE_VALIDITY_INTERVAL: + case IDS_EQUIVALENT_TO_ME: + case IDS_GENERATIONAL_QUALIFIER: + case IDS_GIVEN_NAME: + case IDS_MAILBOX_ID: + case IDS_MAILBOX_LOCATION: + case IDS_PROFILE_MEMBERSHIP: + case IDS_SA: + case IDS_S: + case IDS_L: + NDSGetVar ( varTable[i].VarName, vartext, MAXLEN ); + break; + } + return(nVarLen); + } + } + + if (isdigit(*vartext)) + { + while (isdigit(vartext[nVarLen])) + nVarLen++; + GetArgv(vartext); + } + else if (*vartext == '<') + { + nVarLen = 1; + while (vartext[nVarLen] != '>' && vartext[nVarLen] != 0) + { + if (IsDBCSLeadByte(vartext[nVarLen])) + nVarLen++; + nVarLen++; + } + + if (vartext[nVarLen] == 0) + nVarLen = 0; + else + { + nVarLen++; + GetDosEnv (vartext); + } + } + + return(nVarLen); +} + +/* + * Parse path string. + * If find the %variable value, replace it, otherwise keep as it is. + */ +void NotQuotedStringTranslate(char *buf, BOOL Remove_dbs) +{ + char *pPercentSign, *pRest, vartext[MAXLEN]; + int nVarLen, nInsertlen; + + if ( Remove_dbs ) + { + // Convert \\ to \. + pRest = buf; + for (pRest = buf; *pRest; pRest = NWAnsiNext(pRest)) + { + if (*pRest == '\\' && *(pRest+1) == '\\') + memmove (pRest, pRest+1, strlen (pRest)); + } + } + + // Convert variables following '%' sign. + pRest = buf; + while (pPercentSign = strchr(pRest, '%')) + { + pRest = pPercentSign+1; + + strcpy (vartext, pRest); + + nVarLen = VarTranslate(vartext); + + if (nVarLen == 0) + continue; + + nInsertlen = strlen (vartext); + if (strlen (buf) + nInsertlen - nVarLen < MAXLEN) + { + pRest = pPercentSign+1+nVarLen; + + memmove (pPercentSign+nInsertlen, pRest, strlen (pRest)+1); + memmove (pPercentSign, vartext, nInsertlen); + pRest = pPercentSign+nInsertlen; + } + } +} + +/* + * Used by QuotedStringTranslate() + * On enter, *ppTemp point to a variable, on exit *ppTemp points to the + * charecter next to the variable. *ppBuffer points to the end of the + * value of the variable. + */ +int DoVarTranslate (char **ppTemp, char **ppBuffer, unsigned int nMaxLen, int fInquotes) +{ + int nVarLen; + char vartext[MAXLEN]; + + strcpy (vartext, *ppTemp); + + nVarLen = VarTranslate (vartext); + + if (nVarLen != 0) + { + if (strlen(vartext) >= nMaxLen) + return(FALSE); + + strcpy (*ppBuffer, vartext); + (*ppBuffer) = (*ppBuffer) + strlen (vartext); + (*ppTemp) += nVarLen; + } + else if (fInquotes) + { + strcpy (*ppBuffer, "%"); + (*ppBuffer) += 1; + } + else + return(FALSE); + + return(TRUE); +} + +/* + * Used by QuotedStringTranslate() + * On entry, *(*ppTemp -1) is '\', if **ppTemp is one of those special + * characters, put the value in **ppBuffer, otherwise copy '\\\ and + * whatever is in *ppBuffer to *ppBuffer. + */ +void TranslateSpecialChar (char **ppTemp, char **ppBuffer) +{ + (*ppTemp)++; + + if (**ppTemp == '\\') + **(ppBuffer) = '\\'; + else if (**ppTemp == 'n') + **(ppBuffer) ='\n'; + else if (**ppTemp == 'r') + **(ppBuffer) ='\r'; + else if (**ppTemp == '\"') + **(ppBuffer) ='\"'; + else if (**ppTemp == '7') + **(ppBuffer) ='\7'; + else + { + **(ppBuffer) = '\\'; + (*ppBuffer)++; + return; + } + + (*ppBuffer)++; + (*ppTemp)++;; +} + +/* + * Used by QuotedStringTranslate(). + * Return TRUE if there are more interesting strings and it's seperated by ';' + * FALSE otherwise. + */ +int GetNextString (char **ppTemp, int *pfEnd) +{ + int fMore = FALSE; + + (*ppTemp) = RemoveSpaces (*ppTemp); + + *pfEnd = (**ppTemp == 0); + + if (**ppTemp == ';') + { + (*ppTemp) = RemoveSpaces (*ppTemp+1); + fMore = TRUE; + } + + return(fMore); +} + + +int GetLastShiftOp (char *buffer, char *pchOp, char *lpRest) +{ + int i, inquotes = FALSE; + + // NetWare compatibility fix. + // for (i = strlen (buffer)-1; i >= 0; i--) + + for (i = 0; buffer[i]; i++) + { + if (buffer[i] == '\"' && buffer [i-1] != '\\') + inquotes = !inquotes; + if (!inquotes && + ( (buffer[i] == '>' && buffer[i+1] == '>') + ||(buffer[i] == '<' && buffer[i+1] == '<'))) + { + *pchOp = buffer[i]; + buffer[i] = 0; + strcpy (lpRest, RemoveSpaces(buffer+i+2)); + return(TRUE); + } + } + + return(FALSE); +} +int GetLastAddOp (char *buffer, char *pchOp, char *lpRest) +{ + int i, inquotes = FALSE; + + // NetWare compatibility fix. + // for (i = strlen (buffer)-1; i >= 0; i--) + + for (i = 0; buffer[i]; i++) + { + if (buffer[i] == '\"' && buffer [i-1] != '\\') + inquotes = !inquotes; + if (!inquotes && + (buffer[i] == '+' || buffer[i] == '-') ) + { + *pchOp = buffer[i]; + buffer[i] = 0; + strcpy (lpRest, RemoveSpaces(buffer+i+1)); + return(TRUE); + } + } + + return(FALSE); +} + +int GetLastMultiplyOp (char *buffer, char *pchOp, char *lpRest) +{ + int i, inquotes = FALSE; + + // NetWare compatibility fix. + // for (i = strlen (buffer)-1; i >= 0; i--) + for (i = 0; buffer[i]; i++) + { + if (buffer[i] == '\"' && buffer [i-1] != '\\') + inquotes = !inquotes; + if (!inquotes && + (buffer[i] == '*' || buffer[i] == '/' || buffer[i] == '%') ) + { + + *pchOp = buffer[i]; + buffer[i] = 0; + strcpy (lpRest, RemoveSpaces(buffer+i+1)); + return(TRUE); + } + } + + return(FALSE); +} + +/* + * Used by QuotedStringTranslate. + * Return TRUE if input buffer is right format, FALSE otherwise. + */ +int SingleStringTranslate (char *buffer) +{ + int inquotes = FALSE, fEnd = FALSE, nShift, nLen; + char szRest[MAXLEN], chOp; + char *lpTemp = szRest, *lpBuffer=buffer; + + buffer = RemoveSpaces (buffer); + + if (GetLastShiftOp (buffer, &chOp, szRest)) + { + if (!QuotedStringTranslate (buffer)) + return(FALSE); + + while (isdigit (*lpTemp)) + lpTemp++; + + if (!EndOfLine(lpTemp)) + return(FALSE); + + *lpTemp = 0; + + nShift = atoi (szRest); + nLen = strlen (buffer); + + if (nShift >= nLen) + *buffer = 0; + else + { + if (chOp == '<') + memmove (buffer, buffer+nShift, nLen-nShift); + + *(buffer+nLen-nShift) = 0; + } + } + else if (GetLastAddOp (buffer, &chOp, szRest)) + { + if (!QuotedStringTranslate (buffer) || + !QuotedStringTranslate (szRest)) + return(FALSE); + + sprintf (buffer, "%d", (chOp == '+')? (atoi (buffer) + atoi (szRest)) + : (atoi (buffer) - atoi (szRest))); + } + else if (GetLastMultiplyOp (buffer, &chOp, szRest)) + { + if (!QuotedStringTranslate (buffer) || + !QuotedStringTranslate (szRest)) + return(FALSE); + + if (chOp == '*') + sprintf (buffer, "%d", atoi (buffer) * atoi (szRest)); + else + { + if (atoi (szRest) == 0) + { + DisplayMessage(IDR_DIVIDE_BY_ZERO); + strcpy (buffer, "0"); + } + else + { + sprintf (buffer, "%d",(chOp == '/')? (atoi (buffer) / atoi (szRest)) + : (atoi (buffer) % atoi (szRest))); + } + } + } + else + { + strcpy (szRest, buffer); + *buffer = 0; + + while (*lpTemp) + { + if (inquotes) + { + if (*lpTemp == '\\') + TranslateSpecialChar (&lpTemp, &buffer); + else if (*lpTemp == '\"') + { + inquotes = !inquotes; + lpTemp++; + if (!GetNextString (&lpTemp, &fEnd)) + break; + } + else if (*lpTemp == '%') + { + lpTemp++; + DoVarTranslate (&lpTemp, &buffer, MAXLEN-(buffer-lpBuffer), TRUE); + } + else + { + *buffer = *lpTemp; + if (IsDBCSLeadByte(*buffer)) + { + buffer++; + lpTemp++; + *buffer = *lpTemp; + } + buffer++; + lpTemp++; + } + } + else + { + if (*lpTemp == '\"') + { + inquotes = !inquotes; + lpTemp++; + } + else + { + if (!DoVarTranslate (&lpTemp, &buffer, MAXLEN-(buffer-lpBuffer), FALSE) || + !GetNextString (&lpTemp, &fEnd)) + break; + } + } + } + if (!fEnd) + { + if ( inquotes ) + DisplayMessage( IDR_NO_END_QUOTE ); + return(FALSE); + } + *buffer = 0; + } + + return(TRUE); +} + +/* + * Replace the variables in the string with their value. + * Use this function when the input string is quoted format. + * Return TRUE if input buffer is right format, FALSE otherwise. + */ +int QuotedStringTranslate (char *buffer) +{ + char szTemp[MAXLEN], *lpLeft, *lpRight, *ptr = buffer, *pNext; + int inquotes; + + lpLeft = *buffer == '('? buffer : NULL; + lpRight = *buffer == ')'? buffer : NULL; + inquotes = (*ptr == '"'); + + while (*ptr) + { + pNext = NWAnsiNext (ptr); + + if (*pNext == '"' && *(ptr) != '\\') + { + pNext++; + inquotes = !inquotes; + } + + ptr = pNext; + + if (!inquotes) + { + if (*ptr == '(') + lpLeft = ptr; + else if (*ptr == ')') + { + lpRight = ptr; + + *lpRight = 0; + + if (lpLeft == NULL) + return(FALSE); + + if (lpRight - lpLeft <= 1) //There should be something in the backets. + return(FALSE); + + *lpLeft = 0; + + strncpy (szTemp, lpLeft+1, lpRight-lpLeft); + + if (!SingleStringTranslate (szTemp)) + return(FALSE); + + if (strlen (buffer) + strlen(szTemp) + strlen (lpRight+1) + 2 >= MAXLEN) + return(FALSE); + + *lpLeft = '"'; + *(lpLeft+1+strlen(szTemp)) = '"'; + memmove (lpLeft+2+strlen(szTemp), lpRight+1, strlen (lpRight+1)+1); + memmove (lpLeft+1, szTemp, strlen(szTemp)); + + lpLeft = *buffer == '('? buffer : NULL; + lpRight = *buffer == ')'? buffer : NULL; + ptr = buffer; + inquotes = (*ptr == '"'); + } + } + } + + if (lpLeft != NULL || lpRight != NULL) + return(FALSE); + return(SingleStringTranslate (buffer)); +} + + +void BreakOff(void) +{ + fBreakOn = FALSE; + + NTBreakOff(); +} + +void BreakOn(void) +{ + fBreakOn = TRUE; + + NTBreakOn(); +} + +/* + * Used by ComspecHandler() and SetHandler() + * Set dos environment variable. + */ +int SetEnv (char *lpEnvLine) +{ + ExportEnv( lpEnvLine ); + return(TRUE); +} diff --git a/private/nw/nwscript/sources b/private/nw/nwscript/sources new file mode 100644 index 000000000..3425d5c96 --- /dev/null +++ b/private/nw/nwscript/sources @@ -0,0 +1,85 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +BLDCRT=1 + +MAJORCOMP=utils +MINORCOMP=nwscript + +C_DEFINES = -DNT=1 -DUNICODE=1 +MSC_WARNING_LEVEL=/W3 /WX + +TARGETNAME=nwscript +TARGETPATH=obj +TARGETTYPE=LIBRARY + +INCLUDES=inc;..\inc;..\..\inc;..\..\..\inc;$(_NTROOT)\private\inc; +#GPSIZE=32 + +SOURCES=capture.c \ + psdb.c \ + ntcap.c \ + helpers.c \ + script.c \ + display.c \ + nwapi1.c \ + nwapi2.c \ + nwapi3.c \ + common.c \ + strings.c \ + ntscript.c \ + dbcs.c \ + parspath.c \ + nt.c \ + ntnw.c \ + drvstat.c \ + env.c \ + break.c \ + attach.c \ + ncp.c \ + drive.c \ + version.c \ + date.c \ + wide.c \ + unc.c \ + nds.c \ + ps40db.c \ + time.c \ + maplist.c \ + lsparse.c \ + nwscript.rc + + +UMTYPE=console +UMAPPL=nwscript +UMLIBS=$(BASEDIR)\Public\Sdk\Lib\*\kernel32.lib \ + $(BASEDIR)\Public\Sdk\Lib\*\user32.lib \ + $(BASEDIR)\Public\Sdk\Lib\*\mpr.lib \ + $(BASEDIR)\Public\Sdk\Lib\*\ntdll.lib \ + $(BASEDIR)\Public\Sdk\Lib\*\nwapi32.lib \ + $(BASEDIR)\Public\Sdk\Lib\*\nwprovau.lib \ + obj\*\nwscript.lib + +UMRES=obj\*\nwscript.res + diff --git a/private/nw/nwscript/strings.c b/private/nw/nwscript/strings.c new file mode 100644 index 000000000..57fb68fab --- /dev/null +++ b/private/nw/nwscript/strings.c @@ -0,0 +1,132 @@ + +/************************************************************************* +* +* STRINGS.C +* +* Various strings +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\STRINGS.C $ +* +* Rev 1.1 22 Dec 1995 14:26:50 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:08:06 terryt +* Initial revision. +* +* Rev 1.1 25 Aug 1995 16:23:56 terryt +* Capture support +* +* Rev 1.0 15 May 1995 19:11:06 terryt +* Initial revision. +* +*************************************************************************/ + +#include "common.h" + +/* + * These haven't been put into resource files, because they aren't user + * messages. Most are control information or variables. To do this + * right, all output and string processing would have to be changed to + * unicode. This can't be done until NetWare and International are + * understood. + */ + + +char *__GREETING__[3] = {"morning", "afternoon", "evening"}; +char *__AMPM__[2] = {"am", "pm"}; +char *__Day__[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; +char *__Month__[12] = {"January", "Feburary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; +char __DEL__[] ="DELETE"; +char __REM__[] ="REMOVE"; +char __INS__[] ="INSERT"; +char __ROOT__[] ="ROOT"; +char __NEXT__[] ="NEXT"; + +/* + * Capture strings + */ +unsigned int CaptureStringsLoaded = FALSE; +WCHAR __DISABLED__[256]; +WCHAR __ENABLED__[256]; +WCHAR __YES__[256]; +WCHAR __NO__[256]; +WCHAR __SECONDS__[256]; +WCHAR __CONVERT_TO_SPACE__[256]; +WCHAR __NO_CONVERSION__[256]; +WCHAR __NOTIFY_USER__[256]; +WCHAR __NOT_NOTIFY_USER__[256]; +WCHAR __NONE__[256]; + +char __JOB_DESCRIPTION__[] ="LPT%d Catch"; + +char __OPT_NO__[] ="No"; + +char __SHOW__[] ="SHOW"; + +char __NOTIFY__[] ="NOTIFY"; +char __SHORT_FOR_NOTIFY__[] ="NOTI"; + +char __NONOTIFY__[] ="NONOTIFY"; +char __SHORT_FOR_NONOTIFY__[]="NNOTI"; + +char __AUTOENDCAP__[] ="AUTOENDCAP"; +char __SHORT_FOR_AUTOENDCAP__[] ="AU"; + +char __NOAUTOENDCAP__[] ="NOAUTOENDCAP"; +char __SHORT_FOR_NOAUTOENDCAP__[] ="NA"; + +char __NOTABS__[] ="NOTABS"; +char __SHORT_FOR_NOTABS__[] ="NT"; + +char __NOBANNER__[] ="NOBANNER"; +char __SHORT_FOR_NOBANNER__[] ="NB"; + +char __FORMFEED__[] ="FORMFEED"; +char __SHORT_FOR_FORMFEED__[] ="FF"; + +char __NOFORMFEED__[] ="NOFORMFEED"; +char __SHORT_FOR_NOFORMFEED__[] ="NFF"; + +char __KEEP__[] ="KEEP"; +char __SHORT_FOR_KEEP__[] ="K"; + +char __TIMEOUT__[] ="TIMEOUT"; +char __SHORT_FOR_TIMEOUT__[] ="TI"; + +char __LOCAL__[] ="LOCAL"; +char __SHORT_FOR_LOCAL__[] ="L"; + +char __LOCAL_3__[] ="LPT"; +char __LOCAL_2__[] ="LP"; + +char __JOB__[] ="JOB"; +char __SHORT_FOR_JOB__[] ="J"; + +char __SERVER__[] ="SERVER"; +char __SHORT_FOR_SERVER__[] ="S"; + +char __QUEUE__[] ="QUEUE"; +char __SHORT_FOR_QUEUE__[] ="Q"; + +char __PRINTER__[] ="PRINTER"; +char __SHORT_FOR_PRINTER__[] ="P"; + +char __CREATE__[] ="CREATE"; +char __SHORT_FOR_CREATE__[] ="CR"; + +char __FORM__[] ="FORM"; +char __SHORT_FOR_FORM__[] ="F"; + +char __COPIES__[] ="COPIES"; +char __SHORT_FOR_COPIES__[] ="C"; + +char __TABS__[] ="TABS"; +char __SHORT_FOR_TABS__[] ="T"; + +char __NAME__[] ="NAME"; +char __SHORT_FOR_NAME__[] ="NAM"; + +char __BANNER__[] ="BANNER"; +char __SHORT_FOR_BANNER__[] ="B"; diff --git a/private/nw/nwscript/time.c b/private/nw/nwscript/time.c new file mode 100644 index 000000000..26639359a --- /dev/null +++ b/private/nw/nwscript/time.c @@ -0,0 +1,184 @@ +/* + * TIME.C - Various time subroutines needed by NetWare Login Script + * + * Copyright (c) 1995 Microsoft Corporation + */ + +#include "common.h" + +// Needed to convert netware net date to DOS date +#define _70_to_80_bias 0x012CEA600L +#define SECS_IN_DAY (60L*60L*24L) +#define SEC2S_IN_DAY (30L*60L*24L) +#define FOURYEARS (3*365+366) + +WORD MonTotal[] = { 0, // dummy entry for month 0 + 0, // days before Jan 1 + 31, // days before Feb 1 + 31+28, // days before Mar 1 + 31+28+31, // days before Apr 1 + 31+28+31+30, // days before May 1 + 31+28+31+30+31, // days before Jun 1 + 31+28+31+30+31+30, // days before Jul 1 + 31+28+31+30+31+30+31, // days before Aug 1 + 31+28+31+30+31+30+31+31, // days before Sep 1 + 31+28+31+30+31+30+31+31+30, // days before Oct 1 + 31+28+31+30+31+30+31+31+30+31, // days before Nov 1 + 31+28+31+30+31+30+31+31+30+31+30, // days before Dec 1 + 31+28+31+30+31+30+31+31+30+31+30+31 // days before end of year +}; + +#define YR_MASK 0xFE00 +#define LEAPYR_MASK 0x0600 +#define YR_BITS 7 +#define MON_MASK 0x01E0 +#define MON_BITS 4 +#define DAY_MASK 0x001F +#define DAY_BITS 5 + +#define HOUR_MASK 0xF800 +#define HOUR_BITS 5 +#define MIN_MASK 0x07E0 +#define MIN_BITS 6 +#define SEC2_MASK 0x001F +#define SEC2_BITS 5 + +static void NetToDosDate( DWORD time, WORD * dosdate, WORD * dostime ) +{ + DWORD secs, days; + WORD r; + + time = (time - _70_to_80_bias) / 2; // # of 2 second periods since 1980 + secs = time % SEC2S_IN_DAY; // 2 second period into day + days = time / SEC2S_IN_DAY; // days since Jan 1 1980 + + r = (WORD) ( secs % 30 ); // # of 2 second steps + secs /= 30; + r |= (secs % 60) << SEC2_BITS; // # of minutes + r |= (secs / 60) << SEC2_BITS+MIN_BITS; // # of hours + *dostime = r; + + r = (WORD) ( days / FOURYEARS );// (r) = four year period past 1980 + days %= FOURYEARS; // (days) = days into four year period + r *= 4; // (r) = years since 1980 (within 3) + + if (days == 31+28) { + //* Special case for FEB 29th + r = (r<<(MON_BITS+DAY_BITS)) + (2< 31+28) + --days; // compensate for leap year + while (days >= 365) { + ++r; + days -= 365; + } + + for (secs = 1; days >= MonTotal[secs+1] ; ++secs) + ; + days -= MonTotal[secs]; + r <<= MON_BITS; + r += (WORD)secs; + r <<= DAY_BITS; + r += (WORD)days+1; + } + *dosdate = r; +} + + +#define TIMEDATE_SIZE 64 + +void nwShowLastLoginTime(VOID) +{ + LONG lTime = 0L; + SYSTEMTIME st; + FILETIME ft; + TIME_ZONE_INFORMATION tz; + WCHAR szTimeBuf[TIMEDATE_SIZE]; + WCHAR szDateBuf[TIMEDATE_SIZE]; + int ret; + WORD dostime, dosdate; + DWORD tzStat; + + if ( ret = NDSGetUserProperty ("Last Login Time", (PBYTE)&lTime, + 4, NULL, NULL) ) + { + #ifdef DEBUG + OutputDebugString("NWLSPROC: error getting LOGIN TIME\n\r"); + #endif + return; + } + + // From NetWare we get seconds from 1970, need to go through + // several conversions to get system time for NLS + + // First deduct bias from UTC time to correct for local time + tzStat = GetTimeZoneInformation(&tz); + if ( tzStat != (DWORD)-1 ) { + if (tzStat == TIME_ZONE_ID_STANDARD) + tz.Bias += tz.StandardBias; + else if (tzStat == TIME_ZONE_ID_DAYLIGHT) + tz.Bias += tz.DaylightBias; + lTime -= tz.Bias*60; + } +#ifdef DEBUG + else { + OutputDebugString("NWLSPROC: GetTimeZoneInformation failed\n\r"); + } +#endif // DEBUG + + NetToDosDate( lTime, &dosdate, &dostime ); + DosDateTimeToFileTime ( dosdate, dostime, &ft ); + FileTimeToSystemTime ( &ft, &st ); + +#ifdef notdef + // I don't understand this comment, this code doesn't seem to be + // needed for NT. - terry + // + // This code will work on NT, but not on Win95. + // Convert the resulting system (UTC) time to local time + if ( GetTimeZoneInformation(&tz) != (DWORD)-1 ) { + SYSTEMTIME utcTime = st; + SystemTimeToTzSpecificLocalTime ( &tz, &utcTime, &st ); + } +#ifdef DEBUG + else { + OutputDebugString("NWLSPROC: GetTimeZoneInformation failed\n\r"); + } +#endif // DEBUG +#endif + + wcscpy(szTimeBuf, L""); + ret = GetTimeFormat ( GetSystemDefaultLCID(), + TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER, + &st, + NULL, + szTimeBuf, + TIMEDATE_SIZE ); +#ifdef DEBUG + if ( !ret ) { + char buf[80]; + wsprintf(buf,"NWLSPROC: GetTimeFormatA failure: %d sec:%ld\n\r", + GetLastError(), lTime ); + OutputDebugString(buf); + } +#endif + ret = GetDateFormat(LOCALE_USER_DEFAULT, + DATE_LONGDATE, + &st, + NULL, + szDateBuf, + TIMEDATE_SIZE ); +#ifdef DEBUG + if ( !ret ) { + char buf[80]; + wsprintf(buf,"NWLSPROC: GetDateFormatA failure: %d sec:%ld\n\r", + GetLastError(), lTime ); + OutputDebugString(buf); + } +#endif + + DisplayMessage( IDR_LASTLOGIN, szDateBuf, szTimeBuf ); +} + + + diff --git a/private/nw/nwscript/unc.c b/private/nw/nwscript/unc.c new file mode 100644 index 000000000..8f99320b9 --- /dev/null +++ b/private/nw/nwscript/unc.c @@ -0,0 +1,142 @@ +/************************************************************************* +* +* UNC.C +* +* NetWare format to UNC format +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\UNC.C $ +* +* Rev 1.4 10 Apr 1996 14:24:00 terryt +* Hotfix for 21181hq +* +* Rev 1.4 12 Mar 1996 19:56:18 terryt +* Relative NDS names and merge +* +* Rev 1.3 04 Jan 1996 18:57:26 terryt +* Bug fixes reported by MS +* +* Rev 1.2 22 Dec 1995 14:27:04 terryt +* Add Microsoft headers +* +* Rev 1.1 22 Dec 1995 11:09:18 terryt +* Fixes +* +* Rev 1.0 15 Nov 1995 18:08:14 terryt +* Initial revision. +* +* Rev 1.1 23 May 1995 19:37:24 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:11:10 terryt +* Initial revision. +* +*************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "inc/common.h" + +/******************************************************************** + + NTNWtoUNCFormat + +Routine Description: + + Given a connection handle and a path, change it to UNC format + if it's in NetWare format. I.E. + + SYS:\usr\terryt ==> \\HELIUM\SYS\usr\terryt + + Don't do the conversion if it's not in NetWare format. + +Arguments: + + ConnectionHandle - Connection Handle + NetWarePath - Input original path + +Return Value: + UNC string + + *******************************************************************/ +char * +NTNWtoUNCFormat( char * NetWarePath ) +{ + static char UNCPath[1024]; + unsigned int Result; + char ServerName[48]; + char * p; + char * q; + + /* + * If it's UNC already, leave it alone + */ + if ( ( NetWarePath[0] == '\\' ) && ( NetWarePath[1] == '\\' ) ) + return NetWarePath; + if ( ( NetWarePath[0] == '/' ) && ( NetWarePath[1] == '/' ) ) + return NetWarePath; + + /* + * if it's drive:dir, leave it alone + */ + if ( NetWarePath[0] && ( NetWarePath[1] == ':' ) ) + return NetWarePath; + + /* + * if it's not volume:dir, leave it alone + */ + p = strchr( NetWarePath, ':' ); + if ( !p ) + return NetWarePath; + + /* + * if slashes before :, it must be a file server + */ + q = strchr( NetWarePath, '\\' ); + if ( q && ( q < p ) ) + { + strcpy( UNCPath, "\\\\" ); + *p = '\0'; + strcat( UNCPath, NetWarePath ); + if (( *(p + 1) != '\\' ) && ( *(p + 1) != '/' ) ) + strcat( UNCPath, "\\" ); + strcat( UNCPath, p + 1 ); + *p = ':'; + return UNCPath; + } + + q = strchr( NetWarePath, '/' ); + if ( q && ( q < p ) ) + { + strcpy( UNCPath, "\\\\" ); + *q = '\\'; + *p = '\0'; + strcat( UNCPath, NetWarePath ); + if (( *(p + 1) != '\\' ) && ( *(p + 1) != '/' ) ) + strcat( UNCPath, "\\" ); + strcat( UNCPath, p + 1 ); + *q = '/'; + *p = ':'; + return UNCPath; + } + + strcpy( UNCPath, "\\\\" ); + strcat( UNCPath, PREFERRED_SERVER ); + strcat( UNCPath, "\\" ); + *p = '\0'; + strcat( UNCPath, NetWarePath ); + if (( *(p + 1) != '\\' ) && ( *(p + 1) != '/' ) ) + strcat( UNCPath, "\\" ); + strcat( UNCPath, p + 1 ); + *p = ':'; + + return UNCPath; +} diff --git a/private/nw/nwscript/version.c b/private/nw/nwscript/version.c new file mode 100644 index 000000000..b4ce000d6 --- /dev/null +++ b/private/nw/nwscript/version.c @@ -0,0 +1,68 @@ +/************************************************************************* +* +* VERSION.C +* +* Shell version information +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\VERSION.C $ +* +* Rev 1.2 10 Apr 1996 14:24:08 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:56:28 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:27:10 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:08:18 terryt +* Initial revision. +* +* Rev 1.1 26 Jul 1995 14:17:24 terryt +* Clean up comments +* +* Rev 1.0 15 May 1995 19:11:12 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nwscript.h" + + +/* + * MSDOS is not neccessarily the best thing to put out, + * maybe Windows_NT, NT or NTDOS. The OS_VERSION is also a problem. + * The script variables don't neccessarily have to match the DOS variables. + * + * The shell version numbers may change with 4.X support. + */ + +#define CLIENT_ID_STRING "MSDOS\0V5.00\0IBM_PC\0IBM" +#define CLIENT_SHELL_MAJOR 0x03 +#define CLIENT_SHELL_MINOR 0x1a +#define CLIENT_SHELL_NUMBER 0x00 + + +void +NTGetVersionOfShell( char * buffer, + unsigned char * shellmajor, + unsigned char * shellminor, + unsigned char * shellnum ) +{ + *shellmajor = CLIENT_SHELL_MAJOR; + *shellminor = CLIENT_SHELL_MINOR; + *shellnum = CLIENT_SHELL_NUMBER; + memcpy( buffer, CLIENT_ID_STRING, 40 ); +} diff --git a/private/nw/nwscript/wide.c b/private/nw/nwscript/wide.c new file mode 100644 index 000000000..09578c7bd --- /dev/null +++ b/private/nw/nwscript/wide.c @@ -0,0 +1,149 @@ +/************************************************************************* +* +* WIDE.C +* +* Wide character translation routines +* +* Copyright (c) 1995 Microsoft Corporation +* +* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\WIDE.C $ +* +* Rev 1.2 10 Apr 1996 14:24:14 terryt +* Hotfix for 21181hq +* +* Rev 1.2 12 Mar 1996 19:56:36 terryt +* Relative NDS names and merge +* +* Rev 1.1 22 Dec 1995 14:27:18 terryt +* Add Microsoft headers +* +* Rev 1.0 15 Nov 1995 18:08:20 terryt +* Initial revision. +* +* Rev 1.1 23 May 1995 19:37:32 terryt +* Spruce up source +* +* Rev 1.0 15 May 1995 19:11:14 terryt +* Initial revision. +* +*************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nwscript.h" + + +/******************************************************************** + + szToWide + +Routine Description: + + Given a single byte character string, convert to wide + +Arguments: + + lpszW - Wide character string returned + lpszC - Single character string input + nSize - length of Wide character buffer + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +DWORD +szToWide( + LPWSTR lpszW, + LPCSTR lpszC, + INT nSize + ) +{ + if (!MultiByteToWideChar(CP_OEMCP, + MB_PRECOMPOSED, + lpszC, + -1, + lpszW, + nSize)) + { + return (GetLastError()) ; + } + + return NO_ERROR ; +} + +/******************************************************************** + + WideTosz + +Routine Description: + + Given a wide character string, convert to single + +Arguments: + + lpszC - Single character string returned + lpszW - Wide character string input + nSize - length of single character buffer + +Return Value: + 0 = success + else NT error + + *******************************************************************/ +DWORD +WideTosz( + LPSTR lpszC, + LPWSTR lpszW, + INT nSize + ) +{ + if (!WideCharToMultiByte(CP_OEMCP, + 0, + (LPCWSTR) lpszW, + -1, + lpszC, + nSize, + NULL, + NULL)) + { + return (GetLastError()) ; + } + + return NO_ERROR ; +} + +/******************************************************************** + + ConvertUnicodeToAscii + +Routine Description: + + Given a wide character string, convert to single + +Arguments: + + Buffer - buffer to be converted + +Return Value: + none + + *******************************************************************/ +void +ConvertUnicodeToAscii( PVOID Buffer ) +{ + LPCWSTR lpszW = Buffer; + BYTE Destination[1024]; + + WideTosz( (LPSTR)Destination, (LPWSTR)Buffer, 1024 ); + + strcpy( Buffer, Destination ); +} -- cgit v1.2.3