[Wine-patches] [eter-1.0.12] Set file locks without wineserver (eterbug #5798).
Alexander Morozov
amorozov на etersoft.ru
Пт Май 13 19:55:06 MSD 2011
----------- следующая часть -----------
From d1fa973ee9474e23ff0a39aa73deb0164e5564cd Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 13 May 2011 18:33:28 +0400
Subject: [eter-1.0.12] Set file locks without wineserver (eterbug #5798).
---
dlls/ntdll/file.c | 48 +++++++++++++++++++++++++++++++++++++---------
dlls/ntdll/server.c | 26 ++++++++++++++++++++++--
include/wine/etersoft.h | 18 +++++++++++++++++
server/fd.c | 7 +++++-
4 files changed, 85 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index dc7af39..8eba2ac 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -82,6 +82,8 @@
#include "winternl.h"
#include "winioctl.h"
#include "ddk/ntddser.h"
+
+#define ETERSOFT_FUNC_LOCK
#include "wine/etersoft.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
@@ -226,6 +228,8 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
if (io->u.Status == STATUS_SUCCESS)
{
+ int fd, needs_close;
+
if (created) io->Information = FILE_CREATED;
else switch(disposition)
{
@@ -244,6 +248,10 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
io->Information = FILE_OVERWRITTEN;
break;
}
+ /* add to cache */
+ if (!server_get_unix_fd( *handle, access, &fd, &needs_close, NULL, NULL )
+ && needs_close)
+ close( fd );
}
return io->u.Status;
@@ -2470,20 +2478,31 @@ NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event,
warn = FALSE;
}
+ LOADETER_FUNC( etersoft_lock_file );
for (;;)
{
- SERVER_START_REQ( lock_file )
+ if (etersoft_lock_file && etersoft_lock_file( hFile, offset->QuadPart,
+ count->QuadPart, dont_wait, exclusive, &ret ))
{
- req->handle = wine_server_obj_handle( hFile );
- req->offset = offset->QuadPart;
- req->count = count->QuadPart;
- req->shared = !exclusive;
- req->wait = !dont_wait;
- ret = wine_server_call( req );
- handle = wine_server_ptr_handle( reply->handle );
- async = reply->overlapped;
+ if (ret == STATUS_UNSUCCESSFUL)
+ ret = FILE_GetNtStatus();
+ /* ret != STATUS_PENDING */
+ }
+ else
+ {
+ SERVER_START_REQ( lock_file )
+ {
+ req->handle = wine_server_obj_handle( hFile );
+ req->offset = offset->QuadPart;
+ req->count = count->QuadPart;
+ req->shared = !exclusive;
+ req->wait = !dont_wait;
+ ret = wine_server_call( req );
+ handle = wine_server_ptr_handle( reply->handle );
+ async = reply->overlapped;
+ }
+ SERVER_END_REQ;
}
- SERVER_END_REQ;
if (ret != STATUS_PENDING)
{
if (!ret && lock_granted_event) NtSetEvent(lock_granted_event, NULL);
@@ -2534,6 +2553,15 @@ NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status,
return STATUS_NOT_IMPLEMENTED;
}
+ LOADETER_FUNC( etersoft_unlock_file );
+ if (etersoft_unlock_file && etersoft_unlock_file( hFile, offset->QuadPart,
+ count->QuadPart, &status ))
+ {
+ if (status == STATUS_UNSUCCESSFUL)
+ status = FILE_GetNtStatus();
+ return status;
+ }
+
SERVER_START_REQ( unlock_file )
{
req->handle = wine_server_obj_handle( hFile );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index f1e2eb9..734a50e 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -69,6 +69,9 @@
#include "wine/debug.h"
#include "ntdll_misc.h"
+#define ETERSOFT_FUNC_FD
+#include "wine/etersoft.h"
+
/* mcache */
extern BOOL mcache_check_msg( const struct __server_request_info* req,
struct __server_request_info* rep );
@@ -456,9 +459,14 @@ static inline unsigned int handle_to_index( HANDLE handle, unsigned int *entry )
static int add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
unsigned int access, unsigned int options )
{
- unsigned int entry, idx = handle_to_index( handle, &entry );
+ unsigned int entry, idx;
int prev_fd;
+ LOADETER_FUNC( etersoft_save_fd );
+ if (etersoft_save_fd && etersoft_save_fd( handle, fd, type, access, options ))
+ return 1;
+
+ idx = handle_to_index( handle, &entry );
if (entry >= FD_CACHE_ENTRIES)
{
FIXME( "too many allocated handles, not caching %p\n", handle );
@@ -494,9 +502,16 @@ static int add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
unsigned int *access, unsigned int *options )
{
- unsigned int entry, idx = handle_to_index( handle, &entry );
+ unsigned int entry, idx;
int fd = -1;
+ LOADETER_FUNC( etersoft_get_fd );
+ if (etersoft_get_fd)
+ fd = etersoft_get_fd( handle, type, access, options );
+ if (fd >= 0)
+ return fd;
+
+ idx = handle_to_index( handle, &entry );
if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
{
fd = fd_cache[entry][idx].fd - 1;
@@ -513,9 +528,14 @@ static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
*/
int server_remove_fd_from_cache( HANDLE handle )
{
- unsigned int entry, idx = handle_to_index( handle, &entry );
+ unsigned int entry, idx;
int fd = -1;
+ LOADETER_FUNC( etersoft_remove_fd );
+ if (etersoft_remove_fd && etersoft_remove_fd( handle ))
+ return -1;
+
+ idx = handle_to_index( handle, &entry );
if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
fd = interlocked_xchg( &fd_cache[entry][idx].fd, 0 ) - 1;
diff --git a/include/wine/etersoft.h b/include/wine/etersoft.h
index 706a6b4..3723285 100644
--- a/include/wine/etersoft.h
+++ b/include/wine/etersoft.h
@@ -200,4 +200,22 @@ static int (*etersoft_ioctl_pre)(unsigned long code, void *in_buff,
static void (*etersoft_ioctl_post)(void *process, void *saved_ptr, char *data);
#endif
+#ifdef ETERSOFT_FUNC_FD
+static int (*etersoft_save_fd)(void *handle, int fd, unsigned int type,
+ unsigned int access, unsigned int options);
+
+static int (*etersoft_get_fd)(void *handle, unsigned int *type,
+ unsigned int *access, unsigned int *options);
+
+static int (*etersoft_remove_fd)(void *handle);
+#endif
+
+#ifdef ETERSOFT_FUNC_LOCK
+static int (*etersoft_lock_file)(void *handle, unsigned long long offset,
+ unsigned long long count, int dont_wait, int exclusive, int *status);
+
+static int (*etersoft_unlock_file)(void *handle, unsigned long long offset,
+ unsigned long long count, int *status);
+#endif
+
#endif
diff --git a/server/fd.c b/server/fd.c
index a208136..12149e0 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2221,7 +2221,12 @@ DECL_HANDLER(get_handle_fd)
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
{
- int unix_fd = get_unix_fd( fd );
+ int unix_fd = -1;
+
+ if (fd->inode)
+ unix_fd = inode_get_lock_fd( fd->inode );
+ if (unix_fd == -1)
+ unix_fd = get_unix_fd( fd );
if (unix_fd != -1)
{
reply->type = fd->fd_ops->get_fd_type( fd );
--
1.7.4.5
Подробная информация о списке рассылки Wine-patches