8 #define MAX_STRING 2000
9 WCHAR szStringBuf
[MAX_STRING
];
10 LPWSTR pszExeName
= L
"cmd.exe";
12 /* Function pointers */
13 typedef DWORD (WINAPI
*GetConsoleCommandHistoryW_t
) (LPWSTR sCommands
, DWORD nBufferLength
, LPWSTR sExeName
);
14 typedef DWORD (WINAPI
*GetConsoleCommandHistoryLengthW_t
) (LPWSTR sExeName
);
15 typedef BOOL (WINAPI
*SetConsoleNumberOfCommandsW_t
)(DWORD nNumber
, LPWSTR sExeName
);
16 typedef VOID (WINAPI
*ExpungeConsoleCommandHistoryW_t
)(LPWSTR sExeName
);
18 GetConsoleCommandHistoryW_t pGetConsoleCommandHistoryW
;
19 GetConsoleCommandHistoryLengthW_t pGetConsoleCommandHistoryLengthW
;
20 SetConsoleNumberOfCommandsW_t pSetConsoleNumberOfCommandsW
;
21 ExpungeConsoleCommandHistoryW_t pExpungeConsoleCommandHistoryW
;
23 static VOID
SetInsert(DWORD dwFlag
)
26 HANDLE hConsole
= GetStdHandle(STD_INPUT_HANDLE
);
27 GetConsoleMode(hConsole
, &dwMode
);
28 dwMode
|= ENABLE_EXTENDED_FLAGS
;
29 SetConsoleMode(hConsole
, (dwMode
& ~ENABLE_INSERT_MODE
) | dwFlag
);
32 static VOID
PrintHistory(VOID
)
34 DWORD Length
= pGetConsoleCommandHistoryLengthW(pszExeName
);
39 HistBuf
= HeapAlloc(GetProcessHeap(),
43 Hist
= (WCHAR
*)HistBuf
;
44 HistEnd
= (WCHAR
*)&HistBuf
[Length
];
46 if (pGetConsoleCommandHistoryW(Hist
, Length
, pszExeName
))
47 for (; Hist
< HistEnd
; Hist
+= wcslen(Hist
) + 1)
48 wprintf(L
"%s\n", Hist
);
50 HeapFree(GetProcessHeap(), 0, HistBuf
);
53 static INT
SetMacro(LPWSTR definition
)
55 WCHAR
*name
, *nameend
, *text
, temp
;
61 /* error if no '=' found */
62 if ((nameend
= wcschr(name
, L
'=')) != NULL
)
68 while (nameend
> name
&& nameend
[-1] == L
' ')
71 /* Split rest into name and substitute */
74 /* Don't allow spaces in the name, since such a macro would be unusable */
75 if (!wcschr(name
, L
' ') && AddConsoleAlias(name
, text
, pszExeName
))
80 LoadString(GetModuleHandle(NULL
), IDS_INVALID_MACRO_DEF
, szStringBuf
, MAX_STRING
);
81 wprintf(szStringBuf
, definition
);
85 static VOID
PrintMacros(LPWSTR pszExeName
, LPWSTR Indent
)
87 DWORD Length
= GetConsoleAliasesLength(pszExeName
);
92 AliasBuf
= HeapAlloc(GetProcessHeap(),
94 Length
* sizeof(BYTE
));
95 if (!AliasBuf
) return;
96 Alias
= (WCHAR
*)AliasBuf
;
97 AliasEnd
= (WCHAR
*)&AliasBuf
[Length
];
99 if (GetConsoleAliases(Alias
, Length
* sizeof(BYTE
), pszExeName
))
100 for (; Alias
< AliasEnd
; Alias
+= wcslen(Alias
) + 1)
101 wprintf(L
"%s%s\n", Indent
, Alias
);
103 HeapFree(GetProcessHeap(), 0, AliasBuf
);
106 static VOID
PrintAllMacros(VOID
)
108 DWORD Length
= GetConsoleAliasExesLength();
113 ExeNameBuf
= HeapAlloc(GetProcessHeap(),
115 Length
* sizeof(BYTE
));
116 if (!ExeNameBuf
) return;
117 ExeName
= (WCHAR
*)ExeNameBuf
;
118 ExeNameEnd
= (WCHAR
*)&ExeNameBuf
[Length
];
120 if (GetConsoleAliasExes(ExeName
, Length
* sizeof(BYTE
)))
122 for (; ExeName
< ExeNameEnd
; ExeName
+= wcslen(ExeName
) + 1)
124 wprintf(L
"[%s]\n", ExeName
);
125 PrintMacros(ExeName
, L
" ");
130 HeapFree(GetProcessHeap(), 0, ExeNameBuf
);
133 static VOID
ReadFromFile(LPWSTR param
)
136 WCHAR line
[MAX_PATH
];
138 fp
= _wfopen(param
, L
"r");
145 while ( fgetws(line
, MAX_PATH
, fp
) != NULL
)
147 /* Remove newline character */
148 WCHAR
*end
= &line
[wcslen(line
) - 1];
160 /* Get the start and end of the next command-line argument. */
161 static BOOL
GetArg(WCHAR
**pStart
, WCHAR
**pEnd
)
163 BOOL bInQuotes
= FALSE
;
165 p
+= wcsspn(p
, L
" \t");
171 if (!bInQuotes
&& (*p
== L
' ' || *p
== L
'\t'))
173 bInQuotes
^= (*p
++ == L
'"');
179 /* Remove starting and ending quotes from a string, if present */
180 static LPWSTR
RemoveQuotes(LPWSTR str
)
183 if (*str
== L
'"' && *(end
= str
+ wcslen(str
) - 1) == L
'"')
198 setlocale(LC_ALL
, "");
200 /* Get the full command line using GetCommandLine(). We can't just use argv,
201 * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */
202 pArgEnd
= GetCommandLine();
203 hKernel32
= LoadLibraryW(L
"kernel32.dll");
205 /* Get function pointers */
206 pGetConsoleCommandHistoryW
= (GetConsoleCommandHistoryW_t
)GetProcAddress( hKernel32
, "GetConsoleCommandHistoryW");
207 pGetConsoleCommandHistoryLengthW
= (GetConsoleCommandHistoryLengthW_t
)GetProcAddress( hKernel32
, "GetConsoleCommandHistoryLengthW");
208 pSetConsoleNumberOfCommandsW
= (SetConsoleNumberOfCommandsW_t
)GetProcAddress( hKernel32
, "SetConsoleNumberOfCommandsW");
209 pExpungeConsoleCommandHistoryW
= (ExpungeConsoleCommandHistoryW_t
)GetProcAddress( hKernel32
, "ExpungeConsoleCommandHistoryW");
211 assert(pGetConsoleCommandHistoryW
&& pGetConsoleCommandHistoryLengthW
&&
212 pSetConsoleNumberOfCommandsW
&& pExpungeConsoleCommandHistoryW
);
214 /* Skip the application name */
215 GetArg(&pArgStart
, &pArgEnd
);
217 while (GetArg(&pArgStart
, &pArgEnd
))
219 /* NUL-terminate this argument to make processing easier */
220 WCHAR tmp
= *pArgEnd
;
223 if (!wcscmp(pArgStart
, L
"/?"))
225 LoadString(GetModuleHandle(NULL
), IDS_HELP
, szStringBuf
, MAX_STRING
);
226 wprintf(szStringBuf
);
229 else if (!_wcsnicmp(pArgStart
, L
"/EXENAME=", 9))
231 pszExeName
= RemoveQuotes(pArgStart
+ 9);
233 else if (!wcsicmp(pArgStart
, L
"/H") ||
234 !wcsicmp(pArgStart
, L
"/HISTORY"))
238 else if (!_wcsnicmp(pArgStart
, L
"/LISTSIZE=", 10))
240 pSetConsoleNumberOfCommandsW(_wtoi(pArgStart
+ 10), pszExeName
);
242 else if (!wcsicmp(pArgStart
, L
"/REINSTALL"))
244 pExpungeConsoleCommandHistoryW(pszExeName
);
246 else if (!wcsicmp(pArgStart
, L
"/INSERT"))
248 SetInsert(ENABLE_INSERT_MODE
);
250 else if (!wcsicmp(pArgStart
, L
"/OVERSTRIKE"))
254 else if (!wcsicmp(pArgStart
, L
"/M") ||
255 !wcsicmp(pArgStart
, L
"/MACROS"))
257 PrintMacros(pszExeName
, L
"");
259 else if (!_wcsnicmp(pArgStart
, L
"/M:", 3) ||
260 !_wcsnicmp(pArgStart
, L
"/MACROS:", 8))
262 LPWSTR exe
= RemoveQuotes(wcschr(pArgStart
, L
':') + 1);
263 if (!wcsicmp(exe
, L
"ALL"))
266 PrintMacros(exe
, L
"");
268 else if (!_wcsnicmp(pArgStart
, L
"/MACROFILE=", 11))
270 ReadFromFile(RemoveQuotes(pArgStart
+ 11));
274 /* This is the beginning of a macro definition. It includes
275 * the entire remainder of the line, so first put back the
276 * character that we replaced with NUL. */
278 return SetMacro(pArgStart
);