[CRT] Massively improve performance of rand_s
[reactos.git] / base / applications / network / net / main.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE: base/applications/network/net/main.c
5 * PURPOSE:
6 *
7 * PROGRAMMERS: Magnus Olsen (greatlord@reactos.org)
8 */
9
10 #include "net.h"
11
12 #define MAX_BUFFER_SIZE 4096
13
14 typedef struct _COMMAND
15 {
16 WCHAR *name;
17 INT (*func)(INT, WCHAR**);
18 // VOID (*help)(INT, WCHAR**);
19 } COMMAND, *PCOMMAND;
20
21 COMMAND cmds[] =
22 {
23 {L"accounts", cmdAccounts},
24 {L"computer", cmdComputer},
25 {L"config", cmdConfig},
26 {L"continue", cmdContinue},
27 {L"file", unimplemented},
28 {L"group", cmdGroup},
29 {L"help", cmdHelp},
30 {L"helpmsg", cmdHelpMsg},
31 {L"localgroup", cmdLocalGroup},
32 {L"pause", cmdPause},
33 {L"session", cmdSession},
34 {L"share", cmdShare},
35 {L"start", cmdStart},
36 {L"statistics", cmdStatistics},
37 {L"stop", cmdStop},
38 {L"syntax", cmdSyntax},
39 {L"time", unimplemented},
40 {L"use", cmdUse},
41 {L"user", cmdUser},
42 {L"view", unimplemented},
43 {NULL, NULL}
44 };
45
46 HMODULE hModuleNetMsg = NULL;
47
48
49 VOID
50 PrintPaddedResourceString(
51 UINT uID,
52 INT nPaddedLength)
53 {
54 INT nLength;
55
56 nLength = ConResPuts(StdOut, uID);
57 if (nLength < nPaddedLength)
58 PrintPadding(L' ', nPaddedLength - nLength);
59 }
60
61
62 VOID
63 PrintPadding(
64 WCHAR chr,
65 INT nPaddedLength)
66 {
67 INT i;
68 WCHAR szMsgBuffer[MAX_BUFFER_SIZE];
69
70 for (i = 0; i < nPaddedLength; i++)
71 szMsgBuffer[i] = chr;
72 szMsgBuffer[nPaddedLength] = UNICODE_NULL;
73
74 ConPuts(StdOut, szMsgBuffer);
75 }
76
77
78 DWORD
79 TranslateAppMessage(
80 DWORD dwMessage)
81 {
82 switch (dwMessage)
83 {
84 case NERR_Success:
85 return 3500; // APPERR_3500
86 case ERROR_MORE_DATA:
87 return 3513; // APPERR_3513
88 }
89 return dwMessage;
90 }
91
92 VOID
93 PrintMessageStringV(
94 DWORD dwMessage,
95 ...)
96 {
97 PWSTR pBuffer;
98 va_list args = NULL;
99
100 va_start(args, dwMessage);
101
102 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
103 hModuleNetMsg,
104 dwMessage,
105 LANG_USER_DEFAULT,
106 (LPWSTR)&pBuffer,
107 0,
108 &args);
109 va_end(args);
110
111 if (pBuffer)
112 {
113 ConPuts(StdOut, pBuffer);
114 LocalFree(pBuffer);
115 pBuffer = NULL;
116 }
117 }
118
119 VOID
120 PrintMessageString(
121 DWORD dwMessage)
122 {
123 PWSTR pBuffer;
124
125 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
126 FORMAT_MESSAGE_IGNORE_INSERTS,
127 hModuleNetMsg,
128 dwMessage,
129 LANG_USER_DEFAULT,
130 (LPWSTR)&pBuffer,
131 0,
132 NULL);
133 if (pBuffer)
134 {
135 ConPuts(StdOut, pBuffer);
136 LocalFree(pBuffer);
137 pBuffer = NULL;
138 }
139 }
140
141
142 VOID
143 PrintPaddedMessageString(
144 DWORD dwMessage,
145 INT nPaddedLength)
146 {
147 PWSTR pBuffer;
148 DWORD dwLength;
149
150 dwLength = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
151 FORMAT_MESSAGE_IGNORE_INSERTS,
152 hModuleNetMsg,
153 dwMessage,
154 LANG_USER_DEFAULT,
155 (LPWSTR)&pBuffer,
156 0,
157 NULL);
158 if (pBuffer)
159 {
160 ConPuts(StdOut, pBuffer);
161 LocalFree(pBuffer);
162 pBuffer = NULL;
163 }
164
165 if (dwLength < (DWORD)nPaddedLength)
166 PrintPadding(L' ', (DWORD)nPaddedLength - dwLength);
167 }
168
169
170 VOID
171 PrintErrorMessage(
172 DWORD dwError)
173 {
174 WCHAR szErrorBuffer[16];
175 PWSTR pBuffer;
176 PWSTR pErrorInserts[2] = {NULL, NULL};
177
178 if (dwError >= MIN_LANMAN_MESSAGE_ID && dwError <= MAX_LANMAN_MESSAGE_ID)
179 {
180 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
181 FORMAT_MESSAGE_IGNORE_INSERTS,
182 hModuleNetMsg,
183 dwError,
184 LANG_USER_DEFAULT,
185 (LPWSTR)&pBuffer,
186 0,
187 NULL);
188 if (pBuffer)
189 {
190 ConPrintf(StdErr, L"%s\n", pBuffer);
191 LocalFree(pBuffer);
192 pBuffer = NULL;
193 }
194 }
195 else
196 {
197 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
198 FORMAT_MESSAGE_IGNORE_INSERTS,
199 NULL,
200 dwError,
201 LANG_USER_DEFAULT,
202 (LPWSTR)&pBuffer,
203 0,
204 NULL);
205 if (pBuffer)
206 {
207 ConPrintf(StdErr, L"%s\n", pBuffer);
208 LocalFree(pBuffer);
209 pBuffer = NULL;
210 }
211 }
212
213 if (dwError != ERROR_SUCCESS)
214 {
215 /* Format insert for the 3514 message */
216 swprintf(szErrorBuffer, L"%lu", dwError);
217 pErrorInserts[0] = szErrorBuffer;
218
219 /* Format and print the 3514 message */
220 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
221 FORMAT_MESSAGE_ARGUMENT_ARRAY,
222 hModuleNetMsg,
223 3514,
224 LANG_USER_DEFAULT,
225 (LPWSTR)&pBuffer,
226 0,
227 (va_list *)pErrorInserts);
228 if (pBuffer)
229 {
230 ConPrintf(StdErr, L"%s\n", pBuffer);
231 LocalFree(pBuffer);
232 pBuffer = NULL;
233 }
234 }
235 }
236
237
238 VOID
239 PrintNetMessage(
240 DWORD dwMessage)
241 {
242 PWSTR pBuffer;
243
244 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
245 FORMAT_MESSAGE_FROM_HMODULE |
246 FORMAT_MESSAGE_IGNORE_INSERTS,
247 GetModuleHandleW(NULL),
248 dwMessage,
249 LANG_USER_DEFAULT,
250 (LPWSTR)&pBuffer,
251 0,
252 NULL);
253 if (pBuffer)
254 {
255 ConPuts(StdOut, pBuffer);
256 ConPuts(StdOut, L"\n");
257 LocalFree(pBuffer);
258 pBuffer = NULL;
259 }
260 }
261
262
263 VOID
264 ReadFromConsole(
265 LPWSTR lpInput,
266 DWORD dwLength,
267 BOOL bEcho)
268 {
269 DWORD dwOldMode;
270 DWORD dwRead = 0;
271 HANDLE hFile;
272 LPWSTR p;
273 PCHAR pBuf;
274
275 pBuf = HeapAlloc(GetProcessHeap(), 0, dwLength - 1);
276 ZeroMemory(lpInput, dwLength * sizeof(WCHAR));
277 hFile = GetStdHandle(STD_INPUT_HANDLE);
278 GetConsoleMode(hFile, &dwOldMode);
279
280 SetConsoleMode(hFile, ENABLE_LINE_INPUT | (bEcho ? ENABLE_ECHO_INPUT : 0));
281
282 ReadFile(hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
283
284 MultiByteToWideChar(CP_OEMCP, 0, pBuf, dwRead, lpInput, dwLength - 1);
285 HeapFree(GetProcessHeap(), 0, pBuf);
286
287 for (p = lpInput; *p; p++)
288 {
289 if (*p == L'\x0d')
290 {
291 *p = L'\0';
292 break;
293 }
294 }
295
296 SetConsoleMode(hFile, dwOldMode);
297 }
298
299
300 int wmain(int argc, WCHAR **argv)
301 {
302 WCHAR szDllBuffer[MAX_PATH];
303 PCOMMAND cmdptr;
304 int nResult = 0;
305 BOOL bRun = FALSE;
306
307 /* Initialize the Console Standard Streams */
308 ConInitStdStreams();
309
310 /* Load netmsg.dll */
311 GetSystemDirectoryW(szDllBuffer, ARRAYSIZE(szDllBuffer));
312 wcscat(szDllBuffer, L"\\netmsg.dll");
313
314 hModuleNetMsg = LoadLibrary(szDllBuffer);
315 if (hModuleNetMsg == NULL)
316 {
317 ConPrintf(StdErr, L"Failed to load netmsg.dll\n");
318 return 1;
319 }
320
321 if (argc < 2)
322 {
323 nResult = 1;
324 goto done;
325 }
326
327 /* Scan the command table */
328 for (cmdptr = cmds; cmdptr->name; cmdptr++)
329 {
330 if (_wcsicmp(argv[1], cmdptr->name) == 0)
331 {
332 nResult = cmdptr->func(argc, argv);
333 bRun = TRUE;
334 break;
335 }
336 }
337
338 done:
339 if (bRun == FALSE)
340 {
341 PrintMessageString(4381);
342 ConPuts(StdOut, L"\n");
343 PrintNetMessage(MSG_NET_SYNTAX);
344 }
345
346 if (hModuleNetMsg != NULL)
347 FreeLibrary(hModuleNetMsg);
348
349 return nResult;
350 }
351
352 INT unimplemented(INT argc, WCHAR **argv)
353 {
354 ConPuts(StdOut, L"This command is not implemented yet\n");
355 return 1;
356 }