ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
37 participants
372 discussions
Start a n
N
ew thread
01/01: [DDRAW] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d255223474c491edc24ef…
commit d255223474c491edc24efad314e6f56328589604 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:15:58 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:15:58 2018 +0100 [DDRAW] Sync with Wine 3.0. CORE-14225 --- dll/directx/wine/ddraw/ddraw.c | 221 ++++++++------------------------- dll/directx/wine/ddraw/ddraw_private.h | 10 +- dll/directx/wine/ddraw/device.c | 50 +++++--- dll/directx/wine/ddraw/executebuffer.c | 5 +- dll/directx/wine/ddraw/surface.c | 182 ++++++++++++--------------- dll/directx/wine/ddraw/vertexbuffer.c | 5 +- dll/directx/wine/ddraw/viewport.c | 4 +- media/doc/README.WINE | 2 +- 8 files changed, 175 insertions(+), 304 deletions(-) diff --git a/dll/directx/wine/ddraw/ddraw.c b/dll/directx/wine/ddraw/ddraw.c index 9712bb53ae..2ab9edd015 100644 --- a/dll/directx/wine/ddraw/ddraw.c +++ b/dll/directx/wine/ddraw/ddraw.c @@ -45,7 +45,6 @@ static struct enum_device_entry char interface_name[100]; char device_name[100]; const GUID *device_guid; - DWORD remove_caps; } device_list7[] = { /* T&L HAL device */ @@ -53,7 +52,6 @@ static struct enum_device_entry "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", "Wine D3D7 T&L HAL", &IID_IDirect3DTnLHalDevice, - 0, }, /* HAL device */ @@ -61,7 +59,6 @@ static struct enum_device_entry "WINE Direct3D7 Hardware acceleration using WineD3D", "Direct3D HAL", &IID_IDirect3DHALDevice, - 0, }, /* RGB device */ @@ -69,7 +66,6 @@ static struct enum_device_entry "WINE Direct3D7 RGB Software Emulation using WineD3D", "Wine D3D7 RGB", &IID_IDirect3DRGBDevice, - D3DDEVCAPS_HWTRANSFORMANDLIGHT, }, }; @@ -1419,23 +1415,10 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) caps->dwMinTextureHeight = 1; /* Convert DWORDs safely to WORDs */ - if (wined3d_caps.MaxTextureBlendStages > 0xffff) - caps->wMaxTextureBlendStages = 0xffff; - else - caps->wMaxTextureBlendStages = (WORD)wined3d_caps.MaxTextureBlendStages; - if (wined3d_caps.MaxSimultaneousTextures > 0xffff) - caps->wMaxSimultaneousTextures = 0xffff; - else - caps->wMaxSimultaneousTextures = (WORD)wined3d_caps.MaxSimultaneousTextures; - - if (wined3d_caps.MaxUserClipPlanes > 0xffff) - caps->wMaxUserClipPlanes = 0xffff; - else - caps->wMaxUserClipPlanes = (WORD)wined3d_caps.MaxUserClipPlanes; - if (wined3d_caps.MaxVertexBlendMatrices > 0xffff) - caps->wMaxVertexBlendMatrices = 0xffff; - else - caps->wMaxVertexBlendMatrices = (WORD)wined3d_caps.MaxVertexBlendMatrices; + caps->wMaxTextureBlendStages = min(wined3d_caps.MaxTextureBlendStages, 0xffff); + caps->wMaxSimultaneousTextures = min(wined3d_caps.MaxSimultaneousTextures, 0xffff); + caps->wMaxUserClipPlanes = min(wined3d_caps.MaxUserClipPlanes, D3DMAXUSERCLIPPLANES); + caps->wMaxVertexBlendMatrices = min(wined3d_caps.MaxVertexBlendMatrices, 0xffff); caps->deviceGUID = IID_IDirect3DTnLHalDevice; @@ -1447,28 +1430,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) return DD_OK; } -HRESULT CALLBACK enum_zbuffer(DDPIXELFORMAT *format, void *ctx) -{ - DDCAPS *caps = ctx; - - switch (format->u1.dwZBufferBitDepth) - { - case 8: - caps->dwZBufferBitDepths |= DDBD_8; - break; - case 16: - caps->dwZBufferBitDepths |= DDBD_16; - break; - case 24: - caps->dwZBufferBitDepths |= DDBD_24; - break; - case 32: - caps->dwZBufferBitDepths |= DDBD_32; - break; - } - return D3DENUMRET_OK; -} - /***************************************************************************** * IDirectDraw7::GetCaps * @@ -1549,10 +1510,6 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD caps.dwCaps |= DDCAPS_ALIGNSTRIDE; caps.dwAlignStrideAlign = DDRAW_STRIDE_ALIGNMENT; - caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps; - - IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps); - if(DriverCaps) { DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps); @@ -1665,17 +1622,14 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 struct ddraw *ddraw = impl_from_IDirectDraw7(iface); struct wined3d_display_mode mode; HRESULT hr; - DWORD Size; TRACE("iface %p, surface_desc %p.\n", iface, DDSD); - wined3d_mutex_lock(); /* This seems sane */ - if (!DDSD) - { - wined3d_mutex_unlock(); + if (!DDSD || (DDSD->dwSize != sizeof(DDSURFACEDESC) && DDSD->dwSize != sizeof(DDSURFACEDESC2))) return DDERR_INVALIDPARAMS; - } + + wined3d_mutex_lock(); if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL))) { @@ -1684,10 +1638,8 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2 return hr; } - Size = DDSD->dwSize; - memset(DDSD, 0, Size); - - DDSD->dwSize = Size; + memset(DDSD, 0, DDSD->dwSize); + DDSD->dwSize = sizeof(*DDSD); DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; DDSD->dwWidth = mode.width; DDSD->dwHeight = mode.height; @@ -1720,21 +1672,25 @@ static HRESULT WINAPI ddraw4_GetDisplayMode(IDirectDraw4 *iface, DDSURFACEDESC2 static HRESULT WINAPI ddraw2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC *surface_desc) { struct ddraw *ddraw = impl_from_IDirectDraw2(iface); + HRESULT hr; TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); - /* FIXME: Test sizes, properly convert surface_desc */ - return ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + hr = ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + if (SUCCEEDED(hr)) surface_desc->dwSize = sizeof(*surface_desc); + return hr; } static HRESULT WINAPI ddraw1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *surface_desc) { struct ddraw *ddraw = impl_from_IDirectDraw(iface); + HRESULT hr; TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); - /* FIXME: Test sizes, properly convert surface_desc */ - return ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + hr = ddraw7_GetDisplayMode(&ddraw->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); + if (SUCCEEDED(hr)) surface_desc->dwSize = sizeof(*surface_desc); + return hr; } /***************************************************************************** @@ -2101,14 +2057,7 @@ static HRESULT WINAPI d3d1_Initialize(IDirect3D *iface, REFIID riid) *****************************************************************************/ static HRESULT WINAPI ddraw7_FlipToGDISurface(IDirectDraw7 *iface) { - struct ddraw *ddraw = impl_from_IDirectDraw7(iface); - - TRACE("iface %p.\n", iface); - - ddraw->flags |= DDRAW_GDI_FLIP; - - if (ddraw->primary) - ddraw_surface_update_frontbuffer(ddraw->primary, NULL, FALSE); + FIXME("iface %p stub!\n", iface); return DD_OK; } @@ -3240,97 +3189,46 @@ static HRESULT WINAPI ddraw7_EnumSurfaces(IDirectDraw7 *iface, DWORD Flags, { struct ddraw *ddraw = impl_from_IDirectDraw7(iface); struct ddraw_surface *surf; - DWORD match_flags = Flags & (DDENUMSURFACES_ALL | DDENUMSURFACES_NOMATCH | DDENUMSURFACES_MATCH); + BOOL all, nomatch; + DDSURFACEDESC2 desc; + struct list *entry, *entry2; 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 (Flags & DDENUMSURFACES_CANBECREATED) - { - IDirectDrawSurface7 *surface; - DDSURFACEDESC2 testdesc; - HRESULT hr; - - if (match_flags != DDENUMSURFACES_MATCH) - return DDERR_INVALIDPARAMS; - - if (!DDSD) - return DDERR_INVALIDPARAMS; + wined3d_mutex_lock(); - 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; - } + /* 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); - hr = IDirectDraw7_CreateSurface(iface, &testdesc, &surface, NULL); - if (SUCCEEDED(hr)) + if (!surf->iface_count) { - surf = unsafe_impl_from_IDirectDrawSurface7(surface); - Callback(NULL, &surf->surface_desc, Context); - IDirectDrawSurface7_Release(surface); + WARN("Not enumerating surface %p because it doesn't have any references.\n", surf); + continue; } - 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; - - wined3d_mutex_lock(); - - /* Use the _SAFE enumeration, the app may destroy enumerated surfaces */ - LIST_FOR_EACH_SAFE(entry, entry2, &ddraw->surface_list) + if (all || (nomatch != ddraw_match_surface_desc(DDSD, &surf->surface_desc))) { - surf = LIST_ENTRY(entry, struct ddraw_surface, surface_list_entry); - - if (!surf->iface_count) + TRACE("Enumerating surface %p.\n", surf); + desc = surf->surface_desc; + IDirectDrawSurface7_AddRef(&surf->IDirectDrawSurface7_iface); + if (Callback(&surf->IDirectDrawSurface7_iface, &desc, Context) != DDENUMRET_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(); + return DD_OK; } } - - wined3d_mutex_unlock(); } - else - return DDERR_INVALIDPARAMS; + + wined3d_mutex_unlock(); return DD_OK; } @@ -3728,7 +3626,6 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA { struct ddraw *ddraw = impl_from_IDirect3D7(iface); D3DDEVICEDESC7 device_desc7; - DWORD dev_caps; HRESULT hr; size_t i; @@ -3745,15 +3642,11 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA return hr; } - dev_caps = device_desc7.dwDevCaps; - for (i = 0; i < sizeof(device_list7)/sizeof(device_list7[0]); i++) { HRESULT ret; device_desc7.deviceGUID = *device_list7[i].device_guid; - device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; - ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); if (ret != DDENUMRET_OK) { @@ -4151,8 +4044,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd if (!fds || !fdr) return DDERR_INVALIDPARAMS; - if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) || (fdr->dwSize != sizeof(D3DFINDDEVICERESULT1) && - fdr->dwSize != sizeof(D3DFINDDEVICERESULT2) && fdr->dwSize != sizeof(D3DFINDDEVICERESULT))) + if (fds->dwSize != sizeof(D3DFINDDEVICESEARCH) + || fdr->dwSize != sizeof(D3DFINDDEVICERESULT)) return DDERR_INVALIDPARAMS; if ((fds->dwFlags & D3DFDS_COLORMODEL) @@ -4181,24 +4074,8 @@ static HRESULT WINAPI d3d3_FindDevice(IDirect3D3 *iface, D3DFINDDEVICESEARCH *fd /* Now return our own GUID */ ddraw_d3dcaps1_from_7(&desc1, &desc7); fdr->guid = IID_D3DDEVICE_WineD3D; - - if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT1)) - { - D3DFINDDEVICERESULT1 *fdr1 = (D3DFINDDEVICERESULT1 *)fdr; - memcpy(&fdr1->ddHwDesc, &desc1, sizeof(fdr1->ddHwDesc)); - memcpy(&fdr1->ddSwDesc, &desc1, sizeof(fdr1->ddSwDesc)); - } - else if (fdr->dwSize == sizeof(D3DFINDDEVICERESULT2)) - { - D3DFINDDEVICERESULT2 *fdr2 = (D3DFINDDEVICERESULT2 *)fdr; - memcpy(&fdr2->ddHwDesc, &desc1, sizeof(fdr2->ddHwDesc)); - memcpy(&fdr2->ddSwDesc, &desc1, sizeof(fdr2->ddSwDesc)); - } - else - { - fdr->ddHwDesc = desc1; - fdr->ddSwDesc = desc1; - } + fdr->ddHwDesc = desc1; + fdr->ddSwDesc = desc1; TRACE("Returning Wine's wined3d device with (undumped) capabilities.\n"); @@ -4255,7 +4132,7 @@ static HRESULT WINAPI d3d7_CreateDevice(IDirect3D7 *iface, REFCLSID riid, TRACE("iface %p, riid %s, surface %p, device %p.\n", iface, debugstr_guid(riid), surface, device); wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, target, (IUnknown *)surface, 7, &object, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, target, (IUnknown *)surface, 7, &object, NULL))) { *device = &object->IDirect3DDevice7_iface; } @@ -4284,7 +4161,7 @@ static HRESULT WINAPI d3d3_CreateDevice(IDirect3D3 *iface, REFCLSID riid, return CLASS_E_NOAGGREGATION; wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 3, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice3_iface; } @@ -4310,7 +4187,7 @@ static HRESULT WINAPI d3d2_CreateDevice(IDirect3D2 *iface, REFCLSID riid, iface, debugstr_guid(riid), surface, device); wined3d_mutex_lock(); - if (SUCCEEDED(hr = d3d_device_create(ddraw, riid, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) + if (SUCCEEDED(hr = d3d_device_create(ddraw, surface_impl, (IUnknown *)surface, 2, &device_impl, NULL))) { *device = &device_impl->IDirect3DDevice2_iface; } @@ -4682,7 +4559,7 @@ static const struct IDirectDraw2Vtbl ddraw2_vtbl = ddraw2_GetAvailableVidMem, }; -static struct IDirectDrawVtbl ddraw1_vtbl = +static const struct IDirectDrawVtbl ddraw1_vtbl = { /* IUnknown */ ddraw1_QueryInterface, diff --git a/dll/directx/wine/ddraw/ddraw_private.h b/dll/directx/wine/ddraw/ddraw_private.h index a7d19d32f6..04ee59c05f 100644 --- a/dll/directx/wine/ddraw/ddraw_private.h +++ b/dll/directx/wine/ddraw/ddraw_private.h @@ -44,6 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + extern const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops DECLSPEC_HIDDEN; extern DWORD force_refresh_rate DECLSPEC_HIDDEN; @@ -62,14 +64,13 @@ struct FvfToDecl #define DDRAW_NO3D 0x00000008 #define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_RECURSIVE 0x00000020 -#define DDRAW_GDI_FLIP 0x00000040 #define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \ | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT) + | WINED3D_LEGACY_CUBEMAP_FILTERING) enum ddraw_device_state { @@ -308,7 +309,6 @@ struct d3d_device IUnknown IUnknown_inner; LONG ref; UINT version; - BOOL hw; IUnknown *outer_unknown; struct wined3d_device *wined3d_device; @@ -349,9 +349,11 @@ struct d3d_device /* Handle management */ struct ddraw_handle_table handle_table; D3DMATRIXHANDLE world, proj, view; + + struct wined3d_vec4 user_clip_planes[D3DMAXUSERCLIPPLANES]; }; -HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) DECLSPEC_HIDDEN; enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device *device) DECLSPEC_HIDDEN; diff --git a/dll/directx/wine/ddraw/device.c b/dll/directx/wine/ddraw/device.c index 6b93266467..fe48ad3b36 100644 --- a/dll/directx/wine/ddraw/device.c +++ b/dll/directx/wine/ddraw/device.c @@ -1166,7 +1166,7 @@ static HRESULT WINAPI d3d_device3_EnumTextureFormats(IDirect3DDevice3 *iface, * IDirect3DDevice2::EnumTextureformats * * EnumTextureFormats for Version 1 and 2, see - * IDirect3DDevice7::EnumTexureFormats for a more detailed description. + * IDirect3DDevice7::EnumTextureFormats for a more detailed description. * * This version has a different callback and does not enumerate FourCC * formats @@ -1852,7 +1852,7 @@ static HRESULT d3d_device7_SetRenderTarget(IDirect3DDevice7 *iface, return DDERR_INVALIDCAPS; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); wined3d_mutex_unlock(); @@ -1928,7 +1928,7 @@ static HRESULT WINAPI d3d_device3_SetRenderTarget(IDirect3DDevice3 *iface, return DDERR_INVALIDPIXELFORMAT; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface4_AddRef(target); @@ -1977,7 +1977,7 @@ static HRESULT WINAPI d3d_device2_SetRenderTarget(IDirect3DDevice2 *iface, return DDERR_INVALIDPIXELFORMAT; } - if (device->hw && !(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target_impl); IDirectDrawSurface_AddRef(target); @@ -6453,6 +6453,7 @@ static HRESULT WINAPI d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *i static HRESULT d3d_device7_SetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + const struct wined3d_vec4 *wined3d_plane; HRESULT hr; TRACE("iface %p, idx %u, plane %p.\n", iface, idx, plane); @@ -6460,8 +6461,19 @@ static HRESULT d3d_device7_SetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DV if (!plane) return DDERR_INVALIDPARAMS; + wined3d_plane = (struct wined3d_vec4 *)plane; + wined3d_mutex_lock(); - hr = wined3d_device_set_clip_plane(device->wined3d_device, idx, (struct wined3d_vec4 *)plane); + hr = wined3d_device_set_clip_plane(device->wined3d_device, idx, wined3d_plane); + if (idx < ARRAY_SIZE(device->user_clip_planes)) + { + device->user_clip_planes[idx] = *wined3d_plane; + if (hr == WINED3DERR_INVALIDCALL) + { + WARN("Clip plane %u is not supported.\n", idx); + hr = D3D_OK; + } + } wined3d_mutex_unlock(); return hr; @@ -6501,6 +6513,7 @@ static HRESULT WINAPI d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *ifa static HRESULT d3d_device7_GetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DVALUE *plane) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_vec4 *wined3d_plane; HRESULT hr; TRACE("iface %p, idx %u, plane %p.\n", iface, idx, plane); @@ -6508,8 +6521,16 @@ static HRESULT d3d_device7_GetClipPlane(IDirect3DDevice7 *iface, DWORD idx, D3DV if (!plane) return DDERR_INVALIDPARAMS; + wined3d_plane = (struct wined3d_vec4 *)plane; + wined3d_mutex_lock(); - hr = wined3d_device_get_clip_plane(device->wined3d_device, idx, (struct wined3d_vec4 *)plane); + hr = wined3d_device_get_clip_plane(device->wined3d_device, idx, wined3d_plane); + if (hr == WINED3DERR_INVALIDCALL && idx < ARRAY_SIZE(device->user_clip_planes)) + { + WARN("Clip plane %u is not supported.\n", idx); + *wined3d_plane = device->user_clip_planes[idx]; + hr = D3D_OK; + } wined3d_mutex_unlock(); return hr; @@ -6866,7 +6887,7 @@ enum wined3d_depth_buffer_type d3d_device_update_depth_stencil(struct d3d_device return WINED3D_ZB_TRUE; } -static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, BOOL hw, +static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, IUnknown *outer_unknown) { static const D3DMATRIX ident = @@ -6889,7 +6910,6 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B device->IUnknown_inner.lpVtbl = &d3d_device_inner_vtbl; device->ref = 1; device->version = version; - device->hw = hw; if (outer_unknown) device->outer_unknown = outer_unknown; @@ -6940,18 +6960,14 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, B return D3D_OK; } -HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_surface *target, IUnknown *rt_iface, +HRESULT d3d_device_create(struct ddraw *ddraw, struct ddraw_surface *target, IUnknown *rt_iface, UINT version, struct d3d_device **device, IUnknown *outer_unknown) { struct d3d_device *object; - BOOL hw = TRUE; HRESULT hr; - TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n", - ddraw, debugstr_guid(guid), target, version, device, outer_unknown); - - if (IsEqualGUID(guid, &IID_IDirect3DRGBDevice)) - hw = FALSE; + TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n", + ddraw, target, version, device, outer_unknown); if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) || (target->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) @@ -6966,7 +6982,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_NOPALETTEATTACHED; } - if (hw && !(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + if (!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) { WARN("Surface %p is not in video memory.\n", target); return D3DERR_SURFACENOTINVIDMEM; @@ -6993,7 +7009,7 @@ HRESULT d3d_device_create(struct ddraw *ddraw, const GUID *guid, struct ddraw_su return DDERR_OUTOFMEMORY; } - if (FAILED(hr = d3d_device_init(object, ddraw, hw, target, rt_iface, version, outer_unknown))) + if (FAILED(hr = d3d_device_init(object, ddraw, target, rt_iface, version, outer_unknown))) { WARN("Failed to initialize device, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/dll/directx/wine/ddraw/executebuffer.c b/dll/directx/wine/ddraw/executebuffer.c index 1bc5b5c5fb..7b68bd70b5 100644 --- a/dll/directx/wine/ddraw/executebuffer.c +++ b/dll/directx/wine/ddraw/executebuffer.c @@ -297,10 +297,7 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, ci->wStart, ci->wDest, ci->dwCount, ci->dwFlags); if (ci->dwFlags & D3DPROCESSVERTICES_UPDATEEXTENTS) - { - static int once; - if (!once++) FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); - } + FIXME("D3DPROCESSVERTICES_UPDATEEXTENTS not implemented.\n"); if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) FIXME("D3DPROCESSVERTICES_NOCOLOR not implemented.\n"); diff --git a/dll/directx/wine/ddraw/surface.c b/dll/directx/wine/ddraw/surface.c index 74f2d15d27..abae18ba6c 100644 --- a/dll/directx/wine/ddraw/surface.c +++ b/dll/directx/wine/ddraw/surface.c @@ -37,7 +37,6 @@ static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDra * to support windowless rendering first. */ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read) { - struct ddraw *ddraw = surface->ddraw; HDC surface_dc, screen_dc; int x, y, w, h; HRESULT hr; @@ -58,14 +57,14 @@ HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RE if (w <= 0 || h <= 0) return DD_OK; - if (ddraw->swapchain_window && !(ddraw->flags & DDRAW_GDI_FLIP)) + if (surface->ddraw->swapchain_window) { /* Nothing to do, we control the frontbuffer, or at least the parts we * care about. */ if (read) return DD_OK; - return wined3d_texture_blt(ddraw->wined3d_frontbuffer, 0, rect, + return wined3d_texture_blt(surface->ddraw->wined3d_frontbuffer, 0, rect, surface->wined3d_texture, surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT); } @@ -204,7 +203,7 @@ static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, { HRESULT hr; - if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface, + if (FAILED(hr = d3d_device_create(This->ddraw, This, (IUnknown *)&This->IDirectDrawSurface_iface, 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface))) { This->device1 = NULL; @@ -5181,46 +5180,6 @@ static struct ddraw_surface *get_sub_mimaplevel(struct ddraw_surface *surface) return impl_from_IDirectDrawSurface7(next_level); } -static BOOL compare_format(DDPIXELFORMAT *format1, DDPIXELFORMAT *format2) -{ - if ((format1->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC)) != - (format2->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_FOURCC))) - return FALSE; - - if (format1->dwFlags & (DDPF_RGB|DDPF_YUV)) - { - if (!(format1->dwFlags & DDPF_ALPHA)) - { - /* The RGB and YUV bits are stored in the same fields */ - if (format1->u1.dwRGBBitCount != format2->u1.dwRGBBitCount) - return FALSE; - - if (format1->u2.dwRBitMask != format2->u2.dwRBitMask) - return FALSE; - - if (format1->u3.dwGBitMask != format2->u3.dwGBitMask) - return FALSE; - - if (format1->u4.dwBBitMask != format2->u4.dwBBitMask) - return FALSE; - } - - if (format1->dwFlags & (DDPF_ALPHAPIXELS | DDPF_ALPHA)) - { - if (format1->u5.dwRGBAlphaBitMask != format2->u5.dwRGBAlphaBitMask) - return FALSE; - } - } - - if (format1->dwFlags & DDPF_FOURCC) - { - if (format1->dwFourCC != format2->dwFourCC) - return FALSE; - } - - return TRUE; -} - /***************************************************************************** * IDirect3DTexture2::Load * @@ -5242,7 +5201,7 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu { struct ddraw_surface *dst_surface = impl_from_IDirect3DTexture2(iface); struct ddraw_surface *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); - RECT src_rect, dst_rect; + struct wined3d_resource *dst_resource, *src_resource; HRESULT hr; TRACE("iface %p, src_texture %p.\n", iface, src_texture); @@ -5255,60 +5214,90 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu wined3d_mutex_lock(); + dst_resource = wined3d_texture_get_resource(dst_surface->wined3d_texture); + src_resource = wined3d_texture_get_resource(src_surface->wined3d_texture); + + if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) + || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) + { + ERR("Trying to load surfaces with different mip-map counts.\n"); + } + for (;;) { - DDSURFACEDESC *src_desc = (DDSURFACEDESC *)&src_surface->surface_desc; + struct ddraw_palette *dst_pal, *src_pal; + DDSURFACEDESC *src_desc, *dst_desc; TRACE("Copying surface %p to surface %p.\n", src_surface, dst_surface); - if (compare_format(&src_surface->surface_desc.u4.ddpfPixelFormat, - &dst_surface->surface_desc.u4.ddpfPixelFormat)) - { - struct ddraw_palette *dst_pal, *src_pal; + /* Suppress the ALLOCONLOAD flag */ + dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; - /* Get the palettes */ - dst_pal = dst_surface->palette; - src_pal = src_surface->palette; + /* Get the palettes */ + dst_pal = dst_surface->palette; + src_pal = src_surface->palette; - if (src_pal) - { - PALETTEENTRY palent[256]; + if (src_pal) + { + PALETTEENTRY palent[256]; - if (!dst_pal) - { - wined3d_mutex_unlock(); - return DDERR_NOPALETTEATTACHED; - } - IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + if (!dst_pal) + { + wined3d_mutex_unlock(); + return DDERR_NOPALETTEATTACHED; } + IDirectDrawPalette_GetEntries(&src_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + IDirectDrawPalette_SetEntries(&dst_pal->IDirectDrawPalette_iface, 0, 0, 256, palent); + } + /* Copy one surface on the other */ + dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); + src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); + + if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) + { + /* Should also check for same pixel format, u1.lPitch, ... */ + ERR("Error in surface sizes.\n"); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } + else + { + struct wined3d_map_desc src_map_desc, dst_map_desc; + + /* Copy the src blit color key if the source has one, don't erase + * the destination's ckey if the source has none */ if (src_desc->dwFlags & DDSD_CKSRCBLT) { IDirectDrawSurface7_SetColorKey(&dst_surface->IDirectDrawSurface7_iface, DDCKEY_SRCBLT, &src_desc->ddckCKSrcBlt); } - } - else - { - if (src_desc->dwFlags & DDSD_CKSRCBLT) - return E_FAIL; - } - /* Suppress the ALLOCONLOAD flag */ - dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; + if (FAILED(hr = wined3d_resource_map(src_resource, + src_surface->sub_resource_idx, &src_map_desc, NULL, 0))) + { + ERR("Failed to lock source surface, hr %#x.\n", hr); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } - SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth, src_surface->surface_desc.dwHeight); - SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth, dst_surface->surface_desc.dwHeight); + if (FAILED(hr = wined3d_resource_map(dst_resource, + dst_surface->sub_resource_idx, &dst_map_desc, NULL, 0))) + { + ERR("Failed to lock destination surface, hr %#x.\n", hr); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); + wined3d_mutex_unlock(); + return D3DERR_TEXTURE_LOAD_FAILED; + } - hr = wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, &dst_rect, - src_surface->wined3d_texture, src_surface->sub_resource_idx, &src_rect, - 0, NULL, WINED3D_TEXF_LINEAR); - if (FAILED(hr)) - { - ERR("Failed to blit surface, hr %#x.\n", hr); - wined3d_mutex_unlock(); - return hr; + if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) + memcpy(dst_map_desc.data, src_map_desc.data, src_surface->surface_desc.u1.dwLinearSize); + else + memcpy(dst_map_desc.data, src_map_desc.data, src_map_desc.row_pitch * src_desc->dwHeight); + + wined3d_resource_unmap(dst_resource, dst_surface->sub_resource_idx); + wined3d_resource_unmap(src_resource, src_surface->sub_resource_idx); } if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) @@ -5321,11 +5310,12 @@ static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTextu else dst_surface = NULL; - if (src_surface && !dst_surface) - return DDERR_NOTFOUND; - if (!src_surface || !dst_surface) + { + if (src_surface != dst_surface) + ERR("Loading surface with different mipmap structure.\n"); break; + } } wined3d_mutex_unlock(); @@ -5555,7 +5545,7 @@ static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = ddraw_surface2_PageUnlock, }; -static struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = +static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = { /* IUnknown */ ddraw_surface1_QueryInterface, @@ -6007,6 +5997,9 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ HeapFree(GetProcessHeap(), 0, texture); return hr_ddraw_from_wined3d(hr); } + + wined3d_device_set_render_state(ddraw->wined3d_device, WINED3D_RS_ZENABLE, + !!swapchain_desc.enable_auto_depth_stencil); } } @@ -6102,24 +6095,7 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_ if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) { - /* - * The ddraw RGB device allows to use system memory surfaces as rendering target. - * This does not cause problems because the RGB device does software rasterization - * though it will fail with hardware accelerated ddraw. In order to be partially - * compatible with games requesting explicitly the RGB device, we ignore the - * specified location and try to create rendering targets in video memory if - * possible. - */ - if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && - SUCCEEDED(hr = wined3d_check_device_format(ddraw->wined3d, WINED3DADAPTER_DEFAULT, - WINED3D_DEVICE_TYPE_HAL, mode.format_id, WINED3DUSAGE_RENDERTARGET, - WINED3D_RTYPE_TEXTURE_2D, wined3d_desc.format))) - { - FIXME("Application wants to create rendering target in system memory, using video memory instead\n"); - wined3d_desc.usage |= WINED3DUSAGE_RENDERTARGET; - } - else - wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; + wined3d_desc.pool = WINED3D_POOL_SYSTEM_MEM; } else { diff --git a/dll/directx/wine/ddraw/vertexbuffer.c b/dll/directx/wine/ddraw/vertexbuffer.c index 04d7adb94a..155a8dd3ff 100644 --- a/dll/directx/wine/ddraw/vertexbuffer.c +++ b/dll/directx/wine/ddraw/vertexbuffer.c @@ -159,6 +159,9 @@ static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface, TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size); + if (buffer->version != 7) + flags &= ~(DDLOCK_NOOVERWRITE | DDLOCK_DISCARDCONTENTS); + /* Writeonly: Pointless. Event: Unsupported by native according to the sdk * nosyslock: Not applicable */ @@ -246,7 +249,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_Unlock(IDirect3DVertexBuffer7 *iface) * SrcIndex: Index of the first vertex in the src buffer to process * D3DDevice: Device to use for transformation * Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying - * unchaned vertices + * unchanged vertices * * Returns: * D3D_OK on success diff --git a/dll/directx/wine/ddraw/viewport.c b/dll/directx/wine/ddraw/viewport.c index 04eaa4b23a..a62cc319ec 100644 --- a/dll/directx/wine/ddraw/viewport.c +++ b/dll/directx/wine/ddraw/viewport.c @@ -1127,7 +1127,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport2(IDirect3DViewport2 *ifa /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewport2Vtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); } struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface) @@ -1135,7 +1135,7 @@ struct d3d_viewport *unsafe_impl_from_IDirect3DViewport(IDirect3DViewport *iface /* IDirect3DViewport and IDirect3DViewport3 use the same iface. */ if (!iface) return NULL; assert(iface->lpVtbl == (IDirect3DViewportVtbl *)&d3d_viewport_vtbl); - return CONTAINING_RECORD((IDirect3DViewport3 *)iface, struct d3d_viewport, IDirect3DViewport3_iface); + return CONTAINING_RECORD(iface, struct d3d_viewport, IDirect3DViewport3_iface); } void d3d_viewport_init(struct d3d_viewport *viewport, struct ddraw *ddraw) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 375b675a93..fb678a5a5e 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -28,7 +28,7 @@ reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3drm # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-2.9 -reactos/dll/directx/wine/ddraw # Synced to WineStaging-2.16 +reactos/dll/directx/wine/ddraw # Synced to Wine-3.0 reactos/dll/directx/wine/devenum # Synced to WineStaging-2.9 reactos/dll/directx/wine/dinput # Synced to WineStaging-2.16 reactos/dll/directx/wine/dinput8 # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [D3D8] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e6c95b14e36b35adbedd7…
commit e6c95b14e36b35adbedd796792ed4ed830996c2a Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:13:33 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:13:33 2018 +0100 [D3D8] Sync with Wine 3.0. CORE-14225 --- dll/directx/wine/d3d8/d3d8_main.c | 80 ++++++++++++++++++++------------------- dll/directx/wine/d3d8/device.c | 7 +++- dll/directx/wine/d3d8/directx.c | 2 +- dll/directx/wine/d3d8/texture.c | 6 +-- media/doc/README.WINE | 2 +- 5 files changed, 51 insertions(+), 46 deletions(-) diff --git a/dll/directx/wine/d3d8/d3d8_main.c b/dll/directx/wine/d3d8/d3d8_main.c index a8ad29b3b3..144817a545 100644 --- a/dll/directx/wine/d3d8/d3d8_main.c +++ b/dll/directx/wine/d3d8/d3d8_main.c @@ -53,73 +53,75 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version) /*********************************************************************** * ValidateVertexShader (D3D8.@) + * + * I've seen reserved1 and reserved2 always passed as 0's + * bool seems always passed as 0 or 1, but other values work as well... + * toto result? */ -HRESULT WINAPI ValidateVertexShader(DWORD *vertexshader, DWORD *reserved1, DWORD *reserved2, - BOOL return_error, char **errors) +HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto) { - const char *message = ""; - HRESULT hr = E_FAIL; + HRESULT ret; + static BOOL warned; - TRACE("(%p %p %p %d %p): semi-stub\n", vertexshader, reserved1, reserved2, return_error, errors); + if (TRACE_ON(d3d8) || !warned) { + FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto); + warned = TRUE; + } - if (!vertexshader) - { - message = "(Global Validation Error) Version Token: Code pointer cannot be NULL.\n"; - goto done; - } + if (!vertexshader) + return E_FAIL; - switch (*vertexshader) - { + if (reserved1 || reserved2) + return E_FAIL; + + switch(*vertexshader) { case 0xFFFE0101: case 0xFFFE0100: - hr = S_OK; + ret=S_OK; break; - default: WARN("Invalid shader version token %#x.\n", *vertexshader); - message = "(Global Validation Error) Version Token: Unsupported vertex shader version.\n"; - } + ret=E_FAIL; + } -done: - if (!return_error) message = ""; - if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) - strcpy(*errors, message); - - return hr; + return ret; } /*********************************************************************** * ValidatePixelShader (D3D8.@) + * + * PARAMS + * toto result? */ -HRESULT WINAPI ValidatePixelShader(DWORD *pixelshader, DWORD *reserved1, BOOL return_error, char **errors) +HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto) { - const char *message = ""; - HRESULT hr = E_FAIL; + HRESULT ret; + static BOOL warned; + + if (TRACE_ON(d3d8) || !warned) { + FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto); + warned = TRUE; + } - TRACE("(%p %p %d %p): semi-stub\n", pixelshader, reserved1, return_error, errors); + if (!pixelshader) + return E_FAIL; - if (!pixelshader) - return E_FAIL; + if (reserved1) + return E_FAIL; - switch (*pixelshader) - { + switch(*pixelshader) { case 0xFFFF0100: case 0xFFFF0101: case 0xFFFF0102: case 0xFFFF0103: case 0xFFFF0104: - hr = S_OK; + ret=S_OK; break; default: WARN("Invalid shader version token %#x.\n", *pixelshader); - message = "(Global Validation Error) Version Token: Unsupported pixel shader version.\n"; - } - - if (!return_error) message = ""; - if (errors && (*errors = HeapAlloc(GetProcessHeap(), 0, strlen(message) + 1))) - strcpy(*errors, message); - - return hr; + ret=E_FAIL; + } + return ret; } void d3d8_resource_cleanup(struct d3d8_resource *resource) diff --git a/dll/directx/wine/d3d8/device.c b/dll/directx/wine/d3d8/device.c index 5dbfe174f9..6573baa355 100644 --- a/dll/directx/wine/d3d8/device.c +++ b/dll/directx/wine/d3d8/device.c @@ -734,6 +734,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface, { present_parameters->BackBufferCount = swapchain_desc.backbuffer_count; wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); + wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_ZENABLE, + !!swapchain_desc.enable_auto_depth_stencil); device->device_state = D3D8_DEVICE_STATE_OK; } else @@ -3258,8 +3260,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine return D3DERR_INVALIDCALL; } - hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_init_3d(device->wined3d_device, &swapchain_desc))) { WARN("Failed to initialize 3D, hr %#x.\n", hr); wined3d_device_release_focus_window(device->wined3d_device); @@ -3269,6 +3270,8 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine return hr; } + wined3d_device_set_render_state(device->wined3d_device, + WINED3D_RS_ZENABLE, !!swapchain_desc.enable_auto_depth_stencil); wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0); wined3d_mutex_unlock(); diff --git a/dll/directx/wine/d3d8/directx.c b/dll/directx/wine/d3d8/directx.c index ccf54565e2..ffb8ddefb4 100644 --- a/dll/directx/wine/d3d8/directx.c +++ b/dll/directx/wine/d3d8/directx.c @@ -405,7 +405,7 @@ BOOL d3d8_init(struct d3d8 *d3d8) DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART - | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT; + | WINED3D_LEGACY_CUBEMAP_FILTERING; d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; d3d8->refcount = 1; diff --git a/dll/directx/wine/d3d8/texture.c b/dll/directx/wine/d3d8/texture.c index c0fa7469ae..b860859987 100644 --- a/dll/directx/wine/d3d8/texture.c +++ b/dll/directx/wine/d3d8/texture.c @@ -20,17 +20,17 @@ static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface) { - return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface) { - return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) { - return CONTAINING_RECORD((IDirect3DBaseTexture8 *)iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); + return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5077043221..375b675a93 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -22,7 +22,7 @@ reactos/sdk/tools/wpp # Synced to WineStaging-2.9 The following libraries are shared with Wine. reactos/dll/directx/wine/amstream # Synced to Wine-3.0 -reactos/dll/directx/wine/d3d8 # Synced to WineStaging-2.16 +reactos/dll/directx/wine/d3d8 # Synced to Wine-3.0 reactos/dll/directx/wine/d3d9 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3drm # Synced to WineStaging-2.16
6 years, 11 months
1
0
0
0
01/01: [AMSTREAM] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=928bad849bd6e7bfb7568…
commit 928bad849bd6e7bfb7568d1ac050eb332b9f58b9 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:11:24 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:11:24 2018 +0100 [AMSTREAM] Sync with Wine 3.0. CORE-14225 --- dll/directx/wine/amstream/mediastreamfilter.c | 2 +- media/doc/README.WINE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dll/directx/wine/amstream/mediastreamfilter.c b/dll/directx/wine/amstream/mediastreamfilter.c index 0ba9a7033b..39c3a5eddb 100644 --- a/dll/directx/wine/amstream/mediastreamfilter.c +++ b/dll/directx/wine/amstream/mediastreamfilter.c @@ -58,7 +58,7 @@ typedef struct { static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface) { - return CONTAINING_RECORD((IBaseFilter *)iface, IMediaStreamFilterImpl, filter.IBaseFilter_iface); + return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter); } static HRESULT WINAPI BasePinImpl_CheckMediaType(BasePin *This, const AM_MEDIA_TYPE *pmt) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index f1703a5bed..5077043221 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -21,7 +21,7 @@ reactos/sdk/tools/wpp # Synced to WineStaging-2.9 The following libraries are shared with Wine. -reactos/dll/directx/wine/amstream # Synced to WineStaging-2.9 +reactos/dll/directx/wine/amstream # Synced to Wine-3.0 reactos/dll/directx/wine/d3d8 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3d9 # Synced to WineStaging-2.16 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-2.16
6 years, 11 months
1
0
0
0
01/01: [WINHLP32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9a9ebc0e93d1bf8c4f24b…
commit 9a9ebc0e93d1bf8c4f24ba3e71727c7f2f152143 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:10:10 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:10:10 2018 +0100 [WINHLP32] Sync with Wine 3.0. CORE-14225 --- base/applications/winhlp32/winhelp.c | 2 +- media/doc/README.WINE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base/applications/winhlp32/winhelp.c b/base/applications/winhlp32/winhelp.c index bf80603af3..fdd1b40969 100644 --- a/base/applications/winhlp32/winhelp.c +++ b/base/applications/winhlp32/winhelp.c @@ -1648,7 +1648,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) option = *cmdline; if (option) cmdline++; - while (*cmdline && *cmdline == ' ') cmdline++; + while (*cmdline == ' ') cmdline++; switch (option) { case 'i': diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 46b7bafe5a..f1703a5bed 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -238,7 +238,7 @@ reactos/base/applications/extrac32 # Synced to WineStaging-2.9 reactos/base/applications/iexplore # Synced to WineStaging-2.9 reactos/base/applications/notepad # Forked at Wine-20041201 reactos/base/applications/regedit # Out of sync -reactos/base/applications/winhlp32 # Synced to WineStaging-1.9.16 +reactos/base/applications/winhlp32 # Synced to Wine-3.0 reactos/base/applications/wordpad # Synced to WineStaging-1.9.16 reactos/base/applications/write # Synced to WineStaging-2.9 reactos/base/services/rpcss # Synced to WineStaging-1.9.16
6 years, 11 months
1
0
0
0
01/01: [XCOPY] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=502927fd0e0e2e3c90540…
commit 502927fd0e0e2e3c90540c7f97b986e5b23990f0 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:08:40 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:08:40 2018 +0100 [XCOPY] Sync with Wine 3.0. CORE-14225 --- base/applications/cmdutils/xcopy/xcopy.c | 2 +- media/doc/README.WINE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base/applications/cmdutils/xcopy/xcopy.c b/base/applications/cmdutils/xcopy/xcopy.c index e8455f0c6c..cda6e4eb63 100644 --- a/base/applications/cmdutils/xcopy/xcopy.c +++ b/base/applications/cmdutils/xcopy/xcopy.c @@ -99,7 +99,7 @@ static WCHAR *XCOPY_LoadMessage(UINT id) { * and hence required WriteConsoleW to output it, however if file i/o is * redirected, it needs to be WriteFile'd using OEM (not ANSI) format * ========================================================================= */ -static int __cdecl XCOPY_wprintf(const WCHAR *format, ...) { +static int WINAPIV XCOPY_wprintf(const WCHAR *format, ...) { static WCHAR *output_bufW = NULL; static char *output_bufA = NULL; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5afbe03c2f..46b7bafe5a 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -232,7 +232,7 @@ reactos/base/applications/cmdutils/schtasks # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/taskkill # Synced to Wine-3.0 reactos/base/applications/cmdutils/wmic # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/wscript # Synced to WineStaging-2.9 -reactos/base/applications/cmdutils/xcopy # Synced to WineStaging-2.9 +reactos/base/applications/cmdutils/xcopy # Synced to Wine-3.0 reactos/base/applications/games/winmine # Synced to WineStaging-2.16 with our own resources. reactos/base/applications/extrac32 # Synced to WineStaging-2.9 reactos/base/applications/iexplore # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [TASKKILL] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f7f635d47839d5742ace1…
commit f7f635d47839d5742ace1f80fc1a9a252550710e Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:07:31 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:07:31 2018 +0100 [TASKKILL] Sync with Wine 3.0. CORE-14225 --- base/applications/cmdutils/taskkill/taskkill.c | 4 ++-- media/doc/README.WINE | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/base/applications/cmdutils/taskkill/taskkill.c b/base/applications/cmdutils/taskkill/taskkill.c index 894e06a5ea..db3fab414e 100644 --- a/base/applications/cmdutils/taskkill/taskkill.c +++ b/base/applications/cmdutils/taskkill/taskkill.c @@ -77,7 +77,7 @@ static int taskkill_vprintfW(const WCHAR *msg, __ms_va_list va_args) return count; } -static int CDECL taskkill_printfW(const WCHAR *msg, ...) +static int WINAPIV taskkill_printfW(const WCHAR *msg, ...) { __ms_va_list va_args; int len; @@ -89,7 +89,7 @@ static int CDECL taskkill_printfW(const WCHAR *msg, ...) return len; } -static int CDECL taskkill_message_printfW(int msg, ...) +static int WINAPIV taskkill_message_printfW(int msg, ...) { __ms_va_list va_args; WCHAR msg_buffer[8192]; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5e66b918b0..5afbe03c2f 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -229,7 +229,7 @@ ReactOS shares the following programs with Winehq. reactos/base/applications/cmdutils/cscript # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/reg # Synced to Wine-3.0 reactos/base/applications/cmdutils/schtasks # Synced to WineStaging-2.9 -reactos/base/applications/cmdutils/taskkill # Synced to WineStaging-2.9 +reactos/base/applications/cmdutils/taskkill # Synced to Wine-3.0 reactos/base/applications/cmdutils/wmic # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/wscript # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/xcopy # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [REG_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=819443d39d34a2efb2ce1…
commit 819443d39d34a2efb2ce149818e11658a0a3a286 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:05:34 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:05:34 2018 +0100 [REG_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/reg/reg.c | 828 ++++++++++++++++++++++++++--------- 1 file changed, 612 insertions(+), 216 deletions(-) diff --git a/modules/rostests/winetests/reg/reg.c b/modules/rostests/winetests/reg/reg.c index 8c0b1fbd07..7d842c493d 100644 --- a/modules/rostests/winetests/reg/reg.c +++ b/modules/rostests/winetests/reg/reg.c @@ -29,6 +29,7 @@ #define TODO_REG_TYPE (0x0001u) #define TODO_REG_SIZE (0x0002u) #define TODO_REG_DATA (0x0004u) +#define TODO_REG_COMPARE (0x0008u) #define run_reg_exe(c,r) run_reg_exe_(__LINE__,c,r) static BOOL run_reg_exe_(unsigned line, const char *cmd, DWORD *rc) @@ -79,8 +80,11 @@ static void verify_reg_(unsigned line, HKEY hkey, const char* value, lok(type == exp_type, "got wrong type %d, expected %d\n", type, exp_type); todo_wine_if (todo & TODO_REG_SIZE) lok(size == exp_size, "got wrong size %d, expected %d\n", size, exp_size); - todo_wine_if (todo & TODO_REG_DATA) - lok(memcmp(data, exp_data, size) == 0, "got wrong data\n"); + if (exp_data) + { + todo_wine_if (todo & TODO_REG_DATA) + lok(memcmp(data, exp_data, size) == 0, "got wrong data\n"); + } } #define verify_reg_nonexist(k,v) verify_reg_nonexist_(__LINE__,k,v) @@ -93,6 +97,15 @@ static void verify_reg_nonexist_(unsigned line, HKEY hkey, const char *value) (value && *value) ? value : "(Default)", err); } +#define open_key(b,p,s,k) open_key_(__LINE__,b,p,s,k) +static void open_key_(unsigned line, const HKEY base, const char *path, const DWORD sam, HKEY *hkey) +{ + LONG err; + + err = RegOpenKeyExA(base, path, 0, KEY_READ|sam, hkey); + lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", err); +} + #define verify_key(k,s) verify_key_(__LINE__,k,s) static void verify_key_(unsigned line, HKEY key_base, const char *subkey) { @@ -120,6 +133,89 @@ static void verify_key_nonexist_(unsigned line, HKEY key_base, const char *subke RegCloseKey(hkey); } +#define add_key(k,p,s) add_key_(__LINE__,k,p,s) +static void add_key_(unsigned line, const HKEY hkey, const char *path, HKEY *subkey) +{ + LONG err; + + err = RegCreateKeyExA(hkey, path, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_READ|KEY_WRITE, NULL, subkey, NULL); + lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: %d\n", err); +} + +#define delete_key(k,p) delete_key_(__LINE__,k,p) +static void delete_key_(unsigned line, const HKEY hkey, const char *path) +{ + if (path && *path) + { + LONG err; + + err = RegDeleteKeyA(hkey, path); + lok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", err); + } +} + +static LONG delete_tree(const HKEY key, const char *subkey) +{ + HKEY hkey; + LONG ret; + char *subkey_name = NULL; + DWORD max_subkey_len, subkey_len; + static const char empty[1]; + + ret = RegOpenKeyExA(key, subkey, 0, KEY_READ, &hkey); + if (ret) return ret; + + ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &max_subkey_len, + NULL, NULL, NULL, NULL, NULL, NULL); + if (ret) goto cleanup; + + max_subkey_len++; + + subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len); + if (!subkey_name) + { + ret = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + + for (;;) + { + subkey_len = max_subkey_len; + ret = RegEnumKeyExA(hkey, 0, subkey_name, &subkey_len, NULL, NULL, NULL, NULL); + if (ret == ERROR_NO_MORE_ITEMS) break; + if (ret) goto cleanup; + ret = delete_tree(hkey, subkey_name); + if (ret) goto cleanup; + } + + ret = RegDeleteKeyA(hkey, empty); + +cleanup: + HeapFree(GetProcessHeap(), 0, subkey_name); + RegCloseKey(hkey); + return ret; +} + +#define add_value(k,n,t,d,s) add_value_(__LINE__,k,n,t,d,s) +static void add_value_(unsigned line, HKEY hkey, const char *name, DWORD type, + const void *data, size_t size) +{ + LONG err; + + err = RegSetValueExA(hkey, name, 0, type, (const BYTE *)data, size); + lok(err == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", err); +} + +#define delete_value(k,n) delete_value_(__LINE__,k,n) +static void delete_value_(unsigned line, const HKEY hkey, const char *name) +{ + LONG err; + + err = RegDeleteValueA(hkey, name); + lok(err == ERROR_SUCCESS, "RegDeleteValueA failed: %d\n", err); +} + static void test_add(void) { HKEY hkey; @@ -133,6 +229,12 @@ static void test_add(void) run_reg_exe("reg add /?", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + run_reg_exe("reg add /h", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg add -H", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); @@ -141,8 +243,7 @@ static void test_add(void) run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); - ok(err == ERROR_SUCCESS, "key creation failed, got %d\n", err); + open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); /* Test empty type */ run_reg_exe("reg add HKCU\\" KEY_BASE " /v emptyType /t \"\" /d WineTest /f", &r); @@ -169,14 +270,12 @@ static void test_add(void) run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest3\\ /f", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r); verify_key(hkey, "keytest3"); - err = RegDeleteKeyA(hkey, "keytest3"); - ok(err == ERROR_SUCCESS, "got exit code %d\n", err); + delete_key(hkey, "keytest3"); run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest4 /f", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r); verify_key(hkey, "keytest4"); - err = RegDeleteKeyA(hkey, "keytest4"); - ok(err == ERROR_SUCCESS, "got exit code %d\n", err); + delete_key(hkey, "keytest4"); /* REG_NONE */ run_reg_exe("reg add HKCU\\" KEY_BASE " /v none0 /d deadbeef /t REG_NONE /f", &r); @@ -498,8 +597,7 @@ static void test_add(void) run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid4 -", &r); ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "got %d\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); } static void test_delete(void) @@ -509,26 +607,27 @@ static void test_delete(void) DWORD r; const DWORD deadbeef = 0xdeadbeef; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + run_reg_exe("reg delete", &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); run_reg_exe("reg delete /?", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegCreateKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); - ok(err == ERROR_SUCCESS, "got %d\n", err); - - err = RegSetValueExA(hkey, "foo", 0, REG_DWORD, (LPBYTE)&deadbeef, sizeof(deadbeef)); - ok(err == ERROR_SUCCESS, "got %d\n" ,err); + run_reg_exe("reg delete /h", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegSetValueExA(hkey, "bar", 0, REG_DWORD, (LPBYTE)&deadbeef, sizeof(deadbeef)); - ok(err == ERROR_SUCCESS, "got %d\n" ,err); + run_reg_exe("reg delete -H", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegSetValueExA(hkey, "", 0, REG_DWORD, (LPBYTE)&deadbeef, sizeof(deadbeef)); - ok(err == ERROR_SUCCESS, "got %d\n" ,err); + add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey); + add_value(hkey, "foo", REG_DWORD, &deadbeef, sizeof(deadbeef)); + add_value(hkey, "bar", REG_DWORD, &deadbeef, sizeof(deadbeef)); + add_value(hkey, NULL, REG_DWORD, &deadbeef, sizeof(deadbeef)); - err = RegCreateKeyExA(hkey, "subkey", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hsubkey, NULL); - ok(err == ERROR_SUCCESS, "got %d\n" ,err); + add_key(hkey, "subkey", &hsubkey); RegCloseKey(hsubkey); run_reg_exe("reg delete HKCU\\" KEY_BASE " /v bar /f", &r); @@ -566,28 +665,31 @@ static void test_query(void) const DWORD dword1 = 0x123; const DWORD dword2 = 0xabc; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + run_reg_exe("reg query", &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); run_reg_exe("reg query /?", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + run_reg_exe("reg query /h", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg query -H", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + /* Create a test key */ - err = RegCreateKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + add_key(HKEY_CURRENT_USER, KEY_BASE, &key); run_reg_exe("reg query HKCU\\" KEY_BASE " /ve", &r); ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */), "got exit code %d, expected 0\n", r); - err = RegSetValueExA(key, "Test", 0, REG_SZ, (BYTE *)hello, sizeof(hello)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - err = RegSetValueExA(key, "Wine", 0, REG_DWORD, (BYTE *)&dword1, sizeof(dword1)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - err = RegSetValueExA(key, NULL, 0, REG_SZ, (BYTE *)empty1, sizeof(empty1)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + add_value(key, "Test", REG_SZ, hello, sizeof(hello)); + add_value(key, "Wine", REG_DWORD, &dword1, sizeof(dword1)); + add_value(key, NULL, REG_SZ, empty1, sizeof(empty1)); run_reg_exe("reg query HKCU\\" KEY_BASE, &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); @@ -608,17 +710,10 @@ static void test_query(void) ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); /* Create a test subkey */ - err = RegCreateKeyExA(key, "Subkey", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL); - ok(err == ERROR_SUCCESS, "got %d\n", err); - - err = RegSetValueExA(subkey, "Test", 0, REG_SZ, (BYTE *)world, sizeof(world)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - err = RegSetValueExA(subkey, "Wine", 0, REG_DWORD, (BYTE *)&dword2, sizeof(dword2)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - err = RegSetValueExA(subkey, NULL, 0, REG_SZ, (BYTE *)empty2, sizeof(empty2)); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + add_key(key, "Subkey", &subkey); + add_value(subkey, "Test", REG_SZ, world, sizeof(world)); + add_value(subkey, "Wine", REG_DWORD, &dword2, sizeof(dword2)); + add_value(subkey, NULL, REG_SZ, empty2, sizeof(empty2)); err = RegCloseKey(subkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); @@ -652,8 +747,7 @@ static void test_query(void) "got exit code %d, expected 0\n", r); /* Clean-up, then query */ - err = RegDeleteKeyA(key, "subkey"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(key, "subkey"); err = RegCloseKey(key); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); @@ -661,8 +755,7 @@ static void test_query(void) run_reg_exe("reg query HKCU\\" KEY_BASE "\\subkey", &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); run_reg_exe("reg query HKCU\\" KEY_BASE, &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); @@ -705,85 +798,50 @@ static void test_v_flags(void) ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); } -static BOOL write_reg_file(const char *value, char *tmp_name) +static BOOL write_file(const void *str, DWORD size) { - static const char regedit4[] = "REGEDIT4"; - static const char key[] = "[HKEY_CURRENT_USER\\" KEY_BASE "]"; - char file_data[MAX_PATH], tmp_path[MAX_PATH]; - HANDLE hfile; - DWORD written; + HANDLE file; BOOL ret; - - sprintf(file_data, "%s\n\n%s\n%s\n", regedit4, key, value); - - GetTempPathA(MAX_PATH, tmp_path); - GetTempFileNameA(tmp_path, "reg", 0, tmp_name); - - hfile = CreateFileA(tmp_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (hfile == INVALID_HANDLE_VALUE) - return FALSE; - - ret = WriteFile(hfile, file_data, strlen(file_data), &written, NULL); - CloseHandle(hfile); - return ret; -} - -#define test_import_str(c,r) test_import_str_(__LINE__,c,r) -static BOOL test_import_str_(unsigned line, const char *file_contents, DWORD *rc) -{ - HANDLE regfile; DWORD written; - BOOL ret; - regfile = CreateFileA("test.reg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - lok(regfile != INVALID_HANDLE_VALUE, "Failed to create test.reg file\n"); - if(regfile == INVALID_HANDLE_VALUE) + file = CreateFileA("test.reg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + if (file == INVALID_HANDLE_VALUE) return FALSE; - ret = WriteFile(regfile, file_contents, strlen(file_contents), &written, NULL); - lok(ret, "WriteFile failed: %u\n", GetLastError()); - CloseHandle(regfile); - - run_reg_exe("reg import test.reg", rc); - - ret = DeleteFileA("test.reg"); - lok(ret, "DeleteFile failed: %u\n", GetLastError()); + ret = WriteFile(file, str, size, &written, NULL); + ok(ret, "WriteFile failed: %u\n", GetLastError()); + CloseHandle(file); return ret; } -#define test_import_wstr(c,r) test_import_wstr_(__LINE__,c,r) -static BOOL test_import_wstr_(unsigned line, const char *file_contents, DWORD *rc) +#define test_import_str(c,r) import_reg(__LINE__,c,FALSE,r) +#define test_import_wstr(c,r) import_reg(__LINE__,c,TRUE,r) + +static BOOL import_reg(unsigned line, const char *contents, BOOL unicode, DWORD *rc) { - int lenA, len, memsize; - WCHAR *wstr; - HANDLE regfile; - DWORD written; + int lenA; BOOL ret; - lenA = strlen(file_contents); - - len = MultiByteToWideChar(CP_UTF8, 0, file_contents, lenA, NULL, 0); - memsize = len * sizeof(WCHAR); - wstr = HeapAlloc(GetProcessHeap(), 0, memsize); - if (!wstr) return FALSE; - MultiByteToWideChar(CP_UTF8, 0, file_contents, lenA, wstr, len); + lenA = strlen(contents); - regfile = CreateFileA("test.reg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - lok(regfile != INVALID_HANDLE_VALUE, "Failed to create test.reg file\n"); - if (regfile == INVALID_HANDLE_VALUE) + if (unicode) { + int len = MultiByteToWideChar(CP_UTF8, 0, contents, lenA, NULL, 0); + int size = len * sizeof(WCHAR); + WCHAR *wstr = HeapAlloc(GetProcessHeap(), 0, size); + if (!wstr) return FALSE; + MultiByteToWideChar(CP_UTF8, 0, contents, lenA, wstr, len); + + ret = write_file(wstr, size); HeapFree(GetProcessHeap(), 0, wstr); - return FALSE; } + else + ret = write_file(contents, lenA); - ret = WriteFile(regfile, wstr, memsize, &written, NULL); - lok(ret, "WriteFile failed: %u\n", GetLastError()); - CloseHandle(regfile); - - HeapFree(GetProcessHeap(), 0, wstr); + if (!ret) return FALSE; run_reg_exe("reg import test.reg", rc); @@ -796,51 +854,31 @@ static BOOL test_import_wstr_(unsigned line, const char *file_contents, DWORD *r static void test_import(void) { DWORD r, dword = 0x123, type, size; - char test1_reg[MAX_PATH], test2_reg[MAX_PATH], cmdline[MAX_PATH]; - char test_string[] = "Test string", buffer[24]; + char buffer[24]; HKEY hkey, subkey = NULL; LONG err; BYTE hex[8]; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + run_reg_exe("reg import", &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); run_reg_exe("reg import /?", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - run_reg_exe("reg import missing.reg", &r); - ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); - - /* Create test files */ - ok(write_reg_file("\"Wine\"=dword:00000123", test1_reg), "Failed to write registry file\n"); - ok(write_reg_file("@=\"Test string\"", test2_reg), "Failed to write registry file\n"); - - sprintf(cmdline, "reg import %s", test1_reg); - run_reg_exe(cmdline, &r); + run_reg_exe("reg import /h", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - sprintf(cmdline, "reg import %s", test2_reg); - run_reg_exe(cmdline, &r); + run_reg_exe("reg import -H", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - verify_reg(hkey, "Wine", REG_DWORD, &dword, sizeof(dword), 0); - verify_reg(hkey, "", REG_SZ, test_string, sizeof(test_string), 0); - - err = RegCloseKey(hkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - - sprintf(cmdline, "reg import %s %s", test1_reg, test2_reg); - run_reg_exe(cmdline, &r); + run_reg_exe("reg import missing.reg", &r); ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); - DeleteFileA(test1_reg); - DeleteFileA(test2_reg); + run_reg_exe("reg import a.reg b.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); /* Test file contents */ test_import_str("regedit\n", &r); @@ -897,8 +935,19 @@ static void test_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ|KEY_SET_VALUE, &hkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(HKEY_CURRENT_USER, KEY_BASE, KEY_SET_VALUE, &hkey); + + test_import_str("REGEDIT4\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine\"=dword:00000123\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, "Wine", REG_DWORD, &dword, sizeof(dword), 0); + + test_import_str("REGEDIT4\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "@=\"Test string\"\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, NULL, REG_SZ, "Test string", 12, 0); test_import_str("REGEDIT3\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -1589,25 +1638,21 @@ static void test_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey\"1]\n" "\"Wine\\\\31\"=\"Test value\"\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(hkey, "Subkey\"1", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(hkey, "Subkey\"1", 0, &subkey); verify_reg(subkey, "Wine\\31", REG_SZ, "Test value", 11, 0); err = RegCloseKey(subkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1"); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey/2]\n" "\"123/\\\"4;'5\"=\"Random value name\"\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(hkey, "Subkey/2", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(hkey, "Subkey/2", 0, &subkey); verify_reg(subkey, "123/\"4;'5", REG_SZ, "Random value name", 18, 0); err = RegCloseKey(subkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2"); /* Test key creation */ test_import_str("REGEDIT4\n\n" @@ -1634,15 +1679,13 @@ static void test_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1c ]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1c "); - err = RegDeleteKeyA(hkey, "Subkey1c "); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(hkey, "Subkey1c "); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1d\t]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1d\t"); - err = RegDeleteKeyA(hkey, "Subkey1d\t"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(hkey, "Subkey1d\t"); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1e\\]\n" @@ -1650,12 +1693,10 @@ static void test_import(void) ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1e\\"); verify_key(hkey, "Subkey1e"); - err = RegOpenKeyExA(hkey, "Subkey1e", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1e", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1e"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1e"); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1f\\\\]\n" @@ -1664,12 +1705,10 @@ static void test_import(void) verify_key(hkey, "Subkey1f\\\\"); verify_key(hkey, "Subkey1f\\"); verify_key(hkey, "Subkey1f"); - err = RegOpenKeyExA(hkey, "Subkey1f\\\\", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1f\\\\", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1f\\\\"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1f\\\\"); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1g\\\\\\\\]\n" @@ -1679,12 +1718,10 @@ static void test_import(void) verify_key(hkey, "Subkey1g\\\\"); verify_key(hkey, "Subkey1g\\"); verify_key(hkey, "Subkey1g"); - err = RegOpenKeyExA(hkey, "Subkey1g\\\\", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1g\\\\", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1g\\\\"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1g\\\\"); /* Test key deletion. We start by creating some registry keys. */ test_import_str("REGEDIT4\n\n" @@ -1929,8 +1966,7 @@ static void test_import(void) verify_reg_nonexist(hkey, "Wine54b"); verify_key(hkey, "Subkey2"); - err = RegDeleteKeyA(hkey, "Subkey2"); - ok(err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err); + delete_key(hkey, "Subkey2"); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -2022,8 +2058,7 @@ static void test_import(void) verify_reg_nonexist(hkey, "Wine57i"); verify_reg(hkey, "Wine57j", REG_EXPAND_SZ, "%PATH%", 7, 0); - err = RegDeleteValueW(hkey, NULL); - ok(err == ERROR_SUCCESS, "RegDeleteValue failed: %u\n", err); + delete_value(hkey, NULL); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -2051,8 +2086,7 @@ static void test_import(void) verify_reg_nonexist(hkey, "Wine58c"); verify_reg(hkey, NULL, REG_SZ, "Default value 3", 16, 0); - err = RegDeleteValueW(hkey, NULL); - ok(err == ERROR_SUCCESS, "RegDeleteValue failed: %u\n", err); + delete_value(hkey, NULL); test_import_str("REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -2301,11 +2335,32 @@ static void test_import(void) verify_reg(hkey, "Wine67c", REG_EXPAND_SZ, "%PATH%", 7, 0); verify_reg(hkey, "Wine67d", REG_EXPAND_SZ, "%PATH%", 7, 0); + test_import_str("REGEDIT4\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine68a\"=hex(1):\n" + "\"Wine68b\"=hex(2):\n" + "\"Wine68c\"=hex(3):\n" + "\"Wine68d\"=hex(4):\n" + "\"Wine68e\"=hex(7):\n" + "\"Wine68f\"=hex(100):\n" + "\"Wine68g\"=hex(abcd):\n" + "\"Wine68h\"=hex:\n" + "\"Wine68i\"=hex(0):\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, "Wine68a", REG_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68b", REG_EXPAND_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68c", REG_BINARY, NULL, 0, 0); + verify_reg(hkey, "Wine68d", REG_DWORD, NULL, 0, 0); + verify_reg(hkey, "Wine68e", REG_MULTI_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68f", 0x100, NULL, 0, 0); + verify_reg(hkey, "Wine68g", 0xabcd, NULL, 0, 0); + verify_reg(hkey, "Wine68h", REG_BINARY, NULL, 0, 0); + verify_reg(hkey, "Wine68i", REG_NONE, NULL, 0, 0); + err = RegCloseKey(hkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); } static void test_unicode_import(void) @@ -2316,6 +2371,9 @@ static void test_unicode_import(void) char buffer[24]; BYTE hex[8]; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + test_import_wstr("REGEDIT\n", &r); ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS) /* WinXP */, "got exit code %d, expected 1\n", r); @@ -2350,8 +2408,7 @@ static void test_unicode_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ|KEY_SET_VALUE, &hkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(HKEY_CURRENT_USER, KEY_BASE, KEY_SET_VALUE, &hkey); test_import_wstr("\xef\xbb\xbfREGEDIT3\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -2481,6 +2538,18 @@ static void test_unicode_import(void) "got exit code %d, expected 1\n", r); verify_reg_nonexist(hkey, "Test12"); + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine\"=dword:00000123\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, "Wine", REG_DWORD, &dword, sizeof(dword), 0); + + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "@=\"Test string\"\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, NULL, REG_SZ, "Test string", 12, 0); + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "\"Unicode4\"=\"Value4\"\n", &r); @@ -3067,25 +3136,21 @@ static void test_unicode_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey\"1]\n" "\"Wine\\\\31\"=\"Test value\"\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(hkey, "Subkey\"1", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(hkey, "Subkey\"1", 0, &subkey); verify_reg(subkey, "Wine\\31", REG_SZ, "Test value", 11, 0); err = RegCloseKey(subkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1"); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey/2]\n" "\"123/\\\"4;'5\"=\"Random value name\"\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); - err = RegOpenKeyExA(hkey, "Subkey/2", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + open_key(hkey, "Subkey/2", 0, &subkey); verify_reg(subkey, "123/\"4;'5", REG_SZ, "Random value name", 18, 0); err = RegCloseKey(subkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2"); /* Test key creation */ test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" @@ -3112,15 +3177,13 @@ static void test_unicode_import(void) "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1c ]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1c "); - err = RegDeleteKeyA(hkey, "Subkey1c "); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(hkey, "Subkey1c "); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1d\t]\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1d\t"); - err = RegDeleteKeyA(hkey, "Subkey1d\t"); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(hkey, "Subkey1d\t"); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1e\\]\n" @@ -3128,12 +3191,10 @@ static void test_unicode_import(void) ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_key(hkey, "Subkey1e\\"); verify_key(hkey, "Subkey1e"); - err = RegOpenKeyExA(hkey, "Subkey1e", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1e", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1e"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1e"); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1f\\\\]\n" @@ -3142,12 +3203,10 @@ static void test_unicode_import(void) verify_key(hkey, "Subkey1f\\\\"); verify_key(hkey, "Subkey1f\\"); verify_key(hkey, "Subkey1f"); - err = RegOpenKeyExA(hkey, "Subkey1f\\\\", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1f\\\\", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1f\\\\"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1f\\\\"); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1g\\\\\\\\]\n" @@ -3157,12 +3216,10 @@ static void test_unicode_import(void) verify_key(hkey, "Subkey1g\\\\"); verify_key(hkey, "Subkey1g\\"); verify_key(hkey, "Subkey1g"); - err = RegOpenKeyExA(hkey, "Subkey1g\\\\", 0, KEY_READ, &subkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %u, expected 0\n", err); + open_key(hkey, "Subkey1g\\\\", 0, &subkey); verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0); RegCloseKey(subkey); - err = RegDeleteKeyA(hkey, "Subkey1g\\\\"); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %u, expected 0\n", err); + delete_key(hkey, "Subkey1g\\\\"); /* Test key deletion. We start by creating some registry keys. */ test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" @@ -3410,8 +3467,7 @@ static void test_unicode_import(void) verify_reg_nonexist(hkey, "Wine54b"); verify_key(hkey, "Subkey2"); - err = RegDeleteKeyA(hkey, "Subkey2"); - ok(err == ERROR_SUCCESS, "RegDeleteKey failed: %u\n", err); + delete_key(hkey, "Subkey2"); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -3503,8 +3559,7 @@ static void test_unicode_import(void) verify_reg_nonexist(hkey, "Wine57i"); verify_reg(hkey, "Wine57j", REG_EXPAND_SZ, "%PATH%", 7, 0); - err = RegDeleteValueW(hkey, NULL); - ok(err == ERROR_SUCCESS, "RegDeleteValue failed: %u\n", err); + delete_value(hkey, NULL); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -3532,8 +3587,7 @@ static void test_unicode_import(void) verify_reg_nonexist(hkey, "Wine58c"); verify_reg(hkey, NULL, REG_SZ, "Default value 3", 16, 0); - err = RegDeleteValueW(hkey, NULL); - ok(err == ERROR_SUCCESS, "RegDeleteValue failed: %u\n", err); + delete_value(hkey, NULL); test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -3789,11 +3843,32 @@ static void test_unicode_import(void) verify_reg(hkey, "Wine67c", REG_EXPAND_SZ, "%PATH%", 7, 0); verify_reg(hkey, "Wine67d", REG_EXPAND_SZ, "%PATH%", 7, 0); + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine68a\"=hex(1):\n" + "\"Wine68b\"=hex(2):\n" + "\"Wine68c\"=hex(3):\n" + "\"Wine68d\"=hex(4):\n" + "\"Wine68e\"=hex(7):\n" + "\"Wine68f\"=hex(100):\n" + "\"Wine68g\"=hex(abcd):\n" + "\"Wine68h\"=hex:\n" + "\"Wine68i\"=hex(0):\n\n", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + verify_reg(hkey, "Wine68a", REG_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68b", REG_EXPAND_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68c", REG_BINARY, NULL, 0, 0); + verify_reg(hkey, "Wine68d", REG_DWORD, NULL, 0, 0); + verify_reg(hkey, "Wine68e", REG_MULTI_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine68f", 0x100, NULL, 0, 0); + verify_reg(hkey, "Wine68g", 0xabcd, NULL, 0, 0); + verify_reg(hkey, "Wine68h", REG_BINARY, NULL, 0, 0); + verify_reg(hkey, "Wine68i", REG_NONE, NULL, 0, 0); + err = RegCloseKey(hkey); ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); } static void test_import_with_whitespace(void) @@ -3802,12 +3877,14 @@ static void test_import_with_whitespace(void) DWORD r, dword; LONG err; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + test_import_str(" REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %d, expected 0\n", err); + open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); test_import_str(" REGEDIT4\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -3939,8 +4016,7 @@ static void test_import_with_whitespace(void) err = RegCloseKey(hkey); ok(err == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); } static void test_unicode_import_with_whitespace(void) @@ -3949,12 +4025,14 @@ static void test_unicode_import_with_whitespace(void) DWORD r, dword; LONG err; + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + test_import_wstr("\xef\xbb\xbf Windows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n", &r); ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r); - err = RegOpenKeyExA(HKEY_CURRENT_USER, KEY_BASE, 0, KEY_READ, &hkey); - ok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %d, expected 0\n", err); + open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); test_import_wstr("\xef\xbb\xbf Windows Registry Editor Version 5.00\n\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" @@ -4086,8 +4164,7 @@ static void test_unicode_import_with_whitespace(void) err = RegCloseKey(hkey); ok(err == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", err); - err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got %d, expected 0\n", err); + delete_key(HKEY_CURRENT_USER, KEY_BASE); } static void test_import_31(void) @@ -4156,8 +4233,7 @@ static void test_import_31(void) ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); verify_reg(hkey, "", REG_SZ, "No newline", 11, 0); - err = RegDeleteValueW(hkey, NULL); - ok(err == ERROR_SUCCESS, "RegDeleteValue failed: %d\n", err); + delete_value(hkey, NULL); /* Test character validity at the start of the line */ test_import_str("REGEDIT\r\n" @@ -4203,8 +4279,327 @@ static void test_import_31(void) RegCloseKey(hkey); - err = RegDeleteKeyA(HKEY_CLASSES_ROOT, KEY_BASE); - ok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", err); + delete_key(HKEY_CLASSES_ROOT, KEY_BASE); +} + +#define compare_export(f,e,todo) compare_export_(__LINE__,f,e,todo) +static BOOL compare_export_(unsigned line, const char *filename, const char *expected, DWORD todo) +{ + FILE *fp; + long file_size; + WCHAR *fbuf = NULL, *wstr = NULL; + size_t len; + BOOL ret = FALSE; + + fp = fopen(filename, "rb"); + if (!fp) return FALSE; + + if (fseek(fp, 0, SEEK_END)) goto error; + file_size = ftell(fp); + if (file_size == -1) goto error; + rewind(fp); + + fbuf = HeapAlloc(GetProcessHeap(), 0, file_size + sizeof(WCHAR)); + if (!fbuf) goto error; + + fread(fbuf, file_size, 1, fp); + fbuf[file_size/sizeof(WCHAR)] = 0; + fclose(fp); + + len = MultiByteToWideChar(CP_UTF8, 0, expected, -1, NULL, 0); + wstr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!wstr) goto exit; + MultiByteToWideChar(CP_UTF8, 0, expected, -1, wstr, len); + + todo_wine_if (todo & TODO_REG_COMPARE) + lok(!lstrcmpW(fbuf, wstr), "export data does not match expected data\n"); + + ret = DeleteFileA(filename); + lok(ret, "DeleteFile failed: %u\n", GetLastError()); + +exit: + HeapFree(GetProcessHeap(), 0, fbuf); + HeapFree(GetProcessHeap(), 0, wstr); + return ret; + +error: + fclose(fp); + return FALSE; +} + +static void test_export(void) +{ + LONG err; + DWORD r, dword; + HKEY hkey, subkey; + BYTE hex[4]; + + const char *empty_key_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n\r\n"; + + const char *simple_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"DWORD\"=dword:00000100\r\n" + "\"String\"=\"Your text here...\"\r\n\r\n"; + + const char *complex_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"DWORD\"=dword:00000100\r\n" + "\"String\"=\"Your text here...\"\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1]\r\n" + "\"Binary\"=hex:11,22,33,44\r\n" + "\"Undefined hex\"=hex(100):25,50,41,54,48,25,00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2a]\r\n" + "\"double\\\"quote\"=\"\\\"Hello, World!\\\"\"\r\n" + "\"single'quote\"=dword:00000008\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2a\\Subkey2b]\r\n" + "@=\"Default value name\"\r\n" + "\"Multiple strings\"=hex(7):4c,00,69,00,6e,00,65,00,31,00,00,00,4c,00,69,00,6e,\\\r\n" + " 00,65,00,32,00,00,00,4c,00,69,00,6e,00,65,00,33,00,00,00,00,00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey3a]\r\n" + "\"Backslash\"=\"Use \\\\\\\\ to escape a backslash\"\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey3a\\Subkey3b]\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey3a\\Subkey3b\\Subkey3c]\r\n" + "\"String expansion\"=hex(2):25,00,48,00,4f,00,4d,00,45,00,25,00,5c,00,25,00,50,\\\r\n" + " 00,41,00,54,00,48,00,25,00,00,00\r\n" + "\"Zero data type\"=hex(0):56,61,6c,75,65,00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey4]\r\n" + "@=dword:12345678\r\n" + "\"43981\"=hex(abcd):56,61,6c,75,65,00\r\n\r\n"; + + const char *key_order_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey1]\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey2]\r\n\r\n"; + + const char *value_order_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"Value 2\"=\"I was added first!\"\r\n" + "\"Value 1\"=\"I was added second!\"\r\n\r\n"; + + const char *empty_hex_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"Wine1a\"=hex(0):\r\n" + "\"Wine1b\"=\"\"\r\n" + "\"Wine1c\"=hex(2):\r\n" + "\"Wine1d\"=hex:\r\n" + "\"Wine1e\"=hex(4):\r\n" + "\"Wine1f\"=hex(7):\r\n" + "\"Wine1g\"=hex(100):\r\n" + "\"Wine1h\"=hex(abcd):\r\n\r\n"; + + const char *empty_hex_test2 = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"Wine2a\"=\"\"\r\n" + "\"Wine2b\"=hex:\r\n" + "\"Wine2c\"=hex(4):\r\n\r\n"; + + const char *hex_types_test = + "\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n" + "\"Wine3a\"=\"Value\"\r\n" + "\"Wine3b\"=hex:12,34,56,78\r\n" + "\"Wine3c\"=dword:10203040\r\n\r\n"; + + err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND, "got %d\n", err); + + run_reg_exe("reg export", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export /?", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg export /h", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg export -H", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg export \\\\remote-pc\\HKLM\\Wine file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_DYN_DATA file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKDD file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE, &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export file.reg HKEY_CURRENT_USER\\" KEY_BASE, &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE, &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg file2.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + /* Test registry export with an empty key */ + add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + + run_reg_exe("reg export /y HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " /y file.reg", &r); + ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r); + ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE), /* winxp */ + "got exit code %d, expected 0\n", r); + + ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); + + /* Test registry export with a simple data structure */ + dword = 0x100; + add_value(hkey, "DWORD", REG_DWORD, &dword, sizeof(dword)); + add_value(hkey, "String", REG_SZ, "Your text here...", 18); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", simple_test, 0), "compare_export() failed\n"); + + /* Test registry export with a complex data structure */ + add_key(hkey, "Subkey1", &subkey); + add_value(subkey, "Binary", REG_BINARY, "\x11\x22\x33\x44", 4); + add_value(subkey, "Undefined hex", 0x100, "%PATH%", 7); + RegCloseKey(subkey); + + add_key(hkey, "Subkey2a", &subkey); + add_value(subkey, "double\"quote", REG_SZ, "\"Hello, World!\"", 16); + dword = 0x8; + add_value(subkey, "single'quote", REG_DWORD, &dword, sizeof(dword)); + RegCloseKey(subkey); + + add_key(hkey, "Subkey2a\\Subkey2b", &subkey); + add_value(subkey, NULL, REG_SZ, "Default value name", 19); + add_value(subkey, "Multiple strings", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19); + RegCloseKey(subkey); + + add_key(hkey, "Subkey3a", &subkey); + add_value(subkey, "Backslash", REG_SZ, "Use \\\\ to escape a backslash", 29); + RegCloseKey(subkey); + + add_key(hkey, "Subkey3a\\Subkey3b\\Subkey3c", &subkey); + add_value(subkey, "String expansion", REG_EXPAND_SZ, "%HOME%\\%PATH%", 14); + add_value(subkey, "Zero data type", REG_NONE, "Value", 6); + RegCloseKey(subkey); + + add_key(hkey, "Subkey4", &subkey); + dword = 0x12345678; + add_value(subkey, NULL, REG_DWORD, &dword, sizeof(dword)); + add_value(subkey, "43981", 0xabcd, "Value", 6); + RegCloseKey(subkey); + + RegCloseKey(hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", complex_test, 0), "compare_export() failed\n"); + + err = delete_tree(HKEY_CURRENT_USER, KEY_BASE); + ok(err == ERROR_SUCCESS, "delete_tree() failed: %d\n", err); + + /* Test the export order of registry keys */ + add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey); + add_key(hkey, "Subkey2", &subkey); + RegCloseKey(subkey); + add_key(hkey, "Subkey1", &subkey); + RegCloseKey(subkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", key_order_test, 0), "compare_export() failed\n"); + + delete_key(hkey, "Subkey1"); + delete_key(hkey, "Subkey2"); + + /* Test the export order of registry values. Windows exports registry values + * in order of creation; Wine uses alphabetical order. + */ + add_value(hkey, "Value 2", REG_SZ, "I was added first!", 19); + add_value(hkey, "Value 1", REG_SZ, "I was added second!", 20); + + RegCloseKey(hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", value_order_test, TODO_REG_COMPARE), "compare_export() failed\n"); + + delete_key(HKEY_CURRENT_USER, KEY_BASE); + + /* Test registry export with empty hex data */ + add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey); + add_value(hkey, "Wine1a", REG_NONE, NULL, 0); + add_value(hkey, "Wine1b", REG_SZ, NULL, 0); + add_value(hkey, "Wine1c", REG_EXPAND_SZ, NULL, 0); + add_value(hkey, "Wine1d", REG_BINARY, NULL, 0); + add_value(hkey, "Wine1e", REG_DWORD, NULL, 0); + add_value(hkey, "Wine1f", REG_MULTI_SZ, NULL, 0); + add_value(hkey, "Wine1g", 0x100, NULL, 0); + add_value(hkey, "Wine1h", 0xabcd, NULL, 0); + RegCloseKey(hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", empty_hex_test, 0), "compare_export() failed\n"); + + delete_key(HKEY_CURRENT_USER, KEY_BASE); + + /* Test registry export after importing alternative registry data types */ + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine2a\"=hex(1):\n" + "\"Wine2b\"=hex(3):\n" + "\"Wine2c\"=hex(4):\n\n", &r); + open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); + verify_reg(hkey, "Wine2a", REG_SZ, NULL, 0, 0); + verify_reg(hkey, "Wine2b", REG_BINARY, NULL, 0, 0); + verify_reg(hkey, "Wine2c", REG_DWORD, NULL, 0, 0); + RegCloseKey(hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", empty_hex_test2, 0), "compare_export() failed\n"); + + delete_key(HKEY_CURRENT_USER, KEY_BASE); + + test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" + "[HKEY_CURRENT_USER\\" KEY_BASE "]\n" + "\"Wine3a\"=hex(1):56,00,61,00,6c,00,75,00,65,00,00,00\n" + "\"Wine3b\"=hex(3):12,34,56,78\n" + "\"Wine3c\"=hex(4):40,30,20,10\n\n", &r); + open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); + verify_reg(hkey, "Wine3a", REG_SZ, "Value", 6, 0); + memcpy(hex, "\x12\x34\x56\x78", 4); + verify_reg(hkey, "Wine3b", REG_BINARY, hex, 4, 0); + dword = 0x10203040; + verify_reg(hkey, "Wine3c", REG_DWORD, &dword, sizeof(dword), 0); + RegCloseKey(hkey); + + run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg", &r); + ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); + ok(compare_export("file.reg", hex_types_test, 0), "compare_export() failed\n"); + + delete_key(HKEY_CURRENT_USER, KEY_BASE); } START_TEST(reg) @@ -4224,4 +4619,5 @@ START_TEST(reg) test_import_with_whitespace(); test_unicode_import_with_whitespace(); test_import_31(); + test_export(); }
6 years, 11 months
1
0
0
0
01/01: [REG] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b50acff2bf0e38bdf1f25…
commit b50acff2bf0e38bdf1f25c707e331b5dc80964b7 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:04:40 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:04:40 2018 +0100 [REG] Sync with Wine 3.0. CORE-14225 --- base/applications/cmdutils/reg/CMakeLists.txt | 2 +- base/applications/cmdutils/reg/export.c | 410 ++++++++++++++++++++++++++ base/applications/cmdutils/reg/import.c | 4 + base/applications/cmdutils/reg/lang/bg-BG.rc | 3 + base/applications/cmdutils/reg/lang/cs-CZ.rc | 3 + base/applications/cmdutils/reg/lang/da-DK.rc | 3 + base/applications/cmdutils/reg/lang/de-DE.rc | 3 + base/applications/cmdutils/reg/lang/en-US.rc | 3 + base/applications/cmdutils/reg/lang/es-ES.rc | 3 + base/applications/cmdutils/reg/lang/fr-FR.rc | 3 + base/applications/cmdutils/reg/lang/it-IT.rc | 3 + base/applications/cmdutils/reg/lang/ja-JP.rc | 3 + base/applications/cmdutils/reg/lang/ko-KR.rc | 3 + base/applications/cmdutils/reg/lang/lt-LT.rc | 3 + base/applications/cmdutils/reg/lang/nl-NL.rc | 3 + base/applications/cmdutils/reg/lang/no-NO.rc | 3 + base/applications/cmdutils/reg/lang/pl-PL.rc | 3 + base/applications/cmdutils/reg/lang/pt-PT.rc | 3 + base/applications/cmdutils/reg/lang/ro-RO.rc | 3 + base/applications/cmdutils/reg/lang/ru-RU.rc | 3 + base/applications/cmdutils/reg/lang/sl-SI.rc | 3 + base/applications/cmdutils/reg/lang/sq-AL.rc | 3 + base/applications/cmdutils/reg/lang/sv-SE.rc | 3 + base/applications/cmdutils/reg/lang/tr-TR.rc | 3 + base/applications/cmdutils/reg/lang/uk-UA.rc | 3 + base/applications/cmdutils/reg/lang/zh-CN.rc | 3 + base/applications/cmdutils/reg/lang/zh-TW.rc | 3 + base/applications/cmdutils/reg/reg.c | 47 +-- base/applications/cmdutils/reg/reg.h | 10 +- base/applications/cmdutils/reg/resource.h | 73 ++--- media/doc/README.WINE | 2 +- 31 files changed, 564 insertions(+), 56 deletions(-) diff --git a/base/applications/cmdutils/reg/CMakeLists.txt b/base/applications/cmdutils/reg/CMakeLists.txt index 56abc0f0ea..53d1fa4c2f 100644 --- a/base/applications/cmdutils/reg/CMakeLists.txt +++ b/base/applications/cmdutils/reg/CMakeLists.txt @@ -2,7 +2,7 @@ remove_definitions(-D_WIN32_WINNT=0x502) add_definitions(-D_WIN32_WINNT=0x600) -add_executable(reg import.c reg.c reg.rc) +add_executable(reg export.c import.c reg.c reg.rc) set_module_type(reg win32cui UNICODE) target_link_libraries(reg wine) add_importlibs(reg advapi32 advapi32_vista user32 msvcrt kernel32 ntdll) diff --git a/base/applications/cmdutils/reg/export.c b/base/applications/cmdutils/reg/export.c new file mode 100644 index 0000000000..24b9dc8374 --- /dev/null +++ b/base/applications/cmdutils/reg/export.c @@ -0,0 +1,410 @@ +/* + * Copyright 2017 Hugh McMaster + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <windef.h> +#include <winbase.h> +#include <winreg.h> +#include <stdlib.h> + +#include <wine/unicode.h> + +#include "reg.h" + +static void write_file(HANDLE hFile, const WCHAR *str) +{ + DWORD written; + + WriteFile(hFile, str, lstrlenW(str) * sizeof(WCHAR), &written, NULL); +} + +static WCHAR *escape_string(WCHAR *str, size_t str_len, size_t *line_len) +{ + size_t i, escape_count, pos; + WCHAR *buf; + + for (i = 0, escape_count = 0; i < str_len; i++) + { + WCHAR c = str[i]; + if (c == '\r' || c == '\n' || c == '\\' || c == '"' || c == '\0') + escape_count++; + } + + buf = heap_xalloc((str_len + escape_count + 1) * sizeof(WCHAR)); + + for (i = 0, pos = 0; i < str_len; i++, pos++) + { + WCHAR c = str[i]; + + switch (c) + { + case '\r': + buf[pos++] = '\\'; + buf[pos] = 'r'; + break; + case '\n': + buf[pos++] = '\\'; + buf[pos] = 'n'; + break; + case '\\': + buf[pos++] = '\\'; + buf[pos] = '\\'; + break; + case '"': + buf[pos++] = '\\'; + buf[pos] = '"'; + break; + case '\0': + buf[pos++] = '\\'; + buf[pos] = '0'; + break; + default: + buf[pos] = c; + } + } + + buf[pos] = 0; + *line_len = pos; + return buf; +} + +static size_t export_value_name(HANDLE hFile, WCHAR *name, size_t len) +{ + static const WCHAR quoted_fmt[] = {'"','%','s','"','=',0}; + static const WCHAR default_name[] = {'@','=',0}; + size_t line_len; + + if (name && *name) + { + WCHAR *str = escape_string(name, len, &line_len); + WCHAR *buf = heap_xalloc((line_len + 4) * sizeof(WCHAR)); + line_len = sprintfW(buf, quoted_fmt, str); + write_file(hFile, buf); + heap_free(buf); + heap_free(str); + } + else + { + line_len = lstrlenW(default_name); + write_file(hFile, default_name); + } + + return line_len; +} + +static void export_string_data(WCHAR **buf, WCHAR *data, size_t size) +{ + size_t len = 0, line_len; + WCHAR *str; + static const WCHAR fmt[] = {'"','%','s','"',0}; + + if (size) + len = size / sizeof(WCHAR) - 1; + str = escape_string(data, len, &line_len); + *buf = heap_xalloc((line_len + 3) * sizeof(WCHAR)); + sprintfW(*buf, fmt, str); + heap_free(str); +} + +static void export_dword_data(WCHAR **buf, DWORD *data) +{ + static const WCHAR fmt[] = {'d','w','o','r','d',':','%','0','8','x',0}; + + *buf = heap_xalloc(15 * sizeof(WCHAR)); + sprintfW(*buf, fmt, *data); +} + +static size_t export_hex_data_type(HANDLE hFile, DWORD type) +{ + static const WCHAR hex[] = {'h','e','x',':',0}; + static const WCHAR hexp_fmt[] = {'h','e','x','(','%','x',')',':',0}; + size_t line_len; + + if (type == REG_BINARY) + { + line_len = lstrlenW(hex); + write_file(hFile, hex); + } + else + { + WCHAR *buf = heap_xalloc(15 * sizeof(WCHAR)); + line_len = sprintfW(buf, hexp_fmt, type); + write_file(hFile, buf); + heap_free(buf); + } + + return line_len; +} + +#define MAX_HEX_CHARS 77 + +static void export_hex_data(HANDLE hFile, WCHAR **buf, DWORD type, + DWORD line_len, void *data, DWORD size) +{ + static const WCHAR fmt[] = {'%','0','2','x',0}; + static const WCHAR hex_concat[] = {'\\','\r','\n',' ',' ',0}; + size_t num_commas, i, pos; + + line_len += export_hex_data_type(hFile, type); + + if (!size) return; + + num_commas = size - 1; + *buf = heap_xalloc(size * 3 * sizeof(WCHAR)); + + for (i = 0, pos = 0; i < size; i++) + { + pos += sprintfW(*buf + pos, fmt, ((BYTE *)data)[i]); + if (i == num_commas) break; + (*buf)[pos++] = ','; + (*buf)[pos] = 0; + line_len += 3; + + if (line_len >= MAX_HEX_CHARS) + { + write_file(hFile, *buf); + write_file(hFile, hex_concat); + line_len = 2; + pos = 0; + } + } +} + +static void export_newline(HANDLE hFile) +{ + static const WCHAR newline[] = {'\r','\n',0}; + + write_file(hFile, newline); +} + +static void export_data(HANDLE hFile, WCHAR *value_name, DWORD value_len, + DWORD type, void *data, size_t size) +{ + WCHAR *buf = NULL; + size_t line_len = export_value_name(hFile, value_name, value_len); + + switch (type) + { + case REG_SZ: + export_string_data(&buf, data, size); + break; + case REG_DWORD: + if (size) + { + export_dword_data(&buf, data); + break; + } + /* fall through */ + case REG_NONE: + case REG_EXPAND_SZ: + case REG_BINARY: + case REG_MULTI_SZ: + default: + export_hex_data(hFile, &buf, type, line_len, data, size); + break; + } + + if (size || type == REG_SZ) + { + write_file(hFile, buf); + heap_free(buf); + } + + export_newline(hFile); +} + +static void export_key_name(HANDLE hFile, WCHAR *name) +{ + static const WCHAR fmt[] = {'\r','\n','[','%','s',']','\r','\n',0}; + WCHAR *buf; + + buf = heap_xalloc((lstrlenW(name) + 7) * sizeof(WCHAR)); + sprintfW(buf, fmt, name); + write_file(hFile, buf); + heap_free(buf); +} + +static int export_registry_data(HANDLE hFile, HKEY key, WCHAR *path) +{ + LONG rc; + DWORD max_value_len = 256, value_len; + DWORD max_data_bytes = 2048, data_size; + DWORD subkey_len; + DWORD i, type, path_len; + WCHAR *value_name, *subkey_name, *subkey_path; + BYTE *data; + HKEY subkey; + + export_key_name(hFile, path); + + value_name = heap_xalloc(max_value_len * sizeof(WCHAR)); + data = heap_xalloc(max_data_bytes); + + i = 0; + for (;;) + { + value_len = max_value_len; + data_size = max_data_bytes; + rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size); + + if (rc == ERROR_SUCCESS) + { + export_data(hFile, value_name, value_len, type, data, data_size); + i++; + } + else if (rc == ERROR_MORE_DATA) + { + if (data_size > max_data_bytes) + { + max_data_bytes = data_size; + data = heap_xrealloc(data, max_data_bytes); + } + else + { + max_value_len *= 2; + value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR)); + } + } + else break; + } + + heap_free(data); + heap_free(value_name); + + subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR)); + + path_len = lstrlenW(path); + + i = 0; + for (;;) + { + subkey_len = MAX_SUBKEY_LEN; + rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL); + if (rc == ERROR_SUCCESS) + { + subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len); + if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey)) + { + export_registry_data(hFile, subkey, subkey_path); + RegCloseKey(subkey); + } + heap_free(subkey_path); + i++; + } + else break; + } + + heap_free(subkey_name); + return 0; +} + +static void export_file_header(HANDLE hFile) +{ + static const WCHAR header[] = { 0xfeff,'W','i','n','d','o','w','s',' ', + 'R','e','g','i','s','t','r','y',' ','E','d','i','t','o','r',' ', + 'V','e','r','s','i','o','n',' ','5','.','0','0','\r','\n'}; + + write_file(hFile, header); +} + +static HANDLE create_file(const WCHAR *filename, DWORD action) +{ + return CreateFileW(filename, GENERIC_WRITE, 0, NULL, action, FILE_ATTRIBUTE_NORMAL, NULL); +} + +static HANDLE get_file_handle(WCHAR *filename, BOOL overwrite_file) +{ + HANDLE hFile = create_file(filename, overwrite_file ? CREATE_ALWAYS : CREATE_NEW); + + if (hFile == INVALID_HANDLE_VALUE) + { + DWORD error = GetLastError(); + + if (error == ERROR_FILE_EXISTS) + { + if (!ask_confirm(STRING_OVERWRITE_FILE, filename)) + { + output_message(STRING_CANCELLED); + exit(0); + } + + hFile = create_file(filename, CREATE_ALWAYS); + } + else + { + WCHAR *str; + + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0, (WCHAR *)&str, 0, NULL); + output_writeconsole(str, lstrlenW(str)); + LocalFree(str); + exit(1); + } + } + + return hFile; +} + +static BOOL is_overwrite_switch(const WCHAR *s) +{ + if (strlenW(s) > 2) + return FALSE; + + if ((s[0] == '/' || s[0] == '-') && (s[1] == 'y' || s[1] == 'Y')) + return TRUE; + + return FALSE; +} + +int reg_export(int argc, WCHAR *argv[]) +{ + HKEY root, hkey; + WCHAR *path, *long_key; + BOOL overwrite_file = FALSE; + HANDLE hFile; + int ret; + + if (argc == 3 || argc > 5) + goto error; + + if (!parse_registry_key(argv[2], &root, &path, &long_key)) + return 1; + + if (argc == 5 && !(overwrite_file = is_overwrite_switch(argv[4]))) + goto error; + + if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey)) + { + output_message(STRING_INVALID_KEY); + return 1; + } + + hFile = get_file_handle(argv[3], overwrite_file); + export_file_header(hFile); + ret = export_registry_data(hFile, hkey, long_key); + export_newline(hFile); + CloseHandle(hFile); + + RegCloseKey(hkey); + + return ret; + +error: + output_message(STRING_INVALID_SYNTAX); + output_message(STRING_FUNC_HELP, struprW(argv[1])); + return 1; +} diff --git a/base/applications/cmdutils/reg/import.c b/base/applications/cmdutils/reg/import.c index 8825765c6d..c4c988d7d1 100644 --- a/base/applications/cmdutils/reg/import.c +++ b/base/applications/cmdutils/reg/import.c @@ -785,6 +785,9 @@ static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos) { WCHAR *line = pos; + if (!*line) + goto set_value; + if (!convert_hex_csv_to_hex(parser, &line)) goto invalid; @@ -796,6 +799,7 @@ static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos) prepare_hex_string_data(parser); +set_value: set_state(parser, SET_VALUE); return line; diff --git a/base/applications/cmdutils/reg/lang/bg-BG.rc b/base/applications/cmdutils/reg/lang/bg-BG.rc index 884d55ee37..23fbfb0255 100644 --- a/base/applications/cmdutils/reg/lang/bg-BG.rc +++ b/base/applications/cmdutils/reg/lang/bg-BG.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/cs-CZ.rc b/base/applications/cmdutils/reg/lang/cs-CZ.rc index f75f8fb36a..ab9bfde01e 100644 --- a/base/applications/cmdutils/reg/lang/cs-CZ.rc +++ b/base/applications/cmdutils/reg/lang/cs-CZ.rc @@ -42,4 +42,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/da-DK.rc b/base/applications/cmdutils/reg/lang/da-DK.rc index a151902421..6c8338ca0f 100644 --- a/base/applications/cmdutils/reg/lang/da-DK.rc +++ b/base/applications/cmdutils/reg/lang/da-DK.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/de-DE.rc b/base/applications/cmdutils/reg/lang/de-DE.rc index 083b7e73c1..ec0cd460ed 100644 --- a/base/applications/cmdutils/reg/lang/de-DE.rc +++ b/base/applications/cmdutils/reg/lang/de-DE.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/en-US.rc b/base/applications/cmdutils/reg/lang/en-US.rc index 3aae61e02c..9c9bef54ed 100644 --- a/base/applications/cmdutils/reg/lang/en-US.rc +++ b/base/applications/cmdutils/reg/lang/en-US.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/es-ES.rc b/base/applications/cmdutils/reg/lang/es-ES.rc index ea9cb3bd27..60bb78af8e 100644 --- a/base/applications/cmdutils/reg/lang/es-ES.rc +++ b/base/applications/cmdutils/reg/lang/es-ES.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/fr-FR.rc b/base/applications/cmdutils/reg/lang/fr-FR.rc index 3e891d3186..89aceb9079 100644 --- a/base/applications/cmdutils/reg/lang/fr-FR.rc +++ b/base/applications/cmdutils/reg/lang/fr-FR.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/it-IT.rc b/base/applications/cmdutils/reg/lang/it-IT.rc index 63cbc5c803..c2ad7f34e5 100644 --- a/base/applications/cmdutils/reg/lang/it-IT.rc +++ b/base/applications/cmdutils/reg/lang/it-IT.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/ja-JP.rc b/base/applications/cmdutils/reg/lang/ja-JP.rc index 7b1c018fbf..07e7fd73bf 100644 --- a/base/applications/cmdutils/reg/lang/ja-JP.rc +++ b/base/applications/cmdutils/reg/lang/ja-JP.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/ko-KR.rc b/base/applications/cmdutils/reg/lang/ko-KR.rc index 2bbe277d1a..ba9af4b55a 100644 --- a/base/applications/cmdutils/reg/lang/ko-KR.rc +++ b/base/applications/cmdutils/reg/lang/ko-KR.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/lt-LT.rc b/base/applications/cmdutils/reg/lang/lt-LT.rc index 75bbcc21d8..c8feef0d97 100644 --- a/base/applications/cmdutils/reg/lang/lt-LT.rc +++ b/base/applications/cmdutils/reg/lang/lt-LT.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/nl-NL.rc b/base/applications/cmdutils/reg/lang/nl-NL.rc index b2fb857f89..a62f1780fa 100644 --- a/base/applications/cmdutils/reg/lang/nl-NL.rc +++ b/base/applications/cmdutils/reg/lang/nl-NL.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/no-NO.rc b/base/applications/cmdutils/reg/lang/no-NO.rc index 5d6b79e0b9..b9c269e1c3 100644 --- a/base/applications/cmdutils/reg/lang/no-NO.rc +++ b/base/applications/cmdutils/reg/lang/no-NO.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/pl-PL.rc b/base/applications/cmdutils/reg/lang/pl-PL.rc index e3d2116fb6..92f98dccae 100644 --- a/base/applications/cmdutils/reg/lang/pl-PL.rc +++ b/base/applications/cmdutils/reg/lang/pl-PL.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/pt-PT.rc b/base/applications/cmdutils/reg/lang/pt-PT.rc index f6ee64dd82..dd39615452 100644 --- a/base/applications/cmdutils/reg/lang/pt-PT.rc +++ b/base/applications/cmdutils/reg/lang/pt-PT.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/ro-RO.rc b/base/applications/cmdutils/reg/lang/ro-RO.rc index ebcbe182c0..5c613624d9 100644 --- a/base/applications/cmdutils/reg/lang/ro-RO.rc +++ b/base/applications/cmdutils/reg/lang/ro-RO.rc @@ -43,4 +43,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/ru-RU.rc b/base/applications/cmdutils/reg/lang/ru-RU.rc index 04ad38c66e..f8d3d8afbe 100644 --- a/base/applications/cmdutils/reg/lang/ru-RU.rc +++ b/base/applications/cmdutils/reg/lang/ru-RU.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/sl-SI.rc b/base/applications/cmdutils/reg/lang/sl-SI.rc index e7d631e80b..cd22ffe74c 100644 --- a/base/applications/cmdutils/reg/lang/sl-SI.rc +++ b/base/applications/cmdutils/reg/lang/sl-SI.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/sq-AL.rc b/base/applications/cmdutils/reg/lang/sq-AL.rc index 3b0dba526f..2c4d2f5f4c 100644 --- a/base/applications/cmdutils/reg/lang/sq-AL.rc +++ b/base/applications/cmdutils/reg/lang/sq-AL.rc @@ -41,4 +41,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/sv-SE.rc b/base/applications/cmdutils/reg/lang/sv-SE.rc index 774bf95814..978e704c6a 100644 --- a/base/applications/cmdutils/reg/lang/sv-SE.rc +++ b/base/applications/cmdutils/reg/lang/sv-SE.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/tr-TR.rc b/base/applications/cmdutils/reg/lang/tr-TR.rc index 9061740de6..e46733002c 100644 --- a/base/applications/cmdutils/reg/lang/tr-TR.rc +++ b/base/applications/cmdutils/reg/lang/tr-TR.rc @@ -39,4 +39,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/uk-UA.rc b/base/applications/cmdutils/reg/lang/uk-UA.rc index b5a8b68e6d..7ca1cff6a5 100644 --- a/base/applications/cmdutils/reg/lang/uk-UA.rc +++ b/base/applications/cmdutils/reg/lang/uk-UA.rc @@ -37,4 +37,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/zh-CN.rc b/base/applications/cmdutils/reg/lang/zh-CN.rc index c952714bd1..6dbe375963 100644 --- a/base/applications/cmdutils/reg/lang/zh-CN.rc +++ b/base/applications/cmdutils/reg/lang/zh-CN.rc @@ -39,4 +39,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/lang/zh-TW.rc b/base/applications/cmdutils/reg/lang/zh-TW.rc index e6c5a6e8ee..b9cff9a283 100644 --- a/base/applications/cmdutils/reg/lang/zh-TW.rc +++ b/base/applications/cmdutils/reg/lang/zh-TW.rc @@ -39,4 +39,7 @@ STRINGTABLE STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n" STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key '%1'.\n" STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n" + STRING_EXPORT_USAGE, "REG EXPORT key_name file.reg [/y]\n" + STRING_INVALID_SYSTEM_KEY, "reg: Invalid system key [%1]\n" + STRING_OVERWRITE_FILE, "The file '%1' already exists. Do you want to overwrite it?" } diff --git a/base/applications/cmdutils/reg/reg.c b/base/applications/cmdutils/reg/reg.c index 5a857dea95..b9db08e787 100644 --- a/base/applications/cmdutils/reg/reg.c +++ b/base/applications/cmdutils/reg/reg.c @@ -81,6 +81,8 @@ type_rels[] = {REG_MULTI_SZ, type_multi_sz}, }; +static const WCHAR newlineW[] = {'\n',0}; + void *heap_xalloc(size_t size) { void *buf = HeapAlloc(GetProcessHeap(), 0, size); @@ -115,7 +117,7 @@ BOOL heap_free(void *buf) return HeapFree(GetProcessHeap(), 0, buf); } -static void output_writeconsole(const WCHAR *str, DWORD wlen) +void output_writeconsole(const WCHAR *str, DWORD wlen) { DWORD count, ret; @@ -155,7 +157,7 @@ static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args) LocalFree(str); } -void __cdecl output_message(unsigned int id, ...) +void WINAPIV output_message(unsigned int id, ...) { WCHAR fmt[1024]; __ms_va_list va_args; @@ -170,7 +172,7 @@ void __cdecl output_message(unsigned int id, ...) __ms_va_end(va_args); } -static void __cdecl output_string(const WCHAR *fmt, ...) +static void WINAPIV output_string(const WCHAR *fmt, ...) { __ms_va_list va_args; @@ -180,7 +182,7 @@ static void __cdecl output_string(const WCHAR *fmt, ...) } /* ask_confirm() adapted from programs/cmd/builtins.c */ -static BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info) +BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info) { HMODULE hmod; WCHAR Ybuffer[4]; @@ -614,7 +616,6 @@ static const WCHAR *reg_type_to_wchar(DWORD type) static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD data_size) { static const WCHAR fmt[] = {' ',' ',' ',' ','%','1',0}; - static const WCHAR newlineW[] = {'\n',0}; WCHAR defval[32]; WCHAR *reg_data; @@ -641,7 +642,7 @@ static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD output_string(newlineW); } -static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len) +WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len) { WCHAR *subkey_path; static const WCHAR fmt[] = {'%','s','\\','%','s',0}; @@ -654,8 +655,6 @@ static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, static unsigned int num_values_found = 0; -#define MAX_SUBKEY_LEN 257 - static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse) { LONG rc; @@ -664,7 +663,6 @@ static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse) DWORD type, path_len, i; BYTE *data; WCHAR fmt[] = {'%','1','\n',0}; - WCHAR newlineW[] = {'\n',0}; WCHAR *subkey_name, *subkey_path; HKEY subkey; @@ -744,7 +742,6 @@ static int query_all(HKEY key, WCHAR *path, BOOL recurse) WCHAR fmt[] = {'%','1','\n',0}; WCHAR fmt_path[] = {'%','1','\\','%','2','\n',0}; WCHAR *value_name, *subkey_name, *subkey_path; - WCHAR newlineW[] = {'\n',0}; BYTE *data; HKEY subkey; @@ -825,7 +822,6 @@ static int reg_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse) { HKEY key; - WCHAR newlineW[] = {'\n',0}; int ret; if (RegOpenKeyExW(root, path, 0, KEY_READ, &key) != ERROR_SUCCESS) @@ -877,32 +873,41 @@ static WCHAR *get_long_key(HKEY root, WCHAR *path) return long_key; } -static BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key) +BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key) { if (!sane_path(key)) return FALSE; + *path = strchrW(key, '\\'); + if (*path) (*path)++; + *root = path_get_rootkey(key); if (!*root) { - output_message(STRING_INVALID_KEY); + if (*path) *(*path - 1) = 0; + output_message(STRING_INVALID_SYSTEM_KEY, key); return FALSE; } - *path = strchrW(key, '\\'); - if (*path) (*path)++; - *long_key = get_long_key(*root, *path); return TRUE; } -static BOOL is_help_switch(const WCHAR *s) +static BOOL is_switch(const WCHAR *s, const WCHAR c) { if (strlenW(s) > 2) return FALSE; - if ((s[0] == '/' || s[0] == '-') && (s[1] == 'h' || s[1] == '?')) + if ((s[0] == '/' || s[0] == '-') && (s[1] == c || s[1] == toupperW(c))) + return TRUE; + + return FALSE; +} + +static BOOL is_help_switch(const WCHAR *s) +{ + if (is_switch(s, '?') || is_switch(s, 'h')) return TRUE; return FALSE; @@ -912,6 +917,7 @@ enum operations { REG_ADD, REG_DELETE, REG_IMPORT, + REG_EXPORT, REG_QUERY, REG_INVALID }; @@ -923,6 +929,7 @@ static enum operations get_operation(const WCHAR *str, int *op_help) static const WCHAR add[] = {'a','d','d',0}; static const WCHAR delete[] = {'d','e','l','e','t','e',0}; static const WCHAR import[] = {'i','m','p','o','r','t',0}; + static const WCHAR export[] = {'e','x','p','o','r','t',0}; static const WCHAR query[] = {'q','u','e','r','y',0}; static const struct op_info op_array[] = @@ -930,6 +937,7 @@ static enum operations get_operation(const WCHAR *str, int *op_help) { add, REG_ADD, STRING_ADD_USAGE }, { delete, REG_DELETE, STRING_DELETE_USAGE }, { import, REG_IMPORT, STRING_IMPORT_USAGE }, + { export, REG_EXPORT, STRING_EXPORT_USAGE }, { query, REG_QUERY, STRING_QUERY_USAGE }, { NULL, -1, 0 } }; @@ -998,6 +1006,9 @@ int wmain(int argc, WCHAR *argvW[]) if (op == REG_IMPORT) return reg_import(argvW[2]); + if (op == REG_EXPORT) + return reg_export(argc, argvW); + if (!parse_registry_key(argvW[2], &root, &path, &key_name)) return 1; diff --git a/base/applications/cmdutils/reg/reg.h b/base/applications/cmdutils/reg/reg.h index 14c05b13d4..eb792bbf88 100644 --- a/base/applications/cmdutils/reg/reg.h +++ b/base/applications/cmdutils/reg/reg.h @@ -22,15 +22,23 @@ #include "resource.h" #define ARRAY_SIZE(A) (sizeof(A)/sizeof(*A)) +#define MAX_SUBKEY_LEN 257 /* reg.c */ void *heap_xalloc(size_t size); void *heap_xrealloc(void *buf, size_t size); BOOL heap_free(void *buf); -void __cdecl output_message(unsigned int id, ...); +void output_writeconsole(const WCHAR *str, DWORD wlen); +void WINAPIV output_message(unsigned int id, ...); +BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info); HKEY path_get_rootkey(const WCHAR *path); +WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len); +BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key); /* import.c */ int reg_import(const WCHAR *filename); +/* export.c */ +int reg_export(int argc, WCHAR *argv[]); + #endif /* __REG_H__ */ diff --git a/base/applications/cmdutils/reg/resource.h b/base/applications/cmdutils/reg/resource.h index 0f57663183..84cbe906b9 100644 --- a/base/applications/cmdutils/reg/resource.h +++ b/base/applications/cmdutils/reg/resource.h @@ -23,38 +23,41 @@ //#include <windef.h> /* Translation IDs. */ -#define STRING_USAGE 101 -#define STRING_ADD_USAGE 102 -#define STRING_DELETE_USAGE 103 -#define STRING_QUERY_USAGE 104 -#define STRING_SUCCESS 105 -#define STRING_INVALID_KEY 106 -#define STRING_INVALID_CMDLINE 107 -#define STRING_NO_REMOTE 108 -#define STRING_CANNOT_FIND 109 -#define STRING_UNSUPPORTED_TYPE 110 -#define STRING_MISSING_INTEGER 111 -#define STRING_MISSING_HEXDATA 112 -#define STRING_UNHANDLED_TYPE 113 -#define STRING_OVERWRITE_VALUE 114 -#define STRING_YESNO 115 -#define STRING_YES 116 -#define STRING_NO 117 -#define STRING_CANCELLED 118 -#define STRING_DEFAULT_VALUE 119 -#define STRING_DELETE_VALUE 120 -#define STRING_DELETE_VALUEALL 121 -#define STRING_DELETE_SUBKEY 122 -#define STRING_INVALID_STRING 123 -#define STRING_VALUEALL_FAILED 124 -#define STRING_GENERAL_FAILURE 125 -#define STRING_MATCHES_FOUND 126 -#define STRING_INVALID_SYNTAX 127 -#define STRING_INVALID_OPTION 128 -#define STRING_REG_HELP 129 -#define STRING_FUNC_HELP 130 -#define STRING_VALUE_NOT_SET 131 -#define STRING_IMPORT_USAGE 132 -#define STRING_FILE_NOT_FOUND 133 -#define STRING_OPEN_KEY_FAILED 134 -#define STRING_ESCAPE_SEQUENCE 135 +#define STRING_USAGE 101 +#define STRING_ADD_USAGE 102 +#define STRING_DELETE_USAGE 103 +#define STRING_QUERY_USAGE 104 +#define STRING_SUCCESS 105 +#define STRING_INVALID_KEY 106 +#define STRING_INVALID_CMDLINE 107 +#define STRING_NO_REMOTE 108 +#define STRING_CANNOT_FIND 109 +#define STRING_UNSUPPORTED_TYPE 110 +#define STRING_MISSING_INTEGER 111 +#define STRING_MISSING_HEXDATA 112 +#define STRING_UNHANDLED_TYPE 113 +#define STRING_OVERWRITE_VALUE 114 +#define STRING_YESNO 115 +#define STRING_YES 116 +#define STRING_NO 117 +#define STRING_CANCELLED 118 +#define STRING_DEFAULT_VALUE 119 +#define STRING_DELETE_VALUE 120 +#define STRING_DELETE_VALUEALL 121 +#define STRING_DELETE_SUBKEY 122 +#define STRING_INVALID_STRING 123 +#define STRING_VALUEALL_FAILED 124 +#define STRING_GENERAL_FAILURE 125 +#define STRING_MATCHES_FOUND 126 +#define STRING_INVALID_SYNTAX 127 +#define STRING_INVALID_OPTION 128 +#define STRING_REG_HELP 129 +#define STRING_FUNC_HELP 130 +#define STRING_VALUE_NOT_SET 131 +#define STRING_IMPORT_USAGE 132 +#define STRING_FILE_NOT_FOUND 133 +#define STRING_OPEN_KEY_FAILED 134 +#define STRING_ESCAPE_SEQUENCE 135 +#define STRING_EXPORT_USAGE 136 +#define STRING_INVALID_SYSTEM_KEY 137 +#define STRING_OVERWRITE_FILE 138 diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 69bf99b9c6..5e66b918b0 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -227,7 +227,7 @@ reactos/win32ss/printing/monitors/localmon/ui/ # Synced to WineStaging-2.9 (kno ReactOS shares the following programs with Winehq. reactos/base/applications/cmdutils/cscript # Synced to WineStaging-2.9 -reactos/base/applications/cmdutils/reg # Synced to WineStaging-2.16 +reactos/base/applications/cmdutils/reg # Synced to Wine-3.0 reactos/base/applications/cmdutils/schtasks # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/taskkill # Synced to WineStaging-2.9 reactos/base/applications/cmdutils/wmic # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
01/01: [WTSAPI32_WINETEST] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d71285065ddb43090bdb2…
commit d71285065ddb43090bdb220b7a3455e66b9ed79b Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:02:13 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:02:13 2018 +0100 [WTSAPI32_WINETEST] Sync with Wine 3.0. CORE-14225 --- modules/rostests/winetests/wtsapi32/wtsapi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/rostests/winetests/wtsapi32/wtsapi.c b/modules/rostests/winetests/wtsapi32/wtsapi.c index dd5c8e8637..0a1b1ecb7c 100644 --- a/modules/rostests/winetests/wtsapi32/wtsapi.c +++ b/modules/rostests/winetests/wtsapi32/wtsapi.c @@ -85,6 +85,7 @@ static void test_WTSEnumerateProcessesW(void) { found = found || !lstrcmpW(pname, info[i].pProcessName); } + todo_wine ok(found || broken(!ret), "process name %s not found\n", wine_dbgstr_w(pname)); if (info) WTSFreeMemory(info); }
6 years, 11 months
1
0
0
0
01/01: [WTSAPI32] Sync with Wine 3.0. CORE-14225
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=90f14ccef3d9d344b7021…
commit 90f14ccef3d9d344b7021407b4c59a7234a19614 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Jan 21 22:01:34 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Jan 21 22:01:34 2018 +0100 [WTSAPI32] Sync with Wine 3.0. CORE-14225 --- dll/win32/wtsapi32/wtsapi32.c | 95 ++++--------------------------------------- media/doc/README.WINE | 2 +- 2 files changed, 10 insertions(+), 87 deletions(-) diff --git a/dll/win32/wtsapi32/wtsapi32.c b/dll/win32/wtsapi32/wtsapi32.c index a7f4c873d9..92a7396f54 100644 --- a/dll/win32/wtsapi32/wtsapi32.c +++ b/dll/win32/wtsapi32/wtsapi32.c @@ -28,9 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wtsapi); -/* FIXME: Inspect */ -#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3) - /************************************************************ * WTSCloseServer (WTSAPI32.@) @@ -99,13 +96,8 @@ BOOL WINAPI WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) { - WTS_PROCESS_INFOW *processInfo; - SYSTEM_PROCESS_INFORMATION *spi; - ULONG size = 0x4000; - void *buf = NULL; - NTSTATUS status; - DWORD count; - WCHAR *name; + FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, + ppProcessInfo, pCount); if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1) { @@ -113,71 +105,9 @@ BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version return FALSE; } - if (hServer != WTS_CURRENT_SERVER_HANDLE) - { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; - } - - do - { - size *= 2; - HeapFree(GetProcessHeap(), 0, buf); - buf = HeapAlloc(GetProcessHeap(), 0, size); - if (!buf) - { - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - status = NtQuerySystemInformation(SystemProcessInformation, buf, size, NULL); - } - while (status == STATUS_INFO_LENGTH_MISMATCH); - - if (status != STATUS_SUCCESS) - { - HeapFree(GetProcessHeap(), 0, buf); - SetLastError(RtlNtStatusToDosError(status)); - return FALSE; - } - - spi = buf; - count = size = 0; - for (;;) - { - size += sizeof(WTS_PROCESS_INFOW) + spi->ProcessName.Length + sizeof(WCHAR); - count++; - if (spi->NextEntryOffset == 0) break; - spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); - } - - processInfo = HeapAlloc(GetProcessHeap(), 0, size); - if (!processInfo) - { - HeapFree(GetProcessHeap(), 0, buf); - SetLastError(ERROR_OUTOFMEMORY); - return FALSE; - } - name = (WCHAR *)&processInfo[count]; - - *ppProcessInfo = processInfo; - *pCount = count; - - spi = buf; - while (count--) - { - processInfo->SessionId = 0; - processInfo->ProcessId = HandleToUlong(spi->UniqueProcessId); - processInfo->pProcessName = name; - processInfo->pUserSid = NULL; - memcpy( name, spi->ProcessName.Buffer, spi->ProcessName.Length ); - name[ spi->ProcessName.Length/sizeof(WCHAR) ] = 0; - - processInfo++; - name += (spi->ProcessName.Length + sizeof(WCHAR))/sizeof(WCHAR); - spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); - } + *pCount = 0; + *ppProcessInfo = NULL; - HeapFree(GetProcessHeap(), 0, buf); return TRUE; } @@ -241,7 +171,9 @@ BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, */ void WINAPI WTSFreeMemory(PVOID pMemory) { - HeapFree(GetProcessHeap(), 0, pMemory); + static int once; + + if (!once++) FIXME("Stub %p\n", pMemory); } /************************************************************ @@ -314,16 +246,7 @@ BOOL WINAPI WTSQuerySessionInformationW( BOOL WINAPI WTSQueryUserToken(ULONG session_id, PHANDLE token) { FIXME("%u %p\n", session_id, token); - - if (!token) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - return DuplicateHandle(GetCurrentProcess(), GetCurrentProcessToken(), - GetCurrentProcess(), token, - 0, FALSE, DUPLICATE_SAME_ACCESS); + return FALSE; } /************************************************************ @@ -357,7 +280,7 @@ BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags) } /************************************************************ - * WTSRegisterSessionNotification (WTSAPI32.@) + * WTSRegisterSessionNotificationEx (WTSAPI32.@) */ BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags) { diff --git a/media/doc/README.WINE b/media/doc/README.WINE index f366990215..69bf99b9c6 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -212,7 +212,7 @@ reactos/dll/win32/wmi # Synced to WineStaging-2.9 reactos/dll/win32/wmiutils # Synced to WineStaging-2.9 reactos/dll/win32/wmvcore # Synced to Wine-3.0 reactos/dll/win32/wshom.ocx # Synced to Wine-3.0 -reactos/dll/win32/wtsapi32 # Synced to WineStaging-2.9 +reactos/dll/win32/wtsapi32 # Synced to Wine-3.0 reactos/dll/win32/wuapi # Synced to WineStaging-2.9 reactos/dll/win32/xinput1_1 # Synced to WineStaging-2.9 reactos/dll/win32/xinput1_2 # Synced to WineStaging-2.9
6 years, 11 months
1
0
0
0
← Newer
1
...
12
13
14
15
16
17
18
...
38
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Results per page:
10
25
50
100
200