Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
00baf1a3
Commit
00baf1a3
authored
Apr 21, 2002
by
Eric Pouech
Committed by
Alexandre Julliard
Apr 21, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added a framework for testing CreateProcess and a few tests.
parent
73cef71b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
741 additions
and
0 deletions
+741
-0
Makefile.in
dlls/kernel/Makefile.in
+1
-0
.cvsignore
dlls/kernel/tests/.cvsignore
+1
-0
process.c
dlls/kernel/tests/process.c
+739
-0
No files found.
dlls/kernel/Makefile.in
View file @
00baf1a3
...
...
@@ -43,6 +43,7 @@ CTESTS = \
tests/alloc.c
\
tests/directory.c
\
tests/path.c
\
tests/process.c
\
tests/thread.c
PLTESTS
=
\
...
...
dlls/kernel/tests/.cvsignore
View file @
00baf1a3
...
...
@@ -3,5 +3,6 @@ atom.ok
directory.ok
kernel32_test.spec.c
path.ok
process.ok
testlist.c
thread.ok
dlls/kernel/tests/process.c
0 → 100644
View file @
00baf1a3
/*
* Unit test suite for CreateProcess function.
*
* Copyright 2002 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "winbase.h"
#include "winuser.h"
#include "wine/test.h"
static
char
base
[
MAX_PATH
];
static
char
selfname
[
MAX_PATH
];
static
char
resfile
[
MAX_PATH
];
static
int
myARGC
;
static
char
**
myARGV
;
/* ---------------- portable memory allocation thingie */
static
char
memory
[
16384
];
static
char
*
memory_index
=
memory
;
static
char
*
grab_memory
(
size_t
len
)
{
char
*
ret
=
memory_index
;
/* align on dword */
len
=
(
len
+
3
)
&
~
3
;
memory_index
+=
len
;
assert
(
memory_index
<=
memory
+
sizeof
(
memory
));
return
ret
;
}
static
void
release_memory
(
void
)
{
memory_index
=
memory
;
}
/* ---------------- simplistic tool to encode/decode strings (to hide \ " ' and such) */
static
char
*
encodeA
(
const
char
*
str
)
{
size_t
len
;
char
*
ptr
;
int
i
;
if
(
!
str
)
return
""
;
len
=
strlen
(
str
)
+
1
;
ptr
=
grab_memory
(
len
*
2
+
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
sprintf
(
&
ptr
[
i
*
2
],
"%02x"
,
(
unsigned
char
)
str
[
i
]);
ptr
[
2
*
len
]
=
'\0'
;
return
ptr
;
}
static
char
*
encodeW
(
const
WCHAR
*
str
)
{
size_t
len
;
char
*
ptr
;
int
i
;
if
(
!
str
)
return
""
;
len
=
lstrlenW
(
str
)
+
1
;
ptr
=
grab_memory
(
len
*
4
+
1
);
assert
(
ptr
);
for
(
i
=
0
;
i
<
len
;
i
++
)
sprintf
(
&
ptr
[
i
*
4
],
"%04x"
,
(
unsigned
int
)(
unsigned
short
)
str
[
i
]);
ptr
[
4
*
len
]
=
'\0'
;
return
ptr
;
}
static
unsigned
decode_char
(
char
c
)
{
if
(
c
>=
'0'
&&
c
<=
'9'
)
return
c
-
'0'
;
if
(
c
>=
'a'
&&
c
<=
'f'
)
return
c
-
'a'
+
10
;
assert
(
c
>=
'A'
&&
c
<=
'F'
);
return
c
-
'A'
+
10
;
}
static
char
*
decodeA
(
const
char
*
str
)
{
size_t
len
;
char
*
ptr
;
int
i
;
len
=
strlen
(
str
)
/
2
;
if
(
!
len
--
)
return
NULL
;
ptr
=
grab_memory
(
len
+
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
ptr
[
i
]
=
(
decode_char
(
str
[
2
*
i
])
<<
4
)
|
decode_char
(
str
[
2
*
i
+
1
]);
ptr
[
len
]
=
'\0'
;
return
ptr
;
}
static
WCHAR
*
decodeW
(
const
char
*
str
)
{
size_t
len
;
WCHAR
*
ptr
;
int
i
;
len
=
strlen
(
str
)
/
4
;
if
(
!
len
--
)
return
NULL
;
ptr
=
(
WCHAR
*
)
grab_memory
(
len
*
2
+
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
ptr
[
i
]
=
(
decode_char
(
str
[
4
*
i
])
<<
12
)
|
(
decode_char
(
str
[
4
*
i
+
1
])
<<
8
)
|
(
decode_char
(
str
[
4
*
i
+
2
])
<<
4
)
|
(
decode_char
(
str
[
4
*
i
+
3
])
<<
0
);
ptr
[
len
]
=
'\0'
;
return
ptr
;
}
/******************************************************************
* init
*
* generates basic information like:
* base: absolute path to curr dir
* selfname: the way to reinvoke ourselves
*/
static
int
init
(
void
)
{
myARGC
=
winetest_get_mainargs
(
&
myARGV
);
if
(
!
GetCurrentDirectoryA
(
sizeof
(
base
),
base
))
return
0
;
if
(
strcmp
(
winetest_platform
,
"windows"
))
{
char
*
ptr
=
getenv
(
"WINELOADER"
);
char
*
root
;
if
(
!
ptr
)
return
0
;
root
=
grab_memory
(
strlen
(
ptr
)
+
1
);
strcpy
(
root
,
ptr
);
ptr
=
strrchr
(
root
,
'/'
);
if
(
!
ptr
)
return
0
;
*
ptr
=
'\0'
;
/* be sure to use absolute pathnames so we can change dirs whenever we want */
sprintf
(
selfname
,
"%s/programs/winetest/runtest -q -P wine -M kernel32.dll -T %s -p %s/dlls/kernel/tests/kernel32_test"
,
root
,
root
,
root
);
}
else
{
strcpy
(
selfname
,
myARGV
[
0
]);
}
return
1
;
}
/******************************************************************
* get_file_name
*
* generates an absolute file_name for temporary file
*
*/
static
void
get_file_name
(
char
*
buf
)
{
char
path
[
MAX_PATH
];
buf
[
0
]
=
'\0'
;
GetTempPathA
(
sizeof
(
path
),
path
);
GetTempFileNameA
(
path
,
"wt"
,
0
,
buf
);
}
/******************************************************************
* static void childPrintf
*
*/
static
void
childPrintf
(
HANDLE
h
,
const
char
*
fmt
,
...)
{
va_list
valist
;
char
buffer
[
2048
];
DWORD
w
;
va_start
(
valist
,
fmt
);
vsprintf
(
buffer
,
fmt
,
valist
);
va_end
(
valist
);
WriteFile
(
h
,
buffer
,
strlen
(
buffer
),
&
w
,
NULL
);
}
/******************************************************************
* doChild
*
* output most of the information in the child process
*/
static
void
doChild
(
const
char
*
file
)
{
STARTUPINFOA
siA
;
STARTUPINFOW
siW
;
int
i
;
char
*
ptrA
;
WCHAR
*
ptrW
;
char
bufA
[
MAX_PATH
];
WCHAR
bufW
[
MAX_PATH
];
HANDLE
hFile
=
CreateFileA
(
file
,
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
0
,
0
);
if
(
hFile
==
INVALID_HANDLE_VALUE
)
return
;
/* output of startup info (Ansi) */
GetStartupInfoA
(
&
siA
);
childPrintf
(
hFile
,
"[StartupInfoA]
\n
cb=%08ld
\n
lpDesktop=%s
\n
lpTitle=%s
\n
"
"dwX=%lu
\n
dwY=%lu
\n
dwXSize=%lu
\n
dwYSize=%lu
\n
"
"dwXCountChars=%lu
\n
dwYCountChars=%lu
\n
dwFillAttribute=%lu
\n
"
"dwFlags=%lu
\n
wShowWindow=%u
\n
"
"hStdInput=%lu
\n
hStdOutput=%lu
\n
hStdError=%lu
\n\n
"
,
siA
.
cb
,
encodeA
(
siA
.
lpDesktop
),
encodeA
(
siA
.
lpTitle
),
siA
.
dwX
,
siA
.
dwY
,
siA
.
dwXSize
,
siA
.
dwYSize
,
siA
.
dwXCountChars
,
siA
.
dwYCountChars
,
siA
.
dwFillAttribute
,
siA
.
dwFlags
,
siA
.
wShowWindow
,
(
DWORD
)
siA
.
hStdInput
,
(
DWORD
)
siA
.
hStdOutput
,
(
DWORD
)
siA
.
hStdError
);
/* since GetStartupInfoW is only implemented in win2k,
* zero out before calling so we can notice the difference
*/
memset
(
&
siW
,
0
,
sizeof
(
siW
));
GetStartupInfoW
(
&
siW
);
childPrintf
(
hFile
,
"[StartupInfoW]
\n
cb=%08ld
\n
lpDesktop=%s
\n
lpTitle=%s
\n
"
"dwX=%lu
\n
dwY=%lu
\n
dwXSize=%lu
\n
dwYSize=%lu
\n
"
"dwXCountChars=%lu
\n
dwYCountChars=%lu
\n
dwFillAttribute=%lu
\n
"
"dwFlags=%lu
\n
wShowWindow=%u
\n
"
"hStdInput=%lu
\n
hStdOutput=%lu
\n
hStdError=%lu
\n\n
"
,
siW
.
cb
,
encodeW
(
siW
.
lpDesktop
),
encodeW
(
siW
.
lpTitle
),
siW
.
dwX
,
siW
.
dwY
,
siW
.
dwXSize
,
siW
.
dwYSize
,
siW
.
dwXCountChars
,
siW
.
dwYCountChars
,
siW
.
dwFillAttribute
,
siW
.
dwFlags
,
siW
.
wShowWindow
,
(
DWORD
)
siW
.
hStdInput
,
(
DWORD
)
siW
.
hStdOutput
,
(
DWORD
)
siW
.
hStdError
);
/* Arguments */
childPrintf
(
hFile
,
"[Arguments]
\n
argcA=%d
\n
"
,
myARGC
);
for
(
i
=
0
;
i
<
myARGC
;
i
++
)
{
childPrintf
(
hFile
,
"argvA%d=%s
\n
"
,
i
,
encodeA
(
myARGV
[
i
]));
}
childPrintf
(
hFile
,
"CommandLineA=%s
\n
"
,
encodeA
(
GetCommandLineA
()));
#if 0
int argcW;
WCHAR** argvW;
/* this is part of shell32... and should be tested there */
argvW = CommandLineToArgvW(GetCommandLineW(), &argcW);
for (i = 0; i < argcW; i++)
{
childPrintf(hFile, "argvW%d=%s\n", i, encodeW(argvW[i]));
}
#endif
childPrintf
(
hFile
,
"CommandLineW=%s
\n\n
"
,
encodeW
(
GetCommandLineW
()));
/* output of environment (Ansi) */
ptrA
=
GetEnvironmentStringsA
();
if
(
ptrA
)
{
childPrintf
(
hFile
,
"[EnvironmentA]
\n
"
);
i
=
0
;
while
(
*
ptrA
)
{
if
(
strlen
(
ptrA
)
<
128
)
{
childPrintf
(
hFile
,
"env%d=%s
\n
"
,
i
,
encodeA
(
ptrA
));
i
++
;
}
ptrA
+=
strlen
(
ptrA
)
+
1
;
}
childPrintf
(
hFile
,
"
\n
"
);
}
/* output of environment (Unicode) */
ptrW
=
GetEnvironmentStringsW
();
if
(
ptrW
)
{
childPrintf
(
hFile
,
"[EnvironmentW]
\n
"
);
i
=
0
;
while
(
*
ptrW
)
{
if
(
lstrlenW
(
ptrW
)
<
128
)
{
childPrintf
(
hFile
,
"env%d=%s
\n
"
,
i
,
encodeW
(
ptrW
));
i
++
;
}
ptrW
+=
lstrlenW
(
ptrW
)
+
1
;
}
childPrintf
(
hFile
,
"
\n
"
);
}
childPrintf
(
hFile
,
"[Misc]
\n
"
);
if
(
GetCurrentDirectoryA
(
sizeof
(
bufA
),
bufA
))
childPrintf
(
hFile
,
"CurrDirA=%s
\n
"
,
encodeA
(
bufA
));
if
(
GetCurrentDirectoryW
(
sizeof
(
bufW
)
/
sizeof
(
bufW
[
0
]),
bufW
))
childPrintf
(
hFile
,
"CurrDirW=%s
\n
"
,
encodeW
(
bufW
));
childPrintf
(
hFile
,
"
\n
"
);
CloseHandle
(
hFile
);
}
static
char
*
getChildString
(
const
char
*
sect
,
const
char
*
key
)
{
char
buf
[
1024
];
char
*
ret
;
GetPrivateProfileStringA
(
sect
,
key
,
"-"
,
buf
,
sizeof
(
buf
),
resfile
);
if
(
buf
[
0
]
==
'\0'
||
(
buf
[
0
]
==
'-'
&&
buf
[
1
]
==
'\0'
))
return
NULL
;
assert
(
!
(
strlen
(
buf
)
&
1
));
ret
=
decodeA
(
buf
);
return
ret
;
}
/* FIXME: this may be moved to the wtmain.c file, because it may be needed by
* others... (windows uses stricmp while Un*x uses strcasecmp...)
*/
static
int
wtstrcasecmp
(
const
char
*
p1
,
const
char
*
p2
)
{
char
c1
,
c2
;
c1
=
c2
=
'@'
;
while
(
c1
==
c2
&&
c1
)
{
c1
=
*
p1
++
;
c2
=
*
p2
++
;
if
(
c1
!=
c2
)
{
c1
=
toupper
(
c1
);
c2
=
toupper
(
c2
);
}
}
return
c1
-
c2
;
}
static
int
strCmp
(
const
char
*
s1
,
const
char
*
s2
,
BOOL
sensitive
)
{
if
(
!
s1
&&
!
s2
)
return
0
;
if
(
!
s2
)
return
-
1
;
if
(
!
s1
)
return
1
;
return
(
sensitive
)
?
strcmp
(
s1
,
s2
)
:
wtstrcasecmp
(
s1
,
s2
);
}
#define okChildString(sect, key, expect) \
do { \
char* result = getChildString(sect, key); \
ok(strCmp(result, expect, 1) == 0, "%s:%s expected %s, got %s", sect, key, expect, result); \
} while (0)
#define okChildIString(sect, key, expect) \
do { \
char* result = getChildString(sect, key); \
ok(strCmp(result, expect, 0) == 0, "%s:%s expected %s, got %s", sect, key, expect, result); \
} while (0)
/* using !expect insures that the test will fail if the sect/key isn't present
* in result file
*/
#define okChildInt(sect, key, expect) \
do { \
int result = GetPrivateProfileIntA(sect, key, !expect, resfile); \
ok(result == expect, "%s:%s expected %d, but got %d\n", sect, key, expect, result); \
} while (0)
static
void
test_Startup
(
void
)
{
char
buffer
[
MAX_PATH
];
PROCESS_INFORMATION
info
;
STARTUPINFOA
startup
;
/* let's start simplistic */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
"I'm the title string"
;
startup
.
lpDesktop
=
"I'm the desktop string"
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
"I'm the title string"
;
startup
.
lpDesktop
=
NULL
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
"I'm the title string"
;
startup
.
lpDesktop
=
""
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
todo_wine
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
NULL
;
startup
.
lpDesktop
=
"I'm the desktop string"
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
""
;
startup
.
lpDesktop
=
"I'm the desktop string"
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
todo_wine
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* not so simplistic now */
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
startup
.
lpTitle
=
""
;
startup
.
lpDesktop
=
""
;
startup
.
dwXCountChars
=
0x12121212
;
startup
.
dwYCountChars
=
0x23232323
;
startup
.
dwX
=
0x34343434
;
startup
.
dwY
=
0x45454545
;
startup
.
dwXSize
=
0x56565656
;
startup
.
dwYSize
=
0x67676767
;
startup
.
dwFillAttribute
=
0xA55A
;
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"StartupInfoA"
,
"cb"
,
startup
.
cb
);
todo_wine
okChildString
(
"StartupInfoA"
,
"lpDesktop"
,
startup
.
lpDesktop
);
todo_wine
okChildString
(
"StartupInfoA"
,
"lpTitle"
,
startup
.
lpTitle
);
okChildInt
(
"StartupInfoA"
,
"dwX"
,
startup
.
dwX
);
okChildInt
(
"StartupInfoA"
,
"dwY"
,
startup
.
dwY
);
okChildInt
(
"StartupInfoA"
,
"dwXSize"
,
startup
.
dwXSize
);
okChildInt
(
"StartupInfoA"
,
"dwYSize"
,
startup
.
dwYSize
);
okChildInt
(
"StartupInfoA"
,
"dwXCountChars"
,
startup
.
dwXCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwYCountChars"
,
startup
.
dwYCountChars
);
okChildInt
(
"StartupInfoA"
,
"dwFillAttribute"
,
startup
.
dwFillAttribute
);
okChildInt
(
"StartupInfoA"
,
"dwFlags"
,
startup
.
dwFlags
);
okChildInt
(
"StartupInfoA"
,
"wShowWindow"
,
startup
.
wShowWindow
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
/* TODO: test for A/W and W/A and W/W */
}
static
void
test_CommandLine
(
void
)
{
char
buffer
[
MAX_PATH
];
PROCESS_INFORMATION
info
;
STARTUPINFOA
startup
;
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
/* the basics */
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s
\"
C:
\\
Program Files
\\
my nice app.exe
\"
"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"Arguments"
,
"argcA"
,
4
);
okChildString
(
"Arguments"
,
"argvA3"
,
"C:
\\
Program Files
\\
my nice app.exe"
);
okChildString
(
"Arguments"
,
"argvA4"
,
NULL
);
okChildString
(
"Arguments"
,
"CommandLineA"
,
buffer
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
/* from Frangois */
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s
\"
a
\\\"
b
\\\\\"
c
\\\"
d"
,
selfname
,
resfile
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
NULL
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildInt
(
"Arguments"
,
"argcA"
,
6
);
okChildString
(
"Arguments"
,
"argvA3"
,
"a
\"
b
\\
"
);
okChildString
(
"Arguments"
,
"argvA4"
,
"c
\"
"
);
okChildString
(
"Arguments"
,
"argvA5"
,
"d"
);
okChildString
(
"Arguments"
,
"argvA6"
,
NULL
);
okChildString
(
"Arguments"
,
"CommandLineA"
,
buffer
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
}
static
void
test_Directory
(
void
)
{
char
buffer
[
MAX_PATH
];
PROCESS_INFORMATION
info
;
STARTUPINFOA
startup
;
char
windir
[
MAX_PATH
];
memset
(
&
startup
,
0
,
sizeof
(
startup
));
startup
.
cb
=
sizeof
(
startup
);
startup
.
dwFlags
=
STARTF_USESHOWWINDOW
;
startup
.
wShowWindow
=
SW_SHOWNORMAL
;
/* the basics */
get_file_name
(
resfile
);
sprintf
(
buffer
,
"%s tests/process.c %s"
,
selfname
,
resfile
);
GetWindowsDirectoryA
(
windir
,
sizeof
(
windir
)
);
ok
(
CreateProcessA
(
NULL
,
buffer
,
NULL
,
NULL
,
FALSE
,
0L
,
NULL
,
windir
,
&
startup
,
&
info
),
"CreateProcess"
);
/* wait for child to terminate */
ok
(
WaitForSingleObject
(
info
.
hProcess
,
30000
)
==
WAIT_OBJECT_0
,
"Child process termination"
);
/* child process has changed result file, so let profile functions know about it */
WritePrivateProfileStringA
(
NULL
,
NULL
,
NULL
,
resfile
);
okChildIString
(
"Misc"
,
"CurrDirA"
,
windir
);
release_memory
();
assert
(
DeleteFileA
(
resfile
)
!=
0
);
}
START_TEST
(
process
)
{
int
b
=
init
();
ok
(
b
,
"Basic init of CreateProcess test"
);
if
(
!
b
)
return
;
if
(
myARGC
>=
3
)
{
doChild
(
myARGV
[
2
]);
return
;
}
test_Startup
();
test_CommandLine
();
test_Directory
();
/* things that can be tested:
* lookup: check the way program to be executed is searched
* environment: check environment string passing
* handles: check the handle inheritance stuff (+sec options)
* console: check if console creation parameters work
*/
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment