Added some support for cross-compilation using mingw32.
[wine/gsoc_dplay.git] / dlls / kernel / tests / process.c
blob267a37b48427b26c64433bebf9ddbfd4ecf9cd55
1 /*
2 * Unit test suite for CreateProcess function.
4 * Copyright 2002 Eric Pouech
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "wine/test.h"
28 static char base[MAX_PATH];
29 static char selfname[MAX_PATH];
30 static char resfile[MAX_PATH];
32 static int myARGC;
33 static char** myARGV;
35 /* ---------------- portable memory allocation thingie */
37 static char memory[16384];
38 static char* memory_index = memory;
40 static char* grab_memory(size_t len)
42 char* ret = memory_index;
43 /* align on dword */
44 len = (len + 3) & ~3;
45 memory_index += len;
46 assert(memory_index <= memory + sizeof(memory));
47 return ret;
50 static void release_memory(void)
52 memory_index = memory;
55 /* ---------------- simplistic tool to encode/decode strings (to hide \ " ' and such) */
57 static char* encodeA(const char* str)
59 size_t len;
60 char* ptr;
61 int i;
63 if (!str) return "";
64 len = strlen(str) + 1;
65 ptr = grab_memory(len * 2 + 1);
66 for (i = 0; i < len; i++)
67 sprintf(&ptr[i * 2], "%02x", (unsigned char)str[i]);
68 ptr[2 * len] = '\0';
69 return ptr;
72 static char* encodeW(const WCHAR* str)
74 size_t len;
75 char* ptr;
76 int i;
78 if (!str) return "";
79 len = lstrlenW(str) + 1;
80 ptr = grab_memory(len * 4 + 1);
81 assert(ptr);
82 for (i = 0; i < len; i++)
83 sprintf(&ptr[i * 4], "%04x", (unsigned int)(unsigned short)str[i]);
84 ptr[4 * len] = '\0';
85 return ptr;
88 static unsigned decode_char(char c)
90 if (c >= '0' && c <= '9') return c - '0';
91 if (c >= 'a' && c <= 'f') return c - 'a' + 10;
92 assert(c >= 'A' && c <= 'F');
93 return c - 'A' + 10;
96 static char* decodeA(const char* str)
98 size_t len;
99 char* ptr;
100 int i;
102 len = strlen(str) / 2;
103 if (!len--) return NULL;
104 ptr = grab_memory(len + 1);
105 for (i = 0; i < len; i++)
106 ptr[i] = (decode_char(str[2 * i]) << 4) | decode_char(str[2 * i + 1]);
107 ptr[len] = '\0';
108 return ptr;
111 static WCHAR* decodeW(const char* str)
113 size_t len;
114 WCHAR* ptr;
115 int i;
117 len = strlen(str) / 4;
118 if (!len--) return NULL;
119 ptr = (WCHAR*)grab_memory(len * 2 + 1);
120 for (i = 0; i < len; i++)
121 ptr[i] = (decode_char(str[4 * i]) << 12) |
122 (decode_char(str[4 * i + 1]) << 8) |
123 (decode_char(str[4 * i + 2]) << 4) |
124 (decode_char(str[4 * i + 3]) << 0);
125 ptr[len] = '\0';
126 return ptr;
129 /******************************************************************
130 * init
132 * generates basic information like:
133 * base: absolute path to curr dir
134 * selfname: the way to reinvoke ourselves
136 static int init(void)
138 myARGC = winetest_get_mainargs( &myARGV );
139 if (!GetCurrentDirectoryA(sizeof(base), base)) return 0;
140 strcpy(selfname, myARGV[0]);
141 return 1;
144 /******************************************************************
145 * get_file_name
147 * generates an absolute file_name for temporary file
150 static void get_file_name(char* buf)
152 char path[MAX_PATH];
154 buf[0] = '\0';
155 GetTempPathA(sizeof(path), path);
156 GetTempFileNameA(path, "wt", 0, buf);
159 /******************************************************************
160 * static void childPrintf
163 static void childPrintf(HANDLE h, const char* fmt, ...)
165 va_list valist;
166 char buffer[2048];
167 DWORD w;
169 va_start(valist, fmt);
170 vsprintf(buffer, fmt, valist);
171 va_end(valist);
172 WriteFile(h, buffer, strlen(buffer), &w, NULL);
176 /******************************************************************
177 * doChild
179 * output most of the information in the child process
181 static void doChild(const char* file)
183 STARTUPINFOA siA;
184 STARTUPINFOW siW;
185 int i;
186 char* ptrA;
187 WCHAR* ptrW;
188 char bufA[MAX_PATH];
189 WCHAR bufW[MAX_PATH];
190 HANDLE hFile = CreateFileA(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
192 if (hFile == INVALID_HANDLE_VALUE) return;
194 /* output of startup info (Ansi) */
195 GetStartupInfoA(&siA);
196 childPrintf(hFile,
197 "[StartupInfoA]\ncb=%08ld\nlpDesktop=%s\nlpTitle=%s\n"
198 "dwX=%lu\ndwY=%lu\ndwXSize=%lu\ndwYSize=%lu\n"
199 "dwXCountChars=%lu\ndwYCountChars=%lu\ndwFillAttribute=%lu\n"
200 "dwFlags=%lu\nwShowWindow=%u\n"
201 "hStdInput=%lu\nhStdOutput=%lu\nhStdError=%lu\n\n",
202 siA.cb, encodeA(siA.lpDesktop), encodeA(siA.lpTitle),
203 siA.dwX, siA.dwY, siA.dwXSize, siA.dwYSize,
204 siA.dwXCountChars, siA.dwYCountChars, siA.dwFillAttribute,
205 siA.dwFlags, siA.wShowWindow,
206 (DWORD)siA.hStdInput, (DWORD)siA.hStdOutput, (DWORD)siA.hStdError);
208 /* since GetStartupInfoW is only implemented in win2k,
209 * zero out before calling so we can notice the difference
211 memset(&siW, 0, sizeof(siW));
212 GetStartupInfoW(&siW);
213 childPrintf(hFile,
214 "[StartupInfoW]\ncb=%08ld\nlpDesktop=%s\nlpTitle=%s\n"
215 "dwX=%lu\ndwY=%lu\ndwXSize=%lu\ndwYSize=%lu\n"
216 "dwXCountChars=%lu\ndwYCountChars=%lu\ndwFillAttribute=%lu\n"
217 "dwFlags=%lu\nwShowWindow=%u\n"
218 "hStdInput=%lu\nhStdOutput=%lu\nhStdError=%lu\n\n",
219 siW.cb, encodeW(siW.lpDesktop), encodeW(siW.lpTitle),
220 siW.dwX, siW.dwY, siW.dwXSize, siW.dwYSize,
221 siW.dwXCountChars, siW.dwYCountChars, siW.dwFillAttribute,
222 siW.dwFlags, siW.wShowWindow,
223 (DWORD)siW.hStdInput, (DWORD)siW.hStdOutput, (DWORD)siW.hStdError);
225 /* Arguments */
226 childPrintf(hFile, "[Arguments]\nargcA=%d\n", myARGC);
227 for (i = 0; i < myARGC; i++)
229 childPrintf(hFile, "argvA%d=%s\n", i, encodeA(myARGV[i]));
231 childPrintf(hFile, "CommandLineA=%s\n", encodeA(GetCommandLineA()));
233 #if 0
234 int argcW;
235 WCHAR** argvW;
237 /* this is part of shell32... and should be tested there */
238 argvW = CommandLineToArgvW(GetCommandLineW(), &argcW);
239 for (i = 0; i < argcW; i++)
241 childPrintf(hFile, "argvW%d=%s\n", i, encodeW(argvW[i]));
243 #endif
244 childPrintf(hFile, "CommandLineW=%s\n\n", encodeW(GetCommandLineW()));
246 /* output of environment (Ansi) */
247 ptrA = GetEnvironmentStringsA();
248 if (ptrA)
250 childPrintf(hFile, "[EnvironmentA]\n");
251 i = 0;
252 while (*ptrA)
254 if (strlen(ptrA) < 128)
256 childPrintf(hFile, "env%d=%s\n", i, encodeA(ptrA));
257 i++;
259 ptrA += strlen(ptrA) + 1;
261 childPrintf(hFile, "\n");
264 /* output of environment (Unicode) */
265 ptrW = GetEnvironmentStringsW();
266 if (ptrW)
268 childPrintf(hFile, "[EnvironmentW]\n");
269 i = 0;
270 while (*ptrW)
272 if (lstrlenW(ptrW) < 128)
274 childPrintf(hFile, "env%d=%s\n", i, encodeW(ptrW));
275 i++;
277 ptrW += lstrlenW(ptrW) + 1;
279 childPrintf(hFile, "\n");
282 childPrintf(hFile, "[Misc]\n");
283 if (GetCurrentDirectoryA(sizeof(bufA), bufA))
284 childPrintf(hFile, "CurrDirA=%s\n", encodeA(bufA));
285 if (GetCurrentDirectoryW(sizeof(bufW) / sizeof(bufW[0]), bufW))
286 childPrintf(hFile, "CurrDirW=%s\n", encodeW(bufW));
287 childPrintf(hFile, "\n");
289 CloseHandle(hFile);
292 static char* getChildString(const char* sect, const char* key)
294 char buf[1024];
295 char* ret;
297 GetPrivateProfileStringA(sect, key, "-", buf, sizeof(buf), resfile);
298 if (buf[0] == '\0' || (buf[0] == '-' && buf[1] == '\0')) return NULL;
299 assert(!(strlen(buf) & 1));
300 ret = decodeA(buf);
301 return ret;
304 /* FIXME: this may be moved to the wtmain.c file, because it may be needed by
305 * others... (windows uses stricmp while Un*x uses strcasecmp...)
307 static int wtstrcasecmp(const char* p1, const char* p2)
309 char c1, c2;
311 c1 = c2 = '@';
312 while (c1 == c2 && c1)
314 c1 = *p1++; c2 = *p2++;
315 if (c1 != c2)
317 c1 = toupper(c1); c2 = toupper(c2);
320 return c1 - c2;
323 static int strCmp(const char* s1, const char* s2, BOOL sensitive)
325 if (!s1 && !s2) return 0;
326 if (!s2) return -1;
327 if (!s1) return 1;
328 return (sensitive) ? strcmp(s1, s2) : wtstrcasecmp(s1, s2);
331 #define okChildString(sect, key, expect) \
332 do { \
333 char* result = getChildString(sect, key); \
334 ok(strCmp(result, expect, 1) == 0, "%s:%s expected %s, got %s", sect, key, expect, result); \
335 } while (0)
337 #define okChildIString(sect, key, expect) \
338 do { \
339 char* result = getChildString(sect, key); \
340 ok(strCmp(result, expect, 0) == 0, "%s:%s expected %s, got %s", sect, key, expect, result); \
341 } while (0)
343 /* using !expect insures that the test will fail if the sect/key isn't present
344 * in result file
346 #define okChildInt(sect, key, expect) \
347 do { \
348 int result = GetPrivateProfileIntA(sect, key, !expect, resfile); \
349 ok(result == expect, "%s:%s expected %d, but got %d\n", sect, key, expect, result); \
350 } while (0)
352 static void test_Startup(void)
354 char buffer[MAX_PATH];
355 PROCESS_INFORMATION info;
356 STARTUPINFOA startup;
358 /* let's start simplistic */
359 memset(&startup, 0, sizeof(startup));
360 startup.cb = sizeof(startup);
361 startup.dwFlags = STARTF_USESHOWWINDOW;
362 startup.wShowWindow = SW_SHOWNORMAL;
364 get_file_name(resfile);
365 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
366 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
367 /* wait for child to terminate */
368 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
369 /* child process has changed result file, so let profile functions know about it */
370 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
372 okChildInt("StartupInfoA", "cb", startup.cb);
373 okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
374 okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
375 okChildInt("StartupInfoA", "dwX", startup.dwX);
376 okChildInt("StartupInfoA", "dwY", startup.dwY);
377 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
378 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
379 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
380 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
381 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
382 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
383 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
384 release_memory();
385 assert(DeleteFileA(resfile) != 0);
387 /* not so simplistic now */
388 memset(&startup, 0, sizeof(startup));
389 startup.cb = sizeof(startup);
390 startup.dwFlags = STARTF_USESHOWWINDOW;
391 startup.wShowWindow = SW_SHOWNORMAL;
392 startup.lpTitle = "I'm the title string";
393 startup.lpDesktop = "I'm the desktop string";
394 startup.dwXCountChars = 0x12121212;
395 startup.dwYCountChars = 0x23232323;
396 startup.dwX = 0x34343434;
397 startup.dwY = 0x45454545;
398 startup.dwXSize = 0x56565656;
399 startup.dwYSize = 0x67676767;
400 startup.dwFillAttribute = 0xA55A;
402 get_file_name(resfile);
403 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
404 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
405 /* wait for child to terminate */
406 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
407 /* child process has changed result file, so let profile functions know about it */
408 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
410 okChildInt("StartupInfoA", "cb", startup.cb);
411 okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
412 okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
413 okChildInt("StartupInfoA", "dwX", startup.dwX);
414 okChildInt("StartupInfoA", "dwY", startup.dwY);
415 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
416 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
417 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
418 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
419 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
420 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
421 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
422 release_memory();
423 assert(DeleteFileA(resfile) != 0);
425 /* not so simplistic now */
426 memset(&startup, 0, sizeof(startup));
427 startup.cb = sizeof(startup);
428 startup.dwFlags = STARTF_USESHOWWINDOW;
429 startup.wShowWindow = SW_SHOWNORMAL;
430 startup.lpTitle = "I'm the title string";
431 startup.lpDesktop = NULL;
432 startup.dwXCountChars = 0x12121212;
433 startup.dwYCountChars = 0x23232323;
434 startup.dwX = 0x34343434;
435 startup.dwY = 0x45454545;
436 startup.dwXSize = 0x56565656;
437 startup.dwYSize = 0x67676767;
438 startup.dwFillAttribute = 0xA55A;
440 get_file_name(resfile);
441 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
442 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
443 /* wait for child to terminate */
444 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
445 /* child process has changed result file, so let profile functions know about it */
446 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
448 okChildInt("StartupInfoA", "cb", startup.cb);
449 okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
450 okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
451 okChildInt("StartupInfoA", "dwX", startup.dwX);
452 okChildInt("StartupInfoA", "dwY", startup.dwY);
453 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
454 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
455 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
456 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
457 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
458 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
459 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
460 release_memory();
461 assert(DeleteFileA(resfile) != 0);
463 /* not so simplistic now */
464 memset(&startup, 0, sizeof(startup));
465 startup.cb = sizeof(startup);
466 startup.dwFlags = STARTF_USESHOWWINDOW;
467 startup.wShowWindow = SW_SHOWNORMAL;
468 startup.lpTitle = "I'm the title string";
469 startup.lpDesktop = "";
470 startup.dwXCountChars = 0x12121212;
471 startup.dwYCountChars = 0x23232323;
472 startup.dwX = 0x34343434;
473 startup.dwY = 0x45454545;
474 startup.dwXSize = 0x56565656;
475 startup.dwYSize = 0x67676767;
476 startup.dwFillAttribute = 0xA55A;
478 get_file_name(resfile);
479 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
480 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
481 /* wait for child to terminate */
482 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
483 /* child process has changed result file, so let profile functions know about it */
484 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
486 okChildInt("StartupInfoA", "cb", startup.cb);
487 todo_wine okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
488 okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
489 okChildInt("StartupInfoA", "dwX", startup.dwX);
490 okChildInt("StartupInfoA", "dwY", startup.dwY);
491 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
492 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
493 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
494 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
495 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
496 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
497 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
498 release_memory();
499 assert(DeleteFileA(resfile) != 0);
501 /* not so simplistic now */
502 memset(&startup, 0, sizeof(startup));
503 startup.cb = sizeof(startup);
504 startup.dwFlags = STARTF_USESHOWWINDOW;
505 startup.wShowWindow = SW_SHOWNORMAL;
506 startup.lpTitle = NULL;
507 startup.lpDesktop = "I'm the desktop string";
508 startup.dwXCountChars = 0x12121212;
509 startup.dwYCountChars = 0x23232323;
510 startup.dwX = 0x34343434;
511 startup.dwY = 0x45454545;
512 startup.dwXSize = 0x56565656;
513 startup.dwYSize = 0x67676767;
514 startup.dwFillAttribute = 0xA55A;
516 get_file_name(resfile);
517 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
518 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
519 /* wait for child to terminate */
520 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
521 /* child process has changed result file, so let profile functions know about it */
522 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
524 okChildInt("StartupInfoA", "cb", startup.cb);
525 okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
526 okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
527 okChildInt("StartupInfoA", "dwX", startup.dwX);
528 okChildInt("StartupInfoA", "dwY", startup.dwY);
529 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
530 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
531 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
532 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
533 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
534 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
535 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
536 release_memory();
537 assert(DeleteFileA(resfile) != 0);
539 /* not so simplistic now */
540 memset(&startup, 0, sizeof(startup));
541 startup.cb = sizeof(startup);
542 startup.dwFlags = STARTF_USESHOWWINDOW;
543 startup.wShowWindow = SW_SHOWNORMAL;
544 startup.lpTitle = "";
545 startup.lpDesktop = "I'm the desktop string";
546 startup.dwXCountChars = 0x12121212;
547 startup.dwYCountChars = 0x23232323;
548 startup.dwX = 0x34343434;
549 startup.dwY = 0x45454545;
550 startup.dwXSize = 0x56565656;
551 startup.dwYSize = 0x67676767;
552 startup.dwFillAttribute = 0xA55A;
554 get_file_name(resfile);
555 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
556 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
557 /* wait for child to terminate */
558 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
559 /* child process has changed result file, so let profile functions know about it */
560 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
562 okChildInt("StartupInfoA", "cb", startup.cb);
563 okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
564 todo_wine okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
565 okChildInt("StartupInfoA", "dwX", startup.dwX);
566 okChildInt("StartupInfoA", "dwY", startup.dwY);
567 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
568 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
569 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
570 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
571 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
572 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
573 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
574 release_memory();
575 assert(DeleteFileA(resfile) != 0);
577 /* not so simplistic now */
578 memset(&startup, 0, sizeof(startup));
579 startup.cb = sizeof(startup);
580 startup.dwFlags = STARTF_USESHOWWINDOW;
581 startup.wShowWindow = SW_SHOWNORMAL;
582 startup.lpTitle = "";
583 startup.lpDesktop = "";
584 startup.dwXCountChars = 0x12121212;
585 startup.dwYCountChars = 0x23232323;
586 startup.dwX = 0x34343434;
587 startup.dwY = 0x45454545;
588 startup.dwXSize = 0x56565656;
589 startup.dwYSize = 0x67676767;
590 startup.dwFillAttribute = 0xA55A;
592 get_file_name(resfile);
593 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
594 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
595 /* wait for child to terminate */
596 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
597 /* child process has changed result file, so let profile functions know about it */
598 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
600 okChildInt("StartupInfoA", "cb", startup.cb);
601 todo_wine okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
602 todo_wine okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
603 okChildInt("StartupInfoA", "dwX", startup.dwX);
604 okChildInt("StartupInfoA", "dwY", startup.dwY);
605 okChildInt("StartupInfoA", "dwXSize", startup.dwXSize);
606 okChildInt("StartupInfoA", "dwYSize", startup.dwYSize);
607 okChildInt("StartupInfoA", "dwXCountChars", startup.dwXCountChars);
608 okChildInt("StartupInfoA", "dwYCountChars", startup.dwYCountChars);
609 okChildInt("StartupInfoA", "dwFillAttribute", startup.dwFillAttribute);
610 okChildInt("StartupInfoA", "dwFlags", startup.dwFlags);
611 okChildInt("StartupInfoA", "wShowWindow", startup.wShowWindow);
612 release_memory();
613 assert(DeleteFileA(resfile) != 0);
615 /* TODO: test for A/W and W/A and W/W */
618 static void test_CommandLine(void)
620 char buffer[MAX_PATH];
621 PROCESS_INFORMATION info;
622 STARTUPINFOA startup;
624 memset(&startup, 0, sizeof(startup));
625 startup.cb = sizeof(startup);
626 startup.dwFlags = STARTF_USESHOWWINDOW;
627 startup.wShowWindow = SW_SHOWNORMAL;
629 /* the basics */
630 get_file_name(resfile);
631 sprintf(buffer, "%s tests/process.c %s \"C:\\Program Files\\my nice app.exe\"", selfname, resfile);
632 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
633 /* wait for child to terminate */
634 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
635 /* child process has changed result file, so let profile functions know about it */
636 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
638 okChildInt("Arguments", "argcA", 4);
639 okChildString("Arguments", "argvA3", "C:\\Program Files\\my nice app.exe");
640 okChildString("Arguments", "argvA4", NULL);
641 okChildString("Arguments", "CommandLineA", buffer);
642 release_memory();
643 assert(DeleteFileA(resfile) != 0);
645 memset(&startup, 0, sizeof(startup));
646 startup.cb = sizeof(startup);
647 startup.dwFlags = STARTF_USESHOWWINDOW;
648 startup.wShowWindow = SW_SHOWNORMAL;
650 /* from Frangois */
651 get_file_name(resfile);
652 sprintf(buffer, "%s tests/process.c %s \"a\\\"b\\\\\" c\\\" d", selfname, resfile);
653 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess");
654 /* wait for child to terminate */
655 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
656 /* child process has changed result file, so let profile functions know about it */
657 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
659 okChildInt("Arguments", "argcA", 6);
660 okChildString("Arguments", "argvA3", "a\"b\\");
661 okChildString("Arguments", "argvA4", "c\"");
662 okChildString("Arguments", "argvA5", "d");
663 okChildString("Arguments", "argvA6", NULL);
664 okChildString("Arguments", "CommandLineA", buffer);
665 release_memory();
666 assert(DeleteFileA(resfile) != 0);
669 static void test_Directory(void)
671 char buffer[MAX_PATH];
672 PROCESS_INFORMATION info;
673 STARTUPINFOA startup;
674 char windir[MAX_PATH];
676 memset(&startup, 0, sizeof(startup));
677 startup.cb = sizeof(startup);
678 startup.dwFlags = STARTF_USESHOWWINDOW;
679 startup.wShowWindow = SW_SHOWNORMAL;
681 /* the basics */
682 get_file_name(resfile);
683 sprintf(buffer, "%s tests/process.c %s", selfname, resfile);
684 GetWindowsDirectoryA( windir, sizeof(windir) );
685 ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, windir, &startup, &info), "CreateProcess");
686 /* wait for child to terminate */
687 ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination");
688 /* child process has changed result file, so let profile functions know about it */
689 WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
691 okChildIString("Misc", "CurrDirA", windir);
692 release_memory();
693 assert(DeleteFileA(resfile) != 0);
696 START_TEST(process)
698 int b = init();
699 ok(b, "Basic init of CreateProcess test");
700 if (!b) return;
702 if (myARGC >= 3)
704 doChild(myARGV[2]);
705 return;
707 test_Startup();
708 test_CommandLine();
709 test_Directory();
711 /* things that can be tested:
712 * lookup: check the way program to be executed is searched
713 * environment: check environment string passing
714 * handles: check the handle inheritance stuff (+sec options)
715 * console: check if console creation parameters work