Compare commits

...

134 commits

Author SHA1 Message Date
Vibhav Pant
ace97f7475
wintypes: Add stubs for IKeyValuePair<HSTRING, IInspectable *>. 2024-11-18 21:35:46 +05:30
Vibhav Pant
35e1a70897
wintypes: Add stubs for IIterator<IKeyValuePair<HSTRING, IInspectable *>>. 2024-11-18 21:35:46 +05:30
Vibhav Pant
e385002e30
wintypes: Add IIterable<IKeyValuePair<HSTRING, IInspectable *>> stub for MapView<HSTRING, IInspectable *>. 2024-11-18 21:35:40 +05:30
Vibhav Pant
c62ecdd8ad
wintypes: Add stubs for IMapView<HSTRING, IInspectable *>.
Implement GetView() for Windows.Foundation.Collections.PropertySet using an instance of this stub.
2024-11-18 21:35:37 +05:30
Vibhav Pant
7f2bb2cb46
wintypes: Add stubs for IMap<HSTRING, IInspectable *>, IObservableMap<HSTRING, IInspectable *>, IIterable<IKeyValuePair<HSTRING, IInspectable *>> to PropertySet implementation. 2024-11-18 21:15:02 +05:30
Vibhav Pant
84a240babb
wintypes: Add stubs for Windows.Foundation.Collections.PropertySet. 2024-11-18 21:15:01 +05:30
Vibhav Pant
76bda56292
wintypes/tests: Add conformance tests for Windows.Foundation.Collections.PropertySet. 2024-11-18 15:41:14 +05:30
Vibhav Pant
52104d01c9
include: Add Windows.Foundation.Collections.PropertySet runtime class. 2024-11-18 15:41:14 +05:30
Rémi Bernon
ae6366b33c winex11: Introduce a new window_update_client_config helper. 2024-11-15 19:08:41 +01:00
Rémi Bernon
d9cf4678a1 winex11: Introduce a new window_update_client_state helper. 2024-11-15 19:08:41 +01:00
Rémi Bernon
da936bcf35 winex11: Use the new window state tracker to get WM_STATE value. 2024-11-15 19:08:40 +01:00
Rémi Bernon
e75192fe72 winex11: Use the new window state tracker to get _NET_WM_STATE value. 2024-11-15 19:08:40 +01:00
Rémi Bernon
0dc7e40468 winex11: Ignore focus changes during WM_STATE transitions.
When WM_STATE is being quickly updated, and depending on the WM we might
receive transient focus changes, which will disrupt the Win32 state and
make us randomly lose focus.

Ignore them instead, when a window is being shown, and wait for WM_STATE
to be updated and stable. We will eventually receive a WM_TAKE_FOCUS /
FocusIn event *after* a window has been shown.

When a window is hidden or minimized, we will receive the FocusOut event
during the WM_STATE transition, and can safely handle it in this case,
as we should have done all the Win32 side effects and have changed the
foreground window already.

When there's no window state change pending, the focus change event is
unexpected, coming from the user or WM, and we handle it normally.
2024-11-15 19:08:20 +01:00
Biswapriyo Nath
700ee59470 include: Add UI Automation Annotation Type ID definitions.
Required for c7ba4a9640
2024-11-15 19:08:10 +01:00
Marc-Aurel Zent
c76a192bf6 winex11: Include kbd.h instead of ime.h. 2024-11-15 19:07:58 +01:00
Marc-Aurel Zent
9acdc03128 include: Add Japanese IME virtual key codes to kbd.h. 2024-11-15 19:07:57 +01:00
Hans Leidekker
8b121591be wininet: Use InternetTimeToSystemTimeW() to convert header values.
The current code calls mktime() which interprets its argument as local time while these
values are assumed to be in UTC.
2024-11-15 19:07:26 +01:00
Hans Leidekker
5a23afb34d wininet: Accept UTC as the equivalent of GMT.
Based on a patch by Etaash Mathamsetty.
2024-11-15 19:07:24 +01:00
Nikolay Sivov
6a01532899 comctl32/listview: Send LVN_HOTTRACK in response to mouse moves.
It's worth noting that comctl32 v6 have hottracking notifications enabled
by default, there is no need to set any extended styles.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
2024-11-15 19:07:06 +01:00
Nikolay Sivov
e5b0ead2b5 comctl32/listview: Initialize hot cursor handle.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
2024-11-15 19:07:04 +01:00
Eric Pouech
b9c06c4474 dbghelp: Fill-in data in SymSrvGetFileIndexIndo if BAD_EXE_FORMAT.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-15 16:25:10 +01:00
Eric Pouech
a57eedec86 dbghelp/tests: Improve SymSrvGetFileIndexInfo tests.
Esp. the failures with ERROR_BAD_EXE_FORMAT still fill all the fields
in the returned structure.

Add more flexibility to .dbg file creation (optional DEBUG_DIRECTORY).

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-15 16:25:10 +01:00
Eric Pouech
9212706ede dbghelp: Only WARN on stripped PE images.
When stripping, binutils' objcopy also sets the flag, yet
without stripping into a .DBG file.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-15 16:25:10 +01:00
Eric Pouech
40b314cf34 dbghelp: Don't try to load PDB for a RSDS debug directory in .buildid section.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-15 16:25:10 +01:00
Brendan Shanks
aa24458086 Add .gitattributes file to mark generated files. 2024-11-15 16:25:10 +01:00
Alexandre Julliard
576d7e24cd server: Use an explicit struct instead of a typedef for async I/O data. 2024-11-15 16:25:10 +01:00
Alexandre Julliard
305ec347dc server: Use an explicit struct instead of a typedef for user APCs. 2024-11-15 16:25:10 +01:00
Alexandre Julliard
4c0103e58c server: Use an explicit union instead of a typedef for APC results. 2024-11-15 16:25:10 +01:00
Alexandre Julliard
1137a10ef7 server: Use an explicit union instead of a typedef for APC calls. 2024-11-15 16:25:10 +01:00
Alexandre Julliard
eae7db4fa4 server: Simplify updating the protocol version. 2024-11-15 16:25:09 +01:00
Alexandre Julliard
75e2ec479b server: Move the generated part of trace.c to a separate header. 2024-11-15 16:25:09 +01:00
Alexandre Julliard
45953cdbec server: Move the generated part of request.h to a separate header. 2024-11-15 16:25:09 +01:00
Alexandre Julliard
126c54cd25 server: Print a warning if page size isn't 4k. 2024-11-15 16:25:09 +01:00
Rémi Bernon
ab40b7fd86 winex11: Always generate ConfigureNotify events for embedded windows.
We won't receive a ConfigureNotify event if the embedded window has been
reparented without moving or resizing it. Top-level windows always
receive synthetic ConfigureNotify from the window manager.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
0bd49a68dc winex11: Generate ConfigureNotify events for the children tree.
When an ancestor window is moved.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
50683f7b32 winex11: Avoid overriding previously received ConfigureNotify events.
The X event merging logic removes events from the queue in advance, and
putting a dummy ConfigureNotify back in the queue will override any
previously received event.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
48bb5f90a2 winex11: Retrieve the HWND for the host window's child window.
Instead of the host window itself, which will never have one.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
7352196f6a winex11: Introduce a new host_window_send_configure_events helper.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
4eefc0b9a9 winex11: Reset the window relative position when it gets reparented.
Instead of keeping the same offset as from the previous window parent,
which may cause offsets to stack up with embedded windows.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Rémi Bernon
51f6839395 winex11: Reset embedded window position to 0x0 before docking it.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57370
2024-11-14 21:56:33 +01:00
Zhiyi Zhang
b240f8ea93 ntdll: Implement NtSetIoCompletionEx(). 2024-11-14 21:56:33 +01:00
Zhiyi Zhang
54b9f68b8e ntdll/tests: Add NtSetIoCompletionEx() tests. 2024-11-14 21:56:33 +01:00
Nikolay Sivov
5a7a4b7f1a dwrite/layout: Skip to the next typography range when current one has no features.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57407
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
2024-11-14 21:56:33 +01:00
Paul Gofman
698ab75a59 server: Don't update cursor pos in set_window_pos() if window wasn't moved.
Fixes a regression introduced by commit db9a4bc66a.
2024-11-14 21:56:33 +01:00
Alexandre Julliard
8e2442584c ntdll/tests: Fix a test failure on 64-bit Windows. 2024-11-14 21:56:33 +01:00
Alexandre Julliard
6d1df55bf3 ntdll: Always return 0 length on failure in SystemFirmwareTableInformation. 2024-11-14 21:56:33 +01:00
Alexandre Julliard
9f8ef43991 rundll32: Restart itself if the dll is for a different architecture.
Based on the corresponding code in regsvr32.
2024-11-14 21:56:33 +01:00
Alexandre Julliard
5c597119a0 rundll32: Rewrite command line parsing.
Windows doesn't do any fancy unescaping.
2024-11-14 11:54:35 +01:00
Alexandre Julliard
c20bf25556 rundll32: Use crt allocation functions. 2024-11-14 11:53:03 +01:00
Alexandre Julliard
194ada7583 rundll32: Don't bother cleaning up at process exit. 2024-11-14 11:52:26 +01:00
Jacek Caban
8a87ce3c4f configure: Use -fms-hotpatch when available.
On Clang, this flag serves as a replacement for the __ms_hook_prologue__ attribute.
2024-11-14 11:10:28 +01:00
Jacek Caban
f47da4307f winegcc: Pass -fms-hotpatch to the linker.
The -fms-hotpatch flag is relevant for both the compiler and the linker.
2024-11-14 11:10:28 +01:00
Jacek Caban
0f84798246 configure: Use -ffunction-sections for PE targets. 2024-11-14 11:10:28 +01:00
Aurimas Fišeras
0eda6a76c7 po: Update Lithuanian translation. 2024-11-14 11:06:38 +01:00
Gabriel Ivăncescu
38f1ce3210 mshtml: Forward deletion for GLOBAL_SCRIPTVAR to the script's object.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:48 +01:00
Gabriel Ivăncescu
9b264c948f mshtml: Check if window global prop still exists before returning its id.
We have to introduce special handling for jscript, as it's probably integrated
on native mshtml.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:47 +01:00
Gabriel Ivăncescu
055bf9f5a2 mshtml: Override window's element prop directly rather than using GLOBAL_DISPEXVAR.
When GLOBAL_DISPEXVAR is used, we store the id of the dynamic prop and
invoke it using the same id. But this is not the case if we have a jsdisp,
which is redirected from InvokeEx and results in an invalid id.

The actual way this works on native (in IE9+) is that element/frame props
are special and not part of the window object at all. They're actually
looked up after the prototype is, in a special way, but that requires a
revamp. Storing over it just creates an actual prop on the window (which
is what we are doing here).

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:36 +01:00
Gabriel Ivăncescu
18aefb5dcf mshtml: Use BSTR to store global prop's name.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:36 +01:00
Gabriel Ivăncescu
85331da430 jscript: Add basic semi-stub implementation of GetMemberProperties.
Also add tests for GetMemberName and DeleteMemberBy* which we did not have.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:35 +01:00
Gabriel Ivăncescu
5947a66f4c mshtml: Throw invalid action for IE8 window prop deletion.
Instead of E_NOTIMPL.

We can't use the dispex's delete because it also applies to dynamic and
builtin props and it also happens too late when deleting by name (after
looking it up), where existing tests show it doesn't look up the dispid
at all.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:33 +01:00
Gabriel Ivăncescu
12755eeb1c mshtml: Reset builtin function props to their default values when deleted.
The previous tests bailed out too early on IE8, and did not test builtin
props. Also added todos for tests that we did not even test because of
returning early.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
2024-11-13 23:14:30 +01:00
Rémi Bernon
e3258e7620 winex11: Simplify the control flow in ConfigureNotify handlers. 2024-11-13 20:27:15 +01:00
Rémi Bernon
968ab4e79a winex11: Simplify the control flow in WM_STATE handlers. 2024-11-13 20:27:15 +01:00
Rémi Bernon
b1dd7da806 winex11: Avoid updating _NET_WM_STATE on iconic windows.
This tends to trigger window mapping with some window managers.
2024-11-13 20:27:13 +01:00
Rémi Bernon
199274d420 winex11: Avoid requesting unnecessary window config changes. 2024-11-13 20:27:13 +01:00
Rémi Bernon
7ac35f13cb winex11: Avoid requesting unnecessary _NET_WM_STATE changes. 2024-11-13 20:27:13 +01:00
Elizabeth Figura
1f42d452aa wined3d: Initialize max_blend_stages in the SPIRV fragment pipe. 2024-11-13 20:26:42 +01:00
Elizabeth Figura
96c37c23f6 wined3d: Clear caps to zero in shader caps query functions. 2024-11-13 20:26:42 +01:00
Elizabeth Figura
f588fec26c wined3d: Rewrite the comment in compute_texture_matrix().
Make the function easier to understand, and use language that's a little less
GL-centric.
2024-11-13 20:26:40 +01:00
Elizabeth Figura
70258a160f wined3d: Calculate the texture matrix solely from the vertex declaration. 2024-11-13 20:26:40 +01:00
Elizabeth Figura
b02b73673b wined3d: Do not clamp fog in the VS.
NVidia and WARP clamp before interpolation in the oFog case; AMD clamps only
after interpolation (which we also do).

On the other hand, test_fog() proves that clamping should not be done before
interpolation in the FFP case, for any driver.

In order to emulate an FFP vertex shader with a real compiled shader, we need to
avoid clamping before interpolation, choosing the AMD behaviour here.
2024-11-13 20:26:35 +01:00
John Chadwick
a5de8d85d3 winex11: Remove stub tablet_get_packet wow64 thunk.
The previous commit ensures that the WTPACKET fields align between
32-bit and 64-bit architectures, so now we can use the same
tablet_get_packet without needing another thunk.
2024-11-13 18:48:42 +01:00
John Chadwick
5b10f924fa wintab32: Align WTPACKET for 32/64-bit archs.
WTPACKET's structure is never directly exposed via the API; it's
internal to Wine. The HCTX value is only used on the wintab32 side,
not the driver side, and it is used as an integer rather than a
pointer, so this should be safe to do.

This eliminates the need to have a wow64 thunk for tablet_get_packet.
2024-11-13 18:48:42 +01:00
Etaash Mathamsetty
ea3c73b12d explorer: Enable the Wayland driver. 2024-11-13 18:48:42 +01:00
Alistair Leslie-Hughes
a93623eced user32: Implement GetDpiAwarenessContextForProcess.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57169
2024-11-13 18:48:42 +01:00
Marc-Aurel Zent
194901b592 winemac.drv: Add additional French symbol vkeys mappings. 2024-11-13 18:48:42 +01:00
Marc-Aurel Zent
484c43c9e9 winemac.drv: Add Mac virtual key code information to the German layout. 2024-11-13 18:48:42 +01:00
Marc-Aurel Zent
1125bb8f71 winemac.drv: Allow symbol vkeys to match on Mac virtual key codes. 2024-11-13 18:48:42 +01:00
Piotr Caban
19018abf86 wine.inf: Set MountMgr service start option to SERVICE_BOOT_START.
This matches with native. It's needed to ensure that mountmgr is started
before other services that use functionality provided by it. Fixes
Autodesk Desktop Licensing Service that uses GetVolumeInformationByHandleW.
2024-11-13 18:48:42 +01:00
Piotr Caban
32be056558 services: Sort services start order by start type. 2024-11-13 18:48:42 +01:00
Zhiyi Zhang
e3db89aa9d urlmon/tests: Test flags for getting properties. 2024-11-13 18:48:42 +01:00
Zhiyi Zhang
61d8e74e72 urlmon: Support Uri_DISPLAY_IDN_HOST.
Uri_DISPLAY_IDN_HOST makes the hostname in Uri_PROPERTY_ABSOLUTE_URI, Uri_PROPERTY_DOMAIN and
Uri_PROPERTY_HOST appear in punycode or Unicode as it would appear in the Uri_PROPERTY_DISPLAY_URI
property. IDNs appears in Unicode on some Windows version and in punycode on others. Wine chose to
display Unicode for Uri_PROPERTY_DISPLAY_URI. So no need to add special handling for
Uri_DISPLAY_IDN_HOST at the moment because they already display in Unicode.
2024-11-13 18:48:42 +01:00
Zhiyi Zhang
427f8fae20 urlmon: Support Uri_PUNYCODE_IDN_HOST. 2024-11-13 18:48:42 +01:00
Zhiyi Zhang
71b4377e68 urlmon: Support Uri_DISPLAY_NO_FRAGMENT. 2024-11-13 18:48:42 +01:00
Zhiyi Zhang
a7b1e5d5dc urlmon: Support Uri_HOST_IDN. 2024-11-13 18:48:42 +01:00
Alexandre Julliard
dd6e73428d fluidsynth: Import upstream release 2.4.0. 2024-11-13 18:48:42 +01:00
Alexandre Julliard
3181ae039e mpg123: Import upstream release 1.32.9. 2024-11-13 15:05:23 +01:00
Alexandre Julliard
786cf5a20b nls: Update locale data to CLDR version 46. 2024-11-13 15:05:23 +01:00
Alexandre Julliard
9accb76341 tools: Download all Unicode data files before generating anything. 2024-11-13 15:05:23 +01:00
Alexandre Julliard
6208d61055 kernelbase: Implement EnumSystemFirmwareTables(). 2024-11-13 15:05:23 +01:00
Alexandre Julliard
966cec7a63 ntdll: Implement BIOS table enumeration.
Based on a patch by Dāvis Mosāns.
2024-11-13 15:05:16 +01:00
Alexandre Julliard
23db166ec8 kernel32/tests: Add some tests for EnumSystemFirmwareTables(). 2024-11-13 10:46:14 +01:00
Bernhard Übelacker
6dd7cd59d9 kernel32/tests: Remove todo_wine from now succeeding heap test.
This is a followup to commit d78cbe84e5.
2024-11-13 09:46:13 +01:00
Elizabeth Figura
60ddc9613b winevulkan: Use the correct logger method. 2024-11-12 21:52:24 +01:00
Elizabeth Figura
ac30eb1505 winevulkan: Use extend() instead of passing two separate roots to functions. 2024-11-12 21:52:24 +01:00
Rémi Bernon
3eb74f9ee8 desk.cpl: Expose the modesetting emulation registry setting. 2024-11-12 21:52:24 +01:00
Rémi Bernon
21623338ab win32u: Introduce a new registry setting to emulate modesetting. 2024-11-12 21:52:24 +01:00
Rémi Bernon
1b80a75048 win32u: Compute monitors raw DPI from the physical / current mode ratio. 2024-11-12 21:52:24 +01:00
Rémi Bernon
9a11af381b server: Use the monitor infos to map points from raw to virt. 2024-11-12 21:52:24 +01:00
Rémi Bernon
e6f8c57cc2 win32u: Offset the new display modes relative to the primary source. 2024-11-12 21:52:24 +01:00
Eric Pouech
d254d4ce12 cmd: Fix 'IF EXIST DIRECTORY' test condition evaluation.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
f21744527e cmd: Modifiers in tilde variable expansion are case insensitive.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
7b638dd0b8 cmd/tests: Add test about IF EXIST.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
68b3826d5f cmd: Implement 'touch' equivalent in COPY builtin.
MSDN documents a way to 'touch' a file in CMD.EXE with:
	COPY /B file.ext+,,
(and actually the /B switch doesn't matter).

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
94c61ed7c8 cmd: Fix substring substitution in variable expansion.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57290
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
888723eedb cmd/tests: Add tests about substring substitution in variable expansion.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
a5e04fa968 server: Amend process rights mapping.
PROCESS_VM_OPERATION | PROCESS_VM_WRITE grants
PROCESS_QUERY_LIMITED_INFORMATION rights.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
fb47740214 advapi32: Test some other cases of process access rights mapping.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
a7900c4594 advapi32/tests: Fix typo in manifest constant.
Harmless, the actual values are the same.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Eric Pouech
b5be39cfb8 kernel32/tests: Don't hardcode page size in buffer size.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
2024-11-12 21:52:24 +01:00
Rémi Bernon
52838daec5 winewayland: Fix surface scaling with HiDPI compositor.
The surface scale is there to match between the Wine DPI and the
compositor scaling, not to implement Wine DPI scaling, ie: when
compositor scaling is set to 200% and Wine DPI is also set to 192,
windows are shown at 1:1 scale, instead of being upscaled twice.
2024-11-12 21:52:24 +01:00
Connor McAdams
3900f6b741 d3dx9: Add support for saving paletted surfaces to DDS files.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:24 +01:00
Connor McAdams
6d5101f3c6 d3dx9: Set the DDSCAPS_ALPHA flag when saving DDS files with a pixel format containing an alpha channel.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:24 +01:00
Connor McAdams
821c25d6bc d3dx9: Improve save_dds_surface_to_memory().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:24 +01:00
Connor McAdams
8effb15214 d3dx9/tests: Add more tests for saving surfaces as DDS files.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:24 +01:00
Connor McAdams
41ec0064d4 d3dx9: Don't attempt to save palettized surfaces in D3DXSaveSurfaceToFileInMemory().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:24 +01:00
Connor McAdams
d5ee734628 d3dx9/tests: Include ddraw.h in surface.c for DDS header flag definitions.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
2024-11-12 21:52:23 +01:00
Yuxuan Shui
5fe083ee8d dinput: Keep the module around while input thread is running.
So we don't crash if the application unloads dinput. This can only happen if the application didn't
release all dinput objects before unloading the module, which we have observed the Yakuza games to
do.
2024-11-12 21:52:23 +01:00
Rémi Bernon
243437903e wined3d: Cast format_id when comparing it to the last format index.
Some FOURCC values such as 0xdeadbeef will en up being negative when cast to the
enum type, and may cause a random crash later on. This happens randomly in the
ddraw tests, depending on the compiler being used.
2024-11-12 21:52:23 +01:00
Rémi Bernon
606a63bc37 d3d8/tests: Use static class for the dummy window. 2024-11-12 21:52:23 +01:00
Rémi Bernon
4c240087d8 d3d8/tests: Avoid creating visible windows concurrently.
This causes a foreground window race condition and will cause spurious failures
depending on how pending X11 events are processed concurrenly.

Some tests now fail consistently and more todo_wine are needed.
2024-11-12 21:52:23 +01:00
Rémi Bernon
e9af0e7c7e d3d9/tests: Use static class for the dummy window. 2024-11-12 21:52:23 +01:00
Rémi Bernon
380933a1f4 d3d9/tests: Avoid creating visible windows concurrently.
This causes a foreground window race condition and will cause spurious failures
depending on how pending X11 events are processed concurrenly.

Some tests now fail consistently and more todo_wine are needed.
2024-11-12 21:52:23 +01:00
Haoyang Chen
ffdd1301d5 winex11: Fix URL encoding for non-ASCII characters. 2024-11-12 21:52:23 +01:00
Haoyang Chen
55a3a7ee77 winhttp: Add support WinHttpRequestOption_SslErrorIgnoreFlags in IWinHttpRequest_get_Option. 2024-11-12 12:32:33 +01:00
Haoyang Chen
d1e17e39d3 winhttp: Add support WinHttpRequestOption_SslErrorIgnoreFlags in IWinHttpRequest_put_Option. 2024-11-12 12:32:32 +01:00
Haoyang Chen
06dac0da4d winhttp/tests: Add some tests for WinHttpRequestOption_SslErrorIgnoreFlags in IWinHttpRequest_{put,get}_Option. 2024-11-12 12:32:32 +01:00
Alexandre Julliard
cc3a18cf0e user32/tests: Remove some obsolete winproc tests. 2024-11-12 11:54:21 +01:00
Alexandre Julliard
727411f07a user32/tests: Add tests for ntdll builtin window procs. 2024-11-12 11:49:38 +01:00
Alexandre Julliard
542e7afdb4 ntdll/tests: Add tests for the builtin window procs table. 2024-11-12 11:48:18 +01:00
Alexandre Julliard
d818a8d91d user32: Make the builtin window procs table layout compatible with Windows. 2024-11-12 11:30:51 +01:00
Alexandre Julliard
9f9ce9fa46 user32: Use the ntdll function table for builtin window procs. 2024-11-12 11:28:17 +01:00
Alexandre Julliard
cd7d895390 user32: Use the ntdll definitions for builtin windows procs. 2024-11-12 11:24:13 +01:00
Alexandre Julliard
357995ee8e ntdll: Add support for the builtin window procs table. 2024-11-12 11:22:41 +01:00
211 changed files with 12938 additions and 8917 deletions

64
.gitattributes vendored Normal file
View file

@ -0,0 +1,64 @@
[attr]generated gitlab-generated linguist-generated=true
# generated by autotools
configure generated
include/config.h.in generated
# generated by dlls/dsound/make_fir
dlls/dsound/fir.h generated
# generated by dlls/opencl/make_opencl
dlls/opencl/opencl.spec generated
dlls/opencl/opencl_types.h generated
dlls/opencl/pe_thunks.c generated
dlls/opencl/unix_thunks.c generated
dlls/opencl/unixlib.h generated
# generated by dlls/opengl32/make_opengl
dlls/opengl32/opengl32.spec generated
dlls/opengl32/thunks.c generated
dlls/opengl32/unix_thunks.c generated
dlls/opengl32/unixlib.h generated
include/wine/wgl.h generated
include/wine/wgl_driver.h generated
# generated by dlls/winevulkan/make_vulkan
dlls/vulkan-1/vulkan-1.spec generated
dlls/winevulkan/loader_thunks.c generated
dlls/winevulkan/loader_thunks.h generated
dlls/winevulkan/vulkan_thunks.c generated
dlls/winevulkan/vulkan_thunks.h generated
dlls/winevulkan/winevulkan.json generated
dlls/winevulkan/winevulkan.spec generated
include/wine/vulkan.h generated
include/wine/vulkan_driver.h generated
# generated by tools/make_requests
include/wine/server_protocol.h generated
server/request_handlers.h generated
server/request_trace.h generated
# generated by tools/make_specfiles
dlls/ntdll/ntsyscalls.h generated
dlls/win32u/win32syscalls.h generated
# generated by tools/make_unicode
dlls/dwrite/bracket.c generated
dlls/dwrite/direction.c generated
dlls/dwrite/linebreak.c generated
dlls/dwrite/mirror.c generated
dlls/dwrite/scripts.c generated
dlls/dwrite/scripts.h generated
dlls/dwrite/shapers/arabic_table.c generated
dlls/gdi32/uniscribe/bracket.c generated
dlls/gdi32/uniscribe/direction.c generated
dlls/gdi32/uniscribe/indicsyllable.c generated
dlls/gdi32/uniscribe/linebreak.c generated
dlls/gdi32/uniscribe/mirror.c generated
dlls/gdi32/uniscribe/shaping.c generated
dlls/kernelbase/kernelbase.rgs generated
dlls/tzres/tzres.rc generated
dlls/win32u/vertical.c generated
dlls/wineps.drv/direction.c generated
dlls/wineps.drv/vertical.c generated
nls/*.nls generated

3
aclocal.m4 vendored
View file

@ -198,6 +198,9 @@ ac_wine_try_cflags_saved_exeext=$ac_exeext
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs $1"
ac_exeext=".exe"
AC_LINK_IFELSE([AC_LANG_SOURCE([[void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }]])],
[AS_VAR_SET(ac_var,yes)], [AS_VAR_SET(ac_var,no)])
CFLAGS=$ac_wine_try_cflags_saved

185
configure generated vendored
View file

@ -10407,6 +10407,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10444,6 +10447,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10660,6 +10666,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10696,6 +10705,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10732,6 +10744,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10768,6 +10783,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10804,6 +10822,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10840,6 +10861,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10876,6 +10900,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10912,6 +10939,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10948,6 +10978,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -10984,6 +11017,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11020,6 +11056,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11056,6 +11095,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11092,6 +11134,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11128,6 +11173,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11164,6 +11212,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11200,6 +11251,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11236,6 +11290,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11272,6 +11329,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11308,6 +11368,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11344,6 +11407,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11380,6 +11446,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11403,6 +11472,86 @@ then :
as_fn_append ${wine_arch}_EXTRACFLAGS " -Wenum-conversion"
fi } ;;
esac
fi }
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-ffunction-sections" | sed "$as_sed_sh"`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -ffunction-sections" >&5
printf %s "checking whether $CC supports -ffunction-sections... " >&6; }
if eval test \${$as_ac_var+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_wine_try_cflags_saved=$CFLAGS
ac_wine_try_cflags_saved_exeext=$ac_exeext
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -ffunction-sections"
ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
eval "$as_ac_var=yes"
else case e in #(
e) eval "$as_ac_var=no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$ac_wine_try_cflags_saved
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
esac
fi
eval ac_res=\$$as_ac_var
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
if eval test \"x\$"$as_ac_var"\" = x"yes"
then :
as_fn_append ${wine_arch}_EXTRACFLAGS " -ffunction-sections"
fi }
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-fms-hotpatch -DMIN_CLANG_VERSION=18" | sed "$as_sed_sh"`
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18" >&5
printf %s "checking whether $CC supports -fms-hotpatch -DMIN_CLANG_VERSION=18... " >&6; }
if eval test \${$as_ac_var+y}
then :
printf %s "(cached) " >&6
else case e in #(
e) ac_wine_try_cflags_saved=$CFLAGS
ac_wine_try_cflags_saved_exeext=$ac_exeext
CFLAGS="$CFLAGS -nostdlib -nodefaultlibs -fms-hotpatch -DMIN_CLANG_VERSION=18"
ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
eval "$as_ac_var=yes"
else case e in #(
e) eval "$as_ac_var=no" ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$ac_wine_try_cflags_saved
ac_exeext=$ac_wine_try_cflags_saved_exeext ;;
esac
fi
eval ac_res=\$$as_ac_var
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
printf "%s\n" "$ac_res" >&6; }
if eval test \"x\$"$as_ac_var"\" = x"yes"
then :
as_fn_append ${wine_arch}_EXTRACFLAGS " -fms-hotpatch"
as_fn_append ${wine_arch}_LDFLAGS " -fms-hotpatch"
fi }
{ as_ac_var=`printf "%s\n" "ac_cv_${wine_arch}_cflags_-flarge-source-files -Wmisleading-indentation" | sed "$as_sed_sh"`
@ -11419,6 +11568,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11457,6 +11609,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11493,6 +11648,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11529,6 +11687,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11565,6 +11726,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11601,6 +11765,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11637,6 +11804,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11673,6 +11843,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11732,6 +11905,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11768,6 +11944,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11808,6 +11987,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"
@ -11844,6 +12026,9 @@ ac_exeext=".exe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
void *__os_arm64x_dispatch_ret = 0;
#if defined(__clang_major__) && defined(MIN_CLANG_VERSION) && __clang_major__ < MIN_CLANG_VERSION
#error Too old clang version
#endif
int __cdecl mainCRTStartup(void) { return 0; }
_ACEOF
if ac_fn_c_try_link "$LINENO"

View file

@ -961,6 +961,12 @@ This is an error since --enable-archs=$wine_arch was requested.])])
WINE_TRY_PE_CFLAGS([-Wlogical-op])
WINE_TRY_PE_CFLAGS([-Wabsolute-value])
WINE_TRY_PE_CFLAGS([-Wenum-enum-conversion],[:],WINE_TRY_PE_CFLAGS([-Wenum-conversion]))
WINE_TRY_PE_CFLAGS([-ffunction-sections])
dnl clang had broken -fms-hotpatch support before version 18 (https://github.com/llvm/llvm-project/pull/77245)
WINE_TRY_PE_CFLAGS([-fms-hotpatch -DMIN_CLANG_VERSION=18],
[AS_VAR_APPEND([${wine_arch}_EXTRACFLAGS],[" -fms-hotpatch"])
AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -fms-hotpatch"])])
dnl GCC can't handle large files when -Wmisleading-indentation is enabled (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89549)
WINE_TRY_PE_CFLAGS([-flarge-source-files -Wmisleading-indentation],[AS_VAR_APPEND(${wine_arch}_EXTRACFLAGS,[" -Wno-misleading-indentation"])])

View file

@ -3118,7 +3118,7 @@ static void test_process_security_child(void)
/* Test thread security */
handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() );
ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%ld\n", GetLastError());
TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
TEST_GRANTED_ACCESS( handle, THREAD_TERMINATE );
CloseHandle( handle );
handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
@ -6154,6 +6154,40 @@ static void test_process_access(void)
"expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
CloseHandle(dup);
SetLastError( 0xdeadbeef );
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
PROCESS_VM_OPERATION, FALSE, 0);
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
access = get_obj_access(dup);
ok(access == PROCESS_VM_OPERATION, "unexpected access right %lx\n", access);
CloseHandle(dup);
SetLastError( 0xdeadbeef );
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
PROCESS_VM_WRITE, FALSE, 0);
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
access = get_obj_access(dup);
ok(access == PROCESS_VM_WRITE, "unexpected access right %lx\n", access);
CloseHandle(dup);
SetLastError( 0xdeadbeef );
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, 0);
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
access = get_obj_access(dup);
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_LIMITED_INFORMATION) ||
broken(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE)) /* Win8 and before */,
"expected PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
CloseHandle(dup);
SetLastError( 0xdeadbeef );
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, 0);
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
access = get_obj_access(dup);
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_READ), "unexpected access right %lx\n", access);
CloseHandle(dup);
TerminateProcess(process, 0);
CloseHandle(process);
}

View file

@ -4150,6 +4150,7 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
/* see if we are supposed to be tracking mouse hovering */
if (LISTVIEW_IsHotTracking(infoPtr)) {
TRACKMOUSEEVENT trackinfo;
NMLISTVIEW nmlv = { 0 };
DWORD flags;
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
@ -4170,6 +4171,15 @@ static LRESULT LISTVIEW_MouseMove(LISTVIEW_INFO *infoPtr, WORD fwKeys, INT x, IN
/* call TRACKMOUSEEVENT so we receive WM_MOUSEHOVER messages */
_TrackMouseEvent(&trackinfo);
}
ht.pt = pt;
LISTVIEW_HitTest(infoPtr, &ht, TRUE, TRUE);
nmlv.iItem = ht.iItem;
nmlv.iSubItem = ht.iSubItem;
nmlv.ptAction = pt;
notify_listview(infoPtr, LVN_HOTTRACK, &nmlv);
}
return 0;
@ -9585,6 +9595,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
infoPtr->iVersion = COMCTL32_VERSION;
infoPtr->colRectsDirty = FALSE;
infoPtr->selected_column = -1;
infoPtr->hHotCursor = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
/* get default font (icon title) */
SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);

View file

@ -7255,6 +7255,19 @@ static void test_LVM_GETNEXTITEM(void)
DestroyWindow(hwnd);
}
static void test_LVM_GETHOTCURSOR(void)
{
HCURSOR cursor;
HWND hwnd;
hwnd = create_listview_control(LVS_REPORT);
cursor = (HCURSOR)SendMessageA(hwnd, LVM_GETHOTCURSOR, 0, 0);
ok(!!cursor, "Unexpected cursor %p.\n", cursor);
DestroyWindow(hwnd);
}
START_TEST(listview)
{
ULONG_PTR ctx_cookie;
@ -7322,6 +7335,7 @@ START_TEST(listview)
test_LVM_SETBKIMAGE(FALSE);
test_custom_sort();
test_LVM_GETNEXTITEM();
test_LVM_GETHOTCURSOR();
if (!load_v6_module(&ctx_cookie, &hCtx))
{
@ -7372,6 +7386,7 @@ START_TEST(listview)
test_LVM_GETNEXTITEMINDEX();
test_LVM_GETNEXTITEM();
test_LVM_SETBKIMAGE(TRUE);
test_LVM_GETHOTCURSOR();
unload_v6_module(ctx_cookie, hCtx);

View file

@ -2773,7 +2773,6 @@ struct wndproc_thread_param
HWND dummy_window;
HANDLE window_created;
HANDLE test_finished;
BOOL running_in_foreground;
};
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
@ -2849,10 +2848,9 @@ static DWORD WINAPI wndproc_thread(void *param)
DWORD res;
BOOL ret;
p->dummy_window = CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
p->running_in_foreground = SetForegroundWindow(p->dummy_window);
p->dummy_window = CreateWindowA("static", "d3d9_test", WS_VISIBLE | WS_CAPTION,
100, 100, 200, 200, 0, 0, 0, 0);
flush_events();
ret = SetEvent(p->window_created);
ok(ret, "SetEvent failed, last error %#lx.\n", GetLastError());
@ -3110,11 +3108,14 @@ static void test_wndproc(void)
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, user32_width, user32_height, 0, 0, 0, 0);
device_window = CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, user32_width, user32_height, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -3127,15 +3128,10 @@ static void test_wndproc(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
flush_events();
@ -3156,13 +3152,10 @@ static void test_wndproc(void)
expect_messages->message, expect_messages->window);
expect_messages = NULL;
if (0) /* Disabled until we can make this work in a reliable way on Wine. */
{
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
}
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
SetForegroundWindow(focus_window);
flush_events();
@ -3539,11 +3532,14 @@ static void test_wndproc_windowed(void)
device_window = CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -3556,15 +3552,10 @@ static void test_wndproc_windowed(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
filter_messages = focus_window;
@ -3580,7 +3571,7 @@ static void test_wndproc_windowed(void)
}
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);

View file

@ -2508,7 +2508,6 @@ struct wndproc_thread_param
HWND dummy_window;
HANDLE window_created;
HANDLE test_finished;
BOOL running_in_foreground;
};
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
@ -2581,10 +2580,9 @@ static DWORD WINAPI wndproc_thread(void *param)
DWORD res;
BOOL ret;
p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
p->running_in_foreground = SetForegroundWindow(p->dummy_window);
p->dummy_window = CreateWindowA("static", "d3d9_test", WS_VISIBLE | WS_CAPTION,
100, 100, 200, 200, 0, 0, 0, 0);
flush_events();
ret = SetEvent(p->window_created);
ok(ret, "SetEvent failed, last error %#lx.\n", GetLastError());
@ -2868,11 +2866,14 @@ static void test_wndproc(void)
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -2885,15 +2886,10 @@ static void test_wndproc(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
flush_events();
@ -2913,13 +2909,10 @@ static void test_wndproc(void)
expect_messages->message, expect_messages->window, i);
expect_messages = NULL;
if (0) /* Disabled until we can make this work in a reliable way on Wine. */
{
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
}
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
SetForegroundWindow(focus_window);
flush_events();
@ -3013,9 +3006,6 @@ static void test_wndproc(void)
SetForegroundWindow(GetDesktopWindow());
ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
expect_messages->message, expect_messages->window, i);
/* kwin sometimes resizes hidden windows. */
flaky
ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
expect_messages = NULL;
@ -3027,28 +3017,12 @@ static void test_wndproc(void)
flush_events();
/* Openbox accidentally sets focus to the device window, causing WM_ACTIVATEAPP to be sent to the focus
* window. d3d9ex then restores the screen mode. This only happens in the D3DCREATE_NOWINDOWCHANGES case.
*
* This appears to be a race condition - it goes away if openbox is started with --sync. d3d9:device and
* d3d8:device are affected too, but because in their case d3d does not automatically restore the screen
* mode (it needs a call to device::Reset), the EnumDisplaySettings check succeeds regardless.
*
* Note that this is not a case of focus follows mouse. This happens when Openbox is configured to use
* click to focus too. */
if (GetForegroundWindow() == device_window)
{
skip("WM set focus to the device window, not checking screen mode.\n");
}
else
{
ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
ok(ret, "Failed to get display mode.\n");
ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth,
"Got unexpected width %lu.\n", devmode.dmPelsWidth);
ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight,
"Got unexpected height %lu.\n", devmode.dmPelsHeight);
}
ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
ok(ret, "Failed to get display mode.\n");
ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth,
"Got unexpected width %lu.\n", devmode.dmPelsWidth);
ok(devmode.dmPelsHeight == registry_mode.dmPelsHeight,
"Got unexpected height %lu.\n", devmode.dmPelsHeight);
/* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
* send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
@ -3125,9 +3099,6 @@ static void test_wndproc(void)
flaky_wine
ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
expect_messages->message, expect_messages->window, i);
/* kwin and Win8+ sometimes resize hidden windows. */
flaky
ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
expect_messages = NULL;
@ -3311,11 +3282,14 @@ static void test_wndproc_windowed(void)
device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -3328,16 +3302,10 @@ static void test_wndproc_windowed(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
flaky
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
filter_messages = focus_window;
@ -3352,7 +3320,7 @@ static void test_wndproc_windowed(void)
}
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);

View file

@ -3762,7 +3762,6 @@ struct wndproc_thread_param
HWND dummy_window;
HANDLE window_created;
HANDLE test_finished;
BOOL running_in_foreground;
};
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
@ -3840,10 +3839,9 @@ static DWORD WINAPI wndproc_thread(void *param)
DWORD res;
BOOL ret;
p->dummy_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
p->running_in_foreground = SetForegroundWindow(p->dummy_window);
p->dummy_window = CreateWindowA("static", "d3d9_test", WS_VISIBLE | WS_CAPTION,
100, 100, 200, 200, 0, 0, 0, 0);
flush_events();
ret = SetEvent(p->window_created);
ok(ret, "SetEvent failed, last error %#lx.\n", GetLastError());
@ -4147,11 +4145,14 @@ static void test_wndproc(void)
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, user32_width, user32_height, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -4164,15 +4165,10 @@ static void test_wndproc(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
flush_events();
@ -4193,13 +4189,10 @@ static void test_wndproc(void)
expect_messages->message, expect_messages->window, i);
expect_messages = NULL;
if (0) /* Disabled until we can make this work in a reliable way on Wine. */
{
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
}
tmp = GetFocus();
ok(tmp == focus_window, "Expected focus %p, got %p.\n", focus_window, tmp);
tmp = GetForegroundWindow();
ok(tmp == focus_window, "Expected foreground window %p, got %p.\n", focus_window, tmp);
SetForegroundWindow(focus_window);
flush_events();
@ -4614,11 +4607,14 @@ static void test_wndproc_windowed(void)
device_window = CreateWindowA("d3d9_test_wndproc_wc", "d3d9_test",
WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION, 0, 0, registry_mode.dmPelsWidth,
registry_mode.dmPelsHeight, 0, 0, 0, 0);
flush_events();
thread = CreateThread(NULL, 0, wndproc_thread, &thread_params, 0, &tid);
ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
res = WaitForSingleObject(thread_params.window_created, INFINITE);
ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
flush_events();
proc = GetWindowLongPtrA(device_window, GWLP_WNDPROC);
ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#Ix, got %#Ix.\n",
@ -4631,15 +4627,10 @@ static void test_wndproc_windowed(void)
device_window, focus_window, thread_params.dummy_window);
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
if (thread_params.running_in_foreground)
{
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
}
else
skip("Not running in foreground, skip foreground window test\n");
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);
filter_messages = focus_window;
@ -4655,7 +4646,7 @@ static void test_wndproc_windowed(void)
}
tmp = GetFocus();
ok(tmp == device_window, "Expected focus %p, got %p.\n", device_window, tmp);
ok(tmp == NULL, "Expected focus %p, got %p.\n", NULL, tmp);
tmp = GetForegroundWindow();
ok(tmp == thread_params.dummy_window, "Expected foreground window %p, got %p.\n",
thread_params.dummy_window, tmp);

View file

@ -79,6 +79,8 @@ static const GUID *wic_guid_from_d3dformat(D3DFORMAT format)
return NULL;
}
#define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256)
/* dds_header.flags */
#define DDS_CAPS 0x1
#define DDS_HEIGHT 0x2
@ -90,7 +92,9 @@ static const GUID *wic_guid_from_d3dformat(D3DFORMAT format)
#define DDS_DEPTH 0x800000
/* dds_header.caps */
#define DDSCAPS_ALPHA 0x2
#define DDS_CAPS_COMPLEX 0x8
#define DDSCAPS_PALETTE 0x100
#define DDS_CAPS_TEXTURE 0x1000
#define DDS_CAPS_MIPMAP 0x400000
@ -378,24 +382,31 @@ static enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dds_pixel_format(cons
return D3DX_PIXEL_FORMAT_COUNT;
}
static HRESULT dds_pixel_format_from_d3dformat(struct dds_pixel_format *pixel_format, D3DFORMAT d3dformat)
static HRESULT dds_pixel_format_from_d3dx_pixel_format_id(struct dds_pixel_format *pixel_format,
enum d3dx_pixel_format_id d3dx_pixel_format)
{
enum d3dx_pixel_format_id d3dx_pixel_format = d3dx_pixel_format_id_from_d3dformat(d3dformat);
const struct dds_pixel_format *pf = NULL;
uint32_t i;
memset(pixel_format, 0, sizeof(*pixel_format));
pixel_format->size = sizeof(*pixel_format);
for (i = 0; i < ARRAY_SIZE(dds_pixel_formats); ++i)
{
if (dds_pixel_formats[i].d3dx_pixel_format == d3dx_pixel_format)
{
*pixel_format = dds_pixel_formats[i].dds_pixel_format;
return D3D_OK;
pf = &dds_pixel_formats[i].dds_pixel_format;
break;
}
}
WARN("Unknown pixel format %#x.\n", d3dformat);
return E_NOTIMPL;
if (!pf)
{
WARN("Unhandled format %#x.\n", d3dx_pixel_format);
return E_NOTIMPL;
}
if (pixel_format)
*pixel_format = *pf;
return D3D_OK;
}
static void d3dx_get_next_mip_level_size(struct volume *size)
@ -454,97 +465,165 @@ static uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id forma
return layer_size;
}
static UINT calculate_dds_file_size(D3DFORMAT format, UINT width, UINT height, UINT depth,
UINT miplevels, UINT faces)
{
const struct pixel_format_desc *fmt_desc = get_format_info(format);
UINT i, file_size = 0;
for (i = 0; i < miplevels; i++)
{
UINT pitch, size = 0;
if (FAILED(d3dx_calculate_pixels_size(fmt_desc->format, width, height, &pitch, &size)))
return 0;
size *= depth;
file_size += size;
width = max(1, width / 2);
height = max(1, height / 2);
depth = max(1, depth / 2);
}
file_size *= faces;
file_size += sizeof(struct dds_header);
return file_size;
}
static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface, const RECT *src_rect)
static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE resource_type,
enum d3dx_pixel_format_id format, const struct volume *size, uint32_t mip_levels)
{
HRESULT hr;
UINT dst_pitch, surface_size, file_size;
D3DSURFACE_DESC src_desc;
D3DLOCKED_RECT locked_rect;
ID3DXBuffer *buffer;
struct dds_header *header;
BYTE *pixels;
struct volume volume;
const struct pixel_format_desc *pixel_format;
IDirect3DSurface9 *temp_surface;
if (src_rect)
{
FIXME("Saving a part of a surface to a DDS file is not implemented yet\n");
return E_NOTIMPL;
}
hr = IDirect3DSurface9_GetDesc(src_surface, &src_desc);
if (FAILED(hr)) return hr;
pixel_format = get_format_info(src_desc.Format);
if (is_unknown_format(pixel_format)) return E_NOTIMPL;
file_size = calculate_dds_file_size(src_desc.Format, src_desc.Width, src_desc.Height, 1, 1, 1);
if (!file_size)
return D3DERR_INVALIDCALL;
hr = d3dx_calculate_pixels_size(pixel_format->format, src_desc.Width, src_desc.Height, &dst_pitch, &surface_size);
if (FAILED(hr)) return hr;
hr = D3DXCreateBuffer(file_size, &buffer);
if (FAILED(hr)) return hr;
header = ID3DXBuffer_GetBufferPointer(buffer);
pixels = (BYTE *)(header + 1);
memset(header, 0, sizeof(*header));
header->signature = MAKEFOURCC('D','D','S',' ');
/* The signature is not really part of the DDS header */
/* The signature is not really part of the DDS header. */
header->size = sizeof(*header) - FIELD_OFFSET(struct dds_header, size);
header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT;
header->height = src_desc.Height;
header->width = src_desc.Width;
header->caps = DDS_CAPS_TEXTURE;
hr = dds_pixel_format_from_d3dformat(&header->pixel_format, src_desc.Format);
hr = dds_pixel_format_from_d3dx_pixel_format_id(&header->pixel_format, format);
if (FAILED(hr))
{
ID3DXBuffer_Release(buffer);
return hr;
header->flags = DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT;
header->height = size->height;
header->width = size->width;
header->caps = DDS_CAPS_TEXTURE;
if (header->pixel_format.flags & DDS_PF_ALPHA || header->pixel_format.flags & DDS_PF_ALPHA_ONLY)
header->caps |= DDSCAPS_ALPHA;
if (header->pixel_format.flags & DDS_PF_INDEXED)
header->caps |= DDSCAPS_PALETTE;
return D3D_OK;
}
static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc,
D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer)
{
enum d3dx_pixel_format_id dst_format = src_fmt_desc->format;
const struct pixel_format_desc *dst_fmt_desc;
uint32_t dst_row_pitch, dst_slice_pitch;
struct d3dx_pixels dst_pixels;
ID3DXBuffer *buffer = NULL;
uint8_t *pixels;
HRESULT hr;
*dst_buffer = NULL;
switch (file_format)
{
case D3DXIFF_DDS:
{
struct dds_header *header;
uint32_t header_size;
hr = dds_pixel_format_from_d3dx_pixel_format_id(NULL, dst_format);
if (FAILED(hr))
return hr;
dst_fmt_desc = get_d3dx_pixel_format_info(dst_format);
hr = d3dx_calculate_pixels_size(dst_format, src_pixels->size.width, src_pixels->size.height, &dst_row_pitch,
&dst_slice_pitch);
if (FAILED(hr))
return hr;
header_size = is_index_format(dst_fmt_desc) ? sizeof(*header) + DDS_PALETTE_SIZE : sizeof(*header);
hr = D3DXCreateBuffer(dst_slice_pitch + header_size, &buffer);
if (FAILED(hr))
return hr;
header = ID3DXBuffer_GetBufferPointer(buffer);
pixels = (uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + header_size;
hr = d3dx_init_dds_header(header, D3DRTYPE_TEXTURE, dst_format, &src_pixels->size, 1);
if (FAILED(hr))
goto exit;
if (is_index_format(dst_fmt_desc))
memcpy((uint8_t *)ID3DXBuffer_GetBufferPointer(buffer) + sizeof(*header), src_pixels->palette,
DDS_PALETTE_SIZE);
break;
}
default:
assert(0 && "Unexpected file format.");
return E_FAIL;
}
if (src_pixels->size.width != 0 && src_pixels->size.height != 0)
{
const RECT dst_rect = { 0, 0, src_pixels->size.width, src_pixels->size.height };
set_d3dx_pixels(&dst_pixels, pixels, dst_row_pitch, dst_slice_pitch, src_pixels->palette, src_pixels->size.width,
src_pixels->size.height, src_pixels->size.depth, &dst_rect);
hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, src_pixels, src_fmt_desc, D3DX_FILTER_NONE, 0);
if (FAILED(hr))
goto exit;
}
*dst_buffer = buffer;
exit:
if (buffer && *dst_buffer != buffer)
ID3DXBuffer_Release(buffer);
return hr;
}
static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSurface9 *src_surface,
const PALETTEENTRY *src_palette, const RECT *src_rect)
{
const struct pixel_format_desc *src_fmt_desc;
D3DSURFACE_DESC src_surface_desc;
IDirect3DSurface9 *temp_surface;
struct d3dx_pixels src_pixels;
D3DLOCKED_RECT locked_rect;
ID3DXBuffer *buffer;
RECT src_rect_temp;
HRESULT hr;
IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);
src_fmt_desc = get_format_info(src_surface_desc.Format);
if (is_unknown_format(src_fmt_desc))
return E_NOTIMPL;
if (!src_palette && is_index_format(src_fmt_desc))
{
FIXME("Default palette unimplemented.\n");
return E_NOTIMPL;
}
if (src_rect)
{
if (src_rect->left > src_rect->right || src_rect->right > src_surface_desc.Width
|| src_rect->top > src_rect->bottom || src_rect->bottom > src_surface_desc.Height
|| src_rect->left < 0 || src_rect->top < 0)
{
WARN("Invalid src_rect specified.\n");
return D3DERR_INVALIDCALL;
}
}
else
{
SetRect(&src_rect_temp, 0, 0, src_surface_desc.Width, src_surface_desc.Height);
src_rect = &src_rect_temp;
}
hr = lock_surface(src_surface, NULL, &locked_rect, &temp_surface, FALSE);
if (FAILED(hr))
return hr;
hr = d3dx_pixels_init(locked_rect.pBits, locked_rect.Pitch, 0, src_palette, src_fmt_desc->format,
src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1, &src_pixels);
if (FAILED(hr))
{
unlock_surface(src_surface, NULL, temp_surface, FALSE);
return hr;
}
hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, D3DXIFF_DDS, &buffer);
if (FAILED(hr))
{
unlock_surface(src_surface, NULL, temp_surface, FALSE);
return hr;
}
hr = unlock_surface(src_surface, NULL, temp_surface, FALSE);
if (FAILED(hr))
{
ID3DXBuffer_Release(buffer);
return hr;
}
volume.width = src_desc.Width;
volume.height = src_desc.Height;
volume.depth = 1;
copy_pixels(locked_rect.pBits, locked_rect.Pitch, 0, pixels, dst_pitch, 0,
&volume, pixel_format);
unlock_surface(src_surface, NULL, temp_surface, FALSE);
*dst_buffer = buffer;
return D3D_OK;
}
@ -603,7 +682,6 @@ static BOOL d3dx_get_image_file_format_from_file_signature(const void *src_data,
return FALSE;
}
#define DDS_PALETTE_SIZE (sizeof(PALETTEENTRY) * 256)
static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src_data_size,
struct d3dx_image *image, uint32_t starting_mip_level)
{
@ -2895,9 +2973,10 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
if (!dst_buffer || !src_surface) return D3DERR_INVALIDCALL;
if (src_palette)
IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);
if (file_format != D3DXIFF_DDS && (src_palette || is_index_format(get_format_info(src_surface_desc.Format))))
{
FIXME("Saving surfaces with palettized pixel formats is not implemented yet\n");
FIXME("Saving surfaces with palettized pixel formats to non-DDS files is not implemented yet.\n");
return D3DERR_INVALIDCALL;
}
@ -2914,7 +2993,7 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
container_format = &GUID_ContainerFormatJpeg;
break;
case D3DXIFF_DDS:
return save_dds_surface_to_memory(dst_buffer, src_surface, src_rect);
return save_dds_surface_to_memory(dst_buffer, src_surface, src_palette, src_rect);
case D3DXIFF_HDR:
case D3DXIFF_PFM:
case D3DXIFF_TGA:
@ -2925,7 +3004,6 @@ HRESULT WINAPI D3DXSaveSurfaceToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE
return D3DERR_INVALIDCALL;
}
IDirect3DSurface9_GetDesc(src_surface, &src_surface_desc);
if (src_rect)
{
if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom)

View file

@ -26,6 +26,15 @@
#include <stdint.h>
#include "d3dx9_test_images.h"
/*
* MAKE_DDHRESULT is first defined in d3dx9.h, with the same definition as the
* one in ddraw.h.
*/
#ifdef MAKE_DDHRESULT
#undef MAKE_DDHRESULT
#endif
#include "ddraw.h"
static BOOL compare_uint(uint32_t x, uint32_t y, uint32_t max_diff)
{
uint32_t diff = x > y ? x - y : y - x;
@ -140,34 +149,6 @@ static HRESULT create_file(const char *filename, const unsigned char *data, cons
return D3DERR_INVALIDCALL;
}
/* dds_header.flags */
#define DDS_CAPS 0x00000001
#define DDS_HEIGHT 0x00000002
#define DDS_WIDTH 0x00000004
#define DDS_PITCH 0x00000008
#define DDS_PIXELFORMAT 0x00001000
#define DDS_MIPMAPCOUNT 0x00020000
#define DDS_LINEARSIZE 0x00080000
#define DDS_PITCH 0x00000008
#define DDS_DEPTH 0x00800000
/* dds_header.caps */
#define DDSCAPS_ALPHA 0x00000002
#define DDS_CAPS_TEXTURE 0x00001000
#define DDS_CAPS_COMPLEX 0x00000008
#define DDS_CAPS2_VOLUME 0x00200000
#define DDS_CAPS2_CUBEMAP 0x00000200
#define DDS_CAPS2_CUBEMAP_POSITIVEX 0x00000400
#define DDS_CAPS2_CUBEMAP_NEGATIVEX 0x00000800
#define DDS_CAPS2_CUBEMAP_POSITIVEY 0x00001000
#define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x00002000
#define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x00004000
#define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x00008000
#define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \
| DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \
| DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ )
/* dds_pixel_format.flags */
#define DDS_PF_ALPHA 0x00000001
#define DDS_PF_ALPHA_ONLY 0x00000002
@ -214,7 +195,7 @@ static void fill_dds_header(struct dds_header *header)
memset(header, 0, sizeof(*header));
header->size = sizeof(*header);
header->flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT;
header->flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
header->height = 4;
header->width = 4;
header->pixel_format.size = sizeof(header->pixel_format);
@ -226,7 +207,7 @@ static void fill_dds_header(struct dds_header *header)
header->pixel_format.gmask = 0x00ff00;
header->pixel_format.bmask = 0x0000ff;
header->pixel_format.amask = 0;
header->caps = DDS_CAPS_TEXTURE;
header->caps = DDSCAPS_TEXTURE;
}
#define check_dds_pixel_format(flags, fourcc, bpp, rmask, gmask, bmask, amask, format) \
@ -332,37 +313,37 @@ static void test_dds_header_handling(void)
/* pitch is ignored */
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, 0, 4, 4, 0, 0,
63 /* pixel data size */, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 0 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 0 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 1 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 2 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 2 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 3 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 3 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 4 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 4 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 16 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 16 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1024 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, 1024 /* pitch */, 0,
64, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, -1 /* pitch */, 0,
{ { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDSD_PITCH, 4, 4, -1 /* pitch */, 0,
64, { D3D_OK, 1 } },
/* linear size is ignored */
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 4, 4, 0, 0,
7 /* pixel data size */, { D3DXERR_INVALIDDATA, 1 } },
/* 10. */
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 0 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, 0 /* linear size */, 0,
8, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 1 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, 1 /* linear size */, 0,
8, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 2 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, 2 /* linear size */, 0,
8, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 9 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, 9 /* linear size */, 0,
8, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 16 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, 16 /* linear size */, 0,
8, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, -1 /* linear size */, 0,
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_LINEARSIZE, 4, 4, -1 /* linear size */, 0,
8, { D3D_OK, 1 } },
/* integer overflows */
{ { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000000, 0x80000000 /* 0x80000000 * 0x80000000 * 4 = 0 */, 0, 0,
@ -376,46 +357,46 @@ static void test_dds_header_handling(void)
/* 20. File size is validated. */
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 64, 0, 0, 49151, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 64, 0, 0, 49152, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 65279, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 65280, { D3D_OK, 4 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 9, 65540, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 9, 65541, { D3D_OK, 9 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 4, 65279, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 4, 65280, { D3D_OK, 4 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 9, 65540, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 9, 65541, { D3D_OK, 9 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196607, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196608, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196609, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 1, 196607, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 1, 196607, { D3DXERR_INVALIDDATA, 0 } },
/* 30. */
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 1, 196608, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 196607, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 196608, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 400000, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 262142, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 262143, { D3D_OK, 9 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 10, 262145, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 10, 262146, { D3D_OK, 10 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 262175, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 262176, { D3D_OK, 20 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 1, 196608, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 196607, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 196608, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 400000, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 262142, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 262143, { D3D_OK, 9 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 10, 262145, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 10, 262146, { D3D_OK, 10 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 262175, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 262176, { D3D_OK, 20 } },
/* 40. */
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 32767, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 32768, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 32767, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 32768, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 43703, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 43704, { D3D_OK, 9 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 43791, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 43792, { D3D_OK, 20 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 32767, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 32768, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 43703, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 43704, { D3D_OK, 9 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 43791, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 43792, { D3D_OK, 20 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 65535, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 65536, { D3D_OK, 1 } },
/* 50. */
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 65535, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 65536, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 87407, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 87408, { D3D_OK, 9 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 87583, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 87584, { D3D_OK, 20 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 21759, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 21760, { D3D_OK, 4 } },
/* DDS_MIPMAPCOUNT is ignored */
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 65535, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 0, 65536, { D3D_OK, 1 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 87407, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 9, 87408, { D3D_OK, 9 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 87583, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 256, 0, 20, 87584, { D3D_OK, 20 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 4, 21759, { D3DXERR_INVALIDDATA, 0 } },
{ { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDSD_MIPMAPCOUNT, 256, 64, 0, 4, 21760, { D3D_OK, 4 } },
/* DDSD_MIPMAPCOUNT is ignored */
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 262146, { D3D_OK, 1 } },
{ { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 2, 262146, { D3D_OK, 2 } },
/* 60. */
@ -462,34 +443,34 @@ static void test_dds_header_handling(void)
BOOL todo_info;
} info_tests[] = {
/* Depth value set to 4, but no caps bits are set. Depth is ignored. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, 0, 0,
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, 0, 0,
{ D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 },
/* The volume texture caps2 field is ignored. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3,
(DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), DDS_CAPS2_VOLUME,
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT), 4, 4, 4, (4 * 4), 3,
(DDSCAPS_TEXTURE | DDSCAPS_COMPLEX), DDSCAPS2_VOLUME,
{ D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 },
/*
* The DDS_DEPTH flag is the only thing checked to determine if a DDS
* The DDSD_DEPTH flag is the only thing checked to determine if a DDS
* file represents a volume texture.
*/
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3,
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_DEPTH), 4, 4, 4, (4 * 4), 3,
0, 0,
{ D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 },
/* Even if the depth field is set to 0, it's still a volume texture. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 0, (4 * 4), 3,
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_DEPTH), 4, 4, 0, (4 * 4), 3,
0, 0,
{ D3D_OK, 4, 4, 1, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 },
/* The DDS_DEPTH flag overrides cubemap caps. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3,
(DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES),
/* The DDSD_DEPTH flag overrides cubemap caps. */
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_DEPTH), 4, 4, 4, (4 * 4), 3,
(DDSCAPS_TEXTURE | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES),
{ D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, (292 * 6) },
/* Cubemap where width field does not equal height. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 5, 1, (4 * 4), 1,
(DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES),
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT), 4, 5, 1, (4 * 4), 1,
(DDSCAPS_TEXTURE | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES),
{ D3D_OK, 4, 5, 1, 1, D3DRTYPE_CUBETEXTURE, }, (80 * 6) },
/* Partial cubemaps are not supported. */
{ (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 1,
(DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_POSITIVEX),
{ (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT), 4, 4, 1, (4 * 4), 1,
(DDSCAPS_TEXTURE | DDSCAPS_COMPLEX), (DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX),
{ D3DXERR_INVALIDDATA, }, (64 * 6) },
};
@ -3444,8 +3425,415 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
}
#define check_dds_pixel_format_struct(pixel_format, expected_pixel_format, wine_todo) \
check_dds_pixel_format_struct_(__FILE__, __LINE__, pixel_format, expected_pixel_format, wine_todo)
static void check_dds_pixel_format_struct_(const char *file, uint32_t line, const struct dds_pixel_format *pixel_format,
const struct dds_pixel_format *expected_pixel_format, BOOL wine_todo)
{
BOOL matched;
matched = !memcmp(expected_pixel_format, pixel_format, sizeof(*pixel_format));
todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds pixel format values.\n");
if (matched)
return;
todo_wine_if(wine_todo && pixel_format->flags != expected_pixel_format->flags)
ok_(file, line)(pixel_format->flags == expected_pixel_format->flags, "Unexpected DDS pixel format flags %#lx.\n",
pixel_format->flags);
todo_wine_if(wine_todo && pixel_format->fourcc != expected_pixel_format->fourcc)
ok_(file, line)(pixel_format->fourcc == expected_pixel_format->fourcc, "Unexpected DDS pixel format fourcc %#lx.\n",
pixel_format->fourcc);
todo_wine_if(wine_todo && pixel_format->bpp != expected_pixel_format->bpp)
ok_(file, line)(pixel_format->bpp == expected_pixel_format->bpp, "Unexpected DDS pixel format bpp %#lx.\n",
pixel_format->bpp);
todo_wine_if(wine_todo && pixel_format->rmask != expected_pixel_format->rmask)
ok_(file, line)(pixel_format->rmask == expected_pixel_format->rmask, "Unexpected DDS pixel format rmask %#lx.\n",
pixel_format->rmask);
todo_wine_if(wine_todo && pixel_format->gmask != expected_pixel_format->gmask)
ok_(file, line)(pixel_format->gmask == expected_pixel_format->gmask, "Unexpected DDS pixel format gmask %#lx.\n",
pixel_format->gmask);
todo_wine_if(wine_todo && pixel_format->bmask != expected_pixel_format->bmask)
ok_(file, line)(pixel_format->bmask == expected_pixel_format->bmask, "Unexpected DDS pixel format bmask %#lx.\n",
pixel_format->bmask);
todo_wine_if(wine_todo && pixel_format->amask != expected_pixel_format->amask)
ok_(file, line)(pixel_format->amask == expected_pixel_format->amask, "Unexpected DDS pixel format amask %#lx.\n",
pixel_format->amask);
}
#define check_dds_header(header, flags, height, width, pitch, depth, mip_levels, pixel_format, caps, caps2, wine_todo) \
check_dds_header_(__FILE__, __LINE__, header, flags, height, width, pitch, depth, mip_levels, pixel_format, \
caps, caps2, wine_todo)
static void check_dds_header_(const char *file, uint32_t line, const struct dds_header *header, uint32_t flags,
uint32_t height, uint32_t width, uint32_t pitch, uint32_t depth, uint32_t mip_levels,
const struct dds_pixel_format *pixel_format, uint32_t caps, uint32_t caps2, BOOL wine_todo)
{
const struct dds_header expected_header = { sizeof(*header), flags, height, width, pitch, depth, mip_levels, { 0 },
*pixel_format, caps, caps2, 0, 0, 0 };
BOOL matched;
matched = !memcmp(&expected_header, header, sizeof(*header));
todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds header values.\n");
if (matched)
return;
todo_wine_if(wine_todo && header->flags != flags)
ok_(file, line)(header->flags == flags, "Unexpected DDS header flags %#lx.\n", header->flags);
todo_wine_if(wine_todo && header->width != width)
ok_(file, line)(header->width == width, "Unexpected DDS header width %#lx.\n", header->width);
todo_wine_if(wine_todo && header->height != height)
ok_(file, line)(header->height == height, "Unexpected DDS header height %#lx.\n", header->height);
todo_wine_if(wine_todo && header->pitch_or_linear_size != pitch)
ok_(file, line)(header->pitch_or_linear_size == pitch, "Unexpected DDS header pitch %#lx.\n",
header->pitch_or_linear_size);
todo_wine_if(wine_todo && header->depth != depth)
ok_(file, line)(header->depth == depth, "Unexpected DDS header depth %#lx.\n", header->depth);
todo_wine_if(wine_todo && header->miplevels != mip_levels)
ok_(file, line)(header->miplevels == mip_levels, "Unexpected DDS header mip levels %#lx.\n", header->miplevels);
ok_(file, line)(!memcmp(header->reserved, expected_header.reserved, sizeof(header->reserved)),
"Unexpected values in DDS header reserved field.");
check_dds_pixel_format_struct(&header->pixel_format, pixel_format, FALSE);
todo_wine_if(wine_todo && header->caps != caps)
ok_(file, line)(header->caps == caps, "Unexpected DDS header caps %#lx.\n", header->caps);
todo_wine_if(wine_todo && header->caps2 != caps2)
ok_(file, line)(header->caps2 == caps2, "Unexpected DDS header caps2 %#lx.\n", header->caps2);
ok_(file, line)(!header->caps3, "Unexpected DDS header caps3 %#lx.\n", header->caps3);
ok_(file, line)(!header->caps4, "Unexpected DDS header caps4 %#lx.\n", header->caps4);
ok_(file, line)(!header->reserved2, "Unexpected DDS header reserved2 %#lx.\n", header->reserved2);
}
#define DDS_FILE_HEADER_SIZE (sizeof(uint32_t) + sizeof(struct dds_header))
#define PALETTED_DDS_FILE_HEADER_SIZE (DDS_FILE_HEADER_SIZE + (sizeof(PALETTEENTRY) * 256))
static void test_save_surface_to_dds(IDirect3DDevice9 *device)
{
struct expected
{
HRESULT hr;
struct dds_pixel_format pixel_format;
uint32_t flags;
uint32_t width;
uint32_t height;
uint32_t pitch;
uint32_t depth;
uint32_t mip_levels;
uint32_t caps;
uint32_t caps2;
uint32_t buffer_size;
};
static const struct
{
D3DFORMAT format;
uint32_t width;
uint32_t height;
const PALETTEENTRY *palette;
struct expected expected_vals;
BOOL todo_hr;
BOOL todo_expected;
} dds_tests[] =
{
{ D3DFMT_P8, 4, 4, test_palette,
{ D3D_OK, { 32, DDS_PF_INDEXED, 0, 8, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_PALETTE, 0,
PALETTED_DDS_FILE_HEADER_SIZE + (4 * 4)
}
},
{ D3DFMT_A8P8, 4, 4, test_palette,
{ D3D_OK, { 32, DDS_PF_INDEXED | DDS_PF_ALPHA, 0, 16, 0, 0, 0, 0xff00 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0,
DDSCAPS_TEXTURE | DDSCAPS_PALETTE | DDSCAPS_ALPHA, 0,
PALETTED_DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
/* If a palette isn't provided, d3dx converts to D3DFMT_A8R8G8B8. */
{ D3DFMT_P8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}, .todo_hr = TRUE
},
{ D3DFMT_A8P8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}, .todo_hr = TRUE
},
{ D3DFMT_V8U8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_BUMPDUDV, 0, 16, 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_V16U16, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_Q8W8V8U8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_BUMPDUDV, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A2W10V10U10, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_BUMPDUDV | DDS_PF_ALPHA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_X8L8V8U8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_BUMPLUMINANCE, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_R5G6B5, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 16, 0xf800, 0x07e0, 0x001f, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
/* 10. */
{ D3DFMT_A1R5G5B5, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x7c00, 0x03e0, 0x001f, 0x8000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_A4R4G4B4, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x0f00, 0x00f0, 0x000f, 0xf000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_R3G3B2, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 8, 0xe0, 0x1c, 0x03, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4)
}
},
{ D3DFMT_A8R3G3B2, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x00e0, 0x001c, 0x0003, 0xff00 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_X4R4G4B4, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 16, 0xf00, 0x0f0, 0x00f, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_A2B10G10R10, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A2R10G10B10, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A8R8G8B8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A8B8G8R8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_X8R8G8B8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
/* 20. */
{ D3DFMT_X8B8G8R8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_R8G8B8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 3 * 4)
}
},
{ D3DFMT_G16R16, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_ALPHA_ONLY, 0, 8, 0, 0, 0, 0xff },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0,
DDS_FILE_HEADER_SIZE + (4 * 4)
}
},
{ D3DFMT_DXT1, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (8)
}
},
{ D3DFMT_DXT2, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_DXT2, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (16)
}
},
{ D3DFMT_DXT3, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_DXT3, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (16)
}
},
{ D3DFMT_DXT4, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (16)
}
},
{ D3DFMT_DXT5, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_DXT5, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (16)
}
},
{ D3DFMT_A16B16G16R16, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_A16B16G16R16, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 8 * 4)
}
},
/* 30. */
{ D3DFMT_Q16W16V16U16, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_Q16W16V16U16, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 8 * 4)
}
},
{ D3DFMT_R16F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_R16F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_G16R16F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_G16R16F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_A16B16G16R16F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_A16B16G16R16F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 8 * 4)
}
},
{ D3DFMT_R32F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_R32F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 4 * 4)
}
},
{ D3DFMT_G32R32F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_G32R32F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 8 * 4)
}
},
{ D3DFMT_A32B32G32R32F, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_A32B32G32R32F, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 16 * 4)
}
},
{ D3DFMT_G8R8_G8B8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_R8G8_B8G8, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
{ D3DFMT_UYVY, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_UYVY, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
/* 40. */
{ D3DFMT_YUY2, 4, 4, NULL,
{ D3D_OK, { 32, DDS_PF_FOURCC, D3DFMT_YUY2, 0, 0, 0, 0, 0 },
DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0, DDSCAPS_TEXTURE, 0,
DDS_FILE_HEADER_SIZE + (4 * 2 * 4)
}
},
};
struct
{
DWORD magic;
struct dds_header header;
BYTE *data;
} *dds;
IDirect3DSurface9 *surface;
ID3DXBuffer *buffer;
unsigned int i;
HRESULT hr;
for (i = 0; i < ARRAY_SIZE(dds_tests); ++i)
{
const struct expected *expected = &dds_tests[i].expected_vals;
hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, dds_tests[i].width, dds_tests[i].height, dds_tests[i].format,
D3DPOOL_SCRATCH, &surface, NULL);
if (FAILED(hr))
{
skip("Couldn't create surface for format %#x.\n", dds_tests[i].format);
continue;
}
winetest_push_context("Test %u", i);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, dds_tests[i].palette, NULL);
todo_wine_if(dds_tests[i].todo_hr) ok(hr == expected->hr, "Unexpected hr %#lx.\n", hr);
if (SUCCEEDED(hr))
{
ok(ID3DXBuffer_GetBufferSize(buffer) == expected->buffer_size, "Unexpected buffer size %lu.\n",
ID3DXBuffer_GetBufferSize(buffer));
dds = ID3DXBuffer_GetBufferPointer(buffer);
check_dds_header(&dds->header, expected->flags, expected->height, expected->width, expected->pitch,
expected->depth, expected->mip_levels, &expected->pixel_format, expected->caps, expected->caps2,
dds_tests[i].todo_expected);
ID3DXBuffer_Release(buffer);
}
IDirect3DSurface9_Release(surface);
winetest_pop_context();
}
}
static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
{
static const struct dds_pixel_format d3dfmt_a8r8g8b8_pf = { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32,
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
static const uint32_t tmp_pixdata_4_4[] = { 0xff000000, 0xff000000, 0xff000000, 0xff000000,
0x00ff0040, 0x00ff0040, 0x00ff0040, 0x00ff0040,
0x0000ff80, 0x0000ff80, 0x0000ff80, 0x0000ff80,
0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0 };
static const struct
{
DWORD usage;
@ -3466,8 +3854,8 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
} *dds;
IDirect3DSurface9 *surface;
IDirect3DTexture9 *texture;
unsigned int i, x, y;
ID3DXBuffer *buffer;
unsigned int i;
HRESULT hr;
RECT rect;
@ -3477,6 +3865,10 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
return;
}
SetRect(&rect, 0, 0, 4, 4);
hr = D3DXLoadSurfaceFromMemory(surface, NULL, NULL, tmp_pixdata_4_4, D3DFMT_A8R8G8B8, 16, NULL, &rect, D3DX_FILTER_NONE, 0);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
SetRectEmpty(&rect);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_BMP, surface, NULL, &rect);
/* fails with the debug version of d3d9 */
@ -3489,38 +3881,57 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
SetRectEmpty(&rect);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect);
todo_wine ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
if (SUCCEEDED(hr))
{
dds = ID3DXBuffer_GetBufferPointer(buffer);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#lx.\n", dds->magic);
ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %lu.\n", dds->header.size);
ok(!dds->header.height, "Got unexpected height %lu.\n", dds->header.height);
ok(!dds->header.width, "Got unexpected width %lu.\n", dds->header.width);
ok(!dds->header.depth, "Got unexpected depth %lu.\n", dds->header.depth);
ok(!dds->header.miplevels, "Got unexpected miplevels %lu.\n", dds->header.miplevels);
ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %lu.\n", dds->header.pitch_or_linear_size);
ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#lx.\n", dds->header.caps);
ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT),
"Got unexpected flags %#lx.\n", dds->header.flags);
ID3DXBuffer_Release(buffer);
dds = ID3DXBuffer_GetBufferPointer(buffer);
check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 0, 0, 0, 0, 0,
&d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE);
ID3DXBuffer_Release(buffer);
/* Test rectangle argument for D3DXIFF_DDS. */
SetRect(&rect, 0, 0, 0, 2);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
dds = ID3DXBuffer_GetBufferPointer(buffer);
check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 2, 0, 0, 0, 0,
&d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE);
ID3DXBuffer_Release(buffer);
SetRect(&rect, 0, 0, 2, 0);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
dds = ID3DXBuffer_GetBufferPointer(buffer);
check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 0, 2, 0, 0, 0,
&d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE);
ID3DXBuffer_Release(buffer);
SetRect(&rect, 2, 2, 4, 4);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
dds = ID3DXBuffer_GetBufferPointer(buffer);
check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 2, 2, 0, 0, 0,
&d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE);
for (y = 0; y < 2; ++y)
{
for (x = 0; x < 2; ++x)
{
const uint32_t expected_pixel = tmp_pixdata_4_4[((2 + y) * 4) + (x + 2)];
const uint32_t saved_pixel = ((uint32_t *)&dds->data)[(y * 2) + x];
ok(expected_pixel == saved_pixel, "Unexpected pixel value %#x.\n", saved_pixel);
}
}
ID3DXBuffer_Release(buffer);
hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, NULL);
ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
dds = ID3DXBuffer_GetBufferPointer(buffer);
ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#lx.\n", dds->magic);
ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %lu.\n", dds->header.size);
ok(dds->header.height == 4, "Got unexpected height %lu.\n", dds->header.height);
ok(dds->header.width == 4, "Got unexpected width %lu.\n", dds->header.width);
ok(!dds->header.depth, "Got unexpected depth %lu.\n", dds->header.depth);
ok(!dds->header.miplevels, "Got unexpected miplevels %lu.\n", dds->header.miplevels);
ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %lu.\n", dds->header.pitch_or_linear_size);
todo_wine ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#lx.\n", dds->header.caps);
ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT),
"Got unexpected flags %#lx.\n", dds->header.flags);
check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 4, 4, 0, 0, 0,
&d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE);
ID3DXBuffer_Release(buffer);
IDirect3DSurface9_Release(surface);
@ -3545,6 +3956,8 @@ static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
IDirect3DSurface9_Release(surface);
IDirect3DTexture9_Release(texture);
}
test_save_surface_to_dds(device);
}
static void test_D3DXSaveSurfaceToFile(IDirect3DDevice9 *device)

View file

@ -4379,7 +4379,13 @@ static BOOL codeview_process_info(const struct process *pcs,
TRACE("Got RSDS type of PDB file: guid=%s age=%08x name=%s\n",
wine_dbgstr_guid(&rsds->guid), rsds->age, debugstr_a(rsds->name));
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
/* gcc/mingw and clang can emit build-id information, but with an empty PDB filename.
* Don't search for the .pdb file in that case.
*/
if (rsds->name[0])
ret = pdb_process_file(pcs, msc_dbg, rsds->name, &rsds->guid, 0, rsds->age);
else
ret = TRUE;
break;
}
default:
@ -4487,7 +4493,7 @@ typedef struct _FPO_DATA
__ENDTRY
/* we haven't found yet any debug information, fallback to unmatched pdb */
if (module->module.SymType == SymDeferred)
if (!ret && module->module.SymType == SymDeferred)
{
SYMSRV_INDEX_INFOW info = {.sizeofstruct = sizeof(info)};
char buffer[MAX_PATH];
@ -4549,38 +4555,35 @@ DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* debug_dir
num_misc_records++;
}
}
return info->stripped && !num_misc_records ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
return (!num_dir || (info->stripped && !num_misc_records)) ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
}
DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
{
const IMAGE_SEPARATE_DEBUG_HEADER *header;
IMAGE_DEBUG_DIRECTORY *dbg;
DWORD num_directories;
if (size < sizeof(*header)) return ERROR_BAD_EXE_FORMAT;
if (size < sizeof(*header)) return ERROR_BAD_FORMAT;
header = image;
if (header->Signature != 0x4944 /* DI */ ||
size < sizeof(*header) + header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + header->ExportedNamesSize + header->DebugDirectorySize)
return ERROR_BAD_EXE_FORMAT;
return ERROR_BAD_FORMAT;
info->size = header->SizeOfImage;
/* seems to use header's timestamp, not debug_directory one */
info->timestamp = header->TimeDateStamp;
info->stripped = FALSE; /* FIXME */
/* header is followed by:
* - header->NumberOfSections of IMAGE_SECTION_HEADER
* - header->ExportedNameSize
* - then num_directories of IMAGE_DEBUG_DIRECTORY
*/
dbg = (IMAGE_DEBUG_DIRECTORY*)((char*)(header + 1) +
header->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
header->ExportedNamesSize);
num_directories = header->DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY);
if (!num_directories) return ERROR_BAD_EXE_FORMAT;
info->age = 0;
memset(&info->guid, 0, sizeof(info->guid));
info->sig = 0;
info->dbgfile[0] = L'\0';
info->pdbfile[0] = L'\0';
info->size = header->SizeOfImage;
/* seems to use header's timestamp, not debug_directory one */
info->timestamp = header->TimeDateStamp;
info->stripped = FALSE; /* FIXME */
return ERROR_SUCCESS;
return msc_get_file_indexinfo(image, dbg, num_directories, info);
}

View file

@ -832,7 +832,7 @@ BOOL WINAPI SymSrvGetFileIndexInfoW(const WCHAR *file, SYMSRV_INDEX_INFOW* info,
if (hMap) CloseHandle(hMap);
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
if (ret == ERROR_SUCCESS) wcscpy(info->file, file_name(file)); /* overflow? */
if (ret == ERROR_SUCCESS || ret == ERROR_BAD_EXE_FORMAT) wcscpy(info->file, file_name(file)); /* overflow? */
SetLastError(ret);
return ret == ERROR_SUCCESS;
}

View file

@ -656,8 +656,8 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* mod
if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
{
ERR("-Debug info stripped, but no .DBG file in module %s\n",
debugstr_w(module->modulename));
WARN("-Debug info stripped, but no .DBG file in module %s\n",
debugstr_w(module->modulename));
}
else
{
@ -1019,7 +1019,7 @@ DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
if (!(nthdr = RtlImageNtHeader(image))) return ERROR_BAD_FORMAT;
dbg = RtlImageDirectoryEntryToData(image, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dirsize);
if (!dbg || dirsize < sizeof(dbg)) return ERROR_BAD_EXE_FORMAT;
if (!dbg) dirsize = 0;
/* fill in information from NT header */
info->timestamp = nthdr->FileHeader.TimeDateStamp;

View file

@ -671,20 +671,22 @@ static BOOL create_test_pdb_ds(const WCHAR* pdb_name, const GUID* guid, DWORD ag
return TRUE;
}
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp, DWORD size)
static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD charac, DWORD timestamp, DWORD size, struct debug_directory_blob *blob)
{
HANDLE hfile;
/* minimalistic .dbg made of a header and a DEBUG_DIRECTORY without any data */
const IMAGE_SEPARATE_DEBUG_HEADER header = {.Signature = 0x4944 /* DI */,
.Flags = 0, .Machine = machine, .Characteristics = 0x010E, .TimeDateStamp = timestamp,
IMAGE_SEPARATE_DEBUG_HEADER header =
{
.Signature = 0x4944 /* DI */,
.Flags = 0, .Machine = machine, .Characteristics = charac, .TimeDateStamp = timestamp,
.CheckSum = 0, .ImageBase = 0x00040000, .SizeOfImage = size, .NumberOfSections = 0,
.ExportedNamesSize = 0, .DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY)};
const IMAGE_DEBUG_DIRECTORY debug_dir = {.Characteristics = 0, .TimeDateStamp = timestamp + 1,
.MajorVersion = 0, .MinorVersion = 0, .Type = IMAGE_DEBUG_TYPE_CODEVIEW,
.SizeOfData = 0, .AddressOfRawData = 0,
.PointerToRawData = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
header.DebugDirectorySize};
.ExportedNamesSize = 0, .DebugDirectorySize = 0
};
DWORD where, expected_size;
if (blob)
header.DebugDirectorySize = sizeof(IMAGE_DEBUG_DIRECTORY);
hfile = CreateFileW(dbg_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "failed to create %ls err %lu\n", dbg_name, GetLastError());
@ -692,8 +694,18 @@ static BOOL create_test_dbg(const WCHAR* dbg_name, WORD machine, DWORD timestamp
check_write_file(hfile, &header, sizeof(header));
/* FIXME: 0 sections... as header.NumberOfSections */
check_write_file(hfile, &debug_dir, sizeof(debug_dir));
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == debug_dir.PointerToRawData, "mismatch\n");
if (blob)
{
where = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
blob->debug_directory.PointerToRawData = (blob->debug_directory.SizeOfData) ?
where + sizeof(IMAGE_DEBUG_DIRECTORY) : 0;
check_write_file(hfile, &blob->debug_directory, sizeof(IMAGE_DEBUG_DIRECTORY));
check_write_file(hfile, blob->content, blob->debug_directory.SizeOfData);
}
expected_size = sizeof(header) + header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
if (blob)
expected_size += sizeof(IMAGE_DEBUG_DIRECTORY) + blob->debug_directory.SizeOfData;
ok(SetFilePointer(hfile, 0, NULL, FILE_CURRENT) == expected_size, "Incorrect file length\n");
CloseHandle(hfile);
return TRUE;
@ -725,16 +737,16 @@ static void test_srvgetindexes_pe(void)
DWORD sig;
WCHAR pdb_name[16];
WCHAR dbg_name[16];
BOOL in_error;
DWORD last_error;
}
indexes[] =
{
/* error cases */
/* 0 */{0, {-1, -1, -1}, .in_error = TRUE},
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, .in_error = TRUE},
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, .in_error = TRUE},
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, .in_error = TRUE},
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, .in_error = TRUE}, /* not 100% logical ! */
/* 0 */{0, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_DEBUG_STRIPPED, { 0, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_DEBUG_STRIPPED, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_DEBUG_STRIPPED, { 2, -1, -1}, 124, &guid1, 0, .pdb_name = L"pdbds.pdb", .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_DEBUG_STRIPPED, {-1, -1, -1}, 0, &null_guid, 0, .last_error = ERROR_BAD_EXE_FORMAT}, /* not 100% logical ! */
/* success */
/* 5 */{0, { 0, -1, -1}, 0, &null_guid, 0 },
{0, { 1, -1, -1}, 123, &null_guid, 0xaaaabbbb, .pdb_name = L"pdbjg.pdb"},
@ -796,16 +808,16 @@ static void test_srvgetindexes_pe(void)
memset(&ssii, 0xa5, sizeof(ssii));
ssii.sizeofstruct = sizeof(ssii);
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
if (indexes[i].in_error)
if (indexes[i].last_error)
{
ok(!ret, "SymSrvGetFileIndexInfo should have failed\n");
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Mismatch in GetLastError: %lu\n", GetLastError());
ok(GetLastError() == indexes[i].last_error, "Mismatch in GetLastError: %lu\n", GetLastError());
}
else
{
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
if (ret || indexes[i].last_error == ERROR_BAD_EXE_FORMAT)
{
ok(ssii.age == indexes[i].age, "Mismatch in age: %lu\n", ssii.age);
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
@ -882,48 +894,69 @@ static void test_srvgetindexes_dbg(void)
WCHAR filename[128];
SYMSRV_INDEX_INFOW ssii;
BOOL ret;
struct debug_directory_blob *blob_refs[1];
static struct
{
/* input parameters */
WORD machine;
DWORD timestamp;
DWORD imagesize;
WORD machine;
DWORD characteristics;
DWORD timestamp;
DWORD imagesize;
int blob;
/* output parameters */
DWORD age;
const GUID *guid;
WCHAR pdbname[16];
WCHAR dbgname[16];
DWORD last_error;
}
indexes[] =
{
{IMAGE_FILE_MACHINE_I386, 0x1234, 0x00560000},
{IMAGE_FILE_MACHINE_AMD64, 0x1235, 0x00570000},
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, -1, 0, &null_guid, .last_error = ERROR_BAD_EXE_FORMAT},
{IMAGE_FILE_MACHINE_I386, 0, 0x1234, 0x00560000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
{IMAGE_FILE_MACHINE_AMD64, 0, 0x1235, 0x00570000, 0, 123, &guid1, .pdbname=L"foo.pdb"},
};
blob_refs[0] = make_pdb_ds_blob(0x1226, &guid1, 123, "foo.pdb");
for (i = 0; i < ARRAY_SIZE(indexes); i++)
{
winetest_push_context("dbg#%02u", i);
/* create dll */
swprintf(filename, ARRAY_SIZE(filename), L"winetest%02u.dbg", i);
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].timestamp, indexes[i].imagesize);
ret = create_test_dbg(filename, indexes[i].machine, indexes[i].characteristics,
indexes[i].timestamp, indexes[i].imagesize,
indexes[i].blob == -1 ? NULL : blob_refs[indexes[i].blob]);
ok(ret, "Couldn't create dbg file %ls\n", filename);
memset(&ssii, 0x45, sizeof(ssii));
ssii.sizeofstruct = sizeof(ssii);
ret = SymSrvGetFileIndexInfoW(filename, &ssii, 0);
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
if (indexes[i].last_error)
{
ok(!ret, "SymSrvGetFileIndexInfo should have\n");
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Unexpected last error: %lu\n", GetLastError());
}
else
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
ok(ssii.age == 0, "Mismatch in age: %lx\n", ssii.age);
ok(!memcmp(&ssii.guid, &null_guid, sizeof(GUID)),
ok(ssii.age == indexes[i].age, "Mismatch in age: %lx\n", ssii.age);
ok(IsEqualGUID(&ssii.guid, indexes[i].guid),
"Mismatch in guid: guid=%s\n", wine_dbgstr_guid(&ssii.guid));
ok(ssii.sig == 0, "Mismatch in sig: %lx\n", ssii.sig);
ok(ssii.size == indexes[i].imagesize, "Mismatch in size: %lx\n", ssii.size);
ok(!ssii.stripped, "Mismatch in stripped: %x\n", ssii.stripped);
ok(ssii.timestamp == indexes[i].timestamp, "Mismatch in timestamp: %lx\n", ssii.timestamp);
ok(!wcscmp(ssii.file, filename), "Mismatch in file: %ls\n", ssii.file);
ok(!ssii.pdbfile[0], "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
ok(!ssii.dbgfile[0], "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
ok(!wcscmp(ssii.pdbfile, indexes[i].pdbname), "Mismatch in pdbfile: %ls\n", ssii.pdbfile);
ok(!wcscmp(ssii.dbgfile, indexes[i].dbgname), "Mismatch in dbgfile: %ls\n", ssii.dbgfile);
DeleteFileW(filename);
winetest_pop_context();
}
for (i = 0; i < ARRAY_SIZE(blob_refs); i++) free(blob_refs[i]);
}
static void make_path(WCHAR file[MAX_PATH], const WCHAR* topdir, const WCHAR* subdir, const WCHAR* base)
@ -1533,7 +1566,8 @@ static void test_load_modules_path(void)
if (test_files[val].guid)
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
else
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
/*create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, blob); */
ok(0, "not supported yet\n");
}
else ok(0, "Unrecognized file reference %c\n", *ptr);
}
@ -1754,7 +1788,7 @@ static void test_load_modules_details(void)
if (test_files[val].guid)
create_test_pdb_ds(filename, test_files[val].guid, test_files[val].age_or_timestamp);
else
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000);
create_test_dbg(filename, IMAGE_FILE_MACHINE_AMD64 /* FIXME */, 0x10E, test_files[val].age_or_timestamp, 0x40000 * val * 0x20000, NULL);
}
else ok(0, "Unrecognized file reference %c\n", *ptr);
}

View file

@ -1,5 +1,5 @@
MODULE = desk.cpl
IMPORTS = ole32 comctl32 user32 gdi32
IMPORTS = advapi32 ole32 comctl32 user32 gdi32
SOURCES = \
desk.rc \

View file

@ -38,6 +38,7 @@ FONT 8, "Ms Shell Dlg"
COMBOBOX IDC_DISPLAY_SETTINGS_LIST, 10, 136, 160, 60, CBS_DROPDOWNLIST | CBS_HASSTRINGS
PUSHBUTTON "&Reset", IDC_DISPLAY_SETTINGS_RESET, 180, 135, 60, 15
PUSHBUTTON "&Apply", IDC_DISPLAY_SETTINGS_APPLY, 250, 135, 60, 15
AUTOCHECKBOX "Emulate display mode changes (requires restart)", IDC_EMULATE_MODESET, 10, 155, 300, 10
}
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

View file

@ -242,6 +242,39 @@ static void handle_display_settings_apply(void)
ChangeDisplaySettingsExW( NULL, NULL, 0, 0, NULL );
}
static void handle_emulate_modeset_change( HWND hwnd )
{
const WCHAR *value = L"N";
HKEY hkey;
/* Registry key can be found in HKCU\Software\Wine\X11 Driver */
if (!RegCreateKeyExW( HKEY_CURRENT_USER, L"Software\\Wine\\X11 Driver", 0, NULL, 0,
KEY_SET_VALUE, NULL, &hkey, NULL ))
{
if (IsDlgButtonChecked( hwnd, IDC_EMULATE_MODESET ) == BST_CHECKED) value = L"Y";
RegSetValueExW( hkey, L"EmulateModeset", 0, REG_SZ, (BYTE *)value, (wcslen( value ) + 1) * sizeof(WCHAR) );
RegCloseKey( hkey );
}
}
static BOOL get_option( const WCHAR *option, BOOL default_value )
{
BOOL ret = default_value;
WCHAR buffer[MAX_PATH];
DWORD size = sizeof(buffer);
#define IS_OPTION_TRUE(ch) \
((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
/* Registry key can be found in HKCU\Software\Wine\X11 Driver */
if (!RegGetValueW( HKEY_CURRENT_USER, L"Software\\Wine\\X11 Driver", option, RRF_RT_REG_SZ, NULL,
(BYTE *)buffer, &size ))
ret = IS_OPTION_TRUE(buffer[0]);
#undef IS_OPTION_TRUE
return ret;
}
static RECT map_virtual_client_rect( RECT rect, RECT client_rect, RECT virtual_rect, float scale )
{
OffsetRect( &rect, -(virtual_rect.left + virtual_rect.right) / 2, -(virtual_rect.top + virtual_rect.bottom) / 2 );
@ -424,6 +457,8 @@ static INT_PTR CALLBACK desktop_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam,
case WM_INITDIALOG:
refresh_device_list( hwnd );
create_desktop_view( hwnd );
SendMessageW( GetDlgItem( hwnd, IDC_EMULATE_MODESET ), BM_SETCHECK,
get_option( L"EmulateModeset", FALSE ), 0 );
return TRUE;
case WM_COMMAND:
@ -432,6 +467,9 @@ static INT_PTR CALLBACK desktop_dialog_proc( HWND hwnd, UINT msg, WPARAM wparam,
case MAKEWPARAM( IDC_DISPLAY_SETTINGS_LIST, CBN_SELCHANGE ):
handle_display_settings_change( hwnd );
break;
case IDC_EMULATE_MODESET:
handle_emulate_modeset_change( hwnd );
break;
case IDC_DISPLAY_SETTINGS_APPLY:
handle_display_settings_apply();
break;

View file

@ -40,5 +40,6 @@
#define IDC_DISPLAY_SETTINGS_LIST 2001
#define IDC_DISPLAY_SETTINGS_RESET 2002
#define IDC_DISPLAY_SETTINGS_APPLY 2003
#define IDC_EMULATE_MODESET 2004
#define ICO_MAIN 100

View file

@ -370,6 +370,7 @@ static DWORD WINAPI dinput_thread_proc( void *params )
struct input_thread_state state = {.running = TRUE};
struct dinput_device *device;
HANDLE start_event = params;
HMODULE this_module = NULL;
DWORD ret;
MSG msg;
@ -377,6 +378,10 @@ static DWORD WINAPI dinput_thread_proc( void *params )
di_em_win = CreateWindowW( L"DIEmWin", L"DIEmWin", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, DINPUT_instance, NULL );
input_thread_state = &state;
if (!GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (void *)dinput_thread_proc, &this_module ))
ERR( "Failed to get a handle of dinput to keep it alive: %lu", GetLastError() );
SetEvent( start_event );
while (state.running && (ret = MsgWaitForMultipleObjectsEx( state.events_count, state.events, INFINITE, QS_ALLINPUT, 0 )) <= state.events_count)
@ -417,6 +422,8 @@ static DWORD WINAPI dinput_thread_proc( void *params )
DestroyWindow( di_em_win );
di_em_win = NULL;
if (this_module != NULL) FreeLibraryAndExitThread( this_module, 0 );
return 0;
}

View file

@ -897,7 +897,7 @@ static HRESULT layout_shape_get_user_features(const struct dwrite_textlayout *la
feature_count = IDWriteTypography_GetFontFeatureCount(typography);
if (!feature_count)
{
i = range->h.range.length - i + 1;
i = range->h.range.startPosition + range->h.range.length;
continue;
}

View file

@ -656,7 +656,13 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val)
TRACE("no prop_put\n");
return S_OK;
}
return This->builtin_info->prop_put(This, prop->u.id, val);
hres = This->builtin_info->prop_put(This, prop->u.id, val);
if(hres != S_FALSE)
return hres;
prop->type = PROP_JSVAL;
prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE;
prop->u.val = jsval_undefined();
break;
default:
ERR("type %d\n", prop->type);
return E_FAIL;
@ -2322,8 +2328,21 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DI
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatch *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
jsdisp_t *This = impl_from_IWineJSDispatch(iface);
FIXME("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
return E_NOTIMPL;
dispex_prop_t *prop;
TRACE("(%p)->(%lx %lx %p)\n", This, id, grfdexFetch, pgrfdex);
prop = get_prop(This, id);
if(!prop)
return DISP_E_MEMBERNOTFOUND;
*pgrfdex = 0;
if(grfdexFetch) {
FIXME("unimplemented flags %08lx\n", grfdexFetch);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT WINAPI DispatchEx_GetMemberName(IWineJSDispatch *iface, DISPID id, BSTR *pbstrName)

View file

@ -3641,6 +3641,85 @@ static void test_invokeex(void)
IActiveScript_Release(script);
}
static void test_members(void)
{
DISPID func_id, prop_id;
IActiveScript *script;
IDispatchEx *dispex;
DWORD propflags;
HRESULT hres;
VARIANT v;
BSTR str;
hres = parse_script_expr(L"var o = { func: function() {}, prop: 1 }; o", &v, &script);
ok(hres == S_OK, "parse_script_expr failed: %08lx\n", hres);
ok(V_VT(&v) == VT_DISPATCH, "V_VT(v) = %d\n", V_VT(&v));
hres = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IDispatchEx, (void**)&dispex);
ok(hres == S_OK, "Could not get IDispatchEx iface: %08lx\n", hres);
VariantClear(&v);
str = SysAllocString(L"func");
hres = IDispatchEx_GetDispID(dispex, str, 0, &func_id);
SysFreeString(str);
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
str = SysAllocString(L"prop");
hres = IDispatchEx_GetDispID(dispex, str, 0, &prop_id);
SysFreeString(str);
ok(hres == S_OK, "GetDispID failed: %08lx\n", hres);
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
ok(!wcscmp(str, L"func"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
SysFreeString(str);
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
SysFreeString(str);
propflags = 0xdeadbeef;
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
ok(propflags == 0, "propflags = %08lx", propflags);
propflags = 0xdeadbeef;
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
ok(propflags == 0, "propflags = %08lx", propflags);
hres = IDispatchEx_DeleteMemberByDispID(dispex, func_id);
ok(hres == S_OK, "DeleteMemberByDispID failed: %08lx\n", hres);
hres = IDispatchEx_GetMemberName(dispex, func_id, &str);
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
hres = IDispatchEx_GetMemberProperties(dispex, func_id, 0, &propflags);
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
ok(hres == S_OK, "GetMemberName failed: %08lx\n", hres);
ok(!wcscmp(str, L"prop"), "GetMemberName returned %s\n", wine_dbgstr_w(str));
SysFreeString(str);
propflags = 0xdeadbeef;
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
ok(hres == S_OK, "GetMemberProperties failed: %08lx\n", hres);
ok(propflags == 0, "propflags = %08lx", propflags);
str = SysAllocString(L"prop");
hres = IDispatchEx_DeleteMemberByName(dispex, str, 0);
ok(hres == S_OK, "DeleteMemberByName failed: %08lx\n", hres);
SysFreeString(str);
hres = IDispatchEx_GetMemberName(dispex, prop_id, &str);
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberName failed: %08lx\n", hres);
hres = IDispatchEx_GetMemberProperties(dispex, prop_id, 0, &propflags);
ok(hres == DISP_E_MEMBERNOTFOUND, "GetMemberProperties failed: %08lx\n", hres);
IDispatchEx_Release(dispex);
IActiveScript_Release(script);
}
static void test_destructors(void)
{
static const WCHAR cyclic_refs[] = L"(function() {\n"
@ -4299,6 +4378,7 @@ static BOOL run_tests(void)
test_script_exprs();
test_invokeex();
test_members();
test_destructors();
test_eval();
test_error_reports();

View file

@ -217,7 +217,6 @@ static void test_HeapCreate(void)
count = GetProcessHeaps( ARRAY_SIZE(heaps), heaps );
ok( count == heap_count + 2, "GetProcessHeaps returned %lu\n", count );
ok( heaps[0] == GetProcessHeap(), "got wrong heap\n" );
todo_wine
ok( heaps[heap_count + 0] == heap, "got wrong heap\n" );
todo_wine
ok( heaps[heap_count + 1] == heap1, "got wrong heap\n" );

View file

@ -18,12 +18,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "wine/test.h"
#include "winbase.h"
#include "winternl.h"
#include "appmodel.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, void *, DWORD);
static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
static LONG (WINAPI * pPackageIdFromFullName)(const WCHAR *, UINT32, UINT32 *, BYTE *);
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
@ -44,6 +47,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("kernel32.dll");
GET_PROC(GetProductInfo);
GET_PROC(EnumSystemFirmwareTables);
GET_PROC(GetSystemFirmwareTable);
GET_PROC(PackageIdFromFullName);
@ -701,17 +705,18 @@ static void test_VerifyVersionInfo(void)
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
}
static void test_GetSystemFirmwareTable(void)
static void test_SystemFirmwareTable(void)
{
static const ULONG min_sfti_len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
ULONG expected_len;
UINT len;
NTSTATUS status;
SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
UCHAR *smbios_table;
if (!pGetSystemFirmwareTable)
if (!pGetSystemFirmwareTable || !pEnumSystemFirmwareTables)
{
win_skip("GetSystemFirmwareTable not available\n");
win_skip("SystemFirmwareTable functions not available\n");
return;
}
@ -720,18 +725,21 @@ static void test_GetSystemFirmwareTable(void)
sfti->ProviderSignature = RSMB;
sfti->Action = SystemFirmwareTable_Get;
sfti->TableID = 0;
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
if (expected_len == 0) /* xp, 2003 */
{
win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
ok(!!sfti, "Failed to allocate memory\n");
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
expected_len -= min_sfti_len;
ok( sfti->TableBufferLength == expected_len, "wrong len %lu/%lx\n",
sfti->TableBufferLength, expected_len );
len = pGetSystemFirmwareTable(RSMB, 0, NULL, 0);
ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
@ -744,9 +752,27 @@ static void test_GetSystemFirmwareTable(void)
sfti->TableBuffer[3], sfti->TableBuffer[4], sfti->TableBuffer[5],
smbios_table[0], smbios_table[1], smbios_table[2],
smbios_table[3], smbios_table[4], smbios_table[5]);
HeapFree(GetProcessHeap(), 0, smbios_table);
sfti->Action = SystemFirmwareTable_Enumerate;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
ok( expected_len == min_sfti_len + sizeof(UINT), "wrong len %lu\n", expected_len );
ok( sfti->TableBufferLength == sizeof(UINT), "wrong len %lu\n", sfti->TableBufferLength );
ok( *(UINT *)sfti->TableBuffer == 0, "wrong table id %x\n", *(UINT *)sfti->TableBuffer );
len = pEnumSystemFirmwareTables( RSMB, NULL, 0 );
ok( len == sizeof(UINT), "wrong len %u\n", len );
smbios_table = malloc( len );
len = pEnumSystemFirmwareTables( RSMB, smbios_table, len );
ok( len == sizeof(UINT), "wrong len %u\n", len );
ok( *(UINT *)smbios_table == 0, "wrong table id %x\n", *(UINT *)smbios_table );
free( smbios_table );
HeapFree(GetProcessHeap(), 0, sfti);
HeapFree(GetProcessHeap(), 0, smbios_table);
}
static const struct
@ -1100,6 +1126,6 @@ START_TEST(version)
test_GetVersionEx();
test_VerifyVersionInfo();
test_pe_os_version();
test_GetSystemFirmwareTable();
test_SystemFirmwareTable();
test_PackageIdFromFullName();
}

View file

@ -4368,13 +4368,15 @@ static void test_PrefetchVirtualMemory(void)
static void test_ReadProcessMemory(void)
{
BYTE buf[0x2000];
BYTE *buf;
DWORD old_prot;
SIZE_T copied;
HANDLE hproc;
void *ptr;
BOOL ret;
buf = malloc(2 * si.dwPageSize);
ok(buf != NULL, "OOM\n");
ret = DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
&hproc, 0, FALSE, DUPLICATE_SAME_ACCESS);
ok(ret, "DuplicateHandle failed %lu\n", GetLastError());
@ -4403,6 +4405,7 @@ static void test_ReadProcessMemory(void)
ret = VirtualFree(ptr, 0, MEM_RELEASE);
ok(ret, "VirtualFree failed %lu\n", GetLastError());
CloseHandle(hproc);
free(buf);
}
START_TEST(virtual)

View file

@ -1785,27 +1785,12 @@ BOOL WINAPI GetXStateFeaturesMask( CONTEXT *context, DWORD64 *feature_mask )
* Firmware functions
***********************************************************************/
/***********************************************************************
* EnumSystemFirmwareTable (kernelbase.@)
*/
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
{
FIXME( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
return 0;
}
/***********************************************************************
* GetSystemFirmwareTable (kernelbase.@)
*/
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
static UINT get_firmware_table( DWORD provider, SYSTEM_FIRMWARE_TABLE_ACTION action, DWORD id,
void *buffer, DWORD size )
{
SYSTEM_FIRMWARE_TABLE_INFORMATION *info;
ULONG buffer_size = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer ) + size;
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, buffer_size )))
{
SetLastError( ERROR_OUTOFMEMORY );
@ -1813,7 +1798,7 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
}
info->ProviderSignature = provider;
info->Action = SystemFirmwareTable_Get;
info->Action = action;
info->TableID = id;
set_ntstatus( NtQuerySystemInformation( SystemFirmwareTableInformation,
@ -1824,3 +1809,23 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR
HeapFree( GetProcessHeap(), 0, info );
return buffer_size;
}
/***********************************************************************
* EnumSystemFirmwareTables (kernelbase.@)
*/
UINT WINAPI EnumSystemFirmwareTables( DWORD provider, void *buffer, DWORD size )
{
TRACE( "(0x%08lx, %p, %ld)\n", provider, buffer, size );
return get_firmware_table( provider, SystemFirmwareTable_Enumerate, 0, buffer, size );
}
/***********************************************************************
* GetSystemFirmwareTable (kernelbase.@)
*/
UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWORD size )
{
TRACE( "(0x%08lx, 0x%08lx, %p, %ld)\n", provider, id, buffer, size );
return get_firmware_table( provider, SystemFirmwareTable_Get, id, buffer, size );
}

View file

@ -1764,6 +1764,26 @@ HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
return call_builtin_function(dispex, func, dp, res, ei, caller);
}
static VARIANT_BOOL reset_builtin_func(DispatchEx *dispex, func_info_t *func)
{
func_obj_entry_t *entry;
if(!dispex->dynamic_data || !dispex->dynamic_data->func_disps ||
!dispex->dynamic_data->func_disps[func->func_disp_idx].func_obj)
return VARIANT_FALSE;
entry = dispex->dynamic_data->func_disps + func->func_disp_idx;
if(V_VT(&entry->val) == VT_DISPATCH &&
V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface)
return VARIANT_FALSE;
VariantClear(&entry->val);
V_VT(&entry->val) = VT_DISPATCH;
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
IDispatch_AddRef(V_DISPATCH(&entry->val));
return VARIANT_TRUE;
}
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
{
switch(get_dispid_type(id)) {
@ -1793,26 +1813,7 @@ HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
/* For builtin functions, we set their value to the original function. */
if(func->func_disp_idx >= 0) {
func_obj_entry_t *entry;
if(!This->dynamic_data || !This->dynamic_data->func_disps
|| !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
*success = VARIANT_FALSE;
return S_OK;
}
entry = This->dynamic_data->func_disps + func->func_disp_idx;
if(V_VT(&entry->val) == VT_DISPATCH
&& V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface) {
*success = VARIANT_FALSE;
return S_OK;
}
VariantClear(&entry->val);
V_VT(&entry->val) = VT_DISPATCH;
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IWineJSDispatchHost_iface;
IDispatch_AddRef(V_DISPATCH(&entry->val));
*success = VARIANT_TRUE;
*success = reset_builtin_func(This, func);
return S_OK;
}
*success = VARIANT_TRUE;
@ -2304,7 +2305,8 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
return E_NOTIMPL;
}
if(is_dynamic_dispid(id)) {
switch(get_dispid_type(id)) {
case DISPEXPROP_DYNAMIC: {
DWORD idx = id - DISPID_DYNPROP_0;
dynamic_prop_t *prop;
@ -2316,6 +2318,24 @@ static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id)
prop->flags |= DYNPROP_DELETED;
return S_OK;
}
case DISPEXPROP_BUILTIN: {
func_info_t *func;
HRESULT hres;
if(!ensure_real_info(dispex))
return E_OUTOFMEMORY;
hres = get_builtin_func(dispex->info, id, &func);
if(FAILED(hres))
return hres;
if(func->func_disp_idx >= 0)
reset_builtin_func(dispex, func);
return S_OK;
}
default:
break;
}
return S_OK;
}

View file

@ -48,6 +48,7 @@ IDispatch *script_parse_event(HTMLInnerWindow*,LPCWSTR);
HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*);
void update_browser_script_mode(GeckoBrowser*,IUri*);
BOOL find_global_prop(HTMLInnerWindow*,const WCHAR*,DWORD,ScriptHost**,DISPID*);
HRESULT global_prop_still_exists(HTMLInnerWindow*,global_prop_t*);
IDispatch *get_script_disp(ScriptHost*);
IActiveScriptSite *get_first_script_site(HTMLInnerWindow*);
void initialize_script_global(HTMLInnerWindow*);

View file

