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 "precomp.h" 22 23 #include <direct.h> 24 25 void __cdecl __getmainargs(int *, char ***, char ***, int, int *); 26 static int* (__cdecl *p___p___argc)(void); 27 static char*** (__cdecl *p___p___argv)(void); 28 29 typedef void (__cdecl *_INITTERMFUN)(void); 30 static void (__cdecl *p_initterm)(_INITTERMFUN *start, _INITTERMFUN *end); 31 32 static int (__cdecl *p_get_pgmptr)(char **p); 33 34 static int callbacked; 35 36 static void __cdecl initcallback(void) 37 { 38 callbacked++; 39 } 40 41 #define initterm_test(start, end, expected) \ 42 callbacked = 0; \ 43 p_initterm(start, end); \ 44 ok(expected == callbacked,"_initterm: callbacks count mismatch: got %i, expected %i\n", callbacked, expected); 45 46 static void test_initterm(void) 47 { 48 int i; 49 static _INITTERMFUN callbacks[4]; 50 51 if (!p_initterm) 52 return; 53 54 for (i = 0; i < 4; i++) 55 { 56 callbacks[i] = initcallback; 57 } 58 59 initterm_test(&callbacks[0], &callbacks[1], 1); 60 initterm_test(&callbacks[0], &callbacks[2], 2); 61 initterm_test(&callbacks[0], &callbacks[3], 3); 62 63 callbacks[1] = NULL; 64 initterm_test(&callbacks[0], &callbacks[3], 2); 65 } 66 67 static void test_initvar( HMODULE hmsvcrt ) 68 { 69 OSVERSIONINFOA osvi = { sizeof(OSVERSIONINFOA) }; 70 int *pp_winver = (int*)GetProcAddress(hmsvcrt, "_winver"); 71 int *pp_winmajor = (int*)GetProcAddress(hmsvcrt, "_winmajor"); 72 int *pp_winminor = (int*)GetProcAddress(hmsvcrt, "_winminor"); 73 int *pp_osver = (int*)GetProcAddress(hmsvcrt, "_osver"); 74 int *pp_osplatform = (int*)GetProcAddress(hmsvcrt, "_osplatform"); 75 unsigned int winver, winmajor, winminor, osver, osplatform; 76 77 if( !( pp_winmajor && pp_winminor && pp_winver)) { 78 win_skip("_winver variables are not available\n"); 79 return; 80 } 81 winver = *pp_winver; 82 winminor = *pp_winminor; 83 winmajor = *pp_winmajor; 84 GetVersionExA( &osvi); 85 ok( winminor == osvi.dwMinorVersion, "Wrong value for _winminor %02x expected %02x\n", 86 winminor, osvi.dwMinorVersion); 87 ok( winmajor == osvi.dwMajorVersion, "Wrong value for _winmajor %02x expected %02x\n", 88 winmajor, osvi.dwMajorVersion); 89 ok( winver == ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion), 90 "Wrong value for _winver %02x expected %02x\n", 91 winver, ((osvi.dwMajorVersion << 8) | osvi.dwMinorVersion)); 92 if( !pp_osver || !pp_osplatform ) { 93 win_skip("_osver variables are not available\n"); 94 return; 95 } 96 osver = *pp_osver; 97 osplatform = *pp_osplatform; 98 ok( osver == (osvi.dwBuildNumber & 0xffff) || 99 ((osvi.dwBuildNumber >> 24) == osvi.dwMajorVersion && 100 ((osvi.dwBuildNumber >> 16) & 0xff) == osvi.dwMinorVersion), /* 95/98/ME */ 101 "Wrong value for _osver %04x expected %04x\n", 102 osver, osvi.dwBuildNumber); 103 ok(osplatform == osvi.dwPlatformId, 104 "Wrong value for _osplatform %x expected %x\n", 105 osplatform, osvi.dwPlatformId); 106 } 107 108 static void test_get_pgmptr(void) 109 { 110 char *pgm = NULL; 111 int res; 112 113 if (!p_get_pgmptr) 114 return; 115 116 res = p_get_pgmptr(&pgm); 117 118 ok( res == 0, "Wrong _get_pgmptr return value %d expected 0\n", res); 119 ok( pgm != NULL, "_get_pgmptr returned a NULL pointer\n" ); 120 } 121 122 static void test___getmainargs(void) 123 { 124 int argc, new_argc, mode; 125 char **argv, **new_argv, **envp; 126 char tmppath[MAX_PATH], filepath[MAX_PATH]; 127 FILE *f; 128 129 ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); 130 131 mode = 0; 132 __getmainargs(&argc, &argv, &envp, 0, &mode); 133 ok(argc == 4, "argc = %d\n", argc); 134 ok(!strcmp(argv[1], "data"), "argv[1] = %s\n", argv[1]); 135 sprintf(filepath, "%s*\\*", tmppath); 136 ok(!strcmp(argv[2], filepath), "argv[2] = %s\n", argv[2]); 137 sprintf(filepath, "%swine_test/*", tmppath); 138 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 139 ok(!argv[4], "argv[4] != NULL\n"); 140 141 if(p___p___argc && p___p___argv) { 142 new_argc = *p___p___argc(); 143 new_argv = *p___p___argv(); 144 ok(new_argc == 4, "*__p___argc() = %d\n", new_argc); 145 ok(new_argv == argv, "*__p___argv() = %p, expected %p\n", new_argv, argv); 146 }else { 147 win_skip("__p___argc or __p___argv is not available\n"); 148 } 149 150 mode = 0; 151 __getmainargs(&argc, &argv, &envp, 1, &mode); 152 ok(argc == 5, "argc = %d\n", argc); 153 ok(!strcmp(argv[1], "data"), "argv[1] = %s\n", argv[1]); 154 sprintf(filepath, "%s*\\*", tmppath); 155 ok(!strcmp(argv[2], filepath), "argv[2] = %s\n", argv[2]); 156 sprintf(filepath, "%swine_test/a", tmppath); 157 if(argv[3][strlen(argv[3])-1] == 'a') { 158 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 159 sprintf(filepath, "%swine_test/test", tmppath); 160 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 161 }else { 162 ok(!strcmp(argv[4], filepath), "argv[4] = %s\n", argv[4]); 163 sprintf(filepath, "%swine_test/test", tmppath); 164 ok(!strcmp(argv[3], filepath), "argv[3] = %s\n", argv[3]); 165 } 166 ok(!argv[5], "argv[5] != NULL\n"); 167 168 if(p___p___argc && p___p___argv) { 169 new_argc = *p___p___argc(); 170 new_argv = *p___p___argv(); 171 ok(new_argc == argc, "*__p___argc() = %d, expected %d\n", new_argc, argc); 172 ok(new_argv == argv, "*__p___argv() = %p, expected %p\n", new_argv, argv); 173 } 174 175 sprintf(filepath, "%swine_test/b", tmppath); 176 f = fopen(filepath, "w"); 177 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 178 fclose(f); 179 mode = 0; 180 __getmainargs(&new_argc, &new_argv, &envp, 1, &mode); 181 ok(new_argc == argc+1, "new_argc = %d, expected %d\n", new_argc, argc+1); 182 _unlink(filepath); 183 } 184 185 static void test___getmainargs_parent(char *name) 186 { 187 char cmdline[3*MAX_PATH]; 188 char tmppath[MAX_PATH], filepath[MAX_PATH]; 189 STARTUPINFOA startup; 190 PROCESS_INFORMATION proc; 191 FILE *f; 192 int ret; 193 194 ok(GetTempPathA(MAX_PATH, tmppath) != 0, "GetTempPath failed\n"); 195 sprintf(cmdline, "%s data %s*\\* %swine_test/*", name, tmppath, tmppath); 196 197 sprintf(filepath, "%swine_test", tmppath); 198 ret = _mkdir(filepath); 199 ok(!ret, "_mkdir failed: %d\n", errno); 200 sprintf(filepath, "%swine_test\\a", tmppath); 201 f = fopen(filepath, "w"); 202 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 203 fclose(f); 204 sprintf(filepath, "%swine_test\\test", tmppath); 205 f = fopen(filepath, "w"); 206 ok(f != NULL, "fopen(%s) failed: %d\n", filepath, errno); 207 fclose(f); 208 209 memset(&startup, 0, sizeof(startup)); 210 startup.cb = sizeof(startup); 211 CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &proc); 212 winetest_wait_child_process(proc.hProcess); 213 214 _unlink(filepath); 215 sprintf(filepath, "%swine_test\\a", tmppath); 216 _unlink(filepath); 217 sprintf(filepath, "%swine_test", tmppath); 218 _rmdir(filepath); 219 } 220 221 START_TEST(data) 222 { 223 HMODULE hmsvcrt; 224 int arg_c; 225 char** arg_v; 226 227 hmsvcrt = GetModuleHandleA("msvcrt.dll"); 228 if (!hmsvcrt) 229 hmsvcrt = GetModuleHandleA("msvcrtd.dll"); 230 if (hmsvcrt) 231 { 232 p_initterm=(void*)GetProcAddress(hmsvcrt, "_initterm"); 233 p_get_pgmptr=(void*)GetProcAddress(hmsvcrt, "_get_pgmptr"); 234 p___p___argc=(void*)GetProcAddress(hmsvcrt, "__p___argc"); 235 p___p___argv=(void*)GetProcAddress(hmsvcrt, "__p___argv"); 236 } 237 238 arg_c = winetest_get_mainargs(&arg_v); 239 if(arg_c >= 3) { 240 test___getmainargs(); 241 return; 242 } 243 244 test_initterm(); 245 test_initvar(hmsvcrt); 246 test_get_pgmptr(); 247 test___getmainargs_parent(arg_v[0]); 248 } 249