1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2016 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // A permission to use the source code is granted as long as reference to |
---|
6 | // source website http://alax.info is retained. |
---|
7 | |
---|
8 | #include "stdafx.h" |
---|
9 | |
---|
10 | //////////////////////////////////////////////////////////// |
---|
11 | // CModule |
---|
12 | |
---|
13 | class CModule : |
---|
14 | public CAtlExeModuleT<CModule> |
---|
15 | { |
---|
16 | public: |
---|
17 | |
---|
18 | //////////////////////////////////////////////////////// |
---|
19 | // CCommandLineArguments |
---|
20 | |
---|
21 | class CCommandLineArguments |
---|
22 | { |
---|
23 | public: |
---|
24 | |
---|
25 | ////////////////////////////////////////////////////////// |
---|
26 | // CArgument |
---|
27 | |
---|
28 | class CArgument |
---|
29 | { |
---|
30 | public: |
---|
31 | BOOL m_bSwitch; |
---|
32 | CString m_sSwitchName; |
---|
33 | CString m_sSwitchValue; |
---|
34 | BOOL m_bIntegerSwitchValueAvailable; |
---|
35 | INT m_nIntegerSwitchValue; |
---|
36 | CString m_sValue; |
---|
37 | |
---|
38 | public: |
---|
39 | // CArgument |
---|
40 | CArgument() : |
---|
41 | m_bSwitch(FALSE), |
---|
42 | m_bIntegerSwitchValueAvailable(FALSE) |
---|
43 | { |
---|
44 | } |
---|
45 | VOID Initialize() |
---|
46 | { |
---|
47 | m_bSwitch = FALSE; |
---|
48 | m_sSwitchName.Empty();; |
---|
49 | m_sSwitchValue.Empty();; |
---|
50 | m_bIntegerSwitchValueAvailable = FALSE; |
---|
51 | m_sValue.Empty(); |
---|
52 | } |
---|
53 | }; |
---|
54 | |
---|
55 | private: |
---|
56 | SIZE_T m_argc; |
---|
57 | TCHAR** m_argv; |
---|
58 | SIZE_T m_nIndex; |
---|
59 | |
---|
60 | public: |
---|
61 | // CCommandLineArguments |
---|
62 | CCommandLineArguments(SIZE_T argc, TCHAR* argv[]) : |
---|
63 | m_argc(argc), |
---|
64 | m_argv(argv), |
---|
65 | m_nIndex(1) |
---|
66 | { |
---|
67 | } |
---|
68 | CCommandLineArguments(LPCWSTR pszCommandLine) |
---|
69 | { |
---|
70 | INT nArgumentCount = 0; |
---|
71 | LPWSTR* pszArguments = CommandLineToArgvW(pszCommandLine, &nArgumentCount); |
---|
72 | m_argc = nArgumentCount; |
---|
73 | m_argv = pszArguments; |
---|
74 | m_nIndex = 1; |
---|
75 | } |
---|
76 | BOOL CanNext() const |
---|
77 | { |
---|
78 | if(m_nIndex >= m_argc) |
---|
79 | return FALSE; |
---|
80 | return TRUE; |
---|
81 | } |
---|
82 | BOOL Next(CArgument& Argument) |
---|
83 | { |
---|
84 | if(m_nIndex >= m_argc) |
---|
85 | return FALSE; |
---|
86 | CString sArgument = m_argv[m_nIndex++]; |
---|
87 | _A(!sArgument.IsEmpty()); |
---|
88 | Argument.Initialize(); |
---|
89 | if(_tcschr(_T("-/"), sArgument[0])) |
---|
90 | { |
---|
91 | Argument.m_bSwitch = TRUE; |
---|
92 | sArgument.Delete(0); |
---|
93 | const INT nSeparatorPosition = sArgument.Find(_T(':')); |
---|
94 | if(nSeparatorPosition > 0) |
---|
95 | { |
---|
96 | Argument.m_sSwitchName = sArgument.Left(nSeparatorPosition); |
---|
97 | Argument.m_sSwitchValue = sArgument.Mid(nSeparatorPosition + 1); |
---|
98 | if(!Argument.m_sSwitchValue.IsEmpty()) |
---|
99 | Argument.m_bIntegerSwitchValueAvailable = AtlStringToInteger(Argument.m_sSwitchValue, Argument.m_nIntegerSwitchValue); |
---|
100 | } else |
---|
101 | Argument.m_sSwitchName = sArgument; |
---|
102 | return TRUE; |
---|
103 | } |
---|
104 | if(sArgument.GetLength() >= 2 && sArgument[0] == _T('"') && sArgument[sArgument.GetLength() - 1] == _T('"')) |
---|
105 | sArgument = sArgument.Mid(1, sArgument.GetLength() - 2); |
---|
106 | Argument.m_sValue = sArgument; |
---|
107 | return TRUE; |
---|
108 | } |
---|
109 | }; |
---|
110 | |
---|
111 | private: |
---|
112 | UINT m_nPrintCount; |
---|
113 | |
---|
114 | public: |
---|
115 | // CModule |
---|
116 | CModule() |
---|
117 | { |
---|
118 | m_nPrintCount = 0; |
---|
119 | } |
---|
120 | static VOID Syntax() |
---|
121 | { |
---|
122 | _tprintf( |
---|
123 | _T("Syntax: PrintTime [commands]") _T("\n") |
---|
124 | _T("\n") |
---|
125 | _T("Commands:") _T("\n") |
---|
126 | _T("\t") _T("help - command line syntax help") _T("\n") |
---|
127 | _T("\t") _T("now - print current time") _T("\n") |
---|
128 | _T("\t") _T("filetime <N> - print FILETIME time N (100 ms units)") _T("\n") |
---|
129 | _T("\t") _T("ole <F> - print DATE time F (day units)") _T("\n") |
---|
130 | ); |
---|
131 | } |
---|
132 | static VOID PrintFileTime(ULONGLONG nValue, LPCTSTR pszPrefix = _T("")) |
---|
133 | { |
---|
134 | CString sPrefix = pszPrefix; |
---|
135 | if(!sPrefix.IsEmpty()) |
---|
136 | sPrefix.AppendChar(_T(' ')); |
---|
137 | { |
---|
138 | CString sValue = AtlFormatString(_T("%I64u"), nValue); |
---|
139 | if(sValue.GetLength() > 7) |
---|
140 | sValue.Insert(sValue.GetLength() - 7, _T(' ')); |
---|
141 | if(sValue.GetLength() > 4) |
---|
142 | sValue.Insert(sValue.GetLength() - 4, _T(' ')); |
---|
143 | _tprintf(_T("%s") _T("FILETIME: %s (%I64d)\n"), sPrefix, sValue, nValue); |
---|
144 | } |
---|
145 | SYSTEMTIME SystemTime; |
---|
146 | if(FileTimeToSystemTime(&reinterpret_cast<const FILETIME&>(nValue), &SystemTime)) |
---|
147 | { |
---|
148 | _tprintf(_T("%s") _T("SYSTEMTIME: %04d-%02d-%02d %02d:%02d:%02d.%03d (%d)\n"), sPrefix, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, SystemTime.wDayOfWeek); |
---|
149 | DATE fTime; |
---|
150 | if(SystemTimeToVariantTime(&SystemTime, &fTime)) |
---|
151 | _tprintf(_T("%s") _T("DATE: %.10f\n"), sPrefix, fTime); |
---|
152 | } |
---|
153 | } |
---|
154 | VOID Print(ULONGLONG nValue) |
---|
155 | { |
---|
156 | PrintFileTime(nValue); |
---|
157 | ULONGLONG nLocalValue; |
---|
158 | FileTimeToLocalFileTime(&reinterpret_cast<const FILETIME&>(nValue), &reinterpret_cast<FILETIME&>(nLocalValue)); |
---|
159 | PrintFileTime(nLocalValue, _T("Local")); |
---|
160 | _tprintf(_T("\n")); |
---|
161 | m_nPrintCount++; |
---|
162 | } |
---|
163 | bool ParseCommandLine(LPCTSTR pszCommandLine, HRESULT* pnResult) |
---|
164 | { |
---|
165 | //if(!__super::ParseCommandLine(pszCommandLine, pnResult)) |
---|
166 | // return false; |
---|
167 | _ATLTRY |
---|
168 | { |
---|
169 | CCommandLineArguments Arguments(pszCommandLine); |
---|
170 | if(!Arguments.CanNext()) |
---|
171 | { |
---|
172 | Syntax(); |
---|
173 | return false; |
---|
174 | } |
---|
175 | for(; ; ) |
---|
176 | { |
---|
177 | CCommandLineArguments::CArgument Argument; |
---|
178 | if(!Arguments.Next(Argument)) |
---|
179 | break; |
---|
180 | __D(!Argument.m_bSwitch, E_INVALIDARG); |
---|
181 | if(Argument.m_sValue.CompareNoCase(_T("help")) == 0) |
---|
182 | { |
---|
183 | Syntax(); |
---|
184 | return false; |
---|
185 | } //else |
---|
186 | if(Argument.m_sValue.CompareNoCase(_T("now")) == 0) |
---|
187 | { |
---|
188 | FILETIME FileTime; |
---|
189 | GetSystemTimeAsFileTime(&FileTime); |
---|
190 | _tprintf(_T("Now:\n\n")); |
---|
191 | Print(reinterpret_cast<const ULONGLONG&>(FileTime)); |
---|
192 | } else |
---|
193 | if(Argument.m_sValue.CompareNoCase(_T("filetime")) == 0 || Argument.m_sValue.CompareNoCase(_T("ft")) == 0) |
---|
194 | { |
---|
195 | CCommandLineArguments::CArgument ValueArgument; |
---|
196 | __D(Arguments.Next(ValueArgument), E_INVALIDARG); |
---|
197 | __D(!ValueArgument.m_bSwitch, E_INVALIDARG); |
---|
198 | LONGLONG nValue; |
---|
199 | __D(AtlStringToInteger(ValueArgument.m_sValue, nValue), E_UNNAMED); |
---|
200 | Print((ULONGLONG) nValue); |
---|
201 | } else |
---|
202 | if(Argument.m_sValue.CompareNoCase(_T("ole")) == 0) |
---|
203 | { |
---|
204 | CCommandLineArguments::CArgument ValueArgument; |
---|
205 | __D(Arguments.Next(ValueArgument), E_INVALIDARG); |
---|
206 | __D(!ValueArgument.m_bSwitch, E_INVALIDARG); |
---|
207 | DOUBLE fValue; |
---|
208 | __D(AtlStringToDouble(ValueArgument.m_sValue, fValue), E_UNNAMED); |
---|
209 | SYSTEMTIME SystemTime; |
---|
210 | __D(VariantTimeToSystemTime(fValue, &SystemTime), E_UNNAMED); |
---|
211 | FILETIME FileTime; |
---|
212 | __D(SystemTimeToFileTime(&SystemTime, &FileTime), E_UNNAMED); |
---|
213 | Print(reinterpret_cast<const ULONGLONG&>(FileTime)); |
---|
214 | } else |
---|
215 | { |
---|
216 | #if !defined(_DEBUG) |
---|
217 | __C(E_INVALIDARG); |
---|
218 | #endif // !defined(_DEBUG) |
---|
219 | } |
---|
220 | } |
---|
221 | } |
---|
222 | _ATLCATCHALL() |
---|
223 | { |
---|
224 | _Z_EXCEPTION(); |
---|
225 | _tprintf(_T("Fatal Error: Failed to parse command line arguments\n")); |
---|
226 | _tprintf(_T("\n")); |
---|
227 | Syntax(); |
---|
228 | return false; |
---|
229 | } |
---|
230 | if(!m_nPrintCount) |
---|
231 | { |
---|
232 | Syntax(); |
---|
233 | return false; |
---|
234 | } |
---|
235 | return true; |
---|
236 | } |
---|
237 | HRESULT PreMessageLoop(int nShowCommand) |
---|
238 | { |
---|
239 | // NOTE: Suppress S_FALSE |
---|
240 | _C(__super::PreMessageLoop(nShowCommand)); |
---|
241 | return S_OK; |
---|
242 | } |
---|
243 | VOID RunMessageLoop() |
---|
244 | { |
---|
245 | } |
---|
246 | }; |
---|
247 | |
---|
248 | int _tmain(int argc, _TCHAR* argv[]) |
---|
249 | { |
---|
250 | _ATLTRY |
---|
251 | { |
---|
252 | CModule Module; |
---|
253 | Module.WinMain(SW_SHOWNORMAL); |
---|
254 | } |
---|
255 | _ATLCATCH(Exception) |
---|
256 | { |
---|
257 | _tprintf(_T("Fatal Error 0x%08X\n"), (HRESULT) Exception); |
---|
258 | } |
---|
259 | return 0; |
---|
260 | } |
---|