Compare commits

..

15 Commits
v9.15 ... v9.16

Author SHA1 Message Date
Alistair Leslie-Hughes
6c5cb54635 Release v9.16 2024-08-24 13:19:31 +10:00
Alistair Leslie-Hughes
03b53697da Updated dinput-scancode patchset 2024-08-24 12:46:03 +10:00
Elizabeth Figura
c901884ac0 ntdll-WRITECOPY: Remove patch 0010.
This is a hack specifically meant for upstream Wine; it was never meant to apply to Wine-Staging.

This very patch set is supposed to be a more complete and holistic hack/implementation of the same logic.

This hack only works for CEF, and breaks the existing tests that are fixed by the rest of ntdll-WRITECOPY.
2024-08-22 19:20:23 -05:00
Elizabeth Figura
5fad8dd101 Rebase against 6a7bfbab10d653f6724e2917e0552515520e4fb3. 2024-08-22 19:07:19 -05:00
Elizabeth Figura
ae46f56f2c ntdll-WRITECOPY: Install existing signal handlers earlier instead of using a special early signal handler. 2024-08-22 18:49:16 -05:00
Alistair Leslie-Hughes
5eeb4b76d6 Updated vkd3d-latest patchset 2024-08-21 08:05:40 +10:00
Alistair Leslie-Hughes
b9a08f8300 Rebase against 6e15604c48acd63dd8095a4ce2fd011cb3be96db. 2024-08-21 07:52:15 +10:00
Alistair Leslie-Hughes
41367bc540 Updated vkd3d-latest patchset 2024-08-20 07:49:47 +10:00
Alistair Leslie-Hughes
e780e2e62d Rebase against ba66d9c71519176bd499eb846ed11fb0ea421118. 2024-08-20 07:43:11 +10:00
Alistair Leslie-Hughes
a90554bb04 Rebase against 16a6b0ad65e9b8cdbb68fc9125951483781ca616. 2024-08-16 08:26:55 +10:00
Alistair Leslie-Hughes
7104b9b6ba Rebase against 75f8de6bd41c945abe230e8fd1d8645f30b7667f. 2024-08-15 08:35:27 +10:00
Alistair Leslie-Hughes
51d8ac0717 Rebase against eef229cc1eb77c3236ab4e210a6a276b65173e39.
Fixes regression with latest odbc32.
2024-08-14 07:58:19 +10:00
Alistair Leslie-Hughes
4af1f11315 Rebase against d98f067294918aa5cfeadb576652dd8fd1757c38. 2024-08-13 11:58:33 +10:00
Elizabeth Figura
cd2cce28cc eventfd_synchronization: Fix compile warnings.
Why, GCC, did you think this was a good idea?
2024-08-12 16:55:29 -05:00
Elizabeth Figura
761b7f72d0 dinput-regression-fix: Remove patch.
This is not the correct fix for the regression, and the regression is not in fact a regression.
2024-08-12 16:50:26 -05:00
59 changed files with 20013 additions and 20523 deletions

View File

@@ -1,29 +0,0 @@
From 434df65f9023ec64c175825e5b38cd9daf744565 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aida=20Jonikien=C4=97?= <aidas957@gmail.com>
Date: Sat, 10 Aug 2024 22:20:30 +0300
Subject: [PATCH] dinput: Use the correct array index in
keyboard_create_device().
This fixes a segfault when launching NFS Underground.
Fixes: f434ea12b83 ("dinput: Implement DIPROP_SCANCODE.")
---
dlls/dinput/keyboard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index a83f825e97d..aee1d996dde 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -211,7 +211,7 @@ HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirect
if (FAILED(hr = dinput_device_init_device_format( &impl->base.IDirectInputDevice8W_iface ))) goto failed;
- for (i = 0, index = 0; i < 512; ++i)
+ for (i = 0, index = 0; i < impl->base.device_format.dwNumObjs; ++i)
{
if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue;
if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue;
--
2.43.0

View File

@@ -1,5 +0,0 @@
Fixes: Fix crash in NFS Underground
#Depends: dinput-joy-mappings
Depends: dinput-scancode
# PR 6249

View File

@@ -0,0 +1,175 @@
From 77a518b61884ef4e06f4fe8b94dd5c855c5e8daf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 23 Aug 2024 08:49:13 +0200
Subject: [PATCH] dinput: Factor keyboard initialization and enumeration loops.
---
dlls/dinput/keyboard.c | 129 +++++++++++++++++++++++------------------
1 file changed, 72 insertions(+), 57 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 8ec9dd47150..d1fa242574e 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -185,12 +185,79 @@ HRESULT keyboard_enum_device( DWORD type, DWORD flags, DIDEVICEINSTANCEW *instan
return DI_OK;
}
+static BOOL enum_object( struct keyboard *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback,
+ UINT index, DIDEVICEOBJECTINSTANCEW *instance, void *data )
+{
+ if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE;
+
+ switch (filter->dwHow)
+ {
+ case DIPH_DEVICE:
+ return callback( &impl->base, index, NULL, instance, data );
+ case DIPH_BYOFFSET:
+ if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE;
+ return callback( &impl->base, index, NULL, instance, data );
+ case DIPH_BYID:
+ if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE;
+ return callback( &impl->base, index, NULL, instance, data );
+ }
+
+ return DIENUM_CONTINUE;
+}
+
+static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter,
+ DWORD flags, enum_object_callback callback, void *data )
+{
+ BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType );
+ DIDEVICEOBJECTINSTANCEW instance =
+ {
+ .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
+ .guidType = GUID_Key,
+ .dwOfs = DIK_ESCAPE,
+ .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ),
+ };
+ DWORD index, i, dik;
+ BOOL ret;
+
+ for (i = 0, index = 0; i < 512; ++i)
+ {
+ if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue;
+ if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue;
+ instance.dwOfs = dik;
+ instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik );
+ ret = enum_object( impl, filter, flags, callback, index++, &instance, data );
+ if (ret != DIENUM_CONTINUE) return DIENUM_STOP;
+ }
+
+ return DIENUM_CONTINUE;
+}
+
+static BOOL init_object_properties( struct dinput_device *device, UINT index, struct hid_value_caps *caps,
+ const DIDEVICEOBJECTINSTANCEW *instance, void *data )
+{
+ struct object_properties *properties;
+ UINT dik = instance->dwOfs;
+
+ if (index == -1) return DIENUM_STOP;
+ properties = device->object_properties + index;
+
+ if (dik == DIK_NUMLOCK) properties->scan_code = 0x451de1;
+ else if (dik == DIK_PAUSE) properties->scan_code = 0x45;
+ else if (dik < 0x80) properties->scan_code = dik;
+ else properties->scan_code = (dik - 0x80) << 8 | 0x00e0;
+
+ return DIENUM_CONTINUE;
+}
+
HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirectInputDevice8W **out )
{
- DIDEVICEOBJECTINSTANCEW instance;
+ static const DIPROPHEADER filter =
+ {
+ .dwSize = sizeof(filter),
+ .dwHeaderSize = sizeof(filter),
+ .dwHow = DIPH_DEVICE,
+ };
struct keyboard *impl;
- DWORD i, index, dik;
- BYTE subtype;
HRESULT hr;
TRACE( "dinput %p, guid %s, out %p.\n", dinput, debugstr_guid( guid ), out );
@@ -207,20 +274,9 @@ HRESULT keyboard_create_device( struct dinput *dinput, const GUID *guid, IDirect
impl->base.caps.dwFirmwareRevision = 100;
impl->base.caps.dwHardwareRevision = 100;
if (dinput->dwVersion >= 0x0800) impl->base.use_raw_input = TRUE;
- subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType );
if (FAILED(hr = dinput_device_init_device_format( &impl->base.IDirectInputDevice8W_iface ))) goto failed;
-
- for (i = 0, index = 0; i < 512; ++i)
- {
- if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue;
- if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue;
-
- if (dik == DIK_NUMLOCK) impl->base.object_properties[index++].scan_code = 0x451de1;
- else if (dik == DIK_PAUSE) impl->base.object_properties[index++].scan_code = 0x45;
- else if (dik < 0x80) impl->base.object_properties[index++].scan_code = dik;
- else impl->base.object_properties[index++].scan_code = (dik - 0x80) << 8 | 0x00e0;
- }
+ enum_objects( impl, &filter, DIDFT_BUTTON, init_object_properties, NULL );
*out = &impl->base.IDirectInputDevice8W_iface;
return DI_OK;
@@ -248,52 +304,11 @@ static HRESULT keyboard_unacquire( IDirectInputDevice8W *iface )
return DI_OK;
}
-static BOOL try_enum_object( struct dinput_device *impl, const DIPROPHEADER *filter, DWORD flags, enum_object_callback callback,
- UINT index, DIDEVICEOBJECTINSTANCEW *instance, void *data )
-{
- if (flags != DIDFT_ALL && !(flags & DIDFT_GETTYPE( instance->dwType ))) return DIENUM_CONTINUE;
-
- switch (filter->dwHow)
- {
- case DIPH_DEVICE:
- return callback( impl, index, NULL, instance, data );
- case DIPH_BYOFFSET:
- if (filter->dwObj != instance->dwOfs) return DIENUM_CONTINUE;
- return callback( impl, index, NULL, instance, data );
- case DIPH_BYID:
- if ((filter->dwObj & 0x00ffffff) != (instance->dwType & 0x00ffffff)) return DIENUM_CONTINUE;
- return callback( impl, index, NULL, instance, data );
- }
-
- return DIENUM_CONTINUE;
-}
-
static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter,
DWORD flags, enum_object_callback callback, void *context )
{
struct keyboard *impl = impl_from_IDirectInputDevice8W( iface );
- BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType );
- DIDEVICEOBJECTINSTANCEW instance =
- {
- .dwSize = sizeof(DIDEVICEOBJECTINSTANCEW),
- .guidType = GUID_Key,
- .dwOfs = DIK_ESCAPE,
- .dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ),
- };
- DWORD index, i, dik;
- BOOL ret;
-
- for (i = 0, index = 0; i < 512; ++i)
- {
- if (!GetKeyNameTextW( i << 16, instance.tszName, ARRAY_SIZE(instance.tszName) )) continue;
- if (!(dik = map_dik_code( i, 0, subtype, impl->base.dinput->dwVersion ))) continue;
- instance.dwOfs = dik;
- instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik );
- ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context );
- if (ret != DIENUM_CONTINUE) return DIENUM_STOP;
- }
-
- return DIENUM_CONTINUE;
+ return enum_objects( impl, filter, flags, callback, context );
}
static HRESULT keyboard_get_property( IDirectInputDevice8W *iface, DWORD property,
--
2.43.0

View File

@@ -1,6 +1,6 @@
From b2764b3d21a64c3c194b29b9cb71379456e03b06 Mon Sep 17 00:00:00 2001
From b9f850d5ba2d36ae39a2e88b31a687e2d9745c6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 7 Jul 2023 12:44:26 +0200
Date: Fri, 23 Aug 2024 08:51:44 +0200
Subject: [PATCH] dinput: Avoid duplicated objects in keyboard devices.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205
@@ -9,10 +9,10 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index cbcbf94f0f6..3fd75bb10e6 100644
index d1fa242574e..d9c73cd7367 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -265,13 +265,15 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH
@@ -216,13 +216,15 @@ static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter,
.dwOfs = DIK_ESCAPE,
.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ),
};
@@ -28,7 +28,7 @@ index cbcbf94f0f6..3fd75bb10e6 100644
+ mapped[dik] = TRUE;
instance.dwOfs = dik;
instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik );
ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context );
ret = enum_object( impl, filter, flags, callback, index++, &instance, data );
--
2.40.1
2.43.0

View File

@@ -1,6 +1,6 @@
From bdf952bf0711a7cf22fee840197234bd413ae611 Mon Sep 17 00:00:00 2001
From c133a17f33a7cce87df6a56c7e265b1553726134 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 7 Jul 2023 12:45:04 +0200
Date: Fri, 23 Aug 2024 08:52:34 +0200
Subject: [PATCH] dinput: Enumerate lower keyboard scancodes values first.
Windows usually doesn't have scancodes higher than 0x7f, or extended
@@ -16,18 +16,18 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55205
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 3fd75bb10e6..1f1db883b80 100644
index d9c73cd7367..407634967de 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -256,6 +256,7 @@ static BOOL try_enum_object( struct dinput_device *impl, const DIPROPHEADER *fil
static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPHEADER *filter,
DWORD flags, enum_object_callback callback, void *context )
@@ -208,6 +208,7 @@ static BOOL enum_object( struct keyboard *impl, const DIPROPHEADER *filter, DWOR
static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter,
DWORD flags, enum_object_callback callback, void *data )
{
+ static const UINT vsc_base[] = {0, 0x100, 0x80, 0x180};
struct keyboard *impl = impl_from_IDirectInputDevice8W( iface );
BYTE subtype = GET_DIDEVICE_SUBTYPE( impl->base.instance.dwDevType );
DIDEVICEOBJECTINSTANCEW instance =
@@ -266,18 +267,21 @@ static HRESULT keyboard_enum_objects( IDirectInputDevice8W *iface, const DIPROPH
{
@@ -217,18 +218,21 @@ static HRESULT enum_objects( struct keyboard *impl, const DIPROPHEADER *filter,
.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( DIK_ESCAPE ),
};
BOOL ret, mapped[0x100] = {0};
@@ -43,7 +43,7 @@ index 3fd75bb10e6..1f1db883b80 100644
- mapped[dik] = TRUE;
- instance.dwOfs = dik;
- instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik );
- ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context );
- ret = enum_object( impl, filter, flags, callback, index++, &instance, data );
- if (ret != DIENUM_CONTINUE) return DIENUM_STOP;
+ for (vsc = vsc_base[i]; vsc < vsc_base[i] + 0x80; vsc++)
+ {
@@ -53,12 +53,12 @@ index 3fd75bb10e6..1f1db883b80 100644
+ mapped[dik] = TRUE;
+ instance.dwOfs = dik;
+ instance.dwType = DIDFT_PSHBUTTON | DIDFT_MAKEINSTANCE( dik );
+ ret = try_enum_object( &impl->base, filter, flags, callback, index++, &instance, context );
+ ret = enum_object( impl, filter, flags, callback, index++, &instance, data );
+ if (ret != DIENUM_CONTINUE) return DIENUM_STOP;
+ }
}
return DIENUM_CONTINUE;
--
2.40.1
2.43.0

View File

