-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathInput.cpp
107 lines (92 loc) · 3.57 KB
/
Input.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <Windows.h>
#include <tchar.h>
#include <memory>
#include "arg.inl"
#define ARRAY_X(a) (a), ARRAYSIZE(a)
template <class T>
auto CreateUnique(HANDLE h, T* f)
{
return std::unique_ptr<std::remove_pointer<HANDLE>::type, T*>(h, f);
}
auto CreateUnique(HANDLE h)
{
return CreateUnique(h, CloseHandle);
}
template <size_t size>
void StrCopyIf(TCHAR (&dest)[size], const TCHAR *src)
{
if (src != nullptr)
_tcscpy_s(dest, src);
}
BOOL WriteFileANSI(HANDLE hFile, _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr, int cchWideChar = -1)
{
CHAR szAnsiCharStr[1024];
int bytes = WideCharToMultiByte(CP_ACP, 0, lpWideCharStr, cchWideChar, szAnsiCharStr, ARRAYSIZE(szAnsiCharStr), nullptr, nullptr);
DWORD dwWritten;
return WriteFile(hFile, szAnsiCharStr, bytes, &dwWritten, NULL);
}
BOOL PrintConsole(const HANDLE hOutput, const WCHAR* const format, ...)
{
WCHAR buffer[1024];
va_list args;
va_start(args, format);
_vsnwprintf_s(ARRAY_X(buffer), format, args);
va_end(args);
return WriteConsole(hOutput, buffer, DWORD(wcslen(buffer)), nullptr, nullptr);
}
BOOL PrintConsole(const HANDLE hOutput, const CHAR* const format, ...)
{
CHAR buffer[1024];
va_list args;
va_start(args, format);
_vsnprintf_s(ARRAY_X(buffer), format, args);
va_end(args);
return WriteConsole(hOutput, buffer, DWORD(strlen(buffer)), nullptr, nullptr);
}
BOOL PrintANSI(const HANDLE hOutput, const TCHAR* const format, ...)
{
TCHAR buffer[1024];
va_list args;
va_start(args, format);
_vsntprintf_s(ARRAY_X(buffer), format, args);
va_end(args);
return WriteFileANSI(hOutput, buffer, -1);
}
#define CHECK(t, msg) \
if (!(t)) \
{ \
DWORD e = GetLastError(); \
PrintANSI(GetStdHandle(STD_ERROR_HANDLE), _T("ERROR:\t%s (error %d)\n"), (msg), e); \
return e; \
};
int _tmain(int argc, const TCHAR* const argv[])
{
//const HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
const HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
TCHAR Buffer[1024] = _T("");
arginit(argc, argv);
const TCHAR* prompt = argnumdesc(1, _T("? "), _T("prompt"), nullptr);
// TODO Expand prompt with cmd-like prompt extensions
StrCopyIf(Buffer, argvaluedesc(_T("/Default"), nullptr, _T("initial_value"), nullptr));
// TODO Get default value from hInput
if (!argcleanup())
return EXIT_FAILURE;
if (argusage())
return EXIT_SUCCESS;
auto hConsoleInput = CreateUnique(CreateFile(_T("CONIN$"), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0));
CHECK(hConsoleInput != NULL, _T("CreateFile CONIN$\n"))
auto hConsoleOutput = CreateUnique(CreateFile(_T("CONOUT$"), GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0));
CHECK(hConsoleOutput != NULL, _T("CreateFile CONOUT$\n"))
DWORD Read = 0;
DWORD Written = 0;
CONSOLE_READCONSOLE_CONTROL control = { sizeof(CONSOLE_READCONSOLE_CONTROL) };
control.nInitialChars = ULONG(_tcslen(Buffer)); // Only works in UNICODE mode
if (prompt)
CHECK(WriteConsole(hConsoleOutput.get(), prompt, DWORD(_tcslen(prompt)), &Written, nullptr), _T("WriteConsole prompt"));
CHECK(WriteConsole(hConsoleOutput.get(), Buffer, control.nInitialChars, &Written, nullptr), _T("WriteConsole Buffer"));
CHECK(ReadConsole(hConsoleInput.get(), ARRAY_X(Buffer), &Read, &control), _T("ReadConsole Buffer"));
Buffer[Read] = _T('\0');
//CHECK(WriteConsole(hOutput, Buffer, Read, &Written, nullptr), _T("WriteConsole Buffer"));
CHECK(WriteFileANSI(hOutput, Buffer, Read), _T("WriteFileANSI Buffer"));
return EXIT_SUCCESS;
}