Compare commits

..

14 Commits
v7.18 ... v7.19

Author SHA1 Message Date
Alistair Leslie-Hughes
41a3c56c50 Release v7.19 2022-10-17 12:17:38 +11:00
Zebediah Figura
5be23b8ae8 Rebase against e3f00bf7c944f1cde6151fde969f2b49649c3de7. 2022-10-16 16:22:20 -05:00
Zebediah Figura
769ddd9f00 ntdll-Junction_Points: Updates from Erich E. Hoover. 2022-10-16 16:22:16 -05:00
Zebediah Figura
aabde22767 Rebase against fded20df6c7422e85dbcd5a20475fd0c5d38d3c6. 2022-10-13 19:46:39 -05:00
Zebediah Figura
ca3220cbd6 Rebase against f87ad783e23a2b6f5e9b8cf78dbf99bad4471a25. 2022-10-13 16:00:57 -05:00
Alistair Leslie-Hughes
ff6cef5d72 Rebase against f87ad783e23a2b6f5e9b8cf78dbf99bad4471a25. 2022-10-13 08:52:08 +11:00
Alistair Leslie-Hughes
d2b7b686f1 Fix Rebase 2022-10-12 13:52:20 +11:00
Alistair Leslie-Hughes
c5c29f9395 Rebase against 4312be1646cad32548f855e25823857092bf31dc. 2022-10-12 11:27:25 +11:00
Zebediah Figura
08ad410761 secur32-InitializeSecurityContext: Remove patch set.
Fixed upstream by c1993458ac.
2022-10-10 22:28:33 -05:00
Zebediah Figura
e6f9a449cd Rebase against 16c6c249a5134de2422fbd3471ead7425c968301. 2022-10-10 22:27:34 -05:00
Alistair Leslie-Hughes
0ea57a0262 Updated wined3d-bindless-texture patchset 2022-09-30 09:31:13 +10:00
Alistair Leslie-Hughes
4f75966580 Updated ntdll-DOS_Attributes patchset
Fixes: https://bugs.winehq.org/show_bug.cgi?id=53715
2022-09-30 09:31:13 +10:00
Zebediah Figura
9f9285256f mfplat-streaming-support: Remove patch 0067.
Upstreamed as 2d7c37da495c.
2022-09-29 16:04:31 -05:00
Alistair Leslie-Hughes
21009111bd Rebase against 2a4ec7dafc7ee38108f6a9f626a7c39e6b6777e0. 2022-09-27 10:29:23 +10:00
50 changed files with 626 additions and 2392 deletions

View File