@@ -0,0 +1,126 @@
From fed04f8ef69b829fa2cf3c7051160a6f822912dd Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Mon, 12 Aug 2024 16:54:44 -0500
Subject: [PATCH] ntdll: Compile warning fixes for esync.
---
dlls/ntdll/unix/esync.c | 26 +++++++++++++-------------
dlls/ntdll/unix/esync.h | 4 ++--
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/unix/esync.c b/dlls/ntdll/unix/esync.c
index f4748e405ef..86809b610c7 100644
--- a/dlls/ntdll/unix/esync.c
+++ b/dlls/ntdll/unix/esync.c
@@ -73,29 +73,29 @@ int do_esync(void)
struct esync
{
- enum esync_type type;
+ LONG type;
int fd;
void *shm;
};
struct semaphore
{
- int max;
- int count;
+ LONG max;
+ LONG count;
};
C_ASSERT(sizeof(struct semaphore) == 8);
struct mutex
{
- DWORD tid;
- int count; /* recursion count */
+ LONG tid;
+ LONG count; /* recursion count */
};
C_ASSERT(sizeof(struct mutex) == 8);
struct event
{
- int signaled;
- int locked;
+ LONG signaled;
+ LONG locked;
};
C_ASSERT(sizeof(struct event) == 8);
@@ -182,7 +182,7 @@ static struct esync *add_to_list( HANDLE handle, enum esync_type type, int fd, v
}
}
- if (!InterlockedCompareExchange( (int *)&esync_list[entry][idx].type, type, 0 ))
+ if (!InterlockedCompareExchange( &esync_list[entry][idx].type, type, 0 ))
{
esync_list[entry][idx].fd = fd;
esync_list[entry][idx].shm = shm;
@@ -206,7 +206,7 @@ static struct esync *get_cached_object( HANDLE handle )
* message queue, etc.) */
static NTSTATUS get_object( HANDLE handle, struct esync **obj )
{
- NTSTATUS ret = STATUS_SUCCESS;
+ int ret = STATUS_SUCCESS;
enum esync_type type = 0;
unsigned int shm_idx = 0;
obj_handle_t fd_handle;
@@ -274,7 +274,7 @@ NTSTATUS esync_close( HANDLE handle )
if (entry < ESYNC_LIST_ENTRIES && esync_list[entry])
{
- if (InterlockedExchange((int *)&esync_list[entry][idx].type, 0))
+ if (InterlockedExchange(&esync_list[entry][idx].type, 0))
{
close( esync_list[entry][idx].fd );
return STATUS_SUCCESS;
@@ -370,7 +370,7 @@ static NTSTATUS open_esync( enum esync_type type, HANDLE *handle,
}
extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
- const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max)
+ const OBJECT_ATTRIBUTES *attr, int initial, int max)
{
TRACE("name %s, initial %d, max %d.\n",
attr ? debugstr_us(attr->ObjectName) : "<no name>", initial, max);
@@ -386,7 +386,7 @@ NTSTATUS esync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
return open_esync( ESYNC_SEMAPHORE, handle, access, attr );
}
-NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev )
+NTSTATUS esync_release_semaphore( HANDLE handle, unsigned int count, ULONG *prev )
{
struct esync *obj;
struct semaphore *semaphore;
@@ -800,7 +800,7 @@ static BOOL update_grabbed_object( struct esync *obj )
/* A value of STATUS_NOT_IMPLEMENTED returned from this function means that we
* need to delegate to server_select(). */
-static NTSTATUS __esync_wait_objects( DWORD count, const HANDLE *handles, BOOLEAN wait_any,
+static NTSTATUS __esync_wait_objects( unsigned int count, const HANDLE *handles, BOOLEAN wait_any,
BOOLEAN alertable, const LARGE_INTEGER *timeout )
{
static const LARGE_INTEGER zero;
diff --git a/dlls/ntdll/unix/esync.h b/dlls/ntdll/unix/esync.h
index 59f8809fc1a..9102cf911aa 100644
--- a/dlls/ntdll/unix/esync.h
+++ b/dlls/ntdll/unix/esync.h
@@ -23,11 +23,11 @@ extern void esync_init(void);
extern NTSTATUS esync_close( HANDLE handle );
extern NTSTATUS esync_create_semaphore(HANDLE *handle, ACCESS_MASK access,
- const OBJECT_ATTRIBUTES *attr, LONG initial, LONG max);
+ const OBJECT_ATTRIBUTES *attr, int initial, int max);
extern NTSTATUS esync_open_semaphore( HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr );
extern NTSTATUS esync_query_semaphore( HANDLE handle, void *info, ULONG *ret_len );
-extern NTSTATUS esync_release_semaphore( HANDLE handle, ULONG count, ULONG *prev );
+extern NTSTATUS esync_release_semaphore( HANDLE handle, unsigned int count, ULONG *prev );
extern NTSTATUS esync_create_event( HANDLE *handle, ACCESS_MASK access,
const OBJECT_ATTRIBUTES *attr, EVENT_TYPE type, BOOLEAN initial );
--
2.45.2

View File

@@ -0,0 +1,63 @@
From 96831bd0bda656192510397cd18cb2c4bff5d8f4 Mon Sep 17 00:00:00 2001
From: Elizabeth Figura <zfigura@codeweavers.com>
Date: Thu, 22 Aug 2024 18:42:33 -0500
Subject: [PATCH 03/10] ntdll: Install signal handlers a bit earlier.
The wine-staging WRITECOPY implementation needs to be able to handle write faults while relocating builtin modules loaded during process initialization.
Note that the comment about debug events isn't relevant anymore because these exceptions all happen on the Unix stack anyway.
Probably there's a better solution involving simply not write-protecting these pages until we get to PE code, but that's not worth writing when this whole patch set is moribund anyway.
---
dlls/ntdll/unix/loader.c | 1 +
dlls/ntdll/unix/server.c | 5 -----
dlls/ntdll/unix/signal_i386.c | 5 ++++-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 92f2e2eb3a3..a6ea16bb7bb 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1866,6 +1866,7 @@ static void start_main_thread(void)
set_load_order_app_name( main_wargv[0] );
init_thread_stack( teb, 0, 0, 0 );
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
+ signal_init_process();
load_ntdll();
load_wow64_ntdll( main_image_info.Machine );
load_apiset_dll();
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 27dbf1331aa..80504e3459c 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -1674,11 +1674,6 @@ void server_init_process_done(void)
send_server_task_port();
#endif
- /* Install signal handlers; this cannot be done earlier, since we cannot
- * send exceptions to the debugger before the create process event that
- * is sent by init_process_done */
- signal_init_process();
-
/* always send the native TEB */
if (!(teb = NtCurrentTeb64())) teb = NtCurrentTeb();
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 61d41ec3589..b838a7a8669 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -719,7 +719,10 @@ static inline void *init_handler( const ucontext_t *sigcontext )
{
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
set_fs( thread_data->fs );
- set_gs( thread_data->gs );
+ /* FIXME ZF: This is a bit of a hack, but it doesn't matter,
+ * since this patch set goes in the wrong direction anyway. */
+ if (thread_data->gs)
+ set_gs( thread_data->gs );
}
#endif
--
2.45.2

View File

@@ -1,178 +0,0 @@
From c9d4a9c3a65b1ff1a0c4b4042394f2fab3b2019a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 02:53:22 +0200
Subject: [PATCH] ntdll: Setup a temporary signal handler during process
startup to handle page faults. (v2)
---
dlls/ntdll/unix/loader.c | 2 ++
dlls/ntdll/unix/signal_arm.c | 6 ++++
dlls/ntdll/unix/signal_arm64.c | 6 ++++
dlls/ntdll/unix/signal_i386.c | 52 +++++++++++++++++++++++++++++++++
dlls/ntdll/unix/signal_x86_64.c | 6 ++++
dlls/ntdll/unix/unix_private.h | 1 +
dlls/ntdll/unix/virtual.c | 2 +-
7 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index fa1a943fd51..5a8b0f57e42 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -2142,6 +2142,8 @@ DECLSPEC_EXPORT void __wine_main( int argc, char *argv[], char *envp[] )
#endif
virtual_init();
+ signal_init_early();
+
init_environment();
#ifdef __APPLE__
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 5115fa7ec3a..8e23007e936 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -1615,6 +1615,12 @@ void signal_init_process(void)
exit(1);
}
+/**********************************************************************
+ * signal_init_early
+ */
+void signal_init_early(void)
+{
+}
/***********************************************************************
* call_init_thunk
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index f96ec330796..eaecf988c54 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -1623,6 +1623,12 @@ void signal_init_process(void)
exit(1);
}
+/**********************************************************************
+ * signal_init_early
+ */
+void signal_init_early(void)
+{
+}
/***********************************************************************
* syscall_dispatcher_return_slowpath
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index c64a8b1efe2..cc1eff1f40b 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1895,6 +1895,30 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext )
}
+/**********************************************************************
+ * segv_handler_early
+ *
+ * Handler for SIGSEGV and related errors. Used only during the initialization
+ * of the process to handle virtual faults.
+ */
+static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
+{
+ ucontext_t *ucontext = sigcontext;
+
+ switch (TRAP_sig(ucontext))
+ {
+ case TRAP_x86_PAGEFLT: /* Page fault */
+ if (!virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09,
+ NULL))
+ return;
+ /* fall-through */
+ default:
+ WINE_ERR( "Got unexpected trap %d during process initialization\n", TRAP_sig(ucontext) );
+ abort_thread(1);
+ break;
+ }
+}
+
/**********************************************************************
* segv_handler
*
@@ -2465,6 +2489,34 @@ void signal_init_process(void)
exit(1);
}
+/**********************************************************************
+ * signal_init_early
+ */
+void signal_init_early(void)
+{
+ struct sigaction sig_act;
+
+ sig_act.sa_mask = server_block_set;
+ sig_act.sa_flags = SA_SIGINFO | SA_RESTART;
+#ifdef SA_ONSTACK
+ sig_act.sa_flags |= SA_ONSTACK;
+#endif
+#ifdef __ANDROID__
+ sig_act.sa_flags |= SA_RESTORER;
+ sig_act.sa_restorer = rt_sigreturn;
+#endif
+ sig_act.sa_sigaction = segv_handler_early;
+ if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
+ if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
+#ifdef SIGBUS
+ if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
+#endif
+ return;
+
+error:
+ perror("sigaction");
+ exit(1);
+}
/***********************************************************************
* call_init_thunk
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index a28762915be..d22515ab921 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2659,6 +2659,12 @@ void signal_init_process(void)
exit(1);
}
+/**********************************************************************
+ * signal_init_early
+ */
+void signal_init_early(void)
+{
+}
/***********************************************************************
* call_init_thunk
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index fadad6ae824..d8eaabef781 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -277,6 +277,7 @@ extern void signal_init_threading(void);
extern NTSTATUS signal_alloc_thread( TEB *teb );
extern void signal_free_thread( TEB *teb );
extern void signal_init_process(void);
+extern void signal_init_early(void);
extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE entry, void *arg,
BOOL suspend, TEB *teb );
extern SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4];
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index e0099f1a5c2..fd0b382b368 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -3961,7 +3961,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
}
#endif
- if (!is_inside_signal_stack( stack ) && (vprot & VPROT_GUARD))
+ if (stack && !is_inside_signal_stack( stack ) && (vprot & VPROT_GUARD))
{
struct thread_stack_info stack_info;
if (!is_inside_thread_stack( page, &stack_info ))
--
2.43.0

View File

@@ -1,4 +1,4 @@
From 4a297f731112822e51086826f975bf5db9178e52 Mon Sep 17 00:00:00 2001
From 8ec23a75cf45f9b2841b76504c827d368682c126 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 4 Oct 2014 03:22:09 +0200
Subject: [PATCH] ntdll: Properly handle PAGE_WRITECOPY protection. (try 5)
@@ -9,10 +9,10 @@ For now, only enable it when a special environment variable is set.
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index cf0c1598720..ff585c647bc 100644
index b108e49ad4d..70211bbfa3d 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -495,6 +495,21 @@ static void reserve_area( void *addr, void *end )
@@ -506,6 +506,21 @@ static void reserve_area( void *addr, void *end )
#endif /* __APPLE__ */
}
@@ -34,7 +34,7 @@ index cf0c1598720..ff585c647bc 100644
static void mmap_init( const struct preload_info *preload_info )
{
@@ -852,8 +867,19 @@ static int get_unix_prot( BYTE vprot )
@@ -1136,8 +1151,19 @@ static int get_unix_prot( BYTE vprot )
{
if (vprot & VPROT_READ) prot |= PROT_READ;
if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ;
@@ -55,7 +55,7 @@ index cf0c1598720..ff585c647bc 100644
if (vprot & VPROT_WRITEWATCH) prot &= ~PROT_WRITE;
}
if (!prot) prot = PROT_NONE;
@@ -1457,7 +1483,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size
@@ -1817,7 +1843,7 @@ static void update_write_watches( void *base, size_t size, size_t accessed_size
{
TRACE( "updating watch %p-%p-%p\n", base, (char *)base + accessed_size, (char *)base + size );
/* clear write watch flag on accessed pages */
@@ -64,9 +64,9 @@ index cf0c1598720..ff585c647bc 100644
/* restore page protections on the entire range */
mprotect_range( base, size, 0, 0 );
}
@@ -2985,12 +3011,13 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
mprotect_range( page, page_size, 0, 0 );
@@ -4065,12 +4091,13 @@ NTSTATUS virtual_handle_fault( EXCEPTION_RECORD *rec, void *stack )
mprotect_range( page, page_size, 0, 0 );
}
}
- /* ignore fault if page is writable now */
- if (get_unix_prot( get_page_vprot( page )) & PROT_WRITE)
@@ -81,8 +81,8 @@ index cf0c1598720..ff585c647bc 100644
+ if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS;
}
mutex_unlock( &virtual_mutex );
return ret;
@@ -3067,11 +3094,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat
rec->ExceptionCode = ret;
@@ -4144,11 +4171,16 @@ static NTSTATUS check_write_access( void *base, size_t size, BOOL *has_write_wat
{
BYTE vprot = get_page_vprot( addr + i );
if (vprot & VPROT_WRITEWATCH) *has_write_watch = TRUE;
@@ -101,5 +101,5 @@ index cf0c1598720..ff585c647bc 100644
}
--
2.28.0
2.45.2

View File

@@ -1,4 +1,4 @@
From e00479d767bf9bbb480be7b5c75dbd55812feb4d Mon Sep 17 00:00:00 2001
From 10f273da9caa0b7c814f46b76279065a956393af Mon Sep 17 00:00:00 2001
From: Andrew Wesie <awesie@gmail.com>
Date: Fri, 24 Apr 2020 14:55:14 -0500
Subject: [PATCH] ntdll: Track if a WRITECOPY page has been modified.
@@ -8,11 +8,11 @@ read-write page.
Signed-off-by: Andrew Wesie <awesie@gmail.com>
---
dlls/ntdll/unix/virtual.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
dlls/ntdll/unix/virtual.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 75d5a3fc966..c91484432c1 100644
index 5eadabf7dca..58fd4d0edfc 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -122,6 +122,7 @@ struct file_view
@@ -23,7 +23,7 @@ index 75d5a3fc966..c91484432c1 100644
/* per-mapping protection flags */
#define VPROT_ARM64EC 0x0100 /* view may contain ARM64EC code */
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
@@ -1127,7 +1128,7 @@ static int get_unix_prot( BYTE vprot )
@@ -1155,7 +1156,7 @@ static int get_unix_prot( BYTE vprot )
#if defined(__i386__)
if (vprot & VPROT_WRITECOPY)
{
@@ -32,7 +32,7 @@ index 75d5a3fc966..c91484432c1 100644
prot = (prot & ~PROT_WRITE) | PROT_READ;
else
prot |= PROT_WRITE | PROT_READ;
@@ -1641,7 +1642,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
@@ -1672,7 +1673,11 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
*/
static DWORD get_win32_prot( BYTE vprot, unsigned int map_prot )
{
@@ -45,7 +45,12 @@ index 75d5a3fc966..c91484432c1 100644
if (vprot & VPROT_GUARD) ret |= PAGE_GUARD;
if (map_prot & SEC_NOCACHE) ret |= PAGE_NOCACHE;
return ret;
@@ -1752,12 +1757,21 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
@@ -1778,16 +1783,29 @@ static void mprotect_range( void *base, size_t size, BYTE set, BYTE clear )
*/
static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vprot )
{
+ int unix_prot;
+
if (view->protect & VPROT_WRITEWATCH)
{
/* each page may need different protections depending on write watch flag */
@@ -54,13 +59,17 @@ index 75d5a3fc966..c91484432c1 100644
mprotect_range( base, size, 0, 0 );
return TRUE;
}
+
if (enable_write_exceptions && is_vprot_exec_write( vprot )) vprot |= VPROT_WRITEWATCH;
- if (mprotect_exec( base, size, get_unix_prot(vprot) )) return FALSE;
- set_page_vprot( base, size, vprot );
+ unix_prot = get_unix_prot(vprot);
+
+ /* check that we can map this memory with PROT_WRITE since we cannot fail later */
+ if (vprot & VPROT_WRITECOPY)
+ unix_prot |= PROT_WRITE;
+
if (mprotect_exec( base, size, unix_prot )) return FALSE;
- set_page_vprot( base, size, vprot );
+ if (mprotect_exec( base, size, unix_prot )) return FALSE;
+ /* each page may need different protections depending on writecopy */
+ set_page_vprot_bits( base, size, vprot, ~vprot & ~VPROT_WRITTEN );
+ if (vprot & VPROT_WRITECOPY)
@@ -69,7 +78,7 @@ index 75d5a3fc966..c91484432c1 100644
return TRUE;
}
@@ -3739,7 +3753,7 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
@@ -4093,7 +4111,7 @@ NTSTATUS virtual_handle_fault( EXCEPTION_RECORD *rec, void *stack )
}
if (vprot & VPROT_WRITECOPY)
{
@@ -79,5 +88,5 @@ index 75d5a3fc966..c91484432c1 100644
}
/* ignore fault if page is writable now */
--
2.40.1
2.45.2

View File

@@ -1,86 +0,0 @@
From 153825fbb1dfc7e8624808681fd44f244b5c7c0e Mon Sep 17 00:00:00 2001
From: Andrew Wesie <awesie@gmail.com>
Date: Fri, 24 Apr 2020 14:55:15 -0500
Subject: [PATCH] ntdll: Support WRITECOPY on x64.
Signed-off-by: Andrew Wesie <awesie@gmail.com>
---
dlls/ntdll/unix/signal_x86_64.c | 41 +++++++++++++++++++++++++++++++++
dlls/ntdll/unix/virtual.c | 2 +-
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index db608b358ea..741d0ebed5f 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2266,6 +2266,30 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec,
}
+/**********************************************************************
+ * segv_handler_early
+ *
+ * Handler for SIGSEGV and related errors. Used only during the initialization
+ * of the process to handle virtual faults.
+ */
+static void segv_handler_early( int signal, siginfo_t *siginfo, void *sigcontext )
+{
+ ucontext_t *ucontext = sigcontext;
+
+ switch(TRAP_sig(ucontext))
+ {
+ case TRAP_x86_PAGEFLT: /* Page fault */
+ if (!virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09,
+ NULL ))
+ return;
+ /* fall-through */
+ default:
+ WINE_ERR( "Got unexpected trap %lld during process initialization\n", TRAP_sig(ucontext) );
+ abort_thread(1);
+ break;
+ }
+}
+
/**********************************************************************
* segv_handler
*
@@ -2641,6 +2665,23 @@ void signal_init_process(void)
*/
void signal_init_early(void)
{
+ struct sigaction sig_act;
+
+ sig_act.sa_mask = server_block_set;
+ sig_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+
+ sig_act.sa_sigaction = segv_handler_early;
+ if (sigaction( SIGSEGV, &sig_act, NULL ) == -1) goto error;
+ if (sigaction( SIGILL, &sig_act, NULL ) == -1) goto error;
+#ifdef SIGBUS
+ if (sigaction( SIGBUS, &sig_act, NULL ) == -1) goto error;
+#endif
+
+ return;
+
+ error:
+ perror("sigaction");
+ exit(1);
}
/***********************************************************************
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 21760152115..534f99a7064 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -820,7 +820,7 @@ static int get_unix_prot( BYTE vprot )
if (vprot & VPROT_READ) prot |= PROT_READ;
if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ;
if (vprot & VPROT_EXEC) prot |= PROT_EXEC | PROT_READ;
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
if (vprot & VPROT_WRITECOPY)
{
if (experimental_WRITECOPY() && !(vprot & VPROT_WRITTEN))
--
2.28.0

View File

@@ -1,4 +1,4 @@
From f26f4f9338473fee2ad3901fe5b259ac26e66f3c Mon Sep 17 00:00:00 2001
From 1d8b9ce07aaafd3184a118c8d986b54617571c7b Mon Sep 17 00:00:00 2001
From: Andrew Wesie <awesie@gmail.com>
Date: Tue, 28 Apr 2020 03:27:16 -0500
Subject: [PATCH] ntdll: Fallback to copy pages for WRITECOPY.
@@ -16,12 +16,12 @@ Signed-off-by: Andrew Wesie <awesie@gmail.com>
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 8346baf77a9..457468b47d9 100644
index 71fe33cdb0e..ba5701d7bfe 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -1587,8 +1587,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
return TRUE;
}
@@ -1796,8 +1796,9 @@ static BOOL set_vprot( struct file_view *view, void *base, size_t size, BYTE vpr
if (enable_write_exceptions && is_vprot_exec_write( vprot )) vprot |= VPROT_WRITEWATCH;
unix_prot = get_unix_prot(vprot);
- /* check that we can map this memory with PROT_WRITE since we cannot fail later */
- if (vprot & VPROT_WRITECOPY)
@@ -31,9 +31,9 @@ index 8346baf77a9..457468b47d9 100644
unix_prot |= PROT_WRITE;
if (mprotect_exec( base, size, unix_prot )) return FALSE;
@@ -3335,10 +3336,26 @@ NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
set_page_vprot_bits( page, page_size, 0, VPROT_WRITEWATCH );
mprotect_range( page, page_size, 0, 0 );
@@ -4111,10 +4112,26 @@ NTSTATUS virtual_handle_fault( EXCEPTION_RECORD *rec, void *stack )
mprotect_range( page, page_size, 0, 0 );
}
}
- if (vprot & VPROT_WRITECOPY)
+ if ((vprot & VPROT_WRITECOPY) && (vprot & VPROT_COMMITTED))
@@ -61,5 +61,5 @@ index 8346baf77a9..457468b47d9 100644
/* ignore fault if page is writable now */
if (get_unix_prot( get_page_vprot( page ) ) & PROT_WRITE) ret = STATUS_SUCCESS;
--
2.30.2
2.45.2

