Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2020
- 72 participants
- 969 discussions
24 Mar '20
This check is essentially validating that the hardcoded state_table[]
has reasonable values for the shader constant states. Use ARRAY_SIZE()
to avoid warnings if the compiler chooses an unsigned integer to back
enum SHADER_CONSTANT_TYPE.
Based on an idea by Henri Verbeet.
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/d3dx9_36/effect.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 88168df1e1a..525b87340bf 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -1469,11 +1469,7 @@ static HRESULT d3dx_set_shader_const_state(struct d3dx_effect *effect, enum SHAD
D3DXVECTOR4 value;
HRESULT ret;
- if (op < 0 || op > SCT_PSINT)
- {
- FIXME("Unknown op %u.\n", op);
- return D3DERR_INVALIDCALL;
- }
+ assert(op < ARRAY_SIZE(const_tbl));
element_count = param->bytes / const_tbl[op].elem_size;
TRACE("%s, index %u, element_count %u.\n", const_tbl[op].name, index, element_count);
if (param->type != const_tbl[op].type)
--
2.24.1
2
1
This stops a compile on the macos.
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/ntdll/file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 1a5f86d7c2..fd2f17dc72 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -139,7 +139,7 @@ static inline ULONG get_file_attributes( const struct stat *st )
static BOOL fd_is_mount_point( int fd, const struct stat *st )
{
struct stat parent;
- return S_ISDIR( st->st_mode ) && !fstatat( fd, "..", &parent, 0 )
+ return S_ISDIR( st->st_mode ) && !lstat( "..", &parent)
&& (parent.st_dev != st->st_dev || parent.st_ino == st->st_ino);
}
--
2.25.1
4
4
[PATCH] kernel32/tests: Fix the grammar and formatting of a process comment.
by Francois Gouget 24 Mar '20
by Francois Gouget 24 Mar '20
24 Mar '20
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/kernel32/tests/process.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 7f7c0159473..32818042337 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3312,9 +3312,10 @@ static void test_SuspendProcessState(void)
ok(pipe_magic == pipe_write_magic, "Did not get the correct magic from the remote process\n");
- /* Validate the Imports, at this point the thread in the new process should have
- initialized the EXE module imports and call each dll DllMain notifying it on
- the new thread in the process. */
+ /* Validate the imports: at this point the thread in the new process
+ * should have initialized the EXE module imports and called each dll's
+ * DllMain(), notifying it of the new thread in the process.
+ */
ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
ok(ret, "EXE IAT is not resolved\n");
--
2.20.1
2
1
24 Mar '20
Signed-off-by: Sven Baars <sbaars(a)codeweavers.com>
---
v2: Added DT_CALCRECT, added some tests to show that the recursive call is
useful (we have to handle things like DT_WORDBREAK to compute the rect), fixed
indentation.
dlls/d3dx9_36/font.c | 30 ++++++++++++++++++++++++------
dlls/d3dx9_36/tests/core.c | 29 +++++++++++++++++++++++++++--
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/font.c b/dlls/d3dx9_36/font.c
index 3645903367..56efb11dfd 100644
--- a/dlls/d3dx9_36/font.c
+++ b/dlls/d3dx9_36/font.c
@@ -603,12 +603,12 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
{
struct d3dx_font *font = impl_from_ID3DXFont(iface);
+ RECT calcrect, textrect = {0};
ID3DXSprite *target = sprite;
- WCHAR *line;
- RECT textrect = {0};
int lh, x, y, width;
int max_width = 0;
int ret = 0;
+ WCHAR *line;
SIZE size;
TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x.\n",
@@ -641,9 +641,27 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
textrect = *rect;
}
- x = textrect.left;
- y = textrect.top;
- width = textrect.right - textrect.left;
+ calcrect = textrect;
+
+ if (format & (DT_VCENTER | DT_BOTTOM))
+ {
+ y = ID3DXFont_DrawTextW(iface, NULL, string, count, &calcrect,
+ (format & ~DT_BOTTOM & ~DT_VCENTER) | DT_CALCRECT, 0);
+
+ if (format & DT_VCENTER)
+ {
+ calcrect.top = textrect.top + (textrect.bottom - textrect.top - y) / 2;
+ calcrect.bottom = calcrect.top + y;
+ }
+ else if (format & DT_BOTTOM)
+ {
+ calcrect.top = textrect.bottom - y;
+ }
+ }
+
+ x = calcrect.left;
+ y = calcrect.top;
+ width = calcrect.right - calcrect.left;
lh = font->metrics.tmHeight;
@@ -718,7 +736,7 @@ static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite,
if (format & DT_CALCRECT)
{
- *rect = textrect;
+ *rect = calcrect;
rect->bottom = y;
rect->right = rect->left + max_width;
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index 6fae8bf8d5..9916fa9bc2 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -837,10 +837,10 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
ok(height == 36, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_BOTTOM, 0xff00ff);
- todo_wine ok(height == 40, "Got unexpected height %d.\n", height);
+ ok(height == 40, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_VCENTER, 0xff00ff);
- todo_wine ok(height == 32, "Got unexpected height %d.\n", height);
+ ok(height == 32, "Got unexpected height %d.\n", height);
height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_RIGHT, 0xff00ff);
ok(height == 24, "Got unexpected height %d.\n", height);
@@ -853,6 +853,31 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
ok(height == 24, "Got unexpected height %d.\n", height);
check_rect(&rect, 10, 10, 30, 34);
+ SetRect(&rect, 10, 10, 50, 50);
+ height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_WORDBREAK | DT_CALCRECT, 0xff00ff);
+ ok(height == 24, "Got unexpected height %d.\n", height);
+ check_rect(&rect, 10, 10, 30, 34);
+
+ SetRect(&rect, 10, 10, 50, 50);
+ height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_BOTTOM | DT_CALCRECT, 0xff00ff);
+ ok(height == 40, "Got unexpected height %d.\n", height);
+ check_rect(&rect, 10, 26, 30, 50);
+
+ SetRect(&rect, 10, 10, 50, 50);
+ height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_BOTTOM | DT_WORDBREAK | DT_CALCRECT, 0xff00ff);
+ ok(height == 40, "Got unexpected height %d.\n", height);
+ check_rect(&rect, 10, 26, 30, 50);
+
+ SetRect(&rect, 10, 10, 50, 50);
+ height = ID3DXFont_DrawTextW(font, NULL, L"aaaa\naaaa", -1, &rect, DT_VCENTER | DT_CALCRECT, 0xff00ff);
+ ok(height == 32, "Got unexpected height %d.\n", height);
+ check_rect(&rect, 10, 18, 30, 42);
+
+ SetRect(&rect, 10, 10, 50, 50);
+ height = ID3DXFont_DrawTextW(font, NULL, L"aaaa aaaa", -1, &rect, DT_VCENTER | DT_WORDBREAK | DT_CALCRECT, 0xff00ff);
+ ok(height == 32, "Got unexpected height %d.\n", height);
+ check_rect(&rect, 10, 18, 30, 42);
+
ID3DXFont_Release(font);
}
--
2.24.0
4
8
24 Mar '20
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=48731
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/d3dx9_36/surface.c | 12 +++++
dlls/d3dx9_36/tests/surface.c | 92 +++++++++++++++++++++++++++++++++++
2 files changed, 104 insertions(+)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index e2b398345c..22a872b5fd 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -108,6 +108,7 @@ static const GUID *d3dformat_to_wic_guid(D3DFORMAT format)
#define DDS_PF_ALPHA 0x1
#define DDS_PF_ALPHA_ONLY 0x2
#define DDS_PF_FOURCC 0x4
+#define DDS_PF_PALETTE8 0x20
#define DDS_PF_RGB 0x40
#define DDS_PF_YUV 0x200
#define DDS_PF_LUMINANCE 0x20000
@@ -349,6 +350,15 @@ static D3DFORMAT dds_alpha_to_d3dformat(const struct dds_pixel_format *pixel_for
return D3DFMT_UNKNOWN;
}
+static D3DFORMAT dds_palette_to_d3dformat(const struct dds_pixel_format *pixel_format)
+{
+ if (pixel_format->bpp == 8)
+ return D3DFMT_P8;
+
+ WARN("Unknown palette pixel format (%u).\n", pixel_format->bpp);
+ return D3DFMT_UNKNOWN;
+}
+
static D3DFORMAT dds_bump_to_d3dformat(const struct dds_pixel_format *pixel_format)
{
if (pixel_format->bpp == 16 && pixel_format->rmask == 0x00ff && pixel_format->gmask == 0xff00)
@@ -381,6 +391,8 @@ static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pi
if (pixel_format->flags & DDS_PF_FOURCC)
return dds_fourcc_to_d3dformat(pixel_format->fourcc);
+ if (pixel_format->flags & DDS_PF_PALETTE8)
+ return dds_palette_to_d3dformat(pixel_format);
if (pixel_format->flags & DDS_PF_RGB)
return dds_rgb_to_d3dformat(pixel_format);
if (pixel_format->flags & DDS_PF_LUMINANCE)
diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c
index d5d3d6d211..e9b9e04178 100644
--- a/dlls/d3dx9_36/tests/surface.c
+++ b/dlls/d3dx9_36/tests/surface.c
@@ -107,6 +107,87 @@ static const unsigned char noimage[4] = {
0x11,0x22,0x33,0x44
};
+/* 16x4 8-bit dds */
+static const unsigned char dds_8bit[] =
+{
+ 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x47,0x49,0x4d,0x50,0x2d,0x44,0x44,0x53,0x5a,0x09,0x03,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,
+ 0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0xec,0x27,0x00,0xff,0x8c,0xcd,0x12,0xff,
+ 0x78,0x01,0x14,0xff,0x50,0xcd,0x12,0xff,0x00,0x3d,0x8c,0xff,0x02,0x00,0x00,0xff,
+ 0x47,0x00,0x00,0xff,0xda,0x07,0x02,0xff,0x50,0xce,0x12,0xff,0xea,0x11,0x01,0xff,
+ 0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x08,0x3d,0x8c,0xff,0x08,0x01,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x60,0xcc,0x12,0xff,
+ 0xa1,0xb2,0xd4,0xff,0xda,0x07,0x02,0xff,0x47,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0x50,0xce,0x12,0xff,0x00,0x00,0x14,0xff,0xa8,0xcc,0x12,0xff,0x3c,0xb2,0xd4,0xff,
+ 0xda,0x07,0x02,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x01,0xff,
+ 0x21,0x00,0x00,0xff,0xd8,0xcb,0x12,0xff,0x54,0xcd,0x12,0xff,0x8b,0x4f,0xd5,0xff,
+ 0x00,0x04,0xda,0xff,0x00,0x00,0x00,0xff,0x3d,0x04,0x91,0xff,0x70,0xce,0x18,0xff,
+ 0xb4,0xcc,0x12,0xff,0x6b,0x4e,0xd5,0xff,0xb0,0xcc,0x12,0xff,0x00,0x00,0x00,0xff,
+ 0xc8,0x05,0x91,0xff,0x98,0xc7,0xcc,0xff,0x7c,0xcd,0x12,0xff,0x51,0x05,0x91,0xff,
+ 0x48,0x07,0x14,0xff,0x6d,0x05,0x91,0xff,0x00,0x07,0xda,0xff,0xa0,0xc7,0xcc,0xff,
+ 0x00,0x07,0xda,0xff,0x3a,0x77,0xd5,0xff,0xda,0x07,0x02,0xff,0x7c,0x94,0xd4,0xff,
+ 0xe0,0xce,0xd6,0xff,0x0a,0x80,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0x78,0x9a,0xab,0xff,0xde,0x08,0x18,0xff,0xda,0x07,0x02,0xff,0x30,0x00,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x50,0xce,0x12,0xff,0x8c,0xcd,0x12,0xff,0xd0,0xb7,0xd8,0xff,
+ 0x00,0x00,0x00,0xff,0x60,0x32,0xd9,0xff,0x30,0xc1,0x1a,0xff,0xa8,0xcd,0x12,0xff,
+ 0xa4,0xcd,0x12,0xff,0xc0,0x1d,0x4b,0xff,0x46,0x71,0x0e,0xff,0xc0,0x1d,0x4b,0xff,
+ 0x09,0x87,0xd4,0xff,0x00,0x00,0x00,0xff,0xf6,0x22,0x00,0xff,0x64,0xcd,0x12,0xff,
+ 0x00,0x00,0x00,0xff,0xca,0x1d,0x4b,0xff,0x09,0x87,0xd4,0xff,0xaa,0x02,0x05,0xff,
+ 0x82,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xc0,0x1d,0x4b,0xff,
+ 0xcd,0xab,0xba,0xff,0x00,0x00,0x00,0xff,0xa4,0xcd,0x12,0xff,0xc0,0x1d,0x4b,0xff,
+ 0xd4,0xcd,0x12,0xff,0xa6,0x4c,0xd5,0xff,0x00,0xf0,0xfd,0xff,0xd4,0xcd,0x12,0xff,
+ 0xf4,0x4c,0xd5,0xff,0x90,0xcd,0x12,0xff,0xc2,0x4c,0xd5,0xff,0x82,0x00,0x00,0xff,
+ 0xaa,0x02,0x05,0xff,0x88,0xd4,0xba,0xff,0x14,0x00,0x00,0xff,0x01,0x00,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x10,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0x0c,0x08,0x13,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0xd0,0xcd,0x12,0xff,0xc6,0x84,0xf1,0xff,0x7c,0x84,0xf1,0xff,0x20,0x20,0xf5,0xff,
+ 0x00,0x00,0x0a,0xff,0xf0,0xb0,0x94,0xff,0x64,0x6c,0xf1,0xff,0x85,0x6c,0xf1,0xff,
+ 0x8b,0x4f,0xd5,0xff,0x00,0x04,0xda,0xff,0x88,0xd4,0xba,0xff,0x82,0x00,0x00,0xff,
+ 0x39,0xde,0xd4,0xff,0x10,0x50,0xd5,0xff,0xaa,0x02,0x05,0xff,0x00,0x00,0x00,0xff,
+ 0x4f,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x5c,0xce,0x12,0xff,0x00,0x00,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x5c,0xce,0x12,0xff,
+ 0xaa,0x02,0x05,0xff,0x4c,0xce,0x12,0xff,0x39,0xe6,0xd4,0xff,0x00,0x00,0x00,0xff,
+ 0x82,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x5b,0xe6,0xd4,0xff,0x00,0x00,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x68,0x50,0xcd,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0x00,0x00,0x00,0xff,0x10,0x00,0x00,0xff,0xe3,0xea,0x90,0xff,0x5c,0xce,0x12,0xff,
+ 0x18,0x00,0x00,0xff,0x88,0xd4,0xba,0xff,0x82,0x00,0x00,0xff,0x00,0x00,0x00,0xff,
+ 0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
+};
+
/* 2x2 24-bit dds, 2 mipmaps */
static const unsigned char dds_24bit[] = {
0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
@@ -650,6 +731,17 @@ static void test_D3DXGetImageInfo(void)
ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
} else skip("Couldn't get image info from 16-bit DDS file in memory\n");
+ memset(&info, 0, sizeof(info));
+ hr = D3DXGetImageInfoFromFileInMemory(dds_8bit, sizeof(dds_8bit), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x\n", hr);
+ ok(info.Width == 16, "Got width %u.\n", info.Width);
+ ok(info.Height == 4, "Got height %u.\n", info.Height);
+ ok(info.Depth == 1, "Got depth %u.\n", info.Depth);
+ ok(info.MipLevels == 1, "Got miplevels %u.\n", info.MipLevels);
+ ok(info.Format == D3DFMT_P8, "Got format %#x.\n", info.Format);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x.\n", info.ResourceType);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x.\n", info.ImageFileFormat);
+
hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map), &info);
ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
if (hr == D3D_OK) {
--
2.25.1
2
1
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/d3dcompiler_43/hlsl.y | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 4f5a7b1782c..4c3e96caa0d 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -1257,7 +1257,7 @@ struct_declaration: var_modifiers struct_spec variables_def_optional ';'
{
if (!$2->name)
{
- hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR,
+ hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR,
"anonymous struct declaration with no variables");
}
if (modifiers)
--
2.25.1
4
11
24 Mar '20
From: Connor McAdams <conmanx360(a)gmail.com>
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/d3d10/d3d10_private.h | 5 ++
dlls/d3d10/effect.c | 111 ++++++++++++++++++++++++++++++++++---
2 files changed, 108 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index f83ff0d4c94..e02ea376bb6 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -61,6 +61,11 @@ enum d3d10_effect_object_operation
D3D10_EOO_ANONYMOUS_SHADER = 7,
};
+struct d3d10_matrix
+{
+ float m[4][4];
+};
+
struct d3d10_effect_object
{
struct d3d10_effect_pass *pass;
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 9f92b590bcd..f843b65bb83 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -5073,8 +5073,91 @@ static const struct ID3D10EffectVectorVariableVtbl d3d10_effect_vector_variable_
d3d10_effect_vector_variable_GetFloatVectorArray,
};
+static void write_matrix_to_buffer(struct d3d10_effect_variable *variable, void *dst_void,
+ struct d3d10_matrix *src, BOOL transpose)
+{
+ unsigned int col_count = !transpose ? variable->type->column_count : variable->type->row_count;
+ unsigned int row_count = !transpose ? variable->type->row_count : variable->type->column_count;
+ BOOL major = variable->type->type_class == D3D10_SVC_MATRIX_COLUMNS ? TRUE : FALSE;
+ float *dst = dst_void;
+ unsigned int row, col;
+
+ if (transpose)
+ major = !major;
+
+ if (major)
+ {
+ for (col = 0; col < col_count; ++col)
+ {
+ for (row = 0; row < row_count; ++row)
+ dst[(col * 4) + row] = src->m[row][col];
+ }
+ }
+ else
+ {
+ for (row = 0; row < row_count; ++row)
+ {
+ for (col = 0; col < col_count; ++col)
+ dst[(row * 4) + col] = src->m[row][col];
+ }
+ }
+}
+
+static void write_matrix_variable_to_buffer(struct d3d10_effect_variable *variable, void *src_data, BOOL transpose)
+{
+ BYTE *dst = variable->buffer->u.buffer.local_buffer + variable->buffer_offset;
+
+ write_matrix_to_buffer(variable, dst, src_data, transpose);
+
+ variable->buffer->u.buffer.changed = TRUE;
+}
+
+static void write_matrix_variable_array_to_buffer(struct d3d10_effect_variable *variable, void *src_data,
+ unsigned int offset, unsigned int count, BOOL transpose)
+{
+ BYTE *dst = variable->buffer->u.buffer.local_buffer + variable->buffer_offset;
+ struct d3d10_matrix *src = src_data;
+ unsigned int i;
+
+ if (!variable->type->element_count)
+ {
+ write_matrix_variable_to_buffer(variable, src_data, transpose);
+ return;
+ }
+
+ if (offset >= variable->type->element_count)
+ {
+ WARN("Offset %u larger than element count %u, ignoring.\n", offset, variable->type->element_count);
+ return;
+ }
+
+ if (count > variable->type->element_count - offset)
+ {
+ WARN("Offset %u, count %u overruns the variable (element count %u), fixing up.\n",
+ offset, count, variable->type->element_count);
+ count = variable->type->element_count - offset;
+ }
+
+ if (offset)
+ dst += variable->type->stride * offset;
+
+ for (i = 0; i < count; ++i)
+ {
+ write_matrix_to_buffer(variable, dst, &src[i], transpose);
+
+ dst += variable->type->stride;
+ }
+
+ variable->buffer->u.buffer.changed = TRUE;
+}
+
/* ID3D10EffectVariable methods */
+static inline struct d3d10_effect_variable *impl_from_ID3D10EffectMatrixVariable(ID3D10EffectMatrixVariable *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d10_effect_variable, ID3D10EffectVariable_iface);
+}
+
static BOOL STDMETHODCALLTYPE d3d10_effect_matrix_variable_IsValid(ID3D10EffectMatrixVariable *iface)
{
TRACE("iface %p\n", iface);
@@ -5231,9 +5314,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetRawValue(ID3D10
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrix(ID3D10EffectMatrixVariable *iface,
float *data)
{
- FIXME("iface %p, data %p stub!\n", iface, data);
+ struct d3d10_effect_variable *var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, data %p.\n", iface, data);
+ write_matrix_variable_to_buffer(var, data, FALSE);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10EffectMatrixVariable *iface,
@@ -5247,9 +5333,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrix(ID3D10Ef
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixArray(ID3D10EffectMatrixVariable *iface,
float *data, UINT offset, UINT count)
{
- FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count);
+ struct d3d10_effect_variable *var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count);
+ write_matrix_variable_array_to_buffer(var, data, offset, count, FALSE);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3D10EffectMatrixVariable *iface,
@@ -5263,9 +5352,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixArray(ID3
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTranspose(ID3D10EffectMatrixVariable *iface,
float *data)
{
- FIXME("iface %p, data %p stub!\n", iface, data);
+ struct d3d10_effect_variable *var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, data %p.\n", iface, data);
+ write_matrix_variable_to_buffer(var, data, TRUE);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose(ID3D10EffectMatrixVariable *iface,
@@ -5279,9 +5371,12 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTranspose
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_SetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface,
float *data, UINT offset, UINT count)
{
- FIXME("iface %p, data %p, offset %u, count %u stub!\n", iface, data, offset, count);
+ struct d3d10_effect_variable *var = impl_from_ID3D10EffectMatrixVariable(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count);
+ write_matrix_variable_array_to_buffer(var, data, offset, count, TRUE);
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d10_effect_matrix_variable_GetMatrixTransposeArray(ID3D10EffectMatrixVariable *iface,
--
2.24.1
1
2
For Project Cars.
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/d3dx11_42/d3dx11_42.spec | 4 ++--
dlls/d3dx11_43/d3dx11_43.spec | 4 ++--
dlls/d3dx11_43/main.c | 22 ++++++++++++++++++++++
include/d3dx11tex.h | 4 ++++
4 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx11_42/d3dx11_42.spec b/dlls/d3dx11_42/d3dx11_42.spec
index 30bdba4244..99a38557b8 100644
--- a/dlls/d3dx11_42/d3dx11_42.spec
+++ b/dlls/d3dx11_42/d3dx11_42.spec
@@ -27,8 +27,8 @@
@ stub D3DX11CreateTextureFromResourceW
@ stub D3DX11CreateThreadPump
@ stdcall D3DX11FilterTexture(ptr ptr long long)
-@ stub D3DX11GetImageInfoFromFileA
-@ stub D3DX11GetImageInfoFromFileW
+@ stdcall D3DX11GetImageInfoFromFileA(str ptr ptr ptr)
+@ stdcall D3DX11GetImageInfoFromFileW(wstr ptr ptr ptr)
@ stdcall D3DX11GetImageInfoFromMemory(ptr long ptr ptr ptr)
@ stub D3DX11GetImageInfoFromResourceA
@ stub D3DX11GetImageInfoFromResourceW
diff --git a/dlls/d3dx11_43/d3dx11_43.spec b/dlls/d3dx11_43/d3dx11_43.spec
index 30bdba4244..99a38557b8 100644
--- a/dlls/d3dx11_43/d3dx11_43.spec
+++ b/dlls/d3dx11_43/d3dx11_43.spec
@@ -27,8 +27,8 @@
@ stub D3DX11CreateTextureFromResourceW
@ stub D3DX11CreateThreadPump
@ stdcall D3DX11FilterTexture(ptr ptr long long)
-@ stub D3DX11GetImageInfoFromFileA
-@ stub D3DX11GetImageInfoFromFileW
+@ stdcall D3DX11GetImageInfoFromFileA(str ptr ptr ptr)
+@ stdcall D3DX11GetImageInfoFromFileW(wstr ptr ptr ptr)
@ stdcall D3DX11GetImageInfoFromMemory(ptr long ptr ptr ptr)
@ stub D3DX11GetImageInfoFromResourceA
@ stub D3DX11GetImageInfoFromResourceW
diff --git a/dlls/d3dx11_43/main.c b/dlls/d3dx11_43/main.c
index 215a51b715..e8eac58cbb 100644
--- a/dlls/d3dx11_43/main.c
+++ b/dlls/d3dx11_43/main.c
@@ -58,6 +58,28 @@ HRESULT WINAPI D3DX11FilterTexture(ID3D11DeviceContext *context, ID3D11Resource
return E_NOTIMPL;
}
+HRESULT WINAPI D3DX11GetImageInfoFromFileA(const char *filename, ID3DX11ThreadPump *pump, D3DX11_IMAGE_INFO *img_info,
+ HRESULT *hresult)
+{
+ FIXME("filename %s, pump %p, img_info %p, hresult %p stub!\n", debugstr_a(filename), pump, img_info, hresult);
+
+ if (!filename)
+ return E_FAIL;
+
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI D3DX11GetImageInfoFromFileW(const WCHAR *filename, ID3DX11ThreadPump *pump, D3DX11_IMAGE_INFO *img_info,
+ HRESULT *hresult)
+{
+ FIXME("filename %s, pump %p, img_info %p, hresult %p stub!\n", debugstr_w(filename), pump, img_info, hresult);
+
+ if (!filename)
+ return E_FAIL;
+
+ return E_NOTIMPL;
+}
+
HRESULT WINAPI D3DX11GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX11ThreadPump *pump,
D3DX11_IMAGE_INFO *img_info, HRESULT *hresult)
{
diff --git a/include/d3dx11tex.h b/include/d3dx11tex.h
index b7c00ac4fd..c8a47925c8 100644
--- a/include/d3dx11tex.h
+++ b/include/d3dx11tex.h
@@ -119,6 +119,10 @@ HRESULT WINAPI D3DX11CreateTextureFromFileW(ID3D11Device *device, const WCHAR *f
HRESULT WINAPI D3DX11CreateTextureFromMemory(ID3D11Device *device, const void *src_data, SIZE_T src_data_size,
D3DX11_IMAGE_LOAD_INFO *loadinfo, ID3DX11ThreadPump *pump, ID3D11Resource **texture, HRESULT *hresult);
HRESULT WINAPI D3DX11FilterTexture(ID3D11DeviceContext *context, ID3D11Resource *texture, UINT src_level, UINT filter);
+HRESULT WINAPI D3DX11GetImageInfoFromFileA(const char *filename, ID3DX11ThreadPump *pump, D3DX11_IMAGE_INFO *img_info,
+ HRESULT *hresult);
+HRESULT WINAPI D3DX11GetImageInfoFromFileW(const WCHAR *filename, ID3DX11ThreadPump *pump, D3DX11_IMAGE_INFO *img_info,
+ HRESULT *hresult);
HRESULT WINAPI D3DX11GetImageInfoFromMemory(const void *src_data, SIZE_T src_data_size, ID3DX11ThreadPump *pump,
D3DX11_IMAGE_INFO *img_info, HRESULT *hresult);
HRESULT WINAPI D3DX11SaveTextureToFileA(ID3D11DeviceContext *context, ID3D11Resource *texture,
--
2.24.1
2
1
24 Mar '20
wait_and_close_child_process() simplifies waiting for the child process
and closing its handles. And because it uses wait_child_process() this
ensures that any error happening in the child process is detected.
reload_child_dump() wraps a cryptic WritePrivateProfileStringA() call
and avoids having to add a comment every time.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
v2: Removed the exit code check in test_SuspendProcessState() and
document the reason. Also document why we can check the exit code in
test_SuspendProcessNewThread().
dlls/kernel32/tests/process.c | 284 ++++++++++++----------------------
1 file changed, 99 insertions(+), 185 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 0f0889073b0..7f7c0159473 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -203,6 +203,21 @@ static WCHAR* decodeW(const char* str)
return ptr;
}
+static void wait_and_close_child_process(PROCESS_INFORMATION *pi)
+{
+ wait_child_process(pi->hProcess);
+ CloseHandle(pi->hThread);
+ CloseHandle(pi->hProcess);
+}
+
+static void reload_child_info(const char* resfile)
+{
+ /* This forces the profile functions to reload the resource file
+ * after the child process has modified it.
+ */
+ WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+}
+
/******************************************************************
* init
*
@@ -615,13 +630,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
GetStartupInfoA(&si);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
@@ -655,13 +666,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -695,13 +702,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -735,13 +738,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -775,13 +774,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -817,13 +812,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -857,13 +848,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -920,13 +907,9 @@ static void test_CommandLine(void)
ok(startup.lpTitle == NULL, "lpTitle is not NULL\n");
ok(startup.dwFlags == STARTF_USESHOWWINDOW, "unexpected dwFlags %04x\n", startup.dwFlags);
ok(startup.wShowWindow == SW_SHOWNORMAL, "unexpected wShowWindow %d\n", startup.wShowWindow);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("Arguments", "argcA", 5);
okChildString("Arguments", "argvA4", "C:\\Program Files\\my nice app.exe");
okChildString("Arguments", "argvA5", NULL);
@@ -938,13 +921,9 @@ static void test_CommandLine(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\" \"a\\\"b\\\\\" c\\\" d", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("Arguments", "argcA", 7);
okChildString("Arguments", "argvA4", "a\"b\\");
okChildString("Arguments", "argvA5", "c\"");
@@ -963,12 +942,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
sprintf(buffer, "./%s", exename);
okChildInt("Arguments", "argcA", 5);
okChildString("Arguments", "argvA0", buffer);
@@ -983,12 +959,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
sprintf(buffer, ".\\%s", exename);
okChildString("Arguments", "argvA0", buffer);
release_memory();
@@ -1005,12 +978,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
if (p) sprintf(buffer, "..%s/%s", p, exename);
else sprintf(buffer, "./%s", exename);
okChildString("Arguments", "argvA0", buffer);
@@ -1030,12 +1000,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildString("Arguments", "argvA0", "dummy");
okChildString("Arguments", "CommandLineA", buffer2);
okChildStringWA("Arguments", "CommandLineW", buffer2);
@@ -1128,13 +1095,9 @@ static void test_Directory(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
GetWindowsDirectoryA( windir, sizeof(windir) );
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, windir, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildIString("Misc", "CurrDirA", windir);
release_memory();
DeleteFileA(resfile);
@@ -1174,11 +1137,9 @@ static void test_Toolhelp(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hProcess);
- CloseHandle(info.hThread);
+ wait_and_close_child_process(&info);
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
okChildInt("Toolhelp", "cntUsage", 0);
okChildInt("Toolhelp", "th32DefaultHeapID", 0);
okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1192,7 +1153,7 @@ static void test_Toolhelp(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process nested \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ wait_child_process(info.hProcess);
process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, info.dwProcessId);
ok(process != NULL, "OpenProcess failed %u\n", GetLastError());
@@ -1214,7 +1175,7 @@ static void test_Toolhelp(void)
ok(i < 20 || broken(i == 20), "process object not released\n");
/* Look for the nested process by pid */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
nested_pid = GetPrivateProfileIntA("Nested", "Pid", 0, resfile);
DeleteFileA(resfile);
@@ -1253,11 +1214,10 @@ static void test_Toolhelp(void)
ok(ret == 1, "expected 1, got %u\n", ret);
CloseHandle(thread);
- ret = WaitForSingleObject(process, 30000);
- ok(ret == WAIT_OBJECT_0, "Child process termination got %u le=%u\n", ret, GetLastError());
+ wait_child_process(process);
CloseHandle(process);
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
okChildInt("Toolhelp", "cntUsage", 0);
okChildInt("Toolhelp", "th32DefaultHeapID", 0);
okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1353,11 +1313,9 @@ static void test_Environment(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
env = GetEnvironmentStringsA();
cmpEnvironment(env);
release_memory();
@@ -1410,11 +1368,9 @@ static void test_Environment(void)
}
*ptr = '\0';
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, child_env, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
cmpEnvironment(child_env);
HeapFree(GetProcessHeap(), 0, child_env);
@@ -1446,13 +1402,11 @@ static void test_SuspendFlag(void)
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
ok(ResumeThread(info.hThread) == 1, "Resuming thread\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
GetStartupInfoA(&us);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1508,13 +1462,11 @@ static void test_DebuggingFlag(void)
} while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
ok(dbg, "I have seen a debug event\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
GetStartupInfoA(&us);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1588,12 +1540,9 @@ static void test_Console(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\" console", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
+ wait_and_close_child_process(&info);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-
+ reload_child_info(resfile);
/* now get the modification the child has made, and resets parents expected values */
ok(GetConsoleScreenBufferInfo(startup.hStdOutput, &sbiC), "Getting sb info\n");
ok(GetConsoleMode(startup.hStdInput, &modeInC), "Getting console in mode\n");
@@ -1715,11 +1664,9 @@ static void test_Console(void)
/* the child may also send the final "n tests executed" string, so read it to avoid a deadlock */
ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildString("StdHandle", "msg", msg);
release_memory();
@@ -1743,11 +1690,10 @@ static void test_ExitCode(void)
sprintf(buffer, "\"%s\" process dump \"%s\" exit_code", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
+ /* not wait_child_process() because of the exit code */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
ok(GetExitCodeProcess(info.hProcess, &code), "Getting exit code\n");
okChildInt("ExitCode", "value", code);
@@ -2458,7 +2404,6 @@ static void test_IsProcessInJob(void)
HANDLE job, job2;
PROCESS_INFORMATION pi;
BOOL ret, out;
- DWORD dwret;
if (!pIsProcessInJob)
{
@@ -2503,9 +2448,7 @@ static void test_IsProcessInJob(void)
ok(out, "IsProcessInJob returned out=%u\n", out);
TerminateProcess(pi.hProcess, 0);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
out = FALSE;
ret = pIsProcessInJob(pi.hProcess, job, &out);
@@ -2536,6 +2479,7 @@ static void test_TerminateJobObject(void)
ret = pTerminateJobObject(job, 123);
ok(ret, "TerminateJobObject error %u\n", GetLastError());
+ /* not wait_child_process() because of the exit code */
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2550,9 +2494,7 @@ static void test_TerminateJobObject(void)
/* Test adding an already terminated process to a job object */
create_process("exit", &pi);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
SetLastError(0xdeadbeef);
ret = pAssignProcessToJobObject(job, pi.hProcess);
@@ -2590,9 +2532,7 @@ static void test_QueryInformationJobObject(void)
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
ReleaseSemaphore(sem, 1, NULL);
- wait_child_process(pi[0].hProcess);
- CloseHandle(pi[0].hProcess);
- CloseHandle(pi[0].hThread);
+ wait_and_close_child_process(&pi[0]);
create_process("wait", &pi[0]);
ret = pAssignProcessToJobObject(job, pi[0].hProcess);
@@ -2696,7 +2636,6 @@ static void test_CompletionPort(void)
JOBOBJECT_ASSOCIATE_COMPLETION_PORT port_info;
PROCESS_INFORMATION pi;
HANDLE job, port;
- DWORD dwret;
BOOL ret;
job = pCreateJobObjectW(NULL, NULL);
@@ -2718,8 +2657,7 @@ static void test_CompletionPort(void)
test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
TerminateProcess(pi.hProcess, 0);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, 0, 100);
@@ -2757,6 +2695,7 @@ static void test_KillOnJobClose(void)
CloseHandle(job);
+ /* not wait_child_process() for the kill */
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2847,9 +2786,7 @@ static void test_WaitForJobObject(void)
dwret = WaitForSingleObject(job, 100);
ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
- wait_child_process(pi.hProcess);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
CloseHandle(job);
CloseHandle(sem);
}
@@ -2871,7 +2808,6 @@ static HANDLE test_AddSelfToJob(void)
static void test_jobInheritance(HANDLE job)
{
PROCESS_INFORMATION pi;
- DWORD dwret;
BOOL ret, out;
if (!pIsProcessInJob)
@@ -2887,11 +2823,7 @@ static void test_jobInheritance(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
static void test_BreakawayOk(HANDLE job)
@@ -2901,7 +2833,6 @@ static void test_BreakawayOk(HANDLE job)
STARTUPINFOA si = {0};
char buffer[MAX_PATH + 23];
BOOL ret, out;
- DWORD dwret;
if (!pIsProcessInJob)
{
@@ -2917,12 +2848,7 @@ static void test_BreakawayOk(HANDLE job)
if (ret)
{
TerminateProcess(pi.hProcess, 0);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK;
@@ -2936,11 +2862,7 @@ static void test_BreakawayOk(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info));
@@ -2953,11 +2875,7 @@ static void test_BreakawayOk(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
/* unset breakaway ok */
limit_info.BasicLimitInformation.LimitFlags = 0;
@@ -2980,8 +2898,9 @@ static void test_StartupNoConsole(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
&info), "CreateProcess\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3012,9 +2931,9 @@ static void test_DetachConsoleHandles(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
&info), "CreateProcess\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
result = GetPrivateProfileIntA("StartupInfoA", "hStdInput", 0, resfile);
ok(result != 0 && result != (UINT)INVALID_HANDLE_VALUE, "bad handle %x\n", result);
result = GetPrivateProfileIntA("StartupInfoA", "hStdOutput", 0, resfile);
@@ -3203,10 +3122,11 @@ static void test_SuspendProcessNewThread(void)
if (thread_handle)
CloseHandle(thread_handle);
+ /* Note that the child's main thread is still suspended so the exit code
+ * is set by the TerminateProcess() call.
+ */
TerminateProcess(pi.hProcess, 0);
- WaitForSingleObject(pi.hProcess, 10000);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
static void test_SuspendProcessState(void)
@@ -3400,8 +3320,12 @@ static void test_SuspendProcessState(void)
ret = WriteFile(server_pipe_handle, &pipe_magic, sizeof(pipe_magic), &numb, NULL);
ok(ret, "Failed to write the magic back to the pipe (%d)\n", GetLastError());
-
CloseHandle(server_pipe_handle);
+
+ /* Avoid wait_child_process() because the exit code results from a race
+ * between the TerminateProcess() call and the child's ExitProcess() call
+ * which uses a random value in the 64 bit case.
+ */
TerminateProcess(pi.hProcess, 0);
WaitForSingleObject(pi.hProcess, 10000);
CloseHandle(pi.hProcess);
@@ -3452,8 +3376,9 @@ static void test_DetachStdHandles(void)
SetStdHandle(STD_ERROR_HANDLE, hstderr);
ok(res, "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3930,9 +3855,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, (STARTUPINFOA *)&si, &info);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
#endif
si.lpAttributeList = heap_alloc(size);
ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
@@ -3944,9 +3867,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, (STARTUPINFOA *)&si, &info);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
CloseHandle(handle);
pDeleteProcThreadAttributeList(si.lpAttributeList);
heap_free(si.lpAttributeList);
@@ -3992,11 +3913,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_HANDLE),
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
if (ret)
- {
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
- }
+ wait_and_close_child_process(&info);
pDeleteProcThreadAttributeList(si.lpAttributeList);
heap_free(si.lpAttributeList);
@@ -4027,10 +3944,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = WriteFile(write_pipe, &parent_data, sizeof(parent_data), &size, NULL);
}
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
if (!level)
{
--
2.20.1
1
0
24 Mar '20
wait_and_close_child_process() simplifies waiting for the child process
and closing its handles. And because it uses wait_child_process() this
ensures that any error happening in the child process is detected.
reload_child_dump() wraps a cryptic WritePrivateProfileStringA() call
and avoids having to add a comment every time.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
dlls/kernel32/tests/process.c | 279 +++++++++++-----------------------
1 file changed, 92 insertions(+), 187 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 0f0889073b0..9a2b05914a6 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -203,6 +203,21 @@ static WCHAR* decodeW(const char* str)
return ptr;
}
+static void wait_and_close_child_process(PROCESS_INFORMATION *pi)
+{
+ wait_child_process(pi->hProcess);
+ CloseHandle(pi->hThread);
+ CloseHandle(pi->hProcess);
+}
+
+static void reload_child_info(const char* resfile)
+{
+ /* This forces the profile functions to reload the resource file
+ * after the child process has modified it.
+ */
+ WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+}
+
/******************************************************************
* init
*
@@ -615,13 +630,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
GetStartupInfoA(&si);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
@@ -655,13 +666,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -695,13 +702,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", si.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -735,13 +738,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -775,13 +774,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -817,13 +812,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -857,13 +848,9 @@ static void test_Startup(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", startup.lpDesktop);
okChildString("StartupInfoA", "lpTitle", startup.lpTitle);
@@ -920,13 +907,9 @@ static void test_CommandLine(void)
ok(startup.lpTitle == NULL, "lpTitle is not NULL\n");
ok(startup.dwFlags == STARTF_USESHOWWINDOW, "unexpected dwFlags %04x\n", startup.dwFlags);
ok(startup.wShowWindow == SW_SHOWNORMAL, "unexpected wShowWindow %d\n", startup.wShowWindow);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("Arguments", "argcA", 5);
okChildString("Arguments", "argvA4", "C:\\Program Files\\my nice app.exe");
okChildString("Arguments", "argvA5", NULL);
@@ -938,13 +921,9 @@ static void test_CommandLine(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\" \"a\\\"b\\\\\" c\\\" d", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildInt("Arguments", "argcA", 7);
okChildString("Arguments", "argvA4", "a\"b\\");
okChildString("Arguments", "argvA5", "c\"");
@@ -963,12 +942,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
sprintf(buffer, "./%s", exename);
okChildInt("Arguments", "argcA", 5);
okChildString("Arguments", "argvA0", buffer);
@@ -983,12 +959,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
sprintf(buffer, ".\\%s", exename);
okChildString("Arguments", "argvA0", buffer);
release_memory();
@@ -1005,12 +978,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
if (p) sprintf(buffer, "..%s/%s", p, exename);
else sprintf(buffer, "./%s", exename);
okChildString("Arguments", "argvA0", buffer);
@@ -1030,12 +1000,9 @@ static void test_CommandLine(void)
SetLastError(0xdeadbeef);
ret = CreateProcessA(buffer, buffer2, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess (%s) failed : %d\n", buffer, GetLastError());
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildString("Arguments", "argvA0", "dummy");
okChildString("Arguments", "CommandLineA", buffer2);
okChildStringWA("Arguments", "CommandLineW", buffer2);
@@ -1128,13 +1095,9 @@ static void test_Directory(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
GetWindowsDirectoryA( windir, sizeof(windir) );
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, windir, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildIString("Misc", "CurrDirA", windir);
release_memory();
DeleteFileA(resfile);
@@ -1174,11 +1137,9 @@ static void test_Toolhelp(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hProcess);
- CloseHandle(info.hThread);
+ wait_and_close_child_process(&info);
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
okChildInt("Toolhelp", "cntUsage", 0);
okChildInt("Toolhelp", "th32DefaultHeapID", 0);
okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1192,7 +1153,7 @@ static void test_Toolhelp(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process nested \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ wait_child_process(info.hProcess);
process = OpenProcess(PROCESS_ALL_ACCESS_NT4, FALSE, info.dwProcessId);
ok(process != NULL, "OpenProcess failed %u\n", GetLastError());
@@ -1214,7 +1175,7 @@ static void test_Toolhelp(void)
ok(i < 20 || broken(i == 20), "process object not released\n");
/* Look for the nested process by pid */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
nested_pid = GetPrivateProfileIntA("Nested", "Pid", 0, resfile);
DeleteFileA(resfile);
@@ -1253,11 +1214,10 @@ static void test_Toolhelp(void)
ok(ret == 1, "expected 1, got %u\n", ret);
CloseHandle(thread);
- ret = WaitForSingleObject(process, 30000);
- ok(ret == WAIT_OBJECT_0, "Child process termination got %u le=%u\n", ret, GetLastError());
+ wait_child_process(process);
CloseHandle(process);
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
okChildInt("Toolhelp", "cntUsage", 0);
okChildInt("Toolhelp", "th32DefaultHeapID", 0);
okChildInt("Toolhelp", "th32ModuleID", 0);
@@ -1353,11 +1313,9 @@ static void test_Environment(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
env = GetEnvironmentStringsA();
cmpEnvironment(env);
release_memory();
@@ -1410,11 +1368,9 @@ static void test_Environment(void)
}
*ptr = '\0';
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, child_env, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
cmpEnvironment(child_env);
HeapFree(GetProcessHeap(), 0, child_env);
@@ -1446,13 +1402,11 @@ static void test_SuspendFlag(void)
ok(GetExitCodeThread(info.hThread, &exit_status) && exit_status == STILL_ACTIVE, "thread still running\n");
ok(ResumeThread(info.hThread) == 1, "Resuming thread\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
GetStartupInfoA(&us);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1508,13 +1462,11 @@ static void test_DebuggingFlag(void)
} while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
ok(dbg, "I have seen a debug event\n");
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
GetStartupInfoA(&us);
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "cb", startup.cb);
okChildString("StartupInfoA", "lpDesktop", us.lpDesktop);
result = getChildString( "StartupInfoA", "lpTitle" );
@@ -1588,12 +1540,9 @@ static void test_Console(void)
get_file_name(resfile);
sprintf(buffer, "\"%s\" process dump \"%s\" console", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
+ wait_and_close_child_process(&info);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
-
+ reload_child_info(resfile);
/* now get the modification the child has made, and resets parents expected values */
ok(GetConsoleScreenBufferInfo(startup.hStdOutput, &sbiC), "Getting sb info\n");
ok(GetConsoleMode(startup.hStdInput, &modeInC), "Getting console in mode\n");
@@ -1715,11 +1664,9 @@ static void test_Console(void)
/* the child may also send the final "n tests executed" string, so read it to avoid a deadlock */
ReadFile(hParentIn, buffer, sizeof(buffer), &w, NULL);
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
okChildString("StdHandle", "msg", msg);
release_memory();
@@ -1743,11 +1690,10 @@ static void test_ExitCode(void)
sprintf(buffer, "\"%s\" process dump \"%s\" exit_code", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
- /* wait for child to terminate */
+ /* not wait_child_process() because of the exit code */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- /* child process has changed result file, so let profile functions know about it */
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ reload_child_info(resfile);
ok(GetExitCodeProcess(info.hProcess, &code), "Getting exit code\n");
okChildInt("ExitCode", "value", code);
@@ -2458,7 +2404,6 @@ static void test_IsProcessInJob(void)
HANDLE job, job2;
PROCESS_INFORMATION pi;
BOOL ret, out;
- DWORD dwret;
if (!pIsProcessInJob)
{
@@ -2503,9 +2448,7 @@ static void test_IsProcessInJob(void)
ok(out, "IsProcessInJob returned out=%u\n", out);
TerminateProcess(pi.hProcess, 0);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
out = FALSE;
ret = pIsProcessInJob(pi.hProcess, job, &out);
@@ -2536,6 +2479,7 @@ static void test_TerminateJobObject(void)
ret = pTerminateJobObject(job, 123);
ok(ret, "TerminateJobObject error %u\n", GetLastError());
+ /* not wait_child_process() because of the exit code */
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2550,9 +2494,7 @@ static void test_TerminateJobObject(void)
/* Test adding an already terminated process to a job object */
create_process("exit", &pi);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
SetLastError(0xdeadbeef);
ret = pAssignProcessToJobObject(job, pi.hProcess);
@@ -2590,9 +2532,7 @@ static void test_QueryInformationJobObject(void)
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
ReleaseSemaphore(sem, 1, NULL);
- wait_child_process(pi[0].hProcess);
- CloseHandle(pi[0].hProcess);
- CloseHandle(pi[0].hThread);
+ wait_and_close_child_process(&pi[0]);
create_process("wait", &pi[0]);
ret = pAssignProcessToJobObject(job, pi[0].hProcess);
@@ -2696,7 +2636,6 @@ static void test_CompletionPort(void)
JOBOBJECT_ASSOCIATE_COMPLETION_PORT port_info;
PROCESS_INFORMATION pi;
HANDLE job, port;
- DWORD dwret;
BOOL ret;
job = pCreateJobObjectW(NULL, NULL);
@@ -2718,8 +2657,7 @@ static void test_CompletionPort(void)
test_completion(port, JOB_OBJECT_MSG_NEW_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
TerminateProcess(pi.hProcess, 0);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
+ wait_child_process(pi.hProcess);
test_completion(port, JOB_OBJECT_MSG_EXIT_PROCESS, (DWORD_PTR)job, pi.dwProcessId, 0);
test_completion(port, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, (DWORD_PTR)job, 0, 100);
@@ -2757,6 +2695,7 @@ static void test_KillOnJobClose(void)
CloseHandle(job);
+ /* not wait_child_process() for the kill */
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
@@ -2847,9 +2786,7 @@ static void test_WaitForJobObject(void)
dwret = WaitForSingleObject(job, 100);
ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret);
- wait_child_process(pi.hProcess);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
CloseHandle(job);
CloseHandle(sem);
}
@@ -2871,7 +2808,6 @@ static HANDLE test_AddSelfToJob(void)
static void test_jobInheritance(HANDLE job)
{
PROCESS_INFORMATION pi;
- DWORD dwret;
BOOL ret, out;
if (!pIsProcessInJob)
@@ -2887,11 +2823,7 @@ static void test_jobInheritance(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
static void test_BreakawayOk(HANDLE job)
@@ -2901,7 +2833,6 @@ static void test_BreakawayOk(HANDLE job)
STARTUPINFOA si = {0};
char buffer[MAX_PATH + 23];
BOOL ret, out;
- DWORD dwret;
if (!pIsProcessInJob)
{
@@ -2917,12 +2848,7 @@ static void test_BreakawayOk(HANDLE job)
if (ret)
{
TerminateProcess(pi.hProcess, 0);
-
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK;
@@ -2936,11 +2862,7 @@ static void test_BreakawayOk(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
ret = pSetInformationJobObject(job, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info));
@@ -2953,11 +2875,7 @@ static void test_BreakawayOk(HANDLE job)
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
- dwret = WaitForSingleObject(pi.hProcess, 1000);
- ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
/* unset breakaway ok */
limit_info.BasicLimitInformation.LimitFlags = 0;
@@ -2980,8 +2898,9 @@ static void test_StartupNoConsole(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
&info), "CreateProcess\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3012,9 +2931,9 @@ static void test_DetachConsoleHandles(void)
sprintf(buffer, "\"%s\" process dump \"%s\"", selfname, resfile);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &startup,
&info), "CreateProcess\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+ reload_child_info(resfile);
result = GetPrivateProfileIntA("StartupInfoA", "hStdInput", 0, resfile);
ok(result != 0 && result != (UINT)INVALID_HANDLE_VALUE, "bad handle %x\n", result);
result = GetPrivateProfileIntA("StartupInfoA", "hStdOutput", 0, resfile);
@@ -3204,9 +3123,7 @@ static void test_SuspendProcessNewThread(void)
CloseHandle(thread_handle);
TerminateProcess(pi.hProcess, 0);
- WaitForSingleObject(pi.hProcess, 10000);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
static void test_SuspendProcessState(void)
@@ -3403,9 +3320,7 @@ static void test_SuspendProcessState(void)
CloseHandle(server_pipe_handle);
TerminateProcess(pi.hProcess, 0);
- WaitForSingleObject(pi.hProcess, 10000);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
+ wait_and_close_child_process(&pi);
}
#else
static void test_SuspendProcessNewThread(void)
@@ -3452,8 +3367,9 @@ static void test_DetachStdHandles(void)
SetStdHandle(STD_ERROR_HANDLE, hstderr);
ok(res, "CreateProcess failed\n");
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- WritePrivateProfileStringA(NULL, NULL, NULL, resfile);
+ wait_and_close_child_process(&info);
+
+ reload_child_info(resfile);
okChildInt("StartupInfoA", "hStdInput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdOutput", (UINT)INVALID_HANDLE_VALUE);
okChildInt("StartupInfoA", "hStdError", (UINT)INVALID_HANDLE_VALUE);
@@ -3930,9 +3846,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, (STARTUPINFOA *)&si, &info);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
#endif
si.lpAttributeList = heap_alloc(size);
ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
@@ -3944,9 +3858,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, (STARTUPINFOA *)&si, &info);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
CloseHandle(handle);
pDeleteProcThreadAttributeList(si.lpAttributeList);
heap_free(si.lpAttributeList);
@@ -3992,11 +3904,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_HANDLE),
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
if (ret)
- {
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
- }
+ wait_and_close_child_process(&info);
pDeleteProcThreadAttributeList(si.lpAttributeList);
heap_free(si.lpAttributeList);
@@ -4027,10 +3935,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = WriteFile(write_pipe, &parent_data, sizeof(parent_data), &size, NULL);
}
- /* wait for child to terminate */
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
- CloseHandle(info.hThread);
- CloseHandle(info.hProcess);
+ wait_and_close_child_process(&info);
if (!level)
{
--
2.20.1
2
2