You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c5cb54635 | ||
|
03b53697da | ||
|
c901884ac0 | ||
|
5fad8dd101 | ||
|
ae46f56f2c | ||
|
5eeb4b76d6 | ||
|
b9a08f8300 | ||
|
41367bc540 | ||
|
e780e2e62d | ||
|
a90554bb04 | ||
|
7104b9b6ba | ||
|
51d8ac0717 | ||
|
4af1f11315 | ||
|
cd2cce28cc | ||
|
761b7f72d0 |
@@ -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
|
||||
|
@@ -1,5 +0,0 @@
|
||||
Fixes: Fix crash in NFS Underground
|
||||
#Depends: dinput-joy-mappings
|
||||
Depends: dinput-scancode
|
||||
|
||||
# PR 6249
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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, ¶ms );
|
||||
}
|
||||
|
||||
+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
|
||||
|
@@ -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
|
||||
|
@@ -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
Reference in New Issue
Block a user