6 #define MAX_STRING 2000
7 TCHAR szStringBuf
[MAX_STRING
];
8 LPTSTR pszExeName
= _T("cmd.exe");
10 static VOID
SetInsert(DWORD dwFlag
)
13 HANDLE hConsole
= GetStdHandle(STD_INPUT_HANDLE
);
14 GetConsoleMode(hConsole
, &dwMode
);
15 dwMode
|= ENABLE_EXTENDED_FLAGS
;
16 SetConsoleMode(hConsole
, (dwMode
& ~ENABLE_INSERT_MODE
) | dwFlag
);
19 static VOID
PrintHistory(VOID
)
21 DWORD Length
= GetConsoleCommandHistoryLength(pszExeName
);
27 /* On Windows, the ANSI version of GetConsoleCommandHistory requires
28 * a buffer twice as large as the actual history length. */
29 BufferLength
= Length
* (sizeof(WCHAR
) / sizeof(TCHAR
)) * sizeof(BYTE
);
31 HistBuf
= HeapAlloc(GetProcessHeap(),
35 Hist
= (TCHAR
*)HistBuf
;
36 HistEnd
= (TCHAR
*)&HistBuf
[Length
];
38 if (GetConsoleCommandHistory(Hist
, BufferLength
, pszExeName
))
39 for (; Hist
< HistEnd
; Hist
+= _tcslen(Hist
) + 1)
40 _tprintf(_T("%s\n"), Hist
);
42 HeapFree(GetProcessHeap(), 0, HistBuf
);
45 static INT
SetMacro(LPTSTR definition
)
47 TCHAR
*name
, *nameend
, *text
, temp
;
50 while (*name
== _T(' '))
53 /* error if no '=' found */
54 if ((nameend
= _tcschr(name
, _T('='))) != NULL
)
57 while (*text
== _T(' '))
60 while (nameend
> name
&& nameend
[-1] == _T(' '))
63 /* Split rest into name and substitute */
66 /* Don't allow spaces in the name, since such a macro would be unusable */
67 if (!_tcschr(name
, _T(' ')) && AddConsoleAlias(name
, text
, pszExeName
))
72 LoadString(GetModuleHandle(NULL
), IDS_INVALID_MACRO_DEF
, szStringBuf
, MAX_STRING
);
73 _tprintf(szStringBuf
, definition
);
77 static VOID
PrintMacros(LPTSTR pszExeName
, LPTSTR Indent
)
79 DWORD Length
= GetConsoleAliasesLength(pszExeName
);
84 AliasBuf
= HeapAlloc(GetProcessHeap(),
86 Length
* sizeof(BYTE
));
87 if (!AliasBuf
) return;
88 Alias
= (TCHAR
*)AliasBuf
;
89 AliasEnd
= (TCHAR
*)&AliasBuf
[Length
];
91 if (GetConsoleAliases(Alias
, Length
* sizeof(BYTE
), pszExeName
))
92 for (; Alias
< AliasEnd
; Alias
+= _tcslen(Alias
) + 1)
93 _tprintf(_T("%s%s\n"), Indent
, Alias
);
95 HeapFree(GetProcessHeap(), 0, AliasBuf
);
98 static VOID
PrintAllMacros(VOID
)
100 DWORD Length
= GetConsoleAliasExesLength();
105 ExeNameBuf
= HeapAlloc(GetProcessHeap(),
107 Length
* sizeof(BYTE
));
108 if (!ExeNameBuf
) return;
109 ExeName
= (TCHAR
*)ExeNameBuf
;
110 ExeNameEnd
= (TCHAR
*)&ExeNameBuf
[Length
];
112 if (GetConsoleAliasExes(ExeName
, Length
* sizeof(BYTE
)))
114 for (; ExeName
< ExeNameEnd
; ExeName
+= _tcslen(ExeName
) + 1)
116 _tprintf(_T("[%s]\n"), ExeName
);
117 PrintMacros(ExeName
, _T(" "));
122 HeapFree(GetProcessHeap(), 0, ExeNameBuf
);
125 static VOID
ReadFromFile(LPTSTR param
)
128 TCHAR line
[MAX_PATH
];
130 fp
= _tfopen(param
, _T("r"));
141 while ( _fgetts(line
, MAX_PATH
, fp
) != NULL
)
143 /* Remove newline character */
144 TCHAR
*end
= &line
[_tcslen(line
) - 1];
145 if (*end
== _T('\n'))
156 /* Get the start and end of the next command-line argument. */
157 static BOOL
GetArg(TCHAR
**pStart
, TCHAR
**pEnd
)
159 BOOL bInQuotes
= FALSE
;
161 p
+= _tcsspn(p
, _T(" \t"));
167 if (!bInQuotes
&& (*p
== _T(' ') || *p
== _T('\t')))
169 bInQuotes
^= (*p
++ == _T('"'));
175 /* Remove starting and ending quotes from a string, if present */
176 static LPTSTR
RemoveQuotes(LPTSTR str
)
179 if (*str
== _T('"') && *(end
= str
+ _tcslen(str
) - 1) == _T('"'))
190 /* Get the full command line using GetCommandLine(). We can't just use argv,
191 * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */
193 TCHAR
*pArgEnd
= GetCommandLine();
195 /* Skip the application name */
196 GetArg(&pArgStart
, &pArgEnd
);
198 while (GetArg(&pArgStart
, &pArgEnd
))
200 /* NUL-terminate this argument to make processing easier */
201 TCHAR tmp
= *pArgEnd
;
204 if (!_tcscmp(pArgStart
, _T("/?")))
206 LoadString(GetModuleHandle(NULL
), IDS_HELP
, szStringBuf
, MAX_STRING
);
207 _tprintf(szStringBuf
);
210 else if (!_tcsnicmp(pArgStart
, _T("/EXENAME="), 9))
212 pszExeName
= RemoveQuotes(pArgStart
+ 9);
214 else if (!_tcsicmp(pArgStart
, _T("/H")) ||
215 !_tcsicmp(pArgStart
, _T("/HISTORY")))
219 else if (!_tcsnicmp(pArgStart
, _T("/LISTSIZE="), 10))
221 SetConsoleNumberOfCommands(_ttoi(pArgStart
+ 10), pszExeName
);
223 else if (!_tcsicmp(pArgStart
, _T("/REINSTALL")))
225 ExpungeConsoleCommandHistory(pszExeName
);
227 else if (!_tcsicmp(pArgStart
, _T("/INSERT")))
229 SetInsert(ENABLE_INSERT_MODE
);
231 else if (!_tcsicmp(pArgStart
, _T("/OVERSTRIKE")))
235 else if (!_tcsicmp(pArgStart
, _T("/M")) ||
236 !_tcsicmp(pArgStart
, _T("/MACROS")))
238 PrintMacros(pszExeName
, _T(""));
240 else if (!_tcsnicmp(pArgStart
, _T("/M:"), 3) ||
241 !_tcsnicmp(pArgStart
, _T("/MACROS:"), 8))
243 LPTSTR exe
= RemoveQuotes(_tcschr(pArgStart
, _T(':')) + 1);
244 if (!_tcsicmp(exe
, _T("ALL")))
247 PrintMacros(exe
, _T(""));
249 else if (!_tcsnicmp(pArgStart
, _T("/MACROFILE="), 11))
251 ReadFromFile(RemoveQuotes(pArgStart
+ 11));
255 /* This is the beginning of a macro definition. It includes
256 * the entire remainder of the line, so first put back the
257 * character that we replaced with NUL. */
259 return SetMacro(pArgStart
);