@ -3302,7 +3302,7 @@ static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_
This->global_prop_size = new_size;
}
This->global_props[This->global_prop_cnt].name = wcsdup(name);
This->global_props[This->global_prop_cnt].name = SysAllocString(name);
if(!This->global_props[This->global_prop_cnt].name)
return NULL;
@ -3324,8 +3324,10 @@ HRESULT search_window_props(HTMLInnerWindow *This, const WCHAR *name, DWORD grfd
for(i=0; i < This->global_prop_cnt; i++) {
/* FIXME: case sensitivity */
if(!wcscmp(This->global_props[i].name, name)) {
*pid = MSHTML_DISPID_CUSTOM_MIN+i;
return S_OK;
HRESULT hres = global_prop_still_exists(This, &This->global_props[i]);
if(hres == S_OK)
*pid = MSHTML_DISPID_CUSTOM_MIN + i;
return (hres == DISP_E_MEMBERNOTFOUND) ? DISP_E_UNKNOWNNAME : hres;
}
}
@ -3364,18 +3366,34 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IWineJSDispatchHost *iface, DISPID i
static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR bstrName, DWORD grfdex)
{
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
TRACE("(%p)->(%s %lx)\n", This, debugstr_w(bstrName), grfdex);
if(compat_mode < COMPAT_MODE_IE8) {
/* Not implemented by IE */
return E_NOTIMPL;
}
if(compat_mode == COMPAT_MODE_IE8)
return MSHTML_E_INVALID_ACTION;
return IWineJSDispatchHost_DeleteMemberByName(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, bstrName, grfdex);
}
static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IWineJSDispatchHost *iface, DISPID id)
{
HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
compat_mode_t compat_mode = dispex_compat_mode(&This->base.inner_window->event_target.dispex);
TRACE("(%p)->(%lx)\n", This, id);
if(compat_mode < COMPAT_MODE_IE8) {
/* Not implemented by IE */
return E_NOTIMPL;
}
if(compat_mode == COMPAT_MODE_IE8)
return MSHTML_E_INVALID_ACTION;
return IWineJSDispatchHost_DeleteMemberByDispID(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id);
}
@ -3763,7 +3781,7 @@ static void HTMLWindow_destructor(DispatchEx *dispex)
VariantClear(&This->performance);
for(i = 0; i < This->global_prop_cnt; i++)
free(This->global_props[i].name);
SysFreeString(This->global_props[i].name);
free(This->global_props);
if(This->mon)
@ -3910,6 +3928,9 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
case DISPATCH_PROPERTYPUT: {
DISPID dispex_id;
if(This->event_target.dispex.jsdisp)
return S_FALSE;
hres = dispex_get_dynid(&This->event_target.dispex, prop->name, TRUE, &dispex_id);
if(FAILED(hres))
return hres;
@ -3953,6 +3974,44 @@ HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags,
return hres;
}
static HRESULT HTMLWindow_delete(DispatchEx *dispex, DISPID id)
{
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN;
global_prop_t *prop;
HRESULT hres = S_OK;
if(idx >= This->global_prop_cnt)
return DISP_E_MEMBERNOTFOUND;
prop = This->global_props + idx;
switch(prop->type) {
case GLOBAL_SCRIPTVAR: {
IDispatchEx *iface;
IDispatch *disp;
disp = get_script_disp(prop->script_host);
if(!disp)
return E_UNEXPECTED;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&iface);
if(SUCCEEDED(hres)) {
hres = IDispatchEx_DeleteMemberByDispID(iface, prop->id);
IDispatchEx_Release(iface);
}else {
WARN("No IDispatchEx, so can't delete\n");
hres = S_OK;
}
IDispatch_Release(disp);
break;
}
default:
break;
}
return hres;
}
static HRESULT HTMLWindow_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid)
{
DWORD idx = (id == DISPID_STARTENUM) ? 0 : id - MSHTML_DISPID_CUSTOM_MIN + 1;
@ -4179,6 +4238,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
.lookup_dispid = HTMLWindow_lookup_dispid,
.find_dispid = HTMLWindow_find_dispid,
.invoke = HTMLWindow_invoke,
.delete = HTMLWindow_delete,
.next_dispid = HTMLWindow_next_dispid,
.get_prop_desc = HTMLWindow_get_prop_desc,
.get_script_global = HTMLWindow_get_script_global,

View file

@ -656,7 +656,7 @@ typedef enum {
typedef struct {
global_prop_type_t type;
WCHAR *name;
BSTR name;
ScriptHost *script_host;
DISPID id;
} global_prop_t;

View file

@ -85,6 +85,7 @@ struct ScriptHost {
SCRIPTSTATE script_state;
HTMLInnerWindow *window;
IDispatchEx *script_dispex;
GUID guid;
struct list entry;
@ -255,6 +256,18 @@ static BOOL init_script_engine(ScriptHost *script_host, IActiveScript *script)
if(is_second_init)
set_script_prop(first_host->script, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var);
}
if(IsEqualGUID(&script_host->guid, &CLSID_JScript)) {
IDispatch *script_disp;
hres = IActiveScript_GetScriptDispatch(script, NULL, &script_disp);
if(FAILED(hres))
WARN("GetScriptDispatch failed: %08lx\n", hres);
else {
IDispatch_QueryInterface(script_disp, &IID_IDispatchEx, (void**)&script_host->script_dispex);
IDispatch_Release(script_disp);
}
}
}else {
WARN("AddNamedItem failed: %08lx\n", hres);
}
@ -288,6 +301,8 @@ static void release_script_engine(ScriptHost *This)
unlink_ref(&This->parse);
}
if(This->script_dispex)
IDispatchEx_Release(This->script_dispex);
IActiveScript_Release(This->script);
This->script = NULL;
This->script_state = SCRIPTSTATE_UNINITIALIZED;
@ -1825,6 +1840,48 @@ BOOL find_global_prop(HTMLInnerWindow *window, const WCHAR *name, DWORD flags, S
return FALSE;
}
HRESULT global_prop_still_exists(HTMLInnerWindow *window, global_prop_t *prop)
{
HRESULT hres;
switch(prop->type) {
case GLOBAL_SCRIPTVAR: {
DWORD properties;
if(!prop->script_host->script)
return E_UNEXPECTED;
if(!prop->script_host->script_dispex)
return S_OK;
return IDispatchEx_GetMemberProperties(prop->script_host->script_dispex, prop->id, 0, &properties);
}
case GLOBAL_ELEMENTVAR: {
IHTMLElement *elem;
hres = IHTMLDocument3_getElementById(&window->doc->IHTMLDocument3_iface, prop->name, &elem);
if(FAILED(hres))
return hres;
if(!elem)
return DISP_E_MEMBERNOTFOUND;
IHTMLElement_Release(elem);
return S_OK;
}
case GLOBAL_FRAMEVAR: {
HTMLOuterWindow *frame;
hres = get_frame_by_name(window->base.outer_window, prop->name, FALSE, &frame);
if(FAILED(hres))
return hres;
return frame ? S_OK : DISP_E_MEMBERNOTFOUND;
}
default:
break;
}
return S_OK;
}
static BOOL is_jscript_available(void)
{
static BOOL available, checked;

View file

@ -1301,7 +1301,7 @@ sync_test("navigator", function() {
sync_test("delete_prop", function() {
var v = document.documentMode;
var obj = document.createElement("div"), r, obj2;
var obj = document.createElement("div"), r, obj2, func, prop;
obj.prop1 = true;
r = false;
@ -1317,6 +1317,40 @@ sync_test("delete_prop", function() {
ok(!r, "got an unexpected exception");
ok(!("prop1" in obj), "prop1 is still in obj");
/* builtin properties don't throw any exception, but are not really deleted */
r = (delete obj.tagName);
ok(r, "delete returned " + r);
ok("tagName" in obj, "tagName deleted from obj");
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
prop = obj.id;
r = (delete obj.id);
ok(r, "delete returned " + r);
ok("id" in obj, "id deleted from obj");
ok(obj.id === prop, "id = " + obj.id);
obj.id = "1234";
ok(obj.id === "1234", "id after set to 1234 = " + obj.id);
r = (delete obj.id);
ok(r, "delete returned " + r);
ok("id" in obj, "id deleted from obj");
ok(obj.id === "1234", "id = " + obj.id);
/* builtin functions get reset to their original values */
func = function() { }
prop = obj.setAttribute;
r = (delete obj.setAttribute);
ok(r, "delete returned " + r);
ok("setAttribute" in obj, "setAttribute deleted from obj");
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
obj.setAttribute = func;
ok(obj.setAttribute === func, "setAttribute after set to func = " + obj.setAttribute);
r = (delete obj.setAttribute);
ok(r, "delete returned " + r);
ok("setAttribute" in obj, "setAttribute deleted from obj");
ok(obj.setAttribute === prop, "setAttribute = " + obj.setAttribute);
/* again, this time prop1 does not exist */
r = false;
try {
@ -1326,7 +1360,6 @@ sync_test("delete_prop", function() {
}
if(v < 9) {
ok(r, "did not get an expected exception");
return;
}else {
ok(!r, "got an unexpected exception");
ok(!("prop1" in obj), "prop1 is still in obj");
@ -1337,12 +1370,6 @@ sync_test("delete_prop", function() {
ok("className" in obj, "className deleted from obj");
ok(obj.className === "", "className = " + obj.className);
/* builtin propertiles don't throw any exception, but are not really deleted */
r = (delete obj.tagName);
ok(r, "delete returned " + r);
ok("tagName" in obj, "tagName deleted from obj");
ok(obj.tagName === "DIV", "tagName = " + obj.tagName);
obj = document.querySelectorAll("*");
ok("0" in obj, "0 is not in obj");
obj2 = obj[0];
@ -1353,12 +1380,27 @@ sync_test("delete_prop", function() {
/* test window object and its global scope handling */
obj = window;
ok("encodeURIComponent" in obj, "encodeURIComponent not in obj");
try {
prop = window.encodeURIComponent;
r = (delete window.encodeURIComponent);
ok(v >= 9, "did not get an expect exception deleting encodeURIComponent");
ok(r, "delete returned " + r);
ok(!("encodeURIComponent" in obj), "encodeURIComponent is still in obj");
window.encodeURIComponent = prop;
}catch(ex) {
ok(v < 9, "expected exception deleting encodeURIComponent");
ok(ex.number === 0xa01bd - 0x80000000, "deleting encodeURIComponent threw " + ex.number);
ok("encodeURIComponent" in obj, "encodeURIComponent is not in obj");
}
obj.globalprop1 = true;
ok(globalprop1, "globalprop1 = " + globalprop1);
r = false;
try {
delete obj.globalprop1;
}catch(ex) {
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop1 threw " + ex.number);
r = true;
}
if(v < 9) {
@ -1374,13 +1416,13 @@ sync_test("delete_prop", function() {
try {
delete obj.globalprop2;
}catch(ex) {
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop2 threw " + ex.number);
r = true;
}
if(v < 9) {
ok(r, "did not get an expected globalprop2 exception");
}else {
ok(!r, "got an unexpected exception");
todo_wine.
ok(!("globalprop2" in obj), "globalprop2 is still in obj");
}
@ -1390,6 +1432,7 @@ sync_test("delete_prop", function() {
try {
delete globalprop3;
}catch(ex) {
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop3 threw " + ex.number);
r = true;
}
if(v < 9) {
@ -1404,8 +1447,88 @@ sync_test("delete_prop", function() {
ok(obj.globalprop4, "globalprop4 = " + globalprop4);
r = (delete globalprop4);
ok(r, "delete returned " + r);
todo_wine.
ok(!("globalprop4" in obj), "globalprop4 is still in obj");
globalprop5 = true;
ok(obj.globalprop5, "globalprop5 = " + globalprop5);
try {
r = (delete window.globalprop5);
ok(v >= 9, "did not get an expected exception deleting globalprop5");
ok(r, "delete returned " + r);
ok(!("globalprop5" in obj), "globalprop5 is still in obj");
}catch(ex) {
ok(v < 9, "expected exception deleting globalprop5");
ok(ex.number === 0xa01bd - 0x80000000, "deleting globalprop5 threw " + ex.number);
ok("globalprop5" in obj, "globalprop5 is not in obj");
}
document.body.innerHTML = '<div id="winetest"/>';
ok("winetest" in obj, "winetest not in obj");
try {
r = (delete window.winetest);
ok(v >= 9, "did not get an expected exception deleting winetest");
ok(r, "delete returned " + r);
}catch(ex) {
ok(v < 9, "expected exception deleting winetest");
ok(ex.number === 0xa01bd - 0x80000000, "deleting winetest threw " + ex.number);
}
ok("winetest" in obj, "winetest is not in obj");
document.body.innerHTML = "";
ok(!("winetest" in obj), "winetest is still in obj");
document.body.innerHTML = '<div id="foobar"/>';
ok("foobar" in obj, "foobar not in obj");
window.foobar = "1234";
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
document.body.innerHTML = "";
ok("foobar" in obj, "foobar is not in obj");
ok(obj.foobar === "1234", "foobar = " + obj.foobar);
try {
r = (delete window.foobar);
ok(v >= 9, "did not get an expected exception deleting foobar");
ok(r, "delete returned " + r);
ok(!("foobar" in obj), "foobar is still in obj");
}catch(ex) {
ok(v < 9, "expected exception deleting foobar");
ok(ex.number === 0xa01bd - 0x80000000, "deleting foobar threw " + ex.number);
ok("foobar" in obj, "foobar is not in obj");
}
document.body.innerHTML = '<div id="barfoo"/>';
ok("barfoo" in obj, "barfoo not in obj");
window.barfoo = "5678";
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
try {
r = (delete window.barfoo);
ok(v >= 9, "did not get an expected exception deleting barfoo");
ok(r, "delete returned " + r);
ok(obj.barfoo !== "5678", "barfoo is still 5678");
}catch(ex) {
ok(v < 9, "expected exception deleting barfoo");
ok(ex.number === 0xa01bd - 0x80000000, "deleting barfoo threw " + ex.number);
ok(obj.barfoo === "5678", "barfoo = " + obj.barfoo);
}
ok("barfoo" in obj, "barfoo is not in obj");
document.body.innerHTML = "";
if(v < 9)
ok("barfoo" in obj, "barfoo is not in obj");
else
ok(!("barfoo" in obj), "barfoo is still in obj");
document.body.innerHTML = '<iframe id="testwine"/>';
ok("testwine" in obj, "testwine not in obj");
try {
r = (delete window.testwine);
ok(v >= 9, "did not get an expected exception deleting testwine");
ok(r, "delete returned " + r);
}catch(ex) {
ok(v < 9, "expected exception deleting testwine");
ok(ex.number === 0xa01bd - 0x80000000, "deleting testwine threw " + ex.number);
}
ok("testwine" in obj, "testwine is not in obj");
document.body.innerHTML = "";
ok(!("testwine" in obj), "testwine is still in obj");
});
sync_test("detached arguments", function() {

View file

@ -400,6 +400,7 @@
@ stdcall -syscall NtSetInformationVirtualMemory(long long ptr ptr ptr long)
@ stdcall -syscall NtSetIntervalProfile(long long)
@ stdcall -syscall NtSetIoCompletion(ptr long long long long)
@ stdcall -syscall NtSetIoCompletionEx(ptr ptr long long long long)
@ stdcall -syscall NtSetLdtEntries(long int64 long int64)
# @ stub NtSetLowEventPair
# @ stub NtSetLowWaitHighEventPair
@ -459,6 +460,10 @@
# @ stub NtWriteRequestData
@ stdcall -syscall NtWriteVirtualMemory(long ptr ptr long ptr)
@ stdcall -syscall NtYieldExecution()
@ stdcall NtdllDefWindowProc_A(long long long long)
@ stdcall NtdllDefWindowProc_W(long long long long)
@ stdcall NtdllDialogWndProc_A(long long long long)
@ stdcall NtdllDialogWndProc_W(long long long long)
@ stub PfxFindPrefix
@ stub PfxInitialize
@ stub PfxInsertPrefix
@ -803,6 +808,7 @@
@ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr)
@ stdcall RtlInitializeGenericTableAvl(ptr ptr ptr ptr ptr)
@ stdcall RtlInitializeHandleTable(long long ptr)
@ stdcall RtlInitializeNtUserPfn(ptr long ptr long ptr long)
@ stub RtlInitializeRXact
# @ stub RtlInitializeRangeList
@ stdcall RtlInitializeResource(ptr)
@ -974,9 +980,11 @@
@ stub RtlRemoteCall
@ stdcall RtlRemoveVectoredContinueHandler(ptr)
@ stdcall RtlRemoveVectoredExceptionHandler(ptr)
@ stdcall RtlResetNtUserPfn()
@ stdcall RtlResetRtlTranslations(ptr)
@ cdecl RtlRestoreContext(ptr ptr)
@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error
@ stdcall RtlRetrieveNtUserPfn(ptr ptr ptr)
@ stub RtlRevertMemoryStream
@ stub RtlRunDecodeUnicodeString
@ stub RtlRunEncodeUnicodeString
@ -1453,6 +1461,7 @@
@ stdcall -private -syscall ZwSetInformationVirtualMemory(long long ptr ptr ptr long) NtSetInformationVirtualMemory
@ stdcall -private -syscall ZwSetIntervalProfile(long long) NtSetIntervalProfile
@ stdcall -private -syscall ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
@ stdcall -private -syscall ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
@ stdcall -private -syscall ZwSetLdtEntries(long int64 long int64) NtSetLdtEntries
# @ stub ZwSetLowEventPair
# @ stub ZwSetLowWaitHighEventPair

158
dlls/ntdll/ntsyscalls.h generated
View file

@ -203,48 +203,49 @@
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 24 ) \
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 8 ) \
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 20 ) \
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 24 ) \
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 12 ) \
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 12 ) \
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 8 ) \
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 8 ) \
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 28 ) \
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 12 ) \
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 24 ) \
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 20 ) \
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 4 ) \
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 16 ) \
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 4 ) \
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 8 ) \
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 24 ) \
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 8 ) \
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 8 ) \
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 8 ) \
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 24 ) \
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 4 ) \
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 4 ) \
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 20 ) \
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 16 ) \
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 8 ) \
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 12 ) \
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 8 ) \
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 16 ) \
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 16 ) \
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 20 ) \
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 12 ) \
SYSCALL_ENTRY( 0x00e8, NtWow64AllocateVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00e9, NtWow64GetNativeSystemInformation, 16 ) \
SYSCALL_ENTRY( 0x00ea, NtWow64IsProcessorFeaturePresent, 4 ) \
SYSCALL_ENTRY( 0x00eb, NtWow64QueryInformationProcess64, 20 ) \
SYSCALL_ENTRY( 0x00ec, NtWow64ReadVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00ed, NtWow64WriteVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00ee, NtWriteFile, 36 ) \
SYSCALL_ENTRY( 0x00ef, NtWriteFileGather, 36 ) \
SYSCALL_ENTRY( 0x00f0, NtWriteVirtualMemory, 20 ) \
SYSCALL_ENTRY( 0x00f1, NtYieldExecution, 0 ) \
SYSCALL_ENTRY( 0x00f2, wine_nt_to_unix_file_name, 16 ) \
SYSCALL_ENTRY( 0x00f3, wine_unix_to_nt_file_name, 12 )
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 24 ) \
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 24 ) \
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 12 ) \
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 12 ) \
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 8 ) \
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 8 ) \
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 28 ) \
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 12 ) \
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 24 ) \
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 20 ) \
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 4 ) \
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 16 ) \
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 4 ) \
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 8 ) \
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 24 ) \
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 8 ) \
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 8 ) \
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 8 ) \
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 24 ) \
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 4 ) \
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 4 ) \
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 20 ) \
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 16 ) \
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 8 ) \
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 12 ) \
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 8 ) \
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 16 ) \
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 16 ) \
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 20 ) \
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 12 ) \
SYSCALL_ENTRY( 0x00e9, NtWow64AllocateVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00ea, NtWow64GetNativeSystemInformation, 16 ) \
SYSCALL_ENTRY( 0x00eb, NtWow64IsProcessorFeaturePresent, 4 ) \
SYSCALL_ENTRY( 0x00ec, NtWow64QueryInformationProcess64, 20 ) \
SYSCALL_ENTRY( 0x00ed, NtWow64ReadVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00ee, NtWow64WriteVirtualMemory64, 28 ) \
SYSCALL_ENTRY( 0x00ef, NtWriteFile, 36 ) \
SYSCALL_ENTRY( 0x00f0, NtWriteFileGather, 36 ) \
SYSCALL_ENTRY( 0x00f1, NtWriteVirtualMemory, 20 ) \
SYSCALL_ENTRY( 0x00f2, NtYieldExecution, 0 ) \
SYSCALL_ENTRY( 0x00f3, wine_nt_to_unix_file_name, 16 ) \
SYSCALL_ENTRY( 0x00f4, wine_unix_to_nt_file_name, 12 )
#define ALL_SYSCALLS64 \
SYSCALL_ENTRY( 0x0000, NtAcceptConnectPort, 48 ) \
@ -449,39 +450,40 @@
SYSCALL_ENTRY( 0x00c7, NtSetInformationVirtualMemory, 48 ) \
SYSCALL_ENTRY( 0x00c8, NtSetIntervalProfile, 16 ) \
SYSCALL_ENTRY( 0x00c9, NtSetIoCompletion, 40 ) \
SYSCALL_ENTRY( 0x00ca, NtSetLdtEntries, 32 ) \
SYSCALL_ENTRY( 0x00cb, NtSetSecurityObject, 24 ) \
SYSCALL_ENTRY( 0x00cc, NtSetSystemInformation, 24 ) \
SYSCALL_ENTRY( 0x00cd, NtSetSystemTime, 16 ) \
SYSCALL_ENTRY( 0x00ce, NtSetThreadExecutionState, 16 ) \
SYSCALL_ENTRY( 0x00cf, NtSetTimer, 56 ) \
SYSCALL_ENTRY( 0x00d0, NtSetTimerResolution, 24 ) \
SYSCALL_ENTRY( 0x00d1, NtSetValueKey, 48 ) \
SYSCALL_ENTRY( 0x00d2, NtSetVolumeInformationFile, 40 ) \
SYSCALL_ENTRY( 0x00d3, NtShutdownSystem, 8 ) \
SYSCALL_ENTRY( 0x00d4, NtSignalAndWaitForSingleObject, 32 ) \
SYSCALL_ENTRY( 0x00d5, NtSuspendProcess, 8 ) \
SYSCALL_ENTRY( 0x00d6, NtSuspendThread, 16 ) \
SYSCALL_ENTRY( 0x00d7, NtSystemDebugControl, 48 ) \
SYSCALL_ENTRY( 0x00d8, NtTerminateJobObject, 16 ) \
SYSCALL_ENTRY( 0x00d9, NtTerminateProcess, 16 ) \
SYSCALL_ENTRY( 0x00da, NtTerminateThread, 16 ) \
SYSCALL_ENTRY( 0x00db, NtTestAlert, 0 ) \
SYSCALL_ENTRY( 0x00dc, NtTraceControl, 48 ) \
SYSCALL_ENTRY( 0x00dd, NtUnloadDriver, 8 ) \
SYSCALL_ENTRY( 0x00de, NtUnloadKey, 8 ) \
SYSCALL_ENTRY( 0x00df, NtUnlockFile, 40 ) \
SYSCALL_ENTRY( 0x00e0, NtUnlockVirtualMemory, 32 ) \
SYSCALL_ENTRY( 0x00e1, NtUnmapViewOfSection, 16 ) \
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSectionEx, 24 ) \
SYSCALL_ENTRY( 0x00e3, NtWaitForAlertByThreadId, 16 ) \
SYSCALL_ENTRY( 0x00e4, NtWaitForDebugEvent, 32 ) \
SYSCALL_ENTRY( 0x00e5, NtWaitForKeyedEvent, 32 ) \
SYSCALL_ENTRY( 0x00e6, NtWaitForMultipleObjects, 40 ) \
SYSCALL_ENTRY( 0x00e7, NtWaitForSingleObject, 24 ) \
SYSCALL_ENTRY( 0x00e8, NtWriteFile, 72 ) \
SYSCALL_ENTRY( 0x00e9, NtWriteFileGather, 72 ) \
SYSCALL_ENTRY( 0x00ea, NtWriteVirtualMemory, 40 ) \
SYSCALL_ENTRY( 0x00eb, NtYieldExecution, 0 ) \
SYSCALL_ENTRY( 0x00ec, wine_nt_to_unix_file_name, 32 ) \
SYSCALL_ENTRY( 0x00ed, wine_unix_to_nt_file_name, 24 )
SYSCALL_ENTRY( 0x00ca, NtSetIoCompletionEx, 48 ) \
SYSCALL_ENTRY( 0x00cb, NtSetLdtEntries, 32 ) \
SYSCALL_ENTRY( 0x00cc, NtSetSecurityObject, 24 ) \
SYSCALL_ENTRY( 0x00cd, NtSetSystemInformation, 24 ) \
SYSCALL_ENTRY( 0x00ce, NtSetSystemTime, 16 ) \
SYSCALL_ENTRY( 0x00cf, NtSetThreadExecutionState, 16 ) \
SYSCALL_ENTRY( 0x00d0, NtSetTimer, 56 ) \
SYSCALL_ENTRY( 0x00d1, NtSetTimerResolution, 24 ) \
SYSCALL_ENTRY( 0x00d2, NtSetValueKey, 48 ) \
SYSCALL_ENTRY( 0x00d3, NtSetVolumeInformationFile, 40 ) \
SYSCALL_ENTRY( 0x00d4, NtShutdownSystem, 8 ) \
SYSCALL_ENTRY( 0x00d5, NtSignalAndWaitForSingleObject, 32 ) \
SYSCALL_ENTRY( 0x00d6, NtSuspendProcess, 8 ) \
SYSCALL_ENTRY( 0x00d7, NtSuspendThread, 16 ) \
SYSCALL_ENTRY( 0x00d8, NtSystemDebugControl, 48 ) \
SYSCALL_ENTRY( 0x00d9, NtTerminateJobObject, 16 ) \
SYSCALL_ENTRY( 0x00da, NtTerminateProcess, 16 ) \
SYSCALL_ENTRY( 0x00db, NtTerminateThread, 16 ) \
SYSCALL_ENTRY( 0x00dc, NtTestAlert, 0 ) \
SYSCALL_ENTRY( 0x00dd, NtTraceControl, 48 ) \
SYSCALL_ENTRY( 0x00de, NtUnloadDriver, 8 ) \
SYSCALL_ENTRY( 0x00df, NtUnloadKey, 8 ) \
SYSCALL_ENTRY( 0x00e0, NtUnlockFile, 40 ) \
SYSCALL_ENTRY( 0x00e1, NtUnlockVirtualMemory, 32 ) \
SYSCALL_ENTRY( 0x00e2, NtUnmapViewOfSection, 16 ) \
SYSCALL_ENTRY( 0x00e3, NtUnmapViewOfSectionEx, 24 ) \
SYSCALL_ENTRY( 0x00e4, NtWaitForAlertByThreadId, 16 ) \
SYSCALL_ENTRY( 0x00e5, NtWaitForDebugEvent, 32 ) \
SYSCALL_ENTRY( 0x00e6, NtWaitForKeyedEvent, 32 ) \
SYSCALL_ENTRY( 0x00e7, NtWaitForMultipleObjects, 40 ) \
SYSCALL_ENTRY( 0x00e8, NtWaitForSingleObject, 24 ) \
SYSCALL_ENTRY( 0x00e9, NtWriteFile, 72 ) \
SYSCALL_ENTRY( 0x00ea, NtWriteFileGather, 72 ) \
SYSCALL_ENTRY( 0x00eb, NtWriteVirtualMemory, 40 ) \
SYSCALL_ENTRY( 0x00ec, NtYieldExecution, 0 ) \
SYSCALL_ENTRY( 0x00ed, wine_nt_to_unix_file_name, 32 ) \
SYSCALL_ENTRY( 0x00ee, wine_unix_to_nt_file_name, 24 )

View file