@@ -1,37 +0,0 @@
From 30e5e0e405af8f99885727687dbcdfbda3e57f08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 18 Jan 2022 13:33:36 +0100
Subject: [PATCH 67/88] winegstreamer: Return S_OK from H264 decoder
GetAttributes.
For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2,
Yakuza 4 Remastered, Hard Reset Redux.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
CW-Bug-Id: #16839
CW-Bug-Id: #18678
CW-Bug-Id: #19362
---
dlls/winegstreamer/h264_decoder.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 5db72c55151..f46d6d77f8e 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -120,7 +120,8 @@ static HRESULT WINAPI h264_decoder_GetOutputStreamInfo(IMFTransform *iface, DWOR
static HRESULT WINAPI h264_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
{
FIXME("iface %p, attributes %p stub!\n", iface, attributes);
- return E_NOTIMPL;
+
+ return MFCreateAttributes(attributes, 0);
}
static HRESULT WINAPI h264_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
--
2.34.1

View File

@@ -1,4 +1,4 @@
From 217794090443a96e712ffe3970e4a70ded2277dc Mon Sep 17 00:00:00 2001
From 27019592a4f4aa7134f605093b5d83fe3764dcf5 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:39:37 +0200
Subject: [PATCH] ntdll: Use fast CS functions for threadpool locking.
@@ -8,19 +8,19 @@ Subject: [PATCH] ntdll: Use fast CS functions for threadpool locking.
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index ca323919d05..581d503b6a4 100644
index 421d1ade133..71771dd2987 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1053,7 +1053,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1063,7 +1063,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
TRACE( "starting timer queue thread\n" );
set_thread_name(L"wine_threadpool_timerqueue");
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
for (;;)
{
NtQuerySystemTime( &now );
@@ -1126,7 +1126,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1136,7 +1136,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
}
timerqueue.thread_running = FALSE;
@@ -29,7 +29,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating timer queue thread\n" );
RtlExitUserThread( 0 );
@@ -1171,7 +1171,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
@@ -1181,7 +1181,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timer->u.timer.period = 0;
timer->u.timer.window_length = 0;
@@ -38,7 +38,7 @@ index ca323919d05..581d503b6a4 100644
/* Make sure that the timerqueue thread is running. */
if (!timerqueue.thread_running)
@@ -1192,7 +1192,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
@@ -1202,7 +1202,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timerqueue.objcount++;
}
@@ -47,7 +47,7 @@ index ca323919d05..581d503b6a4 100644
return status;
}
@@ -1205,7 +1205,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
@@ -1215,7 +1215,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
{
assert( timer->type == TP_OBJECT_TYPE_TIMER );
@@ -56,7 +56,7 @@ index ca323919d05..581d503b6a4 100644
if (timer->u.timer.timer_initialized)
{
/* If timer was pending, remove it. */
@@ -1224,7 +1224,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
@@ -1234,7 +1234,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
timer->u.timer.timer_initialized = FALSE;
}
@@ -65,16 +65,16 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -1242,7 +1242,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1253,7 +1253,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
TRACE( "starting wait queue thread\n" );
set_thread_name(L"wine_threadpool_waitqueue");
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
for (;;)
{
@@ -1291,10 +1291,10 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1302,10 +1302,10 @@ static void CALLBACK waitqueue_thread_proc( void *param )
/* All wait objects have been destroyed, if no new wait objects are created
* within some amount of time, then we can shutdown this thread. */
assert( num_handles == 0 );
@@ -87,7 +87,7 @@ index ca323919d05..581d503b6a4 100644
if (status == STATUS_TIMEOUT && !bucket->objcount)
break;
@@ -1304,7 +1304,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1315,7 +1315,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
handles[num_handles] = bucket->update_event;
RtlLeaveCriticalSection( &waitqueue.cs );
status = NtWaitForMultipleObjects( num_handles + 1, handles, TRUE, bucket->alertable, &timeout );
@@ -96,7 +96,7 @@ index ca323919d05..581d503b6a4 100644
if (status >= STATUS_WAIT_0 && status < STATUS_WAIT_0 + num_handles)
{
@@ -1388,7 +1388,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1399,7 +1399,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
if (!--waitqueue.num_buckets)
assert( list_empty( &waitqueue.buckets ) );
@@ -105,7 +105,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating wait queue thread\n" );
@@ -1418,7 +1418,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
@@ -1429,7 +1429,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
wait->u.wait.timeout = 0;
wait->u.wait.handle = INVALID_HANDLE_VALUE;
@@ -114,7 +114,7 @@ index ca323919d05..581d503b6a4 100644
/* Try to assign to existing bucket if possible. */
LIST_FOR_EACH_ENTRY( bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry )
@@ -1475,7 +1475,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
@@ -1486,7 +1486,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
}
out:
@@ -123,7 +123,7 @@ index ca323919d05..581d503b6a4 100644
return status;
}
@@ -1486,7 +1486,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
@@ -1497,7 +1497,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
{
assert( wait->type == TP_OBJECT_TYPE_WAIT );
@@ -132,7 +132,7 @@ index ca323919d05..581d503b6a4 100644
if (wait->u.wait.bucket)
{
struct waitqueue_bucket *bucket = wait->u.wait.bucket;
@@ -1498,7 +1498,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
@@ -1509,7 +1509,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
NtSetEvent( bucket->update_event, NULL );
}
@@ -141,7 +141,7 @@ index ca323919d05..581d503b6a4 100644
}
static void CALLBACK ioqueue_thread_proc( void *param )
@@ -1775,7 +1775,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1787,7 +1787,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool = default_threadpool;
}
@@ -150,7 +150,7 @@ index ca323919d05..581d503b6a4 100644
/* Make sure that the threadpool has at least one thread. */
if (!pool->num_workers)
@@ -1789,7 +1789,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1801,7 +1801,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool->objcount++;
}
@@ -159,7 +159,7 @@ index ca323919d05..581d503b6a4 100644
if (status != STATUS_SUCCESS)
return status;
@@ -1805,9 +1805,9 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1817,9 +1817,9 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
*/
static void tp_threadpool_unlock( struct threadpool *pool )
{
@@ -171,7 +171,7 @@ index ca323919d05..581d503b6a4 100644
tp_threadpool_release( pool );
}
@@ -1945,10 +1945,10 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1957,10 +1957,10 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
struct threadpool_group *group = object->group;
InterlockedIncrement( &group->refcount );
@@ -184,7 +184,7 @@ index ca323919d05..581d503b6a4 100644
}
if (is_simple_callback)
@@ -1975,7 +1975,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
@@ -1987,7 +1987,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
assert( !object->shutdown );
assert( !pool->shutdown );
@@ -193,7 +193,7 @@ index ca323919d05..581d503b6a4 100644
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers &&
@@ -1998,7 +1998,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
@@ -2010,7 +2010,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
RtlWakeConditionVariable( &pool->update_event );
}
@@ -202,7 +202,7 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -2011,7 +2011,7 @@ static void tp_object_cancel( struct threadpool_object *object )
@@ -2023,7 +2023,7 @@ static void tp_object_cancel( struct threadpool_object *object )
struct threadpool *pool = object->pool;
LONG pending_callbacks = 0;
@@ -211,7 +211,7 @@ index ca323919d05..581d503b6a4 100644
if (object->num_pending_callbacks)
{
pending_callbacks = object->num_pending_callbacks;
@@ -2026,7 +2026,7 @@ static void tp_object_cancel( struct threadpool_object *object )
@@ -2038,7 +2038,7 @@ static void tp_object_cancel( struct threadpool_object *object )
object->u.io.skipped_count += object->u.io.pending_count;
object->u.io.pending_count = 0;
}
@@ -220,7 +220,7 @@ index ca323919d05..581d503b6a4 100644
while (pending_callbacks--)
tp_object_release( object );
@@ -2055,7 +2055,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
@@ -2067,7 +2067,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
{
struct threadpool *pool = object->pool;
@@ -229,7 +229,7 @@ index ca323919d05..581d503b6a4 100644
while (!object_is_finished( object, group_wait ))
{
if (group_wait)
@@ -2063,7 +2063,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
@@ -2075,7 +2075,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
else
RtlSleepConditionVariableCS( &object->finished_event, &pool->cs, NULL );
}
@@ -238,7 +238,7 @@ index ca323919d05..581d503b6a4 100644
}
static void tp_ioqueue_unlock( struct threadpool_object *io )
@@ -2117,13 +2117,13 @@ static BOOL tp_object_release( struct threadpool_object *object )
@@ -2129,13 +2129,13 @@ static BOOL tp_object_release( struct threadpool_object *object )
{
struct threadpool_group *group = object->group;
@@ -254,16 +254,16 @@ index ca323919d05..581d503b6a4 100644
tp_group_release( group );
}
@@ -2324,7 +2324,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -2337,7 +2337,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "starting worker thread for pool %p\n", pool );
set_thread_name(L"wine_threadpool_worker");
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
for (;;)
{
while ((ptr = threadpool_get_next_item( pool )))
@@ -2364,7 +2364,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -2377,7 +2377,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
}
}
pool->num_workers--;
@@ -272,7 +272,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating worker thread for pool %p\n", pool );
tp_threadpool_release( pool );
@@ -2612,7 +2612,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -2625,7 +2625,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
return STATUS_SUCCESS;
pool = object->pool;
@@ -281,7 +281,7 @@ index ca323919d05..581d503b6a4 100644
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers)
@@ -2627,7 +2627,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -2640,7 +2640,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
}
}
@@ -290,7 +290,7 @@ index ca323919d05..581d503b6a4 100644
this->may_run_long = TRUE;
return status;
}
@@ -2708,13 +2708,13 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
@@ -2721,13 +2721,13 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
return;
pool = object->pool;
@@ -306,7 +306,7 @@ index ca323919d05..581d503b6a4 100644
this->associated = FALSE;
}
@@ -2766,7 +2766,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
@@ -2779,7 +2779,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
TRACE( "%p %u %p\n", group, cancel_pending, userdata );
@@ -315,7 +315,7 @@ index ca323919d05..581d503b6a4 100644
/* Unset group, increase references, and mark objects for shutdown */
LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry )
@@ -2792,7 +2792,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
@@ -2805,7 +2805,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
list_init( &members );
list_move_tail( &members, &this->members );
@@ -324,7 +324,7 @@ index ca323919d05..581d503b6a4 100644
/* Cancel pending callbacks if requested */
if (cancel_pending)
@@ -2915,10 +2915,10 @@ VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
@@ -2928,10 +2928,10 @@ VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
TRACE( "%p %u\n", pool, maximum );
@@ -337,7 +337,7 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -2931,7 +2931,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
@@ -2944,7 +2944,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
TRACE( "%p %u\n", pool, minimum );
@@ -346,7 +346,7 @@ index ca323919d05..581d503b6a4 100644
while (this->num_workers < minimum)
{
@@ -2946,7 +2946,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
@@ -2959,7 +2959,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
this->max_workers = max( this->min_workers, this->max_workers );
}
@@ -355,7 +355,7 @@ index ca323919d05..581d503b6a4 100644
return !status;
}
@@ -2962,7 +2962,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
@@ -2975,7 +2975,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
TRACE( "%p %p %u %u\n", timer, timeout, period, window_length );
@@ -364,7 +364,7 @@ index ca323919d05..581d503b6a4 100644
assert( this->u.timer.timer_initialized );
this->u.timer.timer_set = timeout != NULL;
@@ -3022,7 +3022,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
@@ -3035,7 +3035,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
this->u.timer.timer_pending = TRUE;
}
@@ -373,7 +373,7 @@ index ca323919d05..581d503b6a4 100644
if (submit_timer)
tp_object_submit( this, FALSE );
@@ -3038,7 +3038,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
@@ -3051,7 +3051,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
TRACE( "%p %p %p\n", wait, handle, timeout );
@@ -382,7 +382,7 @@ index ca323919d05..581d503b6a4 100644
assert( this->u.wait.bucket );
this->u.wait.handle = handle;
@@ -3077,7 +3077,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
@@ -3090,7 +3090,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
NtSetEvent( bucket->update_event, NULL );
}
@@ -392,5 +392,5 @@ index ca323919d05..581d503b6a4 100644
/***********************************************************************
--
2.30.2
2.37.2

View File

@@ -1,122 +0,0 @@
From 80cb1bf9077b1e754fc2f3426229733c3417c397 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 22:10:49 -0600
Subject: [PATCH] ntdll: Implement retrieving DOS attributes in
[fd_]get_file_info().
---
configure.ac | 12 ++++++++++++
dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index c68c5975e63..84efc670ca4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,7 @@ AC_ARG_WITH(unwind, AS_HELP_STRING([--without-unwind],[do not use the libunwi
AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb library]))
AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)]))
AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan]))
+AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -634,6 +635,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/queue.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1])
+fi
+if test "x$with_xattr" = "xyes"
+then
+ WINE_ERROR_WITH(xattr,[test "x$HAVE_XATTR" = "x"],[xattr ${notice_platform}development files \
+not found. Wine will be built without extended attribute support, which probably isn't what you \
+want. You will need to install ${notice_platform}development packages of libattr at the very least.])
+fi
+
dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"")
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index a29b5cbb980..1ae4645c6fb 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -98,6 +98,9 @@
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include <time.h>
#include <unistd.h>
@@ -355,6 +358,20 @@ NTSTATUS errno_to_status( int err )
}
}
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+
+static int xattr_get( const char *path, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return getxattr( path, name, value, size );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
/* get space from the current directory data buffer, allocating a new one if necessary */
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
{
@@ -1436,6 +1453,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name,
}
+/* Match the Samba conventions for storing DOS file attributes */
+#define SAMBA_XATTR_DOS_ATTRIB XATTR_USER_PREFIX "DOSATTRIB"
+/* We are only interested in some attributes, the others have corresponding Unix attributes */
+#define XATTR_ATTRIBS_MASK (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)
+
+/* decode the xattr-stored DOS attributes */
+static inline int get_file_xattr( char *hexattr, int attrlen )
+{
+ if (attrlen > 2 && hexattr[0] == '0' && hexattr[1] == 'x')
+ {
+ hexattr[attrlen] = 0;
+ return strtol( hexattr+2, NULL, 16 ) & XATTR_ATTRIBS_MASK;
+ }
+ return 0;
+}
+
/* fetch the attributes of a file */
static inline ULONG get_file_attributes( const struct stat *st )
{
@@ -1479,7 +1512,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
char *parent_path;
- int ret;
+ char hexattr[11];
+ int len, ret;
*attr = 0;
ret = lstat( path, st );
@@ -1505,6 +1539,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
free( parent_path );
}
*attr |= get_file_attributes( st );
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *attr |= get_file_xattr( hexattr, len );
return ret;
}
--
2.34.1

View File

