update for HEAD-2003021201
[reactos.git] / 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
26
27 #define APP_VERSION 1
28 #define MAX_LIBS    25
29
30 #ifdef UNICODE
31 #define TARGET  "UNICODE"
32 BOOL bUseAnsi = FALSE;
33 #else
34 #define TARGET  "MBCS"
35 BOOL bUseAnsi = TRUE;
36 #endif
37 BOOL verbose_flagged = FALSE;
38 BOOL debug_flagged = FALSE;
39 BOOL loop_flagged = FALSE;
40 BOOL recursive_flagged = FALSE;
41
42 HANDLE OutputHandle;
43 HANDLE InputHandle;
44
45
46 void dprintf(char* fmt, ...)
47 {
48    va_list args;
49    char buffer[255];
50
51    va_start(args, fmt);
52    wvsprintfA(buffer, fmt, args);
53    WriteConsoleA(OutputHandle, buffer, lstrlenA(buffer), NULL, NULL);
54    va_end(args);
55 }
56
57 long getinput(char* buf, int buflen)
58 {
59     DWORD result;
60
61     ReadConsoleA(InputHandle, buf, buflen, &result, NULL);
62     return (long)result;
63 }
64
65 DWORD ReportLastError(void)
66 {
67     DWORD dwError = GetLastError();
68     if (dwError != ERROR_SUCCESS) {
69         PSTR msg = NULL;
70         if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
71             0, dwError, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (PSTR)&msg, 0, NULL)) {
72             if (msg != NULL) {
73                 dprintf("ReportLastError() %d - %s\n", dwError, msg);
74             } else {
75                 dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError);
76             }
77         } else {
78             dprintf("ReportLastError() %d - unknown error\n", dwError);
79         }
80         if (msg != NULL) {
81             LocalFree(msg);
82         }
83     }
84     return dwError;
85 }
86
87 const char* appName(const char* argv0)
88 {
89     const char* name;
90
91     name = (const char*)strrchr(argv0, '\\');
92     if (name != NULL) 
93         return name + 1;
94     return argv0;
95 }
96
97 int usage(const char* appName)
98 {
99     dprintf("USAGE: %s libname [libname ...] [unicode]|[ansi] [loop][recurse]\n", appName);
100     dprintf("\tWhere libname(s) is one or more libraries to load.\n");
101     dprintf("\t[unicode] - perform tests using UNICODE api calls\n");
102     dprintf("\t[ansi] - perform tests using ANSI api calls\n");
103     dprintf("\t    default is %s\n", TARGET);
104     dprintf("\t[loop] - run test process in continuous loop\n");
105     dprintf("\t[recurse] - load libraries recursively rather than sequentually\n");
106     dprintf("\t[debug] - enable debug mode (unused)\n");
107     dprintf("\t[verbose] - enable verbose output (unused)\n");
108     return 0;
109 }
110
111 DWORD LoadLibraryList(char** libnames, int counter, BOOL bUseAnsi)
112 {
113     HMODULE hModule;
114
115     dprintf("Attempting to LoadLibrary");
116     if (bUseAnsi) {
117         dprintf("A(%s) - ", *libnames);
118         hModule = LoadLibraryA(*libnames);
119     } else {
120         int len;
121         wchar_t libnameW[500];
122         len = mbstowcs(libnameW, *libnames, strlen(*libnames));
123         if (len) {
124             libnameW[len] = L'\0';
125             dprintf("W(%S) - ", libnameW);
126             hModule = LoadLibraryW(libnameW);
127         } else {
128             return ERROR_INVALID_PARAMETER;
129         }
130     }
131     if (hModule == NULL) {
132         dprintf("\nERROR: failed to obtain handle to module %s - %x\n", *libnames, hModule);
133         return ReportLastError();
134     }
135     dprintf("%x\n", hModule);
136
137     if (counter--) {
138         LoadLibraryList(++libnames, counter, bUseAnsi);
139     }
140
141     if (!FreeLibrary(hModule)) {
142         dprintf("ERROR: failed to free module %s - %x\n", *libnames, hModule);
143         return ReportLastError();
144     } else {
145         dprintf("FreeLibrary(%x) - successfull.\n", hModule);
146     }
147     return 0L;
148 }
149
150 int __cdecl main(int argc, char* argv[])
151 {
152     char* libs[MAX_LIBS];
153     int lib_count = 0;
154     int test_num = 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__*/