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 } 157 else skip("__p___argc or __p___argv is not available\n"); 158 159 mode = 0; 160 __getmainargs(&argc, &argv, &envp, 1, &mode); 161 ok(argc == 5, "argc = %d\n", argc); 162 ok(!strcmp(argv[1], "data"), "argv[1] = %s\n", argv[1]); 163 sprintf(filepath, "%s*\\*", tmppath); 164 ok(!strcmp(argv[2], filepath), "argv[2] = %s\n", argv[2]); 165 sprintf(filepath, "%swine_test/a", tmppath); 166 if(argv[3][strlen(argv[3])-1] == 'a') { 167 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 168 sprintf(filepath, "%swine_test/test", tmppath); 169 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 170 }else { 171 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 172 sprintf(filepath, "%swine_test/test", tmppath); 173 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 174 } 175 ok(!argv[5], "argv[5] != NULL\n"); 176 177 if(p___p___argc && p___p___argv) { 178 new_argc = *p___p___argc(); 179 new_argv = *p___p___argv(); 180 ok(new_argc == argc, "*__p___argc() = %d, expected %d\n", new_argc, argc); 181 ok(new_argv == argv, "*__p___argv() = %p, expected %p\n", new_argv, argv); 182 } 183 184 sprintf(filepath, "%swine_test/b", tmppath); 185 f = fopen(filepath, "w"); 186 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 187 fclose(f); 188 mode = 0; 189 __getmainargs(&new_argc, &new_argv, &envp, 1, &mode); 190 ok(new_argc == argc+1, "new_argc = %d, expected %d\n", new_argc, argc+1); 191 _unlink(filepath); 192 } 193 194 static void test___getmainargs_parent(char *name) 195 { 196 char cmdline[3*MAX_PATH]; 197 char tmppath[MAX_PATH], filepath[MAX_PATH]; 198 STARTUPINFOA startup; 199 PROCESS_INFORMATION proc; 200 FILE *f; 201 int ret; 202 203 ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); 204 sprintf(cmdline, "%s data %s*\\* %swine_test/*", name, tmppath, tmppath); 205 206 sprintf(filepath, "%swine_test", tmppath); 207 ret = _mkdir(filepath); 208 ok(!ret, "_mkdir failed: %d\n", errno); 209 sprintf(filepath, "%swine_test\\a", tmppath); 210 f = fopen(filepath, "w"); 211 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 212 fclose(f); 213 sprintf(filepath, "%swine_test\\test", tmppath); 214 f = fopen(filepath, "w"); 215 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 216 fclose(f); 217 218 memset(&startup, 0, sizeof(startup)); 219 startup.cb = sizeof(startup); 220 CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); 221 winetest_wait_child_process(proc.hProcess); 222 223 _unlink(filepath); 224 sprintf(filepath, "%swine_test\\a", tmppath); 225 _unlink(filepath); 226 sprintf(filepath, "%swine_test", tmppath); 227 _rmdir(filepath); 228 } 229 230 START_TEST(data) 231 { 232 HMODULE hmsvcrt; 233 int arg_c; 234 char** arg_v; 235 236 hmsvcrt = GetModuleHandleA("msvcrt.dll"); 237 if (!hmsvcrt) 238 hmsvcrt = GetModuleHandleA("msvcrtd.dll"); 239 if (hmsvcrt) 240 { 241 p_initterm=(void*)GetProcAddress(hmsvcrt, "_initterm"); 242 p_get_pgmptr=(void*)GetProcAddress(hmsvcrt, "_get_pgmptr"); 243 p___p___argc=(void*)GetProcAddress(hmsvcrt, "__p___argc"); 244 p___p___argv=(void*)GetProcAddress(hmsvcrt, "__p___argv"); 245 } 246 247 arg_c = winetest_get_mainargs(&arg_v); 248 if(arg_c >= 3) { 249 test___getmainargs(); 250 return; 251 } 252 253 test_initterm(); 254 test_initvar(hmsvcrt); 255 test_get_pgmptr(); 256 test___getmainargs_parent(arg_v[0]); 257 } 258