@@ -1,160 +0,0 @@
From 49f8ae15c8065c9133e0c08eaba68049cdb85e0b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 00:08:52 -0600
Subject: [PATCH] ntdll: Implement storing DOS attributes in
NtSetInformationFile.
---
dlls/ntdll/tests/file.c | 8 ++---
dlls/ntdll/unix/file.c | 74 ++++++++++++++++++++++++++++++-----------
2 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 4014b395b56..ad718fab828 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1401,7 +1401,7 @@ static void test_file_basic_information(void)
memset(&fbi, 0, sizeof(fbi));
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi.FileAttributes );
/* Then HIDDEN */
memset(&fbi, 0, sizeof(fbi));
@@ -1414,7 +1414,7 @@ static void test_file_basic_information(void)
memset(&fbi, 0, sizeof(fbi));
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi.FileAttributes );
/* Check NORMAL last of all (to make sure we can clear attributes) */
memset(&fbi, 0, sizeof(fbi));
@@ -1471,7 +1471,7 @@ static void test_file_all_information(void)
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
- todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
/* Then HIDDEN */
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
@@ -1484,7 +1484,7 @@ static void test_file_all_information(void)
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
/* Check NORMAL last of all (to make sure we can clear attributes) */
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index a3520898d57..cd53ca36238 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -362,6 +362,26 @@ NTSTATUS errno_to_status( int err )
#define XATTR_USER_PREFIX "user."
#endif
+static int xattr_fremove( int filedes, const char *name )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return fremovexattr( filedes, name );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int xattr_fset( int filedes, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0 );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
static int xattr_get( const char *path, const char *name, void *value, size_t size )
{
#if defined(HAVE_ATTR_XATTR_H)
@@ -1508,6 +1528,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
}
+/* set the stat info and file attributes for a file (by file descriptor) */
+NTSTATUS fd_set_file_info( int fd, ULONG attr )
+{
+ char hexattr[11];
+ struct stat st;
+
+ if (fstat( fd, &st ) == -1) return errno_to_status( errno );
+ if (attr & FILE_ATTRIBUTE_READONLY)
+ {
+ if (S_ISDIR( st.st_mode))
+ WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
+ else
+ st.st_mode &= ~0222; /* clear write permission bits */
+ }
+ else
+ {
+ /* add write permission only where we already have read permission */
+ st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~start_umask);
+ }
+ if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno );
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ if (attr != 0)
+ {
+ int len;
+
+ len = sprintf( hexattr, "0x%x", attr );
+ xattr_fset( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
+ }
+ else
+ xattr_fremove( fd, SAMBA_XATTR_DOS_ATTRIB );
+ return STATUS_SUCCESS;
+}
+
/* get the stat info and file attributes for a file (by name) */
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
@@ -4359,7 +4412,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileBasicInformation:
if (len >= sizeof(FILE_BASIC_INFORMATION))
{
- struct stat st;
const FILE_BASIC_INFORMATION *info = ptr;
LARGE_INTEGER mtime, atime;
@@ -4373,25 +4425,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
status = set_file_times( fd, &mtime, &atime );
if (status == STATUS_SUCCESS && info->FileAttributes)
- {
- if (fstat( fd, &st ) == -1) status = errno_to_status( errno );
- else
- {
- if (info->FileAttributes & FILE_ATTRIBUTE_READONLY)
- {
- if (S_ISDIR( st.st_mode))
- WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
- else
- st.st_mode &= ~0222; /* clear write permission bits */
- }
- else
- {
- /* add write permission only where we already have read permission */
- st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~start_umask);
- }
- if (fchmod( fd, st.st_mode ) == -1) status = errno_to_status( errno );
- }
- }
+ status = fd_set_file_info( fd, info->FileAttributes );
if (needs_close) close( fd );
}
--
2.35.1

View File

@@ -1,154 +0,0 @@
From 2f6ec5b1accc1ac275bcb4edeb44c15e271d2f72 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 15:28:00 -0600
Subject: [PATCH] ntdll: Implement storing DOS attributes in NtCreateFile.
---
dlls/ntdll/tests/directory.c | 24 ++++++++---------
dlls/ntdll/unix/file.c | 51 ++++++++++++++++++++++++++++++++----
2 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index 77b17a50037..07211ebf5de 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -56,7 +56,6 @@ static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *
/* The attribute sets to test */
static struct testfile_s {
- BOOL todo; /* set if it doesn't work on wine yet */
BOOL attr_done; /* set if attributes were tested for this file already */
const DWORD attr; /* desired attribute */
WCHAR name[20]; /* filename to use */
@@ -64,16 +63,16 @@ static struct testfile_s {
const char *description; /* for error messages */
int nfound; /* How many were found (expect 1) */
} testfiles[] = {
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'l','o','n','g','f','i','l','e','n','a','m','e','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'n','.','t','m','p',}, "normal" },
- { 1, 0, FILE_ATTRIBUTE_HIDDEN, {'h','.','t','m','p',}, "hidden" },
- { 1, 0, FILE_ATTRIBUTE_SYSTEM, {'s','.','t','m','p',}, "system" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'d','.','t','m','p',}, "directory" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
+ { 0, FILE_ATTRIBUTE_NORMAL, {'l','o','n','g','f','i','l','e','n','a','m','e','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {'n','.','t','m','p',}, "normal" },
+ { 0, FILE_ATTRIBUTE_HIDDEN, {'h','.','t','m','p',}, "hidden" },
+ { 0, FILE_ATTRIBUTE_SYSTEM, {'s','.','t','m','p',}, "system" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'d','.','t','m','p',}, "directory" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
};
static const int test_dir_count = ARRAY_SIZE(testfiles);
static const int max_test_dir_size = ARRAY_SIZE(testfiles) + 5; /* size of above plus some for .. etc */
@@ -163,8 +162,7 @@ static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
if (namelen != len || memcmp(nameW, testfiles[i].name, len*sizeof(WCHAR)))
continue;
if (!testfiles[i].attr_done) {
- todo_wine_if (testfiles[i].todo)
- ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
+ ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
testfiles[i].attr_done = TRUE;
}
testfiles[i].nfound++;
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index cd53ca36238..185db877d55 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -392,6 +392,26 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
#endif
}
+static int xattr_remove( const char *path, const char *name )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return removexattr( path, name );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int xattr_set( const char *path, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return setxattr( path, name, value, size, 0 );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
/* get space from the current directory data buffer, allocating a new one if necessary */
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
{
@@ -3786,6 +3806,20 @@ static NTSTATUS unmount_device( HANDLE handle )
return status;
}
+NTSTATUS set_file_info( const char *path, ULONG attr )
+{
+ char hexattr[11];
+ int len;
+
+ /* Note: unix mode already set when called this way */
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ len = sprintf( hexattr, "0x%x", attr );
+ if (attr != 0)
+ xattr_set( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
+ else
+ xattr_remove( path, SAMBA_XATTR_DOS_ATTRIB );
+ return STATUS_SUCCESS;
+}
/******************************************************************************
* open_unix_file
@@ -3871,13 +3905,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
status = STATUS_SUCCESS;
}
- if (status == STATUS_SUCCESS)
+ if (status != STATUS_SUCCESS)
{
- status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
- sharing, disposition, options, ea_buffer, ea_length );
- free( unix_name );
+ WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );
+ return status;
}
- else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
+
+ status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
+ sharing, disposition, options, ea_buffer, ea_length );
if (status == STATUS_SUCCESS)
{
@@ -3899,6 +3934,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
io->Information = FILE_OVERWRITTEN;
break;
}
+ if (io->Information == FILE_CREATED)
+ {
+ /* set any DOS extended attributes */
+ set_file_info( unix_name, attributes );
+ }
}
else if (status == STATUS_TOO_MANY_OPENED_FILES)
{
@@ -3907,6 +3947,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
}
free( nt_name.Buffer );
+ free( unix_name );
return io->u.Status = status;
}
--
2.35.1

View File

@@ -1,18 +1,18 @@
From a2e3bc27382f9c0c4894c6e0ab121f075e82db3e Mon Sep 17 00:00:00 2001
From 95b71a04c7d437e25aac1a1d327beba6ebfaf608 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 11:26:48 -0600
Subject: [PATCH] ntdll: Perform the Unix-style hidden file check within the
unified file info grabbing routine.
---
dlls/ntdll/unix/file.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
dlls/ntdll/unix/file.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 73d4cce90ae..b790cde3f90 100644
index 9594c70c016..31579caf03b 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -1328,15 +1328,15 @@ static BOOLEAN get_dir_case_sensitivity( const char *dir )
@@ -1311,16 +1311,16 @@ static BOOLEAN get_dir_case_sensitivity( const char *dir )
*
* Check if the specified file should be hidden based on its name and the show dot files option.
*/
@@ -27,13 +27,15 @@ index 73d4cce90ae..b790cde3f90 100644
- end = p = name->Buffer + name->Length/sizeof(WCHAR);
- while (p > name->Buffer && p[-1] == '\\') p--;
- while (p > name->Buffer && p[-1] != '\\') p--;
- return (p < end && *p == '.');
+ end = p = name + strlen( name );
+ while (p > name && p[-1] == '\\') p--;
+ while (p > name && p[-1] != '\\') p--;
return (p < end && *p == '.');
+ while (p > name && p[-1] == '/') p--;
+ while (p > name && p[-1] != '/') p--;
+ return (p < end && p[0] == '.' && p[1] && (p[1] != '.' || p[2]));
}
@@ -1679,6 +1679,10 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
@@ -1662,6 +1662,10 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
free( parent_path );
}
*attr |= get_file_attributes( st );
@@ -44,7 +46,7 @@ index 73d4cce90ae..b790cde3f90 100644
len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
if (len == -1) return ret;
*attr |= get_file_xattr( hexattr, len );
@@ -2186,11 +2190,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I
@@ -2228,11 +2232,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I
if (class != FileNamesInformation)
{
if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */
@@ -56,7 +58,7 @@ index 73d4cce90ae..b790cde3f90 100644
fill_file_info( &st, attributes, info, class );
}
@@ -4106,7 +4105,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
@@ -4196,7 +4195,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
info->AllocationSize = std.AllocationSize;
info->EndOfFile = std.EndOfFile;
info->FileAttributes = basic.FileAttributes;
@@ -64,7 +66,7 @@ index 73d4cce90ae..b790cde3f90 100644
}
free( unix_name );
}
@@ -4133,10 +4131,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
@@ -4227,10 +4225,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
else
@@ -76,5 +78,5 @@ index 73d4cce90ae..b790cde3f90 100644
}
else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
--
2.30.2
2.37.2

View File