View File

@@ -1,28 +0,0 @@
From 321e3228c6c28256bfb209efdc372b61f9c8535f Mon Sep 17 00:00:00 2001
From: Fabian Maurer <dark.shadow4@web.de>
Date: Thu, 21 Dec 2023 20:09:23 +0100
Subject: [PATCH] kernelbase: Correct return value in VirtualProtect for
PAGE_WRITECOPY
---
dlls/kernelbase/memory.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 4f4bba9a13b..de42395b33b 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -481,7 +481,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH VirtualLock( void *addr, SIZE_T size )
*/
BOOL WINAPI DECLSPEC_HOTPATCH VirtualProtect( void *addr, SIZE_T size, DWORD new_prot, DWORD *old_prot )
{
- return VirtualProtectEx( GetCurrentProcess(), addr, size, new_prot, old_prot );
+ BOOL ret = VirtualProtectEx( GetCurrentProcess(), addr, size, new_prot, old_prot );
+ if (*old_prot == PAGE_WRITECOPY) *old_prot = PAGE_READWRITE;
+ return ret;
}
--
2.43.0

View File

@@ -1,30 +0,0 @@
From d455916aec7649a816deb36c303341a6c7732a97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aida=20Jonikien=C4=97?= <aidas957@gmail.com>
Date: Fri, 26 Jul 2024 20:33:57 +0300
Subject: [PATCH] kernelbase: Handle NULL old_prot parameter in
VirtualProtect().
This fixes a segfault when launching any game with the EA Desktop application.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56694
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56711
---
dlls/kernelbase/memory.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c
index 2b0e674bb9b..d1408cf4c0e 100644
--- a/dlls/kernelbase/memory.c
+++ b/dlls/kernelbase/memory.c
@@ -548,7 +548,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH VirtualLock( void *addr, SIZE_T size )
BOOL WINAPI DECLSPEC_HOTPATCH VirtualProtect( void *addr, SIZE_T size, DWORD new_prot, DWORD *old_prot )
{
BOOL ret = VirtualProtectEx( GetCurrentProcess(), addr, size, new_prot, old_prot );
- if (*old_prot == PAGE_WRITECOPY) *old_prot = PAGE_READWRITE;
+ if (old_prot && *old_prot == PAGE_WRITECOPY) *old_prot = PAGE_READWRITE;
return ret;
}
--
2.43.0

