Rebase against 1976685a0f57bdec939228d73f6252c68ccb8f80.

This commit is contained in:
Zebediah Figura 2020-05-05 16:17:09 -05:00
parent 3e39e3132b
commit dfc3b0f583
8 changed files with 205 additions and 706 deletions

View File

@ -1,235 +0,0 @@
From 4c6b3da41feef98226bbfe14c2b0e88acf39807e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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

View File

@ -1,248 +0,0 @@
From 5dcbd836e663da908a9a39b5791da65d64a00eb8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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

View File

@ -1 +0,0 @@
Fixes: [17233] Implement DDENUMSURFACES_CANBECREATED in IDirectDraw7::EnumSurfaces

View File

@ -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?= <michael@fds-team.de>
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

View File

@ -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...

View File

@ -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" <erich.e.hoover@gmail.com>
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 <erich.e.hoover@gmail.com>
---
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

View File

@ -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