@ -28,7 +28,9 @@
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "ntuser.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "ntdll_misc.h"
@ -167,6 +169,73 @@ NTSTATUS WINAPI vDbgPrintExWithPrefix( LPCSTR prefix, ULONG id, ULONG level, LPC
return STATUS_SUCCESS;
}
static struct ntuser_client_procs_table user_procs;
#define DEFINE_USER_FUNC(name,ptr) \
LRESULT WINAPI name( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { return (ptr)( hwnd, msg, wp, lp ); }
#define USER_FUNC(name,proc) \
DEFINE_USER_FUNC( Ntdll##name##_A, user_procs.A[proc][0] ) \
DEFINE_USER_FUNC( Ntdll##name##_W, user_procs.W[proc][0] )
ALL_NTUSER_CLIENT_PROCS
#undef USER_FUNC
static const struct ntuser_client_procs_table user_funcs =
{
#define USER_FUNC(name,proc) .A[proc] = { Ntdll##name##_A }, .W[proc] = { Ntdll##name##_W },
ALL_NTUSER_CLIENT_PROCS
#undef USER_FUNC
};
static BOOL user_procs_init_done;
/***********************************************************************
* RtlInitializeNtUserPfn (NTDLL.@)
*/
NTSTATUS WINAPI RtlInitializeNtUserPfn( const void *client_procsA, ULONG procsA_size,
const void *client_procsW, ULONG procsW_size,
const void *client_workers, ULONG workers_size )
{
if (procsA_size % sizeof(ntuser_client_func_ptr) || procsA_size > sizeof(user_procs.A) ||
procsW_size % sizeof(ntuser_client_func_ptr) || procsW_size > sizeof(user_procs.W) ||
workers_size % sizeof(ntuser_client_func_ptr) || workers_size > sizeof(user_procs.workers))
return STATUS_INVALID_PARAMETER;
if (user_procs_init_done) return STATUS_INVALID_PARAMETER;
memcpy( user_procs.A, client_procsA, procsA_size );
memcpy( user_procs.W, client_procsW, procsW_size );
memcpy( user_procs.workers, client_workers, workers_size );
user_procs_init_done = TRUE;
return STATUS_SUCCESS;
}
/***********************************************************************
* RtlRetrieveNtUserPfn (NTDLL.@)
*/
NTSTATUS WINAPI RtlRetrieveNtUserPfn( const void **client_procsA,
const void **client_procsW,
const void **client_workers )
{
if (!user_procs_init_done) return STATUS_INVALID_PARAMETER;
*client_procsA = user_funcs.A;
*client_procsW = user_funcs.W;
*client_workers = user_funcs.workers;
return STATUS_SUCCESS;
}
/***********************************************************************
* RtlResetNtUserPfn (NTDLL.@)
*/
NTSTATUS WINAPI RtlResetNtUserPfn(void)
{
if (!user_procs_init_done) return STATUS_INVALID_PARAMETER;
user_procs_init_done = FALSE;
memset( &user_procs, 0, sizeof(user_procs) );
return STATUS_SUCCESS;
}
/******************************************************************************
* RtlInitializeGenericTable [NTDLL.@]
*/

View file

@ -443,6 +443,7 @@ DEFINE_SYSCALL(NtSetInformationToken, (HANDLE token, TOKEN_INFORMATION_CLASS cla
DEFINE_SYSCALL(NtSetInformationVirtualMemory, (HANDLE process, VIRTUAL_MEMORY_INFORMATION_CLASS info_class, ULONG_PTR count, PMEMORY_RANGE_ENTRY addresses, PVOID ptr, ULONG size))
DEFINE_SYSCALL(NtSetIntervalProfile, (ULONG interval, KPROFILE_SOURCE source))
DEFINE_SYSCALL(NtSetIoCompletion, (HANDLE handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
DEFINE_SYSCALL(NtSetIoCompletionEx, (HANDLE completion_handle, HANDLE completion_reserve_handle, ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count))
DEFINE_SYSCALL(NtSetLdtEntries, (ULONG sel1, LDT_ENTRY entry1, ULONG sel2, LDT_ENTRY entry2))
DEFINE_SYSCALL(NtSetSecurityObject, (HANDLE handle, SECURITY_INFORMATION info, PSECURITY_DESCRIPTOR descr))
DEFINE_SYSCALL(NtSetSystemInformation, (SYSTEM_INFORMATION_CLASS class, void *info, ULONG length))

View file

@ -51,6 +51,7 @@ static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * );
static NTSTATUS (WINAPI *pNtAllocateReserveObject)( HANDLE *, const OBJECT_ATTRIBUTES *, MEMORY_RESERVE_OBJECT_TYPE );
static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
ULONG, ULONG, ULONG, PLARGE_INTEGER );
static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
@ -76,6 +77,7 @@ static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION
static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER);
static NTSTATUS (WINAPI *pNtRemoveIoCompletionEx)(HANDLE,FILE_IO_COMPLETION_INFORMATION*,ULONG,ULONG*,LARGE_INTEGER*,BOOLEAN);
static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
static NTSTATUS (WINAPI *pNtSetIoCompletionEx)(HANDLE, HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
@ -5932,6 +5934,62 @@ static void test_reparse_points(void)
CloseHandle( handle );
}
static void test_set_io_completion_ex(void)
{
HANDLE completion, completion_reserve, apc_reserve;
LARGE_INTEGER timeout = {{0}};
IO_STATUS_BLOCK iosb;
ULONG_PTR key, value;
NTSTATUS status;
SIZE_T size = 3;
if (!pNtSetIoCompletionEx || !pNtAllocateReserveObject)
{
win_skip("NtSetIoCompletionEx() or NtAllocateReserveObject() is unavailable.\n");
return;
}
if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
status = pNtAllocateReserveObject(&completion_reserve, NULL, MemoryReserveObjectTypeIoCompletion);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
status = pNtAllocateReserveObject(&apc_reserve, NULL, MemoryReserveObjectTypeUserApc);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
/* Parameter checks */
status = pNtSetIoCompletionEx(NULL, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
status = pNtSetIoCompletionEx(INVALID_HANDLE_VALUE, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
status = pNtSetIoCompletionEx(completion, NULL, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
status = pNtSetIoCompletionEx(completion, INVALID_HANDLE_VALUE, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
status = pNtSetIoCompletionEx(completion, apc_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
/* Normal call */
status = pNtSetIoCompletionEx(completion, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
status = pNtRemoveIoCompletion(completion, &key, &value, &iosb, &timeout);
ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
ok(key == CKEY_FIRST, "Invalid completion key: %#Ix\n", key);
ok(iosb.Information == size, "Invalid iosb.Information: %Iu\n", iosb.Information);
ok(iosb.Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#lx\n", iosb.Status);
ok(value == CVALUE_FIRST, "Invalid completion value: %#Ix\n", value);
CloseHandle(apc_reserve);
CloseHandle(completion_reserve);
CloseHandle(completion);
}
START_TEST(file)
{
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
@ -5949,6 +6007,7 @@ START_TEST(file)
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx");
pNtAllocateReserveObject= (void *)GetProcAddress(hntdll, "NtAllocateReserveObject");
pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
@ -5965,6 +6024,7 @@ START_TEST(file)
pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion");
pNtRemoveIoCompletionEx = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletionEx");
pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion");
pNtSetIoCompletionEx = (void *)GetProcAddress(hntdll, "NtSetIoCompletionEx");
pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile");
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
@ -5983,6 +6043,7 @@ START_TEST(file)
append_file_test();
nt_mailslot_test();
test_set_io_completion();
test_set_io_completion_ex();
test_file_io_completion();
test_file_basic_information();
test_file_all_information();

View file

@ -58,6 +58,8 @@ typedef struct _RTL_HANDLE_TABLE
#endif
static BOOL is_win64 = (sizeof(void *) > sizeof(int));
/* avoid #include <winsock2.h> */
#undef htons
#ifdef WORDS_BIGENDIAN
@ -111,7 +113,13 @@ static VOID (WINAPI *pRtlGetDeviceFamilyInfoEnum)(ULONGLONG *,DWORD *,DWORD
static void (WINAPI *pRtlRbInsertNodeEx)(RTL_RB_TREE *, RTL_BALANCED_NODE *, BOOLEAN, RTL_BALANCED_NODE *);
static void (WINAPI *pRtlRbRemoveNode)(RTL_RB_TREE *, RTL_BALANCED_NODE *);
static DWORD (WINAPI *pRtlConvertDeviceFamilyInfoToString)(DWORD *, DWORD *, WCHAR *, WCHAR *);
static NTSTATUS (WINAPI *pRtlInitializeNtUserPfn)( const UINT64 *client_procsA, ULONG procsA_size,
const UINT64 *client_procsW, ULONG procsW_size,
const void *client_workers, ULONG workers_size );
static NTSTATUS (WINAPI *pRtlRetrieveNtUserPfn)( const UINT64 **client_procsA,
const UINT64 **client_procsW,
const UINT64 **client_workers );
static NTSTATUS (WINAPI *pRtlResetNtUserPfn)(void);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@ -159,6 +167,9 @@ static void InitFunctionPtrs(void)
pRtlRbInsertNodeEx = (void *)GetProcAddress(hntdll, "RtlRbInsertNodeEx");
pRtlRbRemoveNode = (void *)GetProcAddress(hntdll, "RtlRbRemoveNode");
pRtlConvertDeviceFamilyInfoToString = (void *)GetProcAddress(hntdll, "RtlConvertDeviceFamilyInfoToString");
pRtlInitializeNtUserPfn = (void *)GetProcAddress(hntdll, "RtlInitializeNtUserPfn");
pRtlRetrieveNtUserPfn = (void *)GetProcAddress(hntdll, "RtlRetrieveNtUserPfn");
pRtlResetNtUserPfn = (void *)GetProcAddress(hntdll, "RtlResetNtUserPfn");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@ -3992,6 +4003,70 @@ static void test_RtlConvertDeviceFamilyInfoToString(void)
ok(!wcscmp(device_form, L"Unknown"), "Got unexpected %s.\n", wine_dbgstr_w(device_form));
}
static void test_user_procs(void)
{
UINT64 ptrs[32], dummy[32] = { 0 };
NTSTATUS status;
const UINT64 *ptr_A, *ptr_W, *ptr_workers;
ULONG size_A, size_W, size_workers;
if (!pRtlRetrieveNtUserPfn || !pRtlInitializeNtUserPfn)
{
win_skip( "user procs not supported\n" );
return;
}
status = pRtlRetrieveNtUserPfn( &ptr_A, &ptr_W, &ptr_workers );
ok( !status || broken(!is_win64 && status == STATUS_INVALID_PARAMETER), /* <= win8 32-bit */
"RtlRetrieveNtUserPfn failed %lx\n", status );
if (status) return;
/* assume that the tables are consecutive */
size_A = (ptr_W - ptr_A) * sizeof(UINT64);
size_W = (ptr_workers - ptr_W) * sizeof(UINT64);
ok( size_A > 0x80 && size_A < 0x100, "unexpected size for %p %p %p\n", ptr_A, ptr_W, ptr_workers );
ok( size_W == size_A, "unexpected size for %p %p %p\n", ptr_A, ptr_W, ptr_workers );
memcpy( ptrs, ptr_A, size_A );
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, 0 );
ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
if (!pRtlResetNtUserPfn)
{
win_skip( "RtlResetNtUserPfn not supported\n" );
return;
}
status = pRtlResetNtUserPfn();
ok( !status, "RtlResetNtUserPfn failed %lx\n", status );
ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by reset\n" );
/* can't do anything after reset except set them again */
status = pRtlResetNtUserPfn();
ok( status == STATUS_INVALID_PARAMETER, "RtlResetNtUserPfn failed %lx\n", status );
status = pRtlRetrieveNtUserPfn( &ptr_A, &ptr_W, &ptr_workers );
ok( status == STATUS_INVALID_PARAMETER, "RtlRetrieveNtUserPfn failed %lx\n", status );
for (size_workers = 0x100; size_workers > 0; size_workers--)
{
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
if (!status) break;
ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
}
trace( "got sizes %lx %lx %lx\n", size_A, size_W, size_workers );
if (!size_workers) return; /* something went wrong */
ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
/* can't set twice without a reset */
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
status = pRtlResetNtUserPfn();
ok( !status, "RtlResetNtUserPfn failed %lx\n", status );
status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
ok( !status, "RtlInitializeNtUserPfn failed %lx\n", status );
ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
}
START_TEST(rtl)
{
InitFunctionPtrs();
@ -4043,4 +4118,5 @@ START_TEST(rtl)
test_RtlGetDeviceFamilyInfoEnum();
test_RtlConvertDeviceFamilyInfoToString();
test_rb_tree();
test_user_procs();
}

View file

@ -354,7 +354,7 @@ static int wait_select_reply( void *cookie )
/***********************************************************************
* invoke_user_apc
*/
static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTATUS status )
static NTSTATUS invoke_user_apc( CONTEXT *context, const struct user_apc *apc, NTSTATUS status )
{
return call_user_apc_dispatcher( context, apc->args[0], apc->args[1], apc->args[2],
wine_server_get_ptr( apc->func ), status );
@ -364,7 +364,7 @@ static NTSTATUS invoke_user_apc( CONTEXT *context, const user_apc_t *apc, NTSTAT
/***********************************************************************
* invoke_system_apc
*/
static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOOL self )
static void invoke_system_apc( const union apc_call *call, union apc_result *result, BOOL self )
{
SIZE_T size, bits;
void *addr;
@ -688,19 +688,19 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
* server_select
*/
unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc )
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc )
{
unsigned int ret;
int cookie;
obj_handle_t apc_handle = 0;
BOOL suspend_context = !!context;
apc_result_t result;
union apc_result result;
sigset_t old_set;
int signaled;
data_size_t reply_size;
struct
{
apc_call_t call;
union apc_call call;
context_t context[2];
} reply_data;
@ -768,7 +768,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
{
timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE;
unsigned int ret;
user_apc_t apc;
struct user_apc apc;
if (abs_timeout < 0)
{
@ -794,7 +794,7 @@ unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT f
*/
NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
{
user_apc_t apc;
struct user_apc apc;
NTSTATUS status;
if (alertable)
@ -811,7 +811,7 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
*/
NTSTATUS WINAPI NtTestAlert(void)
{
user_apc_t apc;
struct user_apc apc;
NTSTATUS status;
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, &apc );
@ -823,7 +823,7 @@ NTSTATUS WINAPI NtTestAlert(void)
/***********************************************************************
* server_queue_process_apc
*/
unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call, apc_result_t *result )
unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call, union apc_result *result )
{
for (;;)
{
@ -1759,8 +1759,8 @@ NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source, HANDLE
if ((options & DUPLICATE_CLOSE_SOURCE) && source_process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );

View file

@ -1992,6 +1992,35 @@ NTSTATUS WINAPI NtSetIoCompletion( HANDLE handle, ULONG_PTR key, ULONG_PTR value
return ret;
}
/***********************************************************************
* NtSetIoCompletionEx (NTDLL.@)
*
* completion_reserve_handle is a handle allocated by NtAllocateReserveObject() for pre-allocating
* memory for completion objects to deal with low-memory situations. It's not in use for now.
*/
NTSTATUS WINAPI NtSetIoCompletionEx( HANDLE completion_handle, HANDLE completion_reserve_handle,
ULONG_PTR key, ULONG_PTR value, NTSTATUS status, SIZE_T count )
{
unsigned int ret;
TRACE( "(%p, %p, %lx, %lx, %x, %lx)\n", completion_handle, completion_reserve_handle,
key, value, (int)status, count );
if (!completion_reserve_handle) return STATUS_INVALID_HANDLE;
SERVER_START_REQ( add_completion )
{
req->handle = wine_server_obj_handle( completion_handle );
req->ckey = key;
req->cvalue = value;
req->status = status;
req->information = count;
req->reserve_handle = wine_server_obj_handle( completion_reserve_handle );
ret = wine_server_call( req );
}
SERVER_END_REQ;
return ret;
}
/***********************************************************************
* NtRemoveIoCompletion (NTDLL.@)

View file

@ -2131,6 +2131,26 @@ static struct smbios_prologue *create_smbios_data(void)
#endif
static NTSTATUS enum_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
ULONG *required_len )
{
ULONG len;
switch (sfti->ProviderSignature)
{
case RSMB:
sfti->TableBufferLength = len = sizeof(UINT);
*required_len = offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer[len] );
if (available_len < *required_len) return STATUS_BUFFER_TOO_SMALL;
*(UINT *)sfti->TableBuffer = 0;
return STATUS_SUCCESS;
default:
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION provider %08x\n", (unsigned int)sfti->ProviderSignature);
return STATUS_NOT_IMPLEMENTED;
}
}
static NTSTATUS get_firmware_info( SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, ULONG available_len,
ULONG *required_len )
{
@ -3459,14 +3479,17 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
len = 0;
switch (sfti->Action)
{
case SystemFirmwareTable_Enumerate:
ret = enum_firmware_info(sfti, size, &len);
break;
case SystemFirmwareTable_Get:
ret = get_firmware_info(sfti, size, &len);
break;
default:
len = 0;
ret = STATUS_NOT_IMPLEMENTED;
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION action %d\n", sfti->Action);
}

View file

@ -1323,8 +1323,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -1712,7 +1712,7 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
ULONG_PTR arg2, ULONG_PTR arg3 )
{
unsigned int ret;
apc_call_t call;
union apc_call call;
SERVER_START_REQ( queue_apc )
{

View file

@ -209,11 +209,11 @@ extern unsigned int server_call_unlocked( void *req_ptr );
extern void server_enter_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
extern void server_leave_uninterrupted_section( pthread_mutex_t *mutex, sigset_t *sigset );
extern unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT flags,
timeout_t abs_timeout, context_t *context, user_apc_t *user_apc );
timeout_t abs_timeout, context_t *context, struct user_apc *user_apc );
extern unsigned int server_wait( const select_op_t *select_op, data_size_t size, UINT flags,
const LARGE_INTEGER *timeout );
extern unsigned int server_queue_process_apc( HANDLE process, const apc_call_t *call,
apc_result_t *result );
extern unsigned int server_queue_process_apc( HANDLE process, const union apc_call *call,
union apc_result *result );
extern int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
int *needs_close, enum server_fd_type *type, unsigned int *options );
extern void wine_server_send_fd( int fd );
@ -436,10 +436,10 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
if (!process_exiting) pthread_mutex_unlock( mutex );
}
static inline async_data_t server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
static inline struct async_data server_async( HANDLE handle, struct async_fileio *user, HANDLE event,
PIO_APC_ROUTINE apc, void *apc_context, client_ptr_t iosb )
{
async_data_t async;
struct async_data async;
async.handle = wine_server_obj_handle( handle );
async.user = wine_server_client_ptr( user );
async.iosb = iosb;

View file

@ -4671,8 +4671,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
unsigned int status;
memset( &call, 0, sizeof(call) );
@ -4817,8 +4817,8 @@ NTSTATUS WINAPI NtAllocateVirtualMemoryEx( HANDLE process, PVOID *ret, SIZE_T *s
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -4864,8 +4864,8 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -4962,8 +4962,8 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5146,8 +5146,8 @@ static unsigned int get_basic_memory_info( HANDLE process, LPCVOID addr,
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5559,8 +5559,8 @@ NTSTATUS WINAPI NtLockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size,
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5596,8 +5596,8 @@ NTSTATUS WINAPI NtUnlockVirtualMemory( HANDLE process, PVOID *addr, SIZE_T *size
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5672,8 +5672,8 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5744,8 +5744,8 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5788,8 +5788,8 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -5973,8 +5973,8 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );
@ -6359,8 +6359,8 @@ NTSTATUS WINAPI NtWow64AllocateVirtualMemory64( HANDLE process, ULONG64 *ret, UL
if (process != NtCurrentProcess())
{
apc_call_t call;
apc_result_t result;
union apc_call call;
union apc_result result;
memset( &call, 0, sizeof(call) );

View file

@ -1525,6 +1525,7 @@
@ stdcall -private ZwSetInformationToken(long long ptr long) NtSetInformationToken
@ stdcall -private ZwSetIntervalProfile(long long) NtSetIntervalProfile
@ stdcall -private ZwSetIoCompletion(ptr long long long long) NtSetIoCompletion
@ stdcall -private ZwSetIoCompletionEx(ptr ptr long long long long) NtSetIoCompletionEx
@ stdcall -private ZwSetSecurityObject(long long ptr) NtSetSecurityObject
@ stdcall -private ZwSetSystemInformation(long ptr long) NtSetSystemInformation
@ stdcall -private ZwSetSystemTime(ptr ptr) NtSetSystemTime

File diff suppressed because it is too large Load diff

View file

@ -525,11 +525,19 @@ void find_domain_name(const WCHAR *host, DWORD host_len,
return;
}
} else if(last_tld-host < 3)
/* Anything less than 3 characters is considered part
{
/* Anything less than 3 ASCII characters is considered part
* of the TLD name.
* Ex: ak.uk -> Has no domain name.
*/
return;
for(p = host; p < last_tld; p++) {
if(!is_ascii(*p))
break;
}
if(p == last_tld)
return;
}
/* Otherwise the domain name is the whole host name. */
*domain_start = 0;
@ -1339,11 +1347,21 @@ static BOOL parse_reg_name(const WCHAR **ptr, parse_data *data, DWORD extras) {
/* If the host is empty, then it's an unknown host type. */
if(data->host_len == 0 || is_res)
data->host_type = Uri_HOST_UNKNOWN;
else
else {
unsigned int i;
data->host_type = Uri_HOST_DNS;
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld\n", ptr, data, extras,
debugstr_wn(data->host, data->host_len), data->host_len);
for(i = 0; i < data->host_len; i++) {
if(!is_ascii(data->host[i])) {
data->host_type = Uri_HOST_IDN;
break;
}
}
}
TRACE("(%p %p %lx): Parsed reg-name. host=%s len=%ld type=%d\n", ptr, data, extras,
debugstr_wn(data->host, data->host_len), data->host_len, data->host_type);
return TRUE;
}
@ -2276,6 +2294,13 @@ static BOOL canonicalize_host(const parse_data *data, Uri *uri, DWORD flags, BOO
uri->host_type = Uri_HOST_IPV6;
break;
case Uri_HOST_IDN:
uri->host_type = Uri_HOST_IDN;
if(!canonicalize_reg_name(data, uri, flags, computeOnly))
return FALSE;
break;
case Uri_HOST_UNKNOWN:
if(data->host_len > 0 || data->scheme_type != URL_SCHEME_FILE) {
uri->host_start = uri->canon_len;
@ -3873,17 +3898,37 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
return E_INVALIDARG;
}
/* Don't have support for flags yet. */
if(dwFlags) {
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pbstrProperty, dwFlags);
return E_NOTIMPL;
}
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
&& dwFlags != Uri_DISPLAY_IDN_HOST)
return E_INVALIDARG;
if((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))
return E_INVALIDARG;
switch(uriProp) {
case Uri_PROPERTY_ABSOLUTE_URI:
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
*pbstrProperty = SysAllocStringLen(NULL, 0);
hres = S_FALSE;
}
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
else if (dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
unsigned int punycode_host_len;
punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->host_len+punycode_host_len);
hres = S_OK;
if(*pbstrProperty) {
memcpy(*pbstrProperty, This->canon_uri, This->host_start*sizeof(WCHAR));
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty+This->host_start, punycode_host_len);
memcpy(*pbstrProperty+This->host_start+punycode_host_len,
This->canon_uri+This->host_start+This->host_len,
(This->canon_len-This->host_start-This->host_len)*sizeof(WCHAR));
}
} else {
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
if(This->userinfo_len == 0) {
@ -3944,18 +3989,32 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
* scheme types.
*/
if(This->scheme_type != URL_SCHEME_UNKNOWN && This->userinfo_start > -1) {
*pbstrProperty = SysAllocStringLen(NULL, This->canon_len-This->userinfo_len);
unsigned int length = This->canon_len-This->userinfo_len;
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
length -= This->fragment_len;
*pbstrProperty = SysAllocStringLen(NULL, length);
if(*pbstrProperty) {
/* Copy everything before the userinfo over. */
memcpy(*pbstrProperty, This->canon_uri, This->userinfo_start*sizeof(WCHAR));
/* Copy everything after the userinfo over. */
length -= This->userinfo_start+1;
memcpy(*pbstrProperty+This->userinfo_start,
This->canon_uri+This->userinfo_start+This->userinfo_len+1,
(This->canon_len-(This->userinfo_start+This->userinfo_len+1))*sizeof(WCHAR));
This->canon_uri+This->userinfo_start+This->userinfo_len+1, length*sizeof(WCHAR));
}
} else
*pbstrProperty = SysAllocString(This->canon_uri);
} else {
unsigned int length = This->canon_len;
/* Skip fragment if Uri_DISPLAY_NO_FRAGMENT is specified */
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
length -= This->fragment_len;
*pbstrProperty = SysAllocStringLen(This->canon_uri, length);
}
if(!(*pbstrProperty))
hres = E_OUTOFMEMORY;
@ -3965,8 +4024,20 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
break;
case Uri_PROPERTY_DOMAIN:
if(This->domain_offset > -1) {
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
This->host_len-This->domain_offset);
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
unsigned int punycode_length;
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
This->host_len-This->domain_offset, NULL, 0);
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
if (*pbstrProperty)
IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset,
This->host_len-This->domain_offset, *pbstrProperty, punycode_length);
} else {
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+This->domain_offset,
This->host_len-This->domain_offset);
}
hres = S_OK;
} else {
*pbstrProperty = SysAllocStringLen(NULL, 0);
@ -4009,6 +4080,14 @@ static HRESULT WINAPI Uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY uriProp, BST
/* The '[' and ']' aren't included for IPv6 addresses. */
if(This->host_type == Uri_HOST_IPV6)
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start+1, This->host_len-2);
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN) {
unsigned int punycode_length;
punycode_length = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
*pbstrProperty = SysAllocStringLen(NULL, punycode_length);
if (*pbstrProperty)
IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, *pbstrProperty, punycode_length);
}
else
*pbstrProperty = SysAllocStringLen(This->canon_uri+This->host_start, This->host_len);
@ -4156,10 +4235,10 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
if(uriProp > Uri_PROPERTY_STRING_LAST)
return E_INVALIDARG;
/* Don't have support for flags yet. */
if(dwFlags) {
FIXME("(%p)->(%d %p %lx)\n", This, uriProp, pcchProperty, dwFlags);
return E_NOTIMPL;
if(dwFlags != 0 && dwFlags != Uri_DISPLAY_NO_FRAGMENT && dwFlags != Uri_PUNYCODE_IDN_HOST
&& dwFlags != Uri_DISPLAY_IDN_HOST) {
*pcchProperty = 0;
return E_INVALIDARG;
}
switch(uriProp) {
@ -4167,6 +4246,12 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
if(This->display_modifiers & URI_DISPLAY_NO_ABSOLUTE_URI) {
*pcchProperty = 0;
hres = S_FALSE;
}
/* Uri_PUNYCODE_IDN_HOST doesn't remove user info containing only "@" and ":@" */
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1) {
unsigned int punycode_host_len = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
*pcchProperty = This->canon_len - This->host_len + punycode_host_len;
hres = S_OK;
} else {
if(This->scheme_type != URL_SCHEME_UNKNOWN) {
if(This->userinfo_start > -1 && This->userinfo_len == 0)
@ -4201,11 +4286,18 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
else
*pcchProperty = This->canon_len;
if(dwFlags == Uri_DISPLAY_NO_FRAGMENT && This->fragment_start > -1)
*pcchProperty -= This->fragment_len;
hres = S_OK;
break;
case Uri_PROPERTY_DOMAIN:
if(This->domain_offset > -1)
*pcchProperty = This->host_len - This->domain_offset;
if(This->domain_offset > -1) {
if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN)
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start+This->domain_offset, This->host_len-This->domain_offset, NULL, 0);
else
*pcchProperty = This->host_len - This->domain_offset;
}
else
*pcchProperty = 0;
@ -4231,6 +4323,8 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
/* '[' and ']' aren't included in the length. */
if(This->host_type == Uri_HOST_IPV6)
*pcchProperty -= 2;
else if(dwFlags == Uri_PUNYCODE_IDN_HOST && This->host_type == Uri_HOST_IDN && This->host_start > -1)
*pcchProperty = IdnToAscii(0, This->canon_uri+This->host_start, This->host_len, NULL, 0);
hres = (This->host_start > -1) ? S_OK : S_FALSE;
break;
@ -4274,6 +4368,16 @@ static HRESULT WINAPI Uri_GetPropertyLength(IUri *iface, Uri_PROPERTY uriProp, D
hres = E_NOTIMPL;
}
if(hres == S_OK
&& ((dwFlags == Uri_DISPLAY_NO_FRAGMENT && uriProp != Uri_PROPERTY_DISPLAY_URI)
|| (dwFlags == Uri_PUNYCODE_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST)
|| (dwFlags == Uri_DISPLAY_IDN_HOST && uriProp != Uri_PROPERTY_ABSOLUTE_URI
&& uriProp != Uri_PROPERTY_DOMAIN && uriProp != Uri_PROPERTY_HOST))) {
*pcchProperty = 0;
hres = E_INVALIDARG;
}
return hres;
}

View file

@ -27,6 +27,8 @@ extern LRESULT WINAPI ImeWndProcA(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI ImeWndProcW(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI DesktopWndProcA(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI DesktopWndProcW(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI DialogWndProcA(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI DialogWndProcW(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI IconTitleWndProcA(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI IconTitleWndProcW(HWND,UINT,WPARAM,LPARAM);
extern LRESULT WINAPI PopupMenuWndProcA(HWND,UINT,WPARAM,LPARAM);

View file

@ -423,17 +423,17 @@ LRESULT WINAPI USER_DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
}
/***********************************************************************
* DefDlgProcA (USER32.@)
* DialogWndProcA
*/
LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
LRESULT WINAPI DialogWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, FALSE );
}
/***********************************************************************
* DefDlgProcW (USER32.@)
* DialogWndProcW
*/
LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
LRESULT WINAPI DialogWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, TRUE );
}

View file

@ -29,6 +29,7 @@
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
#include "winternl.h"
#include "commctrl.h"
#define NUMCLASSWORDS 4
@ -47,6 +48,8 @@
#define ARCH "none"
#endif
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
static const char comctl32_manifest[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
@ -681,7 +684,6 @@ static void test_builtinproc(void)
static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
WCHAR unistring[] = {0x142, 0x40e, 0x3b4, 0}; /* a string that would be destroyed by a W->A->W conversion */
WNDPROC pDefWindowProcA, pDefWindowProcW;
WNDPROC pNtdllDefWindowProcA, pNtdllDefWindowProcW;
WNDPROC oldproc;
WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
WCHAR buf[128];
@ -691,57 +693,6 @@ static void test_builtinproc(void)
pDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcA");
pDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcW");
pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_A");
pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_W");
/* On Vista+, the user32.dll export DefWindowProcA/W is forwarded to */
/* ntdll.NtdllDefWindowProc_A/W. However, the wndproc returned by */
/* GetClassLong/GetWindowLong points to an unexported user32 function */
if (pDefWindowProcA == pNtdllDefWindowProcA &&
pDefWindowProcW == pNtdllDefWindowProcW)
skip("user32.DefWindowProcX forwarded to ntdll.NtdllDefWindowProc_X\n");
else
{
for (i = 0; i < 4; i++)
{
ZeroMemory(&cls, sizeof(cls));
cls.cbSize = sizeof(cls);
cls.hInstance = GetModuleHandleA(NULL);
cls.hbrBackground = GetStockObject (WHITE_BRUSH);
if (i & 1)
cls.lpfnWndProc = pDefWindowProcA;
else
cls.lpfnWndProc = pDefWindowProcW;
if (i & 2)
{
cls.lpszClassName = classA;
atom = RegisterClassExA(&cls);
}
else
{
cls.lpszClassName = (LPCSTR)classW;
atom = RegisterClassExW((WNDCLASSEXW *)&cls);
}
ok(atom != 0, "Couldn't register class, i=%d, %ld\n", i, GetLastError());
hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), NULL);
ok(hwnd != NULL, "Couldn't create window i=%d\n", i);
ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
(void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), pDefWindowProcA);
ok(GetClassLongPtrA(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
(void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC), pDefWindowProcA);
ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
(void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), pDefWindowProcW);
ok(GetClassLongPtrW(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
(void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW);
DestroyWindow(hwnd);
UnregisterClassA((LPSTR)(DWORD_PTR)atom, GetModuleHandleA(NULL));
}
}
/* built-in winproc - window A/W type automatically detected */
ZeroMemory(&cls, sizeof(cls));
@ -907,6 +858,80 @@ static void test_builtinproc(void)
}
static void test_ntdll_wndprocs(void)
{
static const char *classes[] =
{
"ScrollBar",
"Message",
"#32768", /* menu */
"#32769", /* desktop */
"DefWindowProc", /* not a real class */
"#32772", /* icon title */
"??", /* ?? */
"Button",
"ComboBox",
"ComboLBox",
"#32770", /* dialog */
"Edit",
"ListBox",
"MDIClient",
"Static",
"IME",
"Ghost",
};
unsigned int i;
void *procsA[ARRAY_SIZE(classes)] = { NULL };
void *procsW[ARRAY_SIZE(classes)] = { NULL };
const UINT64 *ptr_A, *ptr_W, *ptr_workers;
NTSTATUS (WINAPI *pRtlRetrieveNtUserPfn)(const UINT64**,const UINT64**,const UINT64 **);
pRtlRetrieveNtUserPfn = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "RtlRetrieveNtUserPfn" );
if (!pRtlRetrieveNtUserPfn || pRtlRetrieveNtUserPfn( &ptr_A, &ptr_W, &ptr_workers ))
{
win_skip( "RtlRetrieveNtUserPfn not supported\n" );
return;
}
for (i = 0; i < ARRAY_SIZE(classes); i++)
{
WNDCLASSA wcA;
WNDCLASSW wcW;
WCHAR buffer[20];
MultiByteToWideChar( CP_ACP, 0, classes[i], -1, buffer, ARRAY_SIZE(buffer) );
if (GetClassInfoA( 0, classes[i], &wcA )) procsA[i] = wcA.lpfnWndProc;
if (GetClassInfoW( 0, buffer, &wcW )) procsW[i] = wcW.lpfnWndProc;
}
procsA[4] = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcA");
procsW[4] = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcW");
if (!is_win64 && ptr_A[0] >> 32) /* some older versions use 32-bit pointers */
{
const void **ptr_A32 = (const void **)ptr_A, **ptr_W32 = (const void **)ptr_W;
for (i = 0; i < ARRAY_SIZE(procsA); i++)
{
ok( !procsA[i] || procsA[i] == ptr_A32[i],
"wrong ptr A %u %s: %p / %p\n", i, classes[i], procsA[i], ptr_A32[i] );
ok( !procsW[i] || procsW[i] == ptr_W32[i] ||
broken(i == 4), /* DefWindowProcW can be different on wow64 */
"wrong ptr W %u %s: %p / %p\n", i, classes[i], procsW[i], ptr_W32[i] );
}
}
else
{
for (i = 0; i < ARRAY_SIZE(procsA); i++)
{
ok( !procsA[i] || (ULONG_PTR)procsA[i] == ptr_A[i],
"wrong ptr A %u %s: %p / %I64x\n", i, classes[i], procsA[i], ptr_A[i] );
ok( !procsW[i] || (ULONG_PTR)procsW[i] == ptr_W[i] ||
broken( !is_win64 && i == 4 ), /* DefWindowProcW can be different on wow64 */
"wrong ptr W %u %s: %p / %I64x\n", i, classes[i], procsW[i], ptr_W[i] );
}
}
}
static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return DefDlgProcA(hWnd, uMsg, wParam, lParam);
@ -1622,6 +1647,7 @@ START_TEST(class)
CreateDialogParamTest(hInstance);
test_styles();
test_builtinproc();
test_ntdll_wndprocs();
test_icons();
test_comctl32_classes();
test_actctx_classes();

View file

@ -6187,6 +6187,13 @@ static const struct message WmMove_mouse[] = {
{ 0 }
};
static const struct message WmMove_mouse2[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE },
{ WM_GETTEXT, sent|optional },
{ WM_GETMINMAXINFO, sent|defwinproc },
{ 0 }
};
static void test_setwindowpos(void)
{
HWND hwnd;
@ -6253,6 +6260,11 @@ static void test_setwindowpos(void)
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
flush_events();
ok_sequence(WmMove_mouse, "MouseMove", FALSE);
/* if the window and client rects were not changed WM_MOUSEMOVE is not sent. */
res = SetWindowPos( hwnd, 0, 205, 205, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE );
ok(res == TRUE, "SetWindowPos expected TRUE, got %Id.\n", res);
flush_events();
ok_sequence(WmMove_mouse2, "MouseMove2", FALSE);
ignore_mouse_messages = TRUE;
DestroyWindow(hwnd);

View file

@ -379,15 +379,15 @@
@ stdcall DdeSetUserHandle(long long long)
@ stdcall DdeUnaccessData(long)
@ stdcall DdeUninitialize(long)
@ stdcall DefDlgProcA(long long long long)
@ stdcall DefDlgProcW(long long long long)
@ stdcall DefDlgProcA(long long long long) NTDLL.NtdllDialogWndProc_A
@ stdcall DefDlgProcW(long long long long) NTDLL.NtdllDialogWndProc_W
@ stdcall DefFrameProcA(long long long long long)
@ stdcall DefFrameProcW(long long long long long)
@ stdcall DefMDIChildProcA(long long long long)
@ stdcall DefMDIChildProcW(long long long long)
@ stdcall DefRawInputProc(ptr long long)
@ stdcall DefWindowProcA(long long long long)
@ stdcall DefWindowProcW(long long long long)
@ stdcall DefWindowProcA(long long long long) NTDLL.NtdllDefWindowProc_A
@ stdcall DefWindowProcW(long long long long) NTDLL.NtdllDefWindowProc_W
@ stdcall DeferWindowPos(long long long long long long long long)
# @ stub DeferWindowPosAndBand
@ stdcall DeleteMenu(long long long) NtUserDeleteMenu
@ -558,7 +558,7 @@
@ stdcall GetDlgItemTextA(long long ptr long)
@ stdcall GetDlgItemTextW(long long ptr long)
@ stdcall GetDoubleClickTime() NtUserGetDoubleClickTime
# @ stub GetDpiAwarenessContextForProcess
@ stdcall GetDpiAwarenessContextForProcess(ptr)
@ stdcall GetDpiForMonitorInternal(long long ptr ptr) NtUserGetDpiForMonitor
@ stdcall GetDpiForSystem()
@ stdcall GetDpiForWindow(long)

View file

@ -615,6 +615,13 @@ DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( HWND hwnd )
return LongToHandle( NtUserGetWindowDpiAwarenessContext( hwnd ) );
}
/***********************************************************************
* GetDpiAwarenessContextForProcess (USER32.@)
*/
DPI_AWARENESS_CONTEXT WINAPI GetDpiAwarenessContextForProcess(HANDLE process)
{
return LongToHandle( NtUserGetProcessDpiAwarenessContext( process ) );
}
/***********************************************************************
* GetWindowDpiHostingBehavior (USER32.@)

View file

@ -1061,43 +1061,27 @@ struct wow_handlers16 wow_handlers =
NULL, /* call_dialog_proc */
};
static const struct user_client_procs client_procsA =
{
.pButtonWndProc = ButtonWndProcA,
.pComboWndProc = ComboWndProcA,
.pDefWindowProc = DefWindowProcA,
.pDefDlgProc = DefDlgProcA,
.pEditWndProc = EditWndProcA,
.pListBoxWndProc = ListBoxWndProcA,
.pMDIClientWndProc = MDIClientWndProcA,
.pScrollBarWndProc = ScrollBarWndProcA,
.pStaticWndProc = StaticWndProcA,
.pImeWndProc = ImeWndProcA,
.pDesktopWndProc = DesktopWndProcA,
.pIconTitleWndProc = IconTitleWndProcA,
.pPopupMenuWndProc = PopupMenuWndProcA,
.pMessageWndProc = MessageWndProc,
};
#define MessageWndProcA MessageWndProc
#define MessageWndProcW MessageWndProc
#define ComboLBoxWndProcA ListBoxWndProcA
#define ComboLBoxWndProcW ListBoxWndProcW
#define GhostWndProcA DefWindowProcA
#define GhostWndProcW DefWindowProcW
static const struct user_client_procs client_procsW =
static const struct ntuser_client_procs_table client_procs =
{
.pButtonWndProc = ButtonWndProcW,
.pComboWndProc = ComboWndProcW,
.pDefWindowProc = DefWindowProcW,
.pDefDlgProc = DefDlgProcW,
.pEditWndProc = EditWndProcW,
.pListBoxWndProc = ListBoxWndProcW,
.pMDIClientWndProc = MDIClientWndProcW,
.pScrollBarWndProc = ScrollBarWndProcW,
.pStaticWndProc = StaticWndProcW,
.pImeWndProc = ImeWndProcW,
.pDesktopWndProc = DesktopWndProcW,
.pIconTitleWndProc = IconTitleWndProcW,
.pPopupMenuWndProc = PopupMenuWndProcW,
.pMessageWndProc = MessageWndProc,
#define USER_FUNC(name,proc) .A[proc] = { name##A }, .W[proc] = { name##W },
ALL_NTUSER_CLIENT_PROCS
#undef USER_FUNC
};
void winproc_init(void)
{
NtUserInitializeClientPfnArrays( &client_procsA, &client_procsW, NULL, user32_module );
const ntuser_client_func_ptr *ptr_A, *ptr_W, *ptr_workers;
RtlInitializeNtUserPfn( client_procs.A, sizeof(client_procs.A),
client_procs.W, sizeof(client_procs.W),
client_procs.workers, sizeof(client_procs.workers) );
RtlRetrieveNtUserPfn( (const void **)&ptr_A, (const void **)&ptr_W, (const void **)&ptr_workers );
NtUserInitializeClientPfnArrays( ptr_A, ptr_W, ptr_workers, user32_module );
}

View file

@ -68,7 +68,7 @@ struct builtin_class_descr
INT extra; /* window extra bytes */
ULONG_PTR cursor; /* cursor id */
HBRUSH brush; /* brush or system color */
enum builtin_winprocs proc;
enum ntuser_client_procs proc;
};
typedef struct tagWINDOWPROC
@ -78,7 +78,7 @@ typedef struct tagWINDOWPROC
} WINDOWPROC;
static WINDOWPROC winproc_array[MAX_WINPROCS];
static UINT winproc_used = NB_BUILTIN_WINPROCS;
static UINT winproc_used = NTUSER_NB_PROCS;
static pthread_mutex_t winproc_lock = PTHREAD_MUTEX_INITIALIZER;
static struct list class_list = LIST_INIT( class_list );
@ -91,7 +91,7 @@ static WINDOWPROC *find_winproc( WNDPROC func, BOOL ansi )
{
unsigned int i;
for (i = 0; i < NB_BUILTIN_WINPROCS; i++)
for (i = 0; i < NTUSER_NB_PROCS; i++)
{
/* match either proc, some apps confuse A and W */
if (winproc_array[i].procA != func && winproc_array[i].procW != func) continue;
@ -257,41 +257,19 @@ static void init_user(void)
/***********************************************************************
* NtUserInitializeClientPfnArrays (win32u.@)
*/
NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs *client_procsA,
const struct user_client_procs *client_procsW,
const void *client_workers, HINSTANCE user_module )
NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const ntuser_client_func_ptr *client_procsA,
const ntuser_client_func_ptr *client_procsW,
const ntuser_client_func_ptr *client_workers,
HINSTANCE user_module )
{
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
UINT i;
winproc_array[WINPROC_BUTTON].procA = client_procsA->pButtonWndProc;
winproc_array[WINPROC_BUTTON].procW = client_procsW->pButtonWndProc;
winproc_array[WINPROC_COMBO].procA = client_procsA->pComboWndProc;
winproc_array[WINPROC_COMBO].procW = client_procsW->pComboWndProc;
winproc_array[WINPROC_DEFWND].procA = client_procsA->pDefWindowProc;
winproc_array[WINPROC_DEFWND].procW = client_procsW->pDefWindowProc;
winproc_array[WINPROC_DIALOG].procA = client_procsA->pDefDlgProc;
winproc_array[WINPROC_DIALOG].procW = client_procsW->pDefDlgProc;
winproc_array[WINPROC_EDIT].procA = client_procsA->pEditWndProc;
winproc_array[WINPROC_EDIT].procW = client_procsW->pEditWndProc;
winproc_array[WINPROC_LISTBOX].procA = client_procsA->pListBoxWndProc;
winproc_array[WINPROC_LISTBOX].procW = client_procsW->pListBoxWndProc;
winproc_array[WINPROC_MDICLIENT].procA = client_procsA->pMDIClientWndProc;
winproc_array[WINPROC_MDICLIENT].procW = client_procsW->pMDIClientWndProc;
winproc_array[WINPROC_SCROLLBAR].procA = client_procsA->pScrollBarWndProc;
winproc_array[WINPROC_SCROLLBAR].procW = client_procsW->pScrollBarWndProc;
winproc_array[WINPROC_STATIC].procA = client_procsA->pStaticWndProc;
winproc_array[WINPROC_STATIC].procW = client_procsW->pStaticWndProc;
winproc_array[WINPROC_IME].procA = client_procsA->pImeWndProc;
winproc_array[WINPROC_IME].procW = client_procsW->pImeWndProc;
winproc_array[WINPROC_DESKTOP].procA = client_procsA->pDesktopWndProc;
winproc_array[WINPROC_DESKTOP].procW = client_procsW->pDesktopWndProc;
winproc_array[WINPROC_ICONTITLE].procA = client_procsA->pIconTitleWndProc;
winproc_array[WINPROC_ICONTITLE].procW = client_procsW->pIconTitleWndProc;
winproc_array[WINPROC_MENU].procA = client_procsA->pPopupMenuWndProc;
winproc_array[WINPROC_MENU].procW = client_procsW->pPopupMenuWndProc;
winproc_array[WINPROC_MESSAGE].procA = client_procsA->pMessageWndProc;
winproc_array[WINPROC_MESSAGE].procW = client_procsW->pMessageWndProc;
for (i = 0; i < NTUSER_NB_PROCS; i++)
{
winproc_array[i].procA = client_procsA[i][0];
winproc_array[i].procW = client_procsW[i][0];
}
user32_module = user_module;
pthread_once( &init_once, init_user );
@ -1081,14 +1059,14 @@ static const struct builtin_class_descr desktop_builtin_class =
{
.name = MAKEINTRESOURCEA(DESKTOP_CLASS_ATOM),
.style = CS_DBLCLKS,
.proc = WINPROC_DESKTOP,
.proc = NTUSER_WNDPROC_DESKTOP,
.brush = (HBRUSH)(COLOR_BACKGROUND + 1),
};
static const struct builtin_class_descr message_builtin_class =
{
.name = "Message",
.proc = WINPROC_MESSAGE,
.proc = NTUSER_WNDPROC_MESSAGE,
};
static const struct builtin_class_descr builtin_classes[] =
@ -1097,7 +1075,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "Button",
.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
.proc = WINPROC_BUTTON,
.proc = NTUSER_WNDPROC_BUTTON,
.extra = sizeof(UINT) + 2 * sizeof(HANDLE),
.cursor = IDC_ARROW,
},
@ -1105,7 +1083,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "ComboBox",
.style = CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
.proc = WINPROC_COMBO,
.proc = NTUSER_WNDPROC_COMBO,
.extra = sizeof(void *),
.cursor = IDC_ARROW,
},
@ -1113,7 +1091,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "ComboLBox",
.style = CS_DBLCLKS | CS_SAVEBITS,
.proc = WINPROC_LISTBOX,
.proc = NTUSER_WNDPROC_COMBOLBOX,
.extra = sizeof(void *),
.cursor = IDC_ARROW,
},
@ -1121,20 +1099,20 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = MAKEINTRESOURCEA(DIALOG_CLASS_ATOM),
.style = CS_SAVEBITS | CS_DBLCLKS,
.proc = WINPROC_DIALOG,
.proc = NTUSER_WNDPROC_DIALOG,
.extra = DLGWINDOWEXTRA,
.cursor = IDC_ARROW,
},
/* icon title */
{
.name = MAKEINTRESOURCEA(ICONTITLE_CLASS_ATOM),
.proc = WINPROC_ICONTITLE,
.proc = NTUSER_WNDPROC_ICONTITLE,
.cursor = IDC_ARROW,
},
/* IME */
{
.name = "IME",
.proc = WINPROC_IME,
.proc = NTUSER_WNDPROC_IME,
.extra = 2 * sizeof(LONG_PTR),
.cursor = IDC_ARROW,
},
@ -1142,7 +1120,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "ListBox",
.style = CS_DBLCLKS,
.proc = WINPROC_LISTBOX,
.proc = NTUSER_WNDPROC_LISTBOX,
.extra = sizeof(void *),
.cursor = IDC_ARROW,
},
@ -1150,7 +1128,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = MAKEINTRESOURCEA(POPUPMENU_CLASS_ATOM),
.style = CS_DROPSHADOW | CS_SAVEBITS | CS_DBLCLKS,
.proc = WINPROC_MENU,
.proc = NTUSER_WNDPROC_MENU,
.extra = sizeof(HMENU),
.cursor = IDC_ARROW,
.brush = (HBRUSH)(COLOR_MENU + 1),
@ -1158,7 +1136,7 @@ static const struct builtin_class_descr builtin_classes[] =
/* MDIClient */
{
.name = "MDIClient",
.proc = WINPROC_MDICLIENT,
.proc = NTUSER_WNDPROC_MDICLIENT,
.extra = 2 * sizeof(void *),
.cursor = IDC_ARROW,
.brush = (HBRUSH)(COLOR_APPWORKSPACE + 1),
@ -1167,7 +1145,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "ScrollBar",
.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC,
.proc = WINPROC_SCROLLBAR,
.proc = NTUSER_WNDPROC_SCROLLBAR,
.extra = sizeof(struct scroll_bar_win_data),
.cursor = IDC_ARROW,
},
@ -1175,7 +1153,7 @@ static const struct builtin_class_descr builtin_classes[] =
{
.name = "Static",
.style = CS_DBLCLKS | CS_PARENTDC,
.proc = WINPROC_STATIC,
.proc = NTUSER_WNDPROC_STATIC,
.extra = 2 * sizeof(HANDLE),
.cursor = IDC_ARROW,
},
@ -1231,7 +1209,7 @@ static void register_builtins(void)
{
.name = "Edit",
.style = CS_DBLCLKS | CS_PARENTDC,
.proc = WINPROC_EDIT,
.proc = NTUSER_WNDPROC_EDIT,
.extra = sizeof(void *) == 4 || NtCurrentTeb()->WowTebOffset ? 6 : sizeof(UINT64),
.cursor = IDC_IBEAM,
};

View file

@ -1729,9 +1729,9 @@ BOOL SYSCALL_API NtUserHiliteMenuItem( HWND hwnd, HMENU handle, UINT item, UINT
SYSCALL_FUNC( NtUserHiliteMenuItem );
}
NTSTATUS SYSCALL_API NtUserInitializeClientPfnArrays( const struct user_client_procs *client_procsA,
const struct user_client_procs *client_procsW,
const void *client_workers, HINSTANCE user_module )
NTSTATUS SYSCALL_API NtUserInitializeClientPfnArrays( const ntuser_client_func_ptr *client_procsA,
const ntuser_client_func_ptr *client_procsW,
const ntuser_client_func_ptr *client_workers, HINSTANCE user_module )
{
SYSCALL_FUNC( NtUserInitializeClientPfnArrays );
}

View file

@ -136,25 +136,6 @@ struct hook_extra_info
LPARAM lparam;
};
enum builtin_winprocs
{
WINPROC_BUTTON = 0,
WINPROC_COMBO,
WINPROC_DEFWND,
WINPROC_DIALOG,
WINPROC_EDIT,
WINPROC_LISTBOX,
WINPROC_MDICLIENT,
WINPROC_SCROLLBAR,
WINPROC_STATIC,
WINPROC_IME,
WINPROC_DESKTOP,
WINPROC_ICONTITLE,
WINPROC_MENU,
WINPROC_MESSAGE,
NB_BUILTIN_WINPROCS,
};
/* FIXME: make it private to scroll.c */
/* data for a single scroll bar */

View file