View File

@@ -1,42 +0,0 @@
From 49adfd79f730714b11c4d5f983ced05b26ffa52a Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 12 Jul 2024 13:42:26 +1000
Subject: [PATCH] odbc32: Support freeing SQL handles for ODBC v2 drivers.
---
dlls/odbc32/proxyodbc.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index 4799ca0a11e..678d9260fbb 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -1867,6 +1867,25 @@ static SQLRETURN free_handle_win32( SQLSMALLINT type, struct handle *handle )
{
if (handle->win32_funcs->SQLFreeHandle)
return handle->win32_funcs->SQLFreeHandle( type, handle->win32_handle );
+ else
+ {
+ /* ODBC v2 */
+ if (type == SQL_HANDLE_ENV)
+ {
+ if (handle->win32_funcs->SQLFreeEnv)
+ return handle->win32_funcs->SQLFreeEnv( handle->win32_handle );
+ }
+ else if (type == SQL_HANDLE_DBC)
+ {
+ if (handle->win32_funcs->SQLFreeConnect)
+ return handle->win32_funcs->SQLFreeConnect( handle->win32_handle );
+ }
+ else if (type == SQL_HANDLE_STMT)
+ {
+ if (handle->win32_funcs->SQLFreeStmt)
+ return handle->win32_funcs->SQLFreeStmt( handle->win32_handle, SQL_CLOSE );
+ }
+ }
return SQL_ERROR;
}
--
2.43.0

