Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 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
May 2020
- 79 participants
- 626 discussions
03 May '20
---
dlls/ntdll/env.c | 44 ++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/env.c | 44 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+)
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c
index 71ae48681d..61c4d56baa 100644
--- a/dlls/ntdll/env.c
+++ b/dlls/ntdll/env.c
@@ -38,6 +38,7 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
+#include "wine/library.h"
#include "wine/debug.h"
#include "ntdll_misc.h"
#include "winnt.h"
@@ -990,6 +991,49 @@ NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR env,
return nts;
}
+
+/******************************************************************
+ * RtlQueryEnvironmentVariable [NTDLL.@]
+ *
+ */
+NTSTATUS WINAPI RtlQueryEnvironmentVariable(PWSTR env,
+ PWSTR name,
+ size_t name_length,
+ PWSTR value,
+ size_t value_length,
+ size_t* return_length)
+{
+ UNICODE_STRING name_u;
+ UNICODE_STRING value_u;
+ NTSTATUS nts;
+
+ name_u.Length = name_length * sizeof(WCHAR);
+ name_u.MaximumLength = name_u.Length;
+ name_u.Buffer = name;
+
+ value_u.Length = 0;
+ value_u.MaximumLength = value_length * sizeof(WCHAR);
+ value_u.Buffer = value;
+
+ nts = RtlQueryEnvironmentVariable_U(env, &name_u, &value_u);
+ switch (nts)
+ {
+ case STATUS_SUCCESS:
+ *return_length = value_u.Length / sizeof(WCHAR);
+ break;
+
+ case STATUS_BUFFER_TOO_SMALL:
+ *return_length = (value_u.Length / sizeof(WCHAR)) + 1;
+ break;
+
+ case STATUS_VARIABLE_NOT_FOUND:
+ default:
+ *return_length = 0;
+ break;
+ }
+ return nts;
+}
+
/******************************************************************
* RtlSetCurrentEnvironment [NTDLL.@]
*
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 4f5fa8c21d..cbc43259bd 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -860,6 +860,7 @@
@ stdcall RtlQueryDepthSList(ptr)
@ stdcall RtlQueryDynamicTimeZoneInformation(ptr)
@ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
+@ stdcall RtlQueryEnvironmentVariable(ptr ptr long ptr long ptr)
@ stdcall RtlQueryHeapInformation(long long ptr long ptr)
@ stdcall RtlQueryInformationAcl(ptr ptr long long)
@ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr)
diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c
index 48c9ed809e..bb081e20ed 100644
--- a/dlls/ntdll/tests/env.c
+++ b/dlls/ntdll/tests/env.c
@@ -27,6 +27,7 @@ static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPD
static NTSTATUS (WINAPI *pRtlCreateEnvironment)(BOOLEAN, PWSTR*);
static NTSTATUS (WINAPI *pRtlDestroyEnvironment)(PWSTR);
static NTSTATUS (WINAPI *pRtlQueryEnvironmentVariable_U)(PWSTR, PUNICODE_STRING, PUNICODE_STRING);
+static NTSTATUS (WINAPI* pRtlQueryEnvironmentVariable)(PWSTR, PWSTR, size_t, PWSTR, size_t, size_t*);
static void (WINAPI *pRtlSetCurrentEnvironment)(PWSTR, PWSTR*);
static NTSTATUS (WINAPI *pRtlSetEnvironmentVariable)(PWSTR*, PUNICODE_STRING, PUNICODE_STRING);
static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings_U)(LPWSTR, PUNICODE_STRING, PUNICODE_STRING, PULONG);
@@ -95,6 +96,9 @@ static void testQuery(void)
UNICODE_STRING name;
UNICODE_STRING value;
NTSTATUS nts;
+ size_t name_length;
+ size_t value_length;
+ size_t return_length;
unsigned int i;
for (i = 0; tests[i].var; i++)
@@ -130,6 +134,45 @@ static void testQuery(void)
break;
}
}
+
+ /* test RtlQueryEnvironmentVariable */
+ if (pRtlQueryEnvironmentVariable)
+ {
+ for (i = 0; tests[i].var; i++)
+ {
+ const struct test* test = &tests[i];
+ name_length = strlen(test->var);
+ value_length = test->len;
+ value.Buffer = bv;
+ bv[test->len] = '@';
+
+ pRtlMultiByteToUnicodeN(bn, sizeof(bn), NULL, test->var, strlen(test->var) + 1);
+ nts = pRtlQueryEnvironmentVariable(small_env, bn, name_length, bv, value_length, &return_length);
+ ok(nts == test->status || (test->alt && nts == test->alt),
+ "[%d]: Wrong status for '%s', expecting %x got %x\n",
+ i, test->var, test->status, nts);
+ if (nts == test->status) switch (nts)
+ {
+ case STATUS_SUCCESS:
+ pRtlMultiByteToUnicodeN(bn, sizeof(bn), NULL, test->val, strlen(test->val) + 1);
+ ok(return_length == strlen(test->val), "Wrong length %d for %s\n",
+ return_length, test->var);
+ ok((return_length == strlen(test->val) && memcmp(bv, bn, return_length) == 0) ||
+ lstrcmpW(bv, bn) == 0,
+ "Wrong result for %s/%d\n", test->var, test->len);
+ ok(bv[test->len] == '@', "Writing too far away in the buffer for %s/%d\n", test->var, test->len);
+ break;
+ case STATUS_BUFFER_TOO_SMALL:
+ ok(return_length == (strlen(test->val) + 1),
+ "Wrong returned length %d (too small buffer) for %s\n", return_length, test->var);
+ break;
+ }
+ }
+ }
+ else
+ {
+ win_skip("RtlQueryEnvironmentVariable not available, skipping tests\n");
+ }
}
static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATUS ret, NTSTATUS alt)
@@ -525,6 +568,7 @@ START_TEST(env)
pRtlCreateEnvironment = (void*)GetProcAddress(mod, "RtlCreateEnvironment");
pRtlDestroyEnvironment = (void*)GetProcAddress(mod, "RtlDestroyEnvironment");
pRtlQueryEnvironmentVariable_U = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable_U");
+ pRtlQueryEnvironmentVariable = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable");
pRtlSetCurrentEnvironment = (void*)GetProcAddress(mod, "RtlSetCurrentEnvironment");
pRtlSetEnvironmentVariable = (void*)GetProcAddress(mod, "RtlSetEnvironmentVariable");
pRtlExpandEnvironmentStrings_U = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings_U");
--
2.17.1
1
0
03 May '20
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ddraw/tests/ddraw1.c | 153 ++++++++++++++++++++++++++++++++++-
dlls/ddraw/tests/ddraw2.c | 153 ++++++++++++++++++++++++++++++++++-
dlls/ddraw/tests/ddraw4.c | 163 +++++++++++++++++++++++++++++++++++--
dlls/ddraw/tests/ddraw7.c | 164 ++++++++++++++++++++++++++++++++++++--
4 files changed, 620 insertions(+), 13 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 4e27ecfb796..34ebfab1b7b 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -12091,9 +12091,27 @@ static void test_clear(void)
DestroyWindow(window);
}
+struct display_mode_list
+{
+ DDSURFACEDESC modes[20];
+ unsigned int count;
+};
+
+static HRESULT CALLBACK build_mode_list_cb(DDSURFACEDESC *desc, void *context)
+{
+ struct display_mode_list *modes = context;
+
+ if (modes->count < ARRAY_SIZE(modes->modes))
+ modes->modes[modes->count] = *desc;
+ ++modes->count;
+
+ return DDENUMRET_OK;
+}
+
struct enum_surfaces_param
{
IDirectDrawSurface *surfaces[8];
+ struct display_mode_list modes;
unsigned int count;
};
@@ -12119,9 +12137,31 @@ static HRESULT WINAPI enum_surfaces_cb(IDirectDrawSurface *surface, DDSURFACEDES
return DDENUMRET_OK;
}
+static HRESULT WINAPI enum_surfaces_create_cb(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
+{
+ static const DWORD expect_flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT;
+ struct enum_surfaces_param *param = context;
+
+ ok(!surface, "Unexpected surface %p.\n", surface);
+ ok((desc->dwFlags & expect_flags) == expect_flags, "Got unexpected flags %#x.\n", desc->dwFlags);
+ if (param->count < ARRAY_SIZE(param->modes.modes))
+ {
+ const DDSURFACEDESC *expect = ¶m->modes.modes[param->count];
+ ok(desc->dwWidth == expect->dwWidth, "Expected width %u, got %u.\n", expect->dwWidth, desc->dwWidth);
+ ok(desc->dwHeight == expect->dwHeight, "Expected height %u, got %u.\n", expect->dwHeight, desc->dwHeight);
+ ok(!memcmp(&desc->ddpfPixelFormat, &expect->ddpfPixelFormat, sizeof(desc->ddpfPixelFormat)),
+ "Pixel formats didn't match.\n");
+ }
+
+ ++param->count;
+
+ return DDENUMRET_OK;
+}
+
static void test_enum_surfaces(void)
{
struct enum_surfaces_param param = {{0}};
+ DDPIXELFORMAT current_format;
IDirectDraw *ddraw;
DDSURFACEDESC desc;
HRESULT hr;
@@ -12129,8 +12169,21 @@ static void test_enum_surfaces(void)
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ hr = IDirectDraw_GetDisplayMode(ddraw, &desc);
+ ok(hr == DD_OK, "Failed to get display mode, hr %#x.\n", hr);
+ current_format = desc.ddpfPixelFormat;
+
hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_ALL, NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
@@ -12150,6 +12203,7 @@ static void test_enum_surfaces(void)
ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
ok(!param.surfaces[3], "Got unexpected pointer %p.\n", param.surfaces[3]);
+ param.count = 0;
hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
&desc, ¶m, enum_surfaces_cb);
ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
@@ -12161,9 +12215,106 @@ static void test_enum_surfaces(void)
ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 2, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST, &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDrawSurface_Release(param.surfaces[2]);
IDirectDrawSurface_Release(param.surfaces[1]);
IDirectDrawSurface_Release(param.surfaces[0]);
+
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
+ NULL, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ /* When not passed width and height, the callback is called with every
+ * available display resolution. */
+
+ param.modes.count = 0;
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat = current_format;
+ hr = IDirectDraw_EnumDisplayModes(ddraw, 0, &desc, ¶m.modes, build_mode_list_cb);
+ ok(hr == DD_OK, "Failed to build mode list, hr %#x.\n", hr);
+
+ param.count = 0;
+ desc.dwFlags &= ~DDSD_PIXELFORMAT;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == param.modes.count, "Expected %u surfaces, got %u.\n", param.modes.count, param.count);
+
+ desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+ desc.dwWidth = desc.dwHeight = 32;
+
+ param.modes.modes[0].dwWidth = param.modes.modes[0].dwHeight = 32;
+
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ hr = IDirectDraw_CreateSurface(ddraw, &desc, ¶m.surfaces[0], NULL);
+ ok(hr == DD_OK, "Failed to create surface, hr %#x.\n", hr);
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ IDirectDrawSurface_Release(param.surfaces[0]);
+
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
+ desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ desc.ddpfPixelFormat.dwFourCC = 0xdeadbeef;
+
+ param.count = 0;
+ hr = IDirectDraw_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDraw_Release(ddraw);
}
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 7c25b2be557..90f7b77c839 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -13067,9 +13067,27 @@ static void test_clear(void)
DestroyWindow(window);
}
+struct display_mode_list
+{
+ DDSURFACEDESC modes[20];
+ unsigned int count;
+};
+
+static HRESULT CALLBACK build_mode_list_cb(DDSURFACEDESC *desc, void *context)
+{
+ struct display_mode_list *modes = context;
+
+ if (modes->count < ARRAY_SIZE(modes->modes))
+ modes->modes[modes->count] = *desc;
+ ++modes->count;
+
+ return DDENUMRET_OK;
+}
+
struct enum_surfaces_param
{
IDirectDrawSurface *surfaces[8];
+ struct display_mode_list modes;
unsigned int count;
};
@@ -13095,9 +13113,31 @@ static HRESULT WINAPI enum_surfaces_cb(IDirectDrawSurface *surface, DDSURFACEDES
return DDENUMRET_OK;
}
+static HRESULT WINAPI enum_surfaces_create_cb(IDirectDrawSurface *surface, DDSURFACEDESC *desc, void *context)
+{
+ static const DWORD expect_flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT;
+ struct enum_surfaces_param *param = context;
+
+ ok(!surface, "Unexpected surface %p.\n", surface);
+ ok((desc->dwFlags & expect_flags) == expect_flags, "Got unexpected flags %#x.\n", desc->dwFlags);
+ if (param->count < ARRAY_SIZE(param->modes.modes))
+ {
+ const DDSURFACEDESC *expect = ¶m->modes.modes[param->count];
+ ok(desc->dwWidth == expect->dwWidth, "Expected width %u, got %u.\n", expect->dwWidth, desc->dwWidth);
+ ok(desc->dwHeight == expect->dwHeight, "Expected height %u, got %u.\n", expect->dwHeight, desc->dwHeight);
+ ok(!memcmp(&desc->ddpfPixelFormat, &expect->ddpfPixelFormat, sizeof(desc->ddpfPixelFormat)),
+ "Pixel formats didn't match.\n");
+ }
+
+ ++param->count;
+
+ return DDENUMRET_OK;
+}
+
static void test_enum_surfaces(void)
{
struct enum_surfaces_param param = {{0}};
+ DDPIXELFORMAT current_format;
IDirectDraw2 *ddraw;
DDSURFACEDESC desc;
HRESULT hr;
@@ -13105,8 +13145,21 @@ static void test_enum_surfaces(void)
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ hr = IDirectDraw2_GetDisplayMode(ddraw, &desc);
+ ok(hr == DD_OK, "Failed to get display mode, hr %#x.\n", hr);
+ current_format = desc.ddpfPixelFormat;
+
hr = IDirectDraw2_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_ALL, NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
@@ -13126,6 +13179,7 @@ static void test_enum_surfaces(void)
ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
ok(!param.surfaces[3], "Got unexpected pointer %p.\n", param.surfaces[3]);
+ param.count = 0;
hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
&desc, ¶m, enum_surfaces_cb);
ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
@@ -13137,9 +13191,106 @@ static void test_enum_surfaces(void)
ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 2, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST, &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDrawSurface_Release(param.surfaces[2]);
IDirectDrawSurface_Release(param.surfaces[1]);
IDirectDrawSurface_Release(param.surfaces[0]);
+
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
+ NULL, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ /* When not passed width and height, the callback is called with every
+ * available display resolution. */
+
+ param.modes.count = 0;
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat = current_format;
+ hr = IDirectDraw2_EnumDisplayModes(ddraw, 0, &desc, ¶m.modes, build_mode_list_cb);
+ ok(hr == DD_OK, "Failed to build mode list, hr %#x.\n", hr);
+
+ param.count = 0;
+ desc.dwFlags &= ~DDSD_PIXELFORMAT;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == param.modes.count, "Expected %u surfaces, got %u.\n", param.modes.count, param.count);
+
+ desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+ desc.dwWidth = desc.dwHeight = 32;
+
+ param.modes.modes[0].dwWidth = param.modes.modes[0].dwHeight = 32;
+
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ hr = IDirectDraw2_CreateSurface(ddraw, &desc, ¶m.surfaces[0], NULL);
+ ok(hr == DD_OK, "Failed to create surface, hr %#x.\n", hr);
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ IDirectDrawSurface2_Release(param.surfaces[0]);
+
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
+ desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ desc.ddpfPixelFormat.dwFourCC = 0xdeadbeef;
+
+ param.count = 0;
+ hr = IDirectDraw2_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDraw2_Release(ddraw);
}
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index c38c0b3ce5a..8012e10a19c 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -15655,9 +15655,27 @@ static void test_clear(void)
DestroyWindow(window);
}
+struct display_mode_list
+{
+ DDSURFACEDESC2 modes[20];
+ unsigned int count;
+};
+
+static HRESULT CALLBACK build_mode_list_cb(DDSURFACEDESC2 *desc, void *context)
+{
+ struct display_mode_list *modes = context;
+
+ if (modes->count < ARRAY_SIZE(modes->modes))
+ modes->modes[modes->count] = *desc;
+ ++modes->count;
+
+ return DDENUMRET_OK;
+}
+
struct enum_surfaces_param
{
IDirectDrawSurface4 *surfaces[8];
+ struct display_mode_list modes;
unsigned int count;
};
@@ -15683,9 +15701,31 @@ static HRESULT WINAPI enum_surfaces_cb(IDirectDrawSurface4 *surface, DDSURFACEDE
return DDENUMRET_OK;
}
+static HRESULT WINAPI enum_surfaces_create_cb(IDirectDrawSurface4 *surface, DDSURFACEDESC2 *desc, void *context)
+{
+ static const DWORD expect_flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT;
+ struct enum_surfaces_param *param = context;
+
+ ok(!surface, "Unexpected surface %p.\n", surface);
+ ok((desc->dwFlags & expect_flags) == expect_flags, "Got unexpected flags %#x.\n", desc->dwFlags);
+ if (param->count < ARRAY_SIZE(param->modes.modes))
+ {
+ const DDSURFACEDESC2 *expect = ¶m->modes.modes[param->count];
+ ok(desc->dwWidth == expect->dwWidth, "Expected width %u, got %u.\n", expect->dwWidth, desc->dwWidth);
+ ok(desc->dwHeight == expect->dwHeight, "Expected height %u, got %u.\n", expect->dwHeight, desc->dwHeight);
+ ok(!memcmp(&U4(*desc).ddpfPixelFormat, &U4(*expect).ddpfPixelFormat, sizeof(U4(*desc).ddpfPixelFormat)),
+ "Pixel formats didn't match.\n");
+ }
+
+ ++param->count;
+
+ return DDENUMRET_OK;
+}
+
static void test_enum_surfaces(void)
{
struct enum_surfaces_param param = {{0}};
+ DDPIXELFORMAT current_format;
DDSURFACEDESC2 desc;
IDirectDraw4 *ddraw;
HRESULT hr;
@@ -15693,8 +15733,21 @@ static void test_enum_surfaces(void)
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ hr = IDirectDraw4_GetDisplayMode(ddraw, &desc);
+ ok(hr == DD_OK, "Failed to get display mode, hr %#x.\n", hr);
+ current_format = U4(desc).ddpfPixelFormat;
+
hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_ALL, NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
@@ -15704,30 +15757,128 @@ static void test_enum_surfaces(void)
desc.dwWidth = 32;
desc.dwHeight = 32;
hr = IDirectDraw4_CreateSurface(ddraw, &desc, ¶m.surfaces[0], NULL);
- ok(SUCCEEDED(hr), "Failed to create a surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to create a surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_GetAttachedSurface(param.surfaces[0], &desc.ddsCaps, ¶m.surfaces[1]);
- ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to get attached surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_GetAttachedSurface(param.surfaces[1], &desc.ddsCaps, ¶m.surfaces[2]);
- ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to get attached surface, hr %#x.\n", hr);
hr = IDirectDrawSurface4_GetAttachedSurface(param.surfaces[2], &desc.ddsCaps, ¶m.surfaces[3]);
ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
ok(!param.surfaces[3], "Got unexpected pointer %p.\n", param.surfaces[3]);
+ param.count = 0;
hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
&desc, ¶m, enum_surfaces_cb);
- ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
param.count = 0;
hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
NULL, ¶m, enum_surfaces_cb);
- ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 2, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST, &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
IDirectDrawSurface4_Release(param.surfaces[2]);
IDirectDrawSurface4_Release(param.surfaces[1]);
IDirectDrawSurface4_Release(param.surfaces[0]);
+
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
+ NULL, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ /* When not passed width and height, the callback is called with every
+ * available display resolution. */
+
+ param.modes.count = 0;
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat = current_format;
+ hr = IDirectDraw4_EnumDisplayModes(ddraw, 0, &desc, ¶m.modes, build_mode_list_cb);
+ ok(hr == DD_OK, "Failed to build mode list, hr %#x.\n", hr);
+
+ param.count = 0;
+ desc.dwFlags &= ~DDSD_PIXELFORMAT;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == param.modes.count, "Expected %u surfaces, got %u.\n", param.modes.count, param.count);
+
+ desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+ desc.dwWidth = desc.dwHeight = 32;
+
+ param.modes.modes[0].dwWidth = param.modes.modes[0].dwHeight = 32;
+
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ hr = IDirectDraw4_CreateSurface(ddraw, &desc, ¶m.surfaces[0], NULL);
+ ok(hr == DD_OK, "Failed to create surface, hr %#x.\n", hr);
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ IDirectDrawSurface4_Release(param.surfaces[0]);
+
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat.dwSize = sizeof(U4(desc).ddpfPixelFormat);
+ U4(desc).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ U4(desc).ddpfPixelFormat.dwFourCC = 0xdeadbeef;
+
+ param.count = 0;
+ hr = IDirectDraw4_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDraw4_Release(ddraw);
}
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index d3ea36e9808..d94676ba5e6 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -15058,9 +15058,27 @@ static void test_clear(void)
DestroyWindow(window);
}
+struct display_mode_list
+{
+ DDSURFACEDESC2 modes[20];
+ unsigned int count;
+};
+
+static HRESULT CALLBACK build_mode_list_cb(DDSURFACEDESC2 *desc, void *context)
+{
+ struct display_mode_list *modes = context;
+
+ if (modes->count < ARRAY_SIZE(modes->modes))
+ modes->modes[modes->count] = *desc;
+ ++modes->count;
+
+ return DDENUMRET_OK;
+}
+
struct enum_surfaces_param
{
IDirectDrawSurface7 *surfaces[8];
+ struct display_mode_list modes;
unsigned int count;
};
@@ -15086,9 +15104,31 @@ static HRESULT WINAPI enum_surfaces_cb(IDirectDrawSurface7 *surface, DDSURFACEDE
return DDENUMRET_OK;
}
+static HRESULT WINAPI enum_surfaces_create_cb(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
+{
+ static const DWORD expect_flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT;
+ struct enum_surfaces_param *param = context;
+
+ ok(!surface, "Unexpected surface %p.\n", surface);
+ ok((desc->dwFlags & expect_flags) == expect_flags, "Got unexpected flags %#x.\n", desc->dwFlags);
+ if (param->count < ARRAY_SIZE(param->modes.modes))
+ {
+ const DDSURFACEDESC2 *expect = ¶m->modes.modes[param->count];
+ ok(desc->dwWidth == expect->dwWidth, "Expected width %u, got %u.\n", expect->dwWidth, desc->dwWidth);
+ ok(desc->dwHeight == expect->dwHeight, "Expected height %u, got %u.\n", expect->dwHeight, desc->dwHeight);
+ ok(!memcmp(&U4(*desc).ddpfPixelFormat, &U4(*expect).ddpfPixelFormat, sizeof(U4(*desc).ddpfPixelFormat)),
+ "Pixel formats didn't match.\n");
+ }
+
+ ++param->count;
+
+ return DDENUMRET_OK;
+}
+
static void test_enum_surfaces(void)
{
struct enum_surfaces_param param = {{0}};
+ DDPIXELFORMAT current_format;
DDSURFACEDESC2 desc;
IDirectDraw7 *ddraw;
HRESULT hr;
@@ -15096,8 +15136,24 @@ static void test_enum_surfaces(void)
ddraw = create_ddraw();
ok(!!ddraw, "Failed to create a ddraw object.\n");
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ hr = IDirectDraw7_GetDisplayMode(ddraw, &desc);
+ ok(hr == DD_OK, "Failed to get display mode, hr %#x.\n", hr);
+ current_format = U4(desc).ddpfPixelFormat;
+
hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to set cooperative level, hr %#x.\n", hr);
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, NULL, NULL, NULL);
+ ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_ALL, NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ NULL, NULL, enum_surfaces_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
@@ -15114,27 +15170,125 @@ static void test_enum_surfaces(void)
}
hr = IDirectDrawSurface7_GetAttachedSurface(param.surfaces[0], &desc.ddsCaps, ¶m.surfaces[1]);
- ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to get attached surface, hr %#x.\n", hr);
hr = IDirectDrawSurface7_GetAttachedSurface(param.surfaces[1], &desc.ddsCaps, ¶m.surfaces[2]);
- ok(SUCCEEDED(hr), "Failed to get attached surface, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to get attached surface, hr %#x.\n", hr);
hr = IDirectDrawSurface7_GetAttachedSurface(param.surfaces[2], &desc.ddsCaps, ¶m.surfaces[3]);
ok(hr == DDERR_NOTFOUND, "Got unexpected hr %#x.\n", hr);
ok(!param.surfaces[3], "Got unexpected pointer %p.\n", param.surfaces[3]);
+ param.count = 0;
hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
&desc, ¶m, enum_surfaces_cb);
- ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
param.count = 0;
hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
NULL, ¶m, enum_surfaces_cb);
- ok(SUCCEEDED(hr), "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 2, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ desc.dwFlags = 0;
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST, &desc, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
ok(param.count == 3, "Got unexpected number of enumerated surfaces %u.\n", param.count);
IDirectDrawSurface7_Release(param.surfaces[2]);
IDirectDrawSurface7_Release(param.surfaces[1]);
IDirectDrawSurface7_Release(param.surfaces[0]);
+
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL,
+ NULL, ¶m, enum_surfaces_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED,
+ &desc, ¶m, enum_surfaces_create_cb);
+ todo_wine ok(hr == DDERR_INVALIDPARAMS, "Failed to enumerate surfaces, hr %#x.\n", hr);
+
+ /* When not passed width and height, the callback is called with every
+ * available display resolution. */
+
+ param.modes.count = 0;
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat = current_format;
+ hr = IDirectDraw7_EnumDisplayModes(ddraw, 0, &desc, ¶m.modes, build_mode_list_cb);
+ ok(hr == DD_OK, "Failed to build mode list, hr %#x.\n", hr);
+
+ param.count = 0;
+ desc.dwFlags &= ~DDSD_PIXELFORMAT;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == param.modes.count, "Expected %u surfaces, got %u.\n", param.modes.count, param.count);
+
+ desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
+ desc.dwWidth = desc.dwHeight = 32;
+
+ param.modes.modes[0].dwWidth = param.modes.modes[0].dwHeight = 32;
+
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
+ hr = IDirectDraw7_CreateSurface(ddraw, &desc, ¶m.surfaces[0], NULL);
+ ok(hr == DD_OK, "Failed to create surface, hr %#x.\n", hr);
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ todo_wine ok(param.count == 1, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+ IDirectDrawSurface7_Release(param.surfaces[0]);
+
+ desc.dwFlags |= DDSD_PIXELFORMAT;
+ U4(desc).ddpfPixelFormat.dwSize = sizeof(U4(desc).ddpfPixelFormat);
+ U4(desc).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+ U4(desc).ddpfPixelFormat.dwFourCC = 0xdeadbeef;
+
+ param.count = 0;
+ hr = IDirectDraw7_EnumSurfaces(ddraw, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
+ &desc, ¶m, enum_surfaces_create_cb);
+ ok(hr == DD_OK, "Failed to enumerate surfaces, hr %#x.\n", hr);
+ ok(!param.count, "Got unexpected number of enumerated surfaces %u.\n", param.count);
+
IDirectDraw7_Release(ddraw);
}
--
2.26.2
2
5
03 May '20
Blindwrite 7's ezplay.sys has sections which are consecutive in memory but not
page aligned. Thus changing the protection to PROT_READWRITE one section at a
time has the effect that old_prot for all sections but the first is set to
PROT_READWRITE (actually, PROT_WRITECOPY), causing us to restore the wrong
protection and the driver to crash in its entry point.
To fix this, protect and unprotect one page at a time while processing it, i.e.
essentially revert 6c0a8c359. To avoid reintroducing bug 28254, protect two
pages at a time instead of just one.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 39 ++++++++++--------------------------
1 file changed, 11 insertions(+), 28 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 398f1dacfd..6ee08f7202 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -3327,16 +3327,13 @@ static inline void *get_rva( HMODULE module, DWORD va )
return (void *)((char *)module + va);
}
-/* Copied from ntdll with checks for page alignment and characteristics removed */
-static NTSTATUS perform_relocations( void *module, SIZE_T len )
+static NTSTATUS perform_relocations( void *module, SIZE_T len, ULONG page_size )
{
IMAGE_NT_HEADERS *nt;
char *base;
IMAGE_BASE_RELOCATION *rel, *end;
const IMAGE_DATA_DIRECTORY *relocs;
- const IMAGE_SECTION_HEADER *sec;
INT_PTR delta;
- ULONG protect_old[96], i;
nt = RtlImageNtHeader( module );
base = (char *)nt->OptionalHeader.ImageBase;
@@ -3355,19 +3352,6 @@ static NTSTATUS perform_relocations( void *module, SIZE_T len )
if (!relocs->Size) return STATUS_SUCCESS;
if (!relocs->VirtualAddress) return STATUS_CONFLICTING_ADDRESSES;
- if (nt->FileHeader.NumberOfSections > ARRAY_SIZE( protect_old ))
- return STATUS_INVALID_IMAGE_FORMAT;
-
- sec = (const IMAGE_SECTION_HEADER *)((const char *)&nt->OptionalHeader +
- nt->FileHeader.SizeOfOptionalHeader);
- for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
- {
- void *addr = get_rva( module, sec[i].VirtualAddress );
- SIZE_T size = sec[i].SizeOfRawData;
- NtProtectVirtualMemory( NtCurrentProcess(), &addr,
- &size, PAGE_READWRITE, &protect_old[i] );
- }
-
TRACE( "relocating from %p-%p to %p-%p\n",
base, base + len, module, (char *)module + len );
@@ -3377,25 +3361,24 @@ static NTSTATUS perform_relocations( void *module, SIZE_T len )
while (rel < end - 1 && rel->SizeOfBlock)
{
+ void *page = get_rva( module, rel->VirtualAddress );
+ DWORD old_prot;
+
if (rel->VirtualAddress >= len)
{
WARN( "invalid address %p in relocation %p\n", get_rva( module, rel->VirtualAddress ), rel );
return STATUS_ACCESS_VIOLATION;
}
- rel = LdrProcessRelocationBlock( get_rva( module, rel->VirtualAddress ),
- (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT),
+
+ /* Relocation entries may hang over the end of the page, so we need to
+ * protect two pages. */
+ VirtualProtect( page, page_size * 2, PAGE_READWRITE, &old_prot );
+ rel = LdrProcessRelocationBlock( page, (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT),
(USHORT *)(rel + 1), delta );
+ VirtualProtect( page, page_size * 2, old_prot, &old_prot );
if (!rel) return STATUS_INVALID_IMAGE_FORMAT;
}
- for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
- {
- void *addr = get_rva( module, sec[i].VirtualAddress );
- SIZE_T size = sec[i].SizeOfRawData;
- NtProtectVirtualMemory( NtCurrentProcess(), &addr,
- &size, protect_old[i], &protect_old[i] );
- }
-
return STATUS_SUCCESS;
}
@@ -3424,7 +3407,7 @@ static HMODULE load_driver_module( const WCHAR *name )
if (nt->OptionalHeader.SectionAlignment < info.PageSize ||
!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
- status = perform_relocations(module, nt->OptionalHeader.SizeOfImage);
+ status = perform_relocations( module, nt->OptionalHeader.SizeOfImage, info.PageSize );
if (status != STATUS_SUCCESS)
goto error;
--
2.26.2
2
2
[PATCH v2 1/2] user32/tests: Add test for RedrawWindow with RDW_VALIDATE flag.
by Roman Pišl 02 May '20
by Roman Pišl 02 May '20
02 May '20
Signed-off-by: Roman Pišl <rpisl(a)seznam.cz>
---
dlls/user32/tests/msg.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 93ab7b4a27..2763857d8a 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -136,7 +136,8 @@ typedef enum {
optional=0x80,
hook=0x100,
winevent_hook=0x200,
- kbd_hook=0x400
+ kbd_hook=0x400,
+ has_update=0x800
} msg_flags_t;
struct message {
@@ -2547,6 +2548,11 @@ static void ok_sequence_(const struct message *expected_list, const char *contex
context, count, expected->message);
if ((expected->flags & kbd_hook) != (actual->flags & kbd_hook)) dump++;
+ todo_wine_if(expected->flags & has_update)
+ ok_( file, line) (!(expected->flags & has_update) || (actual->flags & has_update),
+ "%s: %u: the msg 0x%04x should have update region\n",
+ context, count, expected->message);
+
expected++;
actual++;
}
@@ -7858,6 +7864,11 @@ static const struct message WmPaint[] = {
{ 0 }
};
+static const struct message WmPaintUpdate[] = {
+ { WM_PAINT, sent|has_update },
+ { 0 }
+};
+
static const struct message WmParentOnlyPaint[] = {
{ WM_PAINT, sent|parent },
{ 0 }
@@ -8217,6 +8228,16 @@ static void test_paint_messages(void)
}
ok_sequence( WmGetUpdateRect, "GetUpdateRect", FALSE );
+ /* RedrawWindow with RDW_VALIDATE triggers WM_PAINT with non-empty update region */
+ flush_sequence();
+ InvalidateRect( hwnd, NULL, FALSE );
+ GetClientRect( hwnd, &rect );
+ SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
+ check_update_rgn( hwnd, hrgn );
+ RedrawWindow( hwnd, &rect, NULL, RDW_INTERNALPAINT|RDW_NOERASE|RDW_NOFRAME|RDW_UPDATENOW|RDW_VALIDATE );
+ check_update_rgn( hwnd, 0 );
+ ok_sequence( WmPaintUpdate, "PaintUpdate", FALSE );
+
DestroyWindow( hwnd );
/* now test with a child window */
@@ -9531,6 +9552,9 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
if (beginpaint_counter) msg.flags |= beginpaint;
+
+ if (message == WM_PAINT && GetUpdateRect(hwnd, NULL, FALSE)) msg.flags |= has_update;
+
msg.wParam = wParam;
msg.lParam = lParam;
msg.descr = "MsgCheckProc";
--
2.20.1
2
3
Hello,
this is a third revision of the patch with minor fixes (missing DECLSPEC_HIDDEN
and better naming of the message) and my last try to get ACK/NAK/you screwed completely.
The question that may arise is, whether this should not be a part of X11DRV_ClientMessage
in a more generic way.
I think it is worth the effort as it fixes multiple applications.
Regards,
Roman
Roman Pišl (1):
winex11.drv: Avoid freezing when dropping from native into Wine
application that shows modal dialog.
dlls/winex11.drv/window.c | 3 +++
dlls/winex11.drv/x11drv.h | 4 +++-
dlls/winex11.drv/xdnd.c | 17 +++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
--
2.20.1
1
1
02 May '20
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
server/mapping.c | 2 +-
server/protocol.def | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/server/mapping.c b/server/mapping.c
index 6990a1913d..1c189a282b 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -934,7 +934,7 @@ static void mapping_destroy( struct object *obj )
static enum server_fd_type mapping_get_fd_type( struct fd *fd )
{
- return FD_TYPE_FILE;
+ return FD_TYPE_MAPPING;
}
int get_page_size(void)
diff --git a/server/protocol.def b/server/protocol.def
index 06a29b153e..9f60e323b6 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1318,6 +1318,7 @@ enum server_fd_type
FD_TYPE_MAILSLOT, /* mailslot */
FD_TYPE_CHAR, /* unspecified char device */
FD_TYPE_DEVICE, /* Windows device file */
+ FD_TYPE_MAPPING, /* File mapping */
FD_TYPE_NB_TYPES
};
--
2.26.2
2
3
[PATCH 1/5] quartz/tests: Add some tests for IVMRWindowlessControl9::SetVideoClippingWindow().
by Zebediah Figura 02 May '20
by Zebediah Figura 02 May '20
02 May '20
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/vmr9.c | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index cb04d0b4aa5..a098416bb2c 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -3191,6 +3191,68 @@ static void test_mixing_mode(void)
DestroyWindow(window);
}
+static void test_clipping_window(void)
+{
+ VIDEOINFOHEADER vih =
+ {
+ .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
+ .bmiHeader.biWidth = 32,
+ .bmiHeader.biHeight = 16,
+ .bmiHeader.biBitCount = 32,
+ };
+ AM_MEDIA_TYPE mt =
+ {
+ .majortype = MEDIATYPE_Video,
+ .subtype = MEDIASUBTYPE_RGB32,
+ .formattype = FORMAT_VideoInfo,
+ .cbFormat = sizeof(vih),
+ .pbFormat = (BYTE *)&vih,
+ };
+ IBaseFilter *filter = create_vmr9(VMR9Mode_Windowless);
+ IVMRWindowlessControl9 *windowless_control;
+ IFilterGraph2 *graph = create_graph();
+ struct testfilter source;
+ HWND window;
+ HRESULT hr;
+ ULONG ref;
+ IPin *pin;
+
+ IBaseFilter_QueryInterface(filter, &IID_IVMRWindowlessControl9, (void **)&windowless_control);
+ IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
+ testfilter_init(&source);
+ IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
+ IFilterGraph2_AddFilter(graph, filter, L"vmr9");
+ window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
+ ok(!!window, "Failed to create a window.\n");
+
+ hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, NULL);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, (HWND)0xdeadbeef);
+ todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
+ todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
+
+ hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IFilterGraph2_Disconnect(graph, pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ref = IFilterGraph2_Release(graph);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ IPin_Release(pin);
+ IVMRWindowlessControl9_Release(windowless_control);
+ ref = IBaseFilter_Release(filter);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
+ DestroyWindow(window);
+}
+
START_TEST(vmr9)
{
IBaseFilter *filter;
@@ -3221,6 +3283,7 @@ START_TEST(vmr9)
test_allocate_surface_helper();
test_renderless_formats();
test_mixing_mode();
+ test_clipping_window();
CoUninitialize();
}
--
2.26.2
2
9
01 May '20
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/advapi32/advapi32.spec | 8 +-
dlls/advapi32/security.c | 1314 -----------------------------------
dlls/sechost/Makefile.in | 1 +
dlls/sechost/sechost.spec | 8 +-
dlls/sechost/security.c | 1247 +++++++++++++++++++++++++++++++++
5 files changed, 1256 insertions(+), 1322 deletions(-)
create mode 100644 dlls/sechost/security.c
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index cd4dedac74..ac8ea6268a 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -120,17 +120,17 @@
# @ stub ConvertSecurityDescriptorToAccessNamedW
# @ stub ConvertSecurityDescriptorToAccessW
@ stdcall ConvertSecurityDescriptorToStringSecurityDescriptorA(ptr long long ptr ptr)
-@ stdcall ConvertSecurityDescriptorToStringSecurityDescriptorW(ptr long long ptr ptr)
+@ stdcall -import ConvertSecurityDescriptorToStringSecurityDescriptorW(ptr long long ptr ptr)
@ stdcall ConvertSidToStringSidA(ptr ptr)
-@ stdcall ConvertSidToStringSidW(ptr ptr)
+@ stdcall -import ConvertSidToStringSidW(ptr ptr)
# @ stub ConvertStringSDToSDDomainA
# @ stub ConvertStringSDToSDDomainW
# @ stub ConvertStringSDToSDRootDomainA
# @ stub ConvertStringSDToSDRootDomainW
@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorA(str long ptr ptr)
-@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr)
+@ stdcall -import ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr)
@ stdcall ConvertStringSidToSidA(ptr ptr)
-@ stdcall ConvertStringSidToSidW(ptr ptr)
+@ stdcall -import ConvertStringSidToSidW(ptr ptr)
@ stdcall -import ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr)
@ stdcall -import CopySid(long ptr ptr)
# @ stub CreateCodeAuthzLevel
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index d3c9a6c1e2..fe2f0d9266 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -47,15 +47,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
static DWORD trustee_to_sid(DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee);
-typedef struct _ACEFLAG
-{
- LPCWSTR wstr;
- DWORD value;
-} ACEFLAG, *LPACEFLAG;
-
typedef struct _MAX_SID
{
/* same fields as struct _SID */
@@ -65,97 +58,6 @@ typedef struct _MAX_SID
DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
} MAX_SID;
-typedef struct WELLKNOWNSID
-{
- WCHAR wstr[2];
- WELL_KNOWN_SID_TYPE Type;
- MAX_SID Sid;
-} WELLKNOWNSID;
-
-static const WELLKNOWNSID WellKnownSids[] =
-{
- { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
- { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
- { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
- { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
- { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
- { {'O','W'}, WinCreatorOwnerRightsSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RIGHTS_RID } } },
- { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
- { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
- { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
- { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
- { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
- { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
- { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
- { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
- { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
- { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
- { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
- { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
- { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
- { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
- { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
- { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
- { {0,0}, WinLogonIdsSid, { SID_REVISION, SECURITY_LOGON_IDS_RID_COUNT, { SECURITY_NT_AUTHORITY }, { SECURITY_LOGON_IDS_RID } } },
- { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
- { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
- { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
- { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
- { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
- { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
- { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
- { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
- { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
- { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
- { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
- { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
- { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
- { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
- { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
- { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
- { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
- { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
- { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
- { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
- { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
- { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
- { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
- { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
- { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
- { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
- { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
- { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
- { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
- { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
- { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
- { {'A','C'}, WinBuiltinAnyPackageSid, { SID_REVISION, 2, { SECURITY_APP_PACKAGE_AUTHORITY }, { SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE } } },
-};
-
-/* these SIDs must be constructed as relative to some domain - only the RID is well-known */
-typedef struct WELLKNOWNRID
-{
- WCHAR wstr[2];
- WELL_KNOWN_SID_TYPE Type;
- DWORD Rid;
-} WELLKNOWNRID;
-
-static const WELLKNOWNRID WellKnownRids[] = {
- { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
- { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
- { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
- { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
- { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
- { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
- { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
- { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
- { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
- { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
- { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
- { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
- { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
-};
-
-
typedef struct _AccountSid {
WELL_KNOWN_SID_TYPE type;
LPCWSTR account;
@@ -275,69 +177,6 @@ static const AccountSid ACCOUNT_SIDS[] = {
{ WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
{ WinBuiltinAnyPackageSid, ALL_APPLICATION_PACKAGES, APPLICATION_PACKAGE_AUTHORITY, SidTypeWellKnownGroup },
};
-/*
- * ACE access rights
- */
-static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
-static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
-static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
-static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
-
-static const WCHAR SDDL_READ_PROPERTY[] = {'R','P',0};
-static const WCHAR SDDL_WRITE_PROPERTY[] = {'W','P',0};
-static const WCHAR SDDL_CREATE_CHILD[] = {'C','C',0};
-static const WCHAR SDDL_DELETE_CHILD[] = {'D','C',0};
-static const WCHAR SDDL_LIST_CHILDREN[] = {'L','C',0};
-static const WCHAR SDDL_SELF_WRITE[] = {'S','W',0};
-static const WCHAR SDDL_LIST_OBJECT[] = {'L','O',0};
-static const WCHAR SDDL_DELETE_TREE[] = {'D','T',0};
-static const WCHAR SDDL_CONTROL_ACCESS[] = {'C','R',0};
-
-static const WCHAR SDDL_FILE_ALL[] = {'F','A',0};
-static const WCHAR SDDL_FILE_READ[] = {'F','R',0};
-static const WCHAR SDDL_FILE_WRITE[] = {'F','W',0};
-static const WCHAR SDDL_FILE_EXECUTE[] = {'F','X',0};
-
-static const WCHAR SDDL_KEY_ALL[] = {'K','A',0};
-static const WCHAR SDDL_KEY_READ[] = {'K','R',0};
-static const WCHAR SDDL_KEY_WRITE[] = {'K','W',0};
-static const WCHAR SDDL_KEY_EXECUTE[] = {'K','X',0};
-
-static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
-static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
-static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
-static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
-
-static const WCHAR SDDL_NO_READ_UP[] = {'N','R',0};
-static const WCHAR SDDL_NO_WRITE_UP[] = {'N','W',0};
-static const WCHAR SDDL_NO_EXECUTE_UP[] = {'N','X',0};
-
-/*
- * ACL flags
- */
-static const WCHAR SDDL_PROTECTED[] = {'P',0};
-static const WCHAR SDDL_AUTO_INHERIT_REQ[] = {'A','R',0};
-static const WCHAR SDDL_AUTO_INHERITED[] = {'A','I',0};
-
-/*
- * ACE types
- */
-static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
-static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
-static const WCHAR SDDL_AUDIT[] = {'A','U',0};
-static const WCHAR SDDL_ALARM[] = {'A','L',0};
-static const WCHAR SDDL_MANDATORY_LABEL[] = {'M','L',0};
-
-/*
- * ACE flags
- */
-static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
-static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
-static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
-static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
-static const WCHAR SDDL_INHERITED[] = {'I','D',0};
-static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
-static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
const char * debugstr_sid(PSID sid)
{
@@ -2807,481 +2646,6 @@ DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCE
}
-/******************************************************************************
- * ParseAclStringFlags
- */
-static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
-{
- DWORD flags = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl && *szAcl != '(')
- {
- if (*szAcl == 'P')
- {
- flags |= SE_DACL_PROTECTED;
- }
- else if (*szAcl == 'A')
- {
- szAcl++;
- if (*szAcl == 'R')
- flags |= SE_DACL_AUTO_INHERIT_REQ;
- else if (*szAcl == 'I')
- flags |= SE_DACL_AUTO_INHERITED;
- }
- szAcl++;
- }
-
- *StringAcl = szAcl;
- return flags;
-}
-
-/******************************************************************************
- * ParseAceStringType
- */
-static const ACEFLAG AceType[] =
-{
- { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
- { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
- { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
- { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
- { SDDL_MANDATORY_LABEL,SYSTEM_MANDATORY_LABEL_ACE_TYPE },
- /*
- { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
- */
- { NULL, 0 },
-};
-
-static BYTE ParseAceStringType(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- LPCWSTR szAcl = *StringAcl;
- const ACEFLAG *lpaf = AceType;
-
- while (*szAcl == ' ')
- szAcl++;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- lpaf++;
-
- if (!lpaf->wstr)
- return 0;
-
- *StringAcl = szAcl + len;
- return lpaf->value;
-}
-
-
-/******************************************************************************
- * ParseAceStringFlags
- */
-static const ACEFLAG AceFlags[] =
-{
- { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
- { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
- { SDDL_INHERITED, INHERITED_ACE },
- { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
- { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
- { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
- { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
- { NULL, 0 },
-};
-
-static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- BYTE flags = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl == ' ')
- szAcl++;
-
- while (*szAcl != ';')
- {
- const ACEFLAG *lpaf = AceFlags;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- lpaf++;
-
- if (!lpaf->wstr)
- return 0;
-
- flags |= lpaf->value;
- szAcl += len;
- }
-
- *StringAcl = szAcl;
- return flags;
-}
-
-
-/******************************************************************************
- * ParseAceStringRights
- */
-static const ACEFLAG AceRights[] =
-{
- { SDDL_GENERIC_ALL, GENERIC_ALL },
- { SDDL_GENERIC_READ, GENERIC_READ },
- { SDDL_GENERIC_WRITE, GENERIC_WRITE },
- { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
-
- { SDDL_READ_CONTROL, READ_CONTROL },
- { SDDL_STANDARD_DELETE, DELETE },
- { SDDL_WRITE_DAC, WRITE_DAC },
- { SDDL_WRITE_OWNER, WRITE_OWNER },
-
- { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
- { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
- { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
- { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
- { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
- { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
- { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
- { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
- { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
-
- { SDDL_FILE_ALL, FILE_ALL_ACCESS },
- { SDDL_FILE_READ, FILE_GENERIC_READ },
- { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
- { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
-
- { SDDL_KEY_ALL, KEY_ALL_ACCESS },
- { SDDL_KEY_READ, KEY_READ },
- { SDDL_KEY_WRITE, KEY_WRITE },
- { SDDL_KEY_EXECUTE, KEY_EXECUTE },
-
- { SDDL_NO_READ_UP, SYSTEM_MANDATORY_LABEL_NO_READ_UP },
- { SDDL_NO_WRITE_UP, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
- { SDDL_NO_EXECUTE_UP, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
- { NULL, 0 },
-};
-
-static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- DWORD rights = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl == ' ')
- szAcl++;
-
- if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
- {
- LPCWSTR p = szAcl;
-
- while (*p && *p != ';')
- p++;
-
- if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
- {
- rights = strtoulW(szAcl, NULL, 16);
- szAcl = p;
- }
- else
- WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
- }
- else
- {
- while (*szAcl != ';')
- {
- const ACEFLAG *lpaf = AceRights;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- {
- lpaf++;
- }
-
- if (!lpaf->wstr)
- return 0;
-
- rights |= lpaf->value;
- szAcl += len;
- }
- }
-
- *StringAcl = szAcl;
- return rights;
-}
-
-
-/******************************************************************************
- * ParseStringAclToAcl
- *
- * dacl_flags(string_ace1)(string_ace2)... (string_acen)
- */
-static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
- PACL pAcl, LPDWORD cBytes)
-{
- DWORD val;
- DWORD sidlen;
- DWORD length = sizeof(ACL);
- DWORD acesize = 0;
- DWORD acecount = 0;
- PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
- DWORD error = ERROR_INVALID_ACL;
-
- TRACE("%s\n", debugstr_w(StringAcl));
-
- if (!StringAcl)
- return FALSE;
-
- if (pAcl) /* pAce is only useful if we're setting values */
- pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
-
- /* Parse ACL flags */
- *lpdwFlags = ParseAclStringFlags(&StringAcl);
-
- /* Parse ACE */
- while (*StringAcl == '(')
- {
- StringAcl++;
-
- /* Parse ACE type */
- val = ParseAceStringType(&StringAcl);
- if (pAce)
- pAce->Header.AceType = (BYTE) val;
- if (*StringAcl != ';')
- {
- error = RPC_S_INVALID_STRING_UUID;
- goto lerr;
- }
- StringAcl++;
-
- /* Parse ACE flags */
- val = ParseAceStringFlags(&StringAcl);
- if (pAce)
- pAce->Header.AceFlags = (BYTE) val;
- if (*StringAcl != ';')
- goto lerr;
- StringAcl++;
-
- /* Parse ACE rights */
- val = ParseAceStringRights(&StringAcl);
- if (pAce)
- pAce->Mask = val;
- if (*StringAcl != ';')
- goto lerr;
- StringAcl++;
-
- /* Parse ACE object guid */
- while (*StringAcl == ' ')
- StringAcl++;
- if (*StringAcl != ';')
- {
- FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
- goto lerr;
- }
- StringAcl++;
-
- /* Parse ACE inherit object guid */
- while (*StringAcl == ' ')
- StringAcl++;
- if (*StringAcl != ';')
- {
- FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
- goto lerr;
- }
- StringAcl++;
-
- /* Parse ACE account sid */
- if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
- {
- while (*StringAcl && *StringAcl != ')')
- StringAcl++;
- }
-
- if (*StringAcl != ')')
- goto lerr;
- StringAcl++;
-
- acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
- length += acesize;
- if (pAce)
- {
- pAce->Header.AceSize = acesize;
- pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
- }
- acecount++;
- }
-
- *cBytes = length;
-
- if (length > 0xffff)
- {
- ERR("ACL too large\n");
- goto lerr;
- }
-
- if (pAcl)
- {
- pAcl->AclRevision = ACL_REVISION;
- pAcl->Sbz1 = 0;
- pAcl->AclSize = length;
- pAcl->AceCount = acecount;
- pAcl->Sbz2 = 0;
- }
- return TRUE;
-
-lerr:
- SetLastError(error);
- WARN("Invalid ACE string format\n");
- return FALSE;
-}
-
-
-/******************************************************************************
- * ParseStringSecurityDescriptorToSecurityDescriptor
- */
-static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
- LPCWSTR StringSecurityDescriptor,
- SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
- LPDWORD cBytes)
-{
- BOOL bret = FALSE;
- WCHAR toktype;
- WCHAR *tok;
- LPCWSTR lptoken;
- LPBYTE lpNext = NULL;
- DWORD len;
-
- *cBytes = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-
- tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
-
- if (SecurityDescriptor)
- lpNext = (LPBYTE)(SecurityDescriptor + 1);
-
- while (*StringSecurityDescriptor == ' ')
- StringSecurityDescriptor++;
-
- while (*StringSecurityDescriptor)
- {
- toktype = *StringSecurityDescriptor;
-
- /* Expect char identifier followed by ':' */
- StringSecurityDescriptor++;
- if (*StringSecurityDescriptor != ':')
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
- StringSecurityDescriptor++;
-
- /* Extract token */
- lptoken = StringSecurityDescriptor;
- while (*lptoken && *lptoken != ':')
- lptoken++;
-
- if (*lptoken)
- lptoken--;
-
- len = lptoken - StringSecurityDescriptor;
- memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
- tok[len] = 0;
-
- switch (toktype)
- {
- case 'O':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'G':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'D':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
- SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'S':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
- SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- default:
- FIXME("Unknown token\n");
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
-
- StringSecurityDescriptor = lptoken;
- }
-
- bret = TRUE;
-
-lend:
- heap_free(tok);
- return bret;
-}
-
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
*/
@@ -3309,471 +2673,6 @@ BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
return ret;
}
-/******************************************************************************
- * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
- */
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
- LPCWSTR StringSecurityDescriptor,
- DWORD StringSDRevision,
- PSECURITY_DESCRIPTOR* SecurityDescriptor,
- PULONG SecurityDescriptorSize)
-{
- DWORD cBytes;
- SECURITY_DESCRIPTOR* psd;
- BOOL bret = FALSE;
-
- TRACE("%s, %u, %p, %p\n", debugstr_w(StringSecurityDescriptor), StringSDRevision,
- SecurityDescriptor, SecurityDescriptorSize);
-
- if (GetVersion() & 0x80000000)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- goto lend;
- }
- else if (!StringSecurityDescriptor || !SecurityDescriptor)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
- else if (StringSDRevision != SID_REVISION)
- {
- SetLastError(ERROR_UNKNOWN_REVISION);
- goto lend;
- }
-
- /* Compute security descriptor length */
- if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
- NULL, &cBytes))
- goto lend;
-
- psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
- if (!psd) goto lend;
-
- psd->Revision = SID_REVISION;
- psd->Control |= SE_SELF_RELATIVE;
-
- if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
- (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
- {
- LocalFree(psd);
- goto lend;
- }
-
- if (SecurityDescriptorSize)
- *SecurityDescriptorSize = cBytes;
-
- bret = TRUE;
-
-lend:
- TRACE(" ret=%d\n", bret);
- return bret;
-}
-
-static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
-{
- if (cch == -1)
- cch = strlenW(string);
-
- if (plen)
- *plen += cch;
-
- if (pwptr)
- {
- memcpy(*pwptr, string, sizeof(WCHAR)*cch);
- *pwptr += cch;
- }
-}
-
-static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
- static const WCHAR subauthfmt[] = { '-','%','u',0 };
- DWORD i;
- WCHAR buf[26];
- SID *pisid = psid;
-
- if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
- {
- SetLastError(ERROR_INVALID_SID);
- return FALSE;
- }
-
- if (pisid->IdentifierAuthority.Value[0] ||
- pisid->IdentifierAuthority.Value[1])
- {
- FIXME("not matching MS' bugs\n");
- SetLastError(ERROR_INVALID_SID);
- return FALSE;
- }
-
- sprintfW( buf, fmt, pisid->Revision,
- MAKELONG(
- MAKEWORD( pisid->IdentifierAuthority.Value[5],
- pisid->IdentifierAuthority.Value[4] ),
- MAKEWORD( pisid->IdentifierAuthority.Value[3],
- pisid->IdentifierAuthority.Value[2] )
- ) );
- DumpString(buf, -1, pwptr, plen);
-
- for( i=0; i<pisid->SubAuthorityCount; i++ )
- {
- sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
- DumpString(buf, -1, pwptr, plen);
- }
- return TRUE;
-}
-
-static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
-{
- size_t i;
- for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
- {
- if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
- {
- DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
- return TRUE;
- }
- }
-
- return DumpSidNumeric(psid, pwptr, plen);
-}
-
-static const LPCWSTR AceRightBitNames[32] = {
- SDDL_CREATE_CHILD, /* 0 */
- SDDL_DELETE_CHILD,
- SDDL_LIST_CHILDREN,
- SDDL_SELF_WRITE,
- SDDL_READ_PROPERTY, /* 4 */
- SDDL_WRITE_PROPERTY,
- SDDL_DELETE_TREE,
- SDDL_LIST_OBJECT,
- SDDL_CONTROL_ACCESS, /* 8 */
- NULL,
- NULL,
- NULL,
- NULL, /* 12 */
- NULL,
- NULL,
- NULL,
- SDDL_STANDARD_DELETE, /* 16 */
- SDDL_READ_CONTROL,
- SDDL_WRITE_DAC,
- SDDL_WRITE_OWNER,
- NULL, /* 20 */
- NULL,
- NULL,
- NULL,
- NULL, /* 24 */
- NULL,
- NULL,
- NULL,
- SDDL_GENERIC_ALL, /* 28 */
- SDDL_GENERIC_EXECUTE,
- SDDL_GENERIC_WRITE,
- SDDL_GENERIC_READ
-};
-
-static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR fmtW[] = {'0','x','%','x',0};
- WCHAR buf[15];
- size_t i;
-
- if (mask == 0)
- return;
-
- /* first check if the right have name */
- for (i = 0; i < ARRAY_SIZE(AceRights); i++)
- {
- if (AceRights[i].wstr == NULL)
- break;
- if (mask == AceRights[i].value)
- {
- DumpString(AceRights[i].wstr, -1, pwptr, plen);
- return;
- }
- }
-
- /* then check if it can be built from bit names */
- for (i = 0; i < 32; i++)
- {
- if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
- {
- /* can't be built from bit names */
- sprintfW(buf, fmtW, mask);
- DumpString(buf, -1, pwptr, plen);
- return;
- }
- }
-
- /* build from bit names */
- for (i = 0; i < 32; i++)
- if (mask & (1 << i))
- DumpString(AceRightBitNames[i], -1, pwptr, plen);
-}
-
-static inline BOOL is_object_ace(BYTE AceType)
-{
- switch (AceType)
- {
- case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
- case ACCESS_DENIED_OBJECT_ACE_TYPE:
- case ACCESS_AUDIT_OBJECT_ACE_TYPE:
- case ACCESS_ALARM_OBJECT_ACE_TYPE:
- case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
- case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
- case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
- case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE:
- return TRUE;
-
- default: return FALSE;
- }
-}
-
-static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
-{
- ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
- static const WCHAR openbr = '(';
- static const WCHAR closebr = ')';
- static const WCHAR semicolon = ';';
- DWORD *SidStart;
-
- piace = pace;
-
- if (piace->Header.AceType > ACCESS_MAX_MS_V5_ACE_TYPE || piace->Header.AceSize < sizeof(ACCESS_ALLOWED_ACE))
- {
- SetLastError(ERROR_INVALID_ACL);
- return FALSE;
- }
-
- DumpString(&openbr, 1, pwptr, plen);
- switch (piace->Header.AceType)
- {
- case ACCESS_ALLOWED_ACE_TYPE:
- DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
- break;
- case ACCESS_DENIED_ACE_TYPE:
- DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
- break;
- case SYSTEM_AUDIT_ACE_TYPE:
- DumpString(SDDL_AUDIT, -1, pwptr, plen);
- break;
- case SYSTEM_ALARM_ACE_TYPE:
- DumpString(SDDL_ALARM, -1, pwptr, plen);
- break;
- }
- DumpString(&semicolon, 1, pwptr, plen);
-
- if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
- DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
- if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
- DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
- if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
- DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
- if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
- DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
- if (piace->Header.AceFlags & INHERITED_ACE)
- DumpString(SDDL_INHERITED, -1, pwptr, plen);
- if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
- DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
- if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
- DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
- DumpString(&semicolon, 1, pwptr, plen);
- DumpRights(piace->Mask, pwptr, plen);
- DumpString(&semicolon, 1, pwptr, plen);
- SidStart = &piace->SidStart;
- if (is_object_ace(piace->Header.AceType))
- {
- ACCESS_ALLOWED_OBJECT_ACE *objace = pace;
-
- SidStart++; /* Flags */
- if (objace->Flags & ACE_OBJECT_TYPE_PRESENT)
- SidStart += sizeof(GUID) / sizeof(*SidStart); /* ObjectType */
- if (objace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
- SidStart += sizeof(GUID) / sizeof(*SidStart); /* InheritedObjectType */
- }
- /* objects not supported */
- DumpString(&semicolon, 1, pwptr, plen);
- /* objects not supported */
- DumpString(&semicolon, 1, pwptr, plen);
- if (!DumpSid(SidStart, pwptr, plen))
- return FALSE;
- DumpString(&closebr, 1, pwptr, plen);
- return TRUE;
-}
-
-static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
-{
- WORD count;
- UINT i;
-
- if (protected)
- DumpString(SDDL_PROTECTED, -1, pwptr, plen);
- if (autoInheritReq)
- DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
- if (autoInherited)
- DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
-
- if (pacl == NULL)
- return TRUE;
-
- if (!IsValidAcl(pacl))
- return FALSE;
-
- count = pacl->AceCount;
- for (i = 0; i < count; i++)
- {
- LPVOID ace;
- if (!GetAce(pacl, i, &ace))
- return FALSE;
- if (!DumpAce(ace, pwptr, plen))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR prefix[] = {'O',':',0};
- BOOL bDefaulted;
- PSID psid;
-
- if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
- return FALSE;
-
- if (psid == NULL)
- return TRUE;
-
- DumpString(prefix, -1, pwptr, plen);
- if (!DumpSid(psid, pwptr, plen))
- return FALSE;
- return TRUE;
-}
-
-static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR prefix[] = {'G',':',0};
- BOOL bDefaulted;
- PSID psid;
-
- if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
- return FALSE;
-
- if (psid == NULL)
- return TRUE;
-
- DumpString(prefix, -1, pwptr, plen);
- if (!DumpSid(psid, pwptr, plen))
- return FALSE;
- return TRUE;
-}
-
-static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR dacl[] = {'D',':',0};
- SECURITY_DESCRIPTOR_CONTROL control;
- BOOL present, defaulted;
- DWORD revision;
- PACL pacl;
-
- if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
- return FALSE;
-
- if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
- return FALSE;
-
- if (!present)
- return TRUE;
-
- DumpString(dacl, 2, pwptr, plen);
- if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
- return FALSE;
- return TRUE;
-}
-
-static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR sacl[] = {'S',':',0};
- SECURITY_DESCRIPTOR_CONTROL control;
- BOOL present, defaulted;
- DWORD revision;
- PACL pacl;
-
- if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
- return FALSE;
-
- if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
- return FALSE;
-
- if (!present)
- return TRUE;
-
- DumpString(sacl, 2, pwptr, plen);
- if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
- return FALSE;
- return TRUE;
-}
-
-/******************************************************************************
- * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
- */
-BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
-{
- ULONG len;
- WCHAR *wptr, *wstr;
-
- if (SDRevision != SDDL_REVISION_1)
- {
- ERR("Program requested unknown SDDL revision %d\n", SDRevision);
- SetLastError(ERROR_UNKNOWN_REVISION);
- return FALSE;
- }
-
- len = 0;
- if (RequestedInformation & OWNER_SECURITY_INFORMATION)
- if (!DumpOwner(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (RequestedInformation & GROUP_SECURITY_INFORMATION)
- if (!DumpGroup(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (RequestedInformation & DACL_SECURITY_INFORMATION)
- if (!DumpDacl(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (RequestedInformation & SACL_SECURITY_INFORMATION)
- if (!DumpSacl(SecurityDescriptor, NULL, &len))
- return FALSE;
-
- wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
- if (RequestedInformation & OWNER_SECURITY_INFORMATION)
- if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
- LocalFree (wstr);
- return FALSE;
- }
- if (RequestedInformation & GROUP_SECURITY_INFORMATION)
- if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
- LocalFree (wstr);
- return FALSE;
- }
- if (RequestedInformation & DACL_SECURITY_INFORMATION)
- if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
- LocalFree (wstr);
- return FALSE;
- }
- if (RequestedInformation & SACL_SECURITY_INFORMATION)
- if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
- LocalFree (wstr);
- return FALSE;
- }
- *wptr = 0;
-
- TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
- *OutputString = wstr;
- if (OutputLen)
- *OutputLen = strlenW(*OutputString)+1;
- return TRUE;
-}
-
/******************************************************************************
* ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
*/
@@ -3803,30 +2702,6 @@ BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCR
}
}
-/******************************************************************************
- * ConvertStringSidToSidW [ADVAPI32.@]
- */
-BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
-{
- BOOL bret = FALSE;
- DWORD cBytes;
-
- TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
- if (GetVersion() & 0x80000000)
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- else if (!StringSid || !Sid)
- SetLastError(ERROR_INVALID_PARAMETER);
- else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
- {
- PSID pSid = *Sid = LocalAlloc(0, cBytes);
-
- bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
- if (!bret)
- LocalFree(*Sid);
- }
- return bret;
-}
-
/******************************************************************************
* ConvertStringSidToSidA [ADVAPI32.@]
*/
@@ -3848,34 +2723,6 @@ BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
return bret;
}
-/******************************************************************************
- * ConvertSidToStringSidW [ADVAPI32.@]
- *
- * format of SID string is:
- * S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
- * where
- * <rev> is the revision of the SID encoded as decimal
- * <auth> is the identifier authority encoded as hex
- * <subauthN> is the subauthority id encoded as decimal
- */
-BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
-{
- DWORD len = 0;
- LPWSTR wstr, wptr;
-
- TRACE("%p %p\n", pSid, pstr );
-
- len = 0;
- if (!DumpSidNumeric(pSid, NULL, &len))
- return FALSE;
- wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
- DumpSidNumeric(pSid, &wptr, NULL);
- *wptr = 0;
-
- *pstr = wstr;
- return TRUE;
-}
-
/******************************************************************************
* ConvertSidToStringSidA [ADVAPI32.@]
*/
@@ -3929,167 +2776,6 @@ BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR app
current_directory, startup_info, process_information );
}
-/******************************************************************************
- * ComputeStringSidSize
- */
-static DWORD ComputeStringSidSize(LPCWSTR StringSid)
-{
- if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
- {
- int ctok = 0;
- while (*StringSid)
- {
- if (*StringSid == '-')
- ctok++;
- StringSid++;
- }
-
- if (ctok >= 3)
- return GetSidLengthRequired(ctok - 2);
- }
- else /* String constant format - Only available in winxp and above */
- {
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
- if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
- return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
-
- for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
- if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
- {
- MAX_SID local;
- ADVAPI_GetComputerSid(&local);
- return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1);
- }
-
- }
-
- return GetSidLengthRequired(0);
-}
-
-/******************************************************************************
- * ParseStringSidToSid
- */
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
-{
- BOOL bret = FALSE;
- SID* pisid=pSid;
-
- TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
- if (!StringSid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- TRACE("StringSid is NULL, returning FALSE\n");
- return FALSE;
- }
-
- while (*StringSid == ' ')
- StringSid++;
-
- *cBytes = ComputeStringSidSize(StringSid);
- if (!pisid) /* Simply compute the size */
- {
- TRACE("only size requested, returning TRUE with %d\n", *cBytes);
- return TRUE;
- }
-
- if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
- {
- DWORD i = 0, identAuth;
- DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
-
- StringSid += 2; /* Advance to Revision */
- pisid->Revision = atoiW(StringSid);
-
- if (pisid->Revision != SDDL_REVISION)
- {
- TRACE("Revision %d is unknown\n", pisid->Revision);
- goto lend; /* ERROR_INVALID_SID */
- }
- if (csubauth == 0)
- {
- TRACE("SubAuthorityCount is 0\n");
- goto lend; /* ERROR_INVALID_SID */
- }
-
- pisid->SubAuthorityCount = csubauth;
-
- /* Advance to identifier authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
-
- /* MS' implementation can't handle values greater than 2^32 - 1, so
- * we don't either; assume most significant bytes are always 0
- */
- pisid->IdentifierAuthority.Value[0] = 0;
- pisid->IdentifierAuthority.Value[1] = 0;
- identAuth = atoiW(StringSid);
- pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
- pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
- pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
- pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
-
- /* Advance to first sub authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
-
- while (*StringSid)
- {
- pisid->SubAuthority[i++] = atoiW(StringSid);
-
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
- }
-
- if (i != pisid->SubAuthorityCount)
- goto lend; /* ERROR_INVALID_SID */
-
- bret = TRUE;
- }
- else /* String constant format - Only available in winxp and above */
- {
- unsigned int i;
- pisid->Revision = SDDL_REVISION;
-
- for (i = 0; i < ARRAY_SIZE(WellKnownSids); i++)
- if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
- {
- DWORD j;
- pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
- pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
- for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
- pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
- bret = TRUE;
- }
-
- for (i = 0; i < ARRAY_SIZE(WellKnownRids); i++)
- if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2))
- {
- ADVAPI_GetComputerSid(pisid);
- pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid;
- pisid->SubAuthorityCount++;
- bret = TRUE;
- }
-
- if (!bret)
- FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
- }
-
-lend:
- if (!bret)
- SetLastError(ERROR_INVALID_SID);
-
- TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
- return bret;
-}
-
/******************************************************************************
* GetNamedSecurityInfoA [ADVAPI32.@]
*/
diff --git a/dlls/sechost/Makefile.in b/dlls/sechost/Makefile.in
index eb98d04859..91016c6757 100644
--- a/dlls/sechost/Makefile.in
+++ b/dlls/sechost/Makefile.in
@@ -6,6 +6,7 @@ DELAYIMPORTS = rpcrt4
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
+ security.c \
service.c \
trace.c
diff --git a/dlls/sechost/sechost.spec b/dlls/sechost/sechost.spec
index df6af1646d..f21e2f1cda 100644
--- a/dlls/sechost/sechost.spec
+++ b/dlls/sechost/sechost.spec
@@ -31,13 +31,13 @@
@ stdcall ControlTraceA(int64 str ptr long)
@ stdcall ControlTraceW(int64 wstr ptr long)
@ stub ConvertSDToStringSDRootDomainW
-@ stdcall ConvertSecurityDescriptorToStringSecurityDescriptorW(ptr long long ptr ptr) advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
-@ stdcall ConvertSidToStringSidW(ptr ptr) advapi32.ConvertSidToStringSidW
+@ stdcall ConvertSecurityDescriptorToStringSecurityDescriptorW(ptr long long ptr ptr)
+@ stdcall ConvertSidToStringSidW(ptr ptr)
@ stub ConvertStringSDToSDDomainA
@ stub ConvertStringSDToSDDomainW
@ stub ConvertStringSDToSDRootDomainW
-@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr) advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
-@ stdcall ConvertStringSidToSidW(ptr ptr) advapi32.ConvertStringSidToSidW
+@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr)
+@ stdcall ConvertStringSidToSidW(ptr ptr)
@ stdcall CreateServiceA(long str str long long long long str str ptr str str str)
@ stub CreateServiceEx
@ stdcall CreateServiceW(long wstr wstr long long long long wstr wstr ptr wstr wstr wstr)
diff --git a/dlls/sechost/security.c b/dlls/sechost/security.c
new file mode 100644
index 0000000000..47ffba9ed5
--- /dev/null
+++ b/dlls/sechost/security.c
@@ -0,0 +1,1247 @@
+/*
+ * Security API
+ *
+ * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "sddl.h"
+#include "iads.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(security);
+
+static const struct
+{
+ WCHAR str[3];
+ DWORD value;
+}
+ace_rights[] =
+{
+ { L"GA", GENERIC_ALL },
+ { L"GR", GENERIC_READ },
+ { L"GW", GENERIC_WRITE },
+ { L"GX", GENERIC_EXECUTE },
+
+ { L"RC", READ_CONTROL },
+ { L"SD", DELETE },
+ { L"WD", WRITE_DAC },
+ { L"WO", WRITE_OWNER },
+
+ { L"RP", ADS_RIGHT_DS_READ_PROP },
+ { L"WP", ADS_RIGHT_DS_WRITE_PROP },
+ { L"CC", ADS_RIGHT_DS_CREATE_CHILD },
+ { L"DC", ADS_RIGHT_DS_DELETE_CHILD },
+ { L"LC", ADS_RIGHT_ACTRL_DS_LIST },
+ { L"SW", ADS_RIGHT_DS_SELF },
+ { L"LO", ADS_RIGHT_DS_LIST_OBJECT },
+ { L"DT", ADS_RIGHT_DS_DELETE_TREE },
+ { L"CR", ADS_RIGHT_DS_CONTROL_ACCESS },
+
+ { L"FA", FILE_ALL_ACCESS },
+ { L"FR", FILE_GENERIC_READ },
+ { L"FW", FILE_GENERIC_WRITE },
+ { L"FX", FILE_GENERIC_EXECUTE },
+
+ { L"KA", KEY_ALL_ACCESS },
+ { L"KR", KEY_READ },
+ { L"KW", KEY_WRITE },
+ { L"KX", KEY_EXECUTE },
+
+ { L"NR", SYSTEM_MANDATORY_LABEL_NO_READ_UP },
+ { L"NW", SYSTEM_MANDATORY_LABEL_NO_WRITE_UP },
+ { L"NX", SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP },
+};
+
+struct max_sid
+{
+ /* same fields as struct _SID */
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
+};
+
+static const struct
+{
+ WCHAR str[2];
+ WELL_KNOWN_SID_TYPE Type;
+ struct max_sid sid;
+}
+well_known_sids[] =
+{
+ { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
+ { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
+ { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
+ { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
+ { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
+ { {'O','W'}, WinCreatorOwnerRightsSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RIGHTS_RID } } },
+ { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
+ { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
+ { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
+ { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
+ { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
+ { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
+ { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
+ { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
+ { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
+ { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
+ { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
+ { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
+ { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
+ { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
+ { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
+ { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
+ { {0,0}, WinLogonIdsSid, { SID_REVISION, SECURITY_LOGON_IDS_RID_COUNT, { SECURITY_NT_AUTHORITY }, { SECURITY_LOGON_IDS_RID } } },
+ { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
+ { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
+ { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
+ { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
+ { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
+ { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
+ { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
+ { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
+ { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
+ { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
+ { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
+ { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
+ { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
+ { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
+ { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
+ { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
+ { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
+ { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
+ { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
+ { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
+ { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
+ { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
+ { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
+ { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
+ { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
+ { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
+ { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
+ { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
+ { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
+ { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
+ { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
+ { {'A','C'}, WinBuiltinAnyPackageSid, { SID_REVISION, 2, { SECURITY_APP_PACKAGE_AUTHORITY }, { SECURITY_APP_PACKAGE_BASE_RID, SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE } } },
+};
+
+/* these SIDs must be constructed as relative to some domain - only the RID is well-known */
+static const struct
+{
+ WCHAR str[2];
+ WELL_KNOWN_SID_TYPE type;
+ DWORD rid;
+}
+well_known_rids[] =
+{
+ { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
+ { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
+ { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
+ { {'D','A'}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
+ { {'D','U'}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
+ { {'D','G'}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
+ { {'D','C'}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
+ { {'D','D'}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
+ { {'C','A'}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
+ { {'S','A'}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
+ { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
+ { {'P','A'}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
+ { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
+};
+
+
+static void print_string(const WCHAR *string, int cch, WCHAR **pwptr, ULONG *plen)
+{
+ if (cch == -1)
+ cch = wcslen(string);
+
+ if (plen)
+ *plen += cch;
+
+ if (pwptr)
+ {
+ memcpy(*pwptr, string, sizeof(WCHAR)*cch);
+ *pwptr += cch;
+ }
+}
+
+static BOOL print_sid_numeric(PSID psid, WCHAR **pwptr, ULONG *plen)
+{
+ DWORD i;
+ WCHAR buf[26];
+ SID *pisid = psid;
+
+ if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ if (pisid->IdentifierAuthority.Value[0] ||
+ pisid->IdentifierAuthority.Value[1])
+ {
+ FIXME("not matching MS' bugs\n");
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ swprintf( buf, ARRAY_SIZE(buf), L"S-%u-%d", pisid->Revision, MAKELONG(
+ MAKEWORD( pisid->IdentifierAuthority.Value[5], pisid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( pisid->IdentifierAuthority.Value[3], pisid->IdentifierAuthority.Value[2] )
+ ) );
+ print_string(buf, -1, pwptr, plen);
+
+ for( i=0; i<pisid->SubAuthorityCount; i++ )
+ {
+ swprintf( buf, ARRAY_SIZE(buf), L"-%u", pisid->SubAuthority[i] );
+ print_string(buf, -1, pwptr, plen);
+ }
+ return TRUE;
+}
+
+/******************************************************************************
+ * ConvertSidToStringSidW (sechost.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH ConvertSidToStringSidW( PSID sid, WCHAR **pstr )
+{
+ DWORD len = 0;
+ WCHAR *wstr, *wptr;
+
+ TRACE("%p %p\n", sid, pstr );
+
+ len = 0;
+ if (!print_sid_numeric( sid, NULL, &len ))
+ return FALSE;
+ wstr = wptr = LocalAlloc( 0, (len + 1) * sizeof(WCHAR) );
+ print_sid_numeric( sid, &wptr, NULL );
+ *wptr = 0;
+
+ *pstr = wstr;
+ return TRUE;
+}
+
+static BOOL print_sid(PSID psid, WCHAR **pwptr, ULONG *plen)
+{
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(well_known_sids); i++)
+ {
+ if (well_known_sids[i].str[0] && EqualSid(psid, (PSID)&well_known_sids[i].sid.Revision))
+ {
+ print_string(well_known_sids[i].str, 2, pwptr, plen);
+ return TRUE;
+ }
+ }
+
+ return print_sid_numeric(psid, pwptr, plen);
+}
+
+static void print_rights(DWORD mask, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR *bit_names[32] =
+ {
+ L"CC", /* 0 */
+ L"DC",
+ L"LC",
+ L"SW",
+ L"RP", /* 4 */
+ L"WP",
+ L"DT",
+ L"LO",
+ L"CR", /* 8 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 12 */
+ NULL,
+ NULL,
+ NULL,
+ L"SD", /* 16 */
+ L"RC",
+ L"WD",
+ L"WO",
+ NULL, /* 20 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 24 */
+ NULL,
+ NULL,
+ NULL,
+ L"GA", /* 28 */
+ L"GX",
+ L"GW",
+ L"GR",
+ };
+
+ WCHAR buf[15];
+ size_t i;
+
+ if (mask == 0)
+ return;
+
+ /* first check if the right have name */
+ for (i = 0; i < ARRAY_SIZE(ace_rights); i++)
+ {
+ if (mask == ace_rights[i].value)
+ {
+ print_string(ace_rights[i].str, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* then check if it can be built from bit names */
+ for (i = 0; i < 32; i++)
+ {
+ if ((mask & (1 << i)) && !bit_names[i])
+ {
+ /* can't be built from bit names */
+ swprintf(buf, ARRAY_SIZE(buf), L"0x%x", mask);
+ print_string(buf, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* build from bit names */
+ for (i = 0; i < 32; i++)
+ if (mask & (1 << i))
+ print_string(bit_names[i], -1, pwptr, plen);
+}
+
+static inline BOOL is_object_ace(BYTE type)
+{
+ switch (type)
+ {
+ case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+ case ACCESS_DENIED_OBJECT_ACE_TYPE:
+ case ACCESS_AUDIT_OBJECT_ACE_TYPE:
+ case ACCESS_ALARM_OBJECT_ACE_TYPE:
+ case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
+ case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
+ case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
+ case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+static BOOL print_ace(void *pace, WCHAR **pwptr, ULONG *plen)
+{
+ ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
+ DWORD *sid_start;
+
+ piace = pace;
+
+ if (piace->Header.AceType > ACCESS_MAX_MS_V5_ACE_TYPE || piace->Header.AceSize < sizeof(ACCESS_ALLOWED_ACE))
+ {
+ SetLastError(ERROR_INVALID_ACL);
+ return FALSE;
+ }
+
+ print_string(L"(", -1, pwptr, plen);
+ switch (piace->Header.AceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ print_string(L"A", -1, pwptr, plen);
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ print_string(L"D", -1, pwptr, plen);
+ break;
+ case SYSTEM_AUDIT_ACE_TYPE:
+ print_string(L"AU", -1, pwptr, plen);
+ break;
+ case SYSTEM_ALARM_ACE_TYPE:
+ print_string(L"AL", -1, pwptr, plen);
+ break;
+ }
+ print_string(L";", -1, pwptr, plen);
+
+ if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
+ print_string(L"OI", -1, pwptr, plen);
+ if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
+ print_string(L"CI", -1, pwptr, plen);
+ if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
+ print_string(L"NP", -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
+ print_string(L"IO", -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERITED_ACE)
+ print_string(L"ID", -1, pwptr, plen);
+ if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
+ print_string(L"SA", -1, pwptr, plen);
+ if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
+ print_string(L"FA", -1, pwptr, plen);
+ print_string(L";", -1, pwptr, plen);
+ print_rights(piace->Mask, pwptr, plen);
+ print_string(L";", -1, pwptr, plen);
+ sid_start = &piace->SidStart;
+ if (is_object_ace(piace->Header.AceType))
+ {
+ ACCESS_ALLOWED_OBJECT_ACE *objace = pace;
+
+ sid_start++; /* Flags */
+ if (objace->Flags & ACE_OBJECT_TYPE_PRESENT)
+ sid_start += sizeof(GUID) / sizeof(*sid_start); /* ObjectType */
+ if (objace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
+ sid_start += sizeof(GUID) / sizeof(*sid_start); /* InheritedObjectType */
+ }
+ /* objects not supported */
+ print_string(L";", -1, pwptr, plen);
+ /* objects not supported */
+ print_string(L";", -1, pwptr, plen);
+ if (!print_sid(sid_start, pwptr, plen))
+ return FALSE;
+ print_string(L")", -1, pwptr, plen);
+ return TRUE;
+}
+
+static BOOL print_acl(ACL *pacl, WCHAR **pwptr, ULONG *plen, SECURITY_DESCRIPTOR_CONTROL control)
+{
+ WORD count;
+ UINT i;
+
+ if (control & SE_DACL_PROTECTED)
+ print_string(L"P", -1, pwptr, plen);
+ if (control & SE_DACL_AUTO_INHERIT_REQ)
+ print_string(L"AR", -1, pwptr, plen);
+ if (control & SE_DACL_AUTO_INHERITED)
+ print_string(L"AI", -1, pwptr, plen);
+
+ if (pacl == NULL)
+ return TRUE;
+
+ if (!IsValidAcl(pacl))
+ return FALSE;
+
+ count = pacl->AceCount;
+ for (i = 0; i < count; i++)
+ {
+ void *ace;
+ if (!GetAce(pacl, i, &ace))
+ return FALSE;
+ if (!print_ace(ace, pwptr, plen))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL print_owner(PSECURITY_DESCRIPTOR sd, WCHAR **pwptr, ULONG *plen)
+{
+ BOOL defaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorOwner(sd, &psid, &defaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ print_string(L"O:", -1, pwptr, plen);
+ if (!print_sid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL print_group(PSECURITY_DESCRIPTOR sd, WCHAR **pwptr, ULONG *plen)
+{
+ BOOL defaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorGroup(sd, &psid, &defaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ print_string(L"G:", -1, pwptr, plen);
+ if (!print_sid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL print_dacl(PSECURITY_DESCRIPTOR sd, WCHAR **pwptr, ULONG *plen)
+{
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ ACL *pacl;
+
+ if (!GetSecurityDescriptorDacl(sd, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(sd, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ print_string(L"D:", -1, pwptr, plen);
+ if (!print_acl(pacl, pwptr, plen, control))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL print_sacl(PSECURITY_DESCRIPTOR sd, WCHAR **pwptr, ULONG *plen)
+{
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ ACL *pacl;
+
+ if (!GetSecurityDescriptorSacl(sd, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(sd, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ print_string(L"S:", -1, pwptr, plen);
+ if (!print_acl(pacl, pwptr, plen, control))
+ return FALSE;
+ return TRUE;
+}
+
+/******************************************************************************
+ * ConvertSecurityDescriptorToStringSecurityDescriptorW (sechost.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH ConvertSecurityDescriptorToStringSecurityDescriptorW( PSECURITY_DESCRIPTOR sd,
+ DWORD revision, SECURITY_INFORMATION flags, WCHAR **string, ULONG *ret_len )
+{
+ ULONG len = 0;
+ WCHAR *wptr, *wstr;
+
+ if (revision != SDDL_REVISION_1)
+ {
+ ERR("Unhandled SDDL revision %d\n", revision);
+ SetLastError( ERROR_UNKNOWN_REVISION );
+ return FALSE;
+ }
+
+ if ((flags & OWNER_SECURITY_INFORMATION) && !print_owner(sd, NULL, &len))
+ return FALSE;
+ if ((flags & GROUP_SECURITY_INFORMATION) && !print_group(sd, NULL, &len))
+ return FALSE;
+ if ((flags & DACL_SECURITY_INFORMATION) && !print_dacl(sd, NULL, &len))
+ return FALSE;
+ if ((flags & SACL_SECURITY_INFORMATION) && !print_sacl(sd, NULL, &len))
+ return FALSE;
+
+ wstr = wptr = LocalAlloc( 0, (len + 1) * sizeof(WCHAR) );
+ if ((flags & OWNER_SECURITY_INFORMATION) && !print_owner(sd, &wptr, NULL))
+ {
+ LocalFree(wstr);
+ return FALSE;
+ }
+ if ((flags & GROUP_SECURITY_INFORMATION) && !print_group(sd, &wptr, NULL))
+ {
+ LocalFree(wstr);
+ return FALSE;
+ }
+ if ((flags & DACL_SECURITY_INFORMATION) && !print_dacl(sd, &wptr, NULL))
+ {
+ LocalFree(wstr);
+ return FALSE;
+ }
+ if ((flags & SACL_SECURITY_INFORMATION) && !print_sacl(sd, &wptr, NULL))
+ {
+ LocalFree(wstr);
+ return FALSE;
+ }
+ *wptr = 0;
+
+ TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
+ *string = wstr;
+ if (ret_len) *ret_len = wcslen(*string) + 1;
+ return TRUE;
+}
+
+static BOOL get_computer_sid( PSID sid )
+{
+ static const struct /* same fields as struct SID */
+ {
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[4];
+ } computer_sid =
+ { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
+
+ memcpy( sid, &computer_sid, sizeof(computer_sid) );
+ return TRUE;
+}
+
+static DWORD get_sid_size( const WCHAR *string )
+{
+ if (string[0] == 'S' && string[1] == '-') /* S-R-I(-S)+ */
+ {
+ int token_count = 0;
+ while (*string)
+ {
+ if (*string == '-')
+ token_count++;
+ string++;
+ }
+
+ if (token_count >= 3)
+ return GetSidLengthRequired( token_count - 2 );
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(well_known_sids); i++)
+ {
+ if (!wcsncmp( well_known_sids[i].str, string, 2 ))
+ return GetSidLengthRequired( well_known_sids[i].sid.SubAuthorityCount );
+ }
+
+ for (i = 0; i < ARRAY_SIZE(well_known_rids); i++)
+ {
+ if (!wcsncmp( well_known_rids[i].str, string, 2 ))
+ {
+ struct max_sid local;
+ get_computer_sid(&local);
+ return GetSidLengthRequired( *GetSidSubAuthorityCount(&local) + 1 );
+ }
+ }
+ }
+
+ return GetSidLengthRequired( 0 );
+}
+
+static BOOL parse_sid( const WCHAR *string, SID *pisid, DWORD *size )
+{
+ while (*string == ' ')
+ string++;
+
+ *size = get_sid_size( string );
+ if (!pisid) /* Simply compute the size */
+ return TRUE;
+
+ if (string[0] == 'S' && string[1] == '-') /* S-R-I-S-S */
+ {
+ DWORD i = 0, identAuth;
+ DWORD csubauth = ((*size - GetSidLengthRequired(0)) / sizeof(DWORD));
+
+ string += 2; /* Advance to Revision */
+ pisid->Revision = wcstoul( string, NULL, 10 );
+
+ if (pisid->Revision != SDDL_REVISION)
+ {
+ TRACE("Revision %d is unknown\n", pisid->Revision);
+ SetLastError( ERROR_INVALID_SID );
+ return FALSE;
+ }
+ if (csubauth == 0)
+ {
+ TRACE("SubAuthorityCount is 0\n");
+ SetLastError( ERROR_INVALID_SID );
+ return FALSE;
+ }
+
+ pisid->SubAuthorityCount = csubauth;
+
+ /* Advance to identifier authority */
+ while (*string && *string != '-')
+ string++;
+ if (*string == '-')
+ string++;
+
+ /* MS' implementation can't handle values greater than 2^32 - 1, so
+ * we don't either; assume most significant bytes are always 0
+ */
+ pisid->IdentifierAuthority.Value[0] = 0;
+ pisid->IdentifierAuthority.Value[1] = 0;
+ identAuth = wcstoul( string, NULL, 10 );
+ pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+ pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+ pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+ pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+
+ /* Advance to first sub authority */
+ while (*string && *string != '-')
+ string++;
+ if (*string == '-')
+ string++;
+
+ while (*string)
+ {
+ pisid->SubAuthority[i++] = wcstoul( string, NULL, 10 );
+
+ while (*string && *string != '-')
+ string++;
+ if (*string == '-')
+ string++;
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ {
+ SetLastError( ERROR_INVALID_SID );
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ unsigned int i;
+ pisid->Revision = SDDL_REVISION;
+
+ for (i = 0; i < ARRAY_SIZE(well_known_sids); i++)
+ {
+ if (!wcsncmp(well_known_sids[i].str, string, 2))
+ {
+ DWORD j;
+ pisid->SubAuthorityCount = well_known_sids[i].sid.SubAuthorityCount;
+ pisid->IdentifierAuthority = well_known_sids[i].sid.IdentifierAuthority;
+ for (j = 0; j < well_known_sids[i].sid.SubAuthorityCount; j++)
+ pisid->SubAuthority[j] = well_known_sids[i].sid.SubAuthority[j];
+ return TRUE;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(well_known_rids); i++)
+ {
+ if (!wcsncmp(well_known_rids[i].str, string, 2))
+ {
+ get_computer_sid(pisid);
+ pisid->SubAuthority[pisid->SubAuthorityCount] = well_known_rids[i].rid;
+ pisid->SubAuthorityCount++;
+ return TRUE;
+ }
+ }
+
+ FIXME("String constant not supported: %s\n", debugstr_wn(string, 2));
+ SetLastError( ERROR_INVALID_SID );
+ return FALSE;
+ }
+}
+
+/******************************************************************************
+ * ConvertStringSidToSidW (sechost.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH ConvertStringSidToSidW( const WCHAR *string, PSID *sid )
+{
+ DWORD size;
+
+ TRACE("%s, %p\n", debugstr_w(string), sid);
+
+ if (GetVersion() & 0x80000000)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+ }
+
+ if (!string || !sid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!parse_sid( string, NULL, &size ))
+ return FALSE;
+
+ *sid = LocalAlloc( 0, size );
+
+ if (!parse_sid( string, *sid, &size ))
+ {
+ LocalFree( *sid );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static DWORD parse_acl_flags( const WCHAR **string_ptr )
+{
+ DWORD flags = 0;
+ const WCHAR *string = *string_ptr;
+
+ while (*string && *string != '(')
+ {
+ if (*string == 'P')
+ {
+ flags |= SE_DACL_PROTECTED;
+ }
+ else if (*string == 'A')
+ {
+ string++;
+ if (*string == 'R')
+ flags |= SE_DACL_AUTO_INHERIT_REQ;
+ else if (*string == 'I')
+ flags |= SE_DACL_AUTO_INHERITED;
+ }
+ string++;
+ }
+
+ *string_ptr = string;
+ return flags;
+}
+
+static BYTE parse_ace_type( const WCHAR **string_ptr )
+{
+ static const struct
+ {
+ const WCHAR *str;
+ DWORD value;
+ }
+ ace_types[] =
+ {
+ { L"AL", SYSTEM_ALARM_ACE_TYPE },
+ { L"AU", SYSTEM_AUDIT_ACE_TYPE },
+ { L"A", ACCESS_ALLOWED_ACE_TYPE },
+ { L"D", ACCESS_DENIED_ACE_TYPE },
+ { L"ML", SYSTEM_MANDATORY_LABEL_ACE_TYPE },
+ /*
+ { ACCESS_ALLOWED_OBJECT_ACE_TYPE },
+ { ACCESS_DENIED_OBJECT_ACE_TYPE },
+ { SYSTEM_ALARM_OBJECT_ACE_TYPE },
+ { SYSTEM_AUDIT_OBJECT_ACE_TYPE },
+ */
+ };
+
+ const WCHAR *string = *string_ptr;
+ unsigned int i;
+
+ while (*string == ' ')
+ string++;
+
+ for (i = 0; i < ARRAY_SIZE(ace_types); ++i)
+ {
+ size_t len = wcslen( ace_types[i].str );
+ if (!wcsncmp( string, ace_types[i].str, len ))
+ {
+ *string_ptr = string + len;
+ return ace_types[i].value;
+ }
+ }
+ return 0;
+}
+
+static DWORD parse_ace_flag( const WCHAR *string )
+{
+ static const struct
+ {
+ WCHAR str[3];
+ DWORD value;
+ }
+ ace_flags[] =
+ {
+ { L"CI", CONTAINER_INHERIT_ACE },
+ { L"FA", FAILED_ACCESS_ACE_FLAG },
+ { L"ID", INHERITED_ACE },
+ { L"IO", INHERIT_ONLY_ACE },
+ { L"NP", NO_PROPAGATE_INHERIT_ACE },
+ { L"OI", OBJECT_INHERIT_ACE },
+ { L"SA", SUCCESSFUL_ACCESS_ACE_FLAG },
+ };
+
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ace_flags); ++i)
+ {
+ if (!wcsncmp( string, ace_flags[i].str, 2 ))
+ return ace_flags[i].value;
+ }
+ return 0;
+}
+
+static DWORD parse_ace_right( const WCHAR *string )
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ace_rights); ++i)
+ {
+ if (!wcsncmp( string, ace_rights[i].str, 2 ))
+ return ace_rights[i].value;
+ }
+ return 0;
+}
+
+static BYTE parse_ace_flags( const WCHAR **string_ptr )
+{
+ const WCHAR *string = *string_ptr;
+ BYTE flags = 0;
+
+ while (*string == ' ')
+ string++;
+
+ while (*string != ';')
+ {
+ DWORD flag = parse_ace_flag( string );
+ if (!flag) return 0;
+ flags |= flag;
+ string += 2;
+ }
+
+ *string_ptr = string;
+ return flags;
+}
+
+static DWORD parse_ace_rights( const WCHAR **string_ptr )
+{
+ DWORD rights = 0;
+ const WCHAR *string = *string_ptr;
+
+ while (*string == ' ')
+ string++;
+
+ if (string[0] == '0' && string[1] == 'x')
+ {
+ const WCHAR *p = string;
+
+ while (*p && *p != ';')
+ p++;
+
+ if (p - string <= 10 /* 8 hex digits + "0x" */ )
+ {
+ rights = wcstoul( string, NULL, 16 );
+ string = p;
+ }
+ else
+ WARN("Invalid rights string format: %s\n", debugstr_wn(string, p - string));
+ }
+ else
+ {
+ while (*string != ';')
+ {
+ DWORD right = parse_ace_right( string );
+ if (!right) return 0;
+ rights |= right;
+ string += 2;
+ }
+ }
+
+ *string_ptr = string;
+ return rights;
+}
+
+static BOOL parse_acl( const WCHAR *string, DWORD *flags, ACL *acl, DWORD *ret_size )
+{
+ DWORD val;
+ DWORD sidlen;
+ DWORD length = sizeof(ACL);
+ DWORD acesize = 0;
+ DWORD acecount = 0;
+ ACCESS_ALLOWED_ACE *ace = NULL; /* pointer to current ACE */
+
+ TRACE("%s\n", debugstr_w(string));
+
+ if (acl) /* ace is only useful if we're setting values */
+ ace = (ACCESS_ALLOWED_ACE *)(acl + 1);
+
+ /* Parse ACL flags */
+ *flags = parse_acl_flags( &string );
+
+ /* Parse ACE */
+ while (*string == '(')
+ {
+ string++;
+
+ /* Parse ACE type */
+ val = parse_ace_type( &string );
+ if (ace)
+ ace->Header.AceType = val;
+ if (*string != ';')
+ {
+ SetLastError( RPC_S_INVALID_STRING_UUID );
+ return FALSE;
+ }
+ string++;
+
+ /* Parse ACE flags */
+ val = parse_ace_flags( &string );
+ if (ace)
+ ace->Header.AceFlags = val;
+ if (*string != ';')
+ goto err;
+ string++;
+
+ /* Parse ACE rights */
+ val = parse_ace_rights( &string );
+ if (ace)
+ ace->Mask = val;
+ if (*string != ';')
+ goto err;
+ string++;
+
+ /* Parse ACE object guid */
+ while (*string == ' ')
+ string++;
+ if (*string != ';')
+ {
+ FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
+ goto err;
+ }
+ string++;
+
+ /* Parse ACE inherit object guid */
+ while (*string == ' ')
+ string++;
+ if (*string != ';')
+ {
+ FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
+ goto err;
+ }
+ string++;
+
+ /* Parse ACE account sid */
+ if (parse_sid( string, ace ? (SID *)&ace->SidStart : NULL, &sidlen ))
+ {
+ while (*string && *string != ')')
+ string++;
+ }
+
+ if (*string != ')')
+ goto err;
+ string++;
+
+ acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
+ length += acesize;
+ if (ace)
+ {
+ ace->Header.AceSize = acesize;
+ ace = (ACCESS_ALLOWED_ACE *)((BYTE *)ace + acesize);
+ }
+ acecount++;
+ }
+
+ *ret_size = length;
+
+ if (length > 0xffff)
+ {
+ ERR("ACL too large\n");
+ goto err;
+ }
+
+ if (acl)
+ {
+ acl->AclRevision = ACL_REVISION;
+ acl->Sbz1 = 0;
+ acl->AclSize = length;
+ acl->AceCount = acecount;
+ acl->Sbz2 = 0;
+ }
+ return TRUE;
+
+err:
+ SetLastError( ERROR_INVALID_ACL );
+ WARN("Invalid ACE string format\n");
+ return FALSE;
+}
+
+static BOOL parse_sd( const WCHAR *string, SECURITY_DESCRIPTOR_RELATIVE *sd, DWORD *size)
+{
+ BOOL ret = FALSE;
+ WCHAR toktype;
+ WCHAR *tok;
+ const WCHAR *lptoken;
+ BYTE *next = NULL;
+ DWORD len;
+
+ *size = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
+
+ tok = heap_alloc( (wcslen(string) + 1) * sizeof(WCHAR) );
+ if (!tok)
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+
+ if (sd)
+ next = (BYTE *)(sd + 1);
+
+ while (*string == ' ')
+ string++;
+
+ while (*string)
+ {
+ toktype = *string;
+
+ /* Expect char identifier followed by ':' */
+ string++;
+ if (*string != ':')
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ goto out;
+ }
+ string++;
+
+ /* Extract token */
+ lptoken = string;
+ while (*lptoken && *lptoken != ':')
+ lptoken++;
+
+ if (*lptoken)
+ lptoken--;
+
+ len = lptoken - string;
+ memcpy( tok, string, len * sizeof(WCHAR) );
+ tok[len] = 0;
+
+ switch (toktype)
+ {
+ case 'O':
+ {
+ DWORD bytes;
+
+ if (!parse_sid( tok, (SID *)next, &bytes ))
+ goto out;
+
+ if (sd)
+ {
+ sd->Owner = next - (BYTE *)sd;
+ next += bytes; /* Advance to next token */
+ }
+
+ *size += bytes;
+
+ break;
+ }
+
+ case 'G':
+ {
+ DWORD bytes;
+
+ if (!parse_sid( tok, (SID *)next, &bytes ))
+ goto out;
+
+ if (sd)
+ {
+ sd->Group = next - (BYTE *)sd;
+ next += bytes; /* Advance to next token */
+ }
+
+ *size += bytes;
+
+ break;
+ }
+
+ case 'D':
+ {
+ DWORD flags;
+ DWORD bytes;
+
+ if (!parse_acl( tok, &flags, (ACL *)next, &bytes ))
+ goto out;
+
+ if (sd)
+ {
+ sd->Control |= SE_DACL_PRESENT | flags;
+ sd->Dacl = next - (BYTE *)sd;
+ next += bytes; /* Advance to next token */
+ }
+
+ *size += bytes;
+
+ break;
+ }
+
+ case 'S':
+ {
+ DWORD flags;
+ DWORD bytes;
+
+ if (!parse_acl( tok, &flags, (ACL *)next, &bytes ))
+ goto out;
+
+ if (sd)
+ {
+ sd->Control |= SE_SACL_PRESENT | flags;
+ sd->Sacl = next - (BYTE *)sd;
+ next += bytes; /* Advance to next token */
+ }
+
+ *size += bytes;
+
+ break;
+ }
+
+ default:
+ FIXME("Unknown token\n");
+ SetLastError( ERROR_INVALID_PARAMETER );
+ goto out;
+ }
+
+ string = lptoken;
+ }
+
+ ret = TRUE;
+
+out:
+ heap_free(tok);
+ return ret;
+}
+
+/******************************************************************************
+ * ConvertStringSecurityDescriptorToSecurityDescriptorW (sechost.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH ConvertStringSecurityDescriptorToSecurityDescriptorW(
+ const WCHAR *string, DWORD revision, PSECURITY_DESCRIPTOR *sd, ULONG *ret_size )
+{
+ DWORD size;
+ SECURITY_DESCRIPTOR *psd;
+
+ TRACE("%s, %u, %p, %p\n", debugstr_w(string), revision, sd, ret_size);
+
+ if (GetVersion() & 0x80000000)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+ }
+ if (!string || !sd)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ if (revision != SID_REVISION)
+ {
+ SetLastError(ERROR_UNKNOWN_REVISION);
+ return FALSE;
+ }
+
+ /* Compute security descriptor length */
+ if (!parse_sd( string, NULL, &size ))
+ return FALSE;
+
+ psd = *sd = LocalAlloc( GMEM_ZEROINIT, size );
+ if (!psd)
+ {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+
+ psd->Revision = SID_REVISION;
+ psd->Control |= SE_SELF_RELATIVE;
+
+ if (!parse_sd( string, (SECURITY_DESCRIPTOR_RELATIVE *)psd, &size ))
+ {
+ LocalFree(psd);
+ return FALSE;
+ }
+
+ if (ret_size) *ret_size = size;
+ return TRUE;
+}
--
2.26.2
1
0
Signed-off-by: Gijs Vermeulen <gijsvrm(a)gmail.com>
---
Superseeds 184651
dlls/qcap/filewriter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c
index 5e63facf7b..5e7acf9250 100644
--- a/dlls/qcap/filewriter.c
+++ b/dlls/qcap/filewriter.c
@@ -72,8 +72,8 @@ static HRESULT WINAPI file_writer_sink_receive(struct strmbase_sink *iface, IMed
struct file_writer *filter = impl_from_strmbase_pin(&iface->pin);
REFERENCE_TIME start, stop;
LARGE_INTEGER offset;
+ DWORD size = 0;
HRESULT hr;
- DWORD size;
BYTE *data;
if ((hr = IMediaSample_GetTime(sample, &start, &stop)) != S_OK)
--
2.26.1
1
0
[PATCH] qcap/filewriter: Propagate file I/O failure in file_writer_sink_receive().
by Zebediah Figura 01 May '20
by Zebediah Figura 01 May '20
01 May '20
This supersedes <https://source.winehq.org/patches/data/184651>
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/filewriter.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/qcap/filewriter.c b/dlls/qcap/filewriter.c
index 2a0225a854..be1e4e773a 100644
--- a/dlls/qcap/filewriter.c
+++ b/dlls/qcap/filewriter.c
@@ -81,7 +81,11 @@ static HRESULT WINAPI file_writer_sink_receive(struct strmbase_sink *iface, IMed
offset.QuadPart = start;
if (!SetFilePointerEx(filter->file, offset, NULL, FILE_BEGIN)
|| !WriteFile(filter->file, data, stop - start, &size, NULL))
+ {
ERR("Failed to write file, error %u.\n", GetLastError());
+ return HRESULT_FROM_WIN32(hr);
+ }
+
if (size != stop - start)
ERR("Short write, %u/%u.\n", size, (DWORD)(stop - start));
--
2.26.2
1
0