@@ -1,2 +1,4 @@
Fixes: [9158] Support for DOS hidden/system file attributes
Fixes: [15679] cygwin symlinks not working in wine
# Hopefully in the process of upstreaming.
Disabled: true

View File

@@ -1,24 +1,24 @@
From 6209b270e6f2a7913a95f6c1da18c11e2e2a73a5 Mon Sep 17 00:00:00 2001
From 8919be537a3ada49b59f2686cc14dbfb81a37cb1 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:56:49 -0700
Subject: [PATCH] ntdll: Add support for creating reparse points.
Subject: ntdll: Add support for creating reparse points.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
configure.ac | 2 +
dlls/ntdll/Makefile.in | 2 +-
dlls/ntdll/tests/file.c | 152 ++++++++++++++++++++
dlls/ntdll/unix/file.c | 300 ++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/file.c | 302 ++++++++++++++++++++++++++++++++++++++++
include/Makefile.in | 1 +
include/ntifs.h | 42 ++++++
6 files changed, 498 insertions(+), 1 deletion(-)
6 files changed, 500 insertions(+), 1 deletion(-)
create mode 100644 include/ntifs.h
diff --git a/configure.ac b/configure.ac
index 3ea4c2afe0a..d0ec1d837c3 100644
index e11f3cfdb63..113d126a002 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2030,6 +2030,8 @@ AC_CHECK_FUNCS(\
@@ -2018,6 +2018,8 @@ AC_CHECK_FUNCS(\
prctl \
proc_pidinfo \
sched_yield \
@@ -41,7 +41,7 @@ index 3b1cdb54f9f..6eb4690f8e0 100644
EXTRADLLFLAGS = -nodefaultlibs -Wl,--image-base,0x7bc00000
x86_64_EXTRADLLFLAGS = -nodefaultlibs -Wl,--image-base,0x170000000
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 4b142f241e5..5f6cb223951 100644
index c011733626f..93e50bd6952 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -38,6 +38,7 @@
@@ -217,19 +217,19 @@ index 4b142f241e5..5f6cb223951 100644
test_mailslot_name();
}
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index d103e3195b5..3fb4ded846c 100644
index 604ca866890..f3d831b0a33 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -35,6 +35,8 @@
#include <string.h>
@@ -36,6 +36,8 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
+#include <math.h>
+#include <libgen.h>
#include <limits.h>
#include <unistd.h>
#ifdef HAVE_MNTENT_H
@@ -127,6 +129,7 @@
@@ -121,6 +123,7 @@
#include "wine/list.h"
#include "wine/debug.h"
#include "unix_private.h"
@@ -237,7 +237,7 @@ index d103e3195b5..3fb4ded846c 100644
WINE_DEFAULT_DEBUG_CHANNEL(file);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
@@ -138,6 +141,12 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
@@ -132,6 +135,12 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
#undef EXT2_IOC_GETFLAGS
#undef EXT4_CASEFOLD_FL
@@ -250,7 +250,7 @@ index d103e3195b5..3fb4ded846c 100644
#ifdef linux
/* We want the real kernel dirent structure, not the libc one */
@@ -239,6 +248,95 @@ static const BOOL is_case_sensitive = FALSE;
@@ -236,6 +245,95 @@ static const BOOL is_case_sensitive = FALSE;
static pthread_mutex_t dir_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mnt_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -325,7 +325,7 @@ index d103e3195b5..3fb4ded846c 100644
+}
+
+/* create a directory and all the needed parent directories */
+static int mkdir_p(const char *path, mode_t mode)
+static int mkdir_p( int dirfd, const char *path, mode_t mode )
+{
+ char path_tmp[PATH_MAX], *p;
+
@@ -333,12 +333,12 @@ index d103e3195b5..3fb4ded846c 100644
+ for (p = path_tmp + 1; *p; p++) {
+ if (*p == '/') {
+ *p = '\0';
+ if (mkdir(path_tmp, mode) != 0 && errno != EEXIST)
+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST)
+ return -1;
+ *p = '/';
+ }
+ }
+ if (mkdir(path_tmp, mode) != 0 && errno != EEXIST)
+ if (mkdirat( dirfd, path_tmp, mode ) != 0 && errno != EEXIST)
+ return -1;
+ return 0;
+}
@@ -346,7 +346,7 @@ index d103e3195b5..3fb4ded846c 100644
/* check if a given Unicode char is OK in a DOS short name */
static inline BOOL is_invalid_dos_char( WCHAR ch )
{
@@ -1574,6 +1672,28 @@ static inline ULONG get_file_attributes( const struct stat *st )
@@ -1540,6 +1638,28 @@ static int parse_samba_dos_attrib_data( char *data, int len )
}
@@ -375,7 +375,7 @@ index d103e3195b5..3fb4ded846c 100644
static BOOL fd_is_mount_point( int fd, const struct stat *st )
{
struct stat parent;
@@ -3313,6 +3433,179 @@ done:
@@ -3303,6 +3423,181 @@ done:
}
@@ -386,13 +386,14 @@ index d103e3195b5..3fb4ded846c 100644
+NTSTATUS create_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
+{
+ int buffer_len = buffer->ReparseDataLength+FIELD_OFFSET(typeof(*buffer), GenericReparseBuffer);
+ char target_path[PATH_MAX], link_path[PATH_MAX], link_dir[PATH_MAX], original_dir[PATH_MAX];
+ char target_path[PATH_MAX], link_path[PATH_MAX], link_dir[PATH_MAX];
+ int encoded_len = (int)ceil(buffer_len*4/3.0) + 1, chunk_len;
+ char tmpdir[PATH_MAX], tmplink[PATH_MAX], *d;
+ BOOL needs_close, tempdir_created = FALSE;
+ char filename_buf[PATH_MAX], *filename;
+ char *unix_src = NULL, *encoded = NULL;
+ int i = 0, j = 0, depth = 0, fd;
+ int link_dir_fd = -1;
+ NTSTATUS status;
+ struct stat st;
+ BOOL is_dir;
@@ -469,14 +470,15 @@ index d103e3195b5..3fb4ded846c 100644
+ }
+
+ /* change to the link folder so that we can build any necessary additional data */
+ getcwd( original_dir, PATH_MAX );
+ strcpy( link_dir, tmpdir );
+ link_dir[strlen(link_dir)-16] = 0;
+ chdir( link_dir );
+ link_dir_fd = open( link_dir, O_RDONLY|O_DIRECTORY );
+
+ /* If there is any further information in the reparse tag then store it in the hidden folder */
+ while(i < encoded_len)
+ {
+ int fd;
+
+ j++;
+ strcpy( link_path, target_path );
+
@@ -495,22 +497,21 @@ index d103e3195b5..3fb4ded846c 100644
+
+ strcpy( link_dir, link_path );
+ link_dir[strlen(link_dir)-1] = 0;
+ if (mkdir_p( link_dir, 0777))
+ if (mkdir_p( link_dir_fd, link_dir, 0777))
+ {
+ status = errno_to_status( errno );
+ goto cleanup;
+ }
+ if (symlink( target_path, link_path ))
+ if (symlinkat( target_path, link_dir_fd, link_path ))
+ {
+ status = errno_to_status( errno );
+ goto cleanup;
+ }
+ chdir( link_dir );
+ fd = openat( link_dir_fd, link_dir, O_RDONLY|O_DIRECTORY );
+ close( link_dir_fd );
+ link_dir_fd = fd;
+ }
+
+ /* revert to the original directory */
+ chdir( original_dir );
+
+ /* Atomically move the initial link into position */
+ if (!renameat2( -1, tmplink, -1, unix_src, RENAME_EXCHANGE ))
+ {
@@ -543,6 +544,7 @@ index d103e3195b5..3fb4ded846c 100644
+ status = STATUS_SUCCESS;
+
+cleanup:
+ if (link_dir_fd != -1) close( link_dir_fd );
+ if (tempdir_created) rmdir( tmpdir );
+ if (needs_close) close( fd );
+ free( unix_src );
@@ -555,7 +557,7 @@ index d103e3195b5..3fb4ded846c 100644
/******************************************************************************
* lookup_unix_name
*
@@ -6060,6 +6353,13 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
@@ -6052,6 +6347,13 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
break;
}
@@ -570,7 +572,7 @@ index d103e3195b5..3fb4ded846c 100644
TRACE("FSCTL_SET_SPARSE: Ignoring request\n");
io->Information = 0;
diff --git a/include/Makefile.in b/include/Makefile.in
index 70134a7bcb7..bdddf5426fe 100644
index 1c04f9a298b..7a2c9f96c1b 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -563,6 +563,7 @@ SOURCES = \
@@ -630,5 +632,5 @@ index 00000000000..21d42e17325
+
+#endif /* __WINE_NTIFS_H */
--
2.35.1
2.17.1

View File

@@ -1,16 +1,16 @@
From ded223a1f564442c26860d9e708b963710ecea21 Mon Sep 17 00:00:00 2001
From 51f1d4cee59b11181bbf1432ef7c954020269cf3 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:57:57 -0700
Subject: [PATCH] ntdll: Add support for reading reparse points.
Subject: ntdll: Add support for reading reparse points.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/ntdll/tests/file.c | 21 +++-
dlls/ntdll/unix/file.c | 209 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 228 insertions(+), 2 deletions(-)
dlls/ntdll/unix/file.c | 212 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 231 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 5f6cb223951..33e49793319 100644
index 93e50bd6952..805f5a6a940 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5359,14 +5359,14 @@ static void test_reparse_points(void)
@@ -55,10 +55,10 @@ index 5f6cb223951..33e49793319 100644
cleanup:
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 3fb4ded846c..3a1489c35d0 100644
index f3d831b0a33..8fe543ded08 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -318,6 +318,84 @@ static UINT encode_base64url( const char *bin, unsigned int len, char *base64 )
@@ -315,6 +315,84 @@ static UINT encode_base64url( const char *bin, unsigned int len, char *base64 )
return n;
}
@@ -141,9 +141,9 @@ index 3fb4ded846c..3a1489c35d0 100644
+}
+
/* create a directory and all the needed parent directories */
static int mkdir_p(const char *path, mode_t mode)
static int mkdir_p( int dirfd, const char *path, mode_t mode )
{
@@ -3606,6 +3684,129 @@ cleanup:
@@ -3598,6 +3676,132 @@ cleanup:
}
@@ -153,21 +153,22 @@ index 3fb4ded846c..3a1489c35d0 100644
+ */
+NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *size)
+{
+ char link_dir[PATH_MAX], original_dir[PATH_MAX], *d;
+ char link_dir[PATH_MAX], link_path[PATH_MAX], *d;
+ int link_path_len, buffer_len, encoded_len;
+ char *unix_src, link_path[PATH_MAX];
+ REPARSE_DATA_BUFFER header;
+ ULONG out_size = *size;
+ char *unix_name = NULL;
+ char *encoded = NULL;
+ int link_dir_fd = -1;
+ NTSTATUS status;
+ ssize_t ret;
+ int depth;
+ char *p;
+
+ if ((status = server_get_unix_name( handle, &unix_src )))
+ if ((status = server_get_unix_name( handle, &unix_name )))
+ goto cleanup;
+
+ ret = readlink( unix_src, link_path, sizeof(link_path) );
+ ret = readlink( unix_name, link_path, sizeof(link_path) );
+ if (ret < 0)
+ {
+ status = errno_to_status( errno );
@@ -175,7 +176,7 @@ index 3fb4ded846c..3a1489c35d0 100644
+ }
+ link_path_len = ret;
+ link_path[link_path_len] = 0;
+ if (strncmp( link_path, ".REPARSE_POINT/", 15) != 0)
+ if (strncmp( link_path, ".REPARSE_POINT/", 15 ) != 0)
+ {
+ status = STATUS_NOT_IMPLEMENTED;
+ goto cleanup;
@@ -214,8 +215,8 @@ index 3fb4ded846c..3a1489c35d0 100644
+ status = STATUS_BUFFER_TOO_SMALL;
+ goto cleanup;
+ }
+ encoded_len = (int)ceil(buffer_len*4/3.0) + 1;
+ encoded = realloc( encoded, encoded_len );
+ encoded_len = (int)ceil(buffer_len*4/3.0);
+ encoded = realloc( encoded, encoded_len + 3 ); /* 3 chars = slash, chunk ID, NUL character */
+ if (!encoded)
+ {
+ status = STATUS_NO_MEMORY;
@@ -223,24 +224,25 @@ index 3fb4ded846c..3a1489c35d0 100644
+ }
+
+ /* change to the link folder so that we can build any necessary additional data */
+ getcwd( original_dir, PATH_MAX );
+ strcpy( link_dir, unix_src );
+ strcpy( link_dir, unix_name );
+ d = dirname( link_dir);
+ if (d != link_dir) strcpy( link_dir, d );
+ chdir( link_dir );
+ link_dir_fd = open( link_dir, O_RDONLY|O_DIRECTORY );
+
+ /* Copy the encoded data from the follow on symlinks */
+ while(strlen(encoded) < encoded_len-1)
+ while(strlen(encoded) < encoded_len)
+ {
+ int fd;
+
+ strcpy( link_dir, link_path );
+ ret = readlink( link_dir, link_path, sizeof(link_path) );
+ ret = readlinkat( link_dir_fd, link_dir, link_path, sizeof(link_path) );
+ if (ret < 0)
+ {
+ status = errno_to_status( errno );
+ goto cleanup;
+ }
+ link_path_len = ret;
+ link_path[link_path_len] = 0;
+ link_path[link_path_len] = 0; /* readlink does not NUL terminate */
+
+ p = &link_path[3*depth];
+ for (depth=0; p < link_path + link_path_len; p += NAME_MAX+1, depth++)
@@ -249,12 +251,11 @@ index 3fb4ded846c..3a1489c35d0 100644
+ encoded[strlen(encoded)-1] = 0; /* final slash */
+
+ link_dir[strlen(link_dir)-1] = 0;
+ chdir( link_dir );
+ fd = openat( link_dir_fd, link_dir, O_RDONLY|O_DIRECTORY );
+ close( link_dir_fd );
+ link_dir_fd = fd;
+ }
+
+ /* revert to the original directory */
+ chdir( original_dir );
+
+ /* Decode the reparse buffer from the base64-encoded symlink data */
+ *size = decode_base64url( encoded, strlen(encoded), (char*)buffer );
+ status = STATUS_SUCCESS;
@@ -265,6 +266,8 @@ index 3fb4ded846c..3a1489c35d0 100644
+ }
+
+cleanup:
+ if (link_dir_fd != -1) close( link_dir_fd );
+ free( unix_name );
+ free( encoded );
+ return status;
+}
@@ -273,7 +276,7 @@ index 3fb4ded846c..3a1489c35d0 100644
/******************************************************************************
* lookup_unix_name
*
@@ -6353,6 +6554,14 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
@@ -6347,6 +6551,14 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
break;
}
@@ -289,5 +292,5 @@ index 3fb4ded846c..3a1489c35d0 100644
{
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)in_buffer;
--
2.35.1
2.17.1

View File

@@ -1,7 +1,7 @@
From 2a596f3d73eb9243960ed48c9b348c0e1461284e Mon Sep 17 00:00:00 2001
From cef94f0a808ceccbb756a3fea6622927aff4e489 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:00:21 -0700
Subject: [PATCH] ntdll: Add support for deleting reparse points.
Subject: ntdll: Add support for deleting reparse points.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
@@ -11,7 +11,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
3 files changed, 133 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 33e49793319..54f7c7fc860 100644
index 805f5a6a940..a127a2f4f88 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5360,12 +5360,15 @@ static void test_reparse_points(void)
@@ -72,10 +72,10 @@ index 33e49793319..54f7c7fc860 100644
ok(bret, "Failed to remove temporary target directory!\n");
RemoveDirectoryW(path);
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 3a1489c35d0..af390214624 100644
index 8fe543ded08..4c221f53bfd 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -3807,6 +3807,99 @@ cleanup:
@@ -3802,6 +3802,99 @@ cleanup:
}
@@ -175,7 +175,7 @@ index 3a1489c35d0..af390214624 100644
/******************************************************************************
* lookup_unix_name
*
@@ -6554,6 +6647,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
@@ -6551,6 +6644,12 @@ NTSTATUS WINAPI NtFsControlFile( HANDLE handle, HANDLE event, PIO_APC_ROUTINE ap
break;
}
@@ -210,5 +210,5 @@ index 21d42e17325..4539b89d583 100644
+
#endif /* __WINE_NTIFS_H */
--
2.35.1
2.17.1