@ -158,6 +158,7 @@ static struct list monitors = LIST_INIT(monitors);
static INT64 last_query_display_time;
static pthread_mutex_t display_lock = PTHREAD_MUTEX_INITIALIZER;
static BOOL emulate_modeset;
BOOL decorated_mode = TRUE;
UINT64 thunk_lock_callback = 0;
@ -1655,8 +1656,7 @@ static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *ini
static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param )
{
struct device_manager_ctx *ctx = param;
DEVMODEW dummy, detached = *current, virtual, *virtual_modes = NULL;
const DEVMODEW physical = modes_count == 1 ? *modes : *current;
DEVMODEW dummy, physical, detached = *current, virtual, *virtual_modes = NULL;
struct source *source;
UINT virtual_count;
@ -1665,6 +1665,13 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW
assert( !list_empty( &sources ) );
source = LIST_ENTRY( list_tail( &sources ), struct source, entry );
if (emulate_modeset)
{
modes = current;
modes_count = 1;
}
physical = modes_count == 1 ? *modes : *current;
if (ctx->is_primary) ctx->primary = *current;
detached.dmPelsWidth = 0;
@ -1761,6 +1768,27 @@ static BOOL is_monitor_primary( struct monitor *monitor )
return !!(source->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE);
}
/* display_lock must be held */
static void monitor_virt_to_raw_ratio( struct monitor *monitor, UINT *num, UINT *den )
{
struct source *source = monitor->source;
*num = *den = 1;
if (!source) return;
if (source->physical.dmPelsWidth * source->current.dmPelsHeight <=
source->physical.dmPelsHeight * source->current.dmPelsWidth)
{
*num = source->physical.dmPelsWidth;
*den = source->current.dmPelsWidth;
}
else
{
*num = source->physical.dmPelsHeight;
*den = source->current.dmPelsHeight;
}
}
/* display_lock must be held */
static UINT monitor_get_dpi( struct monitor *monitor, MONITOR_DPI_TYPE type, UINT *dpi_x, UINT *dpi_y )
{
@ -1769,6 +1797,12 @@ static UINT monitor_get_dpi( struct monitor *monitor, MONITOR_DPI_TYPE type, UIN
UINT dpi;
if (!source || !(dpi = source->dpi)) dpi = system_dpi;
if (source && type != MDT_EFFECTIVE_DPI)
{
scale_x = source->physical.dmPelsWidth / (float)source->current.dmPelsWidth;
scale_y = source->physical.dmPelsHeight / (float)source->current.dmPelsHeight;
}
*dpi_x = round( dpi * scale_x );
*dpi_y = round( dpi * scale_y );
return min( *dpi_x, *dpi_y );
@ -1781,6 +1815,7 @@ static RECT monitor_get_rect( struct monitor *monitor, UINT dpi, MONITOR_DPI_TYP
RECT rect = {0, 0, 1024, 768};
struct source *source;
UINT dpi_from, x, y;
DEVMODEW *mode;
/* services do not have any adapters, only a virtual monitor */
if (!(source = monitor->source)) return rect;
@ -1789,9 +1824,10 @@ static RECT monitor_get_rect( struct monitor *monitor, UINT dpi, MONITOR_DPI_TYP
if (!(source->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return rect;
source_get_current_settings( source, &current_mode );
SetRect( &rect, current_mode.dmPosition.x, current_mode.dmPosition.y,
current_mode.dmPosition.x + current_mode.dmPelsWidth,
current_mode.dmPosition.y + current_mode.dmPelsHeight );
mode = type != MDT_EFFECTIVE_DPI ? &source->physical : &current_mode;
SetRect( &rect, mode->dmPosition.x, mode->dmPosition.y,
mode->dmPosition.x + mode->dmPelsWidth,
mode->dmPosition.y + mode->dmPelsHeight );
dpi_from = monitor_get_dpi( monitor, type, &x, &y );
return map_dpi_rect( rect, dpi_from, dpi );
@ -2403,6 +2439,42 @@ static RECT map_monitor_rect( struct monitor *monitor, RECT rect, UINT dpi_from,
UINT dpi_to, MONITOR_DPI_TYPE type_to )
{
UINT x, y;
assert( type_from != type_to );
if (monitor->source)
{
DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}, *mode_from, *mode_to;
UINT num, den, dpi;
source_get_current_settings( monitor->source, &current_mode );
dpi = monitor_get_dpi( monitor, MDT_DEFAULT, &x, &y );
if (!dpi_from) dpi_from = dpi;
if (!dpi_to) dpi_to = dpi;
if (type_from == MDT_RAW_DPI)
{
monitor_virt_to_raw_ratio( monitor, &den, &num );
mode_from = &monitor->source->physical;
mode_to = &current_mode;
}
else
{
monitor_virt_to_raw_ratio( monitor, &num, &den );
mode_from = &current_mode;
mode_to = &monitor->source->physical;
}
rect = map_dpi_rect( rect, dpi_from, dpi * 2 );
OffsetRect( &rect, -mode_from->dmPosition.x * 2 - mode_from->dmPelsWidth,
-mode_from->dmPosition.y * 2 - mode_from->dmPelsHeight );
rect = map_dpi_rect( rect, den, num );
OffsetRect( &rect, mode_to->dmPosition.x * 2 + mode_to->dmPelsWidth,
mode_to->dmPosition.y * 2 + mode_to->dmPelsHeight );
return map_dpi_rect( rect, dpi * 2, dpi_to );
}
if (!dpi_from) dpi_from = monitor_get_dpi( monitor, type_from, &x, &y );
if (!dpi_to) dpi_to = monitor_get_dpi( monitor, type_to, &x, &y );
return map_dpi_rect( rect, dpi_from, dpi_to );
@ -3648,13 +3720,25 @@ static POINT get_placement_offset( const DEVMODEW *displays, const DEVMODEW *pla
return min_offset;
}
static void place_all_displays( DEVMODEW *displays )
static void place_all_displays( DEVMODEW *displays, const WCHAR *primary_name )
{
POINT min_offset, offset;
POINT min_offset, offset = {0};
DEVMODEW *mode, *placing;
for (mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode))
{
if (wcsicmp( mode->dmDeviceName, primary_name )) continue;
offset.x = -mode->dmPosition.x;
offset.y = -mode->dmPosition.y;
break;
}
for (mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode))
{
mode->dmPosition.x += offset.x;
mode->dmPosition.y += offset.y;
mode->dmFields &= ~DM_POSITION;
}
/* Place all displays with no extra space between them and no overlapping */
while (1)
@ -3763,8 +3847,6 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo
return DISP_CHANGE_SUCCESSFUL;
}
place_all_displays( displays );
if (!(primary = find_primary_source())) primary_name[0] = 0;
else
{
@ -3773,8 +3855,10 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo
asciiz_to_unicode( primary_name, device_name );
}
place_all_displays( displays, primary_name );
/* use the default implementation in virtual desktop mode */
if (is_virtual_desktop()) ret = DISP_CHANGE_SUCCESSFUL;
if (is_virtual_desktop() || emulate_modeset) ret = DISP_CHANGE_SUCCESSFUL;
else ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam );
if (ret == DISP_CHANGE_SUCCESSFUL)
@ -5346,6 +5430,8 @@ void sysparams_init(void)
grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
decorated_mode = IS_OPTION_TRUE( buffer[0] );
if (!get_config_key( hkey, appkey, "EmulateModeset", buffer, sizeof(buffer) ))
emulate_modeset = IS_OPTION_TRUE( buffer[0] );
#undef IS_OPTION_TRUE

View file

@ -1078,7 +1078,7 @@ static LONG_PTR get_window_long_size( HWND hwnd, INT offset, UINT size, BOOL ans
* more tolerant to A/W mismatches. The lack of W->A->W conversion for such a mismatch suggests
* that the hack is in GetWindowLongPtr[AW], not in winprocs.
*/
if (win->winproc == BUILTIN_WINPROC(WINPROC_EDIT) && (!!ansi != !(win->flags & WIN_ISUNICODE)))
if (win->winproc == BUILTIN_WINPROC(NTUSER_WNDPROC_EDIT) && (!!ansi != !(win->flags & WIN_ISUNICODE)))
retval = (ULONG_PTR)win->winproc;
else
retval = (ULONG_PTR)get_winproc( win->winproc, ansi );

View file

@ -7366,7 +7366,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
}
else if (shader_match_semantic(semantic_name, WINED3D_DECL_USAGE_FOG))
{
shader_addline(buffer, "%s = clamp(outputs[%u].%c, 0.0, 1.0);\n",
shader_addline(buffer, "%s = outputs[%u].%c;\n",
legacy_syntax ? "gl_FogFragCoord" : "ffp_varying_fogcoord",
output->register_idx, reg_mask[1]);
}
@ -11402,6 +11402,8 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s
TRACE("Shader model %u.\n", shader_model);
memset(caps, 0, sizeof(*caps));
caps->vs_version = min(wined3d_settings.max_sm_vs, shader_model);
caps->hs_version = min(wined3d_settings.max_sm_hs, shader_model);
caps->ds_version = min(wined3d_settings.max_sm_ds, shader_model);
@ -11743,6 +11745,8 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_adapter *adapter,
{
const struct wined3d_gl_info *gl_info = &wined3d_adapter_gl_const(adapter)->gl_info;
memset(caps, 0, sizeof(*caps));
caps->emulated_flatshading = !needs_legacy_glsl_syntax(gl_info);
caps->max_active_lights = WINED3D_MAX_ACTIVE_LIGHTS;
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;

View file

@ -1065,6 +1065,8 @@ static void shader_spirv_init_context_state(struct wined3d_context *context)
static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
{
memset(caps, 0, sizeof(*caps));
caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
@ -1196,6 +1198,7 @@ static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context *cont
static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
{
memset(caps, 0, sizeof(*caps));
caps->max_blend_stages = WINED3D_MAX_FFP_TEXTURES;
}
static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_adapter *adapter)

View file

@ -3697,14 +3697,9 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
if (changed->texture_matrices)
{
struct wined3d_ffp_vs_constants constants;
struct wined3d_stream_info si;
/* FIXME: This is a bit fragile. Ideally we should be calculating
* stream info from the stateblock state. */
wined3d_stream_info_from_declaration(&si, context->state, &device->adapter->d3d_info);
for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i)
get_texture_matrix(&si, state, i, &constants.texture_matrices[i]);
get_texture_matrix(state, i, &constants.texture_matrices[i]);
wined3d_device_context_push_constants(context,
WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_TEXMATRIX,
offsetof(struct wined3d_ffp_vs_constants, texture_matrices),

View file

@ -1933,7 +1933,7 @@ static inline int get_format_idx(enum wined3d_format_id format_id)
{
unsigned int i;
if (format_id < WINED3D_FORMAT_FOURCC_BASE)
if ((unsigned int)format_id < WINED3D_FORMAT_FOURCC_BASE)
return format_id;
for (i = 0; i < ARRAY_SIZE(format_index_remap); ++i)
@ -5608,38 +5608,43 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
mat = *matrix;
/* Under Direct3D the R/Z coord can be used for translation, under
* OpenGL we use the Q coord instead. */
/* When less than 4 components are provided for an attribute, the remaining
* components are filled with (..., 0, 0, 1). This is the case when using
* shaders in Direct3D as well as in GL and Vulkan.
*
* However, when using the Direct3D fixed function vertex pipeline, the
* texture coordinates transformed by texture matrices effectively have
* 1 in the first "default" component and 0 in the others (e.g. for
* R32_FLOAT the coordinates are (..., 1, 0, 0).
*
* We could approximate this by modifying the shader, but modifying uniforms
* is generally cheaper, so instead we change the matrix, copying the 2nd or
* 3rd column to the 4th. That is, whichever coefficients expect a value of
* 1 will instead be used as the coefficients for the 4th column, which
* actually has a value of 1. The coefficients for other columns don't need
* to be modified, since the corresponding texcoord components are zero. */
if (!(flags & WINED3D_TTFF_PROJECTED) && !calculated_coords)
{
switch (format_id)
{
/* Direct3D passes the default 1.0 in the 2nd coord, while GL
* passes it in the 4th. Swap 2nd and 4th coord. No need to
* store the value of mat._41 in mat._21 because the input
* value to the transformation will be 0, so the matrix value
* is irrelevant. */
case WINED3DFMT_R32_FLOAT:
mat._41 = mat._21;
mat._42 = mat._22;
mat._43 = mat._23;
mat._44 = mat._24;
break;
/* See above, just 3rd and 4th coord. */
case WINED3DFMT_R32G32_FLOAT:
mat._41 = mat._31;
mat._42 = mat._32;
mat._43 = mat._33;
mat._44 = mat._34;
break;
case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
/* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
* into a bad place. The division elimination below will apply to make sure the
* 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
*/
case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
case WINED3DFMT_R32G32B32_FLOAT:
case WINED3DFMT_R32G32B32A32_FLOAT:
case WINED3DFMT_UNKNOWN:
break;
default:
FIXME("Unexpected fixed function texture coord input\n");
@ -5649,23 +5654,29 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t
*out_matrix = mat;
}
void get_texture_matrix(const struct wined3d_stream_info *si,
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat)
static enum wined3d_format_id get_texcoord_format(const struct wined3d_vertex_declaration *decl, unsigned int index)
{
for (unsigned int i = 0; i < decl->element_count; ++i)
{
if (decl->elements[i].usage == WINED3D_DECL_USAGE_TEXCOORD
&& decl->elements[i].usage_idx == index)
return decl->elements[i].format->id;
}
return WINED3DFMT_UNKNOWN;
}
void get_texture_matrix(const struct wined3d_stateblock_state *state,
const unsigned int tex, struct wined3d_matrix *mat)
{
BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
!= WINED3DTSS_TCI_PASSTHRU;
unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0x0000ffff,
WINED3D_MAX_FFP_TEXTURES - 1);
enum wined3d_format_id attribute_format;
if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)))
attribute_format = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id;
else
attribute_format = WINED3DFMT_UNKNOWN;
compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex],
state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
generated, attribute_format, mat);
generated, get_texcoord_format(state->vertex_declaration, coord_idx), mat);
}
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,

View file

@ -4376,8 +4376,8 @@ static inline BOOL shader_sampler_is_shadow(const struct wined3d_shader *shader,
void get_identity_matrix(struct wined3d_matrix *mat);
void get_modelview_matrix(const struct wined3d_stateblock_state *state, unsigned int index, struct wined3d_matrix *mat);
void get_texture_matrix(const struct wined3d_stream_info *si,
const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat);
void get_texture_matrix(const struct wined3d_stateblock_state *state,
const unsigned int tex, struct wined3d_matrix *mat);
void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,
float *out_min, float *out_max);
void get_fog_start_end(const struct wined3d_context *context, const struct wined3d_state *state,

View file

@ -696,57 +696,72 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
static const struct {
WCHAR wchar;
DWORD vkey;
/* Mac virtual key code that must match wchar under the current layout.
* A value of -1 means match-any.
* TODO: replace -1 with the actual mac virtual key codes for all mappings
* and their respective layouts to avoid false matches, when possible. */
int mac_keyc;
} symbol_vkeys[] = {
{ '-', VK_OEM_MINUS },
{ '+', VK_OEM_PLUS },
{ '_', VK_OEM_MINUS },
{ ',', VK_OEM_COMMA },
{ '.', VK_OEM_PERIOD },
{ '=', VK_OEM_PLUS },
{ '>', VK_OEM_PERIOD },
{ '<', VK_OEM_COMMA },
{ '|', VK_OEM_5 },
{ '\\', VK_OEM_5 },
{ '`', VK_OEM_3 },
{ '[', VK_OEM_4 },
{ '~', VK_OEM_3 },
{ 0x00DF, VK_OEM_4 }, /* 0x00DF is ESZETT */
{ 0x00FC, VK_OEM_1 }, /* 0x00FC is German U Umlaut */
{ 0x00F6, VK_OEM_3 }, /* 0x00F6 is German O Umlaut */
{ 0x00E4, VK_OEM_7 }, /* 0x00B4 is German A Umlaut */
{ '?', VK_OEM_2 },
{ ']', VK_OEM_6 },
{ '/', VK_OEM_2 },
{ ':', VK_OEM_1 },
{ '}', VK_OEM_6 },
{ '{', VK_OEM_4 },
{ ';', VK_OEM_1 },
{ '\'', VK_OEM_7 },
{ ':', VK_OEM_PERIOD },
{ ';', VK_OEM_COMMA },
{ '"', VK_OEM_7 },
{ 0x00B4, VK_OEM_4 }, /* 0x00B4 is ACUTE ACCENT */
{ '\'', VK_OEM_2 },
{ 0x00A7, VK_OEM_5 }, /* 0x00A7 is SECTION SIGN */
{ '*', VK_OEM_PLUS },
{ 0x00B4, VK_OEM_7 },
{ '`', VK_OEM_4 },
{ '[', VK_OEM_6 },
{ '/', VK_OEM_5 },
{ '^', VK_OEM_6 },
{ '*', VK_OEM_2 },
{ '{', VK_OEM_6 },
{ 0x00B4, VK_OEM_6 },
{ '~', VK_OEM_1 },
{ '?', VK_OEM_PLUS },
{ '?', VK_OEM_4 },
{ 0x00B4, VK_OEM_3 },
{ '?', VK_OEM_COMMA },
{ '~', VK_OEM_PLUS },
{ ']', VK_OEM_4 },
{ '\'', VK_OEM_3 },
{ 0x00A7, VK_OEM_7 },
{ '<', VK_OEM_102 },
{ '-', VK_OEM_PLUS, kVK_ANSI_Equal },
{ '-', VK_OEM_MINUS, -1 },
{ '+', VK_OEM_PLUS, -1 },
{ '_', VK_OEM_MINUS, -1 },
{ ',', VK_OEM_COMMA, -1 },
{ '.', VK_OEM_PERIOD, -1 },
{ '=', VK_OEM_8, kVK_ANSI_Slash },
{ '=', VK_OEM_PLUS, -1 },
{ '!', VK_OEM_8, kVK_ANSI_Slash },
{ 0x00F9, VK_OEM_3, kVK_ANSI_Quote }, /* 0x00F9 is French U accent grave */
{ '$', VK_OEM_1, kVK_ANSI_RightBracket },
{ ':', VK_OEM_2, kVK_ANSI_Period },
{ '*', VK_OEM_5, kVK_ANSI_Backslash },
{ '`', VK_OEM_5, kVK_ANSI_Backslash },
{ ';', VK_OEM_PERIOD, kVK_ANSI_Comma },
{ ')', VK_OEM_4, kVK_ANSI_Minus },
{ '>', VK_OEM_PERIOD, -1 },
{ '<', VK_OEM_COMMA, -1 },
{ '|', VK_OEM_5, -1 },
{ '\\', VK_OEM_5, -1 },
{ '`', VK_OEM_3, -1 },
{ '[', VK_OEM_4, -1 },
{ '~', VK_OEM_3, -1 },
{ 0x00DF, VK_OEM_4, kVK_ANSI_Minus }, /* 0x00DF is ESZETT */
{ 0x00FC, VK_OEM_1, kVK_ANSI_LeftBracket }, /* 0x00FC is German U Umlaut */
{ 0x00F6, VK_OEM_3, kVK_ANSI_Semicolon }, /* 0x00F6 is German O Umlaut */
{ 0x00E4, VK_OEM_7, kVK_ANSI_Quote }, /* 0x00B4 is German A Umlaut */
{ '?', VK_OEM_2, -1 },
{ ']', VK_OEM_6, -1 },
{ '/', VK_OEM_2, -1 },
{ ':', VK_OEM_1, -1 },
{ '}', VK_OEM_6, -1 },
{ '{', VK_OEM_4, },
{ ';', VK_OEM_1, -1 },
{ '\'', VK_OEM_7, -1 },
{ ':', VK_OEM_PERIOD, -1 },
{ ';', VK_OEM_COMMA, -1 },
{ '"', VK_OEM_7, -1 },
{ 0x00B4, VK_OEM_4, kVK_ANSI_Equal }, /* 0x00B4 is ACUTE ACCENT */
{ '\'', VK_OEM_2, -1 },
{ 0x00A7, VK_OEM_5, -1 }, /* 0x00A7 is SECTION SIGN */
{ '*', VK_OEM_PLUS, -1 },
{ 0x00B4, VK_OEM_7, -1 },
{ '`', VK_OEM_4, -1 },
{ '[', VK_OEM_6, -1 },
{ '/', VK_OEM_5, -1 },
{ '^', VK_OEM_6, -1 },
{ '*', VK_OEM_2, -1 },
{ '{', VK_OEM_6, -1 },
{ 0x00B4, VK_OEM_6, -1 },
{ '~', VK_OEM_1, -1 },
{ '?', VK_OEM_PLUS, -1 },
{ '?', VK_OEM_4, -1 },
{ 0x00B4, VK_OEM_3, -1 },
{ '?', VK_OEM_COMMA, -1 },
{ '~', VK_OEM_PLUS, -1 },
{ ']', VK_OEM_4, -1 },
{ '\'', VK_OEM_3, -1 },
{ 0x00A7, VK_OEM_7, -1 },
{ '<', VK_OEM_102, -1 },
};
int i;
@ -915,6 +930,8 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
if (!thread_data->keyc2scan[keyc]) continue; /* not a known Mac key code */
if (thread_data->keyc2vkey[keyc] || !map[keyc][combo][0])
continue;
if (symbol_vkeys[i].mac_keyc != -1 && symbol_vkeys[i].mac_keyc != keyc)
continue;
if (char_matches_string(symbol_vkeys[i].wchar, map[keyc][combo], collatorRef))
{

View file

@ -1577,7 +1577,7 @@ class VkMember(VkVariable):
elif self.is_handle() and self.is_wrapped():
handle = self.type_info["data"]
if direction == Direction.OUTPUT:
LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name))
LOGGER.error("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name))
elif self.optional:
return "{0}{1} = {2} ? {3} : 0;\n".format(output, self.name, self.value(input, conv),
handle.unwrap_handle(self.value(input, conv), unwrap))
@ -1586,9 +1586,9 @@ class VkMember(VkVariable):
handle.unwrap_handle(self.value(input, conv), unwrap))
elif self.is_generic_handle():
if direction == Direction.OUTPUT:
LOGGER.err("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name))
LOGGER.error("OUTPUT parameter {0}.{1} cannot be unwrapped".format(self.type, self.name))
if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER):
LOGGER.err("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name))
LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name))
return "{0}{1} = wine_vk_unwrap_handle({2}{3}, {2}{1});\n".format(output, self.name, input, self.object_type)
else:
selector_part = ", {0}{1}".format(input, self.selector) if self.selector else ""
@ -1754,7 +1754,7 @@ class VkParam(VkVariable):
# Since we have parsed all types before hand, this should not happen.
type_info = types.get(type_elem.text, None)
if type_info is None:
LOGGER.err("type info not found for: {0}".format(type_elem.text))
LOGGER.error("type info not found for: {0}".format(type_elem.text))
return VkParam(type_info, const=const, pointer=pointer, name=name, array_lens=array_lens,
dyn_array_len=dyn_array_len, object_type=object_type, optional=optional,
@ -1992,7 +1992,7 @@ class VkParam(VkVariable):
unwrap_handle = None
if self.object_type != None and self.type == "uint64_t":
if unwrap == Unwrap.DRIVER and self.is_wrapped(Unwrap.DRIVER):
LOGGER.err("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name))
LOGGER.error("DRIVER unwrapping of {0}.{1} not implemented".format(self.type, self.name))
unwrap_handle = "wine_vk_unwrap_handle({0}{1}, {0}{2})".format(
params_prefix, self.object_type, self.name)
@ -3271,22 +3271,25 @@ class VkRegistry(object):
# All of the relevant extensions and commands are in vk.xml.
video_tree = ET.parse(video_xml)
video_root = video_tree.getroot()
self._parse_enums(root, video_root)
self._parse_types(root, video_root)
self.copyright = root.find('./comment').text
self.video_copyright = video_root.find('./comment').text
root.extend(video_root)
self._parse_enums(root)
self._parse_types(root)
self._parse_commands(root)
# Pull in any required types and functions.
self._parse_features(root)
self._parse_extensions(root, video_root)
self._parse_extensions(root)
for enum in self.enums.values():
enum.fixup_64bit_aliases()
self._match_object_types()
self.copyright = root.find('./comment').text
self.video_copyright = video_root.find('./comment').text
def _is_feature_supported(self, feature):
version = self.version_regex.match(feature)
if not version:
@ -3426,11 +3429,11 @@ class VkRegistry(object):
# calls when needed e.g. to adjust member variables.
self.funcs = OrderedDict(sorted(funcs.items()))
def _parse_enums(self, root, video_root):
def _parse_enums(self, root):
""" Parse enums section or better described as constants section. """
enums = {}
self.consts = []
for enum in root.findall("./enums") + video_root.findall("./enums"):
for enum in root.findall("./enums"):
name = enum.attrib.get("name")
_type = enum.attrib.get("type")
@ -3522,10 +3525,10 @@ class VkRegistry(object):
if "data" in member.type_info:
VkRegistry._require_type(member.type_info["data"])
def _parse_extensions(self, root, video_root):
def _parse_extensions(self, root):
""" Parse extensions section and pull in any types and commands for this extension. """
extensions = []
exts = root.findall("./extensions/extension") + video_root.findall("./extensions/extension")
exts = root.findall("./extensions/extension")
deferred_exts = []
skipped_exts = UNSUPPORTED_EXTENSIONS.copy()
@ -3688,9 +3691,9 @@ class VkRegistry(object):
type_info = self.types[name]
type_info["data"].required = True
def _parse_types(self, root, video_root):
def _parse_types(self, root):
""" Parse types section, which contains all data types e.g. structs, typedefs etcetera. """
types = root.findall("./types/type") + video_root.findall("./types/type")
types = root.findall("./types/type")
base_types = []
bitmasks = []

View file

@ -174,7 +174,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data,
}
conf->state = window_state;
conf->scale = NtUserGetWinMonitorDpi(data->hwnd, MDT_RAW_DPI) / 96.0;
conf->scale = NtUserGetSystemDpiForProcess(0) / 96.0;
conf->visible = (style & WS_VISIBLE) == WS_VISIBLE;
conf->managed = data->managed;
}

View file

