7 #define MAX_STRING 2000
8 WCHAR szStringBuf
[MAX_STRING
];
9 LPWSTR pszExeName
= L
"cmd.exe";
11 /* Function pointers */
12 typedef DWORD (WINAPI
*GetConsoleCommandHistoryW_t
) (LPWSTR sCommands
, DWORD nBufferLength
, LPWSTR sExeName
);
13 typedef DWORD (WINAPI
*GetConsoleCommandHistoryLengthW_t
) (LPWSTR sExeName
);
14 typedef BOOL (WINAPI
*SetConsoleNumberOfCommandsW_t
)(DWORD nNumber
, LPWSTR sExeName
);
15 typedef VOID (WINAPI
*ExpungeConsoleCommandHistoryW_t
)(LPWSTR sExeName
);
17 GetConsoleCommandHistoryW_t pGetConsoleCommandHistoryW
;
18 GetConsoleCommandHistoryLengthW_t pGetConsoleCommandHistoryLengthW
;
19 SetConsoleNumberOfCommandsW_t pSetConsoleNumberOfCommandsW
;
20 ExpungeConsoleCommandHistoryW_t pExpungeConsoleCommandHistoryW
;
22 static VOID
SetInsert(DWORD dwFlag
)
25 HANDLE hConsole
= GetStdHandle(STD_INPUT_HANDLE
);
26 GetConsoleMode(hConsole
, &dwMode
);
27 dwMode
|= ENABLE_EXTENDED_FLAGS
;
28 SetConsoleMode(hConsole
, (dwMode
& ~ENABLE_INSERT_MODE
) | dwFlag
);
31 static VOID
PrintHistory(VOID
)
33 DWORD Length
= pGetConsoleCommandHistoryLengthW(pszExeName
);
38 HistBuf
= HeapAlloc(GetProcessHeap(),
42 Hist
= (WCHAR
*)HistBuf
;
43 HistEnd
= (WCHAR
*)&HistBuf
[Length
];
45 if (pGetConsoleCommandHistoryW(Hist
, Length
, pszExeName
))
46 for (; Hist
< HistEnd
; Hist
+= wcslen(Hist
) + 1)
47 wprintf(L
"%s\n", Hist
);
49 HeapFree(GetProcessHeap(), 0, HistBuf
);
52 static INT
SetMacro(LPWSTR definition
)
54 WCHAR
*name
, *nameend
, *text
, temp
;
60 /* error if no '=' found */
61 if ((nameend
= wcschr(name
, L
'=')) != NULL
)
67 while (nameend
> name
&& nameend
[-1] == L
' ')
70 /* Split rest into name and substitute */
73 /* Don't allow spaces in the name, since such a macro would be unusable */
74 if (!wcschr(name
, L
' ') && AddConsoleAlias(name
, text
, pszExeName
))
79 LoadString(GetModuleHandle(NULL
), IDS_INVALID_MACRO_DEF
, szStringBuf
, MAX_STRING
);
80 wprintf(szStringBuf
, definition
);
84 static VOID
PrintMacros(LPWSTR pszExeName
, LPWSTR Indent
)
86 DWORD Length
= GetConsoleAliasesLength(pszExeName
);
91 AliasBuf
= HeapAlloc(GetProcessHeap(),
93 Length
* sizeof(BYTE
));
94 if (!AliasBuf
) return;
95 Alias
= (WCHAR
*)AliasBuf
;
96 AliasEnd
= (WCHAR
*)&AliasBuf
[Length
];
98 if (GetConsoleAliases(Alias
, Length
* sizeof(BYTE
), pszExeName
))
99 for (; Alias
< AliasEnd
; Alias
+= wcslen(Alias
) + 1)
100 wprintf(L
"%s%s\n", Indent
, Alias
);
102 HeapFree(GetProcessHeap(), 0, AliasBuf
);
105 static VOID
PrintAllMacros(VOID
)
107 DWORD Length
= GetConsoleAliasExesLength();
112 ExeNameBuf
= HeapAlloc(GetProcessHeap(),
114 Length
* sizeof(BYTE
));
115 if (!ExeNameBuf
) return;
116 ExeName
= (WCHAR
*)ExeNameBuf
;
117 ExeNameEnd
= (WCHAR
*)&ExeNameBuf
[Length
];
119 if (GetConsoleAliasExes(ExeName
, Length
* sizeof(BYTE
)))
121 for (; ExeName
< ExeNameEnd
; ExeName
+= wcslen(ExeName
) + 1)
123 wprintf(L
"[%s]\n", ExeName
);
124 PrintMacros(ExeName
, L
" ");
129 HeapFree(GetProcessHeap(), 0, ExeNameBuf
);
132 static VOID
ReadFromFile(LPWSTR param
)
135 WCHAR line
[MAX_PATH
];
137 fp
= _wfopen(param
, L
"r");
144 while ( fgetws(line
, MAX_PATH
, fp
) != NULL
)
146 /* Remove newline character */
147 WCHAR
*end
= &line
[wcslen(line
) - 1];
159 /* Get the start and end of the next command-line argument. */
160 static BOOL
GetArg(WCHAR
**pStart
, WCHAR
**pEnd
)
162 BOOL bInQuotes
= FALSE
;
164 p
+= wcsspn(p
, L
" \t");
170 if (!bInQuotes
&& (*p
== L
' ' || *p
== L
'\t'))
172 bInQuotes
^= (*p
++ == L
'"');
178 /* Remove starting and ending quotes from a string, if present */
179 static LPWSTR
RemoveQuotes(LPWSTR str
)
182 if (*str
== L
'"' && *(end
= str
+ wcslen(str
) - 1) == L
'"')
193 /* Get the full command line using GetCommandLine(). We can't just use argv,
194 * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */
196 WCHAR
*pArgEnd
= GetCommandLine();
197 HMODULE hKernel32
= LoadLibraryW(L
"kernel32.dll");
199 /* Get function pointers */
200 pGetConsoleCommandHistoryW
= (GetConsoleCommandHistoryW_t
)GetProcAddress( hKernel32
, "GetConsoleCommandHistoryW");
201 pGetConsoleCommandHistoryLengthW
= (GetConsoleCommandHistoryLengthW_t
)GetProcAddress( hKernel32
, "GetConsoleCommandHistoryLengthW");
202 pSetConsoleNumberOfCommandsW
= (SetConsoleNumberOfCommandsW_t
)GetProcAddress( hKernel32
, "SetConsoleNumberOfCommandsW");
203 pExpungeConsoleCommandHistoryW
= (ExpungeConsoleCommandHistoryW_t
)GetProcAddress( hKernel32
, "ExpungeConsoleCommandHistoryW");
205 assert(pGetConsoleCommandHistoryW
&& pGetConsoleCommandHistoryLengthW
&&
206 pSetConsoleNumberOfCommandsW
&& pSetConsoleNumberOfCommandsW
);
208 /* Skip the application name */
209 GetArg(&pArgStart
, &pArgEnd
);
211 while (GetArg(&pArgStart
, &pArgEnd
))
213 /* NUL-terminate this argument to make processing easier */
214 WCHAR tmp
= *pArgEnd
;
217 if (!wcscmp(pArgStart
, L
"/?"))
219 LoadString(GetModuleHandle(NULL
), IDS_HELP
, szStringBuf
, MAX_STRING
);
220 wprintf(szStringBuf
);
223 else if (!_wcsnicmp(pArgStart
, L
"/EXENAME=", 9))
225 pszExeName
= RemoveQuotes(pArgStart
+ 9);
227 else if (!wcsicmp(pArgStart
, L
"/H") ||
228 !wcsicmp(pArgStart
, L
"/HISTORY"))
232 else if (!_wcsnicmp(pArgStart
, L
"/LISTSIZE=", 10))
234 pSetConsoleNumberOfCommandsW(_wtoi(pArgStart
+ 10), pszExeName
);
236 else if (!wcsicmp(pArgStart
, L
"/REINSTALL"))
238 pExpungeConsoleCommandHistoryW(pszExeName
);
240 else if (!wcsicmp(pArgStart
, L
"/INSERT"))
242 SetInsert(ENABLE_INSERT_MODE
);
244 else if (!wcsicmp(pArgStart
, L
"/OVERSTRIKE"))
248 else if (!wcsicmp(pArgStart
, L
"/M") ||
249 !wcsicmp(pArgStart
, L
"/MACROS"))
251 PrintMacros(pszExeName
, L
"");
253 else if (!_wcsnicmp(pArgStart
, L
"/M:", 3) ||
254 !_wcsnicmp(pArgStart
, L
"/MACROS:", 8))
256 LPWSTR exe
= RemoveQuotes(wcschr(pArgStart
, L
':') + 1);
257 if (!wcsicmp(exe
, L
"ALL"))
260 PrintMacros(exe
, L
"");
262 else if (!_wcsnicmp(pArgStart
, L
"/MACROFILE=", 11))
264 ReadFromFile(RemoveQuotes(pArgStart
+ 11));
268 /* This is the beginning of a macro definition. It includes
269 * the entire remainder of the line, so first put back the
270 * character that we replaced with NUL. */
272 return SetMacro(pArgStart
);