1
1
#include <windows.h>
2
2
#include <stdio.h>
3
- #include <tchar.h>
3
+ #include <wchar.h>
4
+ #include <assert.h>
4
5
#include "doskey.h"
5
6
6
7
#define MAX_STRING 2000
7
- TCHAR szStringBuf [MAX_STRING ];
8
- LPTSTR pszExeName = _T ("cmd.exe" );
8
+ WCHAR szStringBuf [MAX_STRING ];
9
+ LPWSTR pszExeName = L"cmd.exe" ;
10
+
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 );
16
+
17
+ GetConsoleCommandHistoryW_t pGetConsoleCommandHistoryW ;
18
+ GetConsoleCommandHistoryLengthW_t pGetConsoleCommandHistoryLengthW ;
19
+ SetConsoleNumberOfCommandsW_t pSetConsoleNumberOfCommandsW ;
20
+ ExpungeConsoleCommandHistoryW_t pExpungeConsoleCommandHistoryW ;
9
21
10
22
static VOID SetInsert (DWORD dwFlag )
11
23
{
@@ -18,79 +30,74 @@ static VOID SetInsert(DWORD dwFlag)
18
30
19
31
static VOID PrintHistory (VOID )
20
32
{
21
- DWORD Length = GetConsoleCommandHistoryLength (pszExeName );
22
- DWORD BufferLength ;
33
+ DWORD Length = pGetConsoleCommandHistoryLengthW (pszExeName );
23
34
PBYTE HistBuf ;
24
- TCHAR * Hist ;
25
- TCHAR * HistEnd ;
26
-
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 );
35
+ WCHAR * Hist ;
36
+ WCHAR * HistEnd ;
30
37
31
38
HistBuf = HeapAlloc (GetProcessHeap (),
32
39
HEAP_ZERO_MEMORY ,
33
- BufferLength );
40
+ Length );
34
41
if (!HistBuf ) return ;
35
- Hist = (TCHAR * )HistBuf ;
36
- HistEnd = (TCHAR * )& HistBuf [Length ];
42
+ Hist = (WCHAR * )HistBuf ;
43
+ HistEnd = (WCHAR * )& HistBuf [Length ];
37
44
38
- if (GetConsoleCommandHistory (Hist , BufferLength , pszExeName ))
39
- for (; Hist < HistEnd ; Hist += _tcslen (Hist ) + 1 )
40
- _tprintf ( _T ( "%s\n" ) , Hist );
45
+ if (pGetConsoleCommandHistoryW (Hist , Length , pszExeName ))
46
+ for (; Hist < HistEnd ; Hist += wcslen (Hist ) + 1 )
47
+ wprintf ( L "%s\n" , Hist );
41
48
42
49
HeapFree (GetProcessHeap (), 0 , HistBuf );
43
50
}
44
51
45
- static INT SetMacro (LPTSTR definition )
52
+ static INT SetMacro (LPWSTR definition )
46
53
{
47
- TCHAR * name , * nameend , * text , temp ;
54
+ WCHAR * name , * nameend , * text , temp ;
48
55
49
56
name = definition ;
50
- while (* name == _T ( ' ' ) )
57
+ while (* name == L ' ' )
51
58
name ++ ;
52
59
53
60
/* error if no '=' found */
54
- if ((nameend = _tcschr (name , _T ( '=' ) )) != NULL )
61
+ if ((nameend = wcschr (name , L '=' )) != NULL )
55
62
{
56
63
text = nameend + 1 ;
57
- while (* text == _T ( ' ' ) )
64
+ while (* text == L ' ' )
58
65
text ++ ;
59
66
60
- while (nameend > name && nameend [-1 ] == _T ( ' ' ) )
67
+ while (nameend > name && nameend [-1 ] == L ' ' )
61
68
nameend -- ;
62
69
63
70
/* Split rest into name and substitute */
64
71
temp = * nameend ;
65
- * nameend = _T ( '\0' ) ;
72
+ * nameend = L '\0' ;
66
73
/* Don't allow spaces in the name, since such a macro would be unusable */
67
- if (!_tcschr (name , _T ( ' ' ) ) && AddConsoleAlias (name , text , pszExeName ))
74
+ if (!wcschr (name , L ' ' ) && AddConsoleAlias (name , text , pszExeName ))
68
75
return 0 ;
69
76
* nameend = temp ;
70
77
}
71
78
72
79
LoadString (GetModuleHandle (NULL ), IDS_INVALID_MACRO_DEF , szStringBuf , MAX_STRING );
73
- _tprintf (szStringBuf , definition );
80
+ wprintf (szStringBuf , definition );
74
81
return 1 ;
75
82
}
76
83
77
- static VOID PrintMacros (LPTSTR pszExeName , LPTSTR Indent )
84
+ static VOID PrintMacros (LPWSTR pszExeName , LPWSTR Indent )
78
85
{
79
86
DWORD Length = GetConsoleAliasesLength (pszExeName );
80
87
PBYTE AliasBuf ;
81
- TCHAR * Alias ;
82
- TCHAR * AliasEnd ;
88
+ WCHAR * Alias ;
89
+ WCHAR * AliasEnd ;
83
90
84
91
AliasBuf = HeapAlloc (GetProcessHeap (),
85
92
HEAP_ZERO_MEMORY ,
86
93
Length * sizeof (BYTE ));
87
94
if (!AliasBuf ) return ;
88
- Alias = (TCHAR * )AliasBuf ;
89
- AliasEnd = (TCHAR * )& AliasBuf [Length ];
95
+ Alias = (WCHAR * )AliasBuf ;
96
+ AliasEnd = (WCHAR * )& AliasBuf [Length ];
90
97
91
98
if (GetConsoleAliases (Alias , Length * sizeof (BYTE ), pszExeName ))
92
- for (; Alias < AliasEnd ; Alias += _tcslen (Alias ) + 1 )
93
- _tprintf ( _T ( "%s%s\n" ) , Indent , Alias );
99
+ for (; Alias < AliasEnd ; Alias += wcslen (Alias ) + 1 )
100
+ wprintf ( L "%s%s\n" , Indent , Alias );
94
101
95
102
HeapFree (GetProcessHeap (), 0 , AliasBuf );
96
103
}
@@ -99,51 +106,47 @@ static VOID PrintAllMacros(VOID)
99
106
{
100
107
DWORD Length = GetConsoleAliasExesLength ();
101
108
PBYTE ExeNameBuf ;
102
- TCHAR * ExeName ;
103
- TCHAR * ExeNameEnd ;
109
+ WCHAR * ExeName ;
110
+ WCHAR * ExeNameEnd ;
104
111
105
112
ExeNameBuf = HeapAlloc (GetProcessHeap (),
106
113
HEAP_ZERO_MEMORY ,
107
114
Length * sizeof (BYTE ));
108
115
if (!ExeNameBuf ) return ;
109
- ExeName = (TCHAR * )ExeNameBuf ;
110
- ExeNameEnd = (TCHAR * )& ExeNameBuf [Length ];
116
+ ExeName = (WCHAR * )ExeNameBuf ;
117
+ ExeNameEnd = (WCHAR * )& ExeNameBuf [Length ];
111
118
112
119
if (GetConsoleAliasExes (ExeName , Length * sizeof (BYTE )))
113
120
{
114
- for (; ExeName < ExeNameEnd ; ExeName += _tcslen (ExeName ) + 1 )
121
+ for (; ExeName < ExeNameEnd ; ExeName += wcslen (ExeName ) + 1 )
115
122
{
116
- _tprintf ( _T ( "[%s]\n" ) , ExeName );
117
- PrintMacros (ExeName , _T ( " " ) );
118
- _tprintf ( _T ( "\n" ) );
123
+ wprintf ( L "[%s]\n" , ExeName );
124
+ PrintMacros (ExeName , L " " );
125
+ wprintf ( L "\n" );
119
126
}
120
127
}
121
128
122
129
HeapFree (GetProcessHeap (), 0 , ExeNameBuf );
123
130
}
124
131
125
- static VOID ReadFromFile (LPTSTR param )
132
+ static VOID ReadFromFile (LPWSTR param )
126
133
{
127
134
FILE * fp ;
128
- TCHAR line [MAX_PATH ];
135
+ WCHAR line [MAX_PATH ];
129
136
130
- fp = _tfopen (param , _T ( "r" ) );
137
+ fp = _wfopen (param , L "r" );
131
138
if (!fp )
132
139
{
133
- #ifdef UNICODE
134
140
_wperror (param );
135
- #else
136
- perror (param );
137
- #endif
138
141
return ;
139
142
}
140
143
141
- while ( _fgetts (line , MAX_PATH , fp ) != NULL )
144
+ while ( fgetws (line , MAX_PATH , fp ) != NULL )
142
145
{
143
146
/* Remove newline character */
144
- TCHAR * end = & line [_tcslen (line ) - 1 ];
145
- if (* end == _T ( '\n' ) )
146
- * end = _T ( '\0' ) ;
147
+ WCHAR * end = & line [wcslen (line ) - 1 ];
148
+ if (* end == L '\n' )
149
+ * end = L '\0' ;
147
150
148
151
if (* line )
149
152
SetMacro (line );
@@ -154,99 +157,109 @@ static VOID ReadFromFile(LPTSTR param)
154
157
}
155
158
156
159
/* Get the start and end of the next command-line argument. */
157
- static BOOL GetArg (TCHAR * * pStart , TCHAR * * pEnd )
160
+ static BOOL GetArg (WCHAR * * pStart , WCHAR * * pEnd )
158
161
{
159
162
BOOL bInQuotes = FALSE;
160
- TCHAR * p = * pEnd ;
161
- p += _tcsspn (p , _T ( " \t" ) );
163
+ WCHAR * p = * pEnd ;
164
+ p += wcsspn (p , L " \t" );
162
165
if (!* p )
163
166
return FALSE;
164
167
* pStart = p ;
165
168
do
166
169
{
167
- if (!bInQuotes && (* p == _T ( ' ' ) || * p == _T ( '\t' ) ))
170
+ if (!bInQuotes && (* p == L ' ' || * p == L '\t' ))
168
171
break ;
169
- bInQuotes ^= (* p ++ == _T ( '"' ) );
172
+ bInQuotes ^= (* p ++ == L '"' );
170
173
} while (* p );
171
174
* pEnd = p ;
172
175
return TRUE;
173
176
}
174
177
175
178
/* Remove starting and ending quotes from a string, if present */
176
- static LPTSTR RemoveQuotes (LPTSTR str )
179
+ static LPWSTR RemoveQuotes (LPWSTR str )
177
180
{
178
- TCHAR * end ;
179
- if (* str == _T ( '"' ) && * (end = str + _tcslen (str ) - 1 ) == _T ( '"' ) )
181
+ WCHAR * end ;
182
+ if (* str == L '"' && * (end = str + wcslen (str ) - 1 ) == L '"' )
180
183
{
181
184
str ++ ;
182
- * end = _T ( '\0' ) ;
185
+ * end = L '\0' ;
183
186
}
184
187
return str ;
185
188
}
186
189
187
190
int
188
- _tmain (VOID )
191
+ wmain (VOID )
189
192
{
190
193
/* Get the full command line using GetCommandLine(). We can't just use argv,
191
194
* because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */
192
- TCHAR * pArgStart ;
193
- TCHAR * pArgEnd = GetCommandLine ();
195
+ WCHAR * pArgStart ;
196
+ WCHAR * pArgEnd = GetCommandLine ();
197
+ HMODULE hKernel32 = LoadLibraryW (L"kernel32.dll" );
198
+
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" );
204
+
205
+ assert (pGetConsoleCommandHistoryW && pGetConsoleCommandHistoryLengthW &&
206
+ pSetConsoleNumberOfCommandsW && pSetConsoleNumberOfCommandsW );
194
207
195
208
/* Skip the application name */
196
209
GetArg (& pArgStart , & pArgEnd );
197
210
198
211
while (GetArg (& pArgStart , & pArgEnd ))
199
212
{
200
213
/* NUL-terminate this argument to make processing easier */
201
- TCHAR tmp = * pArgEnd ;
202
- * pArgEnd = _T ( '\0' ) ;
214
+ WCHAR tmp = * pArgEnd ;
215
+ * pArgEnd = L '\0' ;
203
216
204
- if (!_tcscmp (pArgStart , _T ( "/?" ) ))
217
+ if (!wcscmp (pArgStart , L "/?" ))
205
218
{
206
219
LoadString (GetModuleHandle (NULL ), IDS_HELP , szStringBuf , MAX_STRING );
207
- _tprintf (szStringBuf );
220
+ wprintf (szStringBuf );
208
221
break ;
209
222
}
210
- else if (!_tcsnicmp (pArgStart , _T ( "/EXENAME=" ) , 9 ))
223
+ else if (!_wcsnicmp (pArgStart , L "/EXENAME=" , 9 ))
211
224
{
212
225
pszExeName = RemoveQuotes (pArgStart + 9 );
213
226
}
214
- else if (!_tcsicmp (pArgStart , _T ( "/H" ) ) ||
215
- !_tcsicmp (pArgStart , _T ( "/HISTORY" ) ))
227
+ else if (!wcsicmp (pArgStart , L "/H" ) ||
228
+ !wcsicmp (pArgStart , L "/HISTORY" ))
216
229
{
217
230
PrintHistory ();
218
231
}
219
- else if (!_tcsnicmp (pArgStart , _T ( "/LISTSIZE=" ) , 10 ))
232
+ else if (!_wcsnicmp (pArgStart , L "/LISTSIZE=" , 10 ))
220
233
{
221
- SetConsoleNumberOfCommands ( _ttoi (pArgStart + 10 ), pszExeName );
234
+ pSetConsoleNumberOfCommandsW ( _wtoi (pArgStart + 10 ), pszExeName );
222
235
}
223
- else if (!_tcsicmp (pArgStart , _T ( "/REINSTALL" ) ))
236
+ else if (!wcsicmp (pArgStart , L "/REINSTALL" ))
224
237
{
225
- ExpungeConsoleCommandHistory (pszExeName );
238
+ pExpungeConsoleCommandHistoryW (pszExeName );
226
239
}
227
- else if (!_tcsicmp (pArgStart , _T ( "/INSERT" ) ))
240
+ else if (!wcsicmp (pArgStart , L "/INSERT" ))
228
241
{
229
242
SetInsert (ENABLE_INSERT_MODE );
230
243
}
231
- else if (!_tcsicmp (pArgStart , _T ( "/OVERSTRIKE" ) ))
244
+ else if (!wcsicmp (pArgStart , L "/OVERSTRIKE" ))
232
245
{
233
246
SetInsert (0 );
234
247
}
235
- else if (!_tcsicmp (pArgStart , _T ( "/M" ) ) ||
236
- !_tcsicmp (pArgStart , _T ( "/MACROS" ) ))
248
+ else if (!wcsicmp (pArgStart , L "/M" ) ||
249
+ !wcsicmp (pArgStart , L "/MACROS" ))
237
250
{
238
- PrintMacros (pszExeName , _T ( "" ) );
251
+ PrintMacros (pszExeName , L"" );
239
252
}
240
- else if (!_tcsnicmp (pArgStart , _T ( "/M:" ) , 3 ) ||
241
- !_tcsnicmp (pArgStart , _T ( "/MACROS:" ) , 8 ))
253
+ else if (!_wcsnicmp (pArgStart , L "/M:" , 3 ) ||
254
+ !_wcsnicmp (pArgStart , L "/MACROS:" , 8 ))
242
255
{
243
- LPTSTR exe = RemoveQuotes (_tcschr (pArgStart , _T ( ':' ) ) + 1 );
244
- if (!_tcsicmp (exe , _T ( "ALL" ) ))
256
+ LPWSTR exe = RemoveQuotes (wcschr (pArgStart , L ':' ) + 1 );
257
+ if (!wcsicmp (exe , L "ALL" ))
245
258
PrintAllMacros ();
246
259
else
247
- PrintMacros (exe , _T ( "" ) );
260
+ PrintMacros (exe , L"" );
248
261
}
249
- else if (!_tcsnicmp (pArgStart , _T ( "/MACROFILE=" ) , 11 ))
262
+ else if (!_wcsnicmp (pArgStart , L "/MACROFILE=" , 11 ))
250
263
{
251
264
ReadFromFile (RemoveQuotes (pArgStart + 11 ));
252
265
}
0 commit comments