00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 #include "precomp.h"
00145 #include <reactos/buildno.h>
00146 #include <reactos/version.h>
00147
00148 #ifndef NT_SUCCESS
00149 #define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
00150 #endif
00151
00152 typedef NTSTATUS (WINAPI *NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS,
00153 PVOID, ULONG, PULONG);
00154 typedef NTSTATUS (WINAPI *NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, ULONG, PULONG);
00155
00156 BOOL bExit = FALSE;
00157 BOOL bCanExit = TRUE;
00158 BOOL bCtrlBreak = FALSE;
00159 BOOL bIgnoreEcho = FALSE;
00160 INT nErrorLevel = 0;
00161 CRITICAL_SECTION ChildProcessRunningLock;
00162 BOOL bUnicodeOutput = FALSE;
00163 BOOL bDisableBatchEcho = FALSE;
00164 BOOL bDelayedExpansion = FALSE;
00165 DWORD dwChildProcessId = 0;
00166 OSVERSIONINFO osvi;
00167 HANDLE hIn;
00168 HANDLE hOut;
00169 LPTSTR lpOriginalEnvironment;
00170 HANDLE CMD_ModuleHandle;
00171
00172 static NtQueryInformationProcessProc NtQueryInformationProcessPtr = NULL;
00173 static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr = NULL;
00174
00175 #ifdef INCLUDE_CMD_COLOR
00176 WORD wDefColor;
00177 #endif
00178
00179
00180
00181
00182
00183
00184 INT
00185 ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator)
00186 {
00187 TCHAR temp[39];
00188 UINT n, iTarget;
00189
00190 if (len <= 1)
00191 return 0;
00192
00193 n = 0;
00194 iTarget = nNumberGroups;
00195 if (!nNumberGroups)
00196 bPutSeperator = FALSE;
00197
00198 do
00199 {
00200 if (iTarget == n && bPutSeperator)
00201 {
00202 iTarget += nNumberGroups + 1;
00203 temp[38 - n++] = cThousandSeparator;
00204 }
00205 temp[38 - n++] = (TCHAR)(num % 10) + _T('0');
00206 num /= 10;
00207 } while (num > 0);
00208 if (n > len-1)
00209 n = len-1;
00210
00211 memcpy(des, temp + 39 - n, n * sizeof(TCHAR));
00212 des[n] = _T('\0');
00213
00214 return n;
00215 }
00216
00217
00218
00219
00220 static BOOL IsConsoleProcess(HANDLE Process)
00221 {
00222 NTSTATUS Status;
00223 PROCESS_BASIC_INFORMATION Info;
00224 PEB ProcessPeb;
00225 ULONG BytesRead;
00226
00227 if (NULL == NtQueryInformationProcessPtr || NULL == NtReadVirtualMemoryPtr)
00228 {
00229 return TRUE;
00230 }
00231
00232 Status = NtQueryInformationProcessPtr (
00233 Process, ProcessBasicInformation,
00234 &Info, sizeof(PROCESS_BASIC_INFORMATION), NULL);
00235 if (! NT_SUCCESS(Status))
00236 {
00237 WARN ("NtQueryInformationProcess failed with status %08x\n", Status);
00238 return TRUE;
00239 }
00240 Status = NtReadVirtualMemoryPtr (
00241 Process, Info.PebBaseAddress, &ProcessPeb,
00242 sizeof(PEB), &BytesRead);
00243 if (! NT_SUCCESS(Status) || sizeof(PEB) != BytesRead)
00244 {
00245 WARN ("Couldn't read virt mem status %08x bytes read %lu\n", Status, BytesRead);
00246 return TRUE;
00247 }
00248
00249 return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubsystem;
00250 }
00251
00252
00253
00254 #ifdef _UNICODE
00255 #define SHELLEXECUTETEXT "ShellExecuteExW"
00256 #else
00257 #define SHELLEXECUTETEXT "ShellExecuteExA"
00258 #endif
00259
00260 typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo);
00261
00262 HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params,
00263 LPTSTR directory, INT show)
00264 {
00265 SHELLEXECUTEINFO sei;
00266 HMODULE hShell32;
00267 MYEX hShExt;
00268 BOOL ret;
00269
00270 TRACE ("RunFile(%s)\n", debugstr_aw(filename));
00271 hShell32 = LoadLibrary(_T("SHELL32.DLL"));
00272 if (!hShell32)
00273 {
00274 WARN ("RunFile: couldn't load SHELL32.DLL!\n");
00275 return NULL;
00276 }
00277
00278 hShExt = (MYEX)(FARPROC)GetProcAddress(hShell32, SHELLEXECUTETEXT);
00279 if (!hShExt)
00280 {
00281 WARN ("RunFile: couldn't find ShellExecuteExA/W in SHELL32.DLL!\n");
00282 FreeLibrary(hShell32);
00283 return NULL;
00284 }
00285
00286 TRACE ("RunFile: ShellExecuteExA/W is at %x\n", hShExt);
00287
00288 memset(&sei, 0, sizeof sei);
00289 sei.cbSize = sizeof sei;
00290 sei.fMask = flags;
00291 sei.lpFile = filename;
00292 sei.lpParameters = params;
00293 sei.lpDirectory = directory;
00294 sei.nShow = show;
00295 ret = hShExt(&sei);
00296
00297 TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret);
00298
00299 FreeLibrary(hShell32);
00300 return ret ? sei.hProcess : NULL;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 static INT
00314 Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
00315 {
00316 TCHAR szFullName[MAX_PATH];
00317 TCHAR *first, *rest, *dot;
00318 TCHAR szWindowTitle[MAX_PATH];
00319 DWORD dwExitCode = 0;
00320 TCHAR *FirstEnd;
00321 TCHAR szFullCmdLine [CMDLINE_LENGTH];
00322
00323 TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest));
00324
00325
00326
00327 if (First[0] == _T('/') || (First[0] && First[1] == _T(':')))
00328 {
00329
00330 FirstEnd = First + _tcslen(First);
00331 }
00332 else
00333 {
00334
00335
00336 BOOL bInside = FALSE;
00337 for (FirstEnd = First; *FirstEnd; FirstEnd++)
00338 {
00339 if (!bInside && (_istspace(*FirstEnd) || _tcschr(_T(",;=/"), *FirstEnd)))
00340 break;
00341 bInside ^= *FirstEnd == _T('"');
00342 }
00343 }
00344
00345
00346 first = Full;
00347 rest = &Full[FirstEnd - First + 1];
00348 _tcscpy(rest, FirstEnd);
00349 _tcscat(rest, Rest);
00350 *FirstEnd = _T('\0');
00351 _tcscpy(first, First);
00352
00353
00354 if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
00355 {
00356 BOOL working = TRUE;
00357 if (!SetCurrentDirectory(first))
00358
00359 {
00360 TCHAR str[4];
00361 str[0]=first[0];
00362 str[1]=_T(':');
00363 str[2]=_T('\\');
00364 str[3]=0;
00365 working = SetCurrentDirectory(str);
00366 }
00367
00368 if (!working) ConErrResPuts (STRING_FREE_ERROR1);
00369 return !working;
00370 }
00371
00372
00373
00374 StripQuotes(First);
00375 if (!SearchForExecutable(First, szFullName))
00376 {
00377 error_bad_command(first);
00378 return 1;
00379 }
00380
00381 GetConsoleTitle (szWindowTitle, MAX_PATH);
00382
00383
00384 dot = _tcsrchr (szFullName, _T('.'));
00385 if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd"))))
00386 {
00387 while (*rest == _T(' '))
00388 rest++;
00389 TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
00390 dwExitCode = Batch(szFullName, first, rest, Cmd);
00391 }
00392 else
00393 {
00394
00395 PROCESS_INFORMATION prci;
00396 STARTUPINFO stui;
00397
00398
00399 BOOL quoted = !!_tcschr(First, ' ');
00400 _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T(""));
00401 _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
00402 _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
00403
00404 if (*rest)
00405 {
00406 _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
00407 _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
00408 }
00409
00410 TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine));
00411
00412
00413 memset (&stui, 0, sizeof (STARTUPINFO));
00414 stui.cb = sizeof (STARTUPINFO);
00415 stui.dwFlags = STARTF_USESHOWWINDOW;
00416 stui.wShowWindow = SW_SHOWDEFAULT;
00417
00418
00419 SetConsoleMode (GetStdHandle(STD_INPUT_HANDLE),
00420 ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
00421
00422 if (CreateProcess (szFullName,
00423 szFullCmdLine,
00424 NULL,
00425 NULL,
00426 TRUE,
00427 0,
00428 NULL,
00429 NULL,
00430 &stui,
00431 &prci))
00432
00433 {
00434 CloseHandle(prci.hThread);
00435 }
00436 else
00437 {
00438
00439 prci.hProcess = RunFile(SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE,
00440 szFullName,
00441 rest,
00442 NULL,
00443 SW_SHOWNORMAL);
00444 }
00445
00446 if (prci.hProcess != NULL)
00447 {
00448 if (IsConsoleProcess(prci.hProcess))
00449 {
00450 EnterCriticalSection(&ChildProcessRunningLock);
00451 dwChildProcessId = prci.dwProcessId;
00452
00453 WaitForSingleObject (prci.hProcess, INFINITE);
00454
00455 LeaveCriticalSection(&ChildProcessRunningLock);
00456
00457 GetExitCodeProcess (prci.hProcess, &dwExitCode);
00458 nErrorLevel = (INT)dwExitCode;
00459 }
00460 CloseHandle (prci.hProcess);
00461 }
00462 else
00463 {
00464 TRACE ("[ShellExecute failed!: %s]\n", debugstr_aw(Full));
00465 error_bad_command (first);
00466 dwExitCode = 1;
00467 }
00468
00469
00470 SetConsoleMode (
00471 GetStdHandle( STD_INPUT_HANDLE ),
00472 ENABLE_PROCESSED_INPUT );
00473 }
00474
00475
00476 InputCodePage= GetConsoleCP();
00477 OutputCodePage = GetConsoleOutputCP();
00478 SetConsoleTitle (szWindowTitle);
00479
00480 return dwExitCode;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 INT
00494 DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
00495 {
00496 TCHAR *com;
00497 TCHAR *cp;
00498 LPTSTR param;
00499 INT cl;
00500 LPCOMMAND cmdptr;
00501 BOOL nointernal = FALSE;
00502 INT ret;
00503
00504 TRACE ("DoCommand: (\'%s\' \'%s\')\n", debugstr_aw(first), debugstr_aw(rest));
00505
00506
00507 com = cmd_alloc((_tcslen(first) + _tcslen(rest) + 2) * sizeof(TCHAR));
00508 if (com == NULL)
00509 {
00510 error_out_of_memory();
00511 return 1;
00512 }
00513
00514
00515
00516 cp = first + _tcscspn(first, _T("\t +,/;=[]"));
00517
00518 for (cl = 0; cl < (cp - first); cl++)
00519 {
00520
00521
00522
00523
00524 if (_tcschr(_T(".:\\"), first[cl]))
00525 {
00526 TCHAR tmp = *cp;
00527 *cp = _T('\0');
00528 nointernal = IsExistingFile(first);
00529 *cp = tmp;
00530 break;
00531 }
00532 }
00533
00534
00535 for (cmdptr = cmds; !nointernal && cmdptr->name; cmdptr++)
00536 {
00537 if (!_tcsnicmp(first, cmdptr->name, cl) && cmdptr->name[cl] == _T('\0'))
00538 {
00539 _tcscpy(com, first);
00540 _tcscat(com, rest);
00541 param = &com[cl];
00542
00543
00544 if (_tcsicmp(cmdptr->name, _T("echo")) != 0)
00545 while (_istspace(*param))
00546 param++;
00547 ret = cmdptr->func(param);
00548 cmd_free(com);
00549 return ret;
00550 }
00551 }
00552
00553 ret = Execute(com, first, rest, Cmd);
00554 cmd_free(com);
00555 return ret;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564 INT ParseCommandLine (LPTSTR cmd)
00565 {
00566 INT Ret = 0;
00567 PARSED_COMMAND *Cmd = ParseCommand(cmd);
00568 if (Cmd)
00569 {
00570 Ret = ExecuteCommand(Cmd);
00571 FreeCommand(Cmd);
00572 }
00573 return Ret;
00574 }
00575
00576
00577
00578
00579
00580
00581 static HANDLE
00582 ExecuteAsync(PARSED_COMMAND *Cmd)
00583 {
00584 TCHAR CmdPath[MAX_PATH];
00585 TCHAR CmdParams[CMDLINE_LENGTH], *ParamsEnd;
00586 STARTUPINFO stui;
00587 PROCESS_INFORMATION prci;
00588
00589
00590 GetModuleFileName(NULL, CmdPath, MAX_PATH);
00591
00592
00593 ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\""));
00594 ParamsEnd = Unparse(Cmd, ParamsEnd, &CmdParams[CMDLINE_LENGTH - 2]);
00595 if (!ParamsEnd)
00596 {
00597 error_out_of_memory();
00598 return NULL;
00599 }
00600 _tcscpy(ParamsEnd, _T("\""));
00601
00602 memset(&stui, 0, sizeof stui);
00603 stui.cb = sizeof(STARTUPINFO);
00604 if (!CreateProcess(CmdPath, CmdParams, NULL, NULL, TRUE, 0,
00605 NULL, NULL, &stui, &prci))
00606 {
00607 ErrorMessage(GetLastError(), NULL);
00608 return NULL;
00609 }
00610
00611 CloseHandle(prci.hThread);
00612 return prci.hProcess;
00613 }
00614
00615 static VOID
00616 ExecutePipeline(PARSED_COMMAND *Cmd)
00617 {
00618 #ifdef FEATURE_REDIRECTION
00619 HANDLE hInput = NULL;
00620 HANDLE hOldConIn = GetStdHandle(STD_INPUT_HANDLE);
00621 HANDLE hOldConOut = GetStdHandle(STD_OUTPUT_HANDLE);
00622 HANDLE hProcess[MAXIMUM_WAIT_OBJECTS];
00623 INT nProcesses = 0;
00624 DWORD dwExitCode;
00625
00626
00627 do
00628 {
00629 HANDLE hPipeRead, hPipeWrite;
00630 if (nProcesses > (MAXIMUM_WAIT_OBJECTS - 2))
00631 {
00632 error_too_many_parameters(_T("|"));
00633 goto failed;
00634 }
00635
00636
00637
00638
00639 if (!CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0))
00640 {
00641 error_no_pipe();
00642 goto failed;
00643 }
00644
00645
00646 SetHandleInformation(hPipeWrite, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
00647 SetStdHandle(STD_OUTPUT_HANDLE, hPipeWrite);
00648
00649
00650 hProcess[nProcesses] = ExecuteAsync(Cmd->Subcommands);
00651 CloseHandle(hPipeWrite);
00652 if (hInput)
00653 CloseHandle(hInput);
00654
00655
00656 SetHandleInformation(hPipeRead, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
00657 SetStdHandle(STD_INPUT_HANDLE, hPipeRead);
00658 hInput = hPipeRead;
00659
00660 if (!hProcess[nProcesses])
00661 goto failed;
00662 nProcesses++;
00663
00664 Cmd = Cmd->Subcommands->Next;
00665 } while (Cmd->Type == C_PIPE);
00666
00667
00668 SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
00669 hProcess[nProcesses] = ExecuteAsync(Cmd);
00670 if (!hProcess[nProcesses])
00671 goto failed;
00672 nProcesses++;
00673 CloseHandle(hInput);
00674 SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
00675
00676
00677 EnterCriticalSection(&ChildProcessRunningLock);
00678 WaitForMultipleObjects(nProcesses, hProcess, TRUE, INFINITE);
00679 LeaveCriticalSection(&ChildProcessRunningLock);
00680
00681
00682 GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode);
00683 nErrorLevel = (INT)dwExitCode;
00684
00685 while (--nProcesses >= 0)
00686 CloseHandle(hProcess[nProcesses]);
00687 return;
00688
00689 failed:
00690 if (hInput)
00691 CloseHandle(hInput);
00692 while (--nProcesses >= 0)
00693 {
00694 TerminateProcess(hProcess[nProcesses], 0);
00695 CloseHandle(hProcess[nProcesses]);
00696 }
00697 SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
00698 SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
00699 #endif
00700 }
00701
00702 INT
00703 ExecuteCommand(PARSED_COMMAND *Cmd)
00704 {
00705 PARSED_COMMAND *Sub;
00706 LPTSTR First, Rest;
00707 INT Ret = 0;
00708
00709 if (!PerformRedirection(Cmd->Redirections))
00710 return 1;
00711
00712 switch (Cmd->Type)
00713 {
00714 case C_COMMAND:
00715 Ret = 1;
00716 First = DoDelayedExpansion(Cmd->Command.First);
00717 if (First)
00718 {
00719 Rest = DoDelayedExpansion(Cmd->Command.Rest);
00720 if (Rest)
00721 {
00722 Ret = DoCommand(First, Rest, Cmd);
00723 cmd_free(Rest);
00724 }
00725 cmd_free(First);
00726 }
00727 break;
00728 case C_QUIET:
00729 case C_BLOCK:
00730 case C_MULTI:
00731 for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next)
00732 Ret = ExecuteCommand(Sub);
00733 break;
00734 case C_IFFAILURE:
00735 Sub = Cmd->Subcommands;
00736 Ret = ExecuteCommand(Sub);
00737 if (Ret != 0)
00738 {
00739 nErrorLevel = Ret;
00740 Ret = ExecuteCommand(Sub->Next);
00741 }
00742 break;
00743 case C_IFSUCCESS:
00744 Sub = Cmd->Subcommands;
00745 Ret = ExecuteCommand(Sub);
00746 if (Ret == 0)
00747 Ret = ExecuteCommand(Sub->Next);
00748 break;
00749 case C_PIPE:
00750 ExecutePipeline(Cmd);
00751 break;
00752 case C_IF:
00753 Ret = ExecuteIf(Cmd);
00754 break;
00755 case C_FOR:
00756 Ret = ExecuteFor(Cmd);
00757 break;
00758 }
00759
00760 UndoRedirection(Cmd->Redirections, NULL);
00761 return Ret;
00762 }
00763
00764 LPTSTR
00765 GetEnvVar(LPCTSTR varName)
00766 {
00767 static LPTSTR ret = NULL;
00768 UINT size;
00769
00770 cmd_free(ret);
00771 ret = NULL;
00772 size = GetEnvironmentVariable(varName, NULL, 0);
00773 if (size > 0)
00774 {
00775 ret = cmd_alloc(size * sizeof(TCHAR));
00776 if (ret != NULL)
00777 GetEnvironmentVariable(varName, ret, size + 1);
00778 }
00779 return ret;
00780 }
00781
00782 LPCTSTR
00783 GetEnvVarOrSpecial(LPCTSTR varName)
00784 {
00785 static TCHAR ret[MAX_PATH];
00786
00787 LPTSTR var = GetEnvVar(varName);
00788 if (var)
00789 return var;
00790
00791
00792
00793 if (_tcsicmp(varName,_T("cd")) ==0)
00794 {
00795 GetCurrentDirectory(MAX_PATH, ret);
00796 return ret;
00797 }
00798
00799 else if (_tcsicmp(varName,_T("time")) ==0)
00800 {
00801 return GetTimeString();
00802 }
00803
00804 else if (_tcsicmp(varName,_T("date")) ==0)
00805 {
00806 return GetDateString();
00807 }
00808
00809
00810 else if (_tcsicmp(varName,_T("random")) ==0)
00811 {
00812
00813 _itot(rand(),ret,10);
00814 return ret;
00815 }
00816
00817
00818 else if (_tcsicmp(varName,_T("cmdcmdline")) ==0)
00819 {
00820 return GetCommandLine();
00821 }
00822
00823
00824 else if (_tcsicmp(varName,_T("cmdextversion")) ==0)
00825 {
00826
00827 _itot(2,ret,10);
00828 return ret;
00829 }
00830
00831
00832 else if (_tcsicmp(varName,_T("errorlevel")) ==0)
00833 {
00834 _itot(nErrorLevel,ret,10);
00835 return ret;
00836 }
00837
00838 return NULL;
00839 }
00840
00841
00842 static LPTSTR
00843 GetEnhancedVar(TCHAR **pFormat, LPTSTR (*GetVar)(TCHAR, BOOL *))
00844 {
00845 static const TCHAR ModifierTable[] = _T("dpnxfsatz");
00846 enum {
00847 M_DRIVE = 1,
00848 M_PATH = 2,
00849 M_NAME = 4,
00850 M_EXT = 8,
00851 M_FULL = 16,
00852 M_SHORT = 32,
00853 M_ATTR = 64,
00854 M_TIME = 128,
00855 M_SIZE = 256,
00856 } Modifiers = 0;
00857
00858 TCHAR *Format, *FormatEnd;
00859 TCHAR *PathVarName = NULL;
00860 LPTSTR Variable;
00861 TCHAR *VarEnd;
00862 BOOL VariableIsParam0;
00863 TCHAR FullPath[MAX_PATH];
00864 TCHAR FixedPath[MAX_PATH], *Filename, *Extension;
00865 HANDLE hFind;
00866 WIN32_FIND_DATA w32fd;
00867 TCHAR *In, *Out;
00868
00869 static TCHAR Result[CMDLINE_LENGTH];
00870
00871
00872
00873
00874
00875
00876
00877 FormatEnd = Format = *pFormat;
00878 while (*FormatEnd && _tcschr(ModifierTable, _totlower(*FormatEnd)))
00879 FormatEnd++;
00880
00881 if (*FormatEnd == _T('$'))
00882 {
00883
00884 PathVarName = FormatEnd + 1;
00885 FormatEnd = _tcschr(PathVarName, _T(':'));
00886 if (!FormatEnd)
00887 return NULL;
00888
00889
00890 Variable = GetVar(*++FormatEnd, &VariableIsParam0);
00891 if (!Variable)
00892 return NULL;
00893 }
00894 else
00895 {
00896
00897 while (!(Variable = GetVar(*FormatEnd, &VariableIsParam0)))
00898 {
00899 if (FormatEnd == Format)
00900 return NULL;
00901 FormatEnd--;
00902 }
00903 }
00904
00905 for (; Format < FormatEnd && *Format != _T('$'); Format++)
00906 Modifiers |= 1 << (_tcschr(ModifierTable, _totlower(*Format)) - ModifierTable);
00907
00908 *pFormat = FormatEnd + 1;
00909
00910
00911 VarEnd = &Variable[_tcslen(Variable)];
00912 if (*Variable == _T('"'))
00913 {
00914 Variable++;
00915 if (VarEnd > Variable && VarEnd[-1] == _T('"'))
00916 VarEnd--;
00917 }
00918
00919 if ((char *)VarEnd - (char *)Variable >= sizeof Result)
00920 return _T("");
00921 memcpy(Result, Variable, (char *)VarEnd - (char *)Variable);
00922 Result[VarEnd - Variable] = _T('\0');
00923
00924 if (PathVarName)
00925 {
00926
00927
00928 LPTSTR PathVar;
00929 FormatEnd[-1] = _T('\0');
00930 PathVar = GetEnvVar(PathVarName);
00931 FormatEnd[-1] = _T(':');
00932 if (!PathVar ||
00933 !SearchPath(PathVar, Result, NULL, MAX_PATH, FullPath, NULL))
00934 {
00935 return _T("");
00936 }
00937 }
00938 else if (Modifiers == 0)
00939 {
00940
00941 return Result;
00942 }
00943 else if (VariableIsParam0)
00944 {
00945
00946
00947
00948 _tcscpy(FullPath, bc->BatchFilePath);
00949 }
00950 else
00951 {
00952
00953 if (!GetFullPathName(Result, MAX_PATH, FullPath, NULL))
00954 return _T("");
00955 }
00956
00957
00958
00959
00960
00961 In = FullPath;
00962 Out = FixedPath;
00963
00964
00965 *Out++ = *In++;
00966 *Out++ = *In++;
00967 *Out++ = *In++;
00968
00969 do {
00970 TCHAR *Next = _tcschr(In, _T('\\'));
00971 if (Next)
00972 *Next++ = _T('\0');
00973
00974 if (Out + _tcslen(In) + 1 >= &FixedPath[MAX_PATH])
00975 return _T("");
00976 _tcscpy(Out, In);
00977 hFind = FindFirstFile(FixedPath, &w32fd);
00978
00979 if (hFind != INVALID_HANDLE_VALUE)
00980 {
00981 LPTSTR FixedComponent = w32fd.cFileName;
00982 if (*w32fd.cAlternateFileName &&
00983 ((Modifiers & M_SHORT) || !_tcsicmp(In, w32fd.cAlternateFileName)))
00984 {
00985 FixedComponent = w32fd.cAlternateFileName;
00986 }
00987 FindClose(hFind);
00988
00989 if (Out + _tcslen(FixedComponent) + 1 >= &FixedPath[MAX_PATH])
00990 return _T("");
00991 _tcscpy(Out, FixedComponent);
00992 }
00993 Filename = Out;
00994 Out += _tcslen(Out);
00995 *Out++ = _T('\\');
00996
00997 In = Next;
00998 } while (In != NULL);
00999 Out[-1] = _T('\0');
01000
01001
01002
01003 Out = Result;
01004 if (hFind != INVALID_HANDLE_VALUE)
01005 {
01006 if (Modifiers & M_ATTR)
01007 {
01008 static const struct {
01009 TCHAR Character;
01010 WORD Value;
01011 } *Attrib, Table[] = {
01012 { _T('d'), FILE_ATTRIBUTE_DIRECTORY },
01013 { _T('r'), FILE_ATTRIBUTE_READONLY },
01014 { _T('a'), FILE_ATTRIBUTE_ARCHIVE },
01015 { _T('h'), FILE_ATTRIBUTE_HIDDEN },
01016 { _T('s'), FILE_ATTRIBUTE_SYSTEM },
01017 { _T('c'), FILE_ATTRIBUTE_COMPRESSED },
01018 { _T('o'), FILE_ATTRIBUTE_OFFLINE },
01019 { _T('t'), FILE_ATTRIBUTE_TEMPORARY },
01020 { _T('l'), FILE_ATTRIBUTE_REPARSE_POINT },
01021 };
01022 for (Attrib = Table; Attrib != &Table[9]; Attrib++)
01023 {
01024 *Out++ = w32fd.dwFileAttributes & Attrib->Value
01025 ? Attrib->Character
01026 : _T('-');
01027 }
01028 *Out++ = _T(' ');
01029 }
01030 if (Modifiers & M_TIME)
01031 {
01032 FILETIME ft;
01033 SYSTEMTIME st;
01034 FileTimeToLocalFileTime(&w32fd.ftLastWriteTime, &ft);
01035 FileTimeToSystemTime(&ft, &st);
01036
01037 Out += FormatDate(Out, &st, TRUE);
01038 *Out++ = _T(' ');
01039 Out += FormatTime(Out, &st);
01040 *Out++ = _T(' ');
01041 }
01042 if (Modifiers & M_SIZE)
01043 {
01044 ULARGE_INTEGER Size;
01045 Size.LowPart = w32fd.nFileSizeLow;
01046 Size.HighPart = w32fd.nFileSizeHigh;
01047 Out += _stprintf(Out, _T("%I64u "), Size.QuadPart);
01048 }
01049 }
01050
01051
01052
01053
01054 if (PathVarName || (Modifiers & M_SHORT))
01055 if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0)
01056 Modifiers |= M_FULL;
01057
01058
01059
01060 Extension = _tcsrchr(Filename, _T('.'));
01061 if (Modifiers & (M_DRIVE | M_FULL))
01062 {
01063 *Out++ = FixedPath[0];
01064 *Out++ = FixedPath[1];
01065 }
01066 if (Modifiers & (M_PATH | M_FULL))
01067 {
01068 memcpy(Out, &FixedPath[2], (char *)Filename - (char *)&FixedPath[2]);
01069 Out += Filename - &FixedPath[2];
01070 }
01071 if (Modifiers & (M_NAME | M_FULL))
01072 {
01073 while (*Filename && Filename != Extension)
01074 *Out++ = *Filename++;
01075 }
01076 if (Modifiers & (M_EXT | M_FULL))
01077 {
01078 if (Extension)
01079 Out = _stpcpy(Out, Extension);
01080 }
01081
01082
01083
01084 while (Out != &Result[0] && Out[-1] == _T(' '))
01085 Out--;
01086 *Out = _T('\0');
01087
01088 return Result;
01089 }
01090
01091 LPCTSTR
01092 GetBatchVar(TCHAR *varName, UINT *varNameLen)
01093 {
01094 LPCTSTR ret;
01095 TCHAR *varNameEnd;
01096 BOOL dummy;
01097
01098 *varNameLen = 1;
01099
01100 switch ( *varName )
01101 {
01102 case _T('~'):
01103 varNameEnd = varName + 1;
01104 ret = GetEnhancedVar(&varNameEnd, FindArg);
01105 if (!ret)
01106 {
01107 error_syntax(varName);
01108 return NULL;
01109 }
01110 *varNameLen = varNameEnd - varName;
01111 return ret;
01112 case _T('0'):
01113 case _T('1'):
01114 case _T('2'):
01115 case _T('3'):
01116 case _T('4'):
01117 case _T('5'):
01118 case _T('6'):
01119 case _T('7'):
01120 case _T('8'):
01121 case _T('9'):
01122 return FindArg(*varName, &dummy);
01123
01124 case _T('*'):
01125
01126
01127
01128 return bc->raw_params;
01129
01130 case _T('%'):
01131 return _T("%");
01132 }
01133 return NULL;
01134 }
01135
01136 BOOL
01137 SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim)
01138 {
01139 #define APPEND(From, Length) { \
01140 if (Dest + (Length) > DestEnd) \
01141 goto too_long; \
01142 memcpy(Dest, From, (Length) * sizeof(TCHAR)); \
01143 Dest += Length; }
01144 #define APPEND1(Char) { \
01145 if (Dest >= DestEnd) \
01146 goto too_long; \
01147 *Dest++ = Char; }
01148
01149 TCHAR *DestEnd = Dest + CMDLINE_LENGTH - 1;
01150 const TCHAR *Var;
01151 int VarLength;
01152 TCHAR *SubstStart;
01153 TCHAR EndChr;
01154 while (*Src)
01155 {
01156 if (*Src != Delim)
01157 {
01158 APPEND1(*Src++)
01159 continue;
01160 }
01161
01162 Src++;
01163 if (bc && Delim == _T('%'))
01164 {
01165 UINT NameLen;
01166 Var = GetBatchVar(Src, &NameLen);
01167 if (Var != NULL)
01168 {
01169 VarLength = _tcslen(Var);
01170 APPEND(Var, VarLength)
01171 Src += NameLen;
01172 continue;
01173 }
01174 }
01175
01176
01177
01178
01179 SubstStart = Src;
01180 while (*Src != Delim && !(*Src == _T(':') && Src[1] != Delim))
01181 {
01182 if (!*Src)
01183 goto bad_subst;
01184 Src++;
01185 }
01186
01187 EndChr = *Src;
01188 *Src = _T('\0');
01189 Var = GetEnvVarOrSpecial(SubstStart);
01190 *Src++ = EndChr;
01191 if (Var == NULL)
01192 {
01193
01194 if (bc)
01195 continue;
01196 goto bad_subst;
01197 }
01198 VarLength = _tcslen(Var);
01199
01200 if (EndChr == Delim)
01201 {
01202
01203 APPEND(Var, VarLength)
01204 }
01205 else if (*Src == _T('~'))
01206 {
01207
01208
01209 int Start = _tcstol(Src + 1, &Src, 0);
01210 int End = VarLength;
01211 if (Start < 0)
01212 Start += VarLength;
01213 Start = max(Start, 0);
01214 Start = min(Start, VarLength);
01215 if (*Src == _T(','))
01216 {
01217 End = _tcstol(Src + 1, &Src, 0);
01218 End += (End < 0) ? VarLength : Start;
01219 End = max(End, Start);
01220 End = min(End, VarLength);
01221 }
01222 if (*Src++ != Delim)
01223 goto bad_subst;
01224 APPEND(&Var[Start], End - Start);
01225 }
01226 else
01227 {
01228
01229
01230
01231 TCHAR *Old, *New;
01232 DWORD OldLength, NewLength;
01233 BOOL Star = FALSE;
01234 int LastMatch = 0, i = 0;
01235
01236 if (*Src == _T('*'))
01237 {
01238 Star = TRUE;
01239 Src++;
01240 }
01241
01242
01243 Src = _tcschr(Old = Src, _T('='));
01244 if (Src == NULL)
01245 goto bad_subst;
01246 OldLength = Src++ - Old;
01247 if (OldLength == 0)
01248 goto bad_subst;
01249
01250 Src = _tcschr(New = Src, Delim);
01251 if (Src == NULL)
01252 goto bad_subst;
01253 NewLength = Src++ - New;
01254
01255 while (i < VarLength)
01256 {
01257 if (_tcsnicmp(&Var[i], Old, OldLength) == 0)
01258 {
01259 if (!Star)
01260 APPEND(&Var[LastMatch], i - LastMatch)
01261 APPEND(New, NewLength)
01262 i += OldLength;
01263 LastMatch = i;
01264 if (Star)
01265 break;
01266 continue;
01267 }
01268 i++;
01269 }
01270 APPEND(&Var[LastMatch], VarLength - LastMatch)
01271 }
01272 continue;
01273
01274 bad_subst:
01275 Src = SubstStart;
01276 if (!bc)
01277 APPEND1(Delim)
01278 }
01279 *Dest = _T('\0');
01280 return TRUE;
01281 too_long:
01282 ConOutResPrintf(STRING_ALIAS_ERROR);
01283 nErrorLevel = 9023;
01284 return FALSE;
01285 #undef APPEND
01286 #undef APPEND1
01287 }
01288
01289
01290 static LPTSTR FindForVar(TCHAR Var, BOOL *IsParam0)
01291 {
01292 FOR_CONTEXT *Ctx;
01293 *IsParam0 = FALSE;
01294 for (Ctx = fc; Ctx != NULL; Ctx = Ctx->prev)
01295 if ((UINT)(Var - Ctx->firstvar) < Ctx->varcount)
01296 return Ctx->values[Var - Ctx->firstvar];
01297 return NULL;
01298 }
01299
01300 BOOL
01301 SubstituteForVars(TCHAR *Src, TCHAR *Dest)
01302 {
01303 TCHAR *DestEnd = &Dest[CMDLINE_LENGTH - 1];
01304 while (*Src)
01305 {
01306 if (Src[0] == _T('%'))
01307 {
01308 BOOL Dummy;
01309 LPTSTR End = &Src[2];
01310 LPTSTR Value = NULL;
01311
01312 if (Src[1] == _T('~'))
01313 Value = GetEnhancedVar(&End, FindForVar);
01314
01315 if (!Value)
01316 Value = FindForVar(Src[1], &Dummy);
01317
01318 if (Value)
01319 {
01320 if (Dest + _tcslen(Value) > DestEnd)
01321 return FALSE;
01322 Dest = _stpcpy(Dest, Value);
01323 Src = End;
01324 continue;
01325 }
01326 }
01327
01328 if (Dest >= DestEnd)
01329 return FALSE;
01330 *Dest++ = *Src++;
01331 }
01332 *Dest = _T('\0');
01333 return TRUE;
01334 }
01335
01336 LPTSTR
01337 DoDelayedExpansion(LPTSTR Line)
01338 {
01339 TCHAR Buf1[CMDLINE_LENGTH];
01340 TCHAR Buf2[CMDLINE_LENGTH];
01341
01342
01343 if (!SubstituteForVars(Line, Buf1))
01344 return NULL;
01345
01346 if (!bDelayedExpansion || !_tcschr(Buf1, _T('!')))
01347 return cmd_dup(Buf1);
01348
01349
01350
01351
01352 if (!SubstituteVars(Buf1, Buf2, _T('!')))
01353 return NULL;
01354 return cmd_dup(Buf2);
01355 }
01356
01357
01358
01359
01360
01361
01362
01363 BOOL
01364 ReadLine (TCHAR *commandline, BOOL bMore)
01365 {
01366 TCHAR readline[CMDLINE_LENGTH];
01367 LPTSTR ip;
01368
01369
01370 if (bc == NULL)
01371 {
01372 if (bMore)
01373 {
01374 ConOutResPrintf(STRING_MORE);
01375 }
01376 else
01377 {
01378
01379 if (bEcho)
01380 {
01381 if (!bIgnoreEcho)
01382 ConOutChar('\n');
01383 PrintPrompt();
01384 }
01385 }
01386
01387 if (!ReadCommand(readline, CMDLINE_LENGTH - 1))
01388 {
01389 bExit = TRUE;
01390 return FALSE;
01391 }
01392
01393 if (CheckCtrlBreak(BREAK_INPUT))
01394 {
01395 ConOutPuts(_T("\n"));
01396 return FALSE;
01397 }
01398 ip = readline;
01399 }
01400 else
01401 {
01402 ip = ReadBatchLine();
01403 if (!ip)
01404 return FALSE;
01405 }
01406
01407 return SubstituteVars(ip, commandline, _T('%'));
01408 }
01409
01410 static VOID
01411 ProcessInput()
01412 {
01413 PARSED_COMMAND *Cmd;
01414
01415 while (!bCanExit || !bExit)
01416 {
01417 Cmd = ParseCommand(NULL);
01418 if (!Cmd)
01419 continue;
01420
01421 ExecuteCommand(Cmd);
01422 FreeCommand(Cmd);
01423 }
01424 }
01425
01426
01427
01428
01429
01430 BOOL WINAPI BreakHandler (DWORD dwCtrlType)
01431 {
01432
01433 DWORD dwWritten;
01434 INPUT_RECORD rec;
01435 static BOOL SelfGenerated = FALSE;
01436
01437 if ((dwCtrlType != CTRL_C_EVENT) &&
01438 (dwCtrlType != CTRL_BREAK_EVENT))
01439 {
01440 return FALSE;
01441 }
01442 else
01443 {
01444 if(SelfGenerated)
01445 {
01446 SelfGenerated = FALSE;
01447 return TRUE;
01448 }
01449 }
01450
01451 if (!TryEnterCriticalSection(&ChildProcessRunningLock))
01452 {
01453 SelfGenerated = TRUE;
01454 GenerateConsoleCtrlEvent (dwCtrlType, 0);
01455 return TRUE;
01456 }
01457 else
01458 {
01459 LeaveCriticalSection(&ChildProcessRunningLock);
01460 }
01461
01462 rec.EventType = KEY_EVENT;
01463 rec.Event.KeyEvent.bKeyDown = TRUE;
01464 rec.Event.KeyEvent.wRepeatCount = 1;
01465 rec.Event.KeyEvent.wVirtualKeyCode = _T('C');
01466 rec.Event.KeyEvent.wVirtualScanCode = _T('C') - 35;
01467 rec.Event.KeyEvent.uChar.AsciiChar = _T('C');
01468 rec.Event.KeyEvent.uChar.UnicodeChar = _T('C');
01469 rec.Event.KeyEvent.dwControlKeyState = RIGHT_CTRL_PRESSED;
01470
01471 WriteConsoleInput(
01472 hIn,
01473 &rec,
01474 1,
01475 &dwWritten);
01476
01477 bCtrlBreak = TRUE;
01478
01479
01480
01481
01482
01483 return TRUE;
01484 }
01485
01486
01487 VOID AddBreakHandler (VOID)
01488 {
01489 SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE);
01490 }
01491
01492
01493 VOID RemoveBreakHandler (VOID)
01494 {
01495 SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE);
01496 }
01497
01498
01499
01500
01501
01502
01503 #if 0
01504 static VOID
01505 ShowCommands (VOID)
01506 {
01507
01508 ConOutResPuts(STRING_CMD_HELP1);
01509 PrintCommandList();
01510
01511
01512 ConOutResPuts(STRING_CMD_HELP2);
01513
01514 #ifdef FEATURE_ALIASES
01515 ConOutResPuts(STRING_CMD_HELP3);
01516 #endif
01517 #ifdef FEATURE_HISTORY
01518 ConOutResPuts(STRING_CMD_HELP4);
01519 #endif
01520 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
01521 ConOutResPuts(STRING_CMD_HELP5);
01522 #endif
01523 #ifdef FEATURE_DIRECTORY_STACK
01524 ConOutResPuts(STRING_CMD_HELP6);
01525 #endif
01526 #ifdef FEATURE_REDIRECTION
01527 ConOutResPuts(STRING_CMD_HELP7);
01528 #endif
01529 ConOutChar(_T('\n'));
01530 }
01531 #endif
01532
01533 static VOID
01534 ExecuteAutoRunFile(HKEY hkeyRoot)
01535 {
01536 TCHAR autorun[2048];
01537 DWORD len = sizeof autorun;
01538 HKEY hkey;
01539
01540 if (RegOpenKeyEx(hkeyRoot,
01541 _T("SOFTWARE\\Microsoft\\Command Processor"),
01542 0,
01543 KEY_READ,
01544 &hkey ) == ERROR_SUCCESS)
01545 {
01546 if(RegQueryValueEx(hkey,
01547 _T("AutoRun"),
01548 0,
01549 0,
01550 (LPBYTE)autorun,
01551 &len) == ERROR_SUCCESS)
01552 {
01553 if (*autorun)
01554 ParseCommandLine(autorun);
01555 }
01556 RegCloseKey(hkey);
01557 }
01558 }
01559
01560
01561 static VOID
01562 GetCmdLineCommand(TCHAR *commandline, TCHAR *ptr, BOOL AlwaysStrip)
01563 {
01564 TCHAR *LastQuote;
01565
01566 while (_istspace(*ptr))
01567 ptr++;
01568
01569
01570 if (*ptr == _T('"') &&
01571 (LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL)
01572 {
01573 TCHAR *Space;
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584 *LastQuote = _T('\0');
01585 for (Space = ptr + 1; Space < LastQuote; Space++)
01586 {
01587 if (_istspace(*Space))
01588 {
01589 if (!AlwaysStrip &&
01590 !_tcspbrk(ptr, _T("\"&<>@^|")) &&
01591 SearchForExecutable(ptr, commandline))
01592 {
01593
01594 *LastQuote = _T('"');
01595 _tcscpy(commandline, ptr - 1);
01596 return;
01597 }
01598 break;
01599 }
01600 }
01601
01602
01603
01604 _tcscpy(commandline, ptr);
01605 _tcscpy(&commandline[LastQuote - ptr], LastQuote + 1);
01606 return;
01607 }
01608
01609
01610 _tcscpy(commandline, ptr);
01611 }
01612
01613
01614
01615
01616 static VOID
01617 Initialize()
01618 {
01619 HMODULE NtDllModule;
01620 TCHAR commandline[CMDLINE_LENGTH];
01621 TCHAR ModuleName[_MAX_PATH + 1];
01622 TCHAR lpBuffer[2];
01623 INT nExitCode;
01624
01625
01626 TCHAR *ptr, *cmdLine, option = 0;
01627 BOOL AlwaysStrip = FALSE;
01628 BOOL AutoRun = TRUE;
01629
01630
01631 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
01632 GetVersionEx (&osvi);
01633
01634
01635
01636
01637 NtDllModule = GetModuleHandle(TEXT("ntdll.dll"));
01638 if (NtDllModule != NULL)
01639 {
01640 NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess");
01641 NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
01642 }
01643
01644 InitLocale ();
01645
01646
01647 hOut = GetStdHandle (STD_OUTPUT_HANDLE);
01648 hIn = GetStdHandle (STD_INPUT_HANDLE);
01649
01650
01651
01652
01653
01654 if (GetEnvironmentVariable(_T("PROMPT"),lpBuffer, sizeof(lpBuffer) / sizeof(lpBuffer[0])) == 0)
01655 SetEnvironmentVariable (_T("PROMPT"), _T("$P$G"));
01656
01657 #ifdef FEATURE_DIR_STACK
01658
01659 InitDirectoryStack ();
01660 #endif
01661
01662 #ifdef FEATURE_HISTORY
01663
01664 InitHistory();
01665 #endif
01666
01667
01668 if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1))
01669 {
01670 ModuleName[_MAX_PATH] = _T('\0');
01671 SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
01672 }
01673
01674
01675 AddBreakHandler ();
01676
01677
01678 SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
01679
01680 cmdLine = GetCommandLine();
01681 TRACE ("[command args: %s]\n", debugstr_aw(cmdLine));
01682
01683 for (ptr = cmdLine; *ptr; ptr++)
01684 {
01685 if (*ptr == _T('/'))
01686 {
01687 option = _totupper(ptr[1]);
01688 if (option == _T('?'))
01689 {
01690 ConOutResPaging(TRUE,STRING_CMD_HELP8);
01691 nErrorLevel = 1;
01692 bExit = TRUE;
01693 return;
01694 }
01695 else if (option == _T('P'))
01696 {
01697 if (!IsExistingFile (_T("\\autoexec.bat")))
01698 {
01699 #ifdef INCLUDE_CMD_DATE
01700 cmd_date (_T(""));
01701 #endif
01702 #ifdef INCLUDE_CMD_TIME
01703 cmd_time (_T(""));
01704 #endif
01705 }
01706 else
01707 {
01708 ParseCommandLine (_T("\\autoexec.bat"));
01709 }
01710 bCanExit = FALSE;
01711 }
01712 else if (option == _T('A'))
01713 {
01714 bUnicodeOutput = FALSE;
01715 }
01716 else if (option == _T('C') || option == _T('K') || option == _T('R'))
01717 {
01718
01719 break;
01720 }
01721 else if (option == _T('D'))
01722 {
01723 AutoRun = FALSE;
01724 }
01725 else if (option == _T('Q'))
01726 {
01727 bDisableBatchEcho = TRUE;
01728 }
01729 else if (option == _T('S'))
01730 {
01731 AlwaysStrip = TRUE;
01732 }
01733 #ifdef INCLUDE_CMD_COLOR
01734 else if (!_tcsnicmp(ptr, _T("/T:"), 3))
01735 {
01736
01737 wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
01738 SetScreenColor(wDefColor, FALSE);
01739 }
01740 #endif
01741 else if (option == _T('U'))
01742 {
01743 bUnicodeOutput = TRUE;
01744 }
01745 else if (option == _T('V'))
01746 {
01747 bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
01748 }
01749 }
01750 }
01751
01752 if (!*ptr)
01753 {
01754
01755 ConOutResPrintf(STRING_REACTOS_VERSION,
01756 _T(KERNEL_RELEASE_STR),
01757 _T(KERNEL_VERSION_BUILD_STR));
01758 ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n"));
01759 }
01760
01761 if (AutoRun)
01762 {
01763 ExecuteAutoRunFile(HKEY_LOCAL_MACHINE);
01764 ExecuteAutoRunFile(HKEY_CURRENT_USER);
01765 }
01766
01767 if (*ptr)
01768 {
01769
01770 GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
01771 nExitCode = ParseCommandLine(commandline);
01772 if (option != _T('K'))
01773 {
01774 nErrorLevel = nExitCode;
01775 bExit = TRUE;
01776 }
01777 }
01778 }
01779
01780
01781 static VOID Cleanup()
01782 {
01783
01784 if (IsExistingFile (_T("cmdexit.bat")))
01785 {
01786 ConErrResPuts(STRING_CMD_ERROR5);
01787
01788 ParseCommandLine (_T("cmdexit.bat"));
01789 }
01790 else if (IsExistingFile (_T("\\cmdexit.bat")))
01791 {
01792 ConErrResPuts (STRING_CMD_ERROR5);
01793 ParseCommandLine (_T("\\cmdexit.bat"));
01794 }
01795
01796 #ifdef FEATURE_DIECTORY_STACK
01797
01798 DestroyDirectoryStack ();
01799 #endif
01800
01801 #ifdef FEATURE_HISTORY
01802 CleanHistory();
01803 #endif
01804
01805
01806 GetEnvVar(NULL);
01807
01808
01809 RemoveBreakHandler ();
01810 SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
01811 ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
01812 DeleteCriticalSection(&ChildProcessRunningLock);
01813 }
01814
01815
01816
01817
01818 int cmd_main (int argc, const TCHAR *argv[])
01819 {
01820 HANDLE hConsole;
01821 TCHAR startPath[MAX_PATH];
01822 CONSOLE_SCREEN_BUFFER_INFO Info;
01823
01824 InitializeCriticalSection(&ChildProcessRunningLock);
01825 lpOriginalEnvironment = DuplicateEnvironment();
01826
01827 GetCurrentDirectory(MAX_PATH,startPath);
01828 _tchdir(startPath);
01829
01830 SetFileApisToOEM();
01831 InputCodePage= 0;
01832 OutputCodePage = 0;
01833
01834 hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
01835 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
01836 OPEN_EXISTING, 0, NULL);
01837 if (hConsole != INVALID_HANDLE_VALUE)
01838 {
01839 if (!GetConsoleScreenBufferInfo(hConsole, &Info))
01840 {
01841 ConErrFormatMessage(GetLastError());
01842 return(1);
01843 }
01844 wDefColor = Info.wAttributes;
01845 CloseHandle(hConsole);
01846 }
01847
01848 InputCodePage= GetConsoleCP();
01849 OutputCodePage = GetConsoleOutputCP();
01850 CMD_ModuleHandle = GetModuleHandle(NULL);
01851
01852
01853 Initialize();
01854
01855
01856 ProcessInput();
01857
01858
01859 Cleanup();
01860
01861 cmd_free(lpOriginalEnvironment);
01862
01863 cmd_exit(nErrorLevel);
01864 return(nErrorLevel);
01865 }
01866
01867