ReactOS 0.4.15-dev-7788-g1ad9096
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 ((Modifiers & M_SHORT) && *w32fd.cAlternateFileName)
1162 FixedComponent = w32fd.cAlternateFileName;
1163
1164 FindClose(hFind);
1165
1166 if (Out + _tcslen(FixedComponent) + 1 >= &FixedPath[ARRAYSIZE(FixedPath)])
1167 return _T("");
1168 _tcscpy(Out, FixedComponent);
1169 }
1170 Filename = Out;
1171 Out += _tcslen(Out);
1172 *Out++ = _T('\\');
1173
1174 In = Next;
1175 } while (In != NULL);
1176 Out[-1] = _T('\0');
1177
1178 /* Build the result string. Start with attributes, modification time, and
1179 * file size. If the file didn't exist, these fields will all be empty. */
1180 Out = Result;
1181 if (hFind != INVALID_HANDLE_VALUE)
1182 {
1183 if (Modifiers & M_ATTR)
1184 {
1185 static const struct {
1186 TCHAR Character;
1187 WORD Value;
1188 } *Attrib, Table[] = {
1189 { _T('d'), FILE_ATTRIBUTE_DIRECTORY },
1190 { _T('r'), FILE_ATTRIBUTE_READONLY },
1191 { _T('a'), FILE_ATTRIBUTE_ARCHIVE },
1192 { _T('h'), FILE_ATTRIBUTE_HIDDEN },
1193 { _T('s'), FILE_ATTRIBUTE_SYSTEM },
1194 { _T('c'), FILE_ATTRIBUTE_COMPRESSED },
1195 { _T('o'), FILE_ATTRIBUTE_OFFLINE },
1196 { _T('t'), FILE_ATTRIBUTE_TEMPORARY },
1198#if (NTDDI_VERSION >= NTDDI_WIN8)
1200 { _T('x'), FILE_ATTRIBUTE_NO_SCRUB_DATA /* 0x20000 */ },
1201#endif
1202 };
1203 for (Attrib = Table; Attrib != &Table[ARRAYSIZE(Table)]; Attrib++)
1204 {
1205 *Out++ = w32fd.dwFileAttributes & Attrib->Value
1206 ? Attrib->Character
1207 : _T('-');
1208 }
1209 *Out++ = _T(' ');
1210 }
1211 if (Modifiers & M_TIME)
1212 {
1213 FILETIME ft;
1214 SYSTEMTIME st;
1215 FileTimeToLocalFileTime(&w32fd.ftLastWriteTime, &ft);
1216 FileTimeToSystemTime(&ft, &st);
1217
1218 Out += FormatDate(Out, &st, TRUE);
1219 *Out++ = _T(' ');
1220 Out += FormatTime(Out, &st);
1221 *Out++ = _T(' ');
1222 }
1223 if (Modifiers & M_SIZE)
1224 {
1226 Size.LowPart = w32fd.nFileSizeLow;
1227 Size.HighPart = w32fd.nFileSizeHigh;
1228 Out += _stprintf(Out, _T("%I64u "), Size.QuadPart);
1229 }
1230 }
1231
1232 /* When using the path-searching syntax or the S modifier,
1233 * at least part of the file path is always included.
1234 * If none of the DPNX modifiers are present, include the full path */
1235 if (PathVarName || (Modifiers & M_SHORT))
1236 if ((Modifiers & (M_DRIVE | M_PATH | M_NAME | M_EXT)) == 0)
1237 Modifiers |= M_FULL;
1238
1239 /* Now add the requested parts of the name.
1240 * With the F modifier, add all parts to form the full path. */
1241 Extension = _tcsrchr(Filename, _T('.'));
1242 if (Modifiers & (M_DRIVE | M_FULL))
1243 {
1244 *Out++ = FixedPath[0];
1245 *Out++ = FixedPath[1];
1246 }
1247 if (Modifiers & (M_PATH | M_FULL))
1248 {
1249 memcpy(Out, &FixedPath[2], (ULONG_PTR)Filename - (ULONG_PTR)&FixedPath[2]);
1250 Out += Filename - &FixedPath[2];
1251 }
1252 if (Modifiers & (M_NAME | M_FULL))
1253 {
1254 while (*Filename && Filename != Extension)
1255 *Out++ = *Filename++;
1256 }
1257 if (Modifiers & (M_EXT | M_FULL))
1258 {
1259 if (Extension)
1261 }
1262
1263 /* Trim trailing space which otherwise would appear as a
1264 * result of using the A/T/Z modifiers but no others. */
1265 while (Out != &Result[0] && Out[-1] == _T(' '))
1266 Out--;
1267 *Out = _T('\0');
1268
1269 return Result;
1270}
1271
1272static PCTSTR
1274 IN PCTSTR varName,
1275 OUT PUINT varNameLen)
1276{
1277 PCTSTR ret;
1278 PCTSTR varNameEnd;
1279
1280 *varNameLen = 1;
1281
1282 switch (*varName)
1283 {
1284 case _T('~'):
1285 {
1286 varNameEnd = varName + 1;
1287 ret = GetEnhancedVar(&varNameEnd, FindArg);
1288 if (!ret)
1289 {
1290 ParseErrorEx(varName);
1291 return NULL;
1292 }
1293 *varNameLen = varNameEnd - varName;
1294 return ret;
1295 }
1296
1297 case _T('0'):
1298 case _T('1'):
1299 case _T('2'):
1300 case _T('3'):
1301 case _T('4'):
1302 case _T('5'):
1303 case _T('6'):
1304 case _T('7'):
1305 case _T('8'):
1306 case _T('9'):
1307 {
1308 BOOL dummy;
1309 if (!FindArg(*varName, &ret, &dummy))
1310 return NULL;
1311 else
1312 return ret;
1313 }
1314
1315 case _T('*'):
1316 /* Copy over the raw params (not including the batch file name) */
1317 return bc->raw_params;
1318
1319 case _T('%'):
1320 return _T("%");
1321 }
1322 return NULL;
1323}
1324
1325BOOL
1327 IN PCTSTR Src,
1328 OUT size_t* SrcIncLen, // VarNameLen
1329 OUT PTCHAR Dest,
1330 IN PTCHAR DestEnd,
1331 OUT size_t* DestIncLen,
1332 IN TCHAR Delim)
1333{
1334#define APPEND(From, Length) \
1335do { \
1336 if (Dest + (Length) > DestEnd) \
1337 goto too_long; \
1338 memcpy(Dest, (From), (Length) * sizeof(TCHAR)); \
1339 Dest += (Length); \
1340} while (0)
1341
1342#define APPEND1(Char) \
1343do { \
1344 if (Dest >= DestEnd) \
1345 goto too_long; \
1346 *Dest++ = (Char); \
1347} while (0)
1348
1349 PCTSTR Var;
1350 PCTSTR Start, End, SubstStart;
1351 TCHAR EndChr;
1352 size_t VarLength;
1353
1354 Start = Src;
1355 End = Dest;
1356 *SrcIncLen = 0;
1357 *DestIncLen = 0;
1358
1359 if (!Delim)
1360 return FALSE;
1361 if (*Src != Delim)
1362 return FALSE;
1363
1364 ++Src;
1365
1366 /* If we are already at the end of the string, fail the substitution */
1367 SubstStart = Src;
1368 if (!*Src || *Src == _T('\r') || *Src == _T('\n'))
1369 goto bad_subst;
1370
1371 if (bc && Delim == _T('%'))
1372 {
1373 UINT NameLen;
1374 Var = GetBatchVar(Src, &NameLen);
1375 if (!Var && bParseError)
1376 {
1377 /* Return the partially-parsed command to be
1378 * echoed for error diagnostics purposes. */
1379 APPEND1(Delim);
1380 APPEND(Src, _tcslen(Src) + 1);
1381 return FALSE;
1382 }
1383 if (Var != NULL)
1384 {
1385 VarLength = _tcslen(Var);
1386 APPEND(Var, VarLength);
1387 Src += NameLen;
1388 goto success;
1389 }
1390 }
1391
1392 /* Find the end of the variable name. A colon (:) will usually
1393 * end the name and begin the optional modifier, but not if it
1394 * is immediately followed by the delimiter (%VAR:%). */
1395 SubstStart = Src;
1396 while (*Src && *Src != Delim && !(*Src == _T(':') && Src[1] != Delim))
1397 {
1398 ++Src;
1399 }
1400 /* If we are either at the end of the string, or the delimiter
1401 * has been repeated more than once, fail the substitution. */
1402 if (!*Src || Src == SubstStart)
1403 goto bad_subst;
1404
1405 EndChr = *Src;
1406 *(PTSTR)Src = _T('\0'); // FIXME: HACK!
1407 Var = GetEnvVarOrSpecial(SubstStart);
1408 *(PTSTR)Src++ = EndChr;
1409 if (Var == NULL)
1410 {
1411 /* In a batch context, %NONEXISTENT% "expands" to an
1412 * empty string, otherwise fail the substitution. */
1413 if (bc)
1414 goto success;
1415 goto bad_subst;
1416 }
1417 VarLength = _tcslen(Var);
1418
1419 if (EndChr == Delim)
1420 {
1421 /* %VAR% - use as-is */
1422 APPEND(Var, VarLength);
1423 }
1424 else if (*Src == _T('~'))
1425 {
1426 /* %VAR:~[start][,length]% - Substring.
1427 * Negative values are offsets from the end.
1428 */
1429 SSIZE_T Start = _tcstol(Src + 1, (PTSTR*)&Src, 0);
1430 SSIZE_T End = (SSIZE_T)VarLength;
1431 if (Start < 0)
1432 Start += VarLength;
1433 Start = min(max(Start, 0), VarLength);
1434 if (*Src == _T(','))
1435 {
1436 End = _tcstol(Src + 1, (PTSTR*)&Src, 0);
1437 End += (End < 0) ? VarLength : Start;
1438 End = min(max(End, Start), VarLength);
1439 }
1440 if (*Src++ != Delim)
1441 goto bad_subst;
1442 APPEND(&Var[Start], End - Start);
1443 }
1444 else
1445 {
1446 /* %VAR:old=new% - Replace all occurrences of old with new.
1447 * %VAR:*old=new% - Replace first occurrence only,
1448 * and remove everything before it.
1449 */
1450 PCTSTR Old, New;
1451 size_t OldLength, NewLength;
1452 BOOL Star = FALSE;
1453 size_t LastMatch = 0, i = 0;
1454
1455 if (*Src == _T('*'))
1456 {
1457 Star = TRUE;
1458 Src++;
1459 }
1460
1461 /* The string to replace may contain the delimiter */
1462 Src = _tcschr(Old = Src, _T('='));
1463 if (Src == NULL)
1464 goto bad_subst;
1465 OldLength = Src++ - Old;
1466 if (OldLength == 0)
1467 goto bad_subst;
1468
1469 Src = _tcschr(New = Src, Delim);
1470 if (Src == NULL)
1471 goto bad_subst;
1472 NewLength = Src++ - New;
1473
1474 while (i < VarLength)
1475 {
1476 if (_tcsnicmp(&Var[i], Old, OldLength) == 0)
1477 {
1478 if (!Star)
1479 APPEND(&Var[LastMatch], i - LastMatch);
1481 i += OldLength;
1482 LastMatch = i;
1483 if (Star)
1484 break;
1485 continue;
1486 }
1487 i++;
1488 }
1489 APPEND(&Var[LastMatch], VarLength - LastMatch);
1490 }
1491
1492success:
1493 *SrcIncLen = (Src - Start);
1494 *DestIncLen = (Dest - End);
1495 return TRUE;
1496
1497bad_subst:
1498 Src = SubstStart;
1499 /* Only if no batch context active do we echo the delimiter */
1500 if (!bc)
1501 APPEND1(Delim);
1502 goto success;
1503
1504too_long:
1506 nErrorLevel = 9023;
1507 return FALSE;
1508
1509#undef APPEND
1510#undef APPEND1
1511}
1512
1513BOOL
1515 IN PCTSTR Src,
1516 OUT PTSTR Dest,
1517 IN TCHAR Delim)
1518{
1519#define APPEND(From, Length) \
1520do { \
1521 if (Dest + (Length) > DestEnd) \
1522 goto too_long; \
1523 memcpy(Dest, (From), (Length) * sizeof(TCHAR)); \
1524 Dest += (Length); \
1525} while (0)
1526
1527#define APPEND1(Char) \
1528do { \
1529 if (Dest >= DestEnd) \
1530 goto too_long; \
1531 *Dest++ = (Char); \
1532} while (0)
1533
1534 PTCHAR DestEnd = Dest + CMDLINE_LENGTH - 1;
1535 PCTSTR End;
1536 size_t SrcIncLen, DestIncLen;
1537
1538 while (*Src /* && (Dest < DestEnd) */)
1539 {
1540 if (*Src != Delim)
1541 {
1542 End = _tcschr(Src, Delim);
1543 if (End == NULL)
1544 End = Src + _tcslen(Src);
1545 APPEND(Src, End - Src);
1546 Src = End;
1547 continue;
1548 }
1549
1550 if (!SubstituteVar(Src, &SrcIncLen, Dest, DestEnd, &DestIncLen, Delim))
1551 {
1552 return FALSE;
1553 }
1554 else
1555 {
1556 Src += SrcIncLen;
1557 Dest += DestIncLen;
1558 }
1559 }
1560 APPEND1(_T('\0'));
1561 return TRUE;
1562
1563too_long:
1565 nErrorLevel = 9023;
1566 return FALSE;
1567
1568#undef APPEND
1569#undef APPEND1
1570}
1571
1572/* Search the list of FOR contexts for a variable */
1573static BOOL
1575 IN TCHAR Var,
1576 OUT PCTSTR* VarPtr,
1577 OUT BOOL* IsParam0)
1578{
1579 PFOR_CONTEXT Ctx;
1580
1581 *VarPtr = NULL;
1582 *IsParam0 = FALSE;
1583
1584 for (Ctx = fc; Ctx != NULL; Ctx = Ctx->prev)
1585 {
1586 if ((UINT)(Var - Ctx->firstvar) < Ctx->varcount)
1587 {
1588 *VarPtr = Ctx->values[Var - Ctx->firstvar];
1589 return TRUE;
1590 }
1591 }
1592 return FALSE;
1593}
1594
1595BOOL
1597 IN PCTSTR Src,
1598 OUT PTSTR Dest)
1599{
1600 PTCHAR DestEnd = &Dest[CMDLINE_LENGTH - 1];
1601 while (*Src)
1602 {
1603 if (Src[0] == _T('%'))
1604 {
1605 BOOL Dummy;
1606 PCTSTR End = &Src[2];
1607 PCTSTR Value = NULL;
1608
1609 if (Src[1] == _T('~'))
1611
1612 if (!Value && Src[1])
1613 {
1614 if (FindForVar(Src[1], &Value, &Dummy) && !Value)
1615 {
1616 /* The variable is empty, return an empty string */
1617 Value = _T("");
1618 }
1619 }
1620
1621 if (Value)
1622 {
1623 if (Dest + _tcslen(Value) > DestEnd)
1624 return FALSE;
1625 Dest = _stpcpy(Dest, Value);
1626 Src = End;
1627 continue;
1628 }
1629 }
1630 /* Not a variable; just copy the character */
1631 if (Dest >= DestEnd)
1632 return FALSE;
1633 *Dest++ = *Src++;
1634 }
1635 *Dest = _T('\0');
1636 return TRUE;
1637}
1638
1639PTSTR
1641 IN PCTSTR Line)
1642{
1643 TCHAR Buf1[CMDLINE_LENGTH];
1644 TCHAR Buf2[CMDLINE_LENGTH];
1645 PTCHAR Src, Dst;
1646 PTCHAR DestEnd = Buf2 + CMDLINE_LENGTH - 1;
1647 size_t SrcIncLen, DestIncLen;
1648
1649 /* First, substitute FOR variables */
1650 if (!SubstituteForVars(Line, Buf1))
1651 return NULL;
1652
1653 if (!bDelayedExpansion || !_tcschr(Buf1, _T('!')))
1654 return cmd_dup(Buf1);
1655
1656 /*
1657 * Delayed substitutions are not actually completely the same as
1658 * immediate substitutions. In particular, it is possible to escape
1659 * the exclamation point using the escape caret.
1660 */
1661
1662 /*
1663 * Perform delayed expansion: expand variables around '!',
1664 * and reparse escape carets.
1665 */
1666
1667#define APPEND1(Char) \
1668do { \
1669 if (Dst >= DestEnd) \
1670 goto too_long; \
1671 *Dst++ = (Char); \
1672} while (0)
1673
1674 Src = Buf1;
1675 Dst = Buf2;
1676 while (*Src && (Src < &Buf1[CMDLINE_LENGTH]))
1677 {
1678 if (*Src == _T('^'))
1679 {
1680 ++Src;
1681 if (!*Src || !(Src < &Buf1[CMDLINE_LENGTH]))
1682 break;
1683
1684 APPEND1(*Src++);
1685 }
1686 else if (*Src == _T('!'))
1687 {
1688 if (!SubstituteVar(Src, &SrcIncLen, Dst, DestEnd, &DestIncLen, _T('!')))
1689 {
1690 return NULL; // Got an error during parsing.
1691 }
1692 else
1693 {
1694 Src += SrcIncLen;
1695 Dst += DestIncLen;
1696 }
1697 }
1698 else
1699 {
1700 APPEND1(*Src++);
1701 }
1702 continue;
1703 }
1704 APPEND1(_T('\0'));
1705
1706 return cmd_dup(Buf2);
1707
1708too_long:
1710 nErrorLevel = 9023;
1711 return NULL;
1712
1713#undef APPEND1
1714}
1715
1716
1717/*
1718 * Do the prompt/input/process loop.
1719 */
1720BOOL
1721ReadLine(TCHAR *commandline, BOOL bMore)
1722{
1724 LPTSTR ip;
1725
1726 /* if no batch input then... */
1727 if (bc == NULL)
1728 {
1729 if (bMore)
1730 {
1732 }
1733 else
1734 {
1735 /* JPP 19980807 - if echo off, don't print prompt */
1736 if (bEcho)
1737 {
1738 if (!bIgnoreEcho)
1739 ConOutChar(_T('\n'));
1740 PrintPrompt();
1741 }
1742 }
1743
1745 {
1746 bExit = TRUE;
1747 return FALSE;
1748 }
1749
1750 if (readline[0] == _T('\0'))
1751 ConOutChar(_T('\n'));
1752
1754 return FALSE;
1755
1756 if (readline[0] == _T('\0'))
1757 return FALSE;
1758
1759 ip = readline;
1760 }
1761 else
1762 {
1763 ip = ReadBatchLine();
1764 if (!ip)
1765 return FALSE;
1766 }
1767
1768 return SubstituteVars(ip, commandline, _T('%'));
1769}
1770
1771static INT
1773{
1774 INT Ret = 0;
1776
1777 while (!bCanExit || !bExit)
1778 {
1779 /* Reset the Ctrl-Break / Ctrl-C state */
1780 bCtrlBreak = FALSE;
1781
1783 if (!Cmd)
1784 continue;
1785
1786 Ret = ExecuteCommand(Cmd);
1788 }
1789
1790 return Ret;
1791}
1792
1793
1794/*
1795 * Control-break handler.
1796 */
1797static BOOL
1798WINAPI
1800{
1801 DWORD dwWritten;
1802 INPUT_RECORD rec;
1803
1804 if ((dwCtrlType != CTRL_C_EVENT) &&
1805 (dwCtrlType != CTRL_BREAK_EVENT))
1806 {
1807 return FALSE;
1808 }
1809
1811 {
1812 /* Child process is running and will have received the control event */
1813 return TRUE;
1814 }
1815 else
1816 {
1818 }
1819
1820 bCtrlBreak = TRUE;
1821
1822 rec.EventType = KEY_EVENT;
1824 rec.Event.KeyEvent.wRepeatCount = 1;
1825 rec.Event.KeyEvent.wVirtualKeyCode = _T('C');
1826 rec.Event.KeyEvent.wVirtualScanCode = _T('C') - 35;
1827 rec.Event.KeyEvent.uChar.AsciiChar = _T('C');
1828 rec.Event.KeyEvent.uChar.UnicodeChar = _T('C');
1830
1832 &rec,
1833 1,
1834 &dwWritten);
1835
1836 /* FIXME: Handle batch files */
1837
1838 // ConOutPrintf(_T("^C"));
1839
1840 return TRUE;
1841}
1842
1843
1845{
1847}
1848
1849
1851{
1853}
1854
1855
1856/*
1857 * Show commands and options that are available.
1858 */
1859#if 0
1860static VOID
1861ShowCommands(VOID)
1862{
1863 /* print command list */
1866
1867 /* print feature list */
1869
1870#ifdef FEATURE_ALIASES
1872#endif
1873#ifdef FEATURE_HISTORY
1875#endif
1876#ifdef FEATURE_UNIX_FILENAME_COMPLETION
1878#endif
1879#ifdef FEATURE_DIRECTORY_STACK
1881#endif
1882#ifdef FEATURE_REDIRECTION
1884#endif
1885 ConOutChar(_T('\n'));
1886}
1887#endif
1888
1889
1890static VOID
1892{
1893 LONG lRet;
1894 HKEY hKey;
1895 DWORD dwType, len;
1896 /*
1897 * Buffer big enough to hold the string L"4294967295",
1898 * corresponding to the literal 0xFFFFFFFF (MAXULONG) in decimal.
1899 */
1900 DWORD Buffer[6];
1901
1902 lRet = RegOpenKeyEx(hKeyRoot,
1903 _T("Software\\Microsoft\\Command Processor"),
1904 0,
1906 &hKey);
1907 if (lRet != ERROR_SUCCESS)
1908 return;
1909
1910#ifdef INCLUDE_CMD_COLOR
1911 len = sizeof(Buffer);
1912 lRet = RegQueryValueEx(hKey,
1913 _T("DefaultColor"),
1914 NULL,
1915 &dwType,
1916 (LPBYTE)&Buffer,
1917 &len);
1918 if (lRet == ERROR_SUCCESS)
1919 {
1920 /* Overwrite the default attributes */
1921 if (dwType == REG_DWORD)
1923 else if (dwType == REG_SZ)
1925 }
1926 // else, use the default attributes retrieved before.
1927#endif
1928
1929#if 0
1930 len = sizeof(Buffer);
1931 lRet = RegQueryValueEx(hKey,
1932 _T("DisableUNCCheck"),
1933 NULL,
1934 &dwType,
1935 (LPBYTE)&Buffer,
1936 &len);
1937 if (lRet == ERROR_SUCCESS)
1938 {
1939 /* Overwrite the default setting */
1940 if (dwType == REG_DWORD)
1941 bDisableUNCCheck = !!*(PDWORD)Buffer;
1942 else if (dwType == REG_SZ)
1943 bDisableUNCCheck = (_ttol((PTSTR)Buffer) == 1);
1944 }
1945 // else, use the default setting set globally.
1946#endif
1947
1948 len = sizeof(Buffer);
1949 lRet = RegQueryValueEx(hKey,
1950 _T("DelayedExpansion"),
1951 NULL,
1952 &dwType,
1953 (LPBYTE)&Buffer,
1954 &len);
1955 if (lRet == ERROR_SUCCESS)
1956 {
1957 /* Overwrite the default setting */
1958 if (dwType == REG_DWORD)
1960 else if (dwType == REG_SZ)
1962 }
1963 // else, use the default setting set globally.
1964
1965 len = sizeof(Buffer);
1966 lRet = RegQueryValueEx(hKey,
1967 _T("EnableExtensions"),
1968 NULL,
1969 &dwType,
1970 (LPBYTE)&Buffer,
1971 &len);
1972 if (lRet == ERROR_SUCCESS)
1973 {
1974 /* Overwrite the default setting */
1975 if (dwType == REG_DWORD)
1977 else if (dwType == REG_SZ)
1979 }
1980 // else, use the default setting set globally.
1981
1982 len = sizeof(Buffer);
1983 lRet = RegQueryValueEx(hKey,
1984 _T("CompletionChar"),
1985 NULL,
1986 &dwType,
1987 (LPBYTE)&Buffer,
1988 &len);
1989 if (lRet == ERROR_SUCCESS)
1990 {
1991 /* Overwrite the default setting */
1992 if (dwType == REG_DWORD)
1994 else if (dwType == REG_SZ)
1996 }
1997 // else, use the default setting set globally.
1998
1999 /* Validity check */
2001 {
2002 /* Disable autocompletion */
2003 AutoCompletionChar = 0x20;
2004 }
2005
2006 len = sizeof(Buffer);
2007 lRet = RegQueryValueEx(hKey,
2008 _T("PathCompletionChar"),
2009 NULL,
2010 &dwType,
2011 (LPBYTE)&Buffer,
2012 &len);
2013 if (lRet == ERROR_SUCCESS)
2014 {
2015 /* Overwrite the default setting */
2016 if (dwType == REG_DWORD)
2018 else if (dwType == REG_SZ)
2020 }
2021 // else, use the default setting set globally.
2022
2023 /* Validity check */
2025 {
2026 /* Disable autocompletion */
2027 PathCompletionChar = 0x20;
2028 }
2029
2030 /* Adjust completion chars */
2031 if (PathCompletionChar >= 0x20 && AutoCompletionChar < 0x20)
2033 else if (AutoCompletionChar >= 0x20 && PathCompletionChar < 0x20)
2035
2037}
2038
2039static VOID
2041{
2042 LONG lRet;
2043 HKEY hKey;
2044 DWORD dwType, len;
2045 TCHAR AutoRun[2048];
2046
2047 lRet = RegOpenKeyEx(hKeyRoot,
2048 _T("Software\\Microsoft\\Command Processor"),
2049 0,
2051 &hKey);
2052 if (lRet != ERROR_SUCCESS)
2053 return;
2054
2055 len = sizeof(AutoRun);
2056 lRet = RegQueryValueEx(hKey,
2057 _T("AutoRun"),
2058 NULL,
2059 &dwType,
2060 (LPBYTE)&AutoRun,
2061 &len);
2062 if ((lRet == ERROR_SUCCESS) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
2063 {
2064 if (*AutoRun)
2065 ParseCommandLine(AutoRun);
2066 }
2067
2069}
2070
2071/* Get the command that comes after a /C or /K switch */
2072static VOID
2074 OUT LPTSTR commandline,
2075 IN LPCTSTR ptr,
2076 IN BOOL AlwaysStrip)
2077{
2078 TCHAR* LastQuote;
2079
2080 while (_istspace(*ptr))
2081 ++ptr;
2082
2083 /* Remove leading quote, find final quote */
2084 if (*ptr == _T('"') &&
2085 (LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL)
2086 {
2087 const TCHAR* Space;
2088 /* Under certain circumstances, all quotes are preserved.
2089 * CMD /? documents these conditions as follows:
2090 * 1. No /S switch
2091 * 2. Exactly two quotes
2092 * 3. No "special characters" between the quotes
2093 * (CMD /? says &<>()@^| but parentheses did not
2094 * trigger this rule when I tested them.)
2095 * 4. Whitespace exists between the quotes
2096 * 5. Enclosed string is an executable filename
2097 */
2098 *LastQuote = _T('\0');
2099 for (Space = ptr + 1; Space < LastQuote; ++Space)
2100 {
2101 if (_istspace(*Space)) /* Rule 4 */
2102 {
2103 if (!AlwaysStrip && /* Rule 1 */
2104 !_tcspbrk(ptr, _T("\"&<>@^|")) && /* Rules 2, 3 */
2105 SearchForExecutable(ptr, commandline)) /* Rule 5 */
2106 {
2107 /* All conditions met: preserve both the quotes */
2108 *LastQuote = _T('"');
2109 _tcscpy(commandline, ptr - 1);
2110 return;
2111 }
2112 break;
2113 }
2114 }
2115
2116 /* The conditions were not met: remove both the
2117 * leading quote and the last quote */
2118 _tcscpy(commandline, ptr);
2119 _tcscpy(&commandline[LastQuote - ptr], LastQuote + 1);
2120 return;
2121 }
2122
2123 /* No quotes; just copy */
2124 _tcscpy(commandline, ptr);
2125}
2126
2127
2128/*
2129 * Set up global initializations and process parameters.
2130 * Return a pointer to the command line if present.
2131 */
2132static LPCTSTR
2134{
2135 HMODULE NtDllModule;
2136 HANDLE hIn, hOut;
2137 LPTSTR ptr, cmdLine;
2138 TCHAR option = 0;
2139 BOOL AutoRun = TRUE;
2141
2142 /* Get version information */
2143 InitOSVersion();
2144
2145 /* Some people like to run ReactOS cmd.exe on Win98, it helps in the
2146 * build process. So don't link implicitly against ntdll.dll, load it
2147 * dynamically instead */
2148 NtDllModule = GetModuleHandle(TEXT("ntdll.dll"));
2149 if (NtDllModule != NULL)
2150 {
2151 NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess");
2152 NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
2153 }
2154
2155 /* Load the registry settings */
2158
2159 /* Initialize our locale */
2160 InitLocale();
2161
2162 /* Initialize prompt support */
2163 InitPrompt();
2164
2165#ifdef FEATURE_DIRECTORY_STACK
2166 /* Initialize directory stack */
2168#endif
2169
2170#ifdef FEATURE_HISTORY
2171 /* Initialize history */
2172 InitHistory();
2173#endif
2174
2175 /* Set COMSPEC environment variable */
2177 {
2178 ModuleName[MAX_PATH] = _T('\0');
2179 SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
2180 }
2181
2182 /* Add ctrl break handler */
2184
2185 /* Set the default console mode */
2188 SetConsoleMode(hOut, 0); // Reinitialize the console output mode
2191
2192 cmdLine = GetCommandLine();
2193 TRACE ("[command args: %s]\n", debugstr_aw(cmdLine));
2194
2195 for (ptr = cmdLine; *ptr; ++ptr)
2196 {
2197 if (*ptr == _T('/'))
2198 {
2199 option = _totupper(ptr[1]);
2200 if (option == _T('?'))
2201 {
2203 nErrorLevel = 1;
2204 bExit = TRUE;
2205 return NULL;
2206 }
2207 else if (option == _T('P'))
2208 {
2209 if (!IsExistingFile(_T("\\autoexec.bat")))
2210 {
2211#ifdef INCLUDE_CMD_DATE
2212 cmd_date(_T(""));
2213#endif
2214#ifdef INCLUDE_CMD_TIME
2215 cmd_time(_T(""));
2216#endif
2217 }
2218 else
2219 {
2220 ParseCommandLine(_T("\\autoexec.bat"));
2221 }
2222 bCanExit = FALSE;
2223 }
2224 else if (option == _T('A'))
2225 {
2227 }
2228 else if (option == _T('C') || option == _T('K') || option == _T('R'))
2229 {
2230 /* Remainder of command line is a command to be run */
2231 fSingleCommand = ((option == _T('K')) << 1) | 1;
2232 break;
2233 }
2234 else if (option == _T('D'))
2235 {
2236 AutoRun = FALSE;
2237 }
2238 else if (option == _T('Q'))
2239 {
2241 }
2242 else if (option == _T('S'))
2243 {
2245 }
2246#ifdef INCLUDE_CMD_COLOR
2247 else if (!_tcsnicmp(ptr, _T("/T:"), 3))
2248 {
2249 /* Process /T (color) argument; overwrite any previous settings */
2250 wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
2251 }
2252#endif
2253 else if (option == _T('U'))
2254 {
2256 }
2257 else if (option == _T('V'))
2258 {
2259 // FIXME: Check validity of the parameter given to V !
2260 bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
2261 }
2262 else if (option == _T('E'))
2263 {
2264 // FIXME: Check validity of the parameter given to E !
2265 bEnableExtensions = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
2266 }
2267 else if (option == _T('X'))
2268 {
2269 /* '/X' is identical to '/E:ON' */
2271 }
2272 else if (option == _T('Y'))
2273 {
2274 /* '/Y' is identical to '/E:OFF' */
2276 }
2277 }
2278 }
2279
2280#ifdef INCLUDE_CMD_COLOR
2281 if (wDefColor == 0)
2282 {
2283 /*
2284 * If we still do not have the console colour attribute set,
2285 * retrieve the default one.
2286 */
2288 }
2289
2290 if (wDefColor != 0)
2292#endif
2293
2294 /* Reset the output Standard Streams translation modes and code page caches */
2295 // ConStreamSetMode(StdIn , OutputStreamMode, InputCodePage );
2298
2299 if (!*ptr)
2300 {
2301 /* If neither /C or /K was given, display a simple version string */
2302 ConOutChar(_T('\n'));
2304 _T(KERNEL_VERSION_STR),
2305 _T(KERNEL_VERSION_BUILD_STR));
2306 ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n"));
2307 }
2308
2309 if (AutoRun)
2310 {
2313 }
2314
2315 /* Returns the rest of the command line */
2316 return ptr;
2317}
2318
2319
2321{
2322 /* Run cmdexit.bat */
2323 if (IsExistingFile(_T("cmdexit.bat")))
2324 {
2326 ParseCommandLine(_T("cmdexit.bat"));
2327 }
2328 else if (IsExistingFile(_T("\\cmdexit.bat")))
2329 {
2331 ParseCommandLine(_T("\\cmdexit.bat"));
2332 }
2333
2334 /* Remove ctrl break handler */
2336
2337 /* Restore the default console mode */
2342
2343
2344#ifdef _DEBUG_MEM
2345#ifdef FEATURE_DIRECTORY_STACK
2346 /* Destroy directory stack */
2348#endif
2349
2350#ifdef FEATURE_HISTORY
2351 CleanHistory();
2352#endif
2353
2354 /* Free GetEnvVar's buffer */
2355 GetEnvVar(NULL);
2356#endif /* _DEBUG_MEM */
2357
2359}
2360
2361/*
2362 * main function
2363 */
2364int _tmain(int argc, const TCHAR *argv[])
2365{
2366 INT nExitCode;
2367 LPCTSTR pCmdLine;
2368 TCHAR startPath[MAX_PATH];
2369
2372
2373 GetCurrentDirectory(ARRAYSIZE(startPath), startPath);
2374 _tchdir(startPath);
2375
2379
2380 /* Initialize the Console Standard Streams */
2384 /* Reset the current thread UI language */
2387 {
2389 }
2390
2392
2393 /*
2394 * Perform general initialization, parse switches on command-line.
2395 * Initialize the exit code with the errorlevel as Initialize() can set it.
2396 */
2397 pCmdLine = Initialize();
2398 nExitCode = nErrorLevel;
2399
2400 if (pCmdLine && *pCmdLine)
2401 {
2402 TCHAR commandline[CMDLINE_LENGTH];
2403
2404 /* Do the /C or /K command */
2405 GetCmdLineCommand(commandline, &pCmdLine[2], bAlwaysStrip);
2406 nExitCode = ParseCommandLine(commandline);
2407 if (fSingleCommand == 1)
2408 {
2409 // nErrorLevel = nExitCode;
2410 bExit = TRUE;
2411 }
2412 fSingleCommand = 0;
2413 }
2414 if (!bExit)
2415 {
2416 /* Call prompt routine */
2417 nExitCode = ProcessInput();
2418 }
2419
2420 /* Do the cleanup */
2421 Cleanup();
2423
2424 cmd_exit(nExitCode);
2425 return nExitCode;
2426}
2427
2428/* 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:33
#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:1574
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:1891
BOOL bDisableBatchEcho
Definition: cmd.c:160
BOOL SubstituteVars(IN PCTSTR Src, OUT PTSTR Dest, IN TCHAR Delim)
Definition: cmd.c:1514
BOOL ReadLine(TCHAR *commandline, BOOL bMore)
Definition: cmd.c:1721
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:1844
BOOL bExit
Definition: cmd.c:152
CON_STREAM_MODE OutputStreamMode
Definition: cmd.c:177
static INT ProcessInput(VOID)
Definition: cmd.c:1772
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:1273
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:1850
static VOID ExecuteAutoRunFile(HKEY hKeyRoot)
Definition: cmd.c:2040
static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr
Definition: cmd.c:171
static VOID GetCmdLineCommand(OUT LPTSTR commandline, IN LPCTSTR ptr, IN BOOL AlwaysStrip)
Definition: cmd.c:2073
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:1640
BOOL(WINAPI * MYEX)(LPSHELLEXECUTEINFO lpExecInfo)
Definition: cmd.c:264
static BOOL WINAPI BreakHandler(IN DWORD dwCtrlType)
Definition: cmd.c:1799
#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:1596
#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:1326
#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:675
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:704
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:38
#define ConOutResPrintf(uID,...)
Definition: console.h:47
#define ConOutPuts(szStr)
Definition: console.h:29
#define ConOutResPuts(uID)
Definition: console.h:35
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:181
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:49
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:21
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:265
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::@3287 Event
WORD EventType
Definition: wincon.h:273
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
WORD wVirtualScanCode
Definition: wincon.h:243
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wVirtualKeyCode
Definition: wincon.h:242
WORD wRepeatCount
Definition: wincon.h:241
union _KEY_EVENT_RECORD::@3286 uChar
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:3749
#define CreateProcess
Definition: winbase.h:3693
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
#define LoadLibrary
Definition: winbase.h:3797
BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3654
#define SetCurrentDirectory
Definition: winbase.h:3838
#define GetCommandLine
Definition: winbase.h:3734
#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:3843
#define GetModuleHandle
Definition: winbase.h:3762
VOID WINAPI SetFileApisToOEM(void)
Definition: utils.c:831
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define SearchPath
Definition: winbase.h:3835
#define FindFirstFile
Definition: winbase.h:3717
#define GetCurrentDirectory
Definition: winbase.h:3740
#define GetModuleFileName
Definition: winbase.h:3766
#define GetFullPathName
Definition: winbase.h:3756
#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:770
#define SW_SHOWDEFAULT
Definition: winuser.h:780
_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:409
#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