Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

doskey.c

Go 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 doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.