mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
9.2 KiB
364 lines
9.2 KiB
/********************************************************************/
|
|
/** 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 <os2.h>
|
|
#include <netcons.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <signal.h>
|
|
#ifdef DBGREMOTE
|
|
#include <stdlib.h> /* getenv(). */
|
|
#endif // DBGREMOTE
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#include "netlib0.h"
|
|
#include <malloc.h> /* free */
|
|
#include <apperr.h>
|
|
#include <access.h>
|
|
#include <apisec.h>
|
|
#include "port1632.h"
|
|
#include "netcmds.h"
|
|
#include "nettext.h"
|
|
#include <lui.h>
|
|
#include <msgtext.h>
|
|
#include <alertmsg.h>
|
|
#include <lmerrlog.h>
|
|
#include <ncberr.h>
|
|
|
|
#define WINSHELLAPI
|
|
#include <shellapi.h>
|
|
|
|
|
|
static VOID NEAR init(VOID);
|
|
VOID MNetClearStringA(LPSTR lpszString) ;
|
|
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;
|
|
|
|
#if defined(PMEMTRACE)
|
|
|
|
extern USHORT usNumAllocs,
|
|
usNumStaticAllocs,
|
|
usNumDynamicAllocs,
|
|
usNumBIGAllocs,
|
|
usNumFrees,
|
|
usNumStaticFrees,
|
|
usNumDynamicFrees;
|
|
|
|
#endif /* defined(PMEMTRACE) */
|
|
|
|
#ifdef DBGREMOTE
|
|
TCHAR * DefaultServerName = TEXT("");
|
|
#endif // DBGREMOTE
|
|
|
|
|
|
|
|
/***
|
|
* 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 _CRTAPI1 main(int argc, CHAR **argv)
|
|
{
|
|
SHORT sindex, aindex;
|
|
SHORT pos=0;
|
|
DWORD cp;
|
|
|
|
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.
|
|
*/
|
|
|
|
GetCPInfo(cp=GetConsoleOutputCP(), &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;
|
|
}
|
|
|
|
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 ;
|
|
WORD err ;
|
|
|
|
if (err = MAllocMem(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)
|
|
{
|
|
memsetf(lpList->lpLocation, 0, lpList->nSize) ;
|
|
lpTmp = (LPMEMORY_ELEMENT) lpList->lpNext ;
|
|
if (lpList->fDelete)
|
|
MFreeMem(lpList->lpLocation) ;
|
|
MFreeMem( (LPBYTE) lpList) ;
|
|
lpList = lpTmp ;
|
|
}
|
|
lpToDeleteList = NULL ;
|
|
|
|
/*
|
|
* cleanup our copy of the args
|
|
*/
|
|
index = 0;
|
|
while (ArgList[index])
|
|
{
|
|
MNetClearStringW(ArgList[index]) ;
|
|
index++ ;
|
|
}
|
|
|
|
/*
|
|
* cleanup original argv
|
|
*/
|
|
for ( index = 1 ; index < SavedArgc ; index++ )
|
|
{
|
|
MNetClearStringA(SavedArgv[index]) ;
|
|
}
|
|
MNetClearStringW(GetCommandLine());
|
|
}
|
|
|
|
VOID call_net1(VOID)
|
|
{
|
|
STARTUPINFO startupinfo ;
|
|
PROCESS_INFORMATION processinfo;
|
|
LPWSTR cmdline, newcmdline, firstarg;
|
|
USHORT err ;
|
|
int net1exitcode = 0;
|
|
|
|
|
|
memset(&startupinfo, 0, sizeof(startupinfo)) ;
|
|
cmdline = GetCommandLineW() ;
|
|
firstarg = _tcschr(cmdline, TEXT(' ')) ;
|
|
|
|
if (err = MAllocMem((_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((USHORT)GetLastError()) ;
|
|
}
|
|
|
|
CloseHandle(processinfo.hThread) ;
|
|
WaitForSingleObject(processinfo.hProcess, INFINITE) ;
|
|
GetExitCodeProcess(processinfo.hProcess, &net1exitcode) ;
|
|
CloseHandle(processinfo.hProcess) ;
|
|
MyExit(net1exitcode) ;
|
|
}
|