Looking at
RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector )
{
RPC_STATUS status;
ULONG c;
TRACE("(%p)\n", BindingVector);
for (c=0; c<(*BindingVector)->Count; c++) {
status = RpcBindingFree(&(*BindingVector)->BindingH[c]);
}
HeapFree(GetProcessHeap(), 0, *BindingVector);
*BindingVector = NULL;
return RPC_S_OK;
}
we currently always ignore the outcome of RpcBindingFree and return
RPC_S_OK.
However, there is one case where RpcBindingFree returns something
different (which is if *Binding is null when RPC_S_INVALID_BINDING
is returned).
What is the proper way of handling this? Just keeping the code as
is and removing the unused status variable? Breaking the loop once
RpcBindingFree returns something different from RPC_S_OK? Continuing
and returning the first / the last status different from RPC_S_OK?
Gerald
Dear all,
While test another online bank with wine ActiveX,
I got an unimplemented fuction of ntoskrnl: IoGetDeviceInterfaces,
I found it listed in http://source.winehq.org/WineAPI/ntoskrnl.html as a stup,
so I can't understand this log:
wine: Unimplemented function ntoskrnl.exe.IoGetDeviceInterfaces called
at address 0x7b839552 (thread 0022), starting debugger...
Grateful for any explain!
env:
wine1.3.12 on Ubuntu 10.04
Here are the steps:
1. install an ActiveX from
https://e.bank.ecitic.com/perbank5/plugs/CNCBSecPkg_EN.exe
$ rm -rf ~/.wine
$ winetricks -q mfc42
$ wine CNCBSecPkg_EN.exe
fixme:ole:DllRegisterServer stub
fixme:win:DisableProcessWindowsGhosting : stub
fixme:msg:ChangeWindowMessageFilter c057 00000001
fixme:msg:ChangeWindowMessageFilter c057 00000001
fixme:msg:ChangeWindowMessageFilter c057 00000001
fixme:ole:CoCreateInstance no instance created for interface
{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf} of class
{56fdf344-fd6d-11d0-958a-006097c9a090}, hres is 0x80004002
fixme:sfc:SfcIsFileProtected ((nil), L"C:\\Program
Files\\\4e2d\4fe1\94f6\884c\7f51\94f6\5b89\5168\63a7\4ef6\\unins000.exe")
stub
fixme:win:WINNLSEnableIME hUnknown1 0x1011a bUnknown2 0: stub!
fixme:win:WINNLSEnableIME hUnknown1 0x1011a bUnknown2 -1: stub!
fixme:win:WINNLSEnableIME hUnknown1 0x1011a bUnknown2 0: stub!
wine: Call from 0x7b839552 to unimplemented function
ntoskrnl.exe.IoGetDeviceInterfaces, aborting
wine: Unimplemented function ntoskrnl.exe.IoGetDeviceInterfaces called
at address 0x7b839552 (thread 002b), starting debugger...
wine: Call from 0x7b839552 to unimplemented function
ntoskrnl.exe.IoGetDeviceInterfaces, aborting
wine: Call from 0x7b839552 to unimplemented function
ntoskrnl.exe.IoGetDeviceInterfaces, aborting
2. open the online bank entry with wine builtin IE, then IE will crash:
$ wine iexplore https://e.bank.ecitic.com/perbank5/signIn.do
Please checkout the full log here:
http://pastebin.com/rbAg7gwj
Should I file a singel bug in ntoskrnl component , or separate bugs,
one for ntoskrnl and one for the IE crashing?
Generalliy what component should I switch while file a bug about IE crashing?
Many thanks!
--
Regards,
Qian Hong
-
Sent from Ubuntu
http://www.ubuntu.com/
Hi guys,
Rather a peripheral question; apologies for that - but I'd imagine
there are experts here that may be able to help.
I have a black-box problem - a Windows app dealing with confidential
data that I can't easily touch (and thus can't get to run under Wine) -
which does some small but critical automation of MS Office - using VBS /
COM scripting.
I'd -really- love some input on how best to trace that series of COM
method calls on Windows itself ie. the (remote) service activation, and
the RPC beyond that - particularly the method names, parameters etc. of
the COM/OLE Office API. I've tried (so far):
http://www.rohitab.com/apimonitor
which, while closed, looks interesting; but traces a lot
in a hard-to-search way and doesn't appear to do the
trick.
https://support.microsoft.com/en-us/help/926098/how-to-enable-com-and-com-d…
Sounds useful: using Event Tracing for Windows (ETW) but
has this rather unhelpful property:
"The binary file must be formatted by Microsoft
so that it can be analyzed. Please forward the
.etl files to your support contact. ..." ;-)
Component models used to be all the rage in my youth ;-) surely someone
solved the "strace for COM calls" problem elegantly some-when !
Crazily - might it be possible to instrument, interpose and use Wine's
COM impl. on Windows [ which sounds a bit 'exciting' ;-], or ?
Anyhow - help much appreciated & sorry for the noise !
Regards,
Michael.
--
michael.meeks(a)collabora.com <><, Pseudo Engineer, itinerant idiot
Good Afternoon.
In section 3.3.6.2 of your User Guide you ask readers to report
successes with databases other than MS SQL. Well here's one (I know
Access 2000 can work with Wine, but this doesn't require Access):
How to set up Wine to enable Windows programs that read and write to Jet
(Access)
databases using ODBC. I write such programs in C and use the API defined in
ODBC API Reference
http://msdn.microsoft.com/en-us/library/ms714562%28VS.85%29.aspx
They work fine on Windows and only require Mingw to be installed to
compile and link them,
both for console programs and those using Windows SDK.
You then can write interactive programs in C which use a full-featured
SQL database which
comes bundled with Windows. No need to purchase Access.
With the set-up below they will also run on Linux (Kubuntu 9.04) and
Wine 1.1.26.
You need to update the registry to install the Access drivers.
Under Windows, export from the Registry to *.reg files the registry entries
- HKLM\Software\ODBC
- HKLM\Software\Microsoft\Jet
all subsidiary keys and values come with them.
You can carefully edit these files to remove drivers and DSNs you don't
need.
Import these files using the registry editor in wine:
wine regedit.exe.
You need to bring across from Windows to Windows\System32 under wine:
clbcatq.dll
comres.dll
expsrv.dll
msjet40.dll
mswstr10.dll
msjter40.dll
msjint40.dll
msjtes40.dll
msrd3x40.dll
odbc32.dll
odbccp32.dll
odbcji32.dll
odbcjt32.dll
odbcad32.exe
odbcint.dll
odbctrac.dll
vbajet32.dll
Register this server in wine:
wine regsvr32.exe msjtes40.dll
No need to install MDAC.
To use Windows ODBC drivers, you have to override Wine's odbccp32.dll
and odbc32.dll with the native
versions because the Wine versions are currently wired directly to
Linux's unixodbc.
This can be done by setting up the ODBC Data Source Administrator
odbcad32.exe using winecfg:
- Add the program to the Applications tab
- then in the libraries tab, pick from 'New override for library' drop-down
odbc32.dll and odbccp32.dll add them and edit them to be Native for Windows.
Then if you do
wine odbcad32.exe
this brings up the ODBC Data Source Administrator window as in the
Windows Control Panel
If needed, set up (System) DSNs using this program.
Bring across the programs and *.mdb database files from Windows.
Using winecfg, you need to set up each program you want to run with
overrides for odbc32.dll and odbccp32.dll
(Applications and Libraries tabs) as above.
The programs should then run as they did in Windows but perhaps a bit
slower with:
wine Odbc-prog.exe
This has been tested twice on a clean .wine install. I cannot vouch
for support of all API and SQL facilities however.
I hope someone finds this useful.
Barry Bird
Hello!
So all the way back at wineconf I volunteered to be swag master for winehq. The idea is to have something that can be given away at trade shows, presentations, LUG visits and the like. Just something to help promote the visibility of the project.
Jana here, CodeWeavers marketing director, has put together a sampling of designs to do as our first sticker and so now we are looking for some feedback on what people prefer.
https://docs.google.com/forms/d/e/1FAIpQLSd5X_fXe9KSFAppRHz8kUo3XKeODyH5KeX…
Rosanne? Could you direct me as to where this should be put up for the users as well? I am unfamiliar with how to communicate to our user base.
The poll will run for as long as it feels like it needs to get some sort of winner. Comments and suggestions are always welcome!
-aric
Artur Świgoń <artur.swigon(a)gmail.com> writes:
> @@ -138,6 +142,14 @@ static int wbufalloc = 0;
>
> static int current_codepage = -1; /* use language default */
>
> +/* Used for differentiating between single- and double-quoted nameID's */
> +static int id_dblquote = 0;
> +
> +/* Used for catching first (quoted) nameID before wanted_id is set.
> + * This variable is reset to 0 once the first ID (quoted or not), string or
> + * data has been encountered */
> +static int id_initial = 1;
That's a bit hackish. Couldn't you simply set the initial state
appropriately instead of introducing a separate variable?
> @@ -402,8 +414,30 @@ static unsigned long xstrtoul(const char *nptr, char **endptr, int base)
> 0[oO][0-7]+[lL]? { parser_lval.num = xstrtoul(yytext+2, 0, 8);
> return (yytext[yyleng-1] == 'L' || yytext[yyleng-1] == 'l') ? tLNUMBER : tNUMBER; }
>
> +<tkid_dbl>[A-Za-z_0-9./\\\']+\" |
> +<tkid_sgl>[A-Za-z_0-9./\\\"]+\' {
There are more characters that should be allowed. Nested quotes are also
supposed to work.
--
Alexandre Julliard
julliard(a)winehq.org
______________________________________________________________
> Od: Austin English <austinenglish(a)gmail.com>
> Komu: wylda(a)volny.cz
> Datum: 20.02.2017 07:07
> Předmět: Re: winetricks alldlls=builtin update based on wine-2.2
>
> CC: <wine-devel(a)winehq.org>
On Sun, Feb 19, 2017 at 7:51 AM, <wylda(a)volny.cz> wrote:
> Hi,
> in case you find it useful...
>
> W.
Hi Wylda,
Please send a pull request to https://github.com/Winetricks/winetricks/
--
-Austin
GPG: 14FB D7EA A041 937B
______________________________________________________________
Hi Austin,
i updated alldlls=builtin function for wine-2.7 and also fixed few things:
- generates properly indentioned library list
- removed nonsensical library names like "./dlls"
- script generates override list matching 1:1 to wine-2.7 available list
Unfortunately i not able to create pull request in github even though
i have created github account right now. It's still grey out and i don't know
different way to upload a patch. Anyway is there a different way to get it in,
so i don't need to maintain locally? (spent whole day on this and i have
no plans to learn git "details" in near futures).
Best regards,
W.
This is v6 of this series. The five previous submissions can be found
here [1], here [2], here[3], here[4], and here[5]. This version addresses
the comments received in v4 plus improvements of the handling of emulation
in 64-bit builds. Please see details in the change log.
=== What is UMIP?
User-Mode Instruction Prevention (UMIP) is a security feature present in
new Intel Processors. If enabled, it prevents the execution of certain
instructions if the Current Privilege Level (CPL) is greater than 0. If
these instructions were executed while in CPL > 0, user space applications
could have access to system-wide settings such as the global and local
descriptor tables, the segment selectors to the current task state and the
local descriptor table.
These are the instructions covered by UMIP:
* SGDT - Store Global Descriptor Table
* SIDT - Store Interrupt Descriptor Table
* SLDT - Store Local Descriptor Table
* SMSW - Store Machine Status Word
* STR - Store Task Register
If any of these instructions is executed with CPL > 0, a general protection
exception is issued when UMIP is enabled.
=== How does it impact applications?
There is a caveat, however. Certain applications rely on some of these
instructions to function. An example of this are applications that use
WineHQ[6]. For instance, these applications rely on sidt returning a non-
accessible memory location[8]. During the discussions, it was proposed that
the fault could be relied to the user-space and perform the emulation in
user-mode. However, this would break existing applications until, for
instance, they update to a new WineHQ version. However, this approach
would require UMIP to be disabled by default. The consensus in this forum
is to always enable it.
This patchset initially treated tasks running in virtual-8086 mode as a
special case. However, I received clarification that DOSEMU[8] does not
support applications that use these instructions. It relies on WineHQ for
this [9]. Furthermore, the applications for which the concern was raised
run in protected mode [8].
Please note that UMIP is always enabled for both 64-bit and 32-bit Linux
builds. However, emulation of the UMIP-protected instructions is not done
for 64-bit processes. 64-bit user space applications will receive the
SIGSEGV signal when UMIP instructions causes a general protection fault.
=== How are UMIP-protected instructions emulated?
This version keeps UMIP enabled at all times and by default. If a general
protection fault caused by the instructions protected by UMIP is
detected, such fault will be fixed-up by returning dummy values as follows:
* SGDT and SIDT return hard-coded dummy values as the base of the global
descriptor and interrupt descriptor tables. These hard-coded values
correspond to memory addresses that are near the end of the kernel
memory map. This is also the case for virtual-8086 mode tasks. In all
my experiments in x86_32, the base of GDT and IDT was always a 4-byte
address, even for 16-bit operands. Thus, my emulation code does the
same. In all cases, the limit of the table is set to 0.
* STR and SLDT return 0 as the segment selector. This looks appropriate
since we are providing a dummy value as the base address of the global
descriptor table.
* SMSW returns the value with which the CR0 register is programmed in
head_32/64.S at boot time. This is, the following bits are enabled:
CR0.0 for Protection Enable, CR.1 for Monitor Coprocessor, CR.4 for
Extension Type, which will always be 1 in recent processors with UMIP;
CR.5 for Numeric Error, CR0.16 for Write Protect, CR0.18 for Alignment
Mask. As per the Intel 64 and IA-32 Architectures Software Developer's
Manual, SMSW returns a 16-bit results for memory operands. However, when
the operand is a register, the results can be up to CR0[63:0]. Since
the emulation code only kicks-in in x86_32, we return up to CR[31:0].
* The proposed emulation code is handles faults that happens in both
protected and virtual-8086 mode.
=== How is this series laid out?
++ Fix bugs in MPX address evaluator
I found very useful the code for Intel MPX (Memory Protection Extensions)
used to parse opcodes and the memory locations contained in the general
purpose registers when used as operands. I put some of this code in
a separate library file that both MPX and UMIP can access and avoid code
duplication. Before creating the new library, I fixed a couple of bugs
that I found in how MPX determines the address contained in the
instruction and operands.
++ Provide a new x86 instruction evaluating library
With bugs fixed, the MPX evaluating code is relocated in a new insn-eval.c
library. The basic functionality of this library is extended to obtain the
segment descriptor selected by either segment override prefixes or the
default segment by the involved registers in the calculation of the
effective address. It was also extended to obtain the default address and
operand sizes as well as the segment base address. Also, support to
process 16-bit address encodings. Armed with this arsenal, it is now
possible to determine the linear address onto which the emulated results
shall be copied.
This code supports Normal 32-bit and 64-bit (i.e., __USER32_CS and/or
__USER_CS) protected mode, virtual-8086 mode, 16-bit protected mode with
32-bit base address.
++ Emulate UMIP instructions
A new fixup_umip_exception functions inspect the instruction at the
instruction pointer. If it is an UMIP-protected instruction, it executes
the emulation code. This uses all the address-computing code of the
previous section.
++ Add self-tests
Lastly, self-tests are added to entry_from_v86.c to exercise the most
typical use cases of UMIP-protected instructions in a virtual-8086 mode.
++ Extensive tests
Extensive tests were performed to test all the combinations of ModRM,
SiB and displacements for 16-bit and 32-bit encodings for the ss, ds,
es, fs and gs segments. Tests also include a 64-bit program that uses
segmentation via fs and gs. For this purpose, I temporarily, and not
as part of this patchset, enabled UMIP support for 64-bit process with
the intention to test the computations of linear addresses in 64-bit
mode, including the extra R8-R15 registers. Extensive test is also
implemented for virtual-8086 tasks. Code of these tests can be found here
[10] and here [11].
[1]. https://lwn.net/Articles/705877/
[2]. https://lkml.org/lkml/2016/12/23/265
[3]. https://lkml.org/lkml/2017/1/25/622
[4]. https://lkml.org/lkml/2017/2/23/40
[5]. https://lkml.org/lkml/2017/3/3/678
[7]. https://www.winehq.org/
[8]. https://www.winehq.org/pipermail/wine-devel/2016-November/115320.html
[9]. http://www.dosemu.org/
[9]. http://marc.info/?l=linux-kernel&m=147876798717927&w=2
[10]. https://github.com/01org/luv-yocto/tree/rneri/umip/meta-luv/recipes-core/um…
[11]. https://github.com/01org/luv-yocto/commit/a72a7fe7d68693c0f4100ad86de6ecabd…
Thanks and BR,
Ricardo
Changes since V5:
* Relocate the page fault error code enumerations to traps.h
Changes since V4:
* Audited patches to use braces in all the branches of conditional.
statements, except those in which the conditional action only takes one
line.
* Implemented support in 64-builds for both 32-bit and 64-bit tasks in the
instruction evaluating library.
* Split segment selector function in the instruction evaluating library
into two functions to resolve the segment type by instruction override
or default and a separate function to actually read the segment selector.
* Fixed a bug when evaluating 32-bit effective addresses with 64-bit
kernels.
* Split patches further for for easier review.
* Use signed variables for computation of effective address.
* Fixed issue with a spurious static modifier in function insn_get_addr_ref
found by kbuild test bot.
* Removed comparison between true and fixup_umip_exception.
* Reworked check logic when identifying erroneous vs invalid values of the
SiB base and index.
Changes since V3:
* Limited emulation to 32-bit and 16-bit modes. For 64-bit mode, a general
protection fault is still issued when UMIP-protected instructions are
executed with CPL > 0.
* Expanded instruction-evaluating code to obtain segment descriptor along
with their attributes such as base address and default address and
operand sizes. Also, support for 16-bit encodings in protected mode was
implemented.
* When getting a segment descriptor, this include support to obtain those
of a local descriptor table.
* Now the instruction-evaluating code returns -EDOM when the value of
registers should not be used in calculating the effective address. The
value -EINVAL is left for errors.
* Incorporate the value of the segment base address in the computation of
linear addresses.
* Renamed new instruction evaluation library from insn-kernel.c to
insn-eval.c
* Exported functions insn_get_reg_offset_* to obtain the register offset
by ModRM r/m, SiB base and SiB index.
* Improved documentation of functions.
* Split patches further for easier review.
Changes since V2:
* Added new utility functions to decode the memory addresses contained in
registers when the 16-bit addressing encodings are used. This includes
code to obtain and compute memory addresses using segment selectors for
real-mode address translation.
* Added support to emulate UMIP-protected instructions for virtual-8086
tasks.
* Added self-tests for virtual-8086 mode that contains representative
use cases: address represented as a displacement, address in registers
and registers as operands.
* Instead of maintaining a static variable for the dummy base addresses
of the IDT and GDT, a hard-coded value is used.
* The emulated SMSW instructions now return the value with which the CR0
register is programmed in head_32/64.S This is: PE | MP | ET | NE | WP
| AM. For x86_64, PG is also enabled.
* The new file arch/x86/lib/insn-utils.c is now renamed as arch/x86/lib/
insn-kernel.c. It also has its own header. This helps keep in sync the
the kernel and objtool instruction decoders. Also, the new insn-kernel.c
contains utility functions that are only relevant in a kernel context.
* Removed printed warnings for errors that occur when decoding instructions
with invalid operands.
* Added more comments on fixes in the instruction-decoding MPX functions.
* Now user_64bit_mode(regs) is used instead of test_thread_flag(TIF_IA32)
to determine if the task is 32-bit or 64-bit.
* Found and fixed a bug in insn-decoder in which X86_MODRM_RM was
incorrectly used to obtain the mod part of the ModRM byte.
* Added more explanatory code in emulation and instruction decoding code.
This includes a comment regarding that copy_from_user could fail if there
exists a memory protection key in place.
* Tested code with CONFIG_X86_DECODER_SELFTEST=y and everything passes now.
* Prefixed get_reg_offset_rm with insn_ as this function is exposed
via a header file. For clarity, this function was added in a separate
patch.
Changes since V1:
* Virtual-8086 mode tasks are not treated in a special manner. All code
for this purpose was removed.
* Instead of attempting to disable UMIP during a context switch or when
entering virtual-8086 mode, UMIP remains enabled all the time. General
protection faults that occur are fixed-up by returning dummy values as
detailed above.
* Removed umip= kernel parameter in favor of using clearcpuid=514 to
disable UMIP.
* Removed selftests designed to detect the absence of SIGSEGV signals when
running in virtual-8086 mode.
* Reused code from MPX to decode instructions operands. For this purpose
code was put in a common location.
* Fixed two bugs in MPX code that decodes operands.
Ricardo Neri (21):
x86/mpx: Use signed variables to compute effective addresses
x86/mpx: Do not use SIB index if index points to R/ESP
x86/mpx: Do not use R/EBP as base in the SIB byte with Mod = 0
x86/mpx, x86/insn: Relocate insn util functions to a new insn-kernel
x86/insn-eval: Add utility functions to get register offsets
x86/insn-eval: Add utility functions to get segment selector
x86/insn-eval: Add utility function to get segment descriptor
x86/insn-eval: Add utility function to get segment descriptor base
address
x86/insn-eval: Add functions to get default operand and address sizes
x86/insn-eval: Do not use R/EBP as base if mod in ModRM is zero
insn/eval: Incorporate segment base in address computation
x86/insn: Support both signed 32-bit and 64-bit effective addresses
x86/insn-eval: Add support to resolve 16-bit addressing encodings
x86/insn-eval: Add wrapper function for 16-bit and 32-bit address
encodings
x86/mm: Relocate page fault error codes to traps.h
x86/cpufeature: Add User-Mode Instruction Prevention definitions
x86: Add emulation code for UMIP instructions
x86/umip: Force a page fault when unable to copy emulated result to
user
x86/traps: Fixup general protection faults caused by UMIP
x86: Enable User-Mode Instruction Prevention
selftests/x86: Add tests for User-Mode Instruction Prevention
arch/x86/Kconfig | 10 +
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/disabled-features.h | 8 +-
arch/x86/include/asm/insn-eval.h | 23 +
arch/x86/include/asm/traps.h | 18 +
arch/x86/include/asm/umip.h | 15 +
arch/x86/include/uapi/asm/processor-flags.h | 2 +
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/cpu/common.c | 16 +-
arch/x86/kernel/traps.c | 4 +
arch/x86/kernel/umip.c | 298 +++++++++
arch/x86/lib/Makefile | 2 +-
arch/x86/lib/insn-eval.c | 832 ++++++++++++++++++++++++++
arch/x86/mm/fault.c | 88 ++-
arch/x86/mm/mpx.c | 120 +---
tools/testing/selftests/x86/entry_from_vm86.c | 39 +-
16 files changed, 1301 insertions(+), 176 deletions(-)
create mode 100644 arch/x86/include/asm/insn-eval.h
create mode 100644 arch/x86/include/asm/umip.h
create mode 100644 arch/x86/kernel/umip.c
create mode 100644 arch/x86/lib/insn-eval.c
--
2.9.3
Hi,
Thanks for taking this up again…
On Apr 24, 2017, at 3:48 PM, Donat Enikeev <donat(a)enikeev.net> wrote:
>
> Based on Ken Thomases <ken(a)codeweavers.com> staging patches
>
> Signed-off-by: Donat Enikeev <donat(a)enikeev.net>
> ---
> dlls/winemac.drv/display.c | 51 +++++++++++++++++++++++++++++++++++++++
> dlls/winemac.drv/winemac.drv.spec | 1 +
> 2 files changed, 52 insertions(+)
This doesn't build:
display.c:1007:13: error: use of undeclared identifier 'monitors'
if (monitors[iDevNum].dwFlags & MONITORINFOF_PRIMARY)
^
display.c:1010:80: error: use of undeclared identifier 'monitors'
memcpy(lpDisplayDevice->DeviceName, monitors[iDevNum].szDevice, sizeof(monitors[iDevNum].szDevice));
^
display.c:1010:45: error: use of undeclared identifier 'monitors'
memcpy(lpDisplayDevice->DeviceName, monitors[iDevNum].szDevice, sizeof(monitors[iDevNum].szDevice));
^
Is this patch written on the assumption that some other staging patches have already been applied?
Beyond that, can you explain the rationale of moving the implementation of EnumDisplayDevices to the drivers? My patches implemented it in user32 based on EnumDisplayMonitors() and GetMonitorInfoW(). It may be somewhat clunky, but has the advantage that it ensures all three functions return mutually consistent results. Since you appear to have dropped my patches which caused GetMonitorInfoW() to return unique names for the displays, they are no longer consistent. GetMonitorInfoW() always uses "\\.\DISPLAY1" for all monitors while this implementation of EnumDisplayDevices() attempts to use "\\.\DISPLAY2", etc., for secondary and subsequent monitors.
For what it's worth, my original patches were rejected because Alexandre wanted the tracking and management of displays and display modes centralized in the explorer process[1]. I have my reservations about that approach, mind you. ;)
[1] https://www.winehq.org/pipermail/wine-devel/2014-March/103680.html
Issues with other patches in the series:
Patch 1: \ No newline at end of file
Patches 1 and 2 ought to come after 3. In the current order, they introduce dead code.
-Ken