Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2009
- 91 participants
- 613 messages
Re: eventlog tests and writing/clearing the logs
by Nikolay Sivov
On Mon, Nov 2, 2009 at 7:35 PM, Paul Vriens <paul.vriens.wine(a)gmail.com> wrote:
>
> Any thoughts on this? Correct approach?
>
Do you plan to implement a real logging or what all of this is for?
> --
> Cheers,
>
> Paul.
>
Nov. 2, 2009
eventlog tests and writing/clearing the logs
by Paul Vriens
Hi,
I'm mostly done with the parameter tests and I'm starting to look what
functional tests I can add.
The biggest issues I have are:
- Writing events needs to go a registered event source
- Clearing an eventlog has to be with a registered event source
- Registering our own event source can be done but needs a reboot to
clear out any remnants.
As we really want to test all of this, my proposal is to run these tests
only in interactive mode. Doing so at least gives us some confidence
that people know what they are doing.
Worst case, they will have an extra event source that can only be
deleted by removing some registry entries, a reboot and removal of the
actual eventlog file (the registry removal will be part of the cleanup
of course but you never know).
Any thoughts on this? Correct approach?
--
Cheers,
Paul.
Nov. 2, 2009
Re: gdi32: add testcases for copying an EMF from a NULL bitmap
by Nikolay Sivov
On Mon, Nov 2, 2009 at 8:27 AM, Austin English <austinenglish(a)gmail.com> wrote:
> Testcase for bug 4553
Are you sure? I don't see any related patches here.
>
> --
> -Austin
>
Why there's no wine failure in this test?
Nov. 2, 2009
Re: [PATCH 0/3] Handling DOS drives in mountmgr (try 2)
by Charles Davis
Alexandre Julliard wrote:
> Charles Davis <cdavis(a)mymail.mines.edu> writes:
>
>> I thought I fixed all the issues. What's wrong with my patches now?
>
> Many things, it's a lot more complicated than that. For instance you
> can't just kill the fstab support, this needs to be preserved somehow,
> probably on the mountmgr side. Also you can't have a single file
> descriptor per device, you need one for each open.
>
OK, I can do that.
I've decided to do the open in mountmgr, so I can have it handle changes
to the fstab while it's running. So, I'm working on implementing
IRP_MJ_CREATE support (which is the standard way for drivers to handle
open requests). I've attached a first stab at that. Can you take a look?
I'm pretty sure there's something I'm missing.
BTW, I'm on #winehackers as I write this (my nick is cdavis5x).
Chip
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 93d72a6..3ad1284 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -142,6 +142,56 @@ static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs )
return EXCEPTION_CONTINUE_SEARCH;
}
+/* process an open request for a given device */
+static NTSTATUS process_open( DEVICE_OBJECT *device, ULONG access, ULONG sharing,
+ ULONG options )
+{
+ IRP irp;
+ IO_STACK_LOCATION irpsp;
+ IO_SECURITY_CONTEXT security;
+ PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_CREATE];
+ NTSTATUS status;
+ LARGE_INTEGER count;
+
+ TRACE( "open device %p access %x sharing %x options %x\n", device, access,
+ access, sharing, options );
+
+ /* so we can spot things that we should initialize */
+ memset( &irp, 0x55, sizeof(irp) );
+ memset( &irpsp, 0x66, sizeof(irpsp) );
+ memset( &security, 0x77, sizeof(security) );
+
+ irp.RequestorMode = UserMode;
+ irp.Tail.Overlay.s.u.CurrentStackLocation = &irpsp;
+ irp.UserIosb = NULL;
+
+ irpsp.MajorFunction = IRP_MJ_CREATE;
+ irpsp.Create.SecurityContext = &security;
+ security.DesiredAccess = access;
+ irpsp.Create.Options = options;
+ irpsp.Create.ShareAccess = sharing;
+ irpsp.DeviceObject = device;
+ irpsp.CompletionRoutine = NULL;
+
+ device->CurrentIrp = &irp;
+
+ KeQueryTickCount( &count ); /* update the global KeTickCount */
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
+ GetCurrentThreadId(), dispatch, device, &irp );
+
+ status = dispatch( device, &irp );
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
+ GetCurrentThreadId(), dispatch, device, &irp, status );
+
+ *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
+ return irp.IoStatus.u.Status;
+
+}
+
/* process an ioctl request for a given device */
static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
void *out_buff, ULONG *out_size )
@@ -206,12 +256,14 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
{
HANDLE manager = get_device_manager();
- obj_handle_t ioctl = 0;
+ obj_handle_t call = 0;
+ enum server_call_type type = CALL_OPEN;
NTSTATUS status = STATUS_SUCCESS;
ULONG code = 0;
void *in_buff, *out_buff = NULL;
DEVICE_OBJECT *device = NULL;
ULONG in_size = 4096, out_size = 0;
+ ULONG access, sharing, options;
HANDLE handles[2];
if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size )))
@@ -228,21 +280,35 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
SERVER_START_REQ( get_next_device_request )
{
req->manager = wine_server_obj_handle( manager );
- req->prev = ioctl;
+ req->prev = call;
req->status = status;
- wine_server_add_data( req, out_buff, out_size );
- wine_server_set_reply( req, in_buff, in_size );
+ if (type == CALL_IOCTL)
+ {
+ wine_server_add_data( req, out_buff, out_size );
+ wine_server_set_reply( req, in_buff, in_size );
+ }
if (!(status = wine_server_call( req )))
{
- code = reply->code;
- ioctl = reply->next;
+ call = reply->next;
+ type = reply->type;
device = wine_server_get_ptr( reply->user_ptr );
- in_size = reply->in_size;
- out_size = reply->out_size;
+ switch(type)
+ {
+ case CALL_OPEN:
+ access = reply->data.open.access;
+ sharing = reply->data.open.sharing;
+ options = reply->data.open.options;
+ break;
+ case CALL_IOCTL:
+ code = reply->data.ioctl.code;
+ in_size = reply->data.ioctl.in_size;
+ out_size = reply->data.ioctl.out_size;
+ break;
+ }
}
else
{
- ioctl = 0; /* no previous ioctl */
+ call = 0; /* no previous call */
out_size = 0;
in_size = reply->in_size;
}
@@ -255,7 +321,15 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
HeapFree( GetProcessHeap(), 0, out_buff );
if (out_size) out_buff = HeapAlloc( GetProcessHeap(), 0, out_size );
else out_buff = NULL;
- status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
+ switch(type)
+ {
+ case CALL_OPEN:
+ status = process_open( device, access, sharing, options );
+ break;
+ case CALL_IOCTL:
+ status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
+ break;
+ }
break;
case STATUS_BUFFER_OVERFLOW:
HeapFree( GetProcessHeap(), 0, in_buff );
diff --git a/server/device.c b/server/device.c
index 4d134a3..cc772c9 100644
--- a/server/device.c
+++ b/server/device.c
@@ -33,17 +33,61 @@
#include "handle.h"
#include "request.h"
-struct ioctl_call
+int suspend_thread( struct thread *thread );
+int resume_thread( struct thread *thread );
+
+struct call_object
{
struct object obj; /* object header */
+ enum server_call_type type; /* type of driver call */
struct list dev_entry; /* entry in device queue */
struct list mgr_entry; /* entry in manager queue */
- struct device *device; /* device containing this ioctl */
- struct thread *thread; /* thread that queued the ioctl */
+ struct device *device; /* device being opened */
+ struct thread *thread; /* thread that opened the device */
client_ptr_t user_arg; /* user arg used to identify the request */
+ unsigned int status; /* resulting status (or STATUS_PENDING) */
+};
+
+static int call_object_signaled( struct object *obj, struct thread *thread );
+static void call_object_destroy( struct object *obj );
+
+struct open_call
+{
+ struct call_object call; /* object header */
+ unsigned int access; /* desired access */
+ unsigned int sharing; /* desired sharing */
+ unsigned int options; /* create options */
+};
+
+static void open_call_dump( struct object *obj, int verbose );
+static void open_call_destroy( struct object *obj );
+
+static const struct object_ops open_call_ops =
+{
+ sizeof(struct open_call), /* size */
+ open_call_dump, /* dump */
+ no_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ call_object_signaled, /* signaled */
+ no_satisfied, /* satisfied */
+ no_signal, /* signal */
+ no_get_fd, /* get_fd */
+ no_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ open_call_destroy /* destroy */
+};
+
+
+struct ioctl_call
+{
+ struct call_object obj; /* object header */
struct async *async; /* pending async op */
ioctl_code_t code; /* ioctl code */
- unsigned int status; /* resulting status (or STATUS_PENDING) */
data_size_t in_size; /* size of input data */
void *in_data; /* input data */
data_size_t out_size; /* size of output data */
@@ -51,7 +95,6 @@ struct ioctl_call
};
static void ioctl_call_dump( struct object *obj, int verbose );
-static int ioctl_call_signaled( struct object *obj, struct thread *thread );
static void ioctl_call_destroy( struct object *obj );
static const struct object_ops ioctl_call_ops =
@@ -61,7 +104,7 @@ static const struct object_ops ioctl_call_ops =
no_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
- ioctl_call_signaled, /* signaled */
+ call_object_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
@@ -160,17 +203,68 @@ static const struct fd_ops device_fd_ops =
};
-static void ioctl_call_dump( struct object *obj, int verbose )
+static int call_object_signaled( struct object *obj, struct thread *thread )
{
- struct ioctl_call *ioctl = (struct ioctl_call *)obj;
- fprintf( stderr, "Ioctl call code=%08x device=%p\n", ioctl->code, ioctl->device );
+ struct call_object *call = (struct call_object *)obj;
+
+ return !call->device; /* device is cleared once the ioctl has completed */
}
-static int ioctl_call_signaled( struct object *obj, struct thread *thread )
+static void call_object_destroy( struct call_object *obj )
{
- struct ioctl_call *ioctl = (struct ioctl_call *)obj;
+ if (obj->device) release_object( obj->device );
+ release_object( obj->thread );
+}
+
+
+static void open_call_dump( struct object *obj, int verbose )
+{
+ struct open_call *open = (struct open_call *)obj;
+ fprintf( stderr, "Open call device=%p\n", open->call.device );
+}
+
+static void open_call_destroy( struct object *obj )
+{
+ struct open_call *open = (struct open_call *)obj;
- return !ioctl->device; /* device is cleared once the ioctl has completed */
+ call_object_destroy( &open->call );
+}
+
+static struct open_call *create_open( struct device *device, unsigned int access,
+ unsigned int sharing, unsigned int options )
+{
+ struct open_call *open;
+
+ if ((open = alloc_object( &open_call_ops )))
+ {
+ open->call.type = CALL_OPEN;
+ open->call.device = (struct device *)grab_object( device );
+ open->access = access;
+ open->sharing = sharing;
+ open->options = options;
+ }
+ return ioctl;
+}
+
+static void complete_open( struct open_call *open, unsigned int status )
+{
+ struct device *device = open->device;
+
+ if (!device) return; /* already finished */
+
+ open->call.status = status;
+ resume_thread( current );
+
+ /* remove it from the device queue */
+ list_remove( &open->call.dev_entry );
+ release_object( open ); /* no longer on the device queue */
+}
+
+
+static void ioctl_call_dump( struct object *obj, int verbose )
+{
+ struct ioctl_call *ioctl = (struct ioctl_call *)obj;
+ fprintf( stderr, "Ioctl call code=%08x device=%p\n", ioctl->code, ioctl->cal.device );
}
static void ioctl_call_destroy( struct object *obj )
@@ -184,8 +278,7 @@ static void ioctl_call_destroy( struct object *obj )
async_terminate( ioctl->async, STATUS_CANCELLED );
release_object( ioctl->async );
}
- if (ioctl->device) release_object( ioctl->device );
- release_object( ioctl->thread );
+ call_object_destroy( &ioctl->call );
}
static struct ioctl_call *create_ioctl( struct device *device, ioctl_code_t code,
@@ -196,14 +289,15 @@ static struct ioctl_call *create_ioctl( struct device *device, ioctl_code_t code
if ((ioctl = alloc_object( &ioctl_call_ops )))
{
- ioctl->device = (struct device *)grab_object( device );
- ioctl->code = code;
- ioctl->async = NULL;
- ioctl->status = STATUS_PENDING;
- ioctl->in_size = in_size;
- ioctl->in_data = NULL;
- ioctl->out_size = out_size;
- ioctl->out_data = NULL;
+ ioctl->call.type = CALL_IOCTL;
+ ioctl->call.device = (struct device *)grab_object( device );
+ ioctl->code = code;
+ ioctl->async = NULL;
+ ioctl->call.status = STATUS_PENDING;
+ ioctl->in_size = in_size;
+ ioctl->in_data = NULL;
+ ioctl->out_size = out_size;
+ ioctl->out_data = NULL;
if (ioctl->in_size && !(ioctl->in_data = memdup( in_data, in_size )))
{
@@ -222,7 +316,7 @@ static void set_ioctl_result( struct ioctl_call *ioctl, unsigned int status,
if (!device) return; /* already finished */
/* FIXME: handle the STATUS_PENDING case */
- ioctl->status = status;
+ ioctl->call.status = status;
ioctl->out_size = min( ioctl->out_size, out_size );
if (ioctl->out_size && !(ioctl->out_data = memdup( out_data, ioctl->out_size )))
ioctl->out_size = 0;
@@ -273,12 +367,12 @@ static struct fd *device_get_fd( struct object *obj )
static void device_destroy( struct object *obj )
{
struct device *device = (struct device *)obj;
- struct ioctl_call *ioctl, *next;
+ struct call_object *obj, *next;
- LIST_FOR_EACH_ENTRY_SAFE( ioctl, next, &device->requests, struct ioctl_call, dev_entry )
+ LIST_FOR_EACH_ENTRY_SAFE( obj, next, &device->requests, struct call_object, dev_entry )
{
- list_remove( &ioctl->dev_entry );
- release_object( ioctl ); /* no longer on the device queue */
+ list_remove( &obj->dev_entry );
+ release_object( obj ); /* no longer on the device queue */
}
if (device->fd) release_object( device->fd );
if (device->manager) list_remove( &device->entry );
@@ -287,6 +381,26 @@ static void device_destroy( struct object *obj )
static struct object *device_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options )
{
+ struct device *device = (struct device *)obj;
+ struct open_call *open;
+
+ if (!device->manager) /* it has been deleted */
+ {
+ set_error( STATUS_FILE_DELETED );
+ return 0;
+ }
+
+ /* create an open request */
+ if (!(open = create_open( device, access, sharing, options )))
+ return NULL;
+ open->call.thread = current;
+ suspend_thread( current );
+
+ list_add_tail( &device->requests, &open->call.dev_entry );
+ list_add_tail( &device->manager->requests, &open->call.mgr_entry );
+ if (list_head( &device->manager->requests ) == &open->call.mgr_entry) /* first one */
+ wake_up( &device->manager->obj, 0 );
+
return grab_object( obj );
}
@@ -298,10 +412,10 @@ static enum server_fd_type device_get_fd_type( struct fd *fd )
static struct ioctl_call *find_ioctl_call( struct device *device, struct thread *thread,
client_ptr_t user_arg )
{
- struct ioctl_call *ioctl;
+ struct call_object *ioctl;
- LIST_FOR_EACH_ENTRY( ioctl, &device->requests, struct ioctl_call, dev_entry )
- if (ioctl->thread == thread && ioctl->user_arg == user_arg) return ioctl;
+ LIST_FOR_EACH_ENTRY( ioctl, &device->requests, struct call_object, dev_entry )
+ if (ioctl->thread == thread && ioctl->user_arg == user_arg && ioctl->type == CALL_IOCTL) return (struct ioctl_call *)ioctl;
set_error( STATUS_INVALID_PARAMETER );
return NULL;
@@ -323,8 +437,8 @@ static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_
if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() )))
return 0;
- ioctl->thread = (struct thread *)grab_object( current );
- ioctl->user_arg = async_data->arg;
+ ioctl->call.thread = (struct thread *)grab_object( current );
+ ioctl->call.user_arg = async_data->arg;
if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 )))
{
@@ -482,9 +596,11 @@ DECL_HANDLER(delete_device)
}
-/* retrieve the next pending device ioctl request */
+/* retrieve the next pending device request */
DECL_HANDLER(get_next_device_request)
{
+ struct call_object *call;
+ struct open_call *open;
struct ioctl_call *ioctl;
struct device_manager *manager;
struct list *ptr;
@@ -502,24 +618,46 @@ DECL_HANDLER(get_next_device_request)
close_handle( current->process, req->prev ); /* avoid an extra round-trip for close */
release_object( ioctl );
}
+ if ((open = (struct open_call *)get_handle_obj( current->process, req->prev,
+ 0, &open_call_ops )))
+ {
+ complete_open( open, req->status );
+ close_handle( current->process, req->prev ); /* avoid an extra round-trip for close */
+ release_object( open );
+ }
clear_error();
}
if ((ptr = list_head( &manager->requests )))
{
- ioctl = LIST_ENTRY( ptr, struct ioctl_call, mgr_entry );
- reply->code = ioctl->code;
- reply->user_ptr = ioctl->device->user_ptr;
- reply->in_size = ioctl->in_size;
- reply->out_size = ioctl->out_size;
- if (ioctl->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
- else if ((reply->next = alloc_handle( current->process, ioctl, 0, 0 )))
+ call = LIST_ENTRY( ptr, struct call_object, mgr_entry );
+ reply->user_ptr = call->device->user_ptr;
+ switch (call->type)
{
- set_reply_data_ptr( ioctl->in_data, ioctl->in_size );
- ioctl->in_data = NULL;
- ioctl->in_size = 0;
- list_remove( &ioctl->mgr_entry );
- list_init( &ioctl->mgr_entry );
+ case CALL_OPEN:
+ open = (struct ioctl_call *)call;
+ reply->data.open.access = open->access;
+ reply->data.open.sharing = open->sharing;
+ reply->data.open.options = open->options;
+ if ((reply->next = alloc_handle( current->process, open, 0, 0 )))
+ {
+ list_remove( &call->mgr_entry );
+ list_init( &call->mgr_entry );
+ }
+ case CALL_IOCTL:
+ ioctl = (struct ioctl_call *)call;
+ reply->data.ioctl.code = ioctl->code;
+ reply->data.ioctl.in_size = ioctl->in_size;
+ reply->data.ioctl.out_size = ioctl->out_size;
+ if (ioctl->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
+ else if ((reply->next = alloc_handle( current->process, ioctl, 0, 0 )))
+ {
+ set_reply_data_ptr( ioctl->in_data, ioctl->in_size );
+ ioctl->in_data = NULL;
+ ioctl->in_size = 0;
+ list_remove( &call->mgr_entry );
+ list_init( &call->mgr_entry );
+ }
}
}
else set_error( STATUS_PENDING );
diff --git a/server/protocol.def b/server/protocol.def
index a0e1702..e554112 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3102,18 +3102,39 @@ enum message_type
@END
-/* Retrieve the next pending device ioctl request */
+enum server_call_type
+{
+ CALL_OPEN,
+ CALL_IOCTL
+};
+
+union next_request
+{
+ struct
+ {
+ ioctl_code_t code; /* ioctl code */
+ data_size_t in_size; /* total needed input size */
+ data_size_t out_size; /* needed output size */
+ } ioctl;
+ struct
+ {
+ unsigned int access;
+ unsigned int sharing;
+ unsigned int options;
+ } open;
+};
+
+/* Retrieve the next pending device request */
@REQ(get_next_device_request)
obj_handle_t manager; /* handle to the device manager */
- obj_handle_t prev; /* handle to the previous ioctl */
- unsigned int status; /* status of the previous ioctl */
+ obj_handle_t prev; /* handle to the previous request */
+ unsigned int status; /* status of the previous request */
VARARG(prev_data,bytes); /* output data of the previous ioctl */
@REPLY
- obj_handle_t next; /* handle to the next ioctl */
- ioctl_code_t code; /* ioctl code */
+ obj_handle_t next; /* handle to the next request */
+ enum server_call_type type; /* type of this request */
client_ptr_t user_ptr; /* opaque ptr for the device */
- data_size_t in_size; /* total needed input size */
- data_size_t out_size; /* needed output size */
+ union next_request data; /* data associated with the next request */
VARARG(next_data,bytes); /* input data of the next ioctl */
@END
diff --git a/server/thread.c b/server/thread.c
index f45be24..a1b4120 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -474,7 +474,7 @@ void stop_thread( struct thread *thread )
}
/* suspend a thread */
-static int suspend_thread( struct thread *thread )
+int suspend_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
@@ -486,7 +486,7 @@ static int suspend_thread( struct thread *thread )
}
/* resume a thread */
-static int resume_thread( struct thread *thread )
+int resume_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend > 0)
Nov. 2, 2009
Re: [PATCH 0/3] Handling DOS drives in mountmgr (try 2)
by Charles Davis
Alexandre Julliard wrote:
> Charles Davis <cdavis(a)mymail.mines.edu> writes:
>
>> I thought I fixed all the issues. What's wrong with my patches now?
>
> Many things, it's a lot more complicated than that. For instance you
> can't just kill the fstab support, this needs to be preserved somehow,
> probably on the mountmgr side. Also you can't have a single file
> descriptor per device, you need one for each open.
>
OK, I can do that.
I've decided to do the open in mountmgr, so I can have it handle changes
to the fstab while it's running. So, I'm working on implementing
IRP_MJ_CREATE support (which is the standard way for drivers to handle
open requests). I've attached a first stab at that. Can you take a look?
I'm pretty sure there's something I'm missing.
BTW, I'm on #winehackers as I write this (my nick is cdavis5x).
Chip
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 93d72a6..3ad1284 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -142,6 +142,56 @@ static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs )
return EXCEPTION_CONTINUE_SEARCH;
}
+/* process an open request for a given device */
+static NTSTATUS process_open( DEVICE_OBJECT *device, ULONG access, ULONG sharing,
+ ULONG options )
+{
+ IRP irp;
+ IO_STACK_LOCATION irpsp;
+ IO_SECURITY_CONTEXT security;
+ PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_CREATE];
+ NTSTATUS status;
+ LARGE_INTEGER count;
+
+ TRACE( "open device %p access %x sharing %x options %x\n", device, access,
+ access, sharing, options );
+
+ /* so we can spot things that we should initialize */
+ memset( &irp, 0x55, sizeof(irp) );
+ memset( &irpsp, 0x66, sizeof(irpsp) );
+ memset( &security, 0x77, sizeof(security) );
+
+ irp.RequestorMode = UserMode;
+ irp.Tail.Overlay.s.u.CurrentStackLocation = &irpsp;
+ irp.UserIosb = NULL;
+
+ irpsp.MajorFunction = IRP_MJ_CREATE;
+ irpsp.Create.SecurityContext = &security;
+ security.DesiredAccess = access;
+ irpsp.Create.Options = options;
+ irpsp.Create.ShareAccess = sharing;
+ irpsp.DeviceObject = device;
+ irpsp.CompletionRoutine = NULL;
+
+ device->CurrentIrp = &irp;
+
+ KeQueryTickCount( &count ); /* update the global KeTickCount */
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
+ GetCurrentThreadId(), dispatch, device, &irp );
+
+ status = dispatch( device, &irp );
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
+ GetCurrentThreadId(), dispatch, device, &irp, status );
+
+ *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
+ return irp.IoStatus.u.Status;
+
+}
+
/* process an ioctl request for a given device */
static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
void *out_buff, ULONG *out_size )
@@ -206,12 +256,14 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
{
HANDLE manager = get_device_manager();
- obj_handle_t ioctl = 0;
+ obj_handle_t call = 0;
+ enum server_call_type type = CALL_OPEN;
NTSTATUS status = STATUS_SUCCESS;
ULONG code = 0;
void *in_buff, *out_buff = NULL;
DEVICE_OBJECT *device = NULL;
ULONG in_size = 4096, out_size = 0;
+ ULONG access, sharing, options;
HANDLE handles[2];
if (!(in_buff = HeapAlloc( GetProcessHeap(), 0, in_size )))
@@ -228,21 +280,35 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
SERVER_START_REQ( get_next_device_request )
{
req->manager = wine_server_obj_handle( manager );
- req->prev = ioctl;
+ req->prev = call;
req->status = status;
- wine_server_add_data( req, out_buff, out_size );
- wine_server_set_reply( req, in_buff, in_size );
+ if (type == CALL_IOCTL)
+ {
+ wine_server_add_data( req, out_buff, out_size );
+ wine_server_set_reply( req, in_buff, in_size );
+ }
if (!(status = wine_server_call( req )))
{
- code = reply->code;
- ioctl = reply->next;
+ call = reply->next;
+ type = reply->type;
device = wine_server_get_ptr( reply->user_ptr );
- in_size = reply->in_size;
- out_size = reply->out_size;
+ switch(type)
+ {
+ case CALL_OPEN:
+ access = reply->data.open.access;
+ sharing = reply->data.open.sharing;
+ options = reply->data.open.options;
+ break;
+ case CALL_IOCTL:
+ code = reply->data.ioctl.code;
+ in_size = reply->data.ioctl.in_size;
+ out_size = reply->data.ioctl.out_size;
+ break;
+ }
}
else
{
- ioctl = 0; /* no previous ioctl */
+ call = 0; /* no previous call */
out_size = 0;
in_size = reply->in_size;
}
@@ -255,7 +321,15 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
HeapFree( GetProcessHeap(), 0, out_buff );
if (out_size) out_buff = HeapAlloc( GetProcessHeap(), 0, out_size );
else out_buff = NULL;
- status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
+ switch(type)
+ {
+ case CALL_OPEN:
+ status = process_open( device, access, sharing, options );
+ break;
+ case CALL_IOCTL:
+ status = process_ioctl( device, code, in_buff, in_size, out_buff, &out_size );
+ break;
+ }
break;
case STATUS_BUFFER_OVERFLOW:
HeapFree( GetProcessHeap(), 0, in_buff );
diff --git a/server/device.c b/server/device.c
index 4d134a3..cc772c9 100644
--- a/server/device.c
+++ b/server/device.c
@@ -33,17 +33,61 @@
#include "handle.h"
#include "request.h"
-struct ioctl_call
+int suspend_thread( struct thread *thread );
+int resume_thread( struct thread *thread );
+
+struct call_object
{
struct object obj; /* object header */
+ enum server_call_type type; /* type of driver call */
struct list dev_entry; /* entry in device queue */
struct list mgr_entry; /* entry in manager queue */
- struct device *device; /* device containing this ioctl */
- struct thread *thread; /* thread that queued the ioctl */
+ struct device *device; /* device being opened */
+ struct thread *thread; /* thread that opened the device */
client_ptr_t user_arg; /* user arg used to identify the request */
+ unsigned int status; /* resulting status (or STATUS_PENDING) */
+};
+
+static int call_object_signaled( struct object *obj, struct thread *thread );
+static void call_object_destroy( struct object *obj );
+
+struct open_call
+{
+ struct call_object call; /* object header */
+ unsigned int access; /* desired access */
+ unsigned int sharing; /* desired sharing */
+ unsigned int options; /* create options */
+};
+
+static void open_call_dump( struct object *obj, int verbose );
+static void open_call_destroy( struct object *obj );
+
+static const struct object_ops open_call_ops =
+{
+ sizeof(struct open_call), /* size */
+ open_call_dump, /* dump */
+ no_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ call_object_signaled, /* signaled */
+ no_satisfied, /* satisfied */
+ no_signal, /* signal */
+ no_get_fd, /* get_fd */
+ no_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ open_call_destroy /* destroy */
+};
+
+
+struct ioctl_call
+{
+ struct call_object obj; /* object header */
struct async *async; /* pending async op */
ioctl_code_t code; /* ioctl code */
- unsigned int status; /* resulting status (or STATUS_PENDING) */
data_size_t in_size; /* size of input data */
void *in_data; /* input data */
data_size_t out_size; /* size of output data */
@@ -51,7 +95,6 @@ struct ioctl_call
};
static void ioctl_call_dump( struct object *obj, int verbose );
-static int ioctl_call_signaled( struct object *obj, struct thread *thread );
static void ioctl_call_destroy( struct object *obj );
static const struct object_ops ioctl_call_ops =
@@ -61,7 +104,7 @@ static const struct object_ops ioctl_call_ops =
no_get_type, /* get_type */
add_queue, /* add_queue */
remove_queue, /* remove_queue */
- ioctl_call_signaled, /* signaled */
+ call_object_signaled, /* signaled */
no_satisfied, /* satisfied */
no_signal, /* signal */
no_get_fd, /* get_fd */
@@ -160,17 +203,68 @@ static const struct fd_ops device_fd_ops =
};
-static void ioctl_call_dump( struct object *obj, int verbose )
+static int call_object_signaled( struct object *obj, struct thread *thread )
{
- struct ioctl_call *ioctl = (struct ioctl_call *)obj;
- fprintf( stderr, "Ioctl call code=%08x device=%p\n", ioctl->code, ioctl->device );
+ struct call_object *call = (struct call_object *)obj;
+
+ return !call->device; /* device is cleared once the ioctl has completed */
}
-static int ioctl_call_signaled( struct object *obj, struct thread *thread )
+static void call_object_destroy( struct call_object *obj )
{
- struct ioctl_call *ioctl = (struct ioctl_call *)obj;
+ if (obj->device) release_object( obj->device );
+ release_object( obj->thread );
+}
+
+
+static void open_call_dump( struct object *obj, int verbose )
+{
+ struct open_call *open = (struct open_call *)obj;
+ fprintf( stderr, "Open call device=%p\n", open->call.device );
+}
+
+static void open_call_destroy( struct object *obj )
+{
+ struct open_call *open = (struct open_call *)obj;
- return !ioctl->device; /* device is cleared once the ioctl has completed */
+ call_object_destroy( &open->call );
+}
+
+static struct open_call *create_open( struct device *device, unsigned int access,
+ unsigned int sharing, unsigned int options )
+{
+ struct open_call *open;
+
+ if ((open = alloc_object( &open_call_ops )))
+ {
+ open->call.type = CALL_OPEN;
+ open->call.device = (struct device *)grab_object( device );
+ open->access = access;
+ open->sharing = sharing;
+ open->options = options;
+ }
+ return ioctl;
+}
+
+static void complete_open( struct open_call *open, unsigned int status )
+{
+ struct device *device = open->device;
+
+ if (!device) return; /* already finished */
+
+ open->call.status = status;
+ resume_thread( current );
+
+ /* remove it from the device queue */
+ list_remove( &open->call.dev_entry );
+ release_object( open ); /* no longer on the device queue */
+}
+
+
+static void ioctl_call_dump( struct object *obj, int verbose )
+{
+ struct ioctl_call *ioctl = (struct ioctl_call *)obj;
+ fprintf( stderr, "Ioctl call code=%08x device=%p\n", ioctl->code, ioctl->cal.device );
}
static void ioctl_call_destroy( struct object *obj )
@@ -184,8 +278,7 @@ static void ioctl_call_destroy( struct object *obj )
async_terminate( ioctl->async, STATUS_CANCELLED );
release_object( ioctl->async );
}
- if (ioctl->device) release_object( ioctl->device );
- release_object( ioctl->thread );
+ call_object_destroy( &ioctl->call );
}
static struct ioctl_call *create_ioctl( struct device *device, ioctl_code_t code,
@@ -196,14 +289,15 @@ static struct ioctl_call *create_ioctl( struct device *device, ioctl_code_t code
if ((ioctl = alloc_object( &ioctl_call_ops )))
{
- ioctl->device = (struct device *)grab_object( device );
- ioctl->code = code;
- ioctl->async = NULL;
- ioctl->status = STATUS_PENDING;
- ioctl->in_size = in_size;
- ioctl->in_data = NULL;
- ioctl->out_size = out_size;
- ioctl->out_data = NULL;
+ ioctl->call.type = CALL_IOCTL;
+ ioctl->call.device = (struct device *)grab_object( device );
+ ioctl->code = code;
+ ioctl->async = NULL;
+ ioctl->call.status = STATUS_PENDING;
+ ioctl->in_size = in_size;
+ ioctl->in_data = NULL;
+ ioctl->out_size = out_size;
+ ioctl->out_data = NULL;
if (ioctl->in_size && !(ioctl->in_data = memdup( in_data, in_size )))
{
@@ -222,7 +316,7 @@ static void set_ioctl_result( struct ioctl_call *ioctl, unsigned int status,
if (!device) return; /* already finished */
/* FIXME: handle the STATUS_PENDING case */
- ioctl->status = status;
+ ioctl->call.status = status;
ioctl->out_size = min( ioctl->out_size, out_size );
if (ioctl->out_size && !(ioctl->out_data = memdup( out_data, ioctl->out_size )))
ioctl->out_size = 0;
@@ -273,12 +367,12 @@ static struct fd *device_get_fd( struct object *obj )
static void device_destroy( struct object *obj )
{
struct device *device = (struct device *)obj;
- struct ioctl_call *ioctl, *next;
+ struct call_object *obj, *next;
- LIST_FOR_EACH_ENTRY_SAFE( ioctl, next, &device->requests, struct ioctl_call, dev_entry )
+ LIST_FOR_EACH_ENTRY_SAFE( obj, next, &device->requests, struct call_object, dev_entry )
{
- list_remove( &ioctl->dev_entry );
- release_object( ioctl ); /* no longer on the device queue */
+ list_remove( &obj->dev_entry );
+ release_object( obj ); /* no longer on the device queue */
}
if (device->fd) release_object( device->fd );
if (device->manager) list_remove( &device->entry );
@@ -287,6 +381,26 @@ static void device_destroy( struct object *obj )
static struct object *device_open_file( struct object *obj, unsigned int access,
unsigned int sharing, unsigned int options )
{
+ struct device *device = (struct device *)obj;
+ struct open_call *open;
+
+ if (!device->manager) /* it has been deleted */
+ {
+ set_error( STATUS_FILE_DELETED );
+ return 0;
+ }
+
+ /* create an open request */
+ if (!(open = create_open( device, access, sharing, options )))
+ return NULL;
+ open->call.thread = current;
+ suspend_thread( current );
+
+ list_add_tail( &device->requests, &open->call.dev_entry );
+ list_add_tail( &device->manager->requests, &open->call.mgr_entry );
+ if (list_head( &device->manager->requests ) == &open->call.mgr_entry) /* first one */
+ wake_up( &device->manager->obj, 0 );
+
return grab_object( obj );
}
@@ -298,10 +412,10 @@ static enum server_fd_type device_get_fd_type( struct fd *fd )
static struct ioctl_call *find_ioctl_call( struct device *device, struct thread *thread,
client_ptr_t user_arg )
{
- struct ioctl_call *ioctl;
+ struct call_object *ioctl;
- LIST_FOR_EACH_ENTRY( ioctl, &device->requests, struct ioctl_call, dev_entry )
- if (ioctl->thread == thread && ioctl->user_arg == user_arg) return ioctl;
+ LIST_FOR_EACH_ENTRY( ioctl, &device->requests, struct call_object, dev_entry )
+ if (ioctl->thread == thread && ioctl->user_arg == user_arg && ioctl->type == CALL_IOCTL) return (struct ioctl_call *)ioctl;
set_error( STATUS_INVALID_PARAMETER );
return NULL;
@@ -323,8 +437,8 @@ static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_
if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() )))
return 0;
- ioctl->thread = (struct thread *)grab_object( current );
- ioctl->user_arg = async_data->arg;
+ ioctl->call.thread = (struct thread *)grab_object( current );
+ ioctl->call.user_arg = async_data->arg;
if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 )))
{
@@ -482,9 +596,11 @@ DECL_HANDLER(delete_device)
}
-/* retrieve the next pending device ioctl request */
+/* retrieve the next pending device request */
DECL_HANDLER(get_next_device_request)
{
+ struct call_object *call;
+ struct open_call *open;
struct ioctl_call *ioctl;
struct device_manager *manager;
struct list *ptr;
@@ -502,24 +618,46 @@ DECL_HANDLER(get_next_device_request)
close_handle( current->process, req->prev ); /* avoid an extra round-trip for close */
release_object( ioctl );
}
+ if ((open = (struct open_call *)get_handle_obj( current->process, req->prev,
+ 0, &open_call_ops )))
+ {
+ complete_open( open, req->status );
+ close_handle( current->process, req->prev ); /* avoid an extra round-trip for close */
+ release_object( open );
+ }
clear_error();
}
if ((ptr = list_head( &manager->requests )))
{
- ioctl = LIST_ENTRY( ptr, struct ioctl_call, mgr_entry );
- reply->code = ioctl->code;
- reply->user_ptr = ioctl->device->user_ptr;
- reply->in_size = ioctl->in_size;
- reply->out_size = ioctl->out_size;
- if (ioctl->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
- else if ((reply->next = alloc_handle( current->process, ioctl, 0, 0 )))
+ call = LIST_ENTRY( ptr, struct call_object, mgr_entry );
+ reply->user_ptr = call->device->user_ptr;
+ switch (call->type)
{
- set_reply_data_ptr( ioctl->in_data, ioctl->in_size );
- ioctl->in_data = NULL;
- ioctl->in_size = 0;
- list_remove( &ioctl->mgr_entry );
- list_init( &ioctl->mgr_entry );
+ case CALL_OPEN:
+ open = (struct ioctl_call *)call;
+ reply->data.open.access = open->access;
+ reply->data.open.sharing = open->sharing;
+ reply->data.open.options = open->options;
+ if ((reply->next = alloc_handle( current->process, open, 0, 0 )))
+ {
+ list_remove( &call->mgr_entry );
+ list_init( &call->mgr_entry );
+ }
+ case CALL_IOCTL:
+ ioctl = (struct ioctl_call *)call;
+ reply->data.ioctl.code = ioctl->code;
+ reply->data.ioctl.in_size = ioctl->in_size;
+ reply->data.ioctl.out_size = ioctl->out_size;
+ if (ioctl->in_size > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
+ else if ((reply->next = alloc_handle( current->process, ioctl, 0, 0 )))
+ {
+ set_reply_data_ptr( ioctl->in_data, ioctl->in_size );
+ ioctl->in_data = NULL;
+ ioctl->in_size = 0;
+ list_remove( &call->mgr_entry );
+ list_init( &call->mgr_entry );
+ }
}
}
else set_error( STATUS_PENDING );
diff --git a/server/protocol.def b/server/protocol.def
index a0e1702..e554112 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3102,18 +3102,39 @@ enum message_type
@END
-/* Retrieve the next pending device ioctl request */
+enum server_call_type
+{
+ CALL_OPEN,
+ CALL_IOCTL
+};
+
+union next_request
+{
+ struct
+ {
+ ioctl_code_t code; /* ioctl code */
+ data_size_t in_size; /* total needed input size */
+ data_size_t out_size; /* needed output size */
+ } ioctl;
+ struct
+ {
+ unsigned int access;
+ unsigned int sharing;
+ unsigned int options;
+ } open;
+};
+
+/* Retrieve the next pending device request */
@REQ(get_next_device_request)
obj_handle_t manager; /* handle to the device manager */
- obj_handle_t prev; /* handle to the previous ioctl */
- unsigned int status; /* status of the previous ioctl */
+ obj_handle_t prev; /* handle to the previous request */
+ unsigned int status; /* status of the previous request */
VARARG(prev_data,bytes); /* output data of the previous ioctl */
@REPLY
- obj_handle_t next; /* handle to the next ioctl */
- ioctl_code_t code; /* ioctl code */
+ obj_handle_t next; /* handle to the next request */
+ enum server_call_type type; /* type of this request */
client_ptr_t user_ptr; /* opaque ptr for the device */
- data_size_t in_size; /* total needed input size */
- data_size_t out_size; /* needed output size */
+ union next_request data; /* data associated with the next request */
VARARG(next_data,bytes); /* input data of the next ioctl */
@END
diff --git a/server/thread.c b/server/thread.c
index f45be24..a1b4120 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -474,7 +474,7 @@ void stop_thread( struct thread *thread )
}
/* suspend a thread */
-static int suspend_thread( struct thread *thread )
+int suspend_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
@@ -486,7 +486,7 @@ static int suspend_thread( struct thread *thread )
}
/* resume a thread */
-static int resume_thread( struct thread *thread )
+int resume_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend > 0)
Nov. 2, 2009
Re: mciwave: Fix copy&paste errors and remove superfluous log.
by Paul Vriens
On 11/02/2009 02:56 PM, Joerg-Cyril.Hoehle(a)t-systems.com wrote:
> Hi,
>
> - shareable is neither supported nor implemented by waveaudio (other MCIxyz support it);
> Let mciOpen supply the same error code as MS-Windows.
> - volatile dwPosition is recommended as the recorder thread callback updates it
> (sometimes I think the whole structure should be declared volatile).
> - WARN after ExitThread is superfluous (and not present in most other code)
> -- should be ERR if at all.
> - TRACE of wave format parameters is a duplicate and already logged a few lines earlier.
> - TRUE (1) is not a valid return code in MMSYSTEM.
> - INPUT/OUTPUTUNSPECIFIED is a typical example of copy&paste error.
>
> Later I'll fix the same in the other MCIxyz libraries (mcicda, mcimidi and mciwave are very similar, mciavi is different). I plan to patch the former 3 only.
>
> Regards,
> Jörg Höhle
>
Hi Jörg,
Doesn't the fact that you list 6 fixes mean you need to split up this patch?
--
Cheers,
Paul.
Nov. 2, 2009
Re: Remove NoAppDBEntry keyword?
by Jerome Leclanche
+1 on removing it.
It would be nice to have a bugzilla filter to replace it, too.
Are we keeping "tasklist" and "tasklet" keywords as well? theres
barely a dozen very old bugs for both of them.
J. Leclanche / Adys
On Mon, Nov 2, 2009 at 1:45 AM, Austin English <austinenglish(a)gmail.com> wrote:
> Anyone opposed to removing that keyword?
>
> --
> -Austin
>
>
>
Nov. 2, 2009
Nov. 1, 2009
Re: Errors using Wordpad from Wine 1.1.6 after applying this patch
by James McKenzie
Reece Dunn wrote:
> 2009/11/1 James McKenzie <jjmckenzie51(a)earthlink.net>:
>
>> All:
>>
>> I've been attempting to bring Tony Rollo's EM_FORMATRANGE patch up to
>> date and got to Wine 1.1.6. At the suggestion of Dylan Smith, I have
>> been using Wordpad to test the patch after adding a little test because
>> of poor display on the Print Preview. However, I've run into two what
>> appears to be separate 'bugs'. The first occurs when I attempt to
>> change the font size, I get an error "Invalid Number Format". The
>> second is that I can change the displayed font one and only one time.
>> I've reversed both of Andrey Turkin's patches that were applied between
>> wine-1.1.5 and wine-1.1.6 but this did not resolve the error message and
>> the inability to change fonts and actually introduced a possible third
>> error where the font name is distorted where it shows a series of blocks
>> and some other unintelligible data in the font display field on the screen.
>>
>
> Have you done a git bisect to locate the commits that introduced the error?
>
>
Yes. And that is part of the problem, the wrong commit was marked as
causing the error. I had to remove the next up commit and then the
problem went away.
> Have you tried proceeding to 1.1.32/latest git to check if the errors
> have been fixed (1.1.6 is old)?
>
I am working from 0.9.54 forward. There are many, many, many changes to
richedit since that release. I may now have a patch that will work with
Wine 1.1.6 and now I'm moving forward to 1.1.7.
> Do you get the error without the patch? If not, have you verified that
> the patch is correct (to the new wine behaviour)
>
Yes. The error exists without the patch. This is why I have two other
programs that I'm using as well.
> Have you tried running the trace logging (with at least richedit and gdi32)?
>
Yes. The continuing problem I have is with the display of Print
Preview. The fonts are WAY too big on the display screen.
That is the next thing to tackle after I get the patch up to and
installed on Wine-1.1.32 (or whatever release is out there when I finish.)
The bad commit that I found is c53b772394bb193169af7d55653cbd1576ff0807
and it is one of Andrey Turkin's. I will check the archives to see if
it was pulled. Failing that, maybe Andrey can provide pointers that
will make the patch better and fit in with the whole
richedit/wordpad/gdi32 concept that has been worked on quite a bit in
the last year.
James McKenzie
Nov. 1, 2009
msi: Initialize string pointer to NULL
by Kirill K. Smirnov
Hi Nathan,
>+ haystack_table_name = NULL;
> r = table->ops->get_column_info( table, i, &col_name, NULL,
> NULL, &haystack_table_name );
> if( r != ERROR_SUCCESS )
I'm afraid, but this patch silences valgrind only, but does not solves the
problem. It seems to me, that if table->ops->get_column_info() succeeds, it
initializes haystack_table_name, and if it fails, we do not use
haystack_table_name at all (we immediately return from this function). Thus,
the problem lies somewhere in get_column_info().
So it is useless (and harmful, because it confuses valgrind) to initialize it
like this.
--
Kirill
Nov. 1, 2009
Re: [1/5] WineD3D: Add a parameter for SetRenderTarget viewport setup
by Stefan Dösinger
Am 01.11.2009 um 13:28 schrieb Stefan Dösinger:
> <0001-WineD3D-SetRT-viewport-param.txt>
Please use the other [1/5] patch - this one has a wrong patch
description in the file
Nov. 1, 2009
Re: Errors using Wordpad from Wine 1.1.6 after applying this patch
by Reece Dunn
2009/11/1 James McKenzie <jjmckenzie51(a)earthlink.net>:
> All:
>
> I've been attempting to bring Tony Rollo's EM_FORMATRANGE patch up to
> date and got to Wine 1.1.6. At the suggestion of Dylan Smith, I have
> been using Wordpad to test the patch after adding a little test because
> of poor display on the Print Preview. However, I've run into two what
> appears to be separate 'bugs'. The first occurs when I attempt to
> change the font size, I get an error "Invalid Number Format". The
> second is that I can change the displayed font one and only one time.
> I've reversed both of Andrey Turkin's patches that were applied between
> wine-1.1.5 and wine-1.1.6 but this did not resolve the error message and
> the inability to change fonts and actually introduced a possible third
> error where the font name is distorted where it shows a series of blocks
> and some other unintelligible data in the font display field on the screen.
Have you done a git bisect to locate the commits that introduced the error?
Have you tried proceeding to 1.1.32/latest git to check if the errors
have been fixed (1.1.6 is old)?
Do you get the error without the patch? If not, have you verified that
the patch is correct (to the new wine behaviour)?
Have you tried running the trace logging (with at least richedit and gdi32)?
- Reece
Nov. 1, 2009
Errors using Wordpad from Wine 1.1.6 after applying this patch
by James McKenzie
All:
I've been attempting to bring Tony Rollo's EM_FORMATRANGE patch up to
date and got to Wine 1.1.6. At the suggestion of Dylan Smith, I have
been using Wordpad to test the patch after adding a little test because
of poor display on the Print Preview. However, I've run into two what
appears to be separate 'bugs'. The first occurs when I attempt to
change the font size, I get an error "Invalid Number Format". The
second is that I can change the displayed font one and only one time.
I've reversed both of Andrey Turkin's patches that were applied between
wine-1.1.5 and wine-1.1.6 but this did not resolve the error message and
the inability to change fonts and actually introduced a possible third
error where the font name is distorted where it shows a series of blocks
and some other unintelligible data in the font display field on the screen.
Any ideas on why this is happening?
Patch attached with debugging code.
James McKenzie
Oct. 31, 2009