Patch by Jonathon Wilson:
[reactos.git] / reactos / apps / testsets / loadlib / loadlib.c
1 /*
2 * ReactOS test program -
3 *
4 * loadlib.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include <windows.h>
24 #include "loadlib.h"
25 #include <string.h>
26 #include <wchar.h>
27
28 #define APP_VERSION 1
29 #define MAX_LIBS 25
30
31 #ifdef UNICODE
32 #define TARGET "UNICODE"
33 BOOL bUseAnsi = FALSE;
34 #else
35 #define TARGET "MBCS"
36 BOOL bUseAnsi = TRUE;
37 #endif
38 BOOL verbose_flagged = FALSE;
39 BOOL debug_flagged = FALSE;
40 BOOL loop_flagged = FALSE;
41 BOOL recursive_flagged = FALSE;
42
43 HANDLE OutputHandle;
44 HANDLE InputHandle;
45
46
47 void dprintf(char* fmt, ...)
48 {
49 va_list args;
50 char buffer[255];
51
52 va_start(args, fmt);
53 wvsprintfA(buffer, fmt, args);
54 WriteConsoleA(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL);
55 va_end(args);
56 }
57
58 long getinput(char* buf, int buflen)
59 {
60 DWORD result;
61
62 ReadConsoleA(InputHandle, buf, buflen, &result, NULL);
63 return (long)result;
64 }
65
66 DWORD ReportLastError(void)
67 {
68 DWORD dwError = GetLastError();
69 if (dwError != ERROR_SUCCESS) {
70 PSTR msg = NULL;
71 if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
72 0, dwError, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PSTR)&msg, 0, NULL)) {
73 if (msg != NULL) {
74 dprintf("ReportLastError() %d - %s\n", dwError, msg);
75 } else {
76 dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError);
77 }
78 } else {
79 dprintf("ReportLastError() %d - unknown error\n", dwError);
80 }
81 if (msg != NULL) {
82 LocalFree(msg);
83 }
84 }
85 return dwError;
86 }
87
88 const char* appName(const char* argv0)
89 {
90 const char* name;
91
92 name = (const char*)strrchr(argv0, '\\');
93 if (name != NULL)
94 return name + 1;
95 return argv0;
96 }
97
98 int usage(const char* appName)
99 {
100 dprintf("USAGE: %s libname [libname ...] [unicode]|[ansi] [loop][recurse]\n", appName);
101 dprintf("\tWhere libname(s) is one or more libraries to load.\n");
102 dprintf("\t[unicode] - perform tests using UNICODE api calls\n");
103 dprintf("\t[ansi] - perform tests using ANSI api calls\n");
104 dprintf("\t default is %s\n", TARGET);
105 dprintf("\t[loop] - run test process in continuous loop\n");
106 dprintf("\t[recurse] - load libraries recursively rather than sequentually\n");
107 dprintf("\t[debug] - enable debug mode (unused)\n");
108 dprintf("\t[verbose] - enable verbose output (unused)\n");
109 return 0;
110 }
111
112 DWORD LoadLibraryList(char** libnames, int counter, BOOL bUseAnsi)
113 {
114 HMODULE hModule;
115
116 dprintf("Attempting to LoadLibrary");
117 if (bUseAnsi) {
118 dprintf("A(%s) - ", *libnames);
119 hModule = LoadLibraryA(*libnames);
120 } else {
121 int len;
122 wchar_t libnameW[500];
123 len = mbstowcs(libnameW, *libnames, strlen(*libnames));
124 if (len) {
125 libnameW[len] = L'\0';
126 dprintf("W(%S) - ", libnameW);
127 hModule = LoadLibraryW(libnameW);
128 } else {
129 return ERROR_INVALID_PARAMETER;
130 }
131 }
132 if (hModule == NULL) {
133 dprintf("\nERROR: failed to obtain handle to module %s - %x\n", *libnames, hModule);
134 return ReportLastError();
135 }
136 dprintf("%x\n", hModule);
137
138 if (counter--) {
139 LoadLibraryList(++libnames, counter, bUseAnsi);
140 }
141
142 if (!FreeLibrary(hModule)) {
143 dprintf("ERROR: failed to free module %s - %x\n", *libnames, hModule);
144 return ReportLastError();
145 } else {
146 dprintf("FreeLibrary(%x) - successfull.\n", hModule);
147 }
148 return 0L;
149 }
150
151 int __cdecl main(int argc, char* argv[])
152 {
153 char* libs[MAX_LIBS];
154 int lib_count = 0;
155 int result = 0;
156 int i = 0;
157
158 AllocConsole();
159 InputHandle = GetStdHandle(STD_INPUT_HANDLE);
160 OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
161
162 dprintf("%s application - build %03d (default: %s)\n", appName(argv[0]), APP_VERSION, TARGET);
163 if (argc < 2) {
164 /*return */usage(appName(argv[0]));
165 }
166 memset(libs, 0, sizeof(libs));
167 for (i = 1; i < argc; i++) {
168 if (lstrcmpiA(argv[i], "ansi") == 0) {
169 bUseAnsi = TRUE;
170 } else if (lstrcmpiA(argv[i], "unicode") == 0) {
171 bUseAnsi = FALSE;
172 } else if (lstrcmpiA(argv[i], "loop") == 0) {
173 loop_flagged = 1;
174 } else if (lstrcmpiA(argv[i], "recurse") == 0) {
175 recursive_flagged = 1;
176 } else if (lstrcmpiA(argv[i], "verbose") == 0) {
177 verbose_flagged = 1;
178 } else if (lstrcmpiA(argv[i], "debug") == 0) {
179 debug_flagged = 1;
180 } else {
181 if (lib_count < MAX_LIBS) {
182 libs[lib_count] = argv[i];
183 ++lib_count;
184 }
185 }
186 }
187 if (lib_count) {
188 do {
189 if (recursive_flagged) {
190 result = LoadLibraryList(libs, lib_count - 1, bUseAnsi);
191 } else {
192 for (i = 0; i < lib_count; i++) {
193 result = LoadLibraryList(&libs[i], 0, bUseAnsi);
194 //if (result != 0) break;
195 }
196 }
197 } while (loop_flagged);
198 } else {
199 int len;
200 char buffer[500];
201 do {
202 dprintf("\nEnter library name to attempt loading: ");
203 len = getinput(buffer, sizeof(buffer) - 1);
204 if (len > 2) {
205 char* buf = buffer;
206 buffer[len-2] = '\0';
207 result = LoadLibraryList(&buf, 0, bUseAnsi);
208 } else break;
209 } while (!result && len);
210 }
211 dprintf("finished\n");
212 return result;
213 }
214
215
216 #ifdef _NOCRT
217 char* args[] = { "loadlib.exe", "advapi32.dll", "user32.dll", "recurse"};
218 int __cdecl mainCRTStartup(void)
219 {
220 return main(3, args);
221 }
222 #endif /*__GNUC__*/