Source code of Windows XP (NT5)
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.

379 lines
9.2 KiB

  1. /********************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1987-1990 **/
  4. /********************************************************************/
  5. /*
  6. * MSNET - a command processor for MSNET 3.0.
  7. * The command grammar is specified in msnet.x
  8. *
  9. * History
  10. *
  11. * ??/??/??, ??????, initial code
  12. * 10/31/88, erichn, uses OS2.H instead of DOSCALLS
  13. * 05/02/89, erichn, NLS conversion
  14. * 06/08/89, erichn, canonicalization sweep, no LONGer u-cases input
  15. * 02/15/91, danhi, convert to be 16/32 portable
  16. * 10/16/91, JohnRo, added DEFAULT_SERVER support.
  17. */
  18. /* #define INCL_NOCOMMON */
  19. #include <os2.h>
  20. #include <lmcons.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <fcntl.h>
  24. #include <io.h>
  25. #include <apperr.h>
  26. #include "netcmds.h"
  27. #include "nettext.h"
  28. #include "msystem.h"
  29. #include "locale.h"
  30. #define _SHELL32_
  31. #include <shellapi.h>
  32. static VOID init(VOID);
  33. VOID call_net1(VOID) ;
  34. TCHAR * ArgList[LIST_SIZE] = {0};
  35. SHORT ArgPos[LIST_SIZE] = {0};
  36. TCHAR * SwitchList[LIST_SIZE] = {0};
  37. SHORT SwitchPos[LIST_SIZE] = {0};
  38. /* Insertion strings for InfoMessage() */
  39. TCHAR FAR * IStrings[10] = {0};
  40. TCHAR FAR * StarStrings[10] = {TEXT("***"),
  41. TEXT("***"),
  42. TEXT("***"),
  43. TEXT("***"),
  44. TEXT("***"),
  45. TEXT("***"),
  46. TEXT("***"),
  47. TEXT("***"),
  48. TEXT("***")};
  49. /* 1 is /Yes, 2 is /No */
  50. SHORT YorN_Switch = 0;
  51. TCHAR ** MyArgv; /* argv */
  52. UINT SavedArgc = 0 ;
  53. CHAR ** SavedArgv = NULL ;
  54. /* Buffers for APIs to use */
  55. TCHAR Buffer[LITTLE_BUF_SIZE]; /* For GetInfo's, etc.*/
  56. TCHAR BigBuffer[BIG_BUF_SIZE]; /* For Enum's */
  57. TCHAR FAR * BigBuf = BigBuffer;
  58. //
  59. // Globals for standard console handles
  60. //
  61. HANDLE g_hStdOut;
  62. HANDLE g_hStdErr;
  63. /***
  64. * MAIN - Seperate the command line into switches and arguments.
  65. * Then call the parser, which will dispatch the command and
  66. * report on error conditions. Allocate the BigBuf.
  67. */
  68. VOID os2cmd(VOID);
  69. CPINFO CurrentCPInfo;
  70. VOID __cdecl main(int argc, CHAR **argv)
  71. {
  72. SHORT sindex, aindex;
  73. SHORT pos=0;
  74. DWORD cp;
  75. CHAR achCodePage[12] = ".OCP"; // '.' + UINT in decimal + '\0'
  76. SavedArgc = argc ;
  77. SavedArgv = argv ;
  78. /*
  79. Added for bilingual message support. This is needed for FormatMessage
  80. to work correctly. (Called from DosGetMessage).
  81. Get current CodePage Info. We need this to decide whether
  82. or not to use half-width characters.
  83. */
  84. cp = GetConsoleOutputCP();
  85. GetCPInfo(cp, &CurrentCPInfo);
  86. switch ( cp )
  87. {
  88. case 932:
  89. case 936:
  90. case 949:
  91. case 950:
  92. SetThreadLocale(
  93. MAKELCID(
  94. MAKELANGID(
  95. PRIMARYLANGID(GetSystemDefaultLangID()),
  96. SUBLANG_ENGLISH_US ),
  97. SORT_DEFAULT
  98. )
  99. );
  100. break;
  101. default:
  102. SetThreadLocale(
  103. MAKELCID(
  104. MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  105. SORT_DEFAULT
  106. )
  107. );
  108. break;
  109. }
  110. if (cp)
  111. {
  112. sprintf(achCodePage, ".%u", cp);
  113. }
  114. setlocale(LC_ALL, achCodePage);
  115. g_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  116. if (g_hStdOut == INVALID_HANDLE_VALUE)
  117. {
  118. ErrorExit(GetLastError());
  119. }
  120. g_hStdErr = GetStdHandle(STD_ERROR_HANDLE);
  121. if (g_hStdErr == INVALID_HANDLE_VALUE)
  122. {
  123. ErrorExit(GetLastError());
  124. }
  125. MyArgv = CommandLineToArgvW(GetCommandLineW(), &argc);
  126. if (MyArgv == NULL)
  127. {
  128. ErrorExit(ERROR_NOT_ENOUGH_MEMORY) ;
  129. }
  130. /* seperate switches and arguments */
  131. ++MyArgv;
  132. for (sindex = 0, aindex = 0; --argc; ++MyArgv, ++pos)
  133. {
  134. if (**MyArgv == SLASH)
  135. {
  136. SHORT arglen;
  137. SHORT arg_is_special = 0;
  138. arglen = (SHORT) _tcslen(*MyArgv);
  139. if (arglen > 1)
  140. {
  141. if ( _tcsnicmp(swtxt_SW_YES, (*MyArgv), arglen) == 0 )
  142. {
  143. if (YorN_Switch == NO)
  144. ErrorExit(APE_ConflictingSwitches);
  145. arg_is_special = 1;
  146. YorN_Switch = YES;
  147. }
  148. else if ( _tcsnicmp(swtxt_SW_NO, (*MyArgv), arglen) == 0 )
  149. {
  150. if (YorN_Switch == YES)
  151. ErrorExit(APE_ConflictingSwitches);
  152. arg_is_special = 1;
  153. YorN_Switch = NO;
  154. }
  155. }
  156. if ( ! arg_is_special )
  157. {
  158. if (sindex >= LIST_SIZE)
  159. ErrorExit(APE_NumArgs) ;
  160. SwitchList[sindex] = *MyArgv;
  161. SwitchPos[sindex] = pos;
  162. sindex++;
  163. }
  164. }
  165. else
  166. {
  167. if (aindex >= LIST_SIZE)
  168. ErrorExit(APE_NumArgs) ;
  169. ArgList[aindex] = *MyArgv;
  170. ArgPos[aindex] = pos;
  171. aindex++;
  172. }
  173. }
  174. // register as locations to zero out on exit
  175. AddToMemClearList(BigBuffer, sizeof(BigBuffer), FALSE) ;
  176. AddToMemClearList(Buffer, sizeof(Buffer),FALSE) ;
  177. init();
  178. os2cmd();
  179. NetcmdExit(0);
  180. }
  181. static VOID NEAR init(VOID)
  182. {
  183. _setmode(_fileno(stdin), O_TEXT);
  184. }
  185. /***
  186. * M y E x i t
  187. *
  188. * Wrapper around C runtime that cleans up memory for security reasons.
  189. */
  190. VOID DOSNEAR FASTCALL
  191. MyExit(int Status)
  192. {
  193. ClearMemory() ;
  194. exit(Status);
  195. }
  196. typedef struct _MEMOMY_ELEMENT {
  197. LPBYTE lpLocation ;
  198. struct _MEMORY_ELEMENT *lpNext ;
  199. UINT nSize ;
  200. BOOL fDelete ;
  201. } MEMORY_ELEMENT, *LPMEMORY_ELEMENT ;
  202. LPMEMORY_ELEMENT lpToDeleteList = NULL ;
  203. /***
  204. * AddToMemClearList
  205. *
  206. * add an entry to list of things to clear
  207. */
  208. VOID
  209. AddToMemClearList(
  210. VOID *lpBuffer,
  211. UINT nSize,
  212. BOOL fDelete
  213. )
  214. {
  215. LPMEMORY_ELEMENT lpNew, lpTmp ;
  216. DWORD err ;
  217. if (err = AllocMem(sizeof(MEMORY_ELEMENT),(LPBYTE *) &lpNew))
  218. {
  219. ErrorExit(err);
  220. }
  221. lpNew->lpLocation = (LPBYTE) lpBuffer ;
  222. lpNew->nSize = nSize ;
  223. lpNew->fDelete = fDelete ;
  224. lpNew->lpNext = NULL ;
  225. if (!lpToDeleteList)
  226. {
  227. lpToDeleteList = lpNew ;
  228. }
  229. else
  230. {
  231. lpTmp = lpToDeleteList ;
  232. while (lpTmp->lpNext)
  233. lpTmp = (LPMEMORY_ELEMENT) lpTmp->lpNext ;
  234. lpTmp->lpNext = (struct _MEMORY_ELEMENT *) lpNew ;
  235. }
  236. }
  237. /***
  238. * ClearMemory()
  239. *
  240. * go thru list of things to clear, and clear them.
  241. */
  242. VOID ClearMemory(VOID)
  243. {
  244. LPMEMORY_ELEMENT lpList, lpTmp ;
  245. UINT index ;
  246. /*
  247. * Go thru memory registered to be cleaned up.
  248. */
  249. lpList = lpToDeleteList ;
  250. while (lpList)
  251. {
  252. memset(lpList->lpLocation, 0, lpList->nSize) ;
  253. lpTmp = (LPMEMORY_ELEMENT) lpList->lpNext ;
  254. if (lpList->fDelete)
  255. {
  256. FreeMem(lpList->lpLocation);
  257. }
  258. FreeMem( (LPBYTE) lpList);
  259. lpList = lpTmp ;
  260. }
  261. lpToDeleteList = NULL ;
  262. /*
  263. * cleanup our copy of the args
  264. */
  265. index = 0;
  266. while (ArgList[index])
  267. {
  268. ClearStringW(ArgList[index]) ;
  269. index++ ;
  270. }
  271. /*
  272. * cleanup original argv
  273. */
  274. for ( index = 1 ; index < SavedArgc ; index++ )
  275. {
  276. ClearStringA(SavedArgv[index]) ;
  277. }
  278. ClearStringW(GetCommandLine());
  279. }
  280. VOID call_net1(VOID)
  281. {
  282. STARTUPINFO startupinfo ;
  283. PROCESS_INFORMATION processinfo;
  284. LPWSTR cmdline, newcmdline, firstarg;
  285. DWORD err ;
  286. int net1exitcode = 0;
  287. memset(&startupinfo, 0, sizeof(startupinfo)) ;
  288. startupinfo.cb = sizeof(startupinfo);
  289. cmdline = GetCommandLineW() ;
  290. firstarg = _tcschr(cmdline, TEXT(' ')) ;
  291. if (err = AllocMem((_tcslen(cmdline)+1) * sizeof(TCHAR)
  292. + sizeof(TEXT("net1")),
  293. (LPBYTE *)&newcmdline))
  294. {
  295. ErrorExit(err) ;
  296. }
  297. _tcscpy(newcmdline, TEXT("net1")) ;
  298. if (firstarg)
  299. _tcscat(newcmdline, firstarg) ;
  300. if (!CreateProcess(NULL,
  301. newcmdline,
  302. NULL,
  303. NULL,
  304. TRUE,
  305. NORMAL_PRIORITY_CLASS,
  306. NULL,
  307. NULL,
  308. &startupinfo,
  309. &processinfo))
  310. {
  311. ErrorExit(GetLastError());
  312. }
  313. CloseHandle(processinfo.hThread) ;
  314. WaitForSingleObject(processinfo.hProcess, INFINITE) ;
  315. GetExitCodeProcess(processinfo.hProcess, &net1exitcode) ;
  316. CloseHandle(processinfo.hProcess) ;
  317. MyExit(net1exitcode) ;
  318. }