/********************************************************************/ /** Microsoft LAN Manager **/ /** Copyright(c) Microsoft Corp., 1987-1990 **/ /********************************************************************/ /* * MSNET - a command processor for MSNET 3.0. * The command grammar is specified in msnet.x * * History * * ??/??/??, ??????, initial code * 10/31/88, erichn, uses OS2.H instead of DOSCALLS * 05/02/89, erichn, NLS conversion * 06/08/89, erichn, canonicalization sweep, no LONGer u-cases input * 02/15/91, danhi, convert to be 16/32 portable * 10/16/91, JohnRo, added DEFAULT_SERVER support. */ /* #define INCL_NOCOMMON */ #include #include #include #include #include #include #include #include "netcmds.h" #include "nettext.h" #include "msystem.h" #include "locale.h" #define _SHELL32_ #include static VOID init(VOID); VOID call_net1(VOID) ; TCHAR * ArgList[LIST_SIZE] = {0}; SHORT ArgPos[LIST_SIZE] = {0}; TCHAR * SwitchList[LIST_SIZE] = {0}; SHORT SwitchPos[LIST_SIZE] = {0}; /* Insertion strings for InfoMessage() */ TCHAR FAR * IStrings[10] = {0}; TCHAR FAR * StarStrings[10] = {TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***"), TEXT("***")}; /* 1 is /Yes, 2 is /No */ SHORT YorN_Switch = 0; TCHAR ** MyArgv; /* argv */ UINT SavedArgc = 0 ; CHAR ** SavedArgv = NULL ; /* Buffers for APIs to use */ TCHAR Buffer[LITTLE_BUF_SIZE]; /* For GetInfo's, etc.*/ TCHAR BigBuffer[BIG_BUF_SIZE]; /* For Enum's */ TCHAR FAR * BigBuf = BigBuffer; // // Globals for standard console handles // HANDLE g_hStdOut; HANDLE g_hStdErr; /*** * MAIN - Seperate the command line into switches and arguments. * Then call the parser, which will dispatch the command and * report on error conditions. Allocate the BigBuf. */ VOID os2cmd(VOID); CPINFO CurrentCPInfo; VOID __cdecl main(int argc, CHAR **argv) { SHORT sindex, aindex; SHORT pos=0; DWORD cp; CHAR achCodePage[12] = ".OCP"; // '.' + UINT in decimal + '\0' SavedArgc = argc ; SavedArgv = argv ; /* Added for bilingual message support. This is needed for FormatMessage to work correctly. (Called from DosGetMessage). Get current CodePage Info. We need this to decide whether or not to use half-width characters. */ cp = GetConsoleOutputCP(); GetCPInfo(cp, &CurrentCPInfo); switch ( cp ) { case 932: case 936: case 949: case 950: SetThreadLocale( MAKELCID( MAKELANGID( PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_ENGLISH_US ), SORT_DEFAULT ) ); break; default: SetThreadLocale( MAKELCID( MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ), SORT_DEFAULT ) ); break; } if (cp) { sprintf(achCodePage, ".%u", cp); } setlocale(LC_ALL, achCodePage); g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); if (g_hStdOut == INVALID_HANDLE_VALUE) { ErrorExit(GetLastError()); } g_hStdErr = GetStdHandle(STD_ERROR_HANDLE); if (g_hStdErr == INVALID_HANDLE_VALUE) { ErrorExit(GetLastError()); } MyArgv = CommandLineToArgvW(GetCommandLineW(), &argc); if (MyArgv == NULL) { ErrorExit(ERROR_NOT_ENOUGH_MEMORY) ; } /* seperate switches and arguments */ ++MyArgv; for (sindex = 0, aindex = 0; --argc; ++MyArgv, ++pos) { if (**MyArgv == SLASH) { SHORT arglen; SHORT arg_is_special = 0; arglen = (SHORT) _tcslen(*MyArgv); if (arglen > 1) { if ( _tcsnicmp(swtxt_SW_YES, (*MyArgv), arglen) == 0 ) { if (YorN_Switch == NO) ErrorExit(APE_ConflictingSwitches); arg_is_special = 1; YorN_Switch = YES; } else if ( _tcsnicmp(swtxt_SW_NO, (*MyArgv), arglen) == 0 ) { if (YorN_Switch == YES) ErrorExit(APE_ConflictingSwitches); arg_is_special = 1; YorN_Switch = NO; } } if ( ! arg_is_special ) { if (sindex >= LIST_SIZE) ErrorExit(APE_NumArgs) ; SwitchList[sindex] = *MyArgv; SwitchPos[sindex] = pos; sindex++; } } else { if (aindex >= LIST_SIZE) ErrorExit(APE_NumArgs) ; ArgList[aindex] = *MyArgv; ArgPos[aindex] = pos; aindex++; } } // register as locations to zero out on exit AddToMemClearList(BigBuffer, sizeof(BigBuffer), FALSE) ; AddToMemClearList(Buffer, sizeof(Buffer),FALSE) ; init(); os2cmd(); NetcmdExit(0); } static VOID NEAR init(VOID) { _setmode(_fileno(stdin), O_TEXT); } /*** * M y E x i t * * Wrapper around C runtime that cleans up memory for security reasons. */ VOID DOSNEAR FASTCALL MyExit(int Status) { ClearMemory() ; exit(Status); } typedef struct _MEMOMY_ELEMENT { LPBYTE lpLocation ; struct _MEMORY_ELEMENT *lpNext ; UINT nSize ; BOOL fDelete ; } MEMORY_ELEMENT, *LPMEMORY_ELEMENT ; LPMEMORY_ELEMENT lpToDeleteList = NULL ; /*** * AddToMemClearList * * add an entry to list of things to clear */ VOID AddToMemClearList( VOID *lpBuffer, UINT nSize, BOOL fDelete ) { LPMEMORY_ELEMENT lpNew, lpTmp ; DWORD err ; if (err = AllocMem(sizeof(MEMORY_ELEMENT),(LPBYTE *) &lpNew)) { ErrorExit(err); } lpNew->lpLocation = (LPBYTE) lpBuffer ; lpNew->nSize = nSize ; lpNew->fDelete = fDelete ; lpNew->lpNext = NULL ; if (!lpToDeleteList) { lpToDeleteList = lpNew ; } else { lpTmp = lpToDeleteList ; while (lpTmp->lpNext) lpTmp = (LPMEMORY_ELEMENT) lpTmp->lpNext ; lpTmp->lpNext = (struct _MEMORY_ELEMENT *) lpNew ; } } /*** * ClearMemory() * * go thru list of things to clear, and clear them. */ VOID ClearMemory(VOID) { LPMEMORY_ELEMENT lpList, lpTmp ; UINT index ; /* * Go thru memory registered to be cleaned up. */ lpList = lpToDeleteList ; while (lpList) { memset(lpList->lpLocation, 0, lpList->nSize) ; lpTmp = (LPMEMORY_ELEMENT) lpList->lpNext ; if (lpList->fDelete) { FreeMem(lpList->lpLocation); } FreeMem( (LPBYTE) lpList); lpList = lpTmp ; } lpToDeleteList = NULL ; /* * cleanup our copy of the args */ index = 0; while (ArgList[index]) { ClearStringW(ArgList[index]) ; index++ ; } /* * cleanup original argv */ for ( index = 1 ; index < SavedArgc ; index++ ) { ClearStringA(SavedArgv[index]) ; } ClearStringW(GetCommandLine()); } VOID call_net1(VOID) { STARTUPINFO startupinfo ; PROCESS_INFORMATION processinfo; LPWSTR cmdline, newcmdline, firstarg; DWORD err ; int net1exitcode = 0; memset(&startupinfo, 0, sizeof(startupinfo)) ; startupinfo.cb = sizeof(startupinfo); cmdline = GetCommandLineW() ; firstarg = _tcschr(cmdline, TEXT(' ')) ; if (err = AllocMem((_tcslen(cmdline)+1) * sizeof(TCHAR) + sizeof(TEXT("net1")), (LPBYTE *)&newcmdline)) { ErrorExit(err) ; } _tcscpy(newcmdline, TEXT("net1")) ; if (firstarg) _tcscat(newcmdline, firstarg) ; if (!CreateProcess(NULL, newcmdline, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startupinfo, &processinfo)) { ErrorExit(GetLastError()); } CloseHandle(processinfo.hThread) ; WaitForSingleObject(processinfo.hProcess, INFINITE) ; GetExitCodeProcess(processinfo.hProcess, &net1exitcode) ; CloseHandle(processinfo.hProcess) ; MyExit(net1exitcode) ; }