@ -1622,7 +1622,7 @@ static BOOL export_hdrop( Display *display, Window win, Atom prop, Atom target,
{
static const char hex_table[] = "0123456789abcdef";
textUriList[next++] = '%';
textUriList[next++] = hex_table[unixFilename[u] >> 4];
textUriList[next++] = hex_table[(unsigned char)unixFilename[u] >> 4];
textUriList[next++] = hex_table[unixFilename[u] & 0xf];
}
textUriList[next++] = '\r';

View file

@ -171,13 +171,49 @@ static inline void free_event_data( XEvent *event )
#endif
}
static BOOL host_window_filter_event( XEvent *event )
static void host_window_send_configure_events( struct host_window *win, Display *display, unsigned long serial, XEvent *previous )
{
XConfigureEvent configure = {.type = ConfigureNotify, .serial = serial, .display = display};
unsigned int i;
for (i = 0; i < win->children_count; i++)
{
RECT rect = win->children[i].rect;
struct x11drv_win_data *data;
HWND hwnd;
configure.event = win->children[i].window;
configure.window = configure.event;
configure.x = rect.left;
configure.y = rect.top;
configure.width = rect.right - rect.left;
configure.height = rect.bottom - rect.top;
configure.send_event = 0;
/* Only send a fake event if we're not expecting one from a state/config request.
* We may know what was requested, but not what the WM will decide to reply, and our
* fake event might trigger some undesired changes before the real ConfigureNotify.
*/
if (!XFindContext( configure.display, configure.window, winContext, (char **)&hwnd ) &&
(data = get_win_data( hwnd )))
{
/* embedded windows won't receive synthetic ConfigureNotify and are positioned by the WM */
BOOL has_serial = !data->embedded && (data->wm_state_serial || data->configure_serial);
release_win_data( data );
if (has_serial) continue;
}
if (previous->type == ConfigureNotify && previous->xconfigure.window == configure.window) continue;
TRACE( "generating ConfigureNotify for window %p/%lx, rect %s\n", hwnd, configure.window, wine_dbgstr_rect(&rect) );
XPutBackEvent( configure.display, (XEvent *)&configure );
}
}
static BOOL host_window_filter_event( XEvent *event, XEvent *previous )
{
struct host_window *win;
RECT old_rect;
if (!(win = get_host_window( event->xany.window, FALSE ))) return FALSE;
old_rect = win->rect;
switch (event->type)
{
@ -190,6 +226,7 @@ static BOOL host_window_filter_event( XEvent *event )
XReparentEvent *reparent = (XReparentEvent *)event;
TRACE( "host window %p/%lx ReparentNotify, parent %lx\n", win, win->window, reparent->parent );
host_window_set_parent( win, reparent->parent );
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
break;
}
case GravityNotify:
@ -198,6 +235,7 @@ static BOOL host_window_filter_event( XEvent *event )
OffsetRect( &win->rect, gravity->x - win->rect.left, gravity->y - win->rect.top );
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, FALSE );
TRACE( "host window %p/%lx GravityNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
break;
}
case ConfigureNotify:
@ -206,44 +244,11 @@ static BOOL host_window_filter_event( XEvent *event )
SetRect( &win->rect, configure->x, configure->y, configure->x + configure->width, configure->y + configure->height );
if (win->parent) win->rect = host_window_configure_child( win->parent, win->window, win->rect, configure->send_event );
TRACE( "host window %p/%lx ConfigureNotify, rect %s\n", win, win->window, wine_dbgstr_rect(&win->rect) );
host_window_send_configure_events( win, event->xany.display, event->xany.serial, previous );
break;
}
}
if (old_rect.left != win->rect.left || old_rect.top != win->rect.top)
{
XConfigureEvent configure = {.type = ConfigureNotify, .serial = event->xany.serial, .display = event->xany.display};
unsigned int i;
for (i = 0; i < win->children_count; i++)
{
RECT rect = win->children[i].rect;
struct x11drv_win_data *data;
BOOL has_serial;
HWND hwnd;
/* Only send a fake event if we're not expecting one from a state/config request.
* We may know what was requested, but not what the WM will decide to reply, and our
* fake event might trigger some undesired changes before the real ConfigureNotify.
*/
if (XFindContext( event->xany.display, event->xany.window, winContext, (char **)&hwnd )) continue;
if (!(data = get_win_data( hwnd ))) continue;
has_serial = data->wm_state_serial || data->configure_serial;
release_win_data( data );
if (has_serial) continue;
configure.event = win->children[i].window;
configure.window = configure.event;
configure.x = rect.left;
configure.y = rect.top;
configure.width = rect.right - rect.left;
configure.height = rect.bottom - rect.top;
configure.send_event = 0;
XPutBackEvent( configure.display, (XEvent *)&configure );
}
}
return TRUE;
}
@ -521,7 +526,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
continue; /* filtered, ignore it */
}
if (host_window_filter_event( &event )) continue;
if (host_window_filter_event( &event, &prev_event )) continue;
get_event_data( &event );
if (prev_event.type) action = merge_events( &prev_event, &event );
@ -756,12 +761,20 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
}
else if (protocol == x11drv_atom(WM_TAKE_FOCUS))
{
HWND last_focus = x11drv_thread_data()->last_focus;
HWND last_focus = x11drv_thread_data()->last_focus, foreground = NtUserGetForegroundWindow();
TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08x), focus=%p, active=%p, fg=%p, last=%p\n",
hwnd, NtUserIsWindowEnabled(hwnd), NtUserIsWindowVisible(hwnd),
(int)NtUserGetWindowLongW(hwnd, GWL_STYLE),
get_focus(), get_active_window(), NtUserGetForegroundWindow(), last_focus );
if (window_has_pending_wm_state( hwnd, -1 ))
{
WARN( "Ignoring window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p during WM_STATE change\n",
hwnd, event->window, event->serial, event_time, foreground );
return;
}
TRACE( "window %p/%lx WM_TAKE_FOCUS serial %lu, event_time %ld, foreground %p\n", hwnd, event->window,
event->serial, event_time, foreground );
TRACE( " enabled %u, visible %u, style %#x, focus %p, active %p, last %p\n",
NtUserIsWindowEnabled( hwnd ), NtUserIsWindowVisible( hwnd ), (int)NtUserGetWindowLongW( hwnd, GWL_STYLE ),
get_focus(), get_active_window(), last_focus );
if (can_activate_window(hwnd))
{
@ -778,7 +791,7 @@ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event )
}
else if (hwnd == NtUserGetDesktopWindow())
{
hwnd = NtUserGetForegroundWindow();
hwnd = foreground;
if (!hwnd) hwnd = last_focus;
if (!hwnd) hwnd = NtUserGetDesktopWindow();
set_focus( event->display, hwnd, event_time );
@ -840,14 +853,23 @@ BOOL is_current_process_focused(void)
*/
static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
{
HWND foreground = NtUserGetForegroundWindow();
XFocusChangeEvent *event = &xev->xfocus;
BOOL was_grabbed;
if (event->detail == NotifyPointer) return FALSE;
if (!hwnd) return FALSE;
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
if (window_has_pending_wm_state( hwnd, -1 ))
{
WARN( "Ignoring window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
return FALSE;
}
TRACE( "window %p/%lx FocusIn serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
if (event->detail == NotifyPointer) return FALSE;
/* when focusing in the virtual desktop window, re-apply the cursor clipping rect */
if (is_virtual_desktop() && hwnd == NtUserGetDesktopWindow()) reapply_cursor_clipping();
if (hwnd == NtUserGetDesktopWindow()) return FALSE;
@ -916,10 +938,9 @@ static void focus_out( Display *display , HWND hwnd )
*/
static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
{
HWND foreground = NtUserGetForegroundWindow();
XFocusChangeEvent *event = &xev->xfocus;
TRACE( "win %p xwin %lx detail=%s mode=%s\n", hwnd, event->window, focus_details[event->detail], focus_modes[event->mode] );
if (event->detail == NotifyPointer)
{
if (!hwnd && event->window == x11drv_thread_data()->clip_window)
@ -933,6 +954,16 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
}
if (!hwnd) return FALSE;
if (window_has_pending_wm_state( hwnd, NormalState )) /* ignore FocusOut only if the window is being shown */
{
WARN( "Ignoring window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p during WM_STATE change\n",
hwnd, event->window, event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
return FALSE;
}
TRACE( "window %p/%lx FocusOut serial %lu, detail %s, mode %s, foreground %p\n", hwnd, event->window,
event->serial, focus_details[event->detail], focus_modes[event->mode], foreground );
/* in virtual desktop mode or when keyboard is grabbed, release any cursor grab but keep the clipping rect */
keyboard_grabbed = event->mode == NotifyGrab || event->mode == NotifyWhileGrabbed;
if (is_virtual_desktop() || keyboard_grabbed) ungrab_clipping_window();
@ -1073,9 +1104,7 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
struct x11drv_win_data *data;
RECT rect;
POINT pos = {event->x, event->y};
UINT flags;
int cx, cy, x, y;
DWORD style;
UINT config_cmd;
if (!hwnd) return FALSE;
if (!(data = get_win_data( hwnd ))) return FALSE;
@ -1094,80 +1123,17 @@ static BOOL X11DRV_ConfigureNotify( HWND hwnd, XEvent *xev )
SetRect( &rect, pos.x, pos.y, pos.x + event->width, pos.y + event->height );
window_configure_notify( data, event->serial, &rect );
if (!data->mapped || data->iconic) goto done;
if (!data->whole_window || !data->managed) goto done;
if (data->configure_serial && (long)(data->configure_serial - event->serial) > 0)
{
TRACE( "win %p/%lx event %d,%d,%dx%d ignoring old serial %lu/%lu\n",
hwnd, data->whole_window, event->x, event->y, event->width, event->height,
event->serial, data->configure_serial );
goto done;
}
rect = window_rect_from_visible( &data->rects, rect );
TRACE( "win %p/%lx new X rect %d,%d,%dx%d (event %d,%d,%dx%d)\n",
hwnd, data->whole_window, (int)rect.left, (int)rect.top,
(int)(rect.right-rect.left), (int)(rect.bottom-rect.top),
event->x, event->y, event->width, event->height );
/* Compare what has changed */
x = rect.left;
y = rect.top;
cx = rect.right - rect.left;
cy = rect.bottom - rect.top;
flags = SWP_NOACTIVATE | SWP_NOZORDER;
if (!data->whole_window) flags |= SWP_NOCOPYBITS; /* we can't copy bits of foreign windows */
if (data->rects.window.left == x && data->rects.window.top == y) flags |= SWP_NOMOVE;
else
TRACE( "%p moving from (%d,%d) to (%d,%d)\n",
hwnd, (int)data->rects.window.left, (int)data->rects.window.top, x, y );
if ((data->rects.window.right - data->rects.window.left == cx &&
data->rects.window.bottom - data->rects.window.top == cy) ||
IsRectEmpty( &data->rects.window ))
flags |= SWP_NOSIZE;
else
TRACE( "%p resizing from (%dx%d) to (%dx%d)\n",
hwnd, (int)(data->rects.window.right - data->rects.window.left),
(int)(data->rects.window.bottom - data->rects.window.top), cx, cy );
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if ((style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
{
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
if ((data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
{
if (!(style & WS_MAXIMIZE))
{
TRACE( "win %p/%lx is maximized\n", data->hwnd, data->whole_window );
release_win_data( data );
send_message( data->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
return TRUE;
}
}
else if (style & WS_MAXIMIZE)
{
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
release_win_data( data );
send_message( data->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
return TRUE;
}
}
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
{
release_win_data( data );
NtUserSetRawWindowPos( hwnd, rect, flags, FALSE );
return TRUE;
}
done:
config_cmd = window_update_client_config( data );
rect = window_rect_from_visible( &data->rects, data->current_state.rect );
release_win_data( data );
return FALSE;
if (config_cmd)
{
if (LOWORD(config_cmd) == SC_MOVE) NtUserSetRawWindowPos( hwnd, rect, HIWORD(config_cmd), FALSE );
else send_message( hwnd, WM_SYSCOMMAND, LOWORD(config_cmd), 0 );
}
return !!config_cmd;
}
@ -1230,7 +1196,7 @@ static int get_window_xembed_info( Display *display, Window window )
static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL update_window )
{
struct x11drv_win_data *data;
UINT style, value = 0;
UINT value = 0, state_cmd = 0;
if (!(data = get_win_data( hwnd ))) return;
if (event->state == PropertyNewValue) value = get_window_wm_state( event->display, event->window );
@ -1251,61 +1217,20 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat
TRACE( "%p/%lx: new WM_STATE %d from %d\n",
data->hwnd, data->whole_window, new_state, old_state );
data->wm_state = new_state;
/* ignore the initial state transition out of withdrawn state */
/* metacity does Withdrawn->NormalState->IconicState when mapping an iconic window */
if (!old_state) goto done;
}
}
break;
}
if (!update_window || !data->managed || !data->mapped) goto done;
if (update_window) state_cmd = window_update_client_state( data );
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if (data->iconic && data->wm_state == NormalState) /* restore window */
{
data->iconic = FALSE;
data->net_wm_state = get_window_net_wm_state( event->display, data->whole_window );
if ((style & WS_CAPTION) == WS_CAPTION && (data->net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
{
if ((style & WS_MAXIMIZEBOX) && !(style & WS_DISABLED))
{
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
release_win_data( data );
send_message( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0 );
return;
}
TRACE( "not restoring to max win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
}
else
{
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
release_win_data( data );
if ((style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE))
NtUserSetActiveWindow( hwnd );
send_message( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 );
return;
}
TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
}
}
else if (!data->iconic && data->wm_state == IconicState)
{
data->iconic = TRUE;
if ((style & WS_MINIMIZEBOX) && !(style & WS_DISABLED))
{
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
release_win_data( data );
send_message( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
return;
}
TRACE( "not minimizing win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );
}
done:
release_win_data( data );
if (state_cmd)
{
if (LOWORD(state_cmd) == SC_RESTORE && HIWORD(state_cmd)) NtUserSetActiveWindow( hwnd );
send_message( hwnd, WM_SYSCOMMAND, LOWORD(state_cmd), 0 );
}
}
static void handle_xembed_info_notify( HWND hwnd, XPropertyEvent *event )

View file

@ -46,7 +46,7 @@
#include "winuser.h"
#include "winreg.h"
#include "winnls.h"
#include "ime.h"
#include "kbd.h"
#include "wine/server.h"
#include "wine/debug.h"

View file

@ -1160,7 +1160,7 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
long monitors[4];
XEvent xev;
if (!(data->net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
if (!(data->pending_state.net_wm_state & (1 << NET_WM_STATE_FULLSCREEN)) || is_virtual_desktop()
|| NtUserGetWindowLongW( data->hwnd, GWL_STYLE ) & WS_MINIMIZE)
return;
@ -1211,10 +1211,12 @@ static void update_net_wm_fullscreen_monitors( struct x11drv_win_data *data )
static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_state )
{
UINT i, count;
UINT i, count, old_state = data->pending_state.net_wm_state;
if (!data->whole_window) return; /* no window, nothing to update */
if (old_state == new_state) return; /* states are the same, nothing to update */
if (data->pending_state.wm_state == IconicState) return; /* window is iconic, don't update its state now */
if (!data->mapped) /* set the _NET_WM_STATE atom directly */
{
Atom atoms[NB_NET_WM_STATES + 1];
@ -1250,6 +1252,8 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
for (i = 0; i < NB_NET_WM_STATES; i++)
{
if (!((old_state ^ new_state) & (1 << i))) continue;
xev.xclient.data.l[0] = (new_state & (1 << i)) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = X11DRV_Atoms[net_wm_state_atoms[i] - FIRST_XATOM];
xev.xclient.data.l[2] = ((net_wm_state_atoms[i] == XATOM__NET_WM_STATE_MAXIMIZED_VERT) ?
@ -1268,9 +1272,11 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat
static void window_set_config( struct x11drv_win_data *data, const RECT *new_rect, BOOL above )
{
UINT style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), mask = 0;
const RECT *old_rect = &data->pending_state.rect;
XWindowChanges changes;
if (!data->whole_window) return; /* no window, nothing to update */
if (EqualRect( old_rect, new_rect )) return; /* rects are the same, nothing to update */
/* resizing a managed maximized window is not allowed */
if (!(style & WS_MAXIMIZE) || !data->managed)
@ -1322,7 +1328,7 @@ static void update_net_wm_states( struct x11drv_win_data *data )
style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if (style & WS_MINIMIZE)
new_state |= data->net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
new_state |= data->pending_state.net_wm_state & ((1 << NET_WM_STATE_FULLSCREEN)|(1 << NET_WM_STATE_MAXIMIZED));
if (data->is_fullscreen)
{
if ((style & WS_MAXIMIZE) && (style & WS_CAPTION) == WS_CAPTION)
@ -1346,7 +1352,6 @@ static void update_net_wm_states( struct x11drv_win_data *data )
}
window_set_net_wm_state( data, new_state );
data->net_wm_state = new_state;
update_net_wm_fullscreen_monitors( data );
}
@ -1412,8 +1417,8 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state )
data->pending_state.wm_state = new_state;
data->wm_state_serial = NextRequest( data->display );
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu\n", data->hwnd, data->whole_window,
old_state, new_state, data->wm_state_serial );
TRACE( "window %p/%lx, requesting WM_STATE %#x -> %#x serial %lu, foreground %p\n", data->hwnd, data->whole_window,
old_state, new_state, data->wm_state_serial, NtUserGetForegroundWindow() );
switch (MAKELONG(old_state, new_state))
{
@ -1484,11 +1489,87 @@ static void unmap_window( HWND hwnd )
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
window_set_wm_state( data, WithdrawnState );
data->mapped = FALSE;
data->net_wm_state = 0;
}
release_win_data( data );
}
UINT window_update_client_state( struct x11drv_win_data *data )
{
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE );
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
if (!data->mapped) return 0; /* ignore state changes on invisible windows */
if (data->iconic && data->current_state.wm_state == NormalState) /* restore window */
{
data->iconic = FALSE;
if ((old_style & WS_CAPTION) == WS_CAPTION && (data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)))
{
if ((old_style & WS_MAXIMIZEBOX) && !(old_style & WS_DISABLED))
{
TRACE( "restoring to max %p/%lx\n", data->hwnd, data->whole_window );
return SC_MAXIMIZE;
}
}
else if (old_style & (WS_MINIMIZE | WS_MAXIMIZE))
{
BOOL activate = (old_style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE);
TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window );
return MAKELONG(SC_RESTORE, activate);
}
}
else if (!data->iconic && data->current_state.wm_state == IconicState)
{
data->iconic = TRUE;
if ((old_style & WS_MINIMIZEBOX) && !(old_style & WS_DISABLED))
{
TRACE( "minimizing win %p/%lx\n", data->hwnd, data->whole_window );
return SC_MINIMIZE;
}
}
return 0;
}
UINT window_update_client_config( struct x11drv_win_data *data )
{
UINT old_style = NtUserGetWindowLongW( data->hwnd, GWL_STYLE ), flags;
RECT rect, old_rect = data->rects.window, new_rect;
if (!data->managed) return 0; /* unmanaged windows are managed by the Win32 side */
if (!data->mapped) return 0; /* ignore config changes on invisible windows */
if (data->iconic) return 0; /* ignore config changes on minimized windows */
if (data->configure_serial) return 0; /* another config update is pending, wait for it to complete */
if ((old_style & WS_CAPTION) == WS_CAPTION || !data->is_fullscreen)
{
if ((data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && !(old_style & WS_MAXIMIZE))
{
TRACE( "window %p/%lx is maximized\n", data->hwnd, data->whole_window );
return SC_MAXIMIZE;
}
if (!(data->current_state.net_wm_state & (1 << NET_WM_STATE_MAXIMIZED)) && (old_style & WS_MAXIMIZE))
{
TRACE( "window %p/%lx is no longer maximized\n", data->hwnd, data->whole_window );
return SC_RESTORE;
}
}
flags = SWP_NOACTIVATE | SWP_NOZORDER;
rect = new_rect = window_rect_from_visible( &data->rects, data->current_state.rect );
if (new_rect.left == old_rect.left && new_rect.top == old_rect.top) flags |= SWP_NOMOVE;
else OffsetRect( &rect, old_rect.left - new_rect.left, old_rect.top - new_rect.top );
if (rect.right == old_rect.right && rect.bottom == old_rect.bottom) flags |= SWP_NOSIZE;
else if (IsRectEmpty( &rect )) flags |= SWP_NOSIZE;
if ((flags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) return 0;
TRACE( "window %p/%lx config changed %s -> %s, flags %#x\n", data->hwnd, data->whole_window,
wine_dbgstr_rect(&old_rect), wine_dbgstr_rect(&new_rect), flags );
return MAKELONG(SC_MOVE, flags);
}
void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value )
{
UINT *pending = &data->pending_state.wm_state, *current = &data->current_state.wm_state;
@ -1587,6 +1668,19 @@ void window_configure_notify( struct x11drv_win_data *data, unsigned long serial
*expect_serial = 0;
}
BOOL window_has_pending_wm_state( HWND hwnd, UINT state )
{
struct x11drv_win_data *data;
BOOL pending;
if (!(data = get_win_data( hwnd ))) return FALSE;
if (state != -1 && data->pending_state.wm_state != state) pending = FALSE;
else pending = !!data->wm_state_serial;
release_win_data( data );
return pending;
}
/***********************************************************************
* make_window_embedded
*/
@ -1594,7 +1688,6 @@ void make_window_embedded( struct x11drv_win_data *data )
{
/* the window cannot be mapped before being embedded */
window_set_wm_state( data, WithdrawnState );
data->net_wm_state = 0;
data->embedded = TRUE;
data->managed = TRUE;
sync_window_style( data );
@ -2006,7 +2099,6 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
data->whole_window = data->client_window = 0;
data->whole_colormap = 0;
data->wm_state = WithdrawnState;
data->net_wm_state = 0;
data->mapped = FALSE;
memset( &data->pending_state, 0, sizeof(data->pending_state) );
@ -2314,7 +2406,12 @@ void set_window_parent( struct x11drv_win_data *data, Window parent )
if (!data->whole_window) return; /* only keep track of parent if we have a toplevel */
TRACE( "window %p/%lx, parent %lx\n", data->hwnd, data->whole_window, parent );
host_window_reparent( &data->parent, parent, data->whole_window );
if (data->parent) host_window_configure_child( data->parent, data->whole_window, data->rects.visible, TRUE );
if (data->parent)
{
RECT rect = data->rects.visible;
OffsetRect( &rect, -rect.left, -rect.top );
host_window_configure_child( data->parent, data->whole_window, rect, TRUE );
}
data->parent_invalid = 0;
}
@ -2468,6 +2565,7 @@ BOOL X11DRV_SystrayDockInsert( HWND hwnd, UINT cx, UINT cy, void *icon )
window = data->whole_window;
release_win_data( data );
NtUserSetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOZORDER );
NtUserShowWindow( hwnd, SW_SHOWNA );
TRACE_(systray)( "icon window %p/%lx\n", hwnd, window );

View file

@ -236,7 +236,7 @@ typedef struct tagWTI_DEVICES_INFO
#define CSR_TYPE_OTHER 0x000
typedef struct tagWTPACKET {
HCTX pkContext;
UINT pkContext;
UINT pkStatus;
LONG pkTime;
WTPKT pkChanged;

View file

@ -634,7 +634,6 @@ struct x11drv_win_data
UINT is_fullscreen : 1; /* is the window visible rect fullscreen */
UINT parent_invalid : 1; /* is the parent host window possibly invalid */
int wm_state; /* current value of the WM_STATE property */
DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */
Window embedder; /* window id of embedder */
Pixmap icon_pixmap;
Pixmap icon_mask;
@ -659,9 +658,13 @@ extern void set_gl_drawable_parent( HWND hwnd, HWND parent );
extern void destroy_gl_drawable( HWND hwnd );
extern void destroy_vk_surface( HWND hwnd );
extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state );
extern void window_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
extern void window_net_wm_state_notify( struct x11drv_win_data *data, unsigned long serial, UINT value );
extern void window_configure_notify( struct x11drv_win_data *data, unsigned long serial, const RECT *rect );
extern UINT window_update_client_state( struct x11drv_win_data *data );
extern UINT window_update_client_config( struct x11drv_win_data *data );
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set );
extern Window init_clip_window(void);
extern void update_user_time( Time time );

View file

@ -811,12 +811,6 @@ C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
#ifdef _WIN64
static NTSTATUS x11drv_wow64_tablet_get_packet( void *arg )
{
FIXME( "%p\n", arg );
return 0;
}
static NTSTATUS x11drv_wow64_tablet_info( void *arg )
{
struct
@ -837,7 +831,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{
x11drv_init,
x11drv_tablet_attach_queue,
x11drv_wow64_tablet_get_packet,
x11drv_tablet_get_packet,
x11drv_wow64_tablet_info,
x11drv_tablet_load_info,
};

View file

@ -4628,6 +4628,7 @@ struct winhttp_request
WINHTTP_PROXY_INFO proxy;
BOOL async;
UINT url_codepage;
DWORD security_flags;
};
static inline struct winhttp_request *impl_from_IWinHttpRequest( IWinHttpRequest *iface )
@ -5378,6 +5379,9 @@ static DWORD request_set_parameters( struct winhttp_request *request )
if (!WinHttpSetOption( request->hrequest, WINHTTP_OPTION_DISABLE_FEATURE, &request->disable_feature,
sizeof(request->disable_feature) )) return GetLastError();
if (!WinHttpSetOption( request->hrequest, WINHTTP_OPTION_SECURITY_FLAGS, &request->security_flags,
sizeof(request->security_flags) )) return GetLastError();
if (!WinHttpSetTimeouts( request->hrequest,
request->resolve_timeout,
request->connect_timeout,
@ -5935,6 +5939,12 @@ static HRESULT WINAPI winhttp_request_get_Option(
V_VT( value ) = VT_I4;
V_I4( value ) = request->url_codepage;
break;
case WinHttpRequestOption_SslErrorIgnoreFlags:
{
V_VT( value ) = VT_I4;
V_I4( value ) = request->security_flags;
break;
}
default:
FIXME("unimplemented option %u\n", option);
hr = E_NOTIMPL;
@ -5985,6 +5995,20 @@ static HRESULT WINAPI winhttp_request_put_Option(
FIXME("URL codepage %s is not recognized\n", debugstr_variant( &value ));
break;
}
case WinHttpRequestOption_SslErrorIgnoreFlags:
{
static const DWORD accepted = SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
SECURITY_FLAG_IGNORE_UNKNOWN_CA |
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
DWORD flags = V_I4( &value );
if (flags && (flags & ~accepted))
hr = E_INVALIDARG;
else
request->security_flags = flags;
break;
}
default:
FIXME("unimplemented option %u\n", option);
hr = E_NOTIMPL;

View file

@ -4607,7 +4607,7 @@ static void test_IWinHttpRequest(int port)
IWinHttpRequest *req;
BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
BSTR date, today, connection, value = NULL;
VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp;
VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp, flags;
VARIANT_BOOL succeeded;
LONG status;
WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
@ -4683,6 +4683,24 @@ static void test_IWinHttpRequest(int port)
hr = IWinHttpRequest_Open( req, method, url, async );
ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %#lx\n", hr );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_VT( &flags ) == VT_I4, "got %#x\n", V_VT( &flags ) );
ok( V_I4( &flags ) == 0, "got %lx\n", V_I4( &flags ) );
V_VT( &flags ) = VT_I4;
V_I4( &flags ) = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags );
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_I4( &flags ) == SECURITY_FLAG_IGNORE_UNKNOWN_CA, "got %lx\n", V_I4( &flags ) );
SysFreeString( method );
method = SysAllocString( L"GET" );
SysFreeString( url );
@ -4725,6 +4743,44 @@ static void test_IWinHttpRequest(int port)
ok( V_VT( &cp ) == VT_I4, "got %#x\n", V_VT( &cp ) );
ok( V_I4( &cp ) == CP_UTF8, "got %ld\n", V_I4( &cp ) );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_I4( &flags ) == SECURITY_FLAG_IGNORE_UNKNOWN_CA, "got %lx\n", V_I4( &flags ) );
V_VT( &flags ) = VT_I4;
V_I4( &flags ) = 0x321;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags );
ok( hr == E_INVALIDARG, "got %#lx\n", hr );
V_VT( &flags ) = VT_UI4;
V_UI4( &flags ) = 0x123;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags );
ok( hr == E_INVALIDARG, "got %#lx\n", hr );
V_VT( &flags ) = VT_UI4;
V_UI4( &flags ) = SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags);
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_I4( &flags ) == SECURITY_FLAG_IGNORE_CERT_DATE_INVALID, "got %lx\n", V_I4( &flags ) );
V_VT( &flags ) = VT_I4;
V_I4( &flags ) = SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags );
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_I4( &flags ) == (SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE), "got %lx\n", V_I4( &flags ) );
hr = IWinHttpRequest_Abort( req );
ok( hr == S_OK, "got %#lx\n", hr );
@ -4857,6 +4913,11 @@ static void test_IWinHttpRequest(int port)
hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &flags ) = VT_I4;
V_I4( &flags ) = SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, flags );
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &proxy_server ) = VT_BSTR;
V_BSTR( &proxy_server ) = SysAllocString( L"proxyserver" );
V_VT( &bypass_list ) = VT_BSTR;
@ -4891,6 +4952,12 @@ static void test_IWinHttpRequest(int port)
hr = IWinHttpRequest_Send( req, empty );
ok( hr == S_OK, "got %#lx\n", hr );
V_VT( &flags ) = VT_ERROR;
V_ERROR( &flags ) = 0xdeadbeef;
hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_SslErrorIgnoreFlags, &flags );
ok( hr == S_OK, "got %#lx\n", hr );
ok( V_I4( &flags ) == (SECURITY_FLAG_IGNORE_UNKNOWN_CA|SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE), "got %lx\n", V_I4( &flags ) );
hr = IWinHttpRequest_get_ResponseText( req, NULL );
ok( hr == E_INVALIDARG, "got %#lx\n", hr );

View file