View File

@@ -1,35 +0,0 @@
From 1966db0e2fe8ee752a7a59b970749235b3fa0e20 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 18 Jul 2024 14:17:44 +1000
Subject: [PATCH] odbc32: SQLSetEnvAttr isnt supported in ODBC v2.0
---
dlls/odbc32/proxyodbc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index 6e51693e33c..0703e2f580d 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -1010,7 +1010,7 @@ static int has_suffix( const WCHAR *str, const WCHAR *suffix )
static SQLRETURN set_env_attr( struct handle *handle, SQLINTEGER attr, SQLPOINTER value, SQLINTEGER len )
{
- SQLRETURN ret = SQL_ERROR;
+ SQLRETURN ret = SQL_SUCCESS;
if (handle->unix_handle)
{
@@ -1019,7 +1019,8 @@ static SQLRETURN set_env_attr( struct handle *handle, SQLINTEGER attr, SQLPOINTE
}
else if (handle->win32_handle)
{
- ret = handle->win32_funcs->SQLSetEnvAttr( handle->win32_handle, attr, value, len );
+ if (handle->win32_funcs->SQLSetEnvAttr)
+ ret = handle->win32_funcs->SQLSetEnvAttr( handle->win32_handle, attr, value, len );
}
return ret;
}
--
2.43.0

View File

@@ -1,71 +0,0 @@
From c6edaf28df9e495ff173910c6e0124d244784f41 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 18 Jul 2024 14:34:49 +1000
Subject: [PATCH] odbc32: Support Allocating SQL handles for ODBC v2 drivers.
---
dlls/odbc32/proxyodbc.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index 6fe38e7a863..6168786084d 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -439,13 +439,32 @@ static SQLRETURN alloc_handle_unix( SQLSMALLINT type, struct handle *input, stru
static SQLRETURN alloc_handle_win32( SQLSMALLINT type, struct handle *input, struct handle *output )
{
+ SQLRETURN ret = SQL_ERROR;
if (input->win32_funcs->SQLAllocHandle)
{
- SQLRETURN ret = input->win32_funcs->SQLAllocHandle( type, input->win32_handle, &output->win32_handle );
- if (SUCCESS( ret )) output->win32_funcs = input->win32_funcs;
- return ret;
+ ret = input->win32_funcs->SQLAllocHandle( type, input->win32_handle, &output->win32_handle );
}
- return SQL_ERROR;
+ else
+ {
+ /* ODBC v2 */
+ if (type == SQL_HANDLE_ENV)
+ {
+ if (input->win32_funcs->SQLAllocEnv)
+ ret = input->win32_funcs->SQLAllocEnv( &output->win32_handle );
+ }
+ else if (type == SQL_HANDLE_DBC)
+ {
+ if (input->win32_funcs->SQLAllocConnect)
+ ret = input->win32_funcs->SQLAllocConnect( input, &output->win32_handle );
+ }
+ else if (type == SQL_HANDLE_STMT)
+ {
+ if (input->win32_funcs->SQLAllocStmt)
+ ret = input->win32_funcs->SQLAllocStmt( input, &output->win32_handle );
+ }
+ }
+ if (SUCCESS( ret )) output->win32_funcs = input->win32_funcs;
+ return ret;
}
/*************************************************************************
@@ -1045,7 +1064,7 @@ static SQLRETURN create_env( struct handle *handle, BOOL is_unix )
}
else
{
- if ((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_ENV, NULL, &handle->win32_handle ))) return ret;
+ if ((ret = alloc_handle_win32(SQL_HANDLE_ENV, handle, handle ))) return ret;
}
return prepare_env( handle );
@@ -1101,7 +1120,7 @@ static SQLRETURN create_con( struct handle *handle )
}
else
{
- if ((ret = handle->win32_funcs->SQLAllocHandle( SQL_HANDLE_DBC, parent->win32_handle, &handle->win32_handle )))
+ if ((ret = alloc_handle_win32(SQL_HANDLE_DBC, parent, handle )))
return ret;
}
--
2.43.0

View File

@@ -1,222 +0,0 @@
From 652327cf649f9d10794f18d6c3a2c3452f42f947 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 12 Jul 2024 14:13:33 +1000
Subject: [PATCH] odbc32: Support Driver in connection string
---
dlls/odbc32/proxyodbc.c | 100 ++++++++++++++++++++++++++++++----------
1 file changed, 75 insertions(+), 25 deletions(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index 94504a8cc26..df8fa06dc57 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -989,23 +989,28 @@ static HKEY open_odbcinst_key( void )
return NULL;
}
-static WCHAR *get_driver_filename( const SQLWCHAR *source )
+static WCHAR *get_driver_filename( const SQLWCHAR *source, BOOL is_dsn )
{
HKEY key_sources, key_odbcinst, key_driver;
WCHAR *driver_name, *ret;
- if (!(key_sources = open_sources_key( HKEY_CURRENT_USER ))) return NULL;
- if (!(driver_name = get_reg_value( key_sources, source )))
+ if (is_dsn)
{
- RegCloseKey( key_sources );
- if (!(key_sources = open_sources_key( HKEY_LOCAL_MACHINE ))) return NULL;
+ if (!(key_sources = open_sources_key( HKEY_CURRENT_USER ))) return NULL;
if (!(driver_name = get_reg_value( key_sources, source )))
{
RegCloseKey( key_sources );
- return NULL;
+ if (!(key_sources = open_sources_key( HKEY_LOCAL_MACHINE ))) return NULL;
+ if (!(driver_name = get_reg_value( key_sources, source )))
+ {
+ RegCloseKey( key_sources );
+ return NULL;
+ }
}
+ RegCloseKey( key_sources );
}
- RegCloseKey( key_sources );
+ else
+ driver_name = wcsdup(source);
if (!(key_odbcinst = open_odbcinst_key()) || RegOpenKeyExW( key_odbcinst, driver_name, 0, KEY_READ, &key_driver ))
{
@@ -1175,7 +1180,7 @@ SQLRETURN WINAPI SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSM
if (!handle) return SQL_INVALID_HANDLE;
- if (!servername || !(filename = get_driver_filename( servername )))
+ if (!servername || !(filename = get_driver_filename( servername, TRUE )))
{
WARN( "can't find driver filename\n" );
goto done;
@@ -3983,6 +3988,35 @@ static SQLRETURN browse_connect_unix_a( struct handle *handle, SQLCHAR *in_conn_
return ODBC_CALL( SQLBrowseConnect, &params );
}
+static WCHAR *get_driver( const WCHAR *connection_string )
+{
+ const WCHAR *p = connection_string, *q;
+ WCHAR *ret = NULL;
+ unsigned int len;
+
+ if (!p) return NULL;
+ while (*p)
+ {
+ if (!wcsnicmp( p, L"DRIVER=", 7 ))
+ {
+ p += 7;
+ if (*p == '{')
+ q = wcschr( ++p, '}' );
+ else
+ q = wcschr( p, ';' );
+ len = q ? (q - p) : wcslen( p );
+ if ((ret = malloc( (len + 1) * sizeof(WCHAR) )))
+ {
+ memcpy( ret, p, len * sizeof(WCHAR) );
+ ret[len] = 0;
+ break;
+ }
+ }
+ p++;
+ }
+ return ret;
+}
+
/*************************************************************************
* SQLBrowseConnect [ODBC32.055]
*/
@@ -3992,6 +4026,7 @@ SQLRETURN WINAPI SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectio
struct handle *handle = ConnectionHandle;
WCHAR *datasource = NULL, *filename = NULL, *connection_string = strdupAW( (const char *)InConnectionString );
SQLRETURN ret = SQL_ERROR;
+ BOOL is_dsn = TRUE;
TRACE("(ConnectionHandle %p, InConnectionString %s, StringLength1 %d, OutConnectionString %p, BufferLength, %d, "
"StringLength2 %p)\n", ConnectionHandle, debugstr_sqlstr(InConnectionString, StringLength1),
@@ -3999,13 +4034,16 @@ SQLRETURN WINAPI SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectio
if (!handle) return SQL_INVALID_HANDLE;
- /* FIXME: try DRIVER attribute if DSN is absent */
if (!connection_string || !(datasource = get_datasource( connection_string )))
{
- WARN( "can't find data source\n" );
- goto done;
+ is_dsn = FALSE;
+ if (!(datasource = get_driver( connection_string )))
+ {
+ WARN( "can't find data source\n" );
+ goto done;
+ }
}
- if (!(filename = get_driver_filename( datasource )))
+ if (!(filename = get_driver_filename( datasource, is_dsn )))
{
WARN( "can't find driver filename\n" );
goto done;
@@ -5083,6 +5121,7 @@ SQLRETURN WINAPI SQLDriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle
struct handle *handle = ConnectionHandle;
WCHAR *datasource = NULL, *filename = NULL, *connection_string = strdupAW( (const char *)InConnectionString );
SQLRETURN ret = SQL_ERROR;
+ BOOL is_dsn = TRUE;
TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p,"
" BufferLength %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle,
@@ -5091,13 +5130,16 @@ SQLRETURN WINAPI SQLDriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle
if (!handle) return SQL_INVALID_HANDLE;
- /* FIXME: try DRIVER attribute if DSN is absent */
if (!connection_string || !(datasource = get_datasource( connection_string )))
{
- WARN( "can't find data source\n" );
- goto done;
+ is_dsn = FALSE;
+ if (!(datasource = get_driver( connection_string )))
+ {
+ WARN( "can't find data source\n" );
+ goto done;
+ }
}
- if (!(filename = get_driver_filename( datasource )))
+ if (!(filename = get_driver_filename( datasource, is_dsn )))
{
WARN( "can't find driver filename\n" );
goto done;
@@ -5310,7 +5352,7 @@ SQLRETURN WINAPI SQLConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *ServerName, SQL
if (!handle) return SQL_INVALID_HANDLE;
- if (!(filename = get_driver_filename( ServerName )))
+ if (!(filename = get_driver_filename( ServerName, TRUE )))
{
WARN( "can't find driver filename\n" );
goto done;
@@ -6137,6 +6179,7 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl
struct handle *handle = ConnectionHandle;
WCHAR *datasource, *filename = NULL;
SQLRETURN ret = SQL_ERROR;
+ BOOL is_dsn = TRUE;
TRACE("(ConnectionHandle %p, WindowHandle %p, InConnectionString %s, Length %d, OutConnectionString %p,"
" BufferLength %d, Length2 %p, DriverCompletion %d)\n", ConnectionHandle, WindowHandle,
@@ -6145,13 +6188,16 @@ SQLRETURN WINAPI SQLDriverConnectW(SQLHDBC ConnectionHandle, SQLHWND WindowHandl
if (!handle) return SQL_INVALID_HANDLE;
- /* FIXME: try DRIVER attribute if DSN is absent */
if (!(datasource = get_datasource( InConnectionString )))
{
- WARN( "can't find data source\n" );
- goto done;
+ is_dsn = FALSE;
+ if (!(datasource = get_driver( InConnectionString )))
+ {
+ WARN( "can't find data source\n" );
+ goto done;
+ }
}
- if (!(filename = get_driver_filename( datasource )))
+ if (!(filename = get_driver_filename( datasource, is_dsn )))
{
WARN( "can't find driver filename\n" );
goto done;
@@ -6553,6 +6599,7 @@ SQLRETURN WINAPI SQLBrowseConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *InConnect
struct handle *handle = ConnectionHandle;
WCHAR *datasource, *filename = NULL;
SQLRETURN ret = SQL_ERROR;
+ BOOL is_dsn = TRUE;
TRACE("(ConnectionHandle %p, InConnectionString %s, StringLength1 %d, OutConnectionString %p, BufferLength %d, "
"StringLength2 %p)\n", ConnectionHandle, debugstr_sqlwstr(InConnectionString, StringLength1), StringLength1,
@@ -6560,13 +6607,16 @@ SQLRETURN WINAPI SQLBrowseConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *InConnect
if (!handle) return SQL_INVALID_HANDLE;
- /* FIXME: try DRIVER attribute if DSN is absent */
if (!(datasource = get_datasource( InConnectionString )))
{
- WARN( "can't find data source\n" );
- goto done;
+ is_dsn = FALSE;
+ if (!(datasource = get_driver( InConnectionString )))
+ {
+ WARN( "can't find data source\n" );
+ goto done;
+ }
}
- if (!(filename = get_driver_filename( datasource )))
+ if (!(filename = get_driver_filename( datasource, is_dsn )))
{
WARN( "can't find driver filename\n" );
goto done;
--
2.43.0

View File

@@ -1,53 +0,0 @@
From 6316f79675f38230ee43da7d8a993ff9cb1379f3 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 12 Jul 2024 14:19:22 +1000
Subject: [PATCH] odbc32: SQLColAttributeW support fallback function
---
dlls/odbc32/proxyodbc.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index df8fa06dc57..cbe3e72ef35 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -5686,6 +5686,21 @@ static SQLRETURN col_attribute_unix_w( struct handle *handle, SQLUSMALLINT col,
return ret;
}
+static SQLINTEGER map_odbc3_to_2(SQLINTEGER fieldid)
+{
+ switch( fieldid )
+ {
+ case SQL_DESC_COUNT:
+ return SQL_COLUMN_COUNT;
+ case SQL_DESC_NULLABLE:
+ return SQL_COLUMN_NULLABLE;
+ case SQL_DESC_NAME:
+ return SQL_COLUMN_NAME;
+ default:
+ return fieldid;
+ }
+}
+
static SQLRETURN col_attribute_win32_w( struct handle *handle, SQLUSMALLINT col, SQLUSMALLINT field_id,
SQLPOINTER char_attr, SQLSMALLINT buflen, SQLSMALLINT *retlen,
SQLLEN *num_attr )
@@ -5693,6 +5708,14 @@ static SQLRETURN col_attribute_win32_w( struct handle *handle, SQLUSMALLINT col,
if (handle->win32_funcs->SQLColAttributeW)
return handle->win32_funcs->SQLColAttributeW( handle->win32_handle, col, field_id, char_attr, buflen,
retlen, num_attr );
+ else if(handle->win32_funcs->SQLColAttributesW)
+ {
+ /* ODBC v2 */
+ field_id = map_odbc3_to_2(field_id);
+ return handle->win32_funcs->SQLColAttributesW( handle->win32_handle, col, field_id,
+ char_attr, buflen, retlen,
+ num_attr );
+ }
if (handle->win32_funcs->SQLColAttribute) FIXME( "Unicode to ANSI conversion not handled\n" );
return SQL_ERROR;
}
--
2.43.0

View File

@@ -1,59 +0,0 @@
From c72487ac8ae2279f43da906df6ac430fa55e2ae9 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 12 Jul 2024 14:29:17 +1000
Subject: [PATCH 06/15] odbc32: SQLGetDiagRec/W handle fallback function
---
dlls/odbc32/proxyodbc.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/dlls/odbc32/proxyodbc.c b/dlls/odbc32/proxyodbc.c
index 1f51ac2a27e..c4e1c046edc 100644
--- a/dlls/odbc32/proxyodbc.c
+++ b/dlls/odbc32/proxyodbc.c
@@ -1915,7 +1915,21 @@ SQLRETURN WINAPI SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMAL
}
else if (handle->win32_handle)
{
- ret = get_diag_rec_win32_a( HandleType, handle, RecNumber, SqlState, NativeError, MessageText, BufferLength,
+ /* ODBC v2.0 */
+ if (handle->win32_funcs->SQLError)
+ {
+ if (HandleType == SQL_HANDLE_ENV)
+ ret = handle->win32_funcs->SQLError(handle->win32_handle, SQL_NULL_HDBC, SQL_NULL_HSTMT,
+ SqlState, NativeError, MessageText, BufferLength, TextLength);
+ else if (HandleType == SQL_HANDLE_DBC)
+ ret = handle->win32_funcs->SQLError(SQL_NULL_HENV, handle->win32_handle, SQL_NULL_HSTMT,
+ SqlState, NativeError, MessageText, BufferLength, TextLength);
+ else if (HandleType == SQL_HANDLE_STMT)
+ ret = handle->win32_funcs->SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, handle->win32_handle,
+ SqlState, NativeError, MessageText, BufferLength, TextLength);
+ }
+ else
+ ret = get_diag_rec_win32_a( HandleType, handle, RecNumber, SqlState, NativeError, MessageText, BufferLength,
TextLength );
}
@@ -4285,6 +4299,19 @@ static SQLRETURN get_diag_rec_win32_w( SQLSMALLINT handle_type, struct handle *h
if (handle->win32_funcs->SQLGetDiagRecW)
return handle->win32_funcs->SQLGetDiagRecW( handle_type, handle->win32_handle, rec_num, state, native_err,
msg, buflen, retlen );
+ else if (handle->win32_funcs->SQLErrorW)
+ {
+ /* ODBC v2 */
+ if (handle_type == SQL_HANDLE_ENV)
+ return handle->win32_funcs->SQLErrorW(handle->win32_handle, SQL_NULL_HDBC, SQL_NULL_HSTMT,
+ state, native_err, msg, buflen, retlen);
+ else if (handle_type == SQL_HANDLE_DBC)
+ return handle->win32_funcs->SQLErrorW(SQL_NULL_HENV, handle->win32_handle, SQL_NULL_HSTMT,
+ state, native_err, msg, buflen, retlen);
+ else if (handle_type == SQL_HANDLE_STMT)
+ return handle->win32_funcs->SQLErrorW(SQL_NULL_HENV, SQL_NULL_HDBC, handle->win32_handle,
+ state, native_err, msg, buflen, retlen);
+ }
if (handle->win32_funcs->SQLGetDiagRec) FIXME( "Unicode to ANSI conversion not handled\n" );
return SQL_ERROR;
}
--
2.43.0

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