ReactOS 0.4.15-dev-6052-g2626c72
cmd.c
Go to the documentation of this file.
1/*
2 * CMD.C - command-line interface.
3 *
4 *
5 * History:
6 *
7 * 17 Jun 1994 (Tim Norman)
8 * started.
9 *
10 * 08 Aug 1995 (Matt Rains)
11 * I have cleaned up the source code. changes now bring this source
12 * into guidelines for recommended programming practice.
13 *
14 * A added the the standard FreeDOS GNU licence test to the
15 * initialize() function.
16 *
17 * Started to replace puts() with printf(). this will help
18 * standardize output. please follow my lead.
19 *
20 * I have added some constants to help making changes easier.
21 *
22 * 15 Dec 1995 (Tim Norman)
23 * major rewrite of the code to make it more efficient and add
24 * redirection support (finally!)
25 *
26 * 06 Jan 1996 (Tim Norman)
27 * finished adding redirection support! Changed to use our own
28 * exec code (MUCH thanks to Svante Frey!!)
29 *
30 * 29 Jan 1996 (Tim Norman)
31 * added support for CHDIR, RMDIR, MKDIR, and ERASE, as per
32 * suggestion of Steffan Kaiser
33 *
34 * changed "file not found" error message to "bad command or
35 * filename" thanks to Dustin Norman for noticing that confusing
36 * message!
37 *
38 * changed the format to call internal commands (again) so that if
39 * they want to split their commands, they can do it themselves
40 * (none of the internal functions so far need that much power, anyway)
41 *
42 * 27 Aug 1996 (Tim Norman)
43 * added in support for Oliver Mueller's ALIAS command
44 *
45 * 14 Jun 1997 (Steffan Kaiser)
46 * added ctrl-break handling and error level
47 *
48 * 16 Jun 1998 (Rob Lake)
49 * Runs command.com if /P is specified in command line. Command.com
50 * also stays permanent. If /C is in the command line, starts the
51 * program next in the line.
52 *
53 * 21 Jun 1998 (Rob Lake)
54 * Fixed up /C so that arguments for the program
55 *
56 * 08-Jul-1998 (John P. Price)
57 * Now sets COMSPEC environment variable
58 * misc clean up and optimization
59 * added date and time commands
60 * changed to using spawnl instead of exec. exec does not copy the
61 * environment to the child process!
62 *
63 * 14 Jul 1998 (Hans B Pufal)
64 * Reorganised source to be more efficient and to more closely
65 * follow MS-DOS conventions. (eg %..% environment variable
66 * replacement works form command line as well as batch file.
67 *
68 * New organisation also properly support nested batch files.
69 *
70 * New command table structure is half way towards providing a
71 * system in which COMMAND will find out what internal commands
72 * are loaded
73 *
74 * 24 Jul 1998 (Hans B Pufal) [HBP_003]
75 * Fixed return value when called with /C option
76 *
77 * 27 Jul 1998 John P. Price
78 * added config.h include
79 *
80 * 28 Jul 1998 John P. Price
81 * added showcmds function to show commands and options available
82 *
83 * 07-Aug-1998 (John P Price <linux-guru@gcfl.net>)
84 * Fixed carriage return output to better match MSDOS with echo
85 * on or off. (marked with "JPP 19980708")
86 *
87 * 07-Dec-1998 (Eric Kohl)
88 * First ReactOS release.
89 * Extended length of commandline buffers to 512.
90 *
91 * 13-Dec-1998 (Eric Kohl)
92 * Added COMSPEC environment variable.
93 * Added "/t" support (color) on cmd command line.
94 *
95 * 07-Jan-1999 (Eric Kohl)
96 * Added help text ("cmd /?").
97 *
98 * 25-Jan-1999 (Eric Kohl)
99 * Unicode and redirection safe!
100 * Fixed redirections and piping.
101 * Piping is based on temporary files, but basic support
102 * for anonymous pipes already exists.
103 *
104 * 27-Jan-1999 (Eric Kohl)
105 * Replaced spawnl() by CreateProcess().
106 *
107 * 22-Oct-1999 (Eric Kohl)
108 * Added break handler.
109 *
110 * 15-Dec-1999 (Eric Kohl)
111 * Fixed current directory
112 *
113 * 28-Dec-1999 (Eric Kohl)
114 * Restore window title after program/batch execution
115 *
116 * 03-Feb-2001 (Eric Kohl)
117 * Workaround because argc[0] is NULL under ReactOS
118 *
119 * 23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
120 * %envvar% replacement conflicted with for.
121 *
122 * 30-Apr-2004 (Filip Navara <xnavara@volny.cz>)
123 * Make MakeSureDirectoryPathExistsEx unicode safe.
124 *
125 * 28-Mai-2004
126 * Removed MakeSureDirectoryPathExistsEx.
127 * Use the current directory if GetTempPath fails.
128 *
129 * 12-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
130 * Added ShellExecute call when all else fails to be able to "launch" any file.
131 *
132 * 02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
133 * Remove all hardcode string to En.rc
134 *
135 * 06-May-2005 (Klemens Friedl <frik85@gmail.com>)
136 * Add 'help' command (list all commands plus description)
137 *
138 * 06-jul-2005 (Magnus Olsen <magnus@greatlord.com>)
139 * translate '%errorlevel%' to the internal value.
140 * Add proper memory alloc ProcessInput, the error
141 * handling for memory handling need to be improve
142 */
143
144#include "precomp.h"
145#include <reactos/buildno.h>
146#include <reactos/version.h>
147
149 PVOID, ULONG, PULONG);
151
152BOOL bExit = FALSE; /* Indicates EXIT was typed */
153BOOL bCanExit = TRUE; /* Indicates if this shell is exitable */
154BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */
155BOOL bIgnoreEcho = FALSE; /* Set this to TRUE to prevent a newline, when executing a command */
156static BOOL fSingleCommand = 0; /* When we are executing something passed on the command line after /C or /K */
158INT nErrorLevel = 0; /* Errorlevel of last launched external program */
166
167BOOL bTitleSet = FALSE; /* Indicates whether the console title has been changed and needs to be restored later */
169
172
173/*
174 * Default output file stream translation mode is UTF8, but CMD switches
175 * allow to change it to either UTF16 (/U) or ANSI (/A).
176 */
178
179#ifdef INCLUDE_CMD_COLOR
180WORD wDefColor = 0; /* Default color */
181#endif
182
183/*
184 * convert
185 *
186 * insert commas into a number
187 */
188INT
190{
191 TCHAR temp[39]; /* maximum length with nNumberGroups == 1 */
192 UINT n, iTarget;
193
194 if (len <= 1)
195 return 0;
196
197 n = 0;
198 iTarget = nNumberGroups;
199 if (!nNumberGroups)
200 bPutSeparator = FALSE;
201
202 do
203 {
204 if (iTarget == n && bPutSeparator)
205 {
206 iTarget += nNumberGroups + 1;
207 temp[38 - n++] = cThousandSeparator;
208 }
209 temp[38 - n++] = (TCHAR)(num % 10) + _T('0');
210 num /= 10;
211 } while (num > 0);
212 if (n > len-1)
213 n = len-1;
214
215 memcpy(des, temp + 39 - n, n * sizeof(TCHAR));
216 des[n] = _T('\0');
217
218 return n;
219}
220
221/*
222 * Is a process a console process?
223 */
225{
228 PEB ProcessPeb;
230
232 {
233 return TRUE;
234 }
235
239 if (! NT_SUCCESS(Status))
240 {
241 WARN ("NtQueryInformationProcess failed with status %08x\n", Status);
242 return TRUE;
243 }
245 Process, Info.PebBaseAddress, &ProcessPeb,
246 sizeof(PEB), &BytesRead);
247 if (! NT_SUCCESS(Status) || sizeof(PEB) != BytesRead)
248 {
249 WARN ("Couldn't read virt mem status %08x bytes read %Iu\n", Status, BytesRead);
250 return TRUE;
251 }
252
253 return IMAGE_SUBSYSTEM_WINDOWS_CUI == ProcessPeb.ImageSubsystem;
254}
255
256
257
258#ifdef _UNICODE
259#define SHELLEXECUTETEXT "ShellExecuteExW"
260#else
261#define SHELLEXECUTETEXT "ShellExecuteExA"
262#endif
263
264typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo);
265
267 LPTSTR directory, INT show)
268{
271 MYEX hShExt;
272 BOOL ret;
273
274 TRACE ("RunFile(%s)\n", debugstr_aw(filename));
275 hShell32 = LoadLibrary(_T("SHELL32.DLL"));
276 if (!hShell32)
277 {
278 WARN ("RunFile: couldn't load SHELL32.DLL!\n");
279 return NULL;
280 }
281
283 if (!hShExt)
284 {
285 WARN ("RunFile: couldn't find ShellExecuteExA/W in SHELL32.DLL!\n");
287 return NULL;
288 }
289
290 TRACE ("RunFile: ShellExecuteExA/W is at %x\n", hShExt);
291
292 memset(&sei, 0, sizeof sei);
293 sei.cbSize = sizeof sei;
294 sei.fMask = flags;
295 sei.lpFile = filename;
296 sei.lpParameters = params;
298 sei.nShow = show;
299 ret = hShExt(&sei);
300
301 TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret);
302
304 return ret ? sei.hProcess : NULL;
305}
306
307
308static VOID
310{
311 TCHAR szNewTitle[MAX_PATH];
312
313 if (!pszTitle)
314 return;
315
316 /* Don't do anything if we run inside a batch file, or we are just running a single command */
317 if (bc || (fSingleCommand == 1))
318 return;
319
320 /* Save the original console title and build a new one */
322 StringCchPrintf(szNewTitle, ARRAYSIZE(szNewTitle),
323 _T("%s - %s"), szCurTitle, pszTitle);
324 bTitleSet = TRUE;
325 ConSetTitle(szNewTitle);
326}
327
328static VOID
330{
331 /* Restore the original console title */
332 if (!bc && bTitleSet)
333 {
336 }
337}
338
339/*
340 * This command (in First) was not found in the command table
341 *
342 * Full - output buffer to hold whole command line
343 * First - first word on command line
344 * Rest - rest of command line
345 */
346static INT
348{
349 TCHAR *first, *rest, *dot;
350 DWORD dwExitCode = 0;
351 TCHAR *FirstEnd;
352 TCHAR szFullName[MAX_PATH];
353 TCHAR szFullCmdLine[CMDLINE_LENGTH];
354
355 TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest));
356
357 /* Though it was already parsed once, we have a different set of rules
358 for parsing before we pass to CreateProcess */
359 if (First[0] == _T('/') || (First[0] && First[1] == _T(':')))
360 {
361 /* Use the entire first word as the program name (no change) */
362 FirstEnd = First + _tcslen(First);
363 }
364 else
365 {
366 /* If present in the first word, spaces and ,;=/ end the program
367 * name and become the beginning of its parameters. */
368 BOOL bInside = FALSE;
369 for (FirstEnd = First; *FirstEnd; FirstEnd++)
370 {
371 if (!bInside && (_istspace(*FirstEnd) || _tcschr(_T(",;=/"), *FirstEnd)))
372 break;
373 bInside ^= *FirstEnd == _T('"');
374 }
375 }
376
377 /* Copy the new first/rest into the buffer */
378 rest = &Full[FirstEnd - First + 1];
379 _tcscpy(rest, FirstEnd);
380 _tcscat(rest, Rest);
381 first = Full;
382 *FirstEnd = _T('\0');
384
385 /* check for a drive change */
386 if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
387 {
388 BOOL working = TRUE;
390 {
391 /* Guess they changed disc or something, handle that gracefully and get to root */
392 TCHAR str[4];
393 str[0]=first[0];
394 str[1]=_T(':');
395 str[2]=_T('\\');
396 str[3]=0;
397 working = SetCurrentDirectory(str);
398 }
399
400 if (!working) ConErrResPuts (STRING_FREE_ERROR1);
401 return !working;
402 }
403
404 /* get the PATH environment variable and parse it */
405 /* search the PATH environment variable for the binary */
407 if (!SearchForExecutable(First, szFullName))
408 {
410 return 1;
411 }
412
413 /* Set the new console title */
414 FirstEnd = first + (FirstEnd - First); /* Point to the separating NULL in the full built string */
415 *FirstEnd = _T(' ');
417
418 /* check if this is a .BAT or .CMD file */
419 dot = _tcsrchr (szFullName, _T('.'));
420 if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd"))))
421 {
422 while (*rest == _T(' '))
423 rest++;
424
425 *FirstEnd = _T('\0');
426 TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
427 dwExitCode = Batch(szFullName, first, rest, Cmd);
428 }
429 else
430 {
431 /* exec the program */
433 STARTUPINFO stui;
434
435 /* build command line for CreateProcess(): FullName + " " + rest */
436 BOOL quoted = !!_tcschr(First, _T(' '));
437 _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T(""));
438 _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
439 _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
440
441 if (*rest)
442 {
443 _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
444 _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
445 }
446
447 TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine));
448
449 /* fill startup info */
450 memset(&stui, 0, sizeof(stui));
451 stui.cb = sizeof(stui);
452 stui.lpTitle = Full;
455
456 /* Set the console to standard mode */
459
460 if (CreateProcess(szFullName,
461 szFullCmdLine,
462 NULL,
463 NULL,
464 TRUE,
465 0,
466 NULL,
467 NULL,
468 &stui,
469 &prci))
470 {
471 CloseHandle(prci.hThread);
472 }
473 else
474 {
475 // See if we can run this with ShellExecute() ie myfile.xls
477 szFullName,
478 rest,
479 NULL,
481 }
482
483 *FirstEnd = _T('\0');
484
485 if (prci.hProcess != NULL)
486 {
487 if (bc != NULL || fSingleCommand != 0 || IsConsoleProcess(prci.hProcess))
488 {
489 /* when processing a batch file or starting console processes: execute synchronously */
492
494
496
497 GetExitCodeProcess(prci.hProcess, &dwExitCode);
498 nErrorLevel = (INT)dwExitCode;
499 }
500 CloseHandle(prci.hProcess);
501 }
502 else
503 {
504 TRACE ("[ShellExecute failed!: %s]\n", debugstr_aw(Full));
506 dwExitCode = 1;
507 }
508
509 /* Restore the default console mode */
514 }
515
516 /* Update the local code page cache */
517 {
518 UINT uNewInputCodePage = GetConsoleCP();
519 UINT uNewOutputCodePage = GetConsoleOutputCP();
520
521 if ((InputCodePage != uNewInputCodePage) ||
522 (OutputCodePage != uNewOutputCodePage))
523 {
524 InputCodePage = uNewInputCodePage;
525 OutputCodePage = uNewOutputCodePage;
526
527 /* Reset the current thread UI language */
530 {
532 }
533 /* Update the streams cached code page */
535
536 /* Update the locale as well */
537 InitLocale();
538 }
539 }
540
541 /* Restore the original console title */
543
544 return dwExitCode;
545}
546
547
548/*
549 * Look through the internal commands and determine whether or not this
550 * command is one of them. If it is, call the command. If not, call
551 * execute to run it as an external program.
552 *
553 * first - first word on command line
554 * rest - rest of command line
555 */
556INT
558{
559 TCHAR *com;
560 TCHAR *cp;
561 LPTSTR param; /* Pointer to command's parameters */
562 INT cl;
563 LPCOMMAND cmdptr;
564 BOOL nointernal = FALSE;
565 INT ret;
566
567 TRACE ("DoCommand: (\'%s\' \'%s\')\n", debugstr_aw(first), debugstr_aw(rest));
568
569 /* Full command line */
570 com = cmd_alloc((_tcslen(first) + _tcslen(rest) + 2) * sizeof(TCHAR));
571 if (com == NULL)
572 {
574 return 1;
575 }
576
577 /* If present in the first word, these characters end the name of an
578 * internal command and become the beginning of its parameters. */
579 cp = first + _tcscspn(first, _T("\t +,/;=[]"));
580
581 for (cl = 0; cl < (cp - first); cl++)
582 {
583 /* These characters do it too, but if one of them is present,
584 * then we check to see if the word is a file name and skip
585 * checking for internal commands if so.
586 * This allows running programs with names like "echo.exe" */
587 if (_tcschr(_T(".:\\"), first[cl]))
588 {
589 TCHAR tmp = *cp;
590 *cp = _T('\0');
591 nointernal = IsExistingFile(first);
592 *cp = tmp;
593 break;
594 }
595 }
596
597 /* Scan internal command table */
598 for (cmdptr = cmds; !nointernal && cmdptr->name; cmdptr++)
599 {
600 if (!_tcsnicmp(first, cmdptr->name, cl) && cmdptr->name[cl] == _T('\0'))
601 {
602 _tcscpy(com, first);
603 _tcscat(com, rest);
604 param = &com[cl];
605
606 /* Skip over whitespace to rest of line, exclude 'echo' command */
607 if (_tcsicmp(cmdptr->name, _T("echo")) != 0)
608 {
609 while (_istspace(*param))
610 param++;
611 }
612
613 /* Set the new console title */
614 SetConTitle(com);
615
616 ret = cmdptr->func(param);
617
618 /* Restore the original console title */
620
621 cmd_free(com);
622 return ret;
623 }
624 }
625
626 ret = Execute(com, first, rest, Cmd);
627 cmd_free(com);
628 return ret;
629}
630
631
632/*
633 * process the command line and execute the appropriate functions
634 * full input/output redirection and piping are supported
635 */
637{
638 INT Ret = 0;
640
642 if (!Cmd)
643 {
644 /* Return an adequate error code */
645 return (!bParseError ? 0 : 1);
646 }
647
648 Ret = ExecuteCommand(Cmd);
650 return Ret;
651}
652
653/* Execute a command without waiting for it to finish. If it's an internal
654 * command or batch file, we must create a new cmd.exe process to handle it.
655 * TODO: For now, this just always creates a cmd.exe process.
656 * This works, but is inefficient for running external programs,
657 * which could just be run directly. */
658static HANDLE
660{
661 TCHAR CmdPath[MAX_PATH];
662 TCHAR CmdParams[CMDLINE_LENGTH], *ParamsEnd;
663 STARTUPINFO stui;
665
666 /* Get the path to cmd.exe */
667 GetModuleFileName(NULL, CmdPath, ARRAYSIZE(CmdPath));
668
669 /* Build the parameter string to pass to cmd.exe */
670 ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\""));
671 ParamsEnd = UnparseCommand(Cmd, ParamsEnd, &CmdParams[CMDLINE_LENGTH - 2]);
672 if (!ParamsEnd)
673 {
675 return NULL;
676 }
677 _tcscpy(ParamsEnd, _T("\""));
678
679 memset(&stui, 0, sizeof stui);
680 stui.cb = sizeof(STARTUPINFO);
681 if (!CreateProcess(CmdPath, CmdParams, NULL, NULL, TRUE, 0,
682 NULL, NULL, &stui, &prci))
683 {
685 return NULL;
686 }
687
688 CloseHandle(prci.hThread);
689 return prci.hProcess;
690}
691
692static INT
694{
695#ifdef FEATURE_REDIRECTION
696 HANDLE hInput = NULL;
700 INT nProcesses = 0;
701 DWORD dwExitCode;
702
703 /* Do all but the last pipe command */
704 do
705 {
706 HANDLE hPipeRead, hPipeWrite;
707 if (nProcesses > (MAXIMUM_WAIT_OBJECTS - 2))
708 {
710 goto failed;
711 }
712
713 /* Create the pipe that this process will write into.
714 * Make the handles non-inheritable initially, because this
715 * process shouldn't inherit the reading handle. */
716 if (!CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0))
717 {
719 goto failed;
720 }
721
722 /* The writing side of the pipe is STDOUT for this process */
724 SetStdHandle(STD_OUTPUT_HANDLE, hPipeWrite);
725
726 /* Execute it (error check is done later for easier cleanup) */
727 hProcess[nProcesses] = ExecuteAsync(Cmd->Subcommands);
728 CloseHandle(hPipeWrite);
729 if (hInput)
730 CloseHandle(hInput);
731
732 /* The reading side of the pipe will be STDIN for the next process */
734 SetStdHandle(STD_INPUT_HANDLE, hPipeRead);
735 hInput = hPipeRead;
736
737 if (!hProcess[nProcesses])
738 goto failed;
739 nProcesses++;
740
741 Cmd = Cmd->Subcommands->Next;
742 } while (Cmd->Type == C_PIPE);
743
744 /* The last process uses the original STDOUT */
745 SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
746 hProcess[nProcesses] = ExecuteAsync(Cmd);
747 if (!hProcess[nProcesses])
748 goto failed;
749 nProcesses++;
750 CloseHandle(hInput);
751 SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
752
753 /* Wait for all processes to complete */
757
758 /* Use the exit code of the last process in the pipeline */
759 GetExitCodeProcess(hProcess[nProcesses - 1], &dwExitCode);
760 nErrorLevel = (INT)dwExitCode;
761
762 while (--nProcesses >= 0)
763 CloseHandle(hProcess[nProcesses]);
764 return nErrorLevel;
765
766failed:
767 if (hInput)
768 CloseHandle(hInput);
769 while (--nProcesses >= 0)
770 {
771 TerminateProcess(hProcess[nProcesses], 0);
772 CloseHandle(hProcess[nProcesses]);
773 }
774 SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
775 SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
776#endif
777
778 return nErrorLevel;
779}
780
781INT
784{
785#define SeenGoto() \
786 (bc && bc->current == NULL)
787
788 PARSED_COMMAND *Sub;
789 LPTSTR First, Rest;
790 INT Ret = 0;
791
792 /* If we don't have any command, or if this is REM, ignore it */
793 if (!Cmd || (Cmd->Type == C_REM))
794 return 0;
795 /*
796 * Do not execute any command if we are about to exit CMD, or about to
797 * change batch execution context, e.g. in case of a CALL / GOTO / EXIT.
798 */
799 if (bExit || SeenGoto())
800 return 0;
801
802 if (!PerformRedirection(Cmd->Redirections))
803 return 1;
804
805 switch (Cmd->Type)
806 {
807 case C_COMMAND:
808 Ret = 1;
809 First = DoDelayedExpansion(Cmd->Command.First);
810 if (First)
811 {
812 Rest = DoDelayedExpansion(Cmd->Command.Rest);
813 if (Rest)
814 {
815 Ret = DoCommand(First, Rest, Cmd);
816 cmd_free(Rest);
817 }
819 }
820 /* Fall through */
821 case C_REM:
822 break;
823
824 case C_QUIET:
825 case C_BLOCK:
826 case C_MULTI:
827 for (Sub = Cmd->Subcommands; Sub && !SeenGoto(); Sub = Sub->Next)
828 Ret = ExecuteCommand(Sub);
829 break;
830
831 case C_OR:
832 Sub = Cmd->Subcommands;
833 Ret = ExecuteCommand(Sub);
834 if ((Ret != 0) && !SeenGoto())
835 {
836 nErrorLevel = Ret;
837 Ret = ExecuteCommand(Sub->Next);
838 }
839 break;
840
841 case C_AND:
842 Sub = Cmd->Subcommands;
843 Ret = ExecuteCommand(Sub);
844 if ((Ret == 0) && !SeenGoto())
845 Ret = ExecuteCommand(Sub->Next);
846 break;
847
848 case C_PIPE:
849 Ret = ExecutePipeline(Cmd);
850 break;
851
852 case C_FOR:
853 Ret = ExecuteFor(Cmd);
854 break;
855
856 case C_IF:
857 Ret = ExecuteIf(Cmd);
858 break;
859 }
860
861 UndoRedirection(Cmd->Redirections, NULL);
862 return Ret;
863
864#undef SeenGoto
865}
866
867INT
870{
871 /* Echo the reconstructed command line */
872 if (bEcho && !bDisableBatchEcho && Cmd && (Cmd->Type != C_QUIET))
873 {
874 if (!bIgnoreEcho)
875 ConOutChar(_T('\n'));
876 PrintPrompt();
878 ConOutChar(_T('\n'));
879 }
880
881 /* Run the command */
882 return ExecuteCommand(Cmd);
883}
884
885LPTSTR
887{
888 static LPTSTR ret = NULL;
889 UINT size;
890
891 cmd_free(ret);
892 ret = NULL;
893 size = GetEnvironmentVariable(varName, NULL, 0);
894 if (size > 0)
895 {
896 ret = cmd_alloc(size * sizeof(TCHAR));
897 if (ret != NULL)
898 GetEnvironmentVariable(varName, ret, size + 1);
899 }
900 return ret;
901}
902
905{
906 static TCHAR ret[MAX_PATH];
907
908 LPTSTR var = GetEnvVar(varName);
909 if (var)
910 return var;
911
912 /* The environment variable doesn't exist, look for
913 * a "special" one only if extensions are enabled. */
915 return NULL;
916
917 /* %CD% */
918 if (_tcsicmp(varName, _T("CD")) == 0)
919 {
921 return ret;
922 }
923 /* %DATE% */
924 else if (_tcsicmp(varName, _T("DATE")) == 0)
925 {
926 return GetDateString();
927 }
928 /* %TIME% */
929 else if (_tcsicmp(varName, _T("TIME")) == 0)
930 {
931 return GetTimeString();
932 }
933 /* %RANDOM% */
934 else if (_tcsicmp(varName, _T("RANDOM")) == 0)
935 {
936 /* Get random number */
937 _itot(rand(), ret, 10);
938 return ret;
939 }
940 /* %CMDCMDLINE% */
941 else if (_tcsicmp(varName, _T("CMDCMDLINE")) == 0)
942 {
943 return GetCommandLine();
944 }
945 /* %CMDEXTVERSION% */
946 else if (_tcsicmp(varName, _T("CMDEXTVERSION")) == 0)
947 {
948 /* Set Command Extensions version number to CMDEXTVERSION */
949 _itot(CMDEXTVERSION, ret, 10);
950 return ret;
951 }
952 /* %ERRORLEVEL% */
953 else if (_tcsicmp(varName, _T("ERRORLEVEL")) == 0)
954 {
955 _itot(nErrorLevel, ret, 10);
956 return ret;
957 }
958#if (NTDDI_VERSION >= NTDDI_WIN7)
959 /* Available in Win7+, even if the underlying API is available in Win2003+ */
960 /* %HIGHESTNUMANODENUMBER% */
961 else if (_tcsicmp(varName, _T("HIGHESTNUMANODENUMBER")) == 0)
962 {
963 ULONG NumaNodeNumber = 0;
964 GetNumaHighestNodeNumber(&NumaNodeNumber);
965 _itot(NumaNodeNumber, ret, 10);
966 return ret;
967 }
968#endif
969
970 return NULL;
971}
972
973/* Handle the %~var syntax */
974static PCTSTR
976 IN OUT PCTSTR* pFormat,
977 IN BOOL (*GetVar)(TCHAR, PCTSTR*, BOOL*))
978{
979 static const TCHAR ModifierTable[] = _T("dpnxfsatz");
980 enum {
981 M_DRIVE = 1, /* D: drive letter */
982 M_PATH = 2, /* P: path */
983 M_NAME = 4, /* N: filename */
984 M_EXT = 8, /* X: extension */
985 M_FULL = 16, /* F: full path (drive+path+name+ext) */
986 M_SHORT = 32, /* S: full path (drive+path+name+ext), use short names */
987 M_ATTR = 64, /* A: attributes */
988 M_TIME = 128, /* T: modification time */
989 M_SIZE = 256, /* Z: file size */
990 } Modifiers = 0;
991
992 PCTSTR Format, FormatEnd;
993 PCTSTR PathVarName = NULL;
994 PCTSTR Variable;
995 PCTSTR VarEnd;
996 BOOL VariableIsParam0;
997 TCHAR FullPath[MAX_PATH];
998 TCHAR FixedPath[MAX_PATH];
1000 HANDLE hFind;
1001 WIN32_FIND_DATA w32fd;
1002 PTCHAR In, Out;
1003
1004 static TCHAR Result[CMDLINE_LENGTH];
1005
1006 /* Check whether the current character is a recognized variable.
1007 * If it is not, then restore the previous one: there is indeed
1008 * ambiguity between modifier characters and FOR variables;
1009 * the rule that CMD uses is to pick the longest possible match.
1010 * This case can happen if we have a FOR-variable specification
1011 * of the following form:
1012 *
1013 * %~<modifiers><actual FOR variable character><other characters>
1014 *
1015 * where the FOR variable character is also a similar to a modifier,
1016 * but should not be interpreted as is, and the following other
1017 * characters are not part of the possible modifier characters, and
1018 * are unrelated to the FOR variable (they can be part of a command).
1019 * For example, if there is a %n variable, then out of %~anxnd,
1020 * %~anxn will be substituted rather than just %~an.
1021 *
1022 * In the following examples, all characters 'd','p','n','x' are valid modifiers.
1023 *
1024 * 1. In this example, the FOR variable character is 'x' and the actual
1025 * modifiers are 'dpn'. Parsing will first determine that 'dpnx'
1026 * are modifiers, with the possible (last) valid variable being 'x',
1027 * and will stop at the letter 'g'. Since 'g' is not a valid
1028 * variable, then the actual variable is the lattest one 'x',
1029 * and the modifiers are then actually 'dpn'.
1030 * The FOR-loop will then display the %x variable formatted with 'dpn'
1031 * and will append any other characters following, 'g'.
1032 *
1033 * C:\Temp>for %x in (foo.exe bar.txt) do @echo %~dpnxg
1034 * C:\Temp\foog
1035 * C:\Temp\barg
1036 *
1037 *
1038 * 2. In this second example, the FOR variable character is 'g' and
1039 * the actual modifiers are 'dpnx'. Parsing will determine also that
1040 * the possible (last) valid variable could be 'x', but since it's
1041 * not present in the FOR-variables list, it won't be the case.
1042 * This means that the actual FOR variable character must follow,
1043 * in this case, 'g'.
1044 *
1045 * C:\Temp>for %g in (foo.exe bar.txt) do @echo %~dpnxg
1046 * C:\Temp\foo.exe
1047 * C:\Temp\bar.txt
1048 */
1049
1050 /* First, go through as many modifier characters as possible */
1051 FormatEnd = Format = *pFormat;
1052 while (*FormatEnd && _tcschr(ModifierTable, _totlower(*FormatEnd)))
1053 ++FormatEnd;
1054
1055 if (*FormatEnd == _T('$'))
1056 {
1057 /* $PATH: syntax */
1058 PathVarName = FormatEnd + 1;
1059 FormatEnd = _tcschr(PathVarName, _T(':'));
1060 if (!FormatEnd)
1061 return NULL;
1062
1063 /* Must be immediately followed by the variable */
1064 if (!GetVar(*++FormatEnd, &Variable, &VariableIsParam0))
1065 return NULL;
1066 }
1067 else
1068 {
1069 /* Backtrack if necessary to get a variable name match */
1070 while (!GetVar(*FormatEnd, &Variable, &VariableIsParam0))
1071 {
1072 if (FormatEnd == Format)
1073 return NULL;
1074 --FormatEnd;
1075 }
1076 }
1077
1078 *pFormat = FormatEnd + 1;
1079
1080 /* If the variable is empty, return an empty string */
1081 if (!Variable || !*Variable)
1082 return _T("");
1083
1084 /* Exclude the leading and trailing quotes */
1085 VarEnd = &Variable[_tcslen(Variable)];
1086 if (*Variable == _T('"'))
1087 {
1088 ++Variable;
1089 if (VarEnd > Variable && VarEnd[-1] == _T('"'))
1090 --VarEnd;
1091 }
1092
1093 if ((ULONG_PTR)VarEnd - (ULONG_PTR)Variable >= sizeof(Result))
1094 return _T("");
1095 memcpy(Result, Variable, (ULONG_PTR)VarEnd - (ULONG_PTR)Variable);
1096 Result[VarEnd - Variable] = _T('\0');
1097
1098 /* Now determine the actual modifiers */
1099 for (; Format < FormatEnd && *Format != _T('$'); ++Format)
1100 Modifiers |= 1 << (_tcschr(ModifierTable, _totlower(*Format)) - ModifierTable);
1101
1102 if (PathVarName)
1103 {
1104 /* $PATH: syntax - search the directories listed in the
1105 * specified environment variable for the file */
1106 PTSTR PathVar;
1107 ((PTSTR)FormatEnd)[-1] = _T('\0'); // FIXME: HACK!
1108 PathVar = GetEnvVar(PathVarName);
1109 ((PTSTR)FormatEnd)[-1] = _T(':');
1110 if (!PathVar ||
1111 !SearchPath(PathVar, Result, NULL, ARRAYSIZE(FullPath), FullPath, NULL))
1112 {
1113 return _T("");
1114 }
1115 }
1116 else if (Modifiers == 0)
1117 {
1118 /* For plain %~var with no modifiers, just return the variable without quotes */
1119 return Result;
1120 }
1121 else if (VariableIsParam0)
1122 {
1123 /* Special case: If the variable is %0 and modifier characters are present,
1124 * use the batch file's path (which includes the .bat/.cmd extension)
1125 * rather than the actual %0 variable (which might not). */
1126 ASSERT(bc);
1127 _tcscpy(FullPath, bc->BatchFilePath);
1128 }
1129 else
1130 {
1131 /* Convert the variable, now without quotes, to a full path */
1132 if (!GetFullPathName(Result, ARRAYSIZE(FullPath), FullPath, NULL))
1133 return _T("");
1134 }
1135
1136 /* Next step is to change the path to fix letter case (e.g.
1137 * C:\ReAcToS -> C:\ReactOS) and, if requested with the S modifier,
1138 * replace long filenames with short. */
1139
1140 In = FullPath;
1141 Out = FixedPath;
1142
1143 /* Copy drive letter */
1144 *Out++ = *In++;
1145 *Out++ = *In++;
1146 *Out++ = *In++;
1147 /* Loop over each \-separated component in the path */
1148 do {
1149 TCHAR *Next = _tcschr(In, _T('\\'));
1150 if (Next)
1151 *Next++ = _T('\0');
1152 /* Use FindFirstFile to get the correct name */
1153 if (Out + _tcslen(In) + 1 >= &FixedPath[ARRAYSIZE(FixedPath)])
1154 return _T("");
1155 _tcscpy(Out, In);
1156 hFind = FindFirstFile(FixedPath, &w32fd);
1157 /* If it doesn't exist, just leave the name as it was given */
1158 if (hFind != INVALID_HANDLE_VALUE)
1159 {
1160 PTSTR FixedComponent = w32fd.cFileName;
1161 if (*w32fd.cAlternateFileName &&
1162 ((Modifiers & M_SHORT) || !_tcsicmp(In, w32fd.cAlternateFileName)))
1163 {
1164 FixedComponent = w32fd.cAlternateFileName;
1165 }
1166 FindClose(hFind);
1167
1168 if (Out + _tcslen(FixedComponent) + 1 >= &FixedPath[ARRAYSIZE(FixedPath)])
1169 return _T("");
1170 _tcscpy(Out, FixedComponent);
1171 }
1172 Filename = Out;
1173 Out += _tcslen(Out);
1174 *Out++ = _T('\\');
1175
1176 In = Next;
1177 } while (In != NULL);
1178 Out[-1] = _T('\0');
1179
1180 /* Build the result string. Start with attributes, modification time, and
1181 * file size. If the file didn't exist, these fields will all be empty. */
1182 Out = Result;
1183 if (hFind != INVALID_HANDLE_VALUE)
1184 {
1185 if (Modifiers & M_ATTR)
1186 {
1187 static const struct {
1188 TCHAR Character;
1189 WORD Value;
1190 } *Attrib, Table[] = {
1191 { _T('d'), FILE_ATTRIBUTE_DIRECTORY },
1192 { _T('r'), FILE_ATTRIBUTE_READONLY },
1193 { _T('a'), FILE_ATTRIBUTE_ARCHIVE },
1194 { _T('h'), FILE_ATTRIBUTE_HIDDEN },
1195 { _T('s'), FILE_ATTRIBUTE_SYSTEM },
1196 { _T('c'), FILE_ATTRIBUTE_COMPRESSED },
1197 { _T('o'), FILE_ATTRIBUTE_OFFLINE },
1198 { _T('t'), FILE_ATTRIBUTE_TEMPORARY },
1200#if (NTDDI_VERSION >= NTDDI_WIN8)
1202 { _T('x'), FILE_ATTRIBUTE_NO_SCRUB_DATA /* 0x20000 */ },
1203#endif
1204 };
1205 for (Attrib = Table; Attrib != &Table[ARRAYSIZE(Table)]; Attrib++)
1206 {
1207 *Out++ = w32fd.dwFileAttributes & Attrib->Value
1208 ? Attrib->Character
1209 : _T('-');
1210 }
1211 *Out++ = _T(' ');
1212 }
1213 if (Modifiers & M_TIME)
1214 {
1215 FILETIME ft;
1216 SYSTEMTIME st;
1217 FileTimeToLocalFileTime(&w32fd.ftLastWriteTime, &ft);
1218 FileTimeToSystemTime(&ft, &st);
1219
1220 Out += FormatDate(Out, &st, TRUE);
1221 *Out++ = _T(' ');
1222 Out += FormatTime(Out, &st);
1223 *Out++ = _T(' ');
1224 }
1225 if (Modifiers & M_SIZE)
1226 {
1228 Size.LowPart = w32fd.nFileSizeLow;
1229 Size.HighPart = w32fd.nFileSizeHigh;
1230 Out += _stprintf(Out, _T("%I64u "), Size.QuadPart);
1231 }
1232 }
1233
1234 /* When using the path-searching syntax or the S modifier,
1235 * at least part of the file path is always included.
1236 * If none of the DPNX modifiers are present, include the full path */
1237 if (PathVarName || (Modifiers & M_SHORT))
1238 if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0)
1239 Modifiers |= M_FULL;
1240
1241 /* Now add the requested parts of the name.
1242 * With the F modifier, add all parts to form the full path. */
1243 Extension = _tcsrchr(Filename, _T('.'));
1244 if (Modifiers & (M_DRIVE | M_FULL))
1245 {
1246 *Out++ = FixedPath[0];
1247 *Out++ = FixedPath[1];
1248 }
1249 if (Modifiers & (M_PATH | M_FULL))
1250 {
1251 memcpy(Out, &FixedPath[2], (ULONG_PTR)Filename - (ULONG_PTR)&FixedPath[2]);
1252 Out += Filename - &FixedPath[2];
1253 }
1254 if (Modifiers & (M_NAME | M_FULL))
1255 {
1256 while (*Filename && Filename != Extension)
1257 *Out++ = *Filename++;
1258 }
1259 if (Modifiers & (M_EXT | M_FULL))
1260 {
1261 if (Extension)
1263 }
1264
1265 /* Trim trailing space which otherwise would appear as a
1266 * result of using the A/T/Z modifiers but no others. */
1267 while (Out != &Result[0] && Out[-1] == _T(' '))
1268 Out--;
1269 *Out = _T('\0');
1270
1271 return Result;
1272}
1273
1274static PCTSTR
1276 IN PCTSTR varName,
1277 OUT PUINT varNameLen)
1278{
1279 PCTSTR ret;
1280 PCTSTR varNameEnd;
1281
1282 *varNameLen = 1;
1283
1284 switch (*varName)
1285 {
1286 case _T('~'):
1287 {
1288 varNameEnd = varName + 1;
1289 ret = GetEnhancedVar(&varNameEnd, FindArg);
1290 if (!ret)
1291 {
1292 ParseErrorEx(varName);
1293 return NULL;
1294 }
1295 *varNameLen = varNameEnd - varName;
1296 return ret;
1297 }
1298
1299 case _T('0'):
1300 case _T('1'):
1301 case _T('2'):
1302 case _T('3'):
1303 case _T('4'):
1304 case _T('5'):
1305 case _T('6'):
1306 case _T('7'):
1307 case _T('8'):
1308 case _T('9'):
1309 {
1310 BOOL dummy;
1311 if (!FindArg(*varName, &ret, &dummy))
1312 return NULL;
1313 else
1314 return ret;
1315 }
1316
1317 case _T('*'):
1318 /* Copy over the raw params (not including the batch file name) */
1319 return bc->raw_params;
1320
1321 case _T('%'):
1322 return _T("%");
1323 }
1324 return NULL;
1325}
1326
1327BOOL
1329 IN PCTSTR Src,
1330 OUT size_t* SrcIncLen, // VarNameLen
1331 OUT PTCHAR Dest,
1332 IN PTCHAR DestEnd,
1333 OUT size_t* DestIncLen,
1334 IN TCHAR Delim)
1335{
1336#define APPEND(From, Length) \
1337do { \
1338 if (Dest + (Length) > DestEnd) \
1339 goto too_long; \
1340 memcpy(Dest, (From), (Length) * sizeof(TCHAR)); \
1341 Dest += (Length); \
1342} while (0)
1343
1344#define APPEND1(Char) \
1345do { \
1346 if (Dest >= DestEnd) \
1347 goto too_long; \
1348 *Dest++ = (Char); \
1349} while (0)
1350
1351 PCTSTR Var;
1352 PCTSTR Start, End, SubstStart;
1353 TCHAR EndChr;
1354 size_t VarLength;
1355
1356 Start = Src;
1357 End = Dest;
1358 *SrcIncLen = 0;
1359 *DestIncLen = 0;
1360
1361 if (!Delim)
1362 return FALSE;
1363 if (*Src != Delim)
1364 return FALSE;
1365
1366 ++Src;
1367
1368 /* If we are already at the end of the string, fail the substitution */
1369 SubstStart = Src;
1370 if (!*Src || *Src == _T('\r') || *Src == _T('\n'))
1371 goto bad_subst;
1372
1373 if (bc && Delim == _T('%'))
1374 {
1375 UINT NameLen;
1376 Var = GetBatchVar(Src, &NameLen);
1377 if (!Var && bParseError)
1378 {
1379 /* Return the partially-parsed command to be
1380 * echoed for error diagnostics purposes. */
1381 APPEND1(Delim);
1382 APPEND(Src, _tcslen(Src) + 1);
1383 return FALSE;
1384 }
1385 if (Var != NULL)
1386 {
1387 VarLength = _tcslen(Var);
1388 APPEND(Var, VarLength);
1389 Src += NameLen;
1390 goto success;
1391 }
1392 }
1393
1394 /* Find the end of the variable name. A colon (:) will usually
1395 * end the name and begin the optional modifier, but not if it
1396 * is immediately followed by the delimiter (%VAR:%). */
1397 SubstStart = Src;
1398 while (*Src && *Src != Delim && !(*Src == _T(':') && Src[1] != Delim))
1399 {
1400 ++Src;
1401 }
1402 /* If we are either at the end of the string, or the delimiter
1403 * has been repeated more than once, fail the substitution. */
1404 if (!*Src || Src == SubstStart)
1405 goto bad_subst;
1406
1407 EndChr = *Src;
1408 *(PTSTR)Src = _T('\0'); // FIXME: HACK!
1409 Var = GetEnvVarOrSpecial(SubstStart);
1410 *(PTSTR)Src++ = EndChr;
1411 if (Var == NULL)
1412 {
1413 /* In a batch context, %NONEXISTENT% "expands" to an
1414 * empty string, otherwise fail the substitution. */
1415 if (bc)
1416 goto success;
1417 goto bad_subst;
1418 }
1419 VarLength = _tcslen(Var);
1420
1421 if (EndChr == Delim)
1422 {
1423 /* %VAR% - use as-is */
1424 APPEND(Var, VarLength);
1425 }
1426 else if (*Src == _T('~'))
1427 {
1428 /* %VAR:~[start][,length]% - Substring.
1429 * Negative values are offsets from the end.
1430 */
1431 SSIZE_T Start = _tcstol(Src + 1, (PTSTR*)&Src, 0);
1432 SSIZE_T End = (SSIZE_T)VarLength;
1433 if (Start < 0)
1434 Start += VarLength;
1435 Start = min(max(Start, 0), VarLength);
1436 if (*Src == _T(','))
1437 {
1438 End = _tcstol(Src + 1, (PTSTR*)&Src, 0);
1439 End += (End < 0) ? VarLength : Start;
1440 End = min(max(End, Start), VarLength);
1441 }
1442 if (*Src++ != Delim)
1443 goto bad_subst;
1444 APPEND(&Var[Start], End - Start);
1445 }
1446 else
1447 {
1448 /* %VAR:old=new% - Replace all occurrences of old with new.
1449 * %VAR:*old=new% - Replace first occurrence only,
1450 * and remove everything before it.
1451 */
1452 PCTSTR Old, New;
1453 size_t OldLength, NewLength;
1454 BOOL Star = FALSE;
1455 size_t LastMatch = 0, i = 0;
1456
1457 if (*Src == _T('*'))
1458 {
1459 Star = TRUE;
1460 Src++;
1461 }
1462
1463 /* The string to replace may contain the delimiter */
1464 Src = _tcschr(Old = Src, _T('='));
1465 if (Src == NULL)
1466 goto bad_subst;
1467 OldLength = Src++ - Old;
1468 if (OldLength == 0)
1469 goto bad_subst;
1470
1471 Src = _tcschr(New = Src, Delim);
1472 if (Src == NULL)
1473 goto bad_subst;
1474 NewLength = Src++ - New;
1475
1476 while (i < VarLength)
1477 {
1478 if (_tcsnicmp(&Var[i], Old, OldLength) == 0)
1479 {
1480 if (!Star)
1481 APPEND(&Var[LastMatch], i - LastMatch);
1483 i += OldLength;
1484 LastMatch = i;
1485 if (Star)
1486 break;
1487 continue;
1488 }
1489 i++;
1490 }
1491 APPEND(&Var[LastMatch], VarLength - LastMatch);
1492 }
1493
1494success:
1495 *SrcIncLen = (Src - Start);
1496 *DestIncLen = (Dest - End);
1497 return TRUE;
1498
1499bad_subst:
1500 Src = SubstStart;
1501 /* Only if no batch context active do we echo the delimiter */
1502 if (!bc)
1503 APPEND1(Delim);
1504 goto success;
1505
1506too_long:
1508 nErrorLevel = 9023;
1509 return FALSE;
1510
1511#undef APPEND
1512#undef APPEND1
1513}
1514
1515BOOL
1517 IN PCTSTR Src,
1518 OUT PTSTR Dest,
1519 IN TCHAR Delim)
1520{
1521#define APPEND(From, Length) \
1522do { \
1523 if (Dest + (Length) > DestEnd) \
1524 goto too_long; \
1525 memcpy(Dest, (From), (Length) * sizeof(TCHAR)); \
1526 Dest += (Length); \
1527} while (0)
1528
1529#define APPEND1(Char) \
1530do { \
1531 if (Dest >= DestEnd) \
1532 goto too_long; \
1533 *Dest++ = (Char); \
1534} while (0)
1535
1536 PTCHAR DestEnd = Dest + CMDLINE_LENGTH - 1;
1537 PCTSTR End;
1538 size_t SrcIncLen, DestIncLen;
1539
1540 while (*Src /* && (Dest < DestEnd) */)
1541 {
1542 if (*Src != Delim)
1543 {
1544 End = _tcschr(Src, Delim);
1545 if (End == NULL)
1546 End = Src + _tcslen(Src);
1547 APPEND(Src, End - Src);
1548 Src = End;
1549 continue;
1550 }
1551
1552 if (!SubstituteVar(Src, &SrcIncLen, Dest, DestEnd, &DestIncLen, Delim))
1553 {
1554 return FALSE;
1555 }
1556 else
1557 {
1558 Src += SrcIncLen;
1559 Dest += DestIncLen;
1560 }
1561 }
1562 APPEND1(_T('\0'));
1563 return TRUE;
1564
1565too_long:
1567 nErrorLevel = 9023;
1568 return FALSE;
1569
1570#undef APPEND
1571#undef APPEND1
1572}
1573
1574/* Search the list of FOR contexts for a variable */
1575static BOOL
1577 IN TCHAR Var,
1578 OUT PCTSTR* VarPtr,
1579 OUT BOOL* IsParam0)
1580{
1581 PFOR_CONTEXT Ctx;
1582
1583 *VarPtr = NULL;
1584 *IsParam0 = FALSE;
1585
1586 for (Ctx = fc; Ctx != NULL; Ctx = Ctx->prev)
1587 {
1588 if ((UINT)(Var - Ctx->firstvar) < Ctx->varcount)
1589 {
1590 *VarPtr = Ctx->values[Var - Ctx->firstvar];
1591 return TRUE;
1592 }
1593 }
1594 return FALSE;
1595}
1596
1597BOOL
1599 IN PCTSTR Src,
1600 OUT PTSTR Dest)
1601{
1602 PTCHAR DestEnd = &Dest[CMDLINE_LENGTH - 1];
1603 while (*Src)
1604 {
1605 if (Src[0] == _T('%'))
1606 {
1607 BOOL Dummy;
1608 PCTSTR End = &Src[2];
1609 PCTSTR Value = NULL;
1610
1611 if (Src[1] == _T('~'))
1613
1614 if (!Value && Src[1])
1615 {
1616 if (FindForVar(Src[1], &Value, &Dummy) && !Value)
1617 {
1618 /* The variable is empty, return an empty string */
1619 Value = _T("");
1620 }
1621 }
1622
1623 if (Value)
1624 {
1625 if (Dest + _tcslen(Value) > DestEnd)
1626 return FALSE;
1627 Dest = _stpcpy(Dest, Value);
1628 Src = End;
1629 continue;
1630 }
1631 }
1632 /* Not a variable; just copy the character */
1633 if (Dest >= DestEnd)
1634 return FALSE;
1635 *Dest++ = *Src++;
1636 }
1637 *Dest = _T('\0');
1638 return TRUE;
1639}
1640
1641PTSTR
1643 IN PCTSTR Line)
1644{
1645 TCHAR Buf1[CMDLINE_LENGTH];
1646 TCHAR Buf2[CMDLINE_LENGTH];
1647 PTCHAR Src, Dst;
1648 PTCHAR DestEnd = Buf2 + CMDLINE_LENGTH - 1;
1649 size_t SrcIncLen, DestIncLen;
1650
1651 /* First, substitute FOR variables */
1652 if (!SubstituteForVars(Line, Buf1))
1653 return NULL;
1654
1655 if (!bDelayedExpansion || !_tcschr(Buf1, _T('!')))
1656 return cmd_dup(Buf1);
1657
1658 /*
1659 * Delayed substitutions are not actually completely the same as
1660 * immediate substitutions. In particular, it is possible to escape
1661 * the exclamation point using the escape caret.
1662 */
1663
1664 /*
1665 * Perform delayed expansion: expand variables around '!',
1666 * and reparse escape carets.
1667 */
1668
1669#define APPEND1(Char) \
1670do { \
1671 if (Dst >= DestEnd) \
1672 goto too_long; \
1673 *Dst++ = (Char); \
1674} while (0)
1675
1676 Src = Buf1;
1677 Dst = Buf2;
1678 while (*Src && (Src < &Buf1[CMDLINE_LENGTH]))
1679 {
1680 if (*Src == _T('^'))
1681 {
1682 ++Src;
1683 if (!*Src || !(Src < &Buf1[CMDLINE_LENGTH]))
1684 break;
1685
1686 APPEND1(*Src++);
1687 }
1688 else if (*Src == _T('!'))
1689 {
1690 if (!SubstituteVar(Src, &SrcIncLen, Dst, DestEnd, &DestIncLen, _T('!')))
1691 {
1692 return NULL; // Got an error during parsing.
1693 }
1694 else
1695 {
1696 Src += SrcIncLen;
1697 Dst += DestIncLen;
1698 }
1699 }
1700 else
1701 {
1702 APPEND1(*Src++);
1703 }
1704 continue;
1705 }
1706 APPEND1(_T('\0'));
1707
1708 return cmd_dup(Buf2);
1709
1710too_long:
1712 nErrorLevel = 9023;
1713 return NULL;
1714
1715#undef APPEND1
1716}
1717
1718
1719/*
1720 * Do the prompt/input/process loop.
1721 */
1722BOOL
1723ReadLine(TCHAR *commandline, BOOL bMore)
1724{
1726 LPTSTR ip;
1727
1728 /* if no batch input then... */
1729 if (bc == NULL)
1730 {
1731 if (bMore)
1732 {
1734 }
1735 else
1736 {
1737 /* JPP 19980807 - if echo off, don't print prompt */
1738 if (bEcho)
1739 {
1740 if (!bIgnoreEcho)
1741 ConOutChar(_T('\n'));
1742 PrintPrompt();
1743 }
1744 }
1745
1747 {
1748 bExit = TRUE;
1749 return FALSE;
1750 }
1751
1752 if (readline[0] == _T('\0'))
1753 ConOutChar(_T('\n'));
1754
1756 return FALSE;
1757
1758 if (readline[0] == _T('\0'))
1759 return FALSE;
1760
1761 ip = readline;
1762 }
1763 else
1764 {
1765 ip = ReadBatchLine();
1766 if (!ip)
1767 return FALSE;
1768 }
1769
1770 return SubstituteVars(ip, commandline, _T('%'));
1771}
1772
1773static INT
1775{
1776 INT Ret = 0;
1778
1779 while (!bCanExit || !bExit)
1780 {
1781 /* Reset the Ctrl-Break / Ctrl-C state */
1782 bCtrlBreak = FALSE;
1783
1785 if (!Cmd)
1786 continue;
1787
1788 Ret = ExecuteCommand(Cmd);
1790 }
1791
1792 return Ret;
1793}
1794
1795
1796/*
1797 * Control-break handler.
1798 */
1799static BOOL
1800WINAPI
1802{
1803 DWORD dwWritten;
1804 INPUT_RECORD rec;
1805
1806 if ((dwCtrlType != CTRL_C_EVENT) &&
1807 (dwCtrlType != CTRL_BREAK_EVENT))
1808 {
1809 return FALSE;
1810 }
1811
1813 {
1814 /* Child process is running and will have received the control event */
1815 return TRUE;
1816 }
1817 else
1818 {
1820 }
1821
1822 bCtrlBreak = TRUE;
1823
1824 rec.EventType = KEY_EVENT;
1826 rec.Event.KeyEvent.wRepeatCount = 1;
1827 rec.Event.KeyEvent.wVirtualKeyCode = _T('C');
1828 rec.Event.KeyEvent.wVirtualScanCode = _T('C') - 35;
1829 rec.Event.KeyEvent.uChar.AsciiChar = _T('C');
1830 rec.Event.KeyEvent.uChar.UnicodeChar = _T('C');
1832
1834 &rec,
1835 1,
1836 &dwWritten);
1837
1838 /* FIXME: Handle batch files */
1839
1840 // ConOutPrintf(_T("^C"));
1841
1842 return TRUE;
1843}
1844
1845
1847{
1849}
1850
1851
1853{
1855}
1856
1857
1858/*
1859 * Show commands and options that are available.
1860 */
1861#if 0
1862static VOID
1863ShowCommands(VOID)
1864{
1865 /* print command list */
1868
1869 /* print feature list */
1871
1872#ifdef FEATURE_ALIASES
1874#endif
1875#ifdef FEATURE_HISTORY
1877#endif
1878#ifdef FEATURE_UNIX_FILENAME_COMPLETION
1880#endif
1881#ifdef FEATURE_DIRECTORY_STACK
1883#endif
1884#ifdef FEATURE_REDIRECTION
1886#endif
1887 ConOutChar(_T('\n'));
1888}
1889#endif
1890
1891
1892static VOID
1894{
1895 LONG lRet;
1896 HKEY hKey;
1897 DWORD dwType, len;
1898 /*
1899 * Buffer big enough to hold the string L"4294967295",
1900 * corresponding to the literal 0xFFFFFFFF (MAXULONG) in decimal.
1901 */
1902 DWORD Buffer[6];
1903
1904 lRet = RegOpenKeyEx(hKeyRoot,
1905 _T("Software\\Microsoft\\Command Processor"),
1906 0,
1908 &hKey);
1909 if (lRet != ERROR_SUCCESS)
1910 return;
1911
1912#ifdef INCLUDE_CMD_COLOR
1913 len = sizeof(Buffer);
1914 lRet = RegQueryValueEx(hKey,
1915 _T("DefaultColor"),
1916 NULL,
1917 &dwType,
1918 (LPBYTE)&Buffer,
1919 &len);
1920 if (lRet == ERROR_SUCCESS)
1921 {
1922 /* Overwrite the default attributes */
1923 if (dwType == REG_DWORD)
1925 else if (dwType == REG_SZ)
1927 }
1928 // else, use the default attributes retrieved before.
1929#endif
1930
1931#if 0
1932 len = sizeof(Buffer);
1933 lRet = RegQueryValueEx(hKey,
1934 _T("DisableUNCCheck"),
1935 NULL,
1936 &dwType,
1937 (LPBYTE)&Buffer,
1938 &len);
1939 if (lRet == ERROR_SUCCESS)
1940 {
1941 /* Overwrite the default setting */
1942 if (dwType == REG_DWORD)
1943 bDisableUNCCheck = !!*(PDWORD)Buffer;
1944 else if (dwType == REG_SZ)
1945 bDisableUNCCheck = (_ttol((PTSTR)Buffer) == 1);
1946 }
1947 // else, use the default setting set globally.
1948#endif
1949
1950 len = sizeof(Buffer);
1951 lRet = RegQueryValueEx(hKey,
1952 _T("DelayedExpansion"),
1953 NULL,
1954 &dwType,
1955 (LPBYTE)&Buffer,
1956 &len);
1957 if (lRet == ERROR_SUCCESS)
1958 {
1959 /* Overwrite the default setting */
1960 if (dwType == REG_DWORD)
1962 else if (dwType == REG_SZ)
1964 }
1965 // else, use the default setting set globally.
1966
1967 len = sizeof(Buffer);
1968 lRet = RegQueryValueEx(hKey,
1969 _T("EnableExtensions"),
1970 NULL,
1971 &dwType,
1972 (LPBYTE)&Buffer,
1973 &len);
1974 if (lRet == ERROR_SUCCESS)
1975 {
1976 /* Overwrite the default setting */
1977 if (dwType == REG_DWORD)
1979 else if (dwType == REG_SZ)
1981 }
1982 // else, use the default setting set globally.
1983
1984 len = sizeof(Buffer);
1985 lRet = RegQueryValueEx(hKey,
1986 _T("CompletionChar"),
1987 NULL,
1988 &dwType,
1989 (LPBYTE)&Buffer,
1990 &len);
1991 if (lRet == ERROR_SUCCESS)
1992 {
1993 /* Overwrite the default setting */
1994 if (dwType == REG_DWORD)
1996 else if (dwType == REG_SZ)
1998 }
1999 // else, use the default setting set globally.
2000
2001 /* Validity check */
2003 {
2004 /* Disable autocompletion */
2005 AutoCompletionChar = 0x20;
2006 }
2007
2008 len = sizeof(Buffer);
2009 lRet = RegQueryValueEx(hKey,
2010 _T("PathCompletionChar"),
2011 NULL,
2012 &dwType,
2013 (LPBYTE)&Buffer,
2014 &len);
2015 if (lRet == ERROR_SUCCESS)
2016 {
2017 /* Overwrite the default setting */
2018 if (dwType == REG_DWORD)
2020 else if (dwType == REG_SZ)
2022 }
2023 // else, use the default setting set globally.
2024
2025 /* Validity check */
2027 {
2028 /* Disable autocompletion */
2029 PathCompletionChar = 0x20;
2030 }
2031
2032 /* Adjust completion chars */
2033 if (PathCompletionChar >= 0x20 && AutoCompletionChar < 0x20)
2035 else if (AutoCompletionChar >= 0x20 && PathCompletionChar < 0x20)
2037
2039}
2040
2041static VOID
2043{
2044 LONG lRet;
2045 HKEY hKey;
2046 DWORD dwType, len;
2047 TCHAR AutoRun[2048];
2048
2049 lRet = RegOpenKeyEx(hKeyRoot,
2050 _T("Software\\Microsoft\\Command Processor"),
2051 0,
2053 &hKey);
2054 if (lRet != ERROR_SUCCESS)
2055 return;
2056
2057 len = sizeof(AutoRun);
2058 lRet = RegQueryValueEx(hKey,
2059 _T("AutoRun"),
2060 NULL,
2061 &dwType,
2062 (LPBYTE)&AutoRun,
2063 &len);
2064 if ((lRet == ERROR_SUCCESS) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
2065 {
2066 if (*AutoRun)
2067 ParseCommandLine(AutoRun);
2068 }
2069
2071}
2072
2073/* Get the command that comes after a /C or /K switch */
2074static VOID
2076 OUT LPTSTR commandline,
2077 IN LPCTSTR ptr,
2078 IN BOOL AlwaysStrip)
2079{
2080 TCHAR* LastQuote;
2081
2082 while (_istspace(*ptr))
2083 ++ptr;
2084
2085 /* Remove leading quote, find final quote */
2086 if (*ptr == _T('"') &&
2087 (LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL)
2088 {
2089 const TCHAR* Space;
2090 /* Under certain circumstances, all quotes are preserved.
2091 * CMD /? documents these conditions as follows:
2092 * 1. No /S switch
2093 * 2. Exactly two quotes
2094 * 3. No "special characters" between the quotes
2095 * (CMD /? says &<>()@^| but parentheses did not
2096 * trigger this rule when I tested them.)
2097 * 4. Whitespace exists between the quotes
2098 * 5. Enclosed string is an executable filename
2099 */
2100 *LastQuote = _T('\0');
2101 for (Space = ptr + 1; Space < LastQuote; ++Space)
2102 {
2103 if (_istspace(*Space)) /* Rule 4 */
2104 {
2105 if (!AlwaysStrip && /* Rule 1 */
2106 !_tcspbrk(ptr, _T("\"&<>@^|")) && /* Rules 2, 3 */
2107 SearchForExecutable(ptr, commandline)) /* Rule 5 */
2108 {
2109 /* All conditions met: preserve both the quotes */
2110 *LastQuote = _T('"');
2111 _tcscpy(commandline, ptr - 1);
2112 return;
2113 }
2114 break;
2115 }
2116 }
2117
2118 /* The conditions were not met: remove both the
2119 * leading quote and the last quote */
2120 _tcscpy(commandline, ptr);
2121 _tcscpy(&commandline[LastQuote - ptr], LastQuote + 1);
2122 return;
2123 }
2124
2125 /* No quotes; just copy */
2126 _tcscpy(commandline, ptr);
2127}
2128
2129
2130/*
2131 * Set up global initializations and process parameters.
2132 * Return a pointer to the command line if present.
2133 */
2134static LPCTSTR
2136{
2137 HMODULE NtDllModule;
2138 HANDLE hIn, hOut;
2139 LPTSTR ptr, cmdLine;
2140 TCHAR option = 0;
2141 BOOL AutoRun = TRUE;
2143
2144 /* Get version information */
2145 InitOSVersion();
2146
2147 /* Some people like to run ReactOS cmd.exe on Win98, it helps in the
2148 * build process. So don't link implicitly against ntdll.dll, load it
2149 * dynamically instead */
2150 NtDllModule = GetModuleHandle(TEXT("ntdll.dll"));
2151 if (NtDllModule != NULL)
2152 {
2153 NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess");
2154 NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
2155 }
2156
2157 /* Load the registry settings */
2160
2161 /* Initialize our locale */
2162 InitLocale();
2163
2164 /* Initialize prompt support */
2165 InitPrompt();
2166
2167#ifdef FEATURE_DIRECTORY_STACK
2168 /* Initialize directory stack */
2170#endif
2171
2172#ifdef FEATURE_HISTORY
2173 /* Initialize history */
2174 InitHistory();
2175#endif
2176
2177 /* Set COMSPEC environment variable */
2179 {
2180 ModuleName[MAX_PATH] = _T('\0');
2181 SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
2182 }
2183
2184 /* Add ctrl break handler */
2186
2187 /* Set the default console mode */
2190 SetConsoleMode(hOut, 0); // Reinitialize the console output mode
2193
2194 cmdLine = GetCommandLine();
2195 TRACE ("[command args: %s]\n", debugstr_aw(cmdLine));
2196
2197 for (ptr = cmdLine; *ptr; ++ptr)
2198 {
2199 if (*ptr == _T('/'))
2200 {
2201 option = _totupper(ptr[1]);
2202 if (option == _T('?'))
2203 {
2205 nErrorLevel = 1;
2206 bExit = TRUE;
2207 return NULL;
2208 }
2209 else if (option == _T('P'))
2210 {
2211 if (!IsExistingFile(_T("\\autoexec.bat")))
2212 {
2213#ifdef INCLUDE_CMD_DATE
2214 cmd_date(_T(""));
2215#endif
2216#ifdef INCLUDE_CMD_TIME
2217 cmd_time(_T(""));
2218#endif
2219 }
2220 else
2221 {
2222 ParseCommandLine(_T("\\autoexec.bat"));
2223 }
2224 bCanExit = FALSE;
2225 }
2226 else if (option == _T('A'))
2227 {
2229 }
2230 else if (option == _T('C') || option == _T('K') || option == _T('R'))
2231 {
2232 /* Remainder of command line is a command to be run */
2233 fSingleCommand = ((option == _T('K')) << 1) | 1;
2234 break;
2235 }
2236 else if (option == _T('D'))
2237 {
2238 AutoRun = FALSE;
2239 }
2240 else if (option == _T('Q'))
2241 {
2243 }
2244 else if (option == _T('S'))
2245 {
2247 }
2248#ifdef INCLUDE_CMD_COLOR
2249 else if (!_tcsnicmp(ptr, _T("/T:"), 3))
2250 {
2251 /* Process /T (color) argument; overwrite any previous settings */
2252 wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
2253 }
2254#endif
2255 else if (option == _T('U'))
2256 {
2258 }
2259 else if (option == _T('V'))
2260 {
2261 // FIXME: Check validity of the parameter given to V !
2262 bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
2263 }
2264 else if (option == _T('E'))
2265 {
2266 // FIXME: Check validity of the parameter given to E !
2267 bEnableExtensions = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
2268 }
2269 else if (option == _T('X'))
2270 {
2271 /* '/X' is identical to '/E:ON' */
2273 }
2274 else if (option == _T('Y'))
2275 {
2276 /* '/Y' is identical to '/E:OFF' */
2278 }
2279 }
2280 }
2281
2282#ifdef INCLUDE_CMD_COLOR
2283 if (wDefColor == 0)
2284 {
2285 /*
2286 * If we still do not have the console colour attribute set,
2287 * retrieve the default one.
2288 */
2290 }
2291
2292 if (wDefColor != 0)
2294#endif
2295
2296 /* Reset the output Standard Streams translation modes and code page caches */
2297 // ConStreamSetMode(StdIn , OutputStreamMode, InputCodePage );
2300
2301 if (!*ptr)
2302 {
2303 /* If neither /C or /K was given, display a simple version string */
2304 ConOutChar(_T('\n'));
2306 _T(KERNEL_VERSION_STR),
2307 _T(KERNEL_VERSION_BUILD_STR));
2308 ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n"));
2309 }
2310
2311 if (AutoRun)
2312 {
2315 }
2316
2317 /* Returns the rest of the command line */
2318 return ptr;
2319}
2320
2321
2323{
2324 /* Run cmdexit.bat */
2325 if (IsExistingFile(_T("cmdexit.bat")))
2326 {
2328 ParseCommandLine(_T("cmdexit.bat"));
2329 }
2330 else if (IsExistingFile(_T("\\cmdexit.bat")))
2331 {
2333 ParseCommandLine(_T("\\cmdexit.bat"));
2334 }
2335
2336 /* Remove ctrl break handler */
2338
2339 /* Restore the default console mode */
2344
2345
2346#ifdef _DEBUG_MEM
2347#ifdef FEATURE_DIRECTORY_STACK
2348 /* Destroy directory stack */
2350#endif
2351
2352#ifdef FEATURE_HISTORY
2353 CleanHistory();
2354#endif
2355
2356 /* Free GetEnvVar's buffer */
2357 GetEnvVar(NULL);
2358#endif /* _DEBUG_MEM */
2359
2361}
2362
2363/*
2364 * main function
2365 */
2366int _tmain(int argc, const TCHAR *argv[])
2367{
2368 INT nExitCode;
2369 LPCTSTR pCmdLine;
2370 TCHAR startPath[MAX_PATH];
2371
2374
2375 GetCurrentDirectory(ARRAYSIZE(startPath), startPath);
2376 _tchdir(startPath);
2377
2381
2382 /* Initialize the Console Standard Streams */
2386 /* Reset the current thread UI language */
2389 {
2391 }
2392
2394
2395 /*
2396 * Perform general initialization, parse switches on command-line.
2397 * Initialize the exit code with the errorlevel as Initialize() can set it.
2398 */
2399 pCmdLine = Initialize();
2400 nExitCode = nErrorLevel;
2401
2402 if (pCmdLine && *pCmdLine)
2403 {
2404 TCHAR commandline[CMDLINE_LENGTH];
2405
2406 /* Do the /C or /K command */
2407 GetCmdLineCommand(commandline, &pCmdLine[2], bAlwaysStrip);
2408 nExitCode = ParseCommandLine(commandline);
2409 if (fSingleCommand == 1)
2410 {
2411 // nErrorLevel = nExitCode;
2412 bExit = TRUE;
2413 }
2414 fSingleCommand = 0;
2415 }
2416 if (!bExit)
2417 {
2418 /* Call prompt routine */
2419 nExitCode = ProcessInput();
2420 }
2421
2422 /* Do the cleanup */
2423 Cleanup();
2425
2426 cmd_exit(nExitCode);
2427 return nExitCode;
2428}
2429
2430/* EOF */
WCHAR First[]
Definition: FormatMessage.c:11
static USHORT USHORT * NewLength
static int argc
Definition: ServiceArgs.c:12
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
static logline * readline(FILE *inf, adns_state adns, int opts)
Definition: adnslogres.c:145
static VOID ErrorMessage(_In_ DWORD dwErrorCode, _In_opt_ PCWSTR pszMsg,...)
Definition: attrib.c:51
#define StdOut
Definition: fc.c:14
#define StdErr
Definition: fc.c:15
#define CMDLINE_LENGTH
Definition: help.h:12
LONG NTSTATUS
Definition: precomp.h:26
COMMAND cmds[]
Definition: main.c:21
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
PBATCH_CONTEXT bc
Definition: batch.c:67
BOOL FindArg(IN TCHAR Char, OUT PCTSTR *ArgPtr, OUT BOOL *IsParam0)
Definition: batch.c:84
BOOL bEcho
Definition: batch.c:73
LPTSTR ReadBatchLine(VOID)
Definition: batch.c:564
NTSTATUS(WINAPI * NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, SIZE_T, PSIZE_T)
Definition: cmd.c:150
BOOL bCanExit
Definition: cmd.c:153
static BOOL FindForVar(IN TCHAR Var, OUT PCTSTR *VarPtr, OUT BOOL *IsParam0)
Definition: cmd.c:1576
CRITICAL_SECTION ChildProcessRunningLock
Definition: cmd.c:159
#define APPEND(From, Length)
INT nErrorLevel
Definition: cmd.c:158
static VOID LoadRegistrySettings(HKEY hKeyRoot)
Definition: cmd.c:1893
BOOL bDisableBatchEcho
Definition: cmd.c:160
BOOL SubstituteVars(IN PCTSTR Src, OUT PTSTR Dest, IN TCHAR Delim)
Definition: cmd.c:1516
BOOL ReadLine(TCHAR *commandline, BOOL bMore)
Definition: cmd.c:1723
BOOL bDelayedExpansion
Definition: cmd.c:162
static PCTSTR GetEnhancedVar(IN OUT PCTSTR *pFormat, IN BOOL(*GetVar)(TCHAR, PCTSTR *, BOOL *))
Definition: cmd.c:975
static HANDLE ExecuteAsync(PARSED_COMMAND *Cmd)
Definition: cmd.c:659
DWORD dwChildProcessId
Definition: cmd.c:163
INT ExecuteCommand(IN PARSED_COMMAND *Cmd)
Definition: cmd.c:782
HANDLE CMD_ModuleHandle
Definition: cmd.c:165
LPTSTR lpOriginalEnvironment
Definition: cmd.c:164
WORD wDefColor
Definition: cmd.c:180
VOID AddBreakHandler(VOID)
Definition: cmd.c:1846
BOOL bExit
Definition: cmd.c:152
CON_STREAM_MODE OutputStreamMode
Definition: cmd.c:177
static INT ProcessInput(VOID)
Definition: cmd.c:1774
LPTSTR GetEnvVar(LPCTSTR varName)
Definition: cmd.c:886
INT DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
Definition: cmd.c:557
TCHAR szCurTitle[MAX_PATH]
Definition: cmd.c:168
BOOL bEnableExtensions
Definition: cmd.c:161
static PCTSTR GetBatchVar(IN PCTSTR varName, OUT PUINT varNameLen)
Definition: cmd.c:1275
HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params, LPTSTR directory, INT show)
Definition: cmd.c:266
INT ExecuteCommandWithEcho(IN PARSED_COMMAND *Cmd)
Definition: cmd.c:868
static INT Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
Definition: cmd.c:347
static VOID SetConTitle(LPCTSTR pszTitle)
Definition: cmd.c:309
static BOOL IsConsoleProcess(HANDLE Process)
Definition: cmd.c:224
BOOL bTitleSet
Definition: cmd.c:167
VOID RemoveBreakHandler(VOID)
Definition: cmd.c:1852
static VOID ExecuteAutoRunFile(HKEY hKeyRoot)
Definition: cmd.c:2042
static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr
Definition: cmd.c:171
static VOID GetCmdLineCommand(OUT LPTSTR commandline, IN LPCTSTR ptr, IN BOOL AlwaysStrip)
Definition: cmd.c:2075
LPCTSTR GetEnvVarOrSpecial(LPCTSTR varName)
Definition: cmd.c:904
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeparator)
Definition: cmd.c:189
PTSTR DoDelayedExpansion(IN PCTSTR Line)
Definition: cmd.c:1642
BOOL(WINAPI * MYEX)(LPSHELLEXECUTEINFO lpExecInfo)
Definition: cmd.c:264
static BOOL WINAPI BreakHandler(IN DWORD dwCtrlType)
Definition: cmd.c:1801
#define SHELLEXECUTETEXT
Definition: cmd.c:261
static NtQueryInformationProcessProc NtQueryInformationProcessPtr
Definition: cmd.c:170
BOOL bIgnoreEcho
Definition: cmd.c:155
BOOL SubstituteForVars(IN PCTSTR Src, OUT PTSTR Dest)
Definition: cmd.c:1598
#define APPEND1(Char)
static INT ExecutePipeline(PARSED_COMMAND *Cmd)
Definition: cmd.c:693
BOOL bCtrlBreak
Definition: cmd.c:154
INT ParseCommandLine(LPTSTR cmd)
Definition: cmd.c:636
BOOL SubstituteVar(IN PCTSTR Src, OUT size_t *SrcIncLen, OUT PTCHAR Dest, IN PTCHAR DestEnd, OUT size_t *DestIncLen, IN TCHAR Delim)
Definition: cmd.c:1328
#define SeenGoto()
static BOOL fSingleCommand
Definition: cmd.c:156
static BOOL bAlwaysStrip
Definition: cmd.c:157
static VOID ResetConTitle(VOID)
Definition: cmd.c:329
NTSTATUS(WINAPI * NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG)
Definition: cmd.c:148
BOOL IsExistingFile(IN LPCTSTR pszPath)
Definition: misc.c:498
PARSED_COMMAND * ParseCommand(IN PCTSTR Line)
Definition: parser.c:1461
INT ExecuteIf(struct _PARSED_COMMAND *Cmd)
Definition: if.c:66
INT FormatDate(TCHAR *, LPSYSTEMTIME, BOOL)
Definition: dir.c:674
VOID DestroyDirectoryStack(VOID)
Definition: dirstack.c:91
#define IS_COMPLETION_DISABLED(CompletionCtrl)
Definition: cmd.h:135
PTCHAR UnparseCommand(IN PARSED_COMMAND *Cmd, OUT PTCHAR Out, IN PTCHAR OutEnd)
Definition: parser.c:1965
LPTSTR DuplicateEnvironment(VOID)
Definition: setlocal.c:25
BOOL bParseError
Definition: parser.c:90
VOID InitOSVersion(VOID)
Definition: ver.c:32
LPTSTR _stpcpy(LPTSTR, LPCTSTR)
Definition: misc.c:460
VOID ParseErrorEx(IN PCTSTR s)
Definition: parser.c:227
VOID error_too_many_parameters(PCTSTR s)
Definition: error.c:79
VOID error_no_pipe(VOID)
Definition: error.c:131
INT cmd_date(LPTSTR)
Definition: date.c:176
VOID error_bad_command(PCTSTR s)
Definition: error.c:124
VOID EchoCommand(IN PARSED_COMMAND *Cmd)
Definition: parser.c:1808
VOID InitDirectoryStack(VOID)
Definition: dirstack.c:80
BOOL CheckCtrlBreak(INT)
Definition: misc.c:132
BOOL PerformRedirection(REDIRECTION *)
Definition: redir.c:63
VOID PrintCommandList(VOID)
Definition: cmdtable.c:234
BOOL SearchForExecutable(LPCTSTR, LPTSTR)
Definition: where.c:142
VOID InitLocale(VOID)
Definition: locale.c:25
#define BREAK_INPUT
Definition: cmd.h:36
INT nNumberGroups
Definition: locale.c:22
@ C_QUIET
Definition: cmd.h:355
@ C_OR
Definition: cmd.h:359
@ C_COMMAND
Definition: cmd.h:353
@ C_REM
Definition: cmd.h:361
@ C_AND
Definition: cmd.h:359
@ C_MULTI
Definition: cmd.h:359
@ C_IF
Definition: cmd.h:361
@ C_PIPE
Definition: cmd.h:359
@ C_FOR
Definition: cmd.h:361
LPTSTR GetTimeString(VOID)
Definition: locale.c:73
TCHAR AutoCompletionChar
Definition: cmdinput.c:111
VOID error_out_of_memory(VOID)
Definition: error.c:138
TCHAR PathCompletionChar
Definition: cmdinput.c:112
INT cmd_time(LPTSTR)
Definition: time.c:132
#define CMDEXTVERSION
Definition: cmd.h:32
INT ExecuteFor(struct _PARSED_COMMAND *Cmd)
Definition: for.c:604
VOID InitPrompt(VOID)
Definition: prompt.c:57
VOID PrintPrompt(VOID)
Definition: prompt.c:109
TCHAR cThousandSeparator
Definition: locale.c:18
VOID UndoRedirection(REDIRECTION *, REDIRECTION *End)
Definition: redir.c:142
VOID FreeCommand(IN OUT PARSED_COMMAND *Cmd)
Definition: parser.c:527
INT FormatTime(TCHAR *, LPSYSTEMTIME)
Definition: dir.c:703
LPTSTR GetDateString(VOID)
Definition: locale.c:58
VOID ConOutChar(TCHAR c)
Definition: console.c:123
UINT InputCodePage
Definition: console.c:25
BOOL ConSetScreenColor(HANDLE hOutput, WORD wColor, BOOL bFill)
Definition: console.c:302
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
UINT OutputCodePage
Definition: console.c:26
BOOL ConSetTitle(IN LPCTSTR lpConsoleTitle)
Definition: console.c:280
BOOL ConGetDefaultAttributes(PWORD pwDefAttr)
Definition: console.c:255
#define ConErrResPuts(uID)
Definition: console.h:39
#define ConOutResPrintf(uID,...)
Definition: console.h:48
#define ConOutPuts(szStr)
Definition: console.h:30
#define ConOutResPuts(uID)
Definition: console.h:36
VOID InitHistory(VOID)
Definition: history.c:132
VOID CleanHistory(VOID)
Definition: history.c:163
#define debugstr_aw
Definition: precomp.h:43
#define STRING_CMD_HELP2
Definition: resource.h:76
#define STRING_CMD_HELP4
Definition: resource.h:78
#define STRING_CMD_HELP3
Definition: resource.h:77
#define STRING_REACTOS_VERSION
Definition: resource.h:89
#define STRING_MORE
Definition: resource.h:239
#define STRING_CMD_HELP6
Definition: resource.h:80
#define STRING_CMD_ERROR5
Definition: resource.h:31
#define STRING_ALIAS_ERROR
Definition: resource.h:22
#define STRING_CMD_HELP8
Definition: resource.h:82
#define STRING_CMD_HELP7
Definition: resource.h:81
#define STRING_CMD_HELP1
Definition: resource.h:75
#define STRING_FREE_ERROR1
Definition: resource.h:49
#define STRING_CMD_HELP5
Definition: resource.h:79
LONG_PTR SSIZE_T
Definition: basetsd.h:183
PFOR_CONTEXT fc
Definition: for.c:57
#define ENABLE_WRAP_AT_EOL_OUTPUT
Definition: blue.h:54
#define ENABLE_PROCESSED_OUTPUT
Definition: blue.h:53
#define WARN(fmt,...)
Definition: debug.h:112
#define RegCloseKey(hKey)
Definition: registry.h:47
Definition: bufpool.h:45
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
static BOOL ReadCommand(PCONSOLE_STATE State, LPSTR str, INT maxlen)
Definition: cmdcons.c:735
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_exit(code)
Definition: cmddbg.h:34
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_dup(str)
Definition: cmddbg.h:32
#define ERROR_SUCCESS
Definition: deptool.c:10
@ Out
@ In
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define NTSTATUS
Definition: precomp.h:20
static const WCHAR des[]
Definition: oid.c:1212
#define CloseHandle
Definition: compat.h:739
int(* FARPROC)()
Definition: compat.h:36
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleOutputCP(VOID)
Definition: console.c:2451
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode)
Definition: console.c:1606
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
BOOL WINAPI DECLSPEC_HOTPATCH SetStdHandle(DWORD nStdHandle, HANDLE hHandle)
Definition: console.c:1213
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2391
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI SetHandleInformation(IN HANDLE hObject, IN DWORD dwMask, IN DWORD dwFlags)
Definition: handle.c:78
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
BOOL WINAPI GetNumaHighestNodeNumber(OUT PULONG HighestNodeNumber)
Definition: sysinfo.c:264
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221
static const WCHAR Cleanup[]
Definition: register.c:80
#define INFINITE
Definition: serial.h:102
IN PVCB IN PBCB OUT PDIRENT IN USHORT IN POEM_STRING Filename
Definition: fatprocs.h:939
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
ASMGENDATA Table[]
Definition: genincdata.c:61
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
const GLint * first
Definition: glext.h:5794
GLuint GLuint num
Definition: glext.h:9618
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define _istspace
Definition: tchar.h:1504
#define _tcscmp
Definition: tchar.h:1424
#define _tcscat
Definition: tchar.h:622
#define _tcscpy
Definition: tchar.h:623
#define _tcstoul
Definition: tchar.h:595
#define _istalpha
Definition: tchar.h:1492
#define _itot
Definition: tchar.h:608
#define _tcspbrk
Definition: tchar.h:1412
#define _ttol
Definition: tchar.h:612
#define _tcscspn
Definition: tchar.h:1407
#define _tmain
Definition: tchar.h:497
#define _tchdir
Definition: tchar.h:672
#define _tcsncat
Definition: tchar.h:1408
#define _totupper
Definition: tchar.h:1509
#define _tcstol
Definition: tchar.h:594
#define _tcschr
Definition: tchar.h:1406
#define _totlower
Definition: tchar.h:1511
@ ProcessBasicInformation
Definition: winternl.h:394
enum _PROCESSINFOCLASS PROCESSINFOCLASS
Definition: loader.c:63
const char * filename
Definition: ioapi.h:137
#define TEXT(s)
Definition: k32.h:26
#define REG_SZ
Definition: layer.c:22
POINT cp
Definition: magnifier.c:59
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define Dst
Definition: mesh.h:153
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
#define _stprintf
Definition: utility.h:124
#define _tcsrchr
Definition: utility.h:116
static PVOID ptr
Definition: dispmode.c:27
const char * var
Definition: shader.c:5666
static HMODULE hShell32
Definition: string.c:34
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
#define BOOL
Definition: nt_native.h:43
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_COMPRESSED
Definition: nt_native.h:711
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_OFFLINE
Definition: nt_native.h:712
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
LPCSTR PCTSTR
Definition: ntbasedef.h:488
char * PTCHAR
Definition: ntbasedef.h:476
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
@ Batch
Definition: ntsecapi.h:291
static BOOL Full
Definition: pageheap.c:12
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
#define INT
Definition: polytest.cpp:20
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define C_BLOCK
Definition: rsym.h:130
#define New(t)
Definition: rtf.h:1086
@ Cmd
Definition: sacdrv.h:278
#define REG_DWORD
Definition: sdbapi.c:596
#define IsConsoleHandle(h)
Definition: console.h:14
BOOL ConStreamSetMode(IN PCON_STREAM Stream, IN CON_STREAM_MODE Mode, IN UINT CacheCodePage OPTIONAL)
Definition: stream.c:195
BOOL ConStreamInit(OUT PCON_STREAM Stream, IN PVOID Handle, IN CON_STREAM_MODE Mode, IN UINT CacheCodePage OPTIONAL)
Definition: stream.c:185
HANDLE ConStreamGetOSHandle(IN PCON_STREAM Stream)
Definition: stream.c:240
#define ConStdStreamsSetCacheCodePage(InputCodePage, OutputCodePage)
Definition: stream.h:152
#define StdIn
Definition: stream.h:81
@ AnsiText
Definition: stream.h:47
@ UTF16Text
Definition: stream.h:49
@ UTF8Text
Definition: stream.h:50
enum _CON_STREAM_MODE CON_STREAM_MODE
LANGID ConSetThreadUILanguage(IN LANGID LangId OPTIONAL)
Definition: utils.c:352
#define memset(x, y, z)
Definition: compat.h:39
VKNAME Modifiers[]
Definition: data.c:56
#define SEE_MASK_NOCLOSEPROCESS
Definition: shellapi.h:31
#define SEE_MASK_NO_CONSOLE
Definition: shellapi.h:38
#define TRACE(s)
Definition: solgame.cpp:4
#define StringCchPrintf
Definition: strsafe.h:517
Definition: ncftp.h:79
TCHAR BatchFilePath[MAX_PATH]
Definition: batch.h:33
LPTSTR raw_params
Definition: batch.h:35
LPTSTR * values
Definition: batch.h:50
UINT varcount
Definition: batch.h:49
TCHAR firstvar
Definition: batch.h:48
struct _FOR_CONTEXT * prev
Definition: batch.h:47
union _INPUT_RECORD::@3259 Event
WORD EventType
Definition: wincon.h:273
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
WORD wVirtualScanCode
Definition: wincon.h:243
union _KEY_EVENT_RECORD::@3258 uChar
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wVirtualKeyCode
Definition: wincon.h:242
WORD wRepeatCount
Definition: wincon.h:241
WCHAR UnicodeChar
Definition: wincon.h:245
struct _PARSED_COMMAND * Next
Definition: cmd.h:372
ULONG ImageSubsystem
Definition: ntddk_ex.h:304
LPCSTR lpParameters
Definition: shellapi.h:313
LPCSTR lpDirectory
Definition: shellapi.h:314
LPSTR lpTitle
Definition: winbase.h:834
DWORD dwFlags
Definition: winbase.h:842
DWORD cb
Definition: winbase.h:831
WORD wShowWindow
Definition: winbase.h:843
Definition: ftp_var.h:139
Definition: dhcpd.h:62
Definition: getopt.h:109
INT(* func)(PCONSOLE_STATE, LPSTR)
Definition: cmdcons.c:29
LPSTR name
Definition: cmdcons.c:27
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * LPBYTE
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
@ Start
Definition: partlist.h:33
#define _T(x)
Definition: vfdio.h:22
int ret
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define success(from, fromstr, to, tostr)
#define GetEnvironmentVariable
Definition: winbase.h:3685
#define CreateProcess
Definition: winbase.h:3629
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define LoadLibrary
Definition: winbase.h:3733
BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3590
#define SetCurrentDirectory
Definition: winbase.h:3774
#define GetCommandLine
Definition: winbase.h:3670
#define MAXIMUM_WAIT_OBJECTS
Definition: winbase.h:404
#define HANDLE_FLAG_INHERIT
Definition: winbase.h:264
#define STD_ERROR_HANDLE
Definition: winbase.h:269
#define SetEnvironmentVariable
Definition: winbase.h:3779
#define GetModuleHandle
Definition: winbase.h:3698
VOID WINAPI SetFileApisToOEM(void)
Definition: utils.c:831
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define SearchPath
Definition: winbase.h:3771
#define FindFirstFile
Definition: winbase.h:3653
#define GetCurrentDirectory
Definition: winbase.h:3676
#define GetModuleFileName
Definition: winbase.h:3702
#define GetFullPathName
Definition: winbase.h:3692
#define CTRL_C_EVENT
Definition: wincon.h:68
#define ENABLE_ECHO_INPUT
Definition: wincon.h:80
#define KEY_EVENT
Definition: wincon.h:128
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
#define CTRL_BREAK_EVENT
Definition: wincon.h:69
#define WriteConsoleInput
Definition: wincon.h:785
#define ENABLE_LINE_INPUT
Definition: wincon.h:79
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#define GetConsoleTitle
Definition: wincon.h:775
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RegOpenKeyEx
Definition: winreg.h:520
#define RegQueryValueEx
Definition: winreg.h:524
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define SW_SHOWDEFAULT
Definition: winuser.h:774
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define FILE_ATTRIBUTE_INTEGRITY_STREAM
static void Initialize()
Definition: xlate.c:212
char TCHAR
Definition: xmlstorage.h:189
CHAR * PTSTR
Definition: xmlstorage.h:191
#define _tcsnicmp
Definition: xmlstorage.h:207
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198
#define _tcsicmp
Definition: xmlstorage.h:205