Our kernel32.lib already exports all of the console API and in particular the console history API, so we can directly link doskey against it and use them, instead of delay-loading at runtime. We just need to add their prototypes in the source code since they are not declared by wincon.h by default.

svn path=/trunk/; revision=72504
This commit is contained in:
Hermès Bélusca-Maïto 2016-08-29 15:39:19 +00:00
parent 1dd7857278
commit 499b414a4b

View file

@ -1,12 +1,31 @@
#include <stdarg.h> #include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <windef.h> #include <windef.h>
#include <winbase.h> #include <winbase.h>
#include <winuser.h> #include <winuser.h>
#include <wincon.h> #include <wincon.h>
#include <stdio.h>
#include <wchar.h> /* Console API functions which are absent from wincon.h */
#include <assert.h> VOID
#include <locale.h> WINAPI
ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName);
DWORD
WINAPI
GetConsoleCommandHistoryW(LPWSTR lpHistory,
DWORD cbHistory,
LPCWSTR lpExeName);
DWORD
WINAPI
GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName);
BOOL
WINAPI
SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
LPCWSTR lpExeName);
#include "doskey.h" #include "doskey.h"
@ -14,19 +33,12 @@
WCHAR szStringBuf[MAX_STRING]; WCHAR szStringBuf[MAX_STRING];
LPWSTR pszExeName = L"cmd.exe"; LPWSTR pszExeName = L"cmd.exe";
/* Function pointers */
typedef DWORD (WINAPI *GetConsoleCommandHistoryW_t) (LPWSTR sCommands, DWORD nBufferLength, LPWSTR sExeName);
typedef DWORD (WINAPI *GetConsoleCommandHistoryLengthW_t) (LPWSTR sExeName);
typedef BOOL (WINAPI *SetConsoleNumberOfCommandsW_t)(DWORD nNumber, LPWSTR sExeName);
typedef VOID (WINAPI *ExpungeConsoleCommandHistoryW_t)(LPWSTR sExeName);
GetConsoleCommandHistoryW_t pGetConsoleCommandHistoryW;
GetConsoleCommandHistoryLengthW_t pGetConsoleCommandHistoryLengthW;
SetConsoleNumberOfCommandsW_t pSetConsoleNumberOfCommandsW;
ExpungeConsoleCommandHistoryW_t pExpungeConsoleCommandHistoryW;
static VOID SetInsert(DWORD dwFlag) static VOID SetInsert(DWORD dwFlag)
{ {
/*
* NOTE: Enabling the ENABLE_INSERT_MODE mode can also be done by calling
* kernel32:SetConsoleCommandHistoryMode(CONSOLE_OVERSTRIKE) .
*/
DWORD dwMode; DWORD dwMode;
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hConsole, &dwMode); GetConsoleMode(hConsole, &dwMode);
@ -36,7 +48,7 @@ static VOID SetInsert(DWORD dwFlag)
static VOID PrintHistory(VOID) static VOID PrintHistory(VOID)
{ {
DWORD Length = pGetConsoleCommandHistoryLengthW(pszExeName); DWORD Length = GetConsoleCommandHistoryLengthW(pszExeName);
PBYTE HistBuf; PBYTE HistBuf;
WCHAR *Hist; WCHAR *Hist;
WCHAR *HistEnd; WCHAR *HistEnd;
@ -48,9 +60,13 @@ static VOID PrintHistory(VOID)
Hist = (WCHAR *)HistBuf; Hist = (WCHAR *)HistBuf;
HistEnd = (WCHAR *)&HistBuf[Length]; HistEnd = (WCHAR *)&HistBuf[Length];
if (pGetConsoleCommandHistoryW(Hist, Length, pszExeName)) if (GetConsoleCommandHistoryW(Hist, Length, pszExeName))
{
for (; Hist < HistEnd; Hist += wcslen(Hist) + 1) for (; Hist < HistEnd; Hist += wcslen(Hist) + 1)
{
wprintf(L"%s\n", Hist); wprintf(L"%s\n", Hist);
}
}
HeapFree(GetProcessHeap(), 0, HistBuf); HeapFree(GetProcessHeap(), 0, HistBuf);
} }
@ -102,8 +118,12 @@ static VOID PrintMacros(LPWSTR pszExeName, LPWSTR Indent)
AliasEnd = (WCHAR *)&AliasBuf[Length]; AliasEnd = (WCHAR *)&AliasBuf[Length];
if (GetConsoleAliasesW(Alias, Length * sizeof(BYTE), pszExeName)) if (GetConsoleAliasesW(Alias, Length * sizeof(BYTE), pszExeName))
{
for (; Alias < AliasEnd; Alias += wcslen(Alias) + 1) for (; Alias < AliasEnd; Alias += wcslen(Alias) + 1)
{
wprintf(L"%s%s\n", Indent, Alias); wprintf(L"%s%s\n", Indent, Alias);
}
}
HeapFree(GetProcessHeap(), 0, AliasBuf); HeapFree(GetProcessHeap(), 0, AliasBuf);
} }
@ -198,23 +218,12 @@ wmain(VOID)
{ {
WCHAR *pArgStart; WCHAR *pArgStart;
WCHAR *pArgEnd; WCHAR *pArgEnd;
HMODULE hKernel32;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
/* Get the full command line using GetCommandLine(). We can't just use argv, /* Get the full command line using GetCommandLine(). We can't just use argv,
* because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */ * because then a parameter like "gotoroot=cd \" wouldn't be passed completely. */
pArgEnd = GetCommandLineW(); pArgEnd = GetCommandLineW();
hKernel32 = LoadLibraryW(L"kernel32.dll");
/* Get function pointers */
pGetConsoleCommandHistoryW = (GetConsoleCommandHistoryW_t)GetProcAddress( hKernel32, "GetConsoleCommandHistoryW");
pGetConsoleCommandHistoryLengthW = (GetConsoleCommandHistoryLengthW_t)GetProcAddress( hKernel32, "GetConsoleCommandHistoryLengthW");
pSetConsoleNumberOfCommandsW = (SetConsoleNumberOfCommandsW_t)GetProcAddress( hKernel32, "SetConsoleNumberOfCommandsW");
pExpungeConsoleCommandHistoryW = (ExpungeConsoleCommandHistoryW_t)GetProcAddress( hKernel32, "ExpungeConsoleCommandHistoryW");
assert(pGetConsoleCommandHistoryW && pGetConsoleCommandHistoryLengthW &&
pSetConsoleNumberOfCommandsW && pExpungeConsoleCommandHistoryW);
/* Skip the application name */ /* Skip the application name */
GetArg(&pArgStart, &pArgEnd); GetArg(&pArgStart, &pArgEnd);
@ -242,11 +251,11 @@ wmain(VOID)
} }
else if (!_wcsnicmp(pArgStart, L"/LISTSIZE=", 10)) else if (!_wcsnicmp(pArgStart, L"/LISTSIZE=", 10))
{ {
pSetConsoleNumberOfCommandsW(_wtoi(pArgStart + 10), pszExeName); SetConsoleNumberOfCommandsW(_wtoi(pArgStart + 10), pszExeName);
} }
else if (!wcsicmp(pArgStart, L"/REINSTALL")) else if (!wcsicmp(pArgStart, L"/REINSTALL"))
{ {
pExpungeConsoleCommandHistoryW(pszExeName); ExpungeConsoleCommandHistoryW(pszExeName);
} }
else if (!wcsicmp(pArgStart, L"/INSERT")) else if (!wcsicmp(pArgStart, L"/INSERT"))
{ {