@ -3886,26 +3886,23 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
}
else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer)
{
time_t tmpTime;
struct tm tmpTM;
SYSTEMTIME *STHook;
SYSTEMTIME st;
tmpTime = ConvertTimeString(lphttpHdr->lpszValue);
tmpTM = *gmtime(&tmpTime);
STHook = (SYSTEMTIME *)lpBuffer;
STHook->wDay = tmpTM.tm_mday;
STHook->wHour = tmpTM.tm_hour;
STHook->wMilliseconds = 0;
STHook->wMinute = tmpTM.tm_min;
STHook->wDayOfWeek = tmpTM.tm_wday;
STHook->wMonth = tmpTM.tm_mon + 1;
STHook->wSecond = tmpTM.tm_sec;
STHook->wYear = 1900+tmpTM.tm_year;
TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek,
STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds);
if (!InternetTimeToSystemTimeW(lphttpHdr->lpszValue, &st, 0))
{
LeaveCriticalSection( &request->headers_section );
return ERROR_HTTP_INVALID_HEADER;
}
if (*lpdwBufferLength < sizeof(st))
{
*lpdwBufferLength = sizeof(st);
LeaveCriticalSection( &request->headers_section );
return ERROR_INSUFFICIENT_BUFFER;
}
TRACE(" returning time: %04u/%02u/%02u - %u - %02u:%02u:%02u.%02u\n",
st.wYear, st.wMonth, st.wDay, st.wDayOfWeek, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
memcpy(lpBuffer, &st, sizeof(st));
*lpdwBufferLength = sizeof(st);
}
else if (lphttpHdr->lpszValue)
{
@ -4521,7 +4518,7 @@ static BOOL HTTP_ParseDateAsAsctime(LPCWSTR value, FILETIME *ft)
/* asctime() doesn't report a timezone, but some web servers do, so accept
* with or without GMT.
*/
if (*ptr && wcscmp(ptr, L"GMT"))
if (*ptr && (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC")))
{
ERR("unexpected timezone %s\n", debugstr_w(ptr));
return FALSE;
@ -4598,7 +4595,7 @@ static BOOL HTTP_ParseRfc1123Date(LPCWSTR value, FILETIME *ft)
while (iswspace(*ptr))
ptr++;
if (wcscmp(ptr, L"GMT"))
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
{
ERR("unexpected time zone %s\n", debugstr_w(ptr));
return FALSE;
@ -4715,7 +4712,7 @@ static BOOL HTTP_ParseRfc850Date(LPCWSTR value, FILETIME *ft)
while (iswspace(*ptr))
ptr++;
if (wcscmp(ptr, L"GMT"))
if (wcscmp(ptr, L"GMT") && wcscmp(ptr, L"UTC"))
{
ERR("unexpected time zone %s\n", debugstr_w(ptr));
return FALSE;

View file

@ -2412,6 +2412,7 @@ static const char okmsg2[] =
"Content-Length: 0\r\n"
"Set-Cookie: one\r\n"
"Set-Cookie: two\r\n"
"Last-Modified: Mon, 01 Dec 2008 13:44:34 UTC\r\n"
"\r\n";
static DWORD64 content_length;
@ -4566,9 +4567,11 @@ static void test_head_request(int port)
static void test_HttpQueryInfo(int port)
{
static const SYSTEMTIME expect = {2008, 12, 1, 1, 13, 44, 34};
test_request_t req;
DWORD size, index, error;
char buffer[1024];
SYSTEMTIME st;
BOOL ret;
open_simple_request(&req, "localhost", port, NULL, "/testD");
@ -4589,9 +4592,27 @@ static void test_HttpQueryInfo(int port)
ok(index == 1, "expected 1 got %lu\n", index);
index = 0;
size = sizeof(buffer);
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, buffer, &size, &index);
size = 0;
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
ok(size == sizeof(st), "got %lu\n", size);
index = 0;
size = sizeof(st) + 1;
memset(&st, 0, sizeof(st));
ret = HttpQueryInfoA(req.request, HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
ok(size == sizeof(st), "got %lu\n", size);
ok(index == 1, "expected 1 got %lu\n", index);
index = 0;
size = sizeof(st);
memset(&st, 0, sizeof(st));
ret = HttpQueryInfoA(req.request, HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME, &st, &size, &index);
ok(ret, "HttpQueryInfo failed %lu\n", GetLastError());
ok(!memcmp(&st, &expect, sizeof(st)), "wrong time\n");
ok(size == sizeof(st), "got %lu\n", size);
ok(index == 1, "expected 1 got %lu\n", index);
index = 0;

View file

@ -1116,9 +1116,11 @@ static void test_InternetTimeToSystemTime(void)
test_data[] =
{
{ "Fri, 07 Jan 2005 12:06:35 GMT", &expect1, TRUE },
{ "Fri, 07 Jan 2005 12:06:35 UTC", &expect1, TRUE },
{ " fri, 7 jan 2005 12 06 35", &expect1, TRUE },
{ "Fri, 07-01-2005 12:06:35", &expect1, TRUE },
{ "5, 07-01-2005 12:06:35 GMT", &expect1, TRUE },
{ "5, 07-01-2005 12:06:35 UTC", &expect1, TRUE },
{ "5, 07-01-2005 12:06:35 GMT;", &expect1, TRUE },
{ "5, 07-01-2005 12:06:35 GMT123", &expect1, TRUE },
{ "2, 11 01 2022 11 13 05", &expect2, TRUE },
@ -1126,6 +1128,9 @@ static void test_InternetTimeToSystemTime(void)
{ "2, 11*01/2022 11+13=05", &expect2, TRUE },
{ "2, 11-Jan-2022 11:13:05", &expect2, TRUE },
{ "Fr", NULL, FALSE },
{ "Fri Jan 7 12:06:35 2005", &expect1, TRUE, TRUE },
{ "Fri Jan 7 12:06:35 2005 GMT", &expect1, TRUE, TRUE },
{ "Fri Jan 7 12:06:35 2005 UTC", &expect1, TRUE, TRUE },
};
ret = pInternetTimeToSystemTimeA(NULL, NULL, 0);

View file

@ -39,92 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
#define TIME_STRING_LEN 30
time_t ConvertTimeString(LPCWSTR asctime)
{
WCHAR tmpChar[TIME_STRING_LEN];
WCHAR *tmpChar2;
struct tm t;
int timelen = lstrlenW(asctime);
if(!timelen)
return 0;
/* FIXME: the atoiWs below rely on that tmpChar is \0 padded */
memset( tmpChar, 0, sizeof(tmpChar) );
lstrcpynW(tmpChar, asctime, TIME_STRING_LEN);
/* Assert that the string is the expected length */
if (lstrlenW(asctime) >= TIME_STRING_LEN) FIXME("\n");
/* Convert a time such as 'Mon, 15 Nov 1999 16:09:35 GMT' into a SYSTEMTIME structure
* We assume the time is in this format
* and divide it into easy to swallow chunks
*/
tmpChar[3]='\0';
tmpChar[7]='\0';
tmpChar[11]='\0';
tmpChar[16]='\0';
tmpChar[19]='\0';
tmpChar[22]='\0';
tmpChar[25]='\0';
memset( &t, 0, sizeof(t) );
t.tm_year = wcstol(tmpChar+12, NULL, 10) - 1900;
t.tm_mday = wcstol(tmpChar+5, NULL, 10);
t.tm_hour = wcstol(tmpChar+17, NULL, 10);
t.tm_min = wcstol(tmpChar+20, NULL, 10);
t.tm_sec = wcstol(tmpChar+23, NULL, 10);
/* and month */
tmpChar2 = tmpChar + 8;
switch(tmpChar2[2])
{
case 'n':
if(tmpChar2[1]=='a')
t.tm_mon = 0;
else
t.tm_mon = 5;
break;
case 'b':
t.tm_mon = 1;
break;
case 'r':
if(tmpChar2[1]=='a')
t.tm_mon = 2;
else
t.tm_mon = 3;
break;
case 'y':
t.tm_mon = 4;
break;
case 'l':
t.tm_mon = 6;
break;
case 'g':
t.tm_mon = 7;
break;
case 'p':
t.tm_mon = 8;
break;
case 't':
t.tm_mon = 9;
break;
case 'v':
t.tm_mon = 10;
break;
case 'c':
t.tm_mon = 11;
break;
default:
FIXME("\n");
}
return mktime(&t);
}
BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str)
{
ADDRINFOW *res, hints;

View file

@ -102,7 +102,7 @@ static const char* DUMPBITS(int x)
static inline void DUMPPACKET(WTPACKET packet)
{
TRACE("pkContext: %p pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%lx pkChanged: 0x%lx pkSerialNumber: 0x%x pkCursor : %i pkButtons: %lx pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n",
packet.pkContext, packet.pkStatus, packet.pkTime, packet.pkChanged, packet.pkSerialNumber,
packet.pkCursor, packet.pkButtons, packet.pkX, packet.pkY, packet.pkZ,
packet.pkNormalPressure, packet.pkTangentPressure,
@ -205,7 +205,7 @@ LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
tgt = ptr->PacketsQueued;
packet->pkContext = ptr->handle;
packet->pkContext = HandleToULong(ptr->handle);
/* translate packet data to the context */
packet->pkChanged = packet->pkChanged & ptr->context.lcPktData;
@ -296,12 +296,15 @@ static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
LPWTPACKET wtp)
{
LPBYTE ptr;
HCTX ctx;
ptr = lpPkt;
TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData));
ctx = ULongToHandle(wtp->pkContext);
if (context->context.lcPktData & PK_CONTEXT)
ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
ptr+=CopyTabletData(ptr,&ctx,sizeof(HCTX));
if (context->context.lcPktData & PK_STATUS)
ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
if (context->context.lcPktData & PK_TIME)

View file

@ -117,7 +117,7 @@ typedef struct tagWTI_EXTENSIONS_INFO
} WTI_EXTENSIONS_INFO, *LPWTI_EXTENSIONS_INFO;
typedef struct tagWTPACKET {
HCTX pkContext;
UINT pkContext;
UINT pkStatus;
LONG pkTime;
WTPKT pkChanged;

View file

@ -5,4 +5,5 @@ IMPORTS = combase
SOURCES = \
classes.idl \
main.c \
propertyset.c \
wintypes_private.idl

View file

@ -31,6 +31,7 @@
#define WIDL_using_Windows_Foundation
#define WIDL_using_Windows_Foundation_Metadata
#define WIDL_using_Windows_Foundation_Collections
#include "windows.foundation.metadata.h"
#include "wintypes_private.h"
@ -1213,8 +1214,14 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory)
{
const WCHAR *name;
TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
*factory = &wintypes.IActivationFactory_iface;
name = WindowsGetStringRawBuffer(classid, NULL);
if (!wcscmp(name, RuntimeClass_Windows_Foundation_Collections_PropertySet))
*factory = IPropertySet_factory;
else
*factory = &wintypes.IActivationFactory_iface;
IUnknown_AddRef(*factory);
return S_OK;
}

812
dlls/wintypes/propertyset.c Normal file
View file

@ -0,0 +1,812 @@
/*
* Copyright 2024 Vibhav Pant
*
* 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
*/
#define COBJMACROS
#include <winstring.h>
#include <objbase.h>
#include <wine/debug.h>
#include <activation.h>
#define WIDL_using_Windows_Foundation
#define WIDL_using_Windows_Foundation_Collections
#include "wintypes_private.h"
WINE_DEFAULT_DEBUG_CHANNEL( wintypes );
struct kvpair
{
IKeyValuePair_HSTRING_IInspectable IKeyValuePair_HSTRING_IInspectable_iface;
LONG ref;
};
static inline struct kvpair *
impl_from_IKeyValuePair_HSTRING_IInspectable( IKeyValuePair_HSTRING_IInspectable *iface )
{
return CONTAINING_RECORD( iface, struct kvpair, IKeyValuePair_HSTRING_IInspectable_iface );
}
static HRESULT STDMETHODCALLTYPE kvpair_QueryInterface( IKeyValuePair_HSTRING_IInspectable *iface,
REFIID iid, void **out )
{
TRACE( "(%p, %p, %p)\n", iface, debugstr_guid( iid ), out );
*out = NULL;
if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IKeyValuePair_HSTRING_IInspectable ))
{
*out = iface;
IUnknown_AddRef( (IUnknown *)(*out) );
return S_OK;
}
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE kvpair_AddRef( IKeyValuePair_HSTRING_IInspectable *iface )
{
struct kvpair *impl;
TRACE( "(%p)\n", iface );
impl = impl_from_IKeyValuePair_HSTRING_IInspectable( iface );
return InterlockedIncrement( &impl->ref );
}
static ULONG STDMETHODCALLTYPE kvpair_Release( IKeyValuePair_HSTRING_IInspectable *iface )
{
struct kvpair *impl;
ULONG ref;
TRACE( "(%p)\n", iface );
impl = impl_from_IKeyValuePair_HSTRING_IInspectable( iface );
ref = InterlockedDecrement( &impl->ref );
if (!ref)
free( impl );
return ref;
}
static HRESULT STDMETHODCALLTYPE kvpair_GetIIDs( IKeyValuePair_HSTRING_IInspectable *iface,
ULONG *iid_count, IID **iids )
{
FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
kvpair_GetRuntimeClassName( IKeyValuePair_HSTRING_IInspectable *iface, HSTRING *class_name )
{
FIXME( "(%p, %p) stub!\n", iface, class_name );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE kvpair_GetTrustLevel( IKeyValuePair_HSTRING_IInspectable *iface,
TrustLevel *trust_level )
{
FIXME( "(%p, %p) stub!\n", iface, trust_level );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE kvpair_get_Key( IKeyValuePair_HSTRING_IInspectable *iface,
HSTRING *key )
{
FIXME( "(%p, %p) stub!\n", iface, key );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE kvpair_get_Value( IKeyValuePair_HSTRING_IInspectable *iface,
IInspectable **value )
{
FIXME( "(%p, %p) stub!\n", iface, value );
return E_NOTIMPL;
}
const static IKeyValuePair_HSTRING_IInspectableVtbl kvpair_vtbl =
{
kvpair_QueryInterface,
kvpair_AddRef,
kvpair_Release,
kvpair_GetIIDs,
kvpair_GetRuntimeClassName,
kvpair_GetTrustLevel,
kvpair_get_Key,
kvpair_get_Value,
};
static HRESULT kvpair_create( IKeyValuePair_HSTRING_IInspectable **kvpair )
{
struct kvpair *impl;
TRACE( "(%p)\n", kvpair );
*kvpair = NULL;
impl = calloc( 1, sizeof( *impl ) );
if (!impl)
return E_OUTOFMEMORY;
impl->IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl = &kvpair_vtbl;
impl->ref = 1;
*kvpair = &impl->IKeyValuePair_HSTRING_IInspectable_iface;
return S_OK;
}
struct iterator_kvpair_HSTRING_IInspectable
{
IIterator_IKeyValuePair_HSTRING_IInspectable IIterator_IKeyValuePair_HSTRING_IInspectable_iface;
LONG ref;
};
static inline struct iterator_kvpair_HSTRING_IInspectable *
impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface )
{
return CONTAINING_RECORD( iface, struct iterator_kvpair_HSTRING_IInspectable,
IIterator_IKeyValuePair_HSTRING_IInspectable_iface );
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_QueryInterface(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, REFIID iid, void **out )
{
TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
*out = NULL;
if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IIterator_IKeyValuePair_HSTRING_IInspectable ))
{
*out = iface;
IUnknown_AddRef( (IUnknown *)*out );
return S_OK;
}
FIXME( "%s not implemented, returning E_NOINTERFACE.", debugstr_guid( iid ) );
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE
iterator_kvpair_HSTRING_IInspectable_AddRef( IIterator_IKeyValuePair_HSTRING_IInspectable *iface )
{
struct iterator_kvpair_HSTRING_IInspectable *impl;
TRACE( "(%p)\n", iface );
impl = impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable( iface );
return InterlockedIncrement( &impl->ref );
}
static ULONG STDMETHODCALLTYPE
iterator_kvpair_HSTRING_IInspectable_Release( IIterator_IKeyValuePair_HSTRING_IInspectable *iface )
{
struct iterator_kvpair_HSTRING_IInspectable *impl;
ULONG ref;
TRACE( "(%p)\n", iface );
impl = impl_from_IIterator_IKeyValuePair_HSTRING_IInspectable( iface );
ref = InterlockedDecrement( &impl->ref );
if (!ref)
free( impl );
return ref;
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetIids(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, ULONG *iid_count, IID **iids )
{
FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetRuntimeClassName(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, HSTRING *class_name )
{
FIXME( "(%p, %p) stub!\n", iface, class_name );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetTrustLevel(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, TrustLevel *trust_level )
{
FIXME( "(%p, %p) stub!\n", iface, trust_level );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
iterator_kvpair_HSTRING_IInspectable_get_Current( IIterator_IKeyValuePair_HSTRING_IInspectable *iface,
IKeyValuePair_HSTRING_IInspectable **kvpair )
{
FIXME( "(%p, %p) semi-stub!\n", iface, kvpair );
return kvpair_create( kvpair );
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_HasCurrent(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, boolean *exists )
{
FIXME( "(%p, %p) stub!\n", iface, exists );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_MoveNext(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, boolean *valid )
{
FIXME( "(%p, %p) stub!\n", iface, valid );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE iterator_kvpair_HSTRING_IInspectable_GetMany(
IIterator_IKeyValuePair_HSTRING_IInspectable *iface, UINT32 count,
IKeyValuePair_HSTRING_IInspectable **items, UINT32 *value )
{
FIXME( "(%p, %u, %p, %p) stub!\n", iface, count, items, value );
return E_NOTIMPL;
}
const static IIterator_IKeyValuePair_HSTRING_IInspectableVtbl iterator_kvpair_HSTRING_IInspectable_vtbl =
{
/* IUnknown */
iterator_kvpair_HSTRING_IInspectable_QueryInterface,
iterator_kvpair_HSTRING_IInspectable_AddRef,
iterator_kvpair_HSTRING_IInspectable_Release,
/* IInspectable */
iterator_kvpair_HSTRING_IInspectable_GetIids,
iterator_kvpair_HSTRING_IInspectable_GetRuntimeClassName,
iterator_kvpair_HSTRING_IInspectable_GetTrustLevel,
/* IIterator<IKeyValuePair<HSTRING,IInspectable*>> */
iterator_kvpair_HSTRING_IInspectable_get_Current,
iterator_kvpair_HSTRING_IInspectable_HasCurrent,
iterator_kvpair_HSTRING_IInspectable_MoveNext,
iterator_kvpair_HSTRING_IInspectable_GetMany,
};
static HRESULT
iterator_kvpair_HSTRING_IInspectable_create( IIterator_IKeyValuePair_HSTRING_IInspectable **iface )
{
struct iterator_kvpair_HSTRING_IInspectable *impl_iter;
TRACE( "(%p)\n", iface );
impl_iter = calloc( 1, sizeof( *impl_iter ) );
if (!impl_iter)
return E_OUTOFMEMORY;
impl_iter->IIterator_IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl = &iterator_kvpair_HSTRING_IInspectable_vtbl;
impl_iter->ref = 1;
*iface = &impl_iter->IIterator_IKeyValuePair_HSTRING_IInspectable_iface;
return S_OK;
}
struct mapview_HSTRING_IInspectable
{
IMapView_HSTRING_IInspectable IMapView_HSTRING_IInspectable_iface;
IIterable_IKeyValuePair_HSTRING_IInspectable IIterable_IKeyValuePair_HSTRING_IInspectable_iface;
LONG ref;
};
static inline struct mapview_HSTRING_IInspectable *
impl_from_IMapView_HSTRING_IInspectable( IMapView_HSTRING_IInspectable *iface )
{
return CONTAINING_RECORD( iface, struct mapview_HSTRING_IInspectable,
IMapView_HSTRING_IInspectable_iface );
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_QueryInterface(
IMapView_HSTRING_IInspectable *iface, REFIID iid, void **out )
{
TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
*out = NULL;
if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IMapView_HSTRING_IInspectable ))
{
*out = iface;
IUnknown_AddRef( iface );
return S_OK;
}
if (IsEqualGUID( iid, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable ))
{
struct mapview_HSTRING_IInspectable *impl =
impl_from_IMapView_HSTRING_IInspectable( iface );
*out = &impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface;
IUnknown_AddRef( iface );
return S_OK;
}
FIXME( "%s not implemented, returning E_NOTINTERFACE.\n", debugstr_guid( iid ) );
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE
mapview_HSTRING_IInspectable_AddRef( IMapView_HSTRING_IInspectable *iface )
{
struct mapview_HSTRING_IInspectable *impl;
TRACE( "(%p)\n", iface );
impl = impl_from_IMapView_HSTRING_IInspectable( iface );
return InterlockedIncrement( &impl->ref );
}
static ULONG STDMETHODCALLTYPE
mapview_HSTRING_IInspectable_Release( IMapView_HSTRING_IInspectable *iface )
{
struct mapview_HSTRING_IInspectable *impl;
ULONG ref;
TRACE( "(%p)\n", iface );
impl = impl_from_IMapView_HSTRING_IInspectable( iface );
ref = InterlockedDecrement( &impl->ref );
if (!ref)
free( impl );
return ref;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetIids(
IMapView_HSTRING_IInspectable *iface, ULONG *iid_count, IID **iids )
{
FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetRuntimeClassName(
IMapView_HSTRING_IInspectable *iface, HSTRING *class_name )
{
FIXME( "(%p, %p) stub!\n", iface, class_name );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_GetTrustLevel(
IMapView_HSTRING_IInspectable *iface, TrustLevel *trust_level )
{
FIXME( "(%p, %p) stub!\n", iface, trust_level );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
mapview_HSTRING_IInspectable_get_Size( IMapView_HSTRING_IInspectable *iface, UINT32 *size )
{
FIXME( "(%p, %p) stub!\n", iface, size );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_HaKey(
IMapView_HSTRING_IInspectable *iface, HSTRING key, boolean *exists )
{
FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), exists );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_Lookup(
IMapView_HSTRING_IInspectable *iface, HSTRING key, IInspectable **value )
{
FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), value );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE mapview_HSTRING_IInspectable_Split(
IMapView_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **first,
IMapView_HSTRING_IInspectable **second )
{
FIXME( "(%p, %p, %p) stub!\n", iface, first, second );
return E_NOTIMPL;
}
const static IMapView_HSTRING_IInspectableVtbl mapview_HSTRING_IInspectable_vtbl =
{
/* IUnknown */
mapview_HSTRING_IInspectable_QueryInterface,
mapview_HSTRING_IInspectable_AddRef,
mapview_HSTRING_IInspectable_Release,
/* IInspectable */
mapview_HSTRING_IInspectable_GetIids,
mapview_HSTRING_IInspectable_GetRuntimeClassName,
mapview_HSTRING_IInspectable_GetTrustLevel,
/* IMapView<HSTRING, IInspectable*> */
mapview_HSTRING_IInspectable_Lookup,
mapview_HSTRING_IInspectable_get_Size,
mapview_HSTRING_IInspectable_HaKey,
mapview_HSTRING_IInspectable_Split,
};
DEFINE_IINSPECTABLE_( mapview_iterable_kvpair_HSTRING_IInspectable,
IIterable_IKeyValuePair_HSTRING_IInspectable,
struct mapview_HSTRING_IInspectable,
mapview_impl_from_IIterable_IKeyValuePair_HSTRING_IInspectable,
IIterable_IKeyValuePair_HSTRING_IInspectable_iface,
&impl->IMapView_HSTRING_IInspectable_iface );
static HRESULT STDMETHODCALLTYPE mapview_iterable_kvpair_HSTRING_IInspectable_First(
IIterable_IKeyValuePair_HSTRING_IInspectable *iface,
IIterator_IKeyValuePair_HSTRING_IInspectable **iter )
{
FIXME( "(%p, %p) semi-stub!\n", iface, iter );
return iterator_kvpair_HSTRING_IInspectable_create( iter );
}
const static IIterable_IKeyValuePair_HSTRING_IInspectableVtbl
mapview_iterable_kvpair_HSTRING_IInspectable_vtbl =
{
/* IUnknown */
mapview_iterable_kvpair_HSTRING_IInspectable_QueryInterface,
mapview_iterable_kvpair_HSTRING_IInspectable_AddRef,
mapview_iterable_kvpair_HSTRING_IInspectable_Release,
/* IInspectable */
mapview_iterable_kvpair_HSTRING_IInspectable_GetIids,
mapview_iterable_kvpair_HSTRING_IInspectable_GetRuntimeClassName,
mapview_iterable_kvpair_HSTRING_IInspectable_GetTrustLevel,
/* IIterable<IKeyValuePair<HSTRING, IInspectable*>> */
mapview_iterable_kvpair_HSTRING_IInspectable_First
};
struct propertyset
{
IPropertySet IPropertySet_iface;
IObservableMap_HSTRING_IInspectable IObservableMap_HSTRING_IInspectable_iface;
IMap_HSTRING_IInspectable IMap_HSTRING_IInspectable_iface;
IIterable_IKeyValuePair_HSTRING_IInspectable IIterable_IKeyValuePair_HSTRING_IInspectable_iface;
LONG ref;
};
static inline struct propertyset *impl_from_IPropertySet( IPropertySet *iface )
{
return CONTAINING_RECORD( iface, struct propertyset, IPropertySet_iface );
}
static HRESULT STDMETHODCALLTYPE propertyset_QueryInterface( IPropertySet *iface, REFIID iid,
void **out )
{
struct propertyset *impl;
TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
impl = impl_from_IPropertySet( iface );
*out = NULL;
if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IPropertySet ))
{
*out = iface;
IUnknown_AddRef( (IUnknown *)*out );
return S_OK;
}
if (IsEqualGUID( iid, &IID_IObservableMap_HSTRING_IInspectable ))
{
*out = &impl->IObservableMap_HSTRING_IInspectable_iface;
IUnknown_AddRef( (IUnknown *)*out );
return S_OK;
}
if (IsEqualGUID( iid, &IID_IMap_HSTRING_IInspectable ))
{
*out = &impl->IMap_HSTRING_IInspectable_iface;
IUnknown_AddRef( (IUnknown *)iface );
return S_OK;
}
if (IsEqualGUID( iid, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable ))
{
*out = &impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface;
IUnknown_AddRef( (IUnknown *)iface );
return S_OK;
}
FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE propertyset_AddRef( IPropertySet *iface )
{
struct propertyset *impl;
TRACE( "(%p)\n", iface );
impl = impl_from_IPropertySet( iface );
return InterlockedIncrement( &impl->ref );
}
static ULONG STDMETHODCALLTYPE propertyset_Release( IPropertySet *iface )
{
struct propertyset *impl;
ULONG ref;
TRACE( "(%p)\n", iface );
impl = impl_from_IPropertySet( iface );
ref = InterlockedDecrement( &impl->ref );
if (!ref)
free( impl );
return ref;
}
static HRESULT STDMETHODCALLTYPE propertyset_GetIids( IPropertySet *iface, ULONG *iid_count,
IID **iids )
{
FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_GetRuntimeClassName( IPropertySet *iface,
HSTRING *class_name )
{
FIXME( "(%p, %p) stub!\n", iface, class_name );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_GetTrustLevel( IPropertySet *iface,
TrustLevel *trust_level )
{
FIXME( "(%p, %p) stub!\n", iface, trust_level );
return E_NOTIMPL;
}
static const IPropertySetVtbl propertyset_vtbl =
{
/* IUnknown */
propertyset_QueryInterface,
propertyset_AddRef,
propertyset_Release,
/* IInspectable */
propertyset_GetIids,
propertyset_GetRuntimeClassName,
propertyset_GetTrustLevel,
};
DEFINE_IINSPECTABLE( propertyset_IObservableMap, IObservableMap_HSTRING_IInspectable,
struct propertyset, IPropertySet_iface );
static HRESULT STDMETHODCALLTYPE propertyset_IObservableMap_add_MapChanged(
IObservableMap_HSTRING_IInspectable *iface,
IMapChangedEventHandler_HSTRING_IInspectable *handler, EventRegistrationToken *token )
{
FIXME( "(%p, %p, %p) stub!\n", iface, handler, token );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_IObservableMap_remove_MapChanged(
IObservableMap_HSTRING_IInspectable *iface, EventRegistrationToken token )
{
FIXME( "(%p, %I64d) stub!\n", iface, token.value );
return E_NOTIMPL;
}
const static IObservableMap_HSTRING_IInspectableVtbl propertyset_IObservableMap_vtbl =
{
/* IUnknown */
propertyset_IObservableMap_QueryInterface,
propertyset_IObservableMap_AddRef,
propertyset_IObservableMap_Release,
/* IInspectable */
propertyset_IObservableMap_GetIids,
propertyset_IObservableMap_GetRuntimeClassName,
propertyset_IObservableMap_GetTrustLevel,
/* IObservableMap<HSTRING, IInspectable*> */
propertyset_IObservableMap_add_MapChanged,
propertyset_IObservableMap_remove_MapChanged,
};
DEFINE_IINSPECTABLE( propertyset_IMap, IMap_HSTRING_IInspectable, struct propertyset,
IPropertySet_iface );
static HRESULT STDMETHODCALLTYPE propertyset_Lookup( IMap_HSTRING_IInspectable *iface,
HSTRING key,
IInspectable **value )
{
FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), value );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
propertyset_get_size( IMap_HSTRING_IInspectable *iface, UINT32 *size )
{
FIXME( "(%p, %p) stub!\n", iface, size );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_HasKey( IMap_HSTRING_IInspectable *iface,
HSTRING key, boolean *exists )
{
FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_hstring( key ), exists );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_GetView(
IMap_HSTRING_IInspectable *iface, IMapView_HSTRING_IInspectable **view )
{
struct mapview_HSTRING_IInspectable *impl;
FIXME( "(%p, %p) semi-stub!\n", iface, view );
*view = NULL;
impl = calloc( 1, sizeof( *impl ) );
if (!impl)
return E_OUTOFMEMORY;
impl->IMapView_HSTRING_IInspectable_iface.lpVtbl = &mapview_HSTRING_IInspectable_vtbl;
impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl =
&mapview_iterable_kvpair_HSTRING_IInspectable_vtbl;
impl->ref = 1;
*view = &impl->IMapView_HSTRING_IInspectable_iface;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE propertyset_Insert( IMap_HSTRING_IInspectable *iface,
HSTRING key, IInspectable *value,
boolean *replaced )
{
FIXME( "(%p, %s, %p, %p) stub!\n", iface, debugstr_hstring( key ), value, replaced );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_Remove( IMap_HSTRING_IInspectable *iface,
HSTRING key )
{
FIXME( "(%p, %s) stub!\n", iface, debugstr_hstring( key ) );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE propertyset_Clear( IMap_HSTRING_IInspectable *iface )
{
FIXME( "(%p) stub!\n", iface );
return E_NOTIMPL;
}
const static IMap_HSTRING_IInspectableVtbl propertyset_IMap_vtbl =
{
/* IUnknown */
propertyset_IMap_QueryInterface,
propertyset_IMap_AddRef,
propertyset_IMap_Release,
/* IInspectable */
propertyset_IMap_GetIids,
propertyset_IMap_GetRuntimeClassName,
propertyset_IMap_GetTrustLevel,
/* IMap<HSTRING, IInspectable*> */
propertyset_Lookup,
propertyset_get_size,
propertyset_HasKey,
propertyset_GetView,
propertyset_Insert,
propertyset_Remove,
propertyset_Clear,
};
DEFINE_IINSPECTABLE_( iterable_kvpair_HSTRING_IInspectable,
IIterable_IKeyValuePair_HSTRING_IInspectable, struct propertyset,
impl_from_IIterable_IKeyValuePair_HSTRING_IInspectable,
IIterable_IKeyValuePair_HSTRING_IInspectable_iface,
&impl->IMap_HSTRING_IInspectable_iface );
static HRESULT STDMETHODCALLTYPE
iterable_kvpair_HSTRING_IInspectable_First( IIterable_IKeyValuePair_HSTRING_IInspectable *iface,
IIterator_IKeyValuePair_HSTRING_IInspectable **iter )
{
FIXME( "(%p, %p) semi-stub!\n", iface, iter );
return iterator_kvpair_HSTRING_IInspectable_create( iter );
}
const static IIterable_IKeyValuePair_HSTRING_IInspectableVtbl iterable_kvpair_HSTRING_IInspectable_vtbl =
{
/* IUnknown */
iterable_kvpair_HSTRING_IInspectable_QueryInterface,
iterable_kvpair_HSTRING_IInspectable_AddRef,
iterable_kvpair_HSTRING_IInspectable_Release,
/* IInspectable */
iterable_kvpair_HSTRING_IInspectable_GetIids,
iterable_kvpair_HSTRING_IInspectable_GetRuntimeClassName,
iterable_kvpair_HSTRING_IInspectable_GetTrustLevel,
/* IIterable<IKeyValuePair<HSTRING, IInspectable*>> */
iterable_kvpair_HSTRING_IInspectable_First
};
struct propertyset_factory
{
IActivationFactory IActivationFactory_iface;
};
static HRESULT STDMETHODCALLTYPE factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out )
{
TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out );
*out = NULL;
if (IsEqualGUID( &IID_IUnknown, iid ) ||
IsEqualGUID( &IID_IInspectable, iid ) ||
IsEqualGUID( &IID_IAgileObject, iid ) ||
IsEqualGUID( &IID_IActivationFactory, iid ))
{
*out = iface;
IUnknown_AddRef( (IUnknown *)*out );
return S_OK;
}
FIXME( "%s not implemented, return E_NOINTERFACE.\n", debugstr_guid( iid ) );
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE factory_AddRef( IActivationFactory *iface )
{
TRACE( "(%p)\n", iface );
return 2;
}
static ULONG STDMETHODCALLTYPE factory_Release( IActivationFactory *iface )
{
TRACE( "(%p)\n", iface );
return 1;
}
static HRESULT STDMETHODCALLTYPE factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids )
{
FIXME( "(%p, %p, %p) stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name )
{
FIXME( "(%p, %p) stub!\n", iface, class_name );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level )
{
FIXME( "(%p, %p) stub!\n", iface, trust_level );
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance )
{
struct propertyset *impl;
TRACE( "(%p, %p)\n", iface, instance );
impl = calloc( 1, sizeof( *impl ) );
if (!impl)
return E_OUTOFMEMORY;
impl->IPropertySet_iface.lpVtbl = &propertyset_vtbl;
impl->IObservableMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IObservableMap_vtbl;
impl->IMap_HSTRING_IInspectable_iface.lpVtbl = &propertyset_IMap_vtbl;
impl->IIterable_IKeyValuePair_HSTRING_IInspectable_iface.lpVtbl = &iterable_kvpair_HSTRING_IInspectable_vtbl;
impl->ref = 1;
*instance = (IInspectable *)&impl->IPropertySet_iface;
return S_OK;
}
static const IActivationFactoryVtbl propertyset_factory_vtbl =
{
/* IUnknown */
factory_QueryInterface,
factory_AddRef,
factory_Release,
/* IInspectable */
factory_GetIids,
factory_GetRuntimeClassName,
factory_GetTrustLevel,
/* IActivationFactory */
factory_ActivateInstance,
};
static struct propertyset_factory propertyset_factory =
{
{&propertyset_factory_vtbl},
};
IActivationFactory *IPropertySet_factory = &propertyset_factory.IActivationFactory_iface;

View file

@ -2,5 +2,6 @@ TESTDLL = wintypes.dll
IMPORTS = wintypes combase uuid
SOURCES = \
propertyset.c \
wintypes.c \
wintypes_test.idl

View file

@ -0,0 +1,131 @@
/*
* Copyright 2024 Vibhav Pant
*
* 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
*/
#define COBJMACROS
#include "winstring.h"
#include "roapi.h"
#define WIDL_using_Windows_Foundation
#define WIDL_using_Windows_Foundation_Collections
#include "windows.foundation.h"
#include "wine/test.h"
static void test_IPropertySet(void)
{
static const WCHAR *class_name = RuntimeClass_Windows_Foundation_Collections_PropertySet;
IActivationFactory *factory;
IInspectable *inspectable;
IPropertySet *propset;
IMap_HSTRING_IInspectable *map;
IMapView_HSTRING_IInspectable *map_view;
IIterable_IKeyValuePair_HSTRING_IInspectable *iterable;
IIterator_IKeyValuePair_HSTRING_IInspectable *iterator;
IObservableMap_HSTRING_IInspectable *observable_map;
HRESULT hr;
HSTRING name;
hr = RoInitialize( RO_INIT_MULTITHREADED );
ok( SUCCEEDED( hr ), "got %#lx\n", hr );
hr = WindowsCreateString( class_name, wcslen( class_name ), &name );
ok( SUCCEEDED( hr ), "got %#lx\n", hr );
hr = RoGetActivationFactory( name, &IID_IActivationFactory, (void **)&factory );
WindowsDeleteString( name );
ok( hr == S_OK || broken( hr == REGDB_E_CLASSNOTREG ),
"RoGetActivationFactory failed, hr %#lx.\n", hr );
if (hr == REGDB_E_CLASSNOTREG)
{
win_skip( "%s runtimeclass not registered, skipping tests.\n",
wine_dbgstr_w( class_name ) );
RoUninitialize();
return;
}
hr = IActivationFactory_ActivateInstance( factory, &inspectable );
IActivationFactory_Release( factory );
ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (FAILED( hr ))
{
skip("could not activate PropertySet instance.\n");
RoUninitialize();
return;
}
hr = IInspectable_QueryInterface( inspectable, &IID_IPropertySet, (void **)&propset );
IInspectable_Release( inspectable );
ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (FAILED( hr ))
{
RoUninitialize();
return;
}
hr = IPropertySet_QueryInterface( propset, &IID_IMap_HSTRING_IInspectable, (void **)&map );
ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (FAILED( hr ))
{
RoUninitialize();
return;
}
hr = IPropertySet_QueryInterface( propset, &IID_IObservableMap_HSTRING_IInspectable,
(void *)&observable_map );
IPropertySet_Release(propset);
ok(SUCCEEDED(hr), "QueryInterface failed, got %#lx\n", hr);
hr = IMap_HSTRING_IInspectable_QueryInterface( map, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable,
(void **)&iterable );
ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (SUCCEEDED( hr ))
{
hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (SUCCEEDED( hr ))
IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable );
IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator );
}
else
skip( "Could not obtain IIterable<IKeyValuePair<HSTRING, IInspectable *>> instance.\n");
hr = IMap_HSTRING_IInspectable_GetView( map, &map_view );
ok( SUCCEEDED( hr ), "GetView failed, got %#lx\n", hr );
if (SUCCEEDED( hr ))
{
hr = IMapView_HSTRING_IInspectable_QueryInterface( map_view, &IID_IIterable_IKeyValuePair_HSTRING_IInspectable,
(void **)&iterable );
ok( SUCCEEDED( hr ), "QueryInterface failed, got %#lx\n", hr );
if (SUCCEEDED( hr ))
{
hr = IIterable_IKeyValuePair_HSTRING_IInspectable_First( iterable, &iterator );
ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (SUCCEEDED( hr ))
IIterator_IKeyValuePair_HSTRING_IInspectable_Release( iterator );
IIterable_IKeyValuePair_HSTRING_IInspectable_Release( iterable );
}
}
IObservableMap_HSTRING_IInspectable_Release( observable_map );
IMap_HSTRING_IInspectable_Release( map );
RoUninitialize();
}
START_TEST(propertyset)
{
test_IPropertySet();
}

View file

@ -66,3 +66,5 @@ cpp_quote(" }")
cpp_quote("#define DEFINE_IINSPECTABLE( pfx, iface_type, impl_type, base_iface ) \\")
cpp_quote(" DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from_##iface_type, iface_type##_iface, &impl->base_iface )")
cpp_quote("extern IActivationFactory *IPropertySet_factory;")

View file

@ -1449,6 +1449,22 @@ NTSTATUS WINAPI wow64_NtSetIoCompletion( UINT *args )
}
/**********************************************************************
* wow64_NtSetIoCompletionEx
*/
NTSTATUS WINAPI wow64_NtSetIoCompletionEx( UINT *args )
{
HANDLE completion_handle = get_handle( &args );
HANDLE completion_reserve_handle = get_handle( &args );
ULONG_PTR key = get_ulong( &args );
ULONG_PTR value = get_ulong( &args );
NTSTATUS status = get_ulong( &args );
SIZE_T count = get_ulong( &args );
return NtSetIoCompletionEx( completion_handle, completion_reserve_handle, key, value, status, count );
}
/**********************************************************************
* wow64_NtSetTimer
*/

View file

@ -3158,57 +3158,14 @@ NTSTATUS WINAPI wow64_NtUserHiliteMenuItem( UINT *args )
return NtUserHiliteMenuItem( hwnd, handle, item, hilite );
}
struct user_client_procs32
{
ULONG pButtonWndProc;
ULONG pComboWndProc;
ULONG pDefWindowProc;
ULONG pDefDlgProc;
ULONG pEditWndProc;
ULONG pListBoxWndProc;
ULONG pMDIClientWndProc;
ULONG pScrollBarWndProc;
ULONG pStaticWndProc;
ULONG pImeWndProc;
ULONG pDesktopWndProc;
ULONG pIconTitleWndProc;
ULONG pPopupMenuWndProc;
ULONG pMessageWndProc;
};
static struct user_client_procs *user_client_procs_32to64( struct user_client_procs *procs,
const struct user_client_procs32 *procs32 )
{
if (!procs32) return NULL;
procs->pButtonWndProc = UlongToPtr( procs32->pButtonWndProc );
procs->pComboWndProc = UlongToPtr( procs32->pComboWndProc );
procs->pDefWindowProc = UlongToPtr( procs32->pDefWindowProc );
procs->pDefDlgProc = UlongToPtr( procs32->pDefDlgProc );
procs->pEditWndProc = UlongToPtr( procs32->pEditWndProc );
procs->pListBoxWndProc = UlongToPtr( procs32->pListBoxWndProc );
procs->pMDIClientWndProc = UlongToPtr( procs32->pMDIClientWndProc );
procs->pScrollBarWndProc = UlongToPtr( procs32->pScrollBarWndProc );
procs->pStaticWndProc = UlongToPtr( procs32->pStaticWndProc );
procs->pImeWndProc = UlongToPtr( procs32->pImeWndProc );
procs->pDesktopWndProc = UlongToPtr( procs32->pDesktopWndProc );
procs->pIconTitleWndProc = UlongToPtr( procs32->pIconTitleWndProc );
procs->pPopupMenuWndProc = UlongToPtr( procs32->pPopupMenuWndProc );
procs->pMessageWndProc = UlongToPtr( procs32->pMessageWndProc );
return procs;
}
NTSTATUS WINAPI wow64_NtUserInitializeClientPfnArrays( UINT *args )
{
const struct user_client_procs32 *procsA32 = get_ptr( &args );
const struct user_client_procs32 *procsW32 = get_ptr( &args );
void *workers = get_ptr( &args );
const ntuser_client_func_ptr *procsA = get_ptr( &args );
const ntuser_client_func_ptr *procsW = get_ptr( &args );
const ntuser_client_func_ptr *workers = get_ptr( &args );
HINSTANCE user_module = get_ptr( &args );
struct user_client_procs procsA, procsW;
return NtUserInitializeClientPfnArrays( user_client_procs_32to64( &procsA, procsA32 ),
user_client_procs_32to64( &procsW, procsW32 ),
workers, user_module );
return NtUserInitializeClientPfnArrays( procsA, procsW, workers, user_module );
}
NTSTATUS WINAPI wow64_NtUserInternalGetWindowIcon( UINT *args )

View file

@ -343,4 +343,19 @@ typedef struct tagKbdLayer
#error "Unsupported KBD_TYPE"
#endif
#define VK_DBE_ALPHANUMERIC 0x0f0
#define VK_DBE_KATAKANA 0x0f1
#define VK_DBE_HIRAGANA 0x0f2
#define VK_DBE_SBCSCHAR 0x0f3
#define VK_DBE_DBCSCHAR 0x0f4
#define VK_DBE_ROMAN 0x0f5
#define VK_DBE_NOROMAN 0x0f6
#define VK_DBE_ENTERWORDREGISTERMODE 0x0f7
#define VK_DBE_ENTERIMECONFIGMODE 0x0f8
#define VK_DBE_FLUSHSTRING 0x0f9
#define VK_DBE_CODEINPUT 0x0fa
#define VK_DBE_NOCODEINPUT 0x0fb
#define VK_DBE_DETERMINESTRING 0x0fc
#define VK_DBE_ENTERDLGCONVERSIONMODE 0x0fd
#endif /* __WINE_KBD_H */

View file

@ -446,25 +446,59 @@ struct send_message_callback_params
/* NtUserSetScrollInfo flag */
#define SIF_RETURNPREV 0x1000
/* NtUserInitializeClientPfnArrays parameter, not compatible with Windows */
struct user_client_procs
/* NtUserInitializeClientPfnArrays parameter */
enum ntuser_client_procs
{
WNDPROC pButtonWndProc;
WNDPROC pComboWndProc;
WNDPROC pDefWindowProc;
WNDPROC pDefDlgProc;
WNDPROC pEditWndProc;
WNDPROC pListBoxWndProc;
WNDPROC pMDIClientWndProc;
WNDPROC pScrollBarWndProc;
WNDPROC pStaticWndProc;
WNDPROC pImeWndProc;
WNDPROC pDesktopWndProc;
WNDPROC pIconTitleWndProc;
WNDPROC pPopupMenuWndProc;
WNDPROC pMessageWndProc;
NTUSER_WNDPROC_SCROLLBAR,
NTUSER_WNDPROC_MESSAGE,
NTUSER_WNDPROC_MENU,
NTUSER_WNDPROC_DESKTOP,
NTUSER_WNDPROC_DEFWND,
NTUSER_WNDPROC_ICONTITLE,
NTUSER_WNDPROC_UNKNOWN,
NTUSER_WNDPROC_BUTTON,
NTUSER_WNDPROC_COMBO,
NTUSER_WNDPROC_COMBOLBOX,
NTUSER_WNDPROC_DIALOG,
NTUSER_WNDPROC_EDIT,
NTUSER_WNDPROC_LISTBOX,
NTUSER_WNDPROC_MDICLIENT,
NTUSER_WNDPROC_STATIC,
NTUSER_WNDPROC_IME,
NTUSER_WNDPROC_GHOST,
NTUSER_NB_PROCS
};
#define NTUSER_NB_WORKERS 11
/* 64-bit pointers are used on all platforms */
typedef WNDPROC ntuser_client_func_ptr[sizeof(UINT64) / sizeof(void *)];
struct ntuser_client_procs_table
{
ntuser_client_func_ptr A[NTUSER_NB_PROCS];
ntuser_client_func_ptr W[NTUSER_NB_PROCS];
ntuser_client_func_ptr workers[NTUSER_NB_WORKERS];
};
#define ALL_NTUSER_CLIENT_PROCS \
USER_FUNC( ScrollBarWndProc, NTUSER_WNDPROC_SCROLLBAR ) \
USER_FUNC( MessageWndProc, NTUSER_WNDPROC_MESSAGE ) \
USER_FUNC( PopupMenuWndProc, NTUSER_WNDPROC_MENU ) \
USER_FUNC( DesktopWndProc, NTUSER_WNDPROC_DESKTOP ) \
USER_FUNC( DefWindowProc, NTUSER_WNDPROC_DEFWND ) \
USER_FUNC( IconTitleWndProc, NTUSER_WNDPROC_ICONTITLE ) \
USER_FUNC( ButtonWndProc, NTUSER_WNDPROC_BUTTON ) \
USER_FUNC( ComboWndProc, NTUSER_WNDPROC_COMBO ) \
USER_FUNC( ComboLBoxWndProc, NTUSER_WNDPROC_COMBOLBOX ) \
USER_FUNC( DialogWndProc, NTUSER_WNDPROC_DIALOG ) \
USER_FUNC( EditWndProc, NTUSER_WNDPROC_EDIT ) \
USER_FUNC( ListBoxWndProc, NTUSER_WNDPROC_LISTBOX ) \
USER_FUNC( MDIClientWndProc, NTUSER_WNDPROC_MDICLIENT ) \
USER_FUNC( StaticWndProc, NTUSER_WNDPROC_STATIC ) \
USER_FUNC( ImeWndProc, NTUSER_WNDPROC_IME ) \
USER_FUNC( GhostWndProc, NTUSER_WNDPROC_GHOST )
/* NtUserSetCursorIconData parameter, not compatible with Windows */
struct cursoricon_frame
{
@ -775,9 +809,9 @@ W32KAPI BOOL WINAPI NtUserGetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *pla
W32KAPI int WINAPI NtUserGetWindowRgnEx( HWND hwnd, HRGN hrgn, UINT unk );
W32KAPI BOOL WINAPI NtUserHideCaret( HWND hwnd );
W32KAPI BOOL WINAPI NtUserHiliteMenuItem( HWND hwnd, HMENU handle, UINT item, UINT hilite );
W32KAPI NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs *client_procsA,
const struct user_client_procs *client_procsW,
const void *client_workers, HINSTANCE user_module );
W32KAPI NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const ntuser_client_func_ptr *client_procsA,
const ntuser_client_func_ptr *client_procsW,
const ntuser_client_func_ptr *client_workers, HINSTANCE user_module );
W32KAPI HICON WINAPI NtUserInternalGetWindowIcon( HWND hwnd, UINT type );
W32KAPI INT WINAPI NtUserInternalGetWindowText( HWND hwnd, WCHAR *text, INT count );
W32KAPI BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format );

View file

@ -430,6 +430,36 @@ library UIAutomationClient {
const long UIA_AppBarControlTypeId = 50040;
}
[dllname("<no entry points>")]
module UIA_AnnotationTypes
{
const long AnnotationType_Unknown = 60000;
const long AnnotationType_SpellingError = 60001;
const long AnnotationType_GrammarError = 60002;
const long AnnotationType_Comment = 60003;
const long AnnotationType_FormulaError = 60004;
const long AnnotationType_TrackChanges = 60005;
const long AnnotationType_Header = 60006;
const long AnnotationType_Footer = 60007;
const long AnnotationType_Highlighted = 60008;
const long AnnotationType_Endnote = 60009;
const long AnnotationType_Footnote = 60010;
const long AnnotationType_InsertionChange = 60011;
const long AnnotationType_DeletionChange = 60012;
const long AnnotationType_MoveChange = 60013;
const long AnnotationType_FormatChange = 60014;
const long AnnotationType_UnsyncedChange = 60015;
const long AnnotationType_EditingLockedChange = 60016;
const long AnnotationType_ExternalChange = 60017;
const long AnnotationType_ConflictingChange = 60018;
const long AnnotationType_Author = 60019;
const long AnnotationType_AdvancedProofingIssue = 60020;
const long AnnotationType_DataValidationError = 60021;
const long AnnotationType_CircularReferenceError = 60022;
const long AnnotationType_Mathematics = 60023;
const long AnnotationType_Sensitive = 60024;
}
[dllname("<no entry points>")]
module UIA_LandmarkTypeIds
{

View file

@ -30,6 +30,8 @@ import "windows.foundation.collections.idl";
namespace Windows.Foundation.Collections {
interface IPropertySet;
runtimeclass PropertySet;
declare {
interface Windows.Foundation.Collections.IKeyValuePair<HSTRING, HSTRING>;
interface Windows.Foundation.Collections.IKeyValuePair<HSTRING, IInspectable *>;
@ -57,6 +59,20 @@ namespace Windows.Foundation.Collections {
{
}
[
activatable(Windows.Foundation.FoundationContract, 1.0),
contract(Windows.Foundation.FoundationContract, 1.0),
marshaling_behavior(agile),
threading(both)
]
runtimeclass PropertySet
{
[default] interface Windows.Foundation.Collections.IPropertySet;
interface Windows.Foundation.Collections.IObservableMap<HSTRING, IInspectable *>;
interface Windows.Foundation.Collections.IMap<HSTRING, IInspectable *>;
interface Windows.Foundation.Collections.IIterable<Windows.Foundation.Collections.IKeyValuePair<HSTRING, IInspectable *> *>;
}
[
activatable(Windows.Foundation.FoundationContract, 1.0),
contract(Windows.Foundation.FoundationContract, 1.0),

View file

@ -260,7 +260,7 @@ typedef struct
} rectangle_t;
typedef struct
struct async_data
{
obj_handle_t handle;
obj_handle_t event;
@ -268,7 +268,7 @@ typedef struct
client_ptr_t user;
client_ptr_t apc;
apc_param_t apc_context;
} async_data_t;
};
@ -488,18 +488,18 @@ enum apc_type
APC_DUP_HANDLE
};
typedef struct
struct user_apc
{
enum apc_type type;
int __pad;
client_ptr_t func;
apc_param_t args[3];
} user_apc_t;
};
typedef union
union apc_call
{
enum apc_type type;
user_apc_t user;
struct user_apc user;
struct
{
enum apc_type type;
@ -620,9 +620,9 @@ typedef union
unsigned int attributes;
unsigned int options;
} dup_handle;
} apc_call_t;
};
typedef union
union apc_result
{
enum apc_type type;
struct
@ -732,7 +732,7 @@ typedef union
enum apc_type type;
unsigned int status;
} break_process;
} apc_result_t;
};
enum irp_type
{
@ -1343,7 +1343,7 @@ struct get_apc_result_request
struct get_apc_result_reply
{
struct reply_header __header;
apc_result_t result;
union apc_result result;
};
@ -1829,7 +1829,7 @@ struct flush_request
{
struct request_header __header;
char __pad_12[4];
async_data_t async;
struct async_data async;
};
struct flush_reply
{
@ -1857,7 +1857,7 @@ struct get_volume_info_request
{
struct request_header __header;
obj_handle_t handle;
async_data_t async;
struct async_data async;
unsigned int info_class;
char __pad_60[4];
};
@ -1906,7 +1906,7 @@ struct recv_socket_request
{
struct request_header __header;
int oob;
async_data_t async;
struct async_data async;
int force_async;
char __pad_60[4];
};
@ -1925,7 +1925,7 @@ struct send_socket_request
{
struct request_header __header;
unsigned int flags;
async_data_t async;
struct async_data async;
};
struct send_socket_reply
{
@ -2016,7 +2016,7 @@ struct read_directory_changes_request
unsigned int filter;
int subtree;
int want_data;
async_data_t async;
struct async_data async;
};
struct read_directory_changes_reply
{
@ -3152,7 +3152,7 @@ struct register_async_request
{
struct request_header __header;
int type;
async_data_t async;
struct async_data async;
int count;
char __pad_60[4];
};
@ -3216,7 +3216,7 @@ struct read_request
{
struct request_header __header;
char __pad_12[4];
async_data_t async;
struct async_data async;
file_pos_t pos;
};
struct read_reply
@ -3233,7 +3233,7 @@ struct write_request
{
struct request_header __header;
char __pad_12[4];
async_data_t async;
struct async_data async;
file_pos_t pos;
/* VARARG(data,bytes); */
};
@ -3252,7 +3252,7 @@ struct ioctl_request
{
struct request_header __header;
ioctl_code_t code;
async_data_t async;
struct async_data async;
/* VARARG(in_data,bytes); */
};
struct ioctl_reply
@ -5412,8 +5412,8 @@ struct add_completion_request
apc_param_t ckey;
apc_param_t cvalue;
apc_param_t information;
obj_handle_t reserve_handle;
unsigned int status;
char __pad_44[4];
};
struct add_completion_reply
{
@ -6758,10 +6758,6 @@ union generic_reply
struct set_keyboard_repeat_reply set_keyboard_repeat_reply;
};
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 847
/* ### protocol_version end ### */
#define SERVER_PROTOCOL_VERSION 848
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View file

@ -4675,6 +4675,7 @@ NTSYSAPI NTSTATUS WINAPI NtSetInformationToken(HANDLE,TOKEN_INFORMATION_CLASS,P
NTSYSAPI NTSTATUS WINAPI NtSetInformationVirtualMemory(HANDLE,VIRTUAL_MEMORY_INFORMATION_CLASS,ULONG_PTR,PMEMORY_RANGE_ENTRY,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI NtSetIntervalProfile(ULONG,KPROFILE_SOURCE);
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletion(HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
NTSYSAPI NTSTATUS WINAPI NtSetIoCompletionEx(HANDLE,HANDLE,ULONG_PTR,ULONG_PTR,NTSTATUS,SIZE_T);
NTSYSAPI NTSTATUS WINAPI NtSetLdtEntries(ULONG,LDT_ENTRY,ULONG,LDT_ENTRY);
NTSYSAPI NTSTATUS WINAPI NtSetLowEventPair(HANDLE);
NTSYSAPI NTSTATUS WINAPI NtSetLowWaitHighEventPair(HANDLE);
@ -4949,6 +4950,7 @@ NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *,
NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext(void*,ULONG,CONTEXT_EX**);
NTSYSAPI NTSTATUS WINAPI RtlInitializeExtendedContext2(void*,ULONG,CONTEXT_EX**,ULONG64);
NTSYSAPI void WINAPI RtlInitializeHandleTable(ULONG,ULONG,RTL_HANDLE_TABLE *);
NTSYSAPI NTSTATUS WINAPI RtlInitializeNtUserPfn(const void*,ULONG,const void*,ULONG,const void*,ULONG);
NTSYSAPI void WINAPI RtlInitializeResource(LPRTL_RWLOCK);
NTSYSAPI void WINAPI RtlInitializeSRWLock(RTL_SRWLOCK*);
NTSYSAPI NTSTATUS WINAPI RtlInitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE);
@ -5034,6 +5036,8 @@ NTSYSAPI void WINAPI RtlReleaseSRWLockExclusive(RTL_SRWLOCK*);
NTSYSAPI void WINAPI RtlReleaseSRWLockShared(RTL_SRWLOCK*);
NTSYSAPI ULONG WINAPI RtlRemoveVectoredContinueHandler(PVOID);
NTSYSAPI ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID);
NTSYSAPI NTSTATUS WINAPI RtlRetrieveNtUserPfn(const void**,const void**,const void**);
NTSYSAPI NTSTATUS WINAPI RtlResetNtUserPfn(void);
NTSYSAPI void WINAPI RtlResetRtlTranslations(const NLSTABLEINFO*);
NTSYSAPI void WINAPI RtlRestoreLastWin32Error(DWORD);
NTSYSAPI void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *);

View file

@ -40,8 +40,11 @@ summary of contributions.
changes and bug fixes and got the synthesizer to actually work. Most
importantly, he used it on stage to make music.
* S. Christian Collins did much testing of FluidSynth in regards to
EMU10K1 compatibility and provided many synthesis fixes in that regard.
* S. Christian Collins provided many tests and fixes on EMU10K1
compatibility. He also supplied reference chorus and reverb settings for
developing the default ones.
* Alberto Salvia Novella developed the default chorus and reverb settings.
* Stephane Letz from Grame wrote most of the MidiShare driver, all of
the PortAudio driver, ported iiwusynth to MacOS X, and sent in many

View file

@ -57,6 +57,15 @@ enum fluid_mod_flags
FLUID_MOD_SIN = 0x80, /**< Custom non-standard sinus mapping function */
};
/**
* Transform types for the SoundFont2 modulators as defined by SoundFont 2.04 section 8.3.
*/
enum fluid_mod_transforms
{
FLUID_MOD_TRANSFORM_LINEAR = 0, /**< Linear: directly add the computed value to summing node */
FLUID_MOD_TRANSFORM_ABS = 2 /**< Abs: add the absolute value of the computed to summing node */
};
/**
* General controller (if #FLUID_MOD_GC in flags). This
* corresponds to SoundFont 2.04 PDF section 8.2.1
@ -83,6 +92,7 @@ FLUIDSYNTH_API void fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags);
FLUIDSYNTH_API void fluid_mod_set_dest(fluid_mod_t *mod, int dst);
FLUIDSYNTH_API void fluid_mod_set_amount(fluid_mod_t *mod, double amount);
FLUIDSYNTH_API void fluid_mod_set_transform(fluid_mod_t *mod, int type);
FLUIDSYNTH_API int fluid_mod_get_source1(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_flags1(const fluid_mod_t *mod);
@ -90,6 +100,7 @@ FLUIDSYNTH_API int fluid_mod_get_source2(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_flags2(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_dest(const fluid_mod_t *mod);
FLUIDSYNTH_API double fluid_mod_get_amount(const fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_get_transform(fluid_mod_t *mod);
FLUIDSYNTH_API int fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2);
FLUIDSYNTH_API int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl);

Some files were not shown because too many files have changed in this diff Show more