Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendoskey.cGo to the documentation of this file.00001 #include <windows.h> 00002 #include <stdio.h> 00003 #include <wchar.h> 00004 #include <assert.h> 00005 #include <locale.h> 00006 #include "doskey.h" 00007 00008 #define MAX_STRING 2000 00009 WCHAR szStringBuf[MAX_STRING]; 00010 LPWSTR pszExeName = L"cmd.exe"; 00011 00012 /* Function pointers */ 00013 typedef DWORD (WINAPI *GetConsoleCommandHistoryW_t) (LPWSTR sCommands, DWORD nBufferLength, LPWSTR sExeName); 00014 typedef DWORD (WINAPI *GetConsoleCommandHistoryLengthW_t) (LPWSTR sExeName); 00015 typedef BOOL (WINAPI *SetConsoleNumberOfCommandsW_t)(DWORD nNumber, LPWSTR sExeName); 00016 typedef VOID (WINAPI *ExpungeConsoleCommandHistoryW_t)(LPWSTR sExeName); 00017 00018 GetConsoleCommandHistoryW_t pGetConsoleCommandHistoryW; 00019 GetConsoleCommandHistoryLengthW_t pGetConsoleCommandHistoryLengthW; 00020 SetConsoleNumberOfCommandsW_t pSetConsoleNumberOfCommandsW; 00021 ExpungeConsoleCommandHistoryW_t pExpungeConsoleCommandHistoryW; 00022 00023 static VOID SetInsert(DWORD dwFlag) 00024 { 00025 DWORD dwMode; 00026 HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); 00027 GetConsoleMode(hConsole, &dwMode); 00028 dwMode |= ENABLE_EXTENDED_FLAGS; 00029 SetConsoleMode(hConsole, (dwMode & ~ENABLE_INSERT_MODE) | dwFlag); 00030 } 00031 00032 static VOID PrintHistory(VOID) 00033 { 00034 DWORD Length = pGetConsoleCommandHistoryLengthW(pszExeName); 00035 PBYTE HistBuf; 00036 WCHAR *Hist; 00037 WCHAR *HistEnd; 00038 00039 HistBuf = HeapAlloc(GetProcessHeap(), 00040 HEAP_ZERO_MEMORY, 00041 Length); 00042 if (!HistBuf) return; 00043 Hist = (WCHAR *)HistBuf; 00044 HistEnd = (WCHAR *)&HistBuf[Length]; 00045 00046 if (pGetConsoleCommandHistoryW(Hist, Length, pszExeName)) 00047 for (; Hist < HistEnd; Hist += wcslen(Hist) + 1) 00048 wprintf(L"%s\n", Hist); 00049 00050 HeapFree(GetProcessHeap(), 0, HistBuf); 00051 } 00052 00053 static INT SetMacro(LPWSTR definition) 00054 { 00055 WCHAR *name, *nameend, *text, temp; 00056 00057 name = definition; 00058 while (*name == L' ') 00059 name++; 00060 00061 /* error if no '=' found */ 00062 if ((nameend = wcschr(name, L'=')) != NULL) 00063 { 00064 text = nameend + 1; 00065 while (*text == L' ') 00066 text++; 00067 00068 while (nameend > name && nameend[-1] == L' ') 00069 nameend--; 00070 00071 /* Split rest into name and substitute */ 00072 temp = *nameend; 00073 *nameend = L'\0'; 00074 /* Don't allow spaces in the name, since such a macro would be unusable */ 00075 if (!wcschr(name, L' ') && AddConsoleAlias(name, text, pszExeName)) 00076 return 0; 00077 *nameend = temp; 00078 } 00079 00080 LoadString(GetModuleHandle(NULL), IDS_INVALID_MACRO_DEF, szStringBuf, MAX_STRING); 00081 wprintf(szStringBuf, definition); 00082 return 1; 00083 } 00084 00085 static VOID PrintMacros(LPWSTR pszExeName, LPWSTR Indent) 00086 { 00087 DWORD Length = GetConsoleAliasesLength(pszExeName); 00088 PBYTE AliasBuf; 00089 WCHAR *Alias; 00090 WCHAR *AliasEnd; 00091 00092 AliasBuf = HeapAlloc(GetProcessHeap(), 00093 HEAP_ZERO_MEMORY, 00094 Length * sizeof(BYTE)); 00095 if (!AliasBuf) return; 00096 Alias = (WCHAR *)AliasBuf; 00097 AliasEnd = (WCHAR *)&AliasBuf[Length]; 00098 00099 if (GetConsoleAliases(Alias, Length * sizeof(BYTE), pszExeName)) 00100 for (; Alias < AliasEnd; Alias += wcslen(Alias) + 1) 00101 wprintf(L"%s%s\n", Indent, Alias); 00102 00103 HeapFree(GetProcessHeap(), 0, AliasBuf); 00104 } 00105 00106 static VOID PrintAllMacros(VOID) 00107 { 00108 DWORD Length = GetConsoleAliasExesLength(); 00109 PBYTE ExeNameBuf; 00110 WCHAR *ExeName; 00111 WCHAR *ExeNameEnd; 00112 00113 ExeNameBuf = HeapAlloc(GetProcessHeap(), 00114 HEAP_ZERO_MEMORY, 00115 Length * sizeof(BYTE)); 00116 if (!ExeNameBuf) return; 00117 ExeName = (WCHAR *)ExeNameBuf; 00118 ExeNameEnd = (WCHAR *)&ExeNameBuf[Length]; 00119 00120 if (GetConsoleAliasExes(ExeName, Length * sizeof(BYTE))) 00121 { 00122 for (; ExeName < ExeNameEnd; ExeName += wcslen(ExeName) + 1) 00123 { 00124 wprintf(L"[%s]\n", ExeName); 00125 PrintMacros(ExeName, L" "); 00126 wprintf(L"\n"); 00127 } 00128 } 00129 00130 HeapFree(GetProcessHeap(), 0, ExeNameBuf); 00131 } 00132 00133 static VOID ReadFromFile(LPWSTR param) 00134 { 00135 FILE* fp; 00136 WCHAR line[MAX_PATH]; 00137 00138 fp = _wfopen(param, L"r"); 00139 if (!fp) 00140 { 00141 _wperror(param); 00142 return; 00143 } 00144 00145 while ( fgetws(line, MAX_PATH, fp) != NULL) 00146 { 00147 /* Remove newline character */ 00148 WCHAR *end = &line[wcslen(line) - 1]; 00149 if (*end == L'\n') 00150 *end = L'\0'; 00151 00152 if (*line) 00153 SetMacro(line); 00154 } 00155 00156 fclose(fp); 00157 return; 00158 } 00159 00160 /* Get the start and end of the next command-line argument. */ 00161 static BOOL GetArg(WCHAR **pStart, WCHAR **pEnd) 00162 { 00163 BOOL bInQuotes = FALSE; 00164 WCHAR *p = *pEnd; 00165 p += wcsspn(p, L" \t"); 00166 if (!*p) 00167 return FALSE; 00168 *pStart = p; 00169 do 00170 { 00171 if (!bInQuotes && (*p == L' ' || *p == L'\t')) 00172 break; 00173 bInQuotes ^= (*p++ == L'"'); 00174 } while (*p); 00175 *pEnd = p; 00176 return TRUE; 00177 } 00178 00179 /* Remove starting and ending quotes from a string, if present */ 00180 static LPWSTR RemoveQuotes(LPWSTR str) 00181 { 00182 WCHAR *end; 00183 if (*str == L'"' && *(end = str + wcslen(str) - 1) == L'"') 00184 { 00185 str++; 00186 *end = L'\0'; 00187 } 00188 return str; 00189 } 00190 00191 int 00192 wmain(VOID) 00193 { 00194 WCHAR *pArgStart; 00195 WCHAR *pArgEnd; 00196 HMODULE hKernel32; 00197 00198 setlocale(LC_ALL, ""); 00199 00200 /* Get the full command line using GetCommandLine(). We can't just use argv, 00201 * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */ 00202 pArgEnd = GetCommandLine(); 00203 hKernel32 = LoadLibraryW(L"kernel32.dll"); 00204 00205 /* Get function pointers */ 00206 pGetConsoleCommandHistoryW = (GetConsoleCommandHistoryW_t)GetProcAddress( hKernel32, "GetConsoleCommandHistoryW"); 00207 pGetConsoleCommandHistoryLengthW = (GetConsoleCommandHistoryLengthW_t)GetProcAddress( hKernel32, "GetConsoleCommandHistoryLengthW"); 00208 pSetConsoleNumberOfCommandsW = (SetConsoleNumberOfCommandsW_t)GetProcAddress( hKernel32, "SetConsoleNumberOfCommandsW"); 00209 pExpungeConsoleCommandHistoryW = (ExpungeConsoleCommandHistoryW_t)GetProcAddress( hKernel32, "ExpungeConsoleCommandHistoryW"); 00210 00211 assert(pGetConsoleCommandHistoryW && pGetConsoleCommandHistoryLengthW && 00212 pSetConsoleNumberOfCommandsW && pExpungeConsoleCommandHistoryW); 00213 00214 /* Skip the application name */ 00215 GetArg(&pArgStart, &pArgEnd); 00216 00217 while (GetArg(&pArgStart, &pArgEnd)) 00218 { 00219 /* NUL-terminate this argument to make processing easier */ 00220 WCHAR tmp = *pArgEnd; 00221 *pArgEnd = L'\0'; 00222 00223 if (!wcscmp(pArgStart, L"/?")) 00224 { 00225 LoadString(GetModuleHandle(NULL), IDS_HELP, szStringBuf, MAX_STRING); 00226 wprintf(szStringBuf); 00227 break; 00228 } 00229 else if (!_wcsnicmp(pArgStart, L"/EXENAME=", 9)) 00230 { 00231 pszExeName = RemoveQuotes(pArgStart + 9); 00232 } 00233 else if (!wcsicmp(pArgStart, L"/H") || 00234 !wcsicmp(pArgStart, L"/HISTORY")) 00235 { 00236 PrintHistory(); 00237 } 00238 else if (!_wcsnicmp(pArgStart, L"/LISTSIZE=", 10)) 00239 { 00240 pSetConsoleNumberOfCommandsW(_wtoi(pArgStart + 10), pszExeName); 00241 } 00242 else if (!wcsicmp(pArgStart, L"/REINSTALL")) 00243 { 00244 pExpungeConsoleCommandHistoryW(pszExeName); 00245 } 00246 else if (!wcsicmp(pArgStart, L"/INSERT")) 00247 { 00248 SetInsert(ENABLE_INSERT_MODE); 00249 } 00250 else if (!wcsicmp(pArgStart, L"/OVERSTRIKE")) 00251 { 00252 SetInsert(0); 00253 } 00254 else if (!wcsicmp(pArgStart, L"/M") || 00255 !wcsicmp(pArgStart, L"/MACROS")) 00256 { 00257 PrintMacros(pszExeName, L""); 00258 } 00259 else if (!_wcsnicmp(pArgStart, L"/M:", 3) || 00260 !_wcsnicmp(pArgStart, L"/MACROS:", 8)) 00261 { 00262 LPWSTR exe = RemoveQuotes(wcschr(pArgStart, L':') + 1); 00263 if (!wcsicmp(exe, L"ALL")) 00264 PrintAllMacros(); 00265 else 00266 PrintMacros(exe, L""); 00267 } 00268 else if (!_wcsnicmp(pArgStart, L"/MACROFILE=", 11)) 00269 { 00270 ReadFromFile(RemoveQuotes(pArgStart + 11)); 00271 } 00272 else 00273 { 00274 /* This is the beginning of a macro definition. It includes 00275 * the entire remainder of the line, so first put back the 00276 * character that we replaced with NUL. */ 00277 *pArgEnd = tmp; 00278 return SetMacro(pArgStart); 00279 } 00280 00281 if (!tmp) break; 00282 pArgEnd++; 00283 } 00284 00285 return 0; 00286 } Generated on Thu Feb 9 04:39:00 2012 for ReactOS by
1.6.3
|