View File

@@ -1,17 +1,17 @@
From f93a10fd26b694aa0df49f032844f9ddd34c632d Mon Sep 17 00:00:00 2001
From a093cbbe7bd8ea6b1e5d48a552f2712dc2915f2c Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:01:25 -0700
Subject: [PATCH] ntdll: Add support for testing for reparse points with
Subject: ntdll: Add support for testing for reparse points with
GetFileAttributes.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/ntdll/tests/file.c | 5 +++++
dlls/ntdll/unix/file.c | 25 ++++++++++++++++++++-----
2 files changed, 25 insertions(+), 5 deletions(-)
dlls/ntdll/unix/file.c | 23 +++++++++++++++++++----
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 54f7c7fc860..7fa50ec59a6 100644
index a127a2f4f88..ffc4ca44e32 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5469,6 +5469,11 @@ static void test_reparse_points(void)
@@ -27,17 +27,13 @@ index 54f7c7fc860..7fa50ec59a6 100644
HeapFree(GetProcessHeap(), 0, buffer);
buffer_len = sizeof(*buffer) + 2*32767;
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index af390214624..201eeab7013 100644
index 4c221f53bfd..948074b35ec 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -1788,10 +1788,20 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
@@ -1755,6 +1755,16 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
*attr = 0;
ret = fstat( fd, st );
if (ret == -1) return ret;
- *attr |= get_file_attributes( st );
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ if (S_ISLNK( st->st_mode ))
+ {
+ BOOL is_dir;
@@ -48,11 +44,10 @@ index af390214624..201eeab7013 100644
+ if (is_reparse_dir( fd, "", &is_dir ) == 0)
+ st->st_mode = (st->st_mode & ~S_IFMT) | (is_dir ? S_IFDIR : S_IFREG);
+ }
+ *attr |= get_file_attributes( st );
return ret;
}
@@ -1841,10 +1851,15 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
*attr |= get_file_attributes( st );
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
@@ -1828,10 +1838,15 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
if (ret == -1) return ret;
if (S_ISLNK( st->st_mode ))
{
@@ -73,5 +68,5 @@ index af390214624..201eeab7013 100644
else if (S_ISDIR( st->st_mode ) && (parent_path = malloc( strlen(path) + 4 )))
{
--
2.35.1
2.17.1

View File

@@ -1,7 +1,7 @@
From 4f3ab4bdb7daf7b38babb2ff4758c6633e703b7c Mon Sep 17 00:00:00 2001
From da698613af1808ca0fe2599bc4b7898fad9dcf18 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:02:11 -0700
Subject: [PATCH] server: Implement FILE_OPEN_REPARSE_POINT option.
Subject: server: Implement FILE_OPEN_REPARSE_POINT option.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
@@ -10,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
2 files changed, 137 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index 8ae982294f6..2ab399ec8e2 100644
index 5ba7e0be419..bfb291fa925 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -735,6 +735,8 @@ static UINT get_nt_file_options( DWORD attributes )
@@ -272,5 +272,5 @@ index eaebe044f37..1ed975673a6 100644
if (!(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
{
--
2.35.1
2.17.1

View File

@@ -1,7 +1,7 @@
From e5d8dc8bdb7f22a5d1a91b8599ace874c5e2316f Mon Sep 17 00:00:00 2001
From 0423cf43baf2938b4b1e7d705c20af11fb13f82c Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Sat, 12 Dec 2020 17:35:21 -0700
Subject: [PATCH] kernelbase: Add support for deleting reparse points with
Subject: kernelbase: Add support for deleting reparse points with
RemoveDirectory.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
@@ -11,7 +11,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index 2ab399ec8e2..4f4040dd098 100644
index bfb291fa925..6214f549406 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -3493,7 +3493,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryW( LPCWSTR path )
@@ -24,7 +24,7 @@ index 2ab399ec8e2..4f4040dd098 100644
if (!status)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 7fa50ec59a6..fa8083b1c3b 100644
index ffc4ca44e32..f3aad01ee93 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5363,11 +5363,11 @@ static void test_reparse_points(void)
@@ -81,5 +81,5 @@ index 7fa50ec59a6..fa8083b1c3b 100644
/* Cleanup */
pRtlFreeUnicodeString(&nameW);
--
2.35.1
2.17.1

View File

@@ -1,8 +1,7 @@
From 6ba3c723cbc8c5a2f3aea407ac62a005bab9b015 Mon Sep 17 00:00:00 2001
From 03c96b5a2e215a7aa7d8c74ca3fbb5794fdcc95f Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Sat, 6 Feb 2021 12:52:51 -0700
Subject: [PATCH] kernelbase: Add support for deleting reparse points with
DeleteFile.
Subject: kernelbase: Add support for deleting reparse points with DeleteFile.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
@@ -11,7 +10,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index 4f4040dd098..5c9f0ebd485 100644
index 6214f549406..17c25eb5858 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -993,7 +993,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW( LPCWSTR path )
@@ -25,7 +24,7 @@ index 4f4040dd098..5c9f0ebd485 100644
RtlFreeUnicodeString( &nameW );
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index fa8083b1c3b..4d4b861e9fb 100644
index f3aad01ee93..4e3f0f04a3e 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5367,7 +5367,7 @@ static void test_reparse_points(void)
@@ -54,5 +53,5 @@ index fa8083b1c3b..4d4b861e9fb 100644
cleanup:
/* Cleanup */
--
2.35.1
2.17.1

View File

@@ -1,16 +1,16 @@
From c6e4a8f7377c21227044833bb6bf8a4fa4e8c8a5 Mon Sep 17 00:00:00 2001
From d636805ef7d44cf78a08538f3c6c2e8f5a2f0d87 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Sat, 6 Feb 2021 12:52:51 -0700
Subject: [PATCH] ntdll: Add tests for NT symlink reparse points.
Subject: ntdll: Add tests for NT symlink reparse points.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/ntdll/tests/file.c | 238 +++++++++++++++++++++++++++++++++++++---
dlls/ntdll/tests/file.c | 239 +++++++++++++++++++++++++++++++++++++---
include/ntifs.h | 12 ++
2 files changed, 236 insertions(+), 14 deletions(-)
2 files changed, 237 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 4d4b861e9fb..f9e179edc1d 100644
index 4e3f0f04a3e..48abcd338bb 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5327,26 +5327,52 @@ static void test_mailslot_name(void)
@@ -75,7 +75,13 @@ index 4d4b861e9fb..f9e179edc1d 100644
lstrcpyW(subst_dest, filename);
lstrcpyW(print_dest, &filename[prefix_len]);
*pbuffer = buffer;
@@ -5368,9 +5394,12 @@ static void test_reparse_points(void)
@@ -5363,14 +5389,18 @@ static void test_reparse_points(void)
FILE_BASIC_INFORMATION old_attrib, new_attrib;
static const WCHAR fooW[] = {'f','o','o',0};
static WCHAR volW[] = {'c',':','\\',0};
+ const WCHAR *rel_target = &targetW[1];
WCHAR *dest, *long_path, *abs_target;
REPARSE_GUID_DATA_BUFFER guid_buffer;
static const WCHAR dotW[] = {'.',0};
REPARSE_DATA_BUFFER *buffer = NULL;
DWORD dwret, dwLen, dwFlags, err;
@@ -89,7 +95,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
BOOL bret;
/* Create a temporary folder for the junction point tests */
@@ -5435,7 +5464,7 @@ static void test_reparse_points(void)
@@ -5435,7 +5465,7 @@ static void test_reparse_points(void)
win_skip("Failed to open junction point directory handle (0x%lx).\n", GetLastError());
goto cleanup;
}
@@ -98,7 +104,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(!bret && GetLastError()==ERROR_INVALID_REPARSE_DATA, "Unexpected error (0x%lx)\n", GetLastError());
HeapFree(GetProcessHeap(), 0, buffer);
@@ -5466,7 +5495,7 @@ static void test_reparse_points(void)
@@ -5466,7 +5496,7 @@ static void test_reparse_points(void)
}
dwret = NtQueryInformationFile(handle, &iosb, &old_attrib, sizeof(old_attrib), FileBasicInformation);
ok(dwret == STATUS_SUCCESS, "Failed to get junction point folder's attributes (0x%lx).\n", dwret);
@@ -107,7 +113,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
@@ -5513,7 +5542,7 @@ static void test_reparse_points(void)
@@ -5513,7 +5543,7 @@ static void test_reparse_points(void)
HeapFree(GetProcessHeap(), 0, buffer);
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
@@ -116,7 +122,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
CloseHandle(handle);
@@ -5528,7 +5557,7 @@ static void test_reparse_points(void)
@@ -5528,7 +5558,7 @@ static void test_reparse_points(void)
ok(bret, "Failed to create junction point target directory.\n");
handle = CreateFileW(reparse_path, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
@@ -125,7 +131,7 @@ index 4d4b861e9fb..f9e179edc1d 100644
bret = DeviceIoControl(handle, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%lx)\n", GetLastError());
CloseHandle(handle);
@@ -5541,6 +5570,187 @@ static void test_reparse_points(void)
@@ -5541,6 +5571,187 @@ static void test_reparse_points(void)
ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%lx)!\n", dwret);
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: 0x%lx)\n", dwret);
@@ -303,11 +309,11 @@ index 4d4b861e9fb..f9e179edc1d 100644
+ bret = DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer, buffer_len, &dwret, 0);
+ ok(bret, "Failed to read relative symlink!\n");
+ string_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
+ ok(string_len != lstrlenW(&targetW[1]), "Symlink destination length does not match ('%d' != '%d')!\n",
+ string_len, lstrlenW(&targetW[1]));
+ ok(string_len != lstrlenW(rel_target), "Symlink destination length does not match ('%d' != '%d')!\n",
+ string_len, lstrlenW(rel_target));
+ dest = &buffer->SymbolicLinkReparseBuffer.PathBuffer[buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
+ ok((memcmp(dest, &targetW[1], string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
+ wine_dbgstr_w(dest), wine_dbgstr_w(&targetW[1]));
+ ok((memcmp(dest, rel_target, string_len) == 0), "Symlink destination does not match ('%s' != '%s')!\n",
+ wine_dbgstr_w(dest), wine_dbgstr_w(rel_target));
+ CloseHandle(handle);
+
cleanup:
@@ -354,5 +360,5 @@ index 4539b89d583..0d02225bc4f 100644
+
#endif /* __WINE_NTIFS_H */
--
2.35.1
2.17.1

View File

@@ -1,19 +1,18 @@
From edaf25f8037c96fe83885ab47a1195c7f28e2fd6 Mon Sep 17 00:00:00 2001
From 70b8fd99f84708447779b45735e0553755f1b8bb Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Sat, 6 Feb 2021 12:46:30 -0700
Subject: [PATCH] kernelbase: Add support for moving reparse points with
MoveFile*.
Subject: kernelbase: Add support for moving reparse points with MoveFile*.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/kernelbase/file.c | 2 +-
dlls/ntdll/tests/file.c | 13 ++++++++++++-
dlls/ntdll/tests/file.c | 12 +++++++++++-
dlls/ntdll/unix/file.c | 20 ++++++++++++++++++++
server/fd.c | 6 ++++--
4 files changed, 37 insertions(+), 4 deletions(-)
4 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index 5c9f0ebd485..2cbe8f4ac03 100644
index 17c25eb5858..53b9651a8fa 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -2471,7 +2471,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH MoveFileWithProgressW( const WCHAR *source, const
@@ -26,7 +25,7 @@ index 5c9f0ebd485..2cbe8f4ac03 100644
if (!set_ntstatus( status )) goto error;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index f9e179edc1d..6ccdb3c02dc 100644
index 48abcd338bb..808d863ea55 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5381,7 +5381,8 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, ULONG flags,
@@ -39,16 +38,8 @@ index f9e179edc1d..6ccdb3c02dc 100644
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
static const WCHAR parentW[] = {'\\','.','.','\\',0};
@@ -5389,6 +5390,7 @@ static void test_reparse_points(void)
FILE_BASIC_INFORMATION old_attrib, new_attrib;
static const WCHAR fooW[] = {'f','o','o',0};
static WCHAR volW[] = {'c',':','\\',0};
+ const WCHAR *rel_target = &targetW[1];
WCHAR *dest, *long_path, *abs_target;
REPARSE_GUID_DATA_BUFFER guid_buffer;
static const WCHAR dotW[] = {'.',0};
@@ -5751,6 +5753,15 @@ static void test_reparse_points(void)
wine_dbgstr_w(dest), wine_dbgstr_w(&targetW[1]));
@@ -5752,6 +5753,15 @@ static void test_reparse_points(void)
wine_dbgstr_w(dest), wine_dbgstr_w(rel_target));
CloseHandle(handle);
+ /* Check moving a reparse point to another location */
@@ -64,10 +55,10 @@ index f9e179edc1d..6ccdb3c02dc 100644
/* Cleanup */
pRtlFreeUnicodeString(&nameW);
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 201eeab7013..907d51f1fc3 100644
index 948074b35ec..9ae5e194c6d 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -5336,8 +5336,10 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
@@ -5328,8 +5328,10 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
if (len >= sizeof(FILE_RENAME_INFORMATION))
{
FILE_RENAME_INFORMATION *info = ptr;
@@ -78,7 +69,7 @@ index 201eeab7013..907d51f1fc3 100644
char *unix_name;
name_str.Buffer = info->FileName;
@@ -5346,6 +5348,19 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
@@ -5338,6 +5340,19 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
InitializeObjectAttributes( &attr, &name_str, OBJ_CASE_INSENSITIVE, info->RootDirectory, NULL );
get_redirect( &attr, &redir );
@@ -98,7 +89,7 @@ index 201eeab7013..907d51f1fc3 100644
status = nt_to_unix_file_name( &attr, &unix_name, FILE_OPEN_IF );
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
{
@@ -5362,9 +5377,14 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
@@ -5354,9 +5369,14 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
}
SERVER_END_REQ;
@@ -145,5 +136,5 @@ index 1ed975673a6..60ba552f769 100644
if (!fd->unix_name)
set_error( STATUS_NO_MEMORY );
--
2.35.1
2.17.1

View File

@@ -1,7 +1,7 @@
From 1af9d5003cb6d65be02fb68779e208488c242b82 Mon Sep 17 00:00:00 2001
From 2cf08dad55bea4bbf5ca37ff0bf4a0553d1f6be3 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Sat, 3 Sep 2022 08:57:05 -0600
Subject: [PATCH] kernelbase: Add test for reparse point copy behavior.
Subject: kernelbase: Add test for reparse point copy behavior.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
@@ -9,7 +9,7 @@ Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
1 file changed, 6 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 6ccdb3c02dc..b1290f9ef7b 100644
index 808d863ea55..390768f557d 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5762,6 +5762,12 @@ static void test_reparse_points(void)
@@ -26,5 +26,5 @@ index 6ccdb3c02dc..b1290f9ef7b 100644
/* Cleanup */
pRtlFreeUnicodeString(&nameW);
--
2.35.1
2.17.1

View File

@@ -1,16 +1,16 @@
From ff29165847ca6ea105053843f46cac727c7083c8 Mon Sep 17 00:00:00 2001
From a3eedb8eb82f841ae48633d1e3c0416a362ccd34 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Sat, 3 Sep 2022 11:23:31 -0600
Subject: [PATCH] ntdll: Follow reparse points during path resolution.
Subject: ntdll: Follow reparse points during path resolution.
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
dlls/ntdll/tests/file.c | 11 +++-
dlls/ntdll/unix/file.c | 122 +++++++++++++++++++++++++++++++++++++---
2 files changed, 124 insertions(+), 9 deletions(-)
dlls/ntdll/tests/file.c | 11 ++-
dlls/ntdll/unix/file.c | 189 +++++++++++++++++++++++++++++++++++-----
2 files changed, 177 insertions(+), 23 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index b1290f9ef7b..799a8cebe50 100644
index 390768f557d..a0b84849490 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -5381,7 +5381,7 @@ static INT build_reparse_buffer(const WCHAR *filename, ULONG tag, ULONG flags,
@@ -44,10 +44,46 @@ index b1290f9ef7b..799a8cebe50 100644
ok(bret, "Failed to remove temporary reparse point directory!\n");
bret = RemoveDirectoryW(target_path);
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 907d51f1fc3..d520a73b253 100644
index 9ae5e194c6d..ba844e90272 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -3700,14 +3700,13 @@ cleanup:
@@ -3516,6 +3516,35 @@ done:
}
+static NTSTATUS get_reparse_target( UNICODE_STRING *nt_target, REPARSE_DATA_BUFFER *buffer,
+ int *is_relative )
+{
+ int target_len, offset;
+ WCHAR *target;
+
+ switch( buffer->ReparseTag )
+ {
+ case IO_REPARSE_TAG_MOUNT_POINT:
+ offset = buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
+ target_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
+ *is_relative = FALSE;
+ break;
+ case IO_REPARSE_TAG_SYMLINK:
+ offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
+ target_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
+ *is_relative = (buffer->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) == SYMLINK_FLAG_RELATIVE;
+ break;
+ default:
+ return STATUS_IO_REPARSE_TAG_NOT_HANDLED;
+ }
+ nt_target->Buffer = target;
+ nt_target->Length = target_len;
+ return STATUS_REPARSE;
+}
+
+
/*
* Retrieve the unix name corresponding to a file handle, remove that directory, and then symlink
* the requested directory to the location of the old directory.
@@ -3692,16 +3721,14 @@ cleanup:
/*
@@ -56,26 +92,33 @@ index 907d51f1fc3..d520a73b253 100644
+ * Obtain the reparse point buffer from the unix filename for the reparse point.
*/
-NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *size)
+NTSTATUS get_reparse_point_unix(const char *unix_src, REPARSE_DATA_BUFFER *buffer, ULONG *size)
+NTSTATUS get_reparse_point_unix(const char *unix_name, REPARSE_DATA_BUFFER *buffer, ULONG *size)
{
char link_dir[PATH_MAX], original_dir[PATH_MAX], *d;
char link_dir[PATH_MAX], link_path[PATH_MAX], *d;
int link_path_len, buffer_len, encoded_len;
- char *unix_src, link_path[PATH_MAX];
+ char link_path[PATH_MAX];
REPARSE_DATA_BUFFER header;
ULONG out_size = *size;
- char *unix_name = NULL;
char *encoded = NULL;
@@ -3716,9 +3715,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
int link_dir_fd = -1;
NTSTATUS status;
@@ -3709,9 +3736,6 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
int depth;
char *p;
- if ((status = server_get_unix_name( handle, &unix_src )))
- if ((status = server_get_unix_name( handle, &unix_name )))
- goto cleanup;
-
ret = readlink( unix_src, link_path, sizeof(link_path) );
ret = readlink( unix_name, link_path, sizeof(link_path) );
if (ret < 0)
{
@@ -3822,6 +3818,75 @@ cleanup:
@@ -3811,12 +3835,76 @@ NTSTATUS get_reparse_point(HANDLE handle, REPARSE_DATA_BUFFER *buffer, ULONG *si
cleanup:
if (link_dir_fd != -1) close( link_dir_fd );
- free( unix_name );
free( encoded );
return status;
}
@@ -97,13 +140,14 @@ index 907d51f1fc3..d520a73b253 100644
+
+
+/* find the NT target of a reparse point */
+static NTSTATUS find_reparse_target( const char *unix_name, WCHAR **new_name, int *new_name_len)
+static NTSTATUS find_reparse_target( const char *unix_name, const WCHAR *parent, int parent_len,
+ WCHAR **new_name, int *new_name_len)
+{
+ REPARSE_DATA_BUFFER *buffer = NULL;
+ int offset, target_len;
+ UNICODE_STRING nt_target;
+ ULONG buffer_len = 0;
+ int is_relative;
+ NTSTATUS status;
+ WCHAR *target;
+
+ status = get_reparse_point_unix( unix_name, NULL, &buffer_len );
+ if (status != STATUS_BUFFER_TOO_SMALL)
@@ -117,32 +161,27 @@ index 907d51f1fc3..d520a73b253 100644
+ free( buffer );
+ return status;
+ }
+
+ switch( buffer->ReparseTag )
+ if ((status = get_reparse_target( &nt_target, buffer, &is_relative )) == STATUS_REPARSE)
+ {
+ case IO_REPARSE_TAG_MOUNT_POINT:
+ offset = buffer->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
+ target_len = buffer->MountPointReparseBuffer.SubstituteNameLength;
+ break;
+ case IO_REPARSE_TAG_SYMLINK:
+ offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
+ target_len = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
+ break;
+ default:
+ WARN( "Reparse point with unsupported tag: 0x%08x\n", buffer->ReparseTag );
+ status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ if (status == STATUS_SUCCESS)
+ {
+ *new_name_len = target_len/sizeof(WCHAR);
+ *new_name = malloc( target_len );
+ if (*new_name) memcpy( *new_name, target, target_len );
+ WCHAR *p;
+
+ p = *new_name = malloc( nt_target.Length + parent_len*sizeof(WCHAR) );
+ if (!p)
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+ if (is_relative)
+ {
+ memcpy( p, parent, parent_len*sizeof(WCHAR) );
+ p += parent_len;
+ }
+ memcpy( p, nt_target.Buffer, nt_target.Length );
+ p += nt_target.Length/sizeof(WCHAR);
+ *new_name_len = p - *new_name;
+ }
+
+done:
+ free( buffer );
+ return status;
+}
@@ -151,26 +190,35 @@ index 907d51f1fc3..d520a73b253 100644
/*
* Retrieve the unix name corresponding to a file handle, remove that symlink, and then recreate
* a directory at the location of the old filename.
@@ -3924,11 +3989,13 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
UINT disposition, BOOL is_unix )
@@ -3910,15 +3998,25 @@ cleanup:
}
+static NTSTATUS IoReplaceFileObjectName( FILE_OBJECT *fileobj, PWSTR name, USHORT name_len )
+{
+ fileobj->FileName.Buffer = name;
+ fileobj->FileName.Length = name_len;
+ return STATUS_SUCCESS;
+}
+
+
/******************************************************************************
* lookup_unix_name
*
* Helper for nt_to_unix_file_name
*/
-static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer, int unix_len, int pos,
- UINT disposition, BOOL is_unix )
+static NTSTATUS lookup_unix_name( FILE_OBJECT *fileobj, const WCHAR *name, int name_len,
+ char **buffer, int unix_len, int pos, UINT disposition,
+ BOOL is_unix )
{
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, '/', 0 };
+ WCHAR *name_buf = NULL;
+ const WCHAR *fullname = fileobj->FileName.Buffer;
NTSTATUS status;
int ret;
struct stat st;
char *unix_name = *buffer;
const WCHAR *ptr, *end;
+ int old_cwd;
/* check syntax of individual components */
@@ -3977,9 +4044,13 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
/* now do it component by component */
+ old_cwd = open( ".", O_RDONLY );
+
@@ -3975,6 +4073,8 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
while (name_len)
{
const WCHAR *end, *next;
@@ -179,40 +227,32 @@ index 907d51f1fc3..d520a73b253 100644
end = name;
while (end < name + name_len && *end != '\\') end++;
@@ -3999,8 +4070,39 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
@@ -3994,8 +4094,31 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
status = find_file_in_dir( unix_name, pos, name, end - name, is_unix );
+ /* follow reparse point and restart from there (if applicable) */
+ if (find_reparse_target( unix_name, &target, &target_len ) == STATUS_SUCCESS)
+ if (name_len && find_reparse_target( unix_name, fullname, name - fullname, &target, &target_len ) == STATUS_REPARSE)
+ {
+ int new_name_len = target_len + name_len + 1;
+ WCHAR *new_name, *p;
+ WCHAR *p, *new_name;
+
+ if (!(p = new_name = malloc( new_name_len*sizeof(WCHAR) )))
+ {
+ free( target );
+ return STATUS_NO_MEMORY;
+ status = STATUS_NO_MEMORY;
+ break;
+ }
+ memcpy( p, target, target_len*sizeof(WCHAR) );
+ p += target_len;
+ (p++)[0] = '\\';
+ memcpy( p, next, name_len*sizeof(WCHAR) );
+ if (target[0] == '\\')
+ {
+ strcpy( unix_name, "/" );
+ pos = 0;
+ }
+ else
+ unix_name = dirname( unix_name );
+ TRACE( "Follow reparse point %s => %s, %s\n", debugstr_wn(name, end-name), unix_name,
+ debugstr_wn(new_name, new_name_len) );
+ next = new_name;
+ name_len = new_name_len;
+ TRACE( "Follow reparse point %s => %s\n", debugstr_wn(fullname, end-fullname),
+ debugstr_wn(new_name, new_name_len) );
+ free( target );
+ free( name_buf );
+ name_buf = new_name;
+ status = STATUS_SUCCESS;
+ if (IoReplaceFileObjectName( fileobj, new_name, new_name_len*sizeof(WCHAR) ))
+ free( new_name );
+ return STATUS_REPARSE;
+ }
/* if this is the last element, not finding it is not necessarily fatal */
- if (!name_len)
@@ -220,21 +260,118 @@ index 907d51f1fc3..d520a73b253 100644
{
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
{
@@ -4028,10 +4130,14 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
@@ -4034,12 +4157,12 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
/******************************************************************************
* nt_to_unix_file_name_no_root
*/
-static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char **unix_name_ret,
+static NTSTATUS nt_to_unix_file_name_no_root( FILE_OBJECT *fileobj, char **unix_name_ret,
UINT disposition )
{
static const WCHAR unixW[] = {'u','n','i','x'};
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
-
+ const UNICODE_STRING *nameW = &fileobj->FileName;
NTSTATUS status = STATUS_SUCCESS;
const WCHAR *name;
struct stat st;
@@ -4129,7 +4252,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
name += prefix_len;
name_len -= prefix_len;
if (status != STATUS_SUCCESS) break;
+ chdir( unix_name );
pos += strlen( unix_name + pos );
name = next;
- status = lookup_unix_name( name, name_len, &unix_name, unix_len, pos, disposition, is_unix );
+ status = lookup_unix_name( fileobj, name, name_len, &unix_name, unix_len, pos, disposition, is_unix );
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
{
TRACE( "%s -> %s\n", debugstr_us(nameW), debugstr_a(unix_name) );
@@ -4137,7 +4260,8 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
}
else
{
- TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
+ if (status != STATUS_REPARSE)
+ TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
free( unix_name );
}
return status;
@@ -4155,18 +4279,30 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
*/
NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, UINT disposition )
{
+ HANDLE rootdir = attr->RootDirectory;
enum server_fd_type type;
int old_cwd, root_fd, needs_close;
+ int reparse_count = 0;
+ FILE_OBJECT fileobj;
const WCHAR *name;
char *unix_name;
int name_len, unix_len;
NTSTATUS status;
+ fchdir( old_cwd );
+ free( name_buf );
- if (!attr->RootDirectory) /* without root dir fall back to normal lookup */
- return nt_to_unix_file_name_no_root( attr->ObjectName, name_ret, disposition );
+ fileobj.FileName = *attr->ObjectName;
+reparse:
+ if (reparse_count++ == 31)
+ return STATUS_REPARSE_POINT_NOT_RESOLVED;
+ if (!rootdir) /* without root dir fall back to normal lookup */
+ {
+ status = nt_to_unix_file_name_no_root( &fileobj, name_ret, disposition );
+ if (status == STATUS_REPARSE) goto reparse;
+ if (fileobj.FileName.Buffer != attr->ObjectName->Buffer) free( fileobj.FileName.Buffer);
+ return status;
+ }
- name = attr->ObjectName->Buffer;
- name_len = attr->ObjectName->Length / sizeof(WCHAR);
+ name = fileobj.FileName.Buffer;
+ name_len = fileobj.FileName.Length / sizeof(WCHAR);
if (name_len && name[0] == '\\') return STATUS_INVALID_PARAMETER;
@@ -4174,7 +4310,7 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
if (!(unix_name = malloc( unix_len ))) return STATUS_NO_MEMORY;
unix_name[0] = '.';
- if (!(status = server_get_unix_fd( attr->RootDirectory, 0, &root_fd, &needs_close, &type, NULL )))
+ if (!(status = server_get_unix_fd( rootdir, 0, &root_fd, &needs_close, &type, NULL )))
{
if (type != FD_TYPE_DIR)
{
@@ -4186,7 +4322,8 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
mutex_lock( &dir_mutex );
if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1)
{
- status = lookup_unix_name( name, name_len, &unix_name, unix_len, 1, disposition, FALSE );
+ status = lookup_unix_name( &fileobj, name, name_len, &unix_name, unix_len, 1,
+ disposition, FALSE );
if (fchdir( old_cwd ) == -1) chdir( "/" );
}
else status = errno_to_status( errno );
@@ -4199,14 +4336,22 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, U
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
{
- TRACE( "%s -> %s\n", debugstr_us(attr->ObjectName), debugstr_a(unix_name) );
+ TRACE( "%s -> %s\n", debugstr_us(&fileobj.FileName), debugstr_a(unix_name) );
*name_ret = unix_name;
}
+ else if (status == STATUS_REPARSE)
+ {
+ if (fileobj.FileName.Buffer[0] == '\\') rootdir = 0;
+ free( unix_name );
+ goto reparse;
+ }
else
{
TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
free( unix_name );
}
+
+ if (fileobj.FileName.Buffer != attr->ObjectName->Buffer) free( fileobj.FileName.Buffer);
return status;
}
--
2.35.1
2.17.1

View File

@@ -1,4 +1,4 @@
From 2863150ec05b9abf82d0c72bc33b4c64092dc4ee Mon Sep 17 00:00:00 2001
From c232ecbb9cda964d9e279f16127b1e112f62ce55 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Sat, 12 Dec 2020 17:28:31 -0700
Subject: [PATCH] kernel32: Advertise reparse point support.

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