1 /* 2 * Tests msvcrt/data.c 3 * 4 * Copyright 2006 Andrew Ziem 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "wine/test.h" 22 #include <stdarg.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <fcntl.h> 26 #include <sys/stat.h> 27 #include <io.h> 28 #include <windef.h> 29 #include <winbase.h> 30 #include <winnls.h> 31 #include <process.h> 32 #include <errno.h> 33 #include <direct.h> 34 35 void __cdecl __getmainargs(int *, char ***, char ***, int, int *); 36 static int* (__cdecl *p___p___argc)(void); 37 static char*** (__cdecl *p___p___argv)(void); 38 39 typedef void (__cdecl *_INITTERMFUN)(void); 40 static void (__cdecl *p_initterm)(_INITTERMFUN *start, _INITTERMFUN *end); 41 42 static int (__cdecl *p_get_pgmptr)(char **p); 43 44 static int callbacked; 45 46 static void __cdecl initcallback(void) 47 { 48 callbacked++; 49 } 50 51 #define initterm_test(start, end, expected) \ 52 callbacked = 0; \ 53 p_initterm(start, end); \ 54 ok(expected == callbacked,"_initterm: callbacks count mismatch: got %i, expected %i\n", callbacked, expected); 55 56 static void test_initterm(void) 57 { 58 int i; 59 static _INITTERMFUN callbacks[4]; 60 61 if (!p_initterm) 62 return; 63 64 for (i = 0; i < 4; i++) 65 { 66 callbacks[i] = initcallback; 67 } 68 69 initterm_test(&callbacks[0], &callbacks[1], 1); 70 initterm_test(&callbacks[0], &callbacks[2], 2); 71 initterm_test(&callbacks[0], &callbacks[3], 3); 72 73 callbacks[1] = NULL; 74 initterm_test(&callbacks[0], &callbacks[3], 2); 75 } 76 77 static void test_initvar( HMODULE hmsvcrt ) 78 { 79 OSVERSIONINFOA osvi = { sizeof(OSVERSIONINFOA) }; 80 int *pp_winver = (int*)GetProcAddress(hmsvcrt, "_winver"); 81 int *pp_winmajor = (int*)GetProcAddress(hmsvcrt, "_winmajor"); 82 int *pp_winminor = (int*)GetProcAddress(hmsvcrt, "_winminor"); 83 int *pp_osver = (int*)GetProcAddress(hmsvcrt, "_osver"); 84 int *pp_osplatform = (int*)GetProcAddress(hmsvcrt, "_osplatform"); 85 unsigned int winver, winmajor, winminor, osver, osplatform; 86 87 if( !( pp_winmajor && pp_winminor && pp_winver)) { 88 win_skip("_winver variables are not available\n"); 89 return; 90 } 91 winver = *pp_winver; 92 winminor = *pp_winminor; 93 winmajor = *pp_winmajor; 94 GetVersionExA( &osvi); 95 ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02x\n", 96 winminor, osvi.dwMinorVersion); 97 ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02x\n", 98 winmajor, osvi.dwMajorVersion); 99 ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion), 100 "Wrong value for _winver %02x expected %02x\n", 101 winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion)); 102 if( !pp_osver || !pp_osplatform ) { 103 win_skip("_osver variables are not available\n"); 104 return; 105 } 106 osver = *pp_osver; 107 osplatform = *pp_osplatform; 108 ok( osver == (osvi.dwBuildNumber & 0xffff) || 109 ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion && 110 ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */ 111 "Wrong value for _osver %04x expected %04x\n", 112 osver, osvi.dwBuildNumber); 113 ok(osplatform == osvi.dwPlatformId, 114 "Wrong value for _osplatform %x expected %x\n", 115 osplatform, osvi.dwPlatformId); 116 } 117 118 static void test_get_pgmptr(void) 119 { 120 char *pgm = NULL; 121 int res; 122 123 if (!p_get_pgmptr) 124 return; 125 126 res = p_get_pgmptr(&pgm); 127 128 ok( res == 0, "Wrong _get_pgmptr return value %d expected 0\n", res); 129 ok( pgm != NULL, "_get_pgmptr returned a NULL pointer\n" ); 130 } 131 132 static void test___getmainargs(void) 133 { 134 int argc, new_argc, mode; 135 char **argv, **new_argv, **envp; 136 char tmppath[MAX_PATH], filepath[MAX_PATH]; 137 FILE *f; 138 139 ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); 140 141 mode = 0; 142 __getmainargs(&argc, &argv, &envp, 0, &mode); 143 ok(argc == 4, "argc = %d\n", argc); 144 ok(!strcmp(argv[1], "data"), "argv[1] = %s\n", argv[1]); 145 sprintf(filepath, "%s*\\*", tmppath); 146 ok(!strcmp(argv[2], filepath), "argv[2] = %s\n", argv[2]); 147 sprintf(filepath, "%swine_test/*", tmppath); 148 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 149 ok(!argv[4], "argv[4] != NULL\n"); 150 151 if(p___p___argc && p___p___argv) { 152 new_argc = *p___p___argc(); 153 new_argv = *p___p___argv(); 154 ok(new_argc == 4, "*__p___argc() = %d\n", new_argc); 155 ok(new_argv == argv, "*__p___argv() = %p, expected %p\n", new_argv, argv); 156 }else { 157 win_skip("__p___argc or __p___argv is not available\n"); 158 } 159 160 mode = 0; 161 __getmainargs(&argc, &argv, &envp, 1, &mode); 162 ok(argc == 5, "argc = %d\n", argc); 163 ok(!strcmp(argv[1], "data"), "argv[1] = %s\n", argv[1]); 164 sprintf(filepath, "%s*\\*", tmppath); 165 ok(!strcmp(argv[2], filepath), "argv[2] = %s\n", argv[2]); 166 sprintf(filepath, "%swine_test/a", tmppath); 167 if(argv[3][strlen(argv[3])-1] == 'a') { 168 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 169 sprintf(filepath, "%swine_test/test", tmppath); 170 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 171 }else { 172 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 173 sprintf(filepath, "%swine_test/test", tmppath); 174 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 175 } 176 ok(!argv[5], "argv[5] != NULL\n"); 177 178 if(p___p___argc && p___p___argv) { 179 new_argc = *p___p___argc(); 180 new_argv = *p___p___argv(); 181 ok(new_argc == argc, "*__p___argc() = %d, expected %d\n", new_argc, argc); 182 ok(new_argv == argv, "*__p___argv() = %p, expected %p\n", new_argv, argv); 183 } 184 185 sprintf(filepath, "%swine_test/b", tmppath); 186 f = fopen(filepath, "w"); 187 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 188 fclose(f); 189 mode = 0; 190 __getmainargs(&new_argc, &new_argv, &envp, 1, &mode); 191 ok(new_argc == argc+1, "new_argc = %d, expected %d\n", new_argc, argc+1); 192 _unlink(filepath); 193 } 194 195 static void test___getmainargs_parent(char *name) 196 { 197 char cmdline[3*MAX_PATH]; 198 char tmppath[MAX_PATH], filepath[MAX_PATH]; 199 STARTUPINFOA startup; 200 PROCESS_INFORMATION proc; 201 FILE *f; 202 int ret; 203 204 ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); 205 sprintf(cmdline, "%s data %s*\\* %swine_test/*", name, tmppath, tmppath); 206 207 sprintf(filepath, "%swine_test", tmppath); 208 ret = _mkdir(filepath); 209 ok(!ret, "_mkdir failed: %d\n", errno); 210 sprintf(filepath, "%swine_test\\a", tmppath); 211 f = fopen(filepath, "w"); 212 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 213 fclose(f); 214 sprintf(filepath, "%swine_test\\test", tmppath); 215 f = fopen(filepath, "w"); 216 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 217 fclose(f); 218 219 memset(&startup, 0, sizeof(startup)); 220 startup.cb = sizeof(startup); 221 CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); 222 winetest_wait_child_process(proc.hProcess); 223 224 _unlink(filepath); 225 sprintf(filepath, "%swine_test\\a", tmppath); 226 _unlink(filepath); 227 sprintf(filepath, "%swine_test", tmppath); 228 _rmdir(filepath); 229 } 230 231 START_TEST(data) 232 { 233 HMODULE hmsvcrt; 234 int arg_c; 235 char** arg_v; 236 237 hmsvcrt = GetModuleHandleA("msvcrt.dll"); 238 if (!hmsvcrt) 239 hmsvcrt = GetModuleHandleA("msvcrtd.dll"); 240 if (hmsvcrt) 241 { 242 p_initterm=(void*)GetProcAddress(hmsvcrt, "_initterm"); 243 p_get_pgmptr=(void*)GetProcAddress(hmsvcrt, "_get_pgmptr"); 244 p___p___argc=(void*)GetProcAddress(hmsvcrt, "__p___argc"); 245 p___p___argv=(void*)GetProcAddress(hmsvcrt, "__p___argv"); 246 } 247 248 arg_c = winetest_get_mainargs(&arg_v); 249 if(arg_c >= 3) { 250 test___getmainargs(); 251 return; 252 } 253 254 test_initterm(); 255 test_initvar(hmsvcrt); 256 test_get_pgmptr(); 257 test___getmainargs_parent(arg_v[0]); 258 } 259