diff --git a/patches/ddraw-EnumSurfaces/0001-ddraw-tests-Add-more-tests-for-IDirectDraw7-EnumSurf.patch b/patches/ddraw-EnumSurfaces/0001-ddraw-tests-Add-more-tests-for-IDirectDraw7-EnumSurf.patch deleted file mode 100644 index 22fe0399..00000000 --- a/patches/ddraw-EnumSurfaces/0001-ddraw-tests-Add-more-tests-for-IDirectDraw7-EnumSurf.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 4c6b3da41feef98226bbfe14c2b0e88acf39807e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Tue, 25 Aug 2015 11:15:59 +0200 -Subject: ddraw/tests: Add more tests for IDirectDraw7::EnumSurfaces. - ---- - dlls/ddraw/ddraw.c | 3 + - dlls/ddraw/tests/d3d.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 172 insertions(+), 8 deletions(-) - -diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c -index b3caba2..4b7a207 100644 ---- a/dlls/ddraw/ddraw.c -+++ b/dlls/ddraw/ddraw.c -@@ -3135,6 +3135,9 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, - if (!Callback) - return DDERR_INVALIDPARAMS; - -+ if (!all && !DDSD) -+ return DDERR_INVALIDPARAMS; -+ - wined3d_mutex_lock(); - - /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ -diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c -index ec4197a..e9c616e 100644 ---- a/dlls/ddraw/tests/d3d.c -+++ b/dlls/ddraw/tests/d3d.c -@@ -57,6 +57,12 @@ typedef struct { - int total; - } D3D7ECancelTest; - -+typedef struct -+{ -+ int found; -+ int surfaces; -+} EnumSurfaceTest; -+ - #define MAX_ENUMERATION_COUNT 10 - typedef struct - { -@@ -85,17 +91,21 @@ static ULONG getRefcount(IUnknown *iface) - - static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context) - { -- UINT *num = context; -- (*num)++; -- IDirectDrawSurface_Release(surface); -+ EnumSurfaceTest *count = context; -+ count->found++; -+ if (surface) -+ { -+ count->surfaces++; -+ IDirectDrawSurface_Release(surface); -+ } - return DDENUMRET_OK; - } - - static BOOL CreateDirect3D(void) - { - HRESULT rc; -- DDSURFACEDESC2 ddsd; -- UINT num; -+ DDSURFACEDESC2 ddsd, ddsd2; -+ EnumSurfaceTest count; - - rc = pDirectDrawCreateEx(NULL, (void**)&lpDD, - &IID_IDirectDraw7, NULL); -@@ -122,9 +132,160 @@ static BOOL CreateDirect3D(void) - if (FAILED(rc)) - return FALSE; - -- num = 0; -- IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL | DDENUMSURFACES_DOESEXIST, NULL, &num, SurfaceCounter); -- ok(num == 1, "Has %d surfaces, expected 1\n", num); -+ memset(&ddsd2, 0, sizeof(ddsd2)); -+ ddsd2.dwSize = sizeof(ddsd2); -+ ddsd2.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; -+ ddsd2.dwWidth = 256; -+ ddsd2.dwHeight = 256; -+ -+ /* without search type flags */ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, 0, NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, 0, &ddsd, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL, NULL, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_MATCH, NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_NOMATCH, NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ /* search type DDENUMSURFACES_DOESEXIST */ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST, NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST, &ddsd, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST, &ddsd2, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 1, "Has %d surfaces, expected 1\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, -+ NULL, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 1, "Has %d surfaces, expected 1\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH, -+ &ddsd, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH, -+ &ddsd, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 1, "Has %d surfaces, expected 1\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH, -+ &ddsd2, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 1, "Has %d surfaces, expected 1\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH, -+ &ddsd2, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL | -+ DDENUMSURFACES_MATCH, NULL, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL | -+ DDENUMSURFACES_NOMATCH, NULL, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH | -+ DDENUMSURFACES_NOMATCH, NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ /* search type DDENUMSURFACES_CANBECREATED */ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED, &ddsd, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL, -+ &ddsd, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH, -+ &ddsd, &count, SurfaceCounter); -+ todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH, -+ NULL, &count, SurfaceCounter); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH, -+ &ddsd, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ todo_wine ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ -+ /* combination of DDENUMSURFACES_DOESEXIST and DDENUMSURFACES_CANBECREATED */ -+ count.found = count.surfaces = 0; -+ rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_CANBECREATED | -+ DDENUMSURFACES_MATCH, &ddsd, &count, SurfaceCounter); -+ ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -+ todo_wine ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); --- -2.5.0 - diff --git a/patches/ddraw-EnumSurfaces/0003-ddraw-Implement-DDENUMSURFACES_CANBECREATED-flag-in-.patch b/patches/ddraw-EnumSurfaces/0003-ddraw-Implement-DDENUMSURFACES_CANBECREATED-flag-in-.patch deleted file mode 100644 index 643f33aa..00000000 --- a/patches/ddraw-EnumSurfaces/0003-ddraw-Implement-DDENUMSURFACES_CANBECREATED-flag-in-.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 5dcbd836e663da908a9a39b5791da65d64a00eb8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michael=20M=C3=BCller?= -Date: Tue, 25 Aug 2015 11:17:07 +0200 -Subject: ddraw: Implement DDENUMSURFACES_CANBECREATED flag in - ddraw7_EnumSurfaces. - -Also fixes various test failures related to DDENUMSURFACES_DOESEXIST. - -The "Unexpected destination texture level pixels" testfailure on the w8 VM is not related to this patch. ---- - dlls/ddraw/ddraw.c | 98 +++++++++++++++++++++++++++++++++++++------------- - dlls/ddraw/tests/d3d.c | 42 +++++++++++----------- - 2 files changed, 94 insertions(+), 46 deletions(-) - -diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c -index 4b7a207..19ed213 100644 ---- a/dlls/ddraw/ddraw.c -+++ b/dlls/ddraw/ddraw.c -@@ -3122,49 +3122,97 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, - { - struct ddraw *ddraw = impl_from_IDirectDraw7(iface); - struct ddraw_surface *surf; -- BOOL all, nomatch; -- DDSURFACEDESC2 desc; -- struct list *entry, *entry2; -+ DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH); - - TRACE("iface %p, flags %#x, surface_desc %p, context %p, callback %p.\n", - iface, Flags, DDSD, Context, Callback); - -- all = Flags & DDENUMSURFACES_ALL; -- nomatch = Flags & DDENUMSURFACES_NOMATCH; -- - if (!Callback) - return DDERR_INVALIDPARAMS; - -- if (!all && !DDSD) -- return DDERR_INVALIDPARAMS; -+ if (Flags & DDENUMSURFACES_CANBECREATED) -+ { -+ IDirectDrawSurface7 *surface; -+ DDSURFACEDESC2 testdesc; -+ HRESULT hr; - -- wined3d_mutex_lock(); -+ if (match_flags != DDENUMSURFACES_MATCH) -+ return DDERR_INVALIDPARAMS; - -- /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ -- LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) -- { -- surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); -+ if (!DDSD) -+ return DDERR_INVALIDPARAMS; -+ -+ memcpy(&testdesc, DDSD, sizeof(testdesc)); -+ if (!(testdesc.dwFlags & DDSD_WIDTH)) -+ { -+ testdesc.dwFlags |= DDSD_WIDTH; -+ testdesc.dwWidth = 512; -+ } -+ if (!(testdesc.dwFlags & DDSD_HEIGHT)) -+ { -+ testdesc.dwFlags |= DDSD_HEIGHT; -+ testdesc.dwHeight = 512; -+ } - -- if (!surf->iface_count) -+ hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL); -+ if (SUCCEEDED(hr)) - { -- WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); -- continue; -+ surf = unsafe_impl_from_IDirectDrawSurface7(surface); -+ Callback(NULL, &surf->surface_desc, Context); -+ IDirectDrawSurface7_Release(surface); - } -+ else -+ ERR("Failed to create surface, hr %#x.\n", hr); -+ } -+ else if (Flags & DDENUMSURFACES_DOESEXIST) -+ { -+ BOOL all, nomatch; -+ DDSURFACEDESC2 desc; -+ struct list *entry, *entry2; -+ -+ /* a combination of match flags is not allowed */ -+ if (match_flags != 0 && -+ match_flags != DDENUMSURFACES_ALL && -+ match_flags != DDENUMSURFACES_MATCH && -+ match_flags != DDENUMSURFACES_NOMATCH) -+ return DDERR_INVALIDPARAMS; -+ -+ all = (Flags & DDENUMSURFACES_ALL) != 0; -+ nomatch = (Flags & DDENUMSURFACES_NOMATCH) != 0; -+ -+ if (!all && !DDSD) -+ return DDERR_INVALIDPARAMS; - -- if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) -+ wined3d_mutex_lock(); -+ -+ /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ -+ LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) - { -- TRACE("Enumerating surface %p.\n", surf); -- desc = surf->surface_desc; -- IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); -- if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) -+ surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); -+ -+ if (!surf->iface_count) - { -- wined3d_mutex_unlock(); -- return DD_OK; -+ WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); -+ continue; -+ } -+ -+ if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) -+ { -+ TRACE("Enumerating surface %p.\n", surf); -+ desc = surf->surface_desc; -+ IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); -+ if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_OK) -+ { -+ wined3d_mutex_unlock(); -+ return DD_OK; -+ } - } - } -- } - -- wined3d_mutex_unlock(); -+ wined3d_mutex_unlock(); -+ } -+ else -+ return DDERR_INVALIDPARAMS; - - return DD_OK; - } -diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c -index e9c616e..930460f 100644 ---- a/dlls/ddraw/tests/d3d.c -+++ b/dlls/ddraw/tests/d3d.c -@@ -147,15 +147,15 @@ static BOOL CreateDirect3D(void) - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, 0, &ddsd, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); - ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); - ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_ALL, NULL, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_MATCH, NULL, &count, SurfaceCounter); -@@ -220,22 +220,22 @@ static BOOL CreateDirect3D(void) - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_NOMATCH, - &ddsd2, &count, SurfaceCounter); - ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL | - DDENUMSURFACES_MATCH, NULL, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL | - DDENUMSURFACES_NOMATCH, NULL, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_MATCH | -@@ -247,23 +247,23 @@ static BOOL CreateDirect3D(void) - /* search type DDENUMSURFACES_CANBECREATED */ - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED, &ddsd, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); - ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); - ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_ALL, - &ddsd, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_NOMATCH, - &ddsd, &count, SurfaceCounter); -- todo_wine ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -- todo_wine ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -- todo_wine ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); -+ ok(rc == DDERR_INVALIDPARAMS, "Expected DDERR_INVALIDPARAMS, got %x\n", rc); -+ ok(count.found == 0, "Has %d surface descriptions, expected 0\n", count.found); -+ ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - count.found = count.surfaces = 0; - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH, -@@ -276,7 +276,7 @@ static BOOL CreateDirect3D(void) - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH, - &ddsd, &count, SurfaceCounter); - ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -- todo_wine ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); - ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - /* combination of DDENUMSURFACES_DOESEXIST and DDENUMSURFACES_CANBECREATED */ -@@ -284,7 +284,7 @@ static BOOL CreateDirect3D(void) - rc = IDirectDraw7_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_CANBECREATED | - DDENUMSURFACES_MATCH, &ddsd, &count, SurfaceCounter); - ok(rc == DD_OK, "Expected DD_OK, got %x\n", rc); -- todo_wine ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); -+ ok(count.found == 1, "Has %d surface descriptions, expected 1\n", count.found); - ok(count.surfaces == 0, "Has %d surfaces, expected 0\n", count.surfaces); - - memset(&ddsd, 0, sizeof(ddsd)); --- -2.5.0 - diff --git a/patches/ddraw-EnumSurfaces/definition b/patches/ddraw-EnumSurfaces/definition deleted file mode 100644 index 1e83bf0f..00000000 --- a/patches/ddraw-EnumSurfaces/definition +++ /dev/null @@ -1 +0,0 @@ -Fixes: [17233] Implement DDENUMSURFACES_CANBECREATED in IDirectDraw7::EnumSurfaces diff --git a/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch b/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch index e81834f6..8fb8c9fa 100644 --- a/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch +++ b/patches/kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch @@ -1,60 +1,87 @@ -From 96f59c91f45ca9572e3e9141ee9ad81bbb6ba45d Mon Sep 17 00:00:00 2001 +From 34b3bcb23bf0a4b81b1cddca90f8a248f478fee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 26 Feb 2015 06:41:26 +0100 -Subject: [PATCH] kernel32: Add support for progress callback in CopyFileEx. +Subject: [PATCH] kernelbase: Add support for progress callback in CopyFileEx. --- - dlls/kernel32/path.c | 66 +++++++++++++++++++++++++++++++++++++++++++--- - dlls/kernel32/tests/file.c | 6 ----- - 2 files changed, 62 insertions(+), 10 deletions(-) + dlls/kernel32/tests/file.c | 6 ---- + dlls/kernelbase/file.c | 65 ++++++++++++++++++++++++++++++++++++-- + 2 files changed, 63 insertions(+), 8 deletions(-) -diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c -index 41f0d34..f04b0f4 100644 ---- a/dlls/kernel32/path.c -+++ b/dlls/kernel32/path.c -@@ -1177,6 +1177,9 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c +index 2e26e2ace86..1cccb105448 100644 +--- a/dlls/kernel32/tests/file.c ++++ b/dlls/kernel32/tests/file.c +@@ -1173,23 +1173,17 @@ static void test_CopyFileEx(void) + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + SetLastError(0xdeadbeef); + retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); +- todo_wine + ok(!retok, "CopyFileExA unexpectedly succeeded\n"); +- todo_wine + ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); + ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file was deleted\n"); + + hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, 0); +- todo_wine + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); + SetLastError(0xdeadbeef); + retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); +- todo_wine + ok(!retok, "CopyFileExA unexpectedly succeeded\n"); +- todo_wine + ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); +- todo_wine + ok(GetFileAttributesA(dest) == INVALID_FILE_ATTRIBUTES, "file was not deleted\n"); + + retok = CopyFileExA(source, NULL, copy_progress_cb, hfile, NULL, 0); +diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c +index 3b00321eb1a..ab95c8babf1 100644 +--- a/dlls/kernelbase/file.c ++++ b/dlls/kernelbase/file.c +@@ -503,6 +503,10 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT DWORD count; BOOL ret = FALSE; char *buffer; + LARGE_INTEGER size; + LARGE_INTEGER transferred; + DWORD cbret; ++ DWORD source_access = GENERIC_READ; if (!source || !dest) { -@@ -1191,7 +1194,13 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -517,7 +521,15 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT TRACE("%s -> %s, %x\n", debugstr_w(source), debugstr_w(dest), flags); -- if ((h1 = CreateFileW(source, GENERIC_READ, +- if ((h1 = CreateFileW( source, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + if (flags & COPY_FILE_RESTARTABLE) + FIXME("COPY_FILE_RESTARTABLE is not supported\n"); + if (flags & COPY_FILE_COPY_SYMLINK) + FIXME("COPY_FILE_COPY_SYMLINK is not supported\n"); + -+ if ((h1 = CreateFileW(source, (flags & COPY_FILE_OPEN_SOURCE_FOR_WRITE) ? -+ GENERIC_WRITE | GENERIC_READ : GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) ++ if (flags & COPY_FILE_OPEN_SOURCE_FOR_WRITE) ++ source_access |= GENERIC_WRITE; ++ ++ if ((h1 = CreateFileW( source, source_access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) { -@@ -1227,9 +1236,13 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, + WARN("Unable to open source %s\n", debugstr_w(source)); +@@ -551,7 +563,11 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT } } - if ((h2 = CreateFileW( dest, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, -- (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, -- info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) + if ((h2 = CreateFileW( dest, GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, + info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE && + /* retry without DELETE if we got a sharing violation */ + (h2 = CreateFileW( dest, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, -+ (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, -+ info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) + (flags & COPY_FILE_FAIL_IF_EXISTS) ? CREATE_NEW : CREATE_ALWAYS, + info.dwFileAttributes, h1 )) == INVALID_HANDLE_VALUE) { - WARN("Unable to open dest %s\n", debugstr_w(dest)); - HeapFree( GetProcessHeap(), 0, buffer ); -@@ -1237,6 +1250,30 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -561,6 +577,30 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT return FALSE; } @@ -85,7 +112,7 @@ index 41f0d34..f04b0f4 100644 while (ReadFile( h1, buffer, buffer_size, &count, NULL ) && count) { char *p = buffer; -@@ -1246,6 +1283,27 @@ BOOL WINAPI CopyFileExW(LPCWSTR source, LPCWSTR dest, +@@ -570,6 +610,27 @@ BOOL WINAPI CopyFileExW( const WCHAR *source, const WCHAR *dest, LPPROGRESS_ROUT if (!WriteFile( h2, p, count, &res, NULL ) || !res) goto done; p += res; count -= res; @@ -113,34 +140,6 @@ index 41f0d34..f04b0f4 100644 } } ret = TRUE; -diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c -index b47b2b9..68396c0 100644 ---- a/dlls/kernel32/tests/file.c -+++ b/dlls/kernel32/tests/file.c -@@ -1163,23 +1163,17 @@ static void test_CopyFileEx(void) - ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); - SetLastError(0xdeadbeef); - retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); -- todo_wine - ok(!retok, "CopyFileExA unexpectedly succeeded\n"); -- todo_wine - ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); - ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file was deleted\n"); - - hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, 0, 0); -- todo_wine - ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError()); - SetLastError(0xdeadbeef); - retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0); -- todo_wine - ok(!retok, "CopyFileExA unexpectedly succeeded\n"); -- todo_wine - ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %d\n", GetLastError()); -- todo_wine - ok(GetFileAttributesA(dest) == INVALID_FILE_ATTRIBUTES, "file was not deleted\n"); - - retok = CopyFileExA(source, NULL, copy_progress_cb, hfile, NULL, 0); -- -1.9.1 +2.26.2 diff --git a/patches/ntdll-Junction_Points/definition b/patches/ntdll-Junction_Points/definition index fe085afd..1bc08a0b 100644 --- a/patches/ntdll-Junction_Points/definition +++ b/patches/ntdll-Junction_Points/definition @@ -1,2 +1,4 @@ Fixes: [12401] NET Framework 2.0, 3.0, 4.0 installers and other apps that make use of GAC API for managed assembly installation on NTFS filesystems need reparse point/junction API support (FSCTL_SET_REPARSE_POINT/FSCTL_GET_REPARSE_POINT) Fixes: [44948] Multiple apps (Spine (Mod starter for Gothic), MS Office 365 installer) need CreateSymbolicLinkW implementation +# FIXME: patch 0006 was broken by e36a9c459d. We really want to get that information from ntdll instead, but the how is not trivial... +# FIXME 2: patch 0019 needs to call RemoveDirectoryW() from kernelbase, but it's stuck in kernel32 for now... diff --git a/patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch b/patches/ntdll-Junction_Points/xx06-kernel32-Advertise-junction-point-support.patch similarity index 100% rename from patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch rename to patches/ntdll-Junction_Points/xx06-kernel32-Advertise-junction-point-support.patch diff --git a/patches/ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch b/patches/ntdll-Junction_Points/xx19-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch similarity index 92% rename from patches/ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch rename to patches/ntdll-Junction_Points/xx19-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch index ab185c3a..3209c695 100644 --- a/patches/ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch +++ b/patches/ntdll-Junction_Points/xx19-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch @@ -1,4 +1,4 @@ -From bec0c81d2917427c8cdc22fea8f5db86157bccf8 Mon Sep 17 00:00:00 2001 +From cab7c1b99de7c594083c6fd16b728a79f16b9ac8 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Wed, 13 Mar 2019 16:02:05 -0600 Subject: [PATCH] kernel32: Implement CreateSymbolicLink[A|W] with ntdll @@ -6,135 +6,18 @@ Subject: [PATCH] kernel32: Implement CreateSymbolicLink[A|W] with ntdll Signed-off-by: Erich E. Hoover --- - dlls/kernel32/path.c | 124 +++++++++++++++++++++++++++++++-- - dlls/kernel32/tests/path.c | 96 +++++++++++++++++++++++++ - dlls/msvcp120/tests/msvcp120.c | 75 +++++++++----------- - dlls/msvcp140/tests/msvcp140.c | 63 +++++++---------- - 4 files changed, 277 insertions(+), 81 deletions(-) + dlls/kernel32/path.c | 20 ++++++- + dlls/kernel32/tests/path.c | 96 ++++++++++++++++++++++++++++++ + dlls/kernelbase/file.c | 105 ++++++++++++++++++++++++++++++++- + dlls/msvcp120/tests/msvcp120.c | 75 +++++++++++------------ + dlls/msvcp140/tests/msvcp140.c | 63 +++++++++----------- + 5 files changed, 277 insertions(+), 82 deletions(-) diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c -index 849be11d2..bc30e03b0 100644 +index 0f075d0af1c..3d17b53a829 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c -@@ -34,6 +34,8 @@ - #include "windef.h" - #include "winbase.h" - #include "winternl.h" -+#include "winioctl.h" -+#include "ntifs.h" - - #include "kernel_private.h" - #include "wine/unicode.h" -@@ -926,8 +928,106 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str ) - */ - BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags) - { -- FIXME("(%s %s %d): stub\n", debugstr_w(link), debugstr_w(target), flags); -- return TRUE; -+ static INT struct_size = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]); -+ static INT header_size = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer); -+ INT buffer_size, data_size, string_len, prefix_len; -+ WCHAR *subst_dest, *print_dest, *string; -+ REPARSE_DATA_BUFFER *buffer; -+ LPWSTR target_path = NULL; -+ BOOL is_relative, is_dir; -+ int target_path_len = 0; -+ UNICODE_STRING nt_name; -+ BOOLEAN bret = FALSE; -+ NTSTATUS status; -+ HANDLE hlink; -+ DWORD dwret; -+ -+ TRACE("(%s %s %d)\n", debugstr_w(link), debugstr_w(target), flags); -+ -+ is_relative = (RtlDetermineDosPathNameType_U( target ) == RELATIVE_PATH); -+ is_dir = (flags & SYMBOLIC_LINK_FLAG_DIRECTORY); -+ if (is_dir && !CreateDirectoryW( link, NULL )) -+ return FALSE; -+ hlink = CreateFileW( link, GENERIC_READ | GENERIC_WRITE, 0, 0, -+ is_dir ? OPEN_EXISTING : CREATE_NEW, -+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0 ); -+ if (hlink == INVALID_HANDLE_VALUE) -+ goto cleanup; -+ if (is_relative) -+ { -+ UNICODE_STRING nt_path; -+ int len; -+ -+ status = RtlDosPathNameToNtPathName_U_WithStatus( link, &nt_path, NULL, NULL ); -+ if (status != STATUS_SUCCESS) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ goto cleanup; -+ } -+ /* obtain the path of the link */ -+ for (; nt_path.Length > 0; nt_path.Length -= sizeof(WCHAR)) -+ { -+ WCHAR c = nt_path.Buffer[nt_path.Length/sizeof(WCHAR)]; -+ if (c == '/' || c == '\\') -+ { -+ nt_path.Length += sizeof(WCHAR); -+ break; -+ } -+ } -+ /* append the target to the link path */ -+ target_path_len = nt_path.Length / sizeof(WCHAR); -+ len = target_path_len + (strlenW( target ) + 1); -+ target_path = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR) ); -+ lstrcpynW( target_path, nt_path.Buffer, target_path_len+1 ); -+ target_path[target_path_len+1] = 0; -+ lstrcatW( target_path, target ); -+ RtlFreeUnicodeString( &nt_path ); -+ } -+ else -+ target_path = (LPWSTR)target; -+ status = RtlDosPathNameToNtPathName_U_WithStatus( target_path, &nt_name, NULL, NULL ); -+ if (status != STATUS_SUCCESS) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ goto cleanup; -+ } -+ if (is_relative && strncmpW( target_path, nt_name.Buffer, target_path_len ) != 0) -+ { -+ SetLastError( RtlNtStatusToDosError(status) ); -+ goto cleanup; -+ } -+ prefix_len = is_relative ? 0 : strlen("\\??\\"); -+ string = &nt_name.Buffer[target_path_len]; -+ string_len = lstrlenW( &string[prefix_len] ); -+ data_size = (prefix_len + 2 * string_len + 2) * sizeof(WCHAR); -+ buffer_size = struct_size + data_size; -+ buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size ); -+ buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK; -+ buffer->ReparseDataLength = struct_size - header_size + data_size; -+ buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = (prefix_len + string_len) * sizeof(WCHAR); -+ buffer->SymbolicLinkReparseBuffer.PrintNameOffset = (prefix_len + string_len + 1) * sizeof(WCHAR); -+ buffer->SymbolicLinkReparseBuffer.PrintNameLength = string_len * sizeof(WCHAR); -+ buffer->SymbolicLinkReparseBuffer.Flags = is_relative ? SYMLINK_FLAG_RELATIVE : 0; -+ subst_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[0]; -+ print_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[prefix_len + string_len + 1]; -+ lstrcpyW( subst_dest, string ); -+ lstrcpyW( print_dest, &string[prefix_len] ); -+ RtlFreeUnicodeString( &nt_name ); -+ bret = DeviceIoControl( hlink, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_size, NULL, 0, -+ &dwret, 0 ); -+ HeapFree( GetProcessHeap(), 0, buffer ); -+ -+cleanup: -+ CloseHandle( hlink ); -+ if (!bret) -+ { -+ if (is_dir) -+ RemoveDirectoryW( link ); -+ else -+ DeleteFileW( link ); -+ } -+ if (is_relative) HeapFree( GetProcessHeap(), 0, target_path ); -+ return bret; - } - - /************************************************************************* -@@ -935,8 +1035,24 @@ BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags) +@@ -385,8 +385,24 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str ) */ BOOLEAN WINAPI CreateSymbolicLinkA(LPCSTR link, LPCSTR target, DWORD flags) { @@ -162,7 +45,7 @@ index 849be11d2..bc30e03b0 100644 /************************************************************************* diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c -index 7342a865a..78a2e2e06 100644 +index 0e45ad44ff3..841353dcab8 100644 --- a/dlls/kernel32/tests/path.c +++ b/dlls/kernel32/tests/path.c @@ -83,6 +83,9 @@ static NTSTATUS (WINAPI *pLdrGetDllPath)(LPCWSTR,ULONG,LPWSTR*,LPWSTR*); @@ -190,7 +73,7 @@ index 7342a865a..78a2e2e06 100644 #undef MAKEFUNC } -@@ -2672,6 +2678,95 @@ static void test_LdrGetDllPath(void) +@@ -2690,6 +2696,95 @@ static void test_LdrGetDllPath(void) SetEnvironmentVariableW( pathW, old_path ); } @@ -286,14 +169,138 @@ index 7342a865a..78a2e2e06 100644 START_TEST(path) { CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive; -@@ -2701,4 +2796,5 @@ START_TEST(path) +@@ -2719,4 +2814,5 @@ START_TEST(path) test_RtlGetSearchPath(); test_RtlGetExePath(); test_LdrGetDllPath(); + test_CreateSymbolicLink(); } +diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c +index 905029066e4..ed6ba6ae30e 100644 +--- a/dlls/kernelbase/file.c ++++ b/dlls/kernelbase/file.c +@@ -36,6 +36,7 @@ + #include "wincon.h" + #include "fileapi.h" + #include "shlwapi.h" ++#include "ntifs.h" + #include "ddk/ntddk.h" + #include "ddk/ntddser.h" + +@@ -943,10 +944,108 @@ done: + /************************************************************************* + * CreateSymbolicLinkW (kernelbase.@) + */ +-BOOLEAN WINAPI /* DECLSPEC_HOTPATCH */ CreateSymbolicLinkW( LPCWSTR link, LPCWSTR target, DWORD flags ) ++BOOLEAN WINAPI DECLSPEC_HOTPATCH CreateSymbolicLinkW( const WCHAR *link, const WCHAR *target, DWORD flags ) + { +- FIXME( "(%s %s %d): stub\n", debugstr_w(link), debugstr_w(target), flags ); +- return TRUE; ++ static INT struct_size = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]); ++ static INT header_size = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer); ++ INT buffer_size, data_size, string_len, prefix_len; ++ WCHAR *subst_dest, *print_dest, *string; ++ REPARSE_DATA_BUFFER *buffer; ++ LPWSTR target_path = NULL; ++ BOOL is_relative, is_dir; ++ int target_path_len = 0; ++ UNICODE_STRING nt_name; ++ BOOLEAN bret = FALSE; ++ NTSTATUS status; ++ HANDLE hlink; ++ DWORD dwret; ++ ++ TRACE("(%s %s %d)\n", debugstr_w(link), debugstr_w(target), flags); ++ ++ is_relative = (RtlDetermineDosPathNameType_U( target ) == RELATIVE_PATH); ++ is_dir = (flags & SYMBOLIC_LINK_FLAG_DIRECTORY); ++ if (is_dir && !CreateDirectoryW( link, NULL )) ++ return FALSE; ++ hlink = CreateFileW( link, GENERIC_READ | GENERIC_WRITE, 0, 0, ++ is_dir ? OPEN_EXISTING : CREATE_NEW, ++ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0 ); ++ if (hlink == INVALID_HANDLE_VALUE) ++ goto cleanup; ++ if (is_relative) ++ { ++ UNICODE_STRING nt_path; ++ int len; ++ ++ status = RtlDosPathNameToNtPathName_U_WithStatus( link, &nt_path, NULL, NULL ); ++ if (status != STATUS_SUCCESS) ++ { ++ SetLastError( RtlNtStatusToDosError(status) ); ++ goto cleanup; ++ } ++ /* obtain the path of the link */ ++ for (; nt_path.Length > 0; nt_path.Length -= sizeof(WCHAR)) ++ { ++ WCHAR c = nt_path.Buffer[nt_path.Length/sizeof(WCHAR)]; ++ if (c == '/' || c == '\\') ++ { ++ nt_path.Length += sizeof(WCHAR); ++ break; ++ } ++ } ++ /* append the target to the link path */ ++ target_path_len = nt_path.Length / sizeof(WCHAR); ++ len = target_path_len + (wcslen( target ) + 1); ++ target_path = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR) ); ++ lstrcpynW( target_path, nt_path.Buffer, target_path_len+1 ); ++ target_path[target_path_len+1] = 0; ++ wcscat( target_path, target ); ++ RtlFreeUnicodeString( &nt_path ); ++ } ++ else ++ target_path = (LPWSTR)target; ++ status = RtlDosPathNameToNtPathName_U_WithStatus( target_path, &nt_name, NULL, NULL ); ++ if (status != STATUS_SUCCESS) ++ { ++ SetLastError( RtlNtStatusToDosError(status) ); ++ goto cleanup; ++ } ++ if (is_relative && wcsncmp( target_path, nt_name.Buffer, target_path_len )) ++ { ++ SetLastError( RtlNtStatusToDosError(status) ); ++ goto cleanup; ++ } ++ prefix_len = is_relative ? 0 : strlen("\\??\\"); ++ string = &nt_name.Buffer[target_path_len]; ++ string_len = wcslen( &string[prefix_len] ); ++ data_size = (prefix_len + 2 * string_len + 2) * sizeof(WCHAR); ++ buffer_size = struct_size + data_size; ++ buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size ); ++ buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK; ++ buffer->ReparseDataLength = struct_size - header_size + data_size; ++ buffer->SymbolicLinkReparseBuffer.SubstituteNameLength = (prefix_len + string_len) * sizeof(WCHAR); ++ buffer->SymbolicLinkReparseBuffer.PrintNameOffset = (prefix_len + string_len + 1) * sizeof(WCHAR); ++ buffer->SymbolicLinkReparseBuffer.PrintNameLength = string_len * sizeof(WCHAR); ++ buffer->SymbolicLinkReparseBuffer.Flags = is_relative ? SYMLINK_FLAG_RELATIVE : 0; ++ subst_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[0]; ++ print_dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[prefix_len + string_len + 1]; ++ wcscpy( subst_dest, string ); ++ wcscpy( print_dest, &string[prefix_len] ); ++ RtlFreeUnicodeString( &nt_name ); ++ bret = DeviceIoControl( hlink, FSCTL_SET_REPARSE_POINT, buffer, buffer_size, NULL, 0, ++ &dwret, 0 ); ++ HeapFree( GetProcessHeap(), 0, buffer ); ++ ++cleanup: ++ CloseHandle( hlink ); ++ if (!bret) ++ { ++ if (is_dir) ++ RemoveDirectoryW( link ); ++ else ++ DeleteFileW( link ); ++ } ++ if (is_relative) HeapFree( GetProcessHeap(), 0, target_path ); ++ return bret; + } + + diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c -index 7a382ac6f..9775ef5e1 100644 +index 7a382ac6faa..9775ef5e1d8 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -1615,15 +1615,14 @@ static void test_tr2_sys__Stat(void) @@ -435,7 +442,7 @@ index 7a382ac6f..9775ef5e1 100644 } diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c -index 751b1beed..382f5732c 100644 +index 751b1beed86..382f5732c29 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -803,16 +803,15 @@ static void test_Stat(void) @@ -545,5 +552,5 @@ index 751b1beed..382f5732c 100644 } -- -2.25.0 +2.26.2 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 610278dd..d6f8db46 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "4e2ad334b5881af7661be4d6df3c51aae92ca4a2" + echo "1976685a0f57bdec939228d73f6252c68ccb8f80" } # Show version information @@ -114,7 +114,6 @@ patch_enable_all () enable_d3dx9_36_UpdateSkinnedMesh="$1" enable_dbghelp_Debug_Symbols="$1" enable_ddraw_Device_Caps="$1" - enable_ddraw_EnumSurfaces="$1" enable_ddraw_IDirect3DTexture2_Load="$1" enable_ddraw_Rendering_Targets="$1" enable_ddraw_Silence_FIXMEs="$1" @@ -449,9 +448,6 @@ patch_enable () ddraw-Device_Caps) enable_ddraw_Device_Caps="$2" ;; - ddraw-EnumSurfaces) - enable_ddraw_EnumSurfaces="$2" - ;; ddraw-IDirect3DTexture2_Load) enable_ddraw_IDirect3DTexture2_Load="$2" ;; @@ -2710,23 +2706,6 @@ if test "$enable_ddraw_Device_Caps" -eq 1; then ) >> "$patchlist" fi -# Patchset ddraw-EnumSurfaces -# | -# | This patchset fixes the following Wine bugs: -# | * [#17233] Implement DDENUMSURFACES_CANBECREATED in IDirectDraw7::EnumSurfaces -# | -# | Modified files: -# | * dlls/ddraw/ddraw.c, dlls/ddraw/tests/d3d.c -# | -if test "$enable_ddraw_EnumSurfaces" -eq 1; then - patch_apply ddraw-EnumSurfaces/0001-ddraw-tests-Add-more-tests-for-IDirectDraw7-EnumSurf.patch - patch_apply ddraw-EnumSurfaces/0003-ddraw-Implement-DDENUMSURFACES_CANBECREATED-flag-in-.patch - ( - printf '%s\n' '+ { "Michael Müller", "ddraw/tests: Add more tests for IDirectDraw7::EnumSurfaces.", 1 },'; - printf '%s\n' '+ { "Michael Müller", "ddraw: Implement DDENUMSURFACES_CANBECREATED flag in ddraw7_EnumSurfaces.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ddraw-IDirect3DTexture2_Load # | # | This patchset fixes the following Wine bugs: @@ -3201,9 +3180,9 @@ fi # | * [#44948] Multiple apps (Spine (Mod starter for Gothic), MS Office 365 installer) need CreateSymbolicLinkW implementation # | # | Modified files: -# | * configure.ac, dlls/kernel32/path.c, dlls/kernel32/tests/path.c, dlls/kernel32/volume.c, dlls/msvcp120/tests/msvcp120.c, -# | dlls/msvcp140/tests/msvcp140.c, dlls/ntdll/directory.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, include/Makefile.in, -# | include/ntifs.h, include/wine/port.h, include/winternl.h, libs/port/Makefile.in, libs/port/renameat2.c, server/fd.c +# | * configure.ac, dlls/kernel32/path.c, dlls/ntdll/directory.c, dlls/ntdll/file.c, dlls/ntdll/tests/file.c, +# | include/Makefile.in, include/ntifs.h, include/wine/port.h, include/winternl.h, libs/port/Makefile.in, +# | libs/port/renameat2.c, server/fd.c # | if test "$enable_ntdll_Junction_Points" -eq 1; then patch_apply ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch @@ -3211,7 +3190,6 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then patch_apply ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch patch_apply ntdll-Junction_Points/0004-ntdll-Add-a-test-for-junction-point-advertisement.patch patch_apply ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch - patch_apply ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch patch_apply ntdll-Junction_Points/0007-ntdll-Add-support-for-absolute-symlink-creation.patch patch_apply ntdll-Junction_Points/0008-ntdll-Add-support-for-reading-absolute-symlinks.patch patch_apply ntdll-Junction_Points/0009-ntdll-Add-support-for-deleting-symlinks.patch @@ -3224,14 +3202,12 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then patch_apply ntdll-Junction_Points/0016-server-Properly-handle-file-symlink-deletion.patch patch_apply ntdll-Junction_Points/0017-ntdll-Always-report-symbolic-links-as-containing-zer.patch patch_apply ntdll-Junction_Points/0018-ntdll-Find-dangling-symlinks-quickly.patch - patch_apply ntdll-Junction_Points/0019-kernel32-Implement-CreateSymbolicLink-A-W-with-ntdll.patch ( printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for junction point creation.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for reading junction points.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for deleting junction points.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add a test for junction point advertisement.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "kernel32,ntdll: Add support for deleting junction points with RemoveDirectory.", 1 },'; - printf '%s\n' '+ { "Erich E. Hoover", "kernel32: Advertise junction point support.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for absolute symlink creation.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for reading absolute symlinks.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Add support for deleting symlinks.", 1 },'; @@ -3244,7 +3220,6 @@ if test "$enable_ntdll_Junction_Points" -eq 1; then printf '%s\n' '+ { "Erich E. Hoover", "server: Properly handle file symlink deletion.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Always report symbolic links as containing zero bytes.", 1 },'; printf '%s\n' '+ { "Erich E. Hoover", "ntdll: Find dangling symlinks quickly.", 1 },'; - printf '%s\n' '+ { "Erich E. Hoover", "kernel32: Implement CreateSymbolicLink[A|W] with ntdll reparse points.", 1 },'; ) >> "$patchlist" fi @@ -3284,11 +3259,11 @@ fi # | dlls/krnl386.exe16/kernel16_private.h, dlls/krnl386.exe16/ne_module.c, dlls/krnl386.exe16/ne_segment.c, # | dlls/krnl386.exe16/task.c, dlls/krnl386.exe16/thunk.c, dlls/krnl386.exe16/wowthunk.c, dlls/ntdll/actctx.c, # | dlls/ntdll/directory.c, dlls/ntdll/loader.c, dlls/ntdll/locale.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/path.c, -# | dlls/ntdll/process.c, dlls/ntdll/signal_i386.c, dlls/ntdll/signal_x86_64.c, dlls/ntdll/tests/exception.c, -# | dlls/ntdll/thread.c, dlls/system.drv16/system.c, dlls/toolhelp.dll16/toolhelp.c, dlls/user.exe16/message.c, -# | dlls/user.exe16/user.c, dlls/user.exe16/window.c, include/winternl.h, libs/wine/loader.c, tools/winebuild/build.h, -# | tools/winebuild/import.c, tools/winebuild/parser.c, tools/winebuild/relay.c, tools/winebuild/res32.c, -# | tools/winebuild/spec16.c, tools/winebuild/spec32.c, tools/winebuild/utils.c +# | dlls/ntdll/process.c, dlls/ntdll/server.c, dlls/ntdll/signal_i386.c, dlls/ntdll/signal_x86_64.c, +# | dlls/ntdll/tests/exception.c, dlls/ntdll/thread.c, dlls/system.drv16/system.c, dlls/toolhelp.dll16/toolhelp.c, +# | dlls/user.exe16/message.c, dlls/user.exe16/user.c, dlls/user.exe16/window.c, include/winternl.h, libs/wine/loader.c, +# | tools/winebuild/build.h, tools/winebuild/import.c, tools/winebuild/parser.c, tools/winebuild/relay.c, +# | tools/winebuild/res32.c, tools/winebuild/spec16.c, tools/winebuild/spec32.c, tools/winebuild/utils.c # | if test "$enable_winebuild_Fake_Dlls" -eq 1; then patch_apply winebuild-Fake_Dlls/0001-kernel32-tests-Add-basic-tests-for-fake-dlls.patch @@ -4058,12 +4033,12 @@ fi # | * [#22690] Allow to cancel a file operation via progress callback # | # | Modified files: -# | * dlls/kernel32/path.c, dlls/kernel32/tests/file.c +# | * dlls/kernel32/tests/file.c, dlls/kernelbase/file.c # | if test "$enable_kernel32_CopyFileEx" -eq 1; then patch_apply kernel32-CopyFileEx/0001-kernel32-Add-support-for-progress-callback-in-CopyFi.patch ( - printf '%s\n' '+ { "Michael Müller", "kernel32: Add support for progress callback in CopyFileEx.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "kernelbase: Add support for progress callback in CopyFileEx.", 1 },'; ) >> "$patchlist" fi