It is quite rare to have more than one or two of these, and lists are slightly easier to work with.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/pnp.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 6652be73c47..913a63e8f0d 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -42,6 +42,7 @@ #include "wine/exception.h" #include "wine/heap.h" #include "wine/rbtree.h" +#include "wine/list.h"
#include "ntoskrnl_private.h" #include "plugplay.h" @@ -923,20 +924,25 @@ static DRIVER_OBJECT *pnp_manager; struct root_pnp_device { WCHAR id[MAX_DEVICE_ID_LEN]; - struct wine_rb_entry entry; + struct list entry; DEVICE_OBJECT *device; };
-static int root_pnp_devices_rb_compare( const void *key, const struct wine_rb_entry *entry ) +static struct list root_pnp_devices = LIST_INIT(root_pnp_devices); + +static struct root_pnp_device *find_root_pnp_device( const WCHAR *id ) { - const struct root_pnp_device *device = WINE_RB_ENTRY_VALUE( entry, const struct root_pnp_device, entry ); - const WCHAR *k = key; + struct root_pnp_device *device;
- return wcsicmp( k, device->id ); + LIST_FOR_EACH_ENTRY( device, &root_pnp_devices, struct root_pnp_device, entry ) + { + if (!wcsicmp( id, device->id )) + return device; + } + + return NULL; }
-static struct wine_rb_tree root_pnp_devices = { root_pnp_devices_rb_compare }; - static NTSTATUS WINAPI pnp_manager_device_pnp( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); @@ -1043,15 +1049,12 @@ void pnp_manager_start(void) ERR("RpcBindingFromStringBinding() failed, error %#x\n", err); }
-static void destroy_root_pnp_device( struct wine_rb_entry *entry, void *context ) -{ - struct root_pnp_device *device = WINE_RB_ENTRY_VALUE(entry, struct root_pnp_device, entry); - remove_device( device->device ); -} - void pnp_manager_stop(void) { - wine_rb_destroy( &root_pnp_devices, destroy_root_pnp_device, NULL ); + struct root_pnp_device *device, *next; + + LIST_FOR_EACH_ENTRY_SAFE( device, next, &root_pnp_devices, struct root_pnp_device, entry ) + remove_device( device->device ); IoDeleteDriver( pnp_manager ); RpcBindingFree( &plugplay_binding_handle ); } @@ -1088,7 +1091,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL );
- if (wine_rb_get( &root_pnp_devices, id )) + if (find_root_pnp_device( id )) continue;
TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id)); @@ -1103,12 +1106,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - if (wine_rb_put( &root_pnp_devices, id, &pnp_device->entry )) - { - ERR("Failed to insert device %s into tree.\n", debugstr_w(id)); - IoDeleteDevice( device ); - continue; - } + list_add_tail( &root_pnp_devices, &pnp_device->entry );
start_device( device, set, &sp_device ); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 19 +++++++++++++++---- dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e578e51de68..278bc8677e6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2409,6 +2409,18 @@ void CDECL wined3d_device_context_draw(struct wined3d_device_context *context, u 0, start_vertex, vertex_count, start_instance, instance_count, false); }
+void CDECL wined3d_device_context_draw_indexed(struct wined3d_device_context *context, int base_vertex_index, + unsigned int start_index, unsigned int index_count, unsigned int start_instance, unsigned int instance_count) +{ + struct wined3d_state *state = context->state; + + TRACE("context %p, base_vertex_index %d, start_index %u, index_count %u, start_instance %u, instance_count %u.\n", + context, base_vertex_index, start_index, index_count, start_instance, instance_count); + + wined3d_device_context_emit_draw(context, state->primitive_type, state->patch_vertex_count, + base_vertex_index, start_index, index_count, start_instance, instance_count, true); +} + void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { TRACE("device %p, shader %p.\n", device, shader); @@ -4486,8 +4498,7 @@ void CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device,
TRACE("device %p, start_idx %u, index_count %u.\n", device, start_idx, index_count);
- wined3d_device_context_emit_draw(&device->cs->c, state->primitive_type, state->patch_vertex_count, - state->base_vertex_index, start_idx, index_count, 0, 0, true); + wined3d_device_context_draw_indexed(&device->cs->c, state->base_vertex_index, start_idx, index_count, 0, 0); }
void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device, @@ -4498,8 +4509,8 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device TRACE("device %p, start_idx %u, index_count %u, start_instance %u, instance_count %u.\n", device, start_idx, index_count, start_instance, instance_count);
- wined3d_device_context_emit_draw(&device->cs->c, state->primitive_type, state->patch_vertex_count, - state->base_vertex_index, start_idx, index_count, start_instance, instance_count, true); + wined3d_device_context_draw_indexed(&device->cs->c, state->base_vertex_index, + start_idx, index_count, start_instance, instance_count); }
void CDECL wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 087a6bead13..bae5a6d42f0 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -167,6 +167,7 @@ @ cdecl wined3d_device_validate_device(ptr ptr)
@ cdecl wined3d_device_context_draw(ptr long long long long) +@ cdecl wined3d_device_context_draw_indexed(ptr long long long long long) @ cdecl wined3d_device_context_dispatch(ptr long long long) @ cdecl wined3d_device_context_dispatch_indirect(ptr ptr long) @ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 3316d6f6653..ee02914b0fe 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2562,6 +2562,8 @@ void __cdecl wined3d_device_context_dispatch_indirect(struct wined3d_device_cont struct wined3d_buffer *buffer, unsigned int offset); void __cdecl wined3d_device_context_draw(struct wined3d_device_context *context, unsigned int start_vertex, unsigned int vertex_count, unsigned int start_instance, unsigned int instance_count); +void __cdecl wined3d_device_context_draw_indexed(struct wined3d_device_context *context, int base_vertex_index, + unsigned int start_index, unsigned int index_count, unsigned int start_instance, unsigned int instance_count); void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_context *context, struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask); void __cdecl wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index f154bfdf480..685551c014c 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -576,14 +576,14 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_VSSetShader(ID3D11DeviceCo static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexed(ID3D11DeviceContext1 *iface, UINT index_count, UINT start_index_location, INT base_vertex_location) { - struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface);
TRACE("iface %p, index_count %u, start_index_location %u, base_vertex_location %d.\n", iface, index_count, start_index_location, base_vertex_location);
wined3d_mutex_lock(); - wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); - wined3d_device_draw_indexed_primitive(device->wined3d_device, start_index_location, index_count); + wined3d_device_context_draw_indexed(context->wined3d_context, + base_vertex_location, start_index_location, index_count, 0, 0); wined3d_mutex_unlock(); }
@@ -704,7 +704,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstanced(ID3D1 UINT instance_index_count, UINT instance_count, UINT start_index_location, INT base_vertex_location, UINT start_instance_location) { - struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface);
TRACE("iface %p, instance_index_count %u, instance_count %u, start_index_location %u, " "base_vertex_location %d, start_instance_location %u.\n", @@ -712,9 +712,8 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstanced(ID3D1 base_vertex_location, start_instance_location);
wined3d_mutex_lock(); - wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); - wined3d_device_draw_indexed_primitive_instanced(device->wined3d_device, start_index_location, - instance_index_count, start_instance_location, instance_count); + wined3d_device_context_draw_indexed(context->wined3d_context, base_vertex_location, + start_index_location, instance_index_count, start_instance_location, instance_count); wined3d_mutex_unlock(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 52 +++++++++++++++------------- dlls/ntoskrnl.exe/ntoskrnl_private.h | 26 ++++++++++++++ dlls/ntoskrnl.exe/pnp.c | 37 ++++++++------------ dlls/ntoskrnl.exe/sync.c | 19 +++------- 4 files changed, 71 insertions(+), 63 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 685f7d4345b..1ddd3f4d4f0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -21,34 +21,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <stdarg.h> #include <assert.h>
#define NONAMELESSUNION #define NONAMELESSSTRUCT
-#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winsvc.h" -#include "winternl.h" +#include "ntoskrnl_private.h" #include "excpt.h" -#include "winioctl.h" -#include "winbase.h" #include "winreg.h" #include "ntsecapi.h" #include "ddk/csq.h" -#include "ddk/ntddk.h" -#include "ddk/ntifs.h" -#include "ddk/wdm.h" #include "wine/server.h" -#include "wine/debug.h" #include "wine/heap.h" -#include "wine/rbtree.h" #include "wine/svcctl.h"
-#include "ntoskrnl_private.h" - WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); WINE_DECLARE_DEBUG_CHANNEL(relay);
@@ -90,14 +76,6 @@ static void *ldr_notify_cookie; static PLOAD_IMAGE_NOTIFY_ROUTINE load_image_notify_routines[8]; static unsigned int load_image_notify_routine_count;
-struct wine_driver -{ - DRIVER_OBJECT driver_obj; - DRIVER_EXTENSION driver_extension; - SERVICE_STATUS_HANDLE service_handle; - struct wine_rb_entry entry; -}; - static int wine_drivers_rb_compare( const void *key, const struct wine_rb_entry *entry ) { const struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, const struct wine_driver, entry ); @@ -110,6 +88,24 @@ static struct wine_rb_tree wine_drivers = { wine_drivers_rb_compare };
DECLARE_CRITICAL_SECTION(drivers_cs);
+struct wine_driver *get_driver( const WCHAR *name ) +{ + static const WCHAR driverW[] = L"\Driver\"; + struct wine_rb_entry *entry; + UNICODE_STRING drv_name; + + drv_name.Length = (wcslen( driverW ) + wcslen( name )) * sizeof(WCHAR); + if (!(drv_name.Buffer = malloc( drv_name.Length + sizeof(WCHAR) ))) + return NULL; + wcscpy( drv_name.Buffer, driverW ); + wcscat( drv_name.Buffer, name ); + entry = wine_rb_get( &wine_drivers, &drv_name ); + free( drv_name.Buffer ); + + if (entry) return WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry ); + return NULL; +} + static HANDLE get_device_manager(void) { static HANDLE device_manager; @@ -902,6 +898,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) HANDLE manager = get_device_manager(); struct dispatch_context context; NTSTATUS status = STATUS_SUCCESS; + struct wine_driver *driver; HANDLE handles[2];
context.handle = NULL; @@ -983,9 +980,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
done: /* Native PnP drivers expect that all of their devices will be removed when - * their unload routine is called, so we must stop the PnP manager first. */ - pnp_manager_stop(); + * their unload routine is called. Moreover, we cannot unload a module + * until we have removed devices for all lower drivers, so we have to stop + * all devices first, and then unload all drivers. */ + WINE_RB_FOR_EACH_ENTRY( driver, &wine_drivers, struct wine_driver, entry ) + pnp_manager_stop_driver( driver ); wine_rb_destroy( &wine_drivers, unload_driver, NULL ); + pnp_manager_stop(); return status; }
@@ -1486,6 +1487,7 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName ); for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) driver->driver_obj.MajorFunction[i] = unhandled_irp; + list_init( &driver->root_pnp_devices );
EnterCriticalSection( &drivers_cs ); if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index a1e1b892e8c..c0b588f3135 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -21,7 +21,21 @@ #ifndef __WINE_NTOSKRNL_PRIVATE_H #define __WINE_NTOSKRNL_PRIVATE_H
+#include <stdarg.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winioctl.h" +#include "winbase.h" +#include "winsvc.h" +#include "winternl.h" +#include "ddk/ntifs.h" +#include "ddk/wdm.h" + #include "wine/asm.h" +#include "wine/debug.h" +#include "wine/list.h" +#include "wine/rbtree.h"
static inline LPCSTR debugstr_us( const UNICODE_STRING *us ) { @@ -76,12 +90,24 @@ extern POBJECT_TYPE SeTokenObjectType; 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \ static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
+struct wine_driver +{ + DRIVER_OBJECT driver_obj; + DRIVER_EXTENSION driver_extension; + SERVICE_STATUS_HANDLE service_handle; + struct wine_rb_entry entry; + struct list root_pnp_devices; +}; + void ObReferenceObject( void *obj ) DECLSPEC_HIDDEN;
void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) DECLSPEC_HIDDEN; void pnp_manager_start(void) DECLSPEC_HIDDEN; +void pnp_manager_stop_driver( struct wine_driver *driver ) DECLSPEC_HIDDEN; void pnp_manager_stop(void) DECLSPEC_HIDDEN;
+struct wine_driver *get_driver( const WCHAR *name ) DECLSPEC_HIDDEN; + static const WCHAR servicesW[] = {'\','R','e','g','i','s','t','r','y', '\','M','a','c','h','i','n','e', '\','S','y','s','t','e','m', diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 913a63e8f0d..dce6bb90c68 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -20,31 +20,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <stdarg.h> - #define NONAMELESSUNION
-#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winbase.h" -#include "winioctl.h" +#include "ntoskrnl_private.h" #include "winreg.h" #include "winuser.h" -#include "winsvc.h" -#include "winternl.h" #include "setupapi.h" #include "cfgmgr32.h" #include "dbt.h" -#include "ddk/wdm.h" -#include "ddk/ntifs.h" -#include "wine/debug.h" #include "wine/exception.h" #include "wine/heap.h" -#include "wine/rbtree.h" -#include "wine/list.h"
-#include "ntoskrnl_private.h" #include "plugplay.h"
#include "initguid.h" @@ -928,13 +914,11 @@ struct root_pnp_device DEVICE_OBJECT *device; };
-static struct list root_pnp_devices = LIST_INIT(root_pnp_devices); - -static struct root_pnp_device *find_root_pnp_device( const WCHAR *id ) +static struct root_pnp_device *find_root_pnp_device( struct wine_driver *driver, const WCHAR *id ) { struct root_pnp_device *device;
- LIST_FOR_EACH_ENTRY( device, &root_pnp_devices, struct root_pnp_device, entry ) + LIST_FOR_EACH_ENTRY( device, &driver->root_pnp_devices, struct root_pnp_device, entry ) { if (!wcsicmp( id, device->id )) return device; @@ -1049,12 +1033,16 @@ void pnp_manager_start(void) ERR("RpcBindingFromStringBinding() failed, error %#x\n", err); }
-void pnp_manager_stop(void) +void pnp_manager_stop_driver( struct wine_driver *driver ) { struct root_pnp_device *device, *next;
- LIST_FOR_EACH_ENTRY_SAFE( device, next, &root_pnp_devices, struct root_pnp_device, entry ) + LIST_FOR_EACH_ENTRY_SAFE( device, next, &driver->root_pnp_devices, struct root_pnp_device, entry ) remove_device( device->device ); +} + +void pnp_manager_stop(void) +{ IoDeleteDriver( pnp_manager ); RpcBindingFree( &plugplay_binding_handle ); } @@ -1066,6 +1054,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN]; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; struct root_pnp_device *pnp_device; + struct wine_driver *driver; DEVICE_OBJECT *device; NTSTATUS status; unsigned int i; @@ -1073,6 +1062,8 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
TRACE("Searching for new root-enumerated devices for driver %s.\n", debugstr_w(driver_name));
+ driver = get_driver( driver_name ); + set = SetupDiGetClassDevsW( NULL, rootW, NULL, DIGCF_ALLCLASSES ); if (set == INVALID_HANDLE_VALUE) { @@ -1091,7 +1082,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL );
- if (find_root_pnp_device( id )) + if (find_root_pnp_device( driver, id )) continue;
TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id)); @@ -1106,7 +1097,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - list_add_tail( &root_pnp_devices, &pnp_device->entry ); + list_add_tail( &driver->root_pnp_devices, &pnp_device->entry );
start_device( device, set, &sp_device ); } diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 2aa60a0f2a0..445c8d890ab 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -19,23 +19,12 @@ */
#include <limits.h> -#include <stdarg.h> - -#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winbase.h" -#include "winternl.h" -#include "ddk/ntddk.h" -#include "ddk/wdm.h" -#include "ddk/ntifs.h" - -#include "wine/asm.h" -#include "wine/debug.h" -#include "wine/heap.h" -#include "wine/server.h"
#include "ntoskrnl_private.h" +#include "ddk/ntddk.h" + +#include "wine/heap.h" +#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 16 ++++++++-------- dlls/wined3d/device.c | 10 ++-------- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 3 --- include/wine/wined3d.h | 3 +++ 5 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index cbc97d3614a..ef3c0c76c14 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1072,17 +1072,17 @@ void wined3d_device_context_emit_draw(struct wined3d_device_context *context, wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, enum wined3d_primitive_type primitive_type, - unsigned int patch_vertex_count, struct wined3d_buffer *buffer, unsigned int offset, bool indexed) +void CDECL wined3d_device_context_draw_indirect(struct wined3d_device_context *context, + struct wined3d_buffer *buffer, unsigned int offset, bool indexed) { - const struct wined3d_d3d_info *d3d_info = &cs->c.device->adapter->d3d_info; - const struct wined3d_state *state = cs->c.state; + const struct wined3d_d3d_info *d3d_info = &context->device->adapter->d3d_info; + const struct wined3d_state *state = context->state; struct wined3d_cs_draw *op;
- op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DRAW; - op->primitive_type = primitive_type; - op->patch_vertex_count = patch_vertex_count; + op->primitive_type = state->primitive_type; + op->patch_vertex_count = state->patch_vertex_count; op->parameters.indirect = TRUE; op->parameters.u.indirect.buffer = buffer; op->parameters.u.indirect.offset = offset; @@ -1091,7 +1091,7 @@ void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, enum wined3d_primitive acquire_graphics_pipeline_resources(state, indexed, d3d_info); wined3d_resource_acquire(&buffer->resource);
- wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
static void wined3d_cs_exec_flush(struct wined3d_cs *cs, const void *data) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 278bc8677e6..3b22f7b2086 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4484,12 +4484,9 @@ void CDECL wined3d_device_draw_primitive_instanced(struct wined3d_device *device void CDECL wined3d_device_draw_primitive_instanced_indirect(struct wined3d_device *device, struct wined3d_buffer *buffer, unsigned int offset) { - struct wined3d_state *state = device->cs->c.state; - TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
- wined3d_cs_emit_draw_indirect(device->cs, state->primitive_type, - state->patch_vertex_count, buffer, offset, false); + wined3d_device_context_draw_indirect(&device->cs->c, buffer, offset, false); }
void CDECL wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count) @@ -4516,12 +4513,9 @@ void CDECL wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device void CDECL wined3d_device_draw_indexed_primitive_instanced_indirect(struct wined3d_device *device, struct wined3d_buffer *buffer, unsigned int offset) { - struct wined3d_state *state = device->cs->c.state; - TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
- wined3d_cs_emit_draw_indirect(device->cs, state->primitive_type, - state->patch_vertex_count, buffer, offset, true); + wined3d_device_context_draw_indirect(&device->cs->c, buffer, offset, true); }
HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index bae5a6d42f0..918e9e253cc 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -168,6 +168,7 @@
@ cdecl wined3d_device_context_draw(ptr long long long long) @ cdecl wined3d_device_context_draw_indexed(ptr long long long long long) +@ cdecl wined3d_device_context_draw_indirect(ptr ptr long long) @ cdecl wined3d_device_context_dispatch(ptr long long long) @ cdecl wined3d_device_context_dispatch_indirect(ptr ptr long) @ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e9e73da9f25..db6b6488e59 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4735,9 +4735,6 @@ void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) DECLSPEC_HIDDEN; void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav) DECLSPEC_HIDDEN; -void wined3d_cs_emit_draw_indirect(struct wined3d_cs *cs, enum wined3d_primitive_type primitive_type, - unsigned int patch_vertex_count, struct wined3d_buffer *buffer, - unsigned int offset, bool indexed) DECLSPEC_HIDDEN; void wined3d_cs_emit_flush(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_generate_mipmaps(struct wined3d_cs *cs, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ee02914b0fe..18dab157834 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -26,6 +26,7 @@ #ifndef __WINE_WINED3D_H #define __WINE_WINED3D_H
+#include <stdbool.h> #include "wine/list.h"
#define WINED3D_OK S_OK @@ -2564,6 +2565,8 @@ void __cdecl wined3d_device_context_draw(struct wined3d_device_context *context, unsigned int vertex_count, unsigned int start_instance, unsigned int instance_count); void __cdecl wined3d_device_context_draw_indexed(struct wined3d_device_context *context, int base_vertex_index, unsigned int start_index, unsigned int index_count, unsigned int start_instance, unsigned int instance_count); +void __cdecl wined3d_device_context_draw_indirect(struct wined3d_device_context *context, + struct wined3d_buffer *buffer, unsigned int offset, bool indexed); void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_context *context, struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask); void __cdecl wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 2 +- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 + dlls/ntoskrnl.exe/ntoskrnl_private.h | 3 ++- dlls/ntoskrnl.exe/pnp.c | 23 +++++++++++++++++++---- programs/winedevice/device.c | 6 ++++++ 5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 1ddd3f4d4f0..bb9f4bf5259 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3824,7 +3824,7 @@ NTSTATUS WINAPI ZwLoadDriver( const UNICODE_STRING *service_name ) driver = WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry ); driver->service_handle = service_handle;
- pnp_manager_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) ); + wine_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) );
set_service_status( service_handle, SERVICE_RUNNING, SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ); diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 0f5ab76a195..6dea87f347b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -1686,3 +1686,4 @@ # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
@ cdecl wine_ntoskrnl_main_loop(long) +@ cdecl wine_enumerate_root_devices(wstr) diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index c0b588f3135..c736a9805a0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -101,11 +101,12 @@ struct wine_driver
void ObReferenceObject( void *obj ) DECLSPEC_HIDDEN;
-void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) DECLSPEC_HIDDEN; void pnp_manager_start(void) DECLSPEC_HIDDEN; void pnp_manager_stop_driver( struct wine_driver *driver ) DECLSPEC_HIDDEN; void pnp_manager_stop(void) DECLSPEC_HIDDEN;
+void CDECL wine_enumerate_root_devices( const WCHAR *driver_name ); + struct wine_driver *get_driver( const WCHAR *name ) DECLSPEC_HIDDEN;
static const WCHAR servicesW[] = {'\','R','e','g','i','s','t','r','y', diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index dce6bb90c68..7994a8b85b9 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -1047,13 +1047,14 @@ void pnp_manager_stop(void) RpcBindingFree( &plugplay_binding_handle ); }
-void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) +void CDECL wine_enumerate_root_devices( const WCHAR *driver_name ) { static const WCHAR driverW[] = {'\','D','r','i','v','e','r','\',0}; static const WCHAR rootW[] = {'R','O','O','T',0}; WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN]; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - struct root_pnp_device *pnp_device; + struct list new_list = LIST_INIT(new_list); + struct root_pnp_device *pnp_device, *next; struct wine_driver *driver; DEVICE_OBJECT *device; NTSTATUS status; @@ -1082,8 +1083,13 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL );
- if (find_root_pnp_device( driver, id )) + if ((pnp_device = find_root_pnp_device( driver, id ))) + { + TRACE("Found device %s already enumerated.\n", debugstr_w(id)); + list_remove( &pnp_device->entry ); + list_add_tail( &new_list, &pnp_device->entry ); continue; + }
TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id));
@@ -1097,10 +1103,19 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - list_add_tail( &driver->root_pnp_devices, &pnp_device->entry ); + list_add_tail( &new_list, &pnp_device->entry );
start_device( device, set, &sp_device ); }
+ LIST_FOR_EACH_ENTRY_SAFE( pnp_device, next, &driver->root_pnp_devices, struct root_pnp_device, entry ) + { + TRACE("Removing device %s.\n", debugstr_w(pnp_device->id)); + + remove_device( pnp_device->device ); + } + + list_move_head( &driver->root_pnp_devices, &new_list ); + SetupDiDestroyDeviceInfoList(set); } diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c index 3acc5e8a799..509cab96308 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedevice); static const WCHAR servicesW[] = L"\Registry\Machine\System\CurrentControlSet\Services\";
extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ); +extern void CDECL wine_enumerate_root_devices( const WCHAR *driver_name );
static WCHAR winedeviceW[] = L"winedevice"; static SERVICE_STATUS_HANDLE service_handle; @@ -55,6 +56,8 @@ static void set_service_status( SERVICE_STATUS_HANDLE handle, DWORD state, DWORD SetServiceStatus( handle, &status ); }
+#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128 + static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name ) { UNICODE_STRING service_name; @@ -78,6 +81,9 @@ static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name ) result = RtlNtStatusToDosError(ZwUnloadDriver( &service_name )); break;
+ case SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES: + wine_enumerate_root_devices( driver_name ); + default: FIXME( "got driver ctrl %x for %s\n", ctrl, wine_dbgstr_w(driver_name) ); break;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 685551c014c..3b1c42fc592 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1082,7 +1082,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_DrawAuto(ID3D11DeviceConte static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstancedIndirect(ID3D11DeviceContext1 *iface, ID3D11Buffer *buffer, UINT offset) { - struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); struct d3d_buffer *d3d_buffer;
TRACE("iface %p, buffer %p, offset %u.\n", iface, buffer, offset); @@ -1090,15 +1090,14 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_DrawIndexedInstancedIndire d3d_buffer = unsafe_impl_from_ID3D11Buffer(buffer);
wined3d_mutex_lock(); - wined3d_device_draw_indexed_primitive_instanced_indirect(device->wined3d_device, - d3d_buffer->wined3d_buffer, offset); + wined3d_device_context_draw_indirect(context->wined3d_context, d3d_buffer->wined3d_buffer, offset, true); wined3d_mutex_unlock(); }
static void STDMETHODCALLTYPE d3d11_immediate_context_DrawInstancedIndirect(ID3D11DeviceContext1 *iface, ID3D11Buffer *buffer, UINT offset) { - struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + struct d3d11_immediate_context *context = impl_from_ID3D11DeviceContext1(iface); struct d3d_buffer *d3d_buffer;
TRACE("iface %p, buffer %p, offset %u.\n", iface, buffer, offset); @@ -1106,8 +1105,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_DrawInstancedIndirect(ID3D d3d_buffer = unsafe_impl_from_ID3D11Buffer(buffer);
wined3d_mutex_lock(); - wined3d_device_draw_primitive_instanced_indirect(device->wined3d_device, - d3d_buffer->wined3d_buffer, offset); + wined3d_device_context_draw_indirect(context->wined3d_context, d3d_buffer->wined3d_buffer, offset, false); wined3d_mutex_unlock(); }
If the service is already running, starting it has no effect.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index de0413e74f5..0a396cc8464 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -104,6 +104,8 @@ static const WCHAR AddInterface[] = {'A','d','d','I','n','t','e','r','f','a','c' static const WCHAR backslashW[] = {'\',0}; static const WCHAR emptyW[] = {0};
+#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128 + struct driver { WCHAR inf_path[MAX_PATH]; @@ -5123,13 +5125,20 @@ BOOL WINAPI SetupDiInstallDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) if (!wcsnicmp(device->instanceId, rootW, lstrlenW(rootW)) && svc_name[0] && (manager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT))) { - if ((service = OpenServiceW(manager, svc_name, SERVICE_START))) + if ((service = OpenServiceW(manager, svc_name, SERVICE_START | SERVICE_USER_DEFINED_CONTROL))) { + SERVICE_STATUS status; + if (!StartServiceW(service, 0, NULL) && GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { ERR("Failed to start service %s for device %s, error %u.\n", debugstr_w(svc_name), debugstr_w(device->instanceId), GetLastError()); } + if (!ControlService(service, SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES, &status)) + { + ERR("Failed to control service %s for device %s, error %u.\n", + debugstr_w(svc_name), debugstr_w(device->instanceId), GetLastError()); + } CloseServiceHandle(service); } else
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 71 +++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 34 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 3b1c42fc592..2738ff1a5bd 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -4382,7 +4382,7 @@ static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]);
- wined3d_device_set_constant_buffer(device->wined3d_device, type, start_slot + i, + wined3d_device_context_set_constant_buffer(device->immediate_context.wined3d_context, type, start_slot + i, buffer ? buffer->wined3d_buffer : NULL); } wined3d_mutex_unlock(); @@ -4412,8 +4412,8 @@ static void STDMETHODCALLTYPE d3d10_device_PSSetShaderResources(ID3D10Device1 *i { struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]);
- wined3d_device_set_ps_resource_view(device->wined3d_device, start_slot + i, - view ? view->wined3d_view : NULL); + wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_PIXEL, start_slot + i, view ? view->wined3d_view : NULL); } wined3d_mutex_unlock(); } @@ -4427,7 +4427,8 @@ static void STDMETHODCALLTYPE d3d10_device_PSSetShader(ID3D10Device1 *iface, TRACE("iface %p, shader %p\n", iface, shader);
wined3d_mutex_lock(); - wined3d_device_set_pixel_shader(device->wined3d_device, ps ? ps->wined3d_shader : NULL); + wined3d_device_context_set_shader(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_PIXEL, ps ? ps->wined3d_shader : NULL); wined3d_mutex_unlock(); }
@@ -4445,8 +4446,8 @@ static void STDMETHODCALLTYPE d3d10_device_PSSetSamplers(ID3D10Device1 *iface, { struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]);
- wined3d_device_set_ps_sampler(device->wined3d_device, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); + wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_PIXEL, start_slot + i, sampler ? sampler->wined3d_sampler : NULL); } wined3d_mutex_unlock(); } @@ -4460,7 +4461,8 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetShader(ID3D10Device1 *iface, TRACE("iface %p, shader %p\n", iface, shader);
wined3d_mutex_lock(); - wined3d_device_set_vertex_shader(device->wined3d_device, vs ? vs->wined3d_shader : NULL); + wined3d_device_context_set_shader(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_VERTEX, vs ? vs->wined3d_shader : NULL); wined3d_mutex_unlock(); }
@@ -4473,8 +4475,8 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexed(ID3D10Device1 *iface, UIN iface, index_count, start_index_location, base_vertex_location);
wined3d_mutex_lock(); - wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); - wined3d_device_draw_indexed_primitive(device->wined3d_device, start_index_location, index_count); + wined3d_device_context_draw_indexed(device->immediate_context.wined3d_context, + base_vertex_location, start_index_location, index_count, 0, 0); wined3d_mutex_unlock(); }
@@ -4487,7 +4489,7 @@ static void STDMETHODCALLTYPE d3d10_device_Draw(ID3D10Device1 *iface, UINT verte iface, vertex_count, start_vertex_location);
wined3d_mutex_lock(); - wined3d_device_draw_primitive(device->wined3d_device, start_vertex_location, vertex_count); + wined3d_device_context_draw(device->immediate_context.wined3d_context, start_vertex_location, vertex_count, 0, 0); wined3d_mutex_unlock(); }
@@ -4510,7 +4512,7 @@ static void STDMETHODCALLTYPE d3d10_device_IASetInputLayout(ID3D10Device1 *iface TRACE("iface %p, input_layout %p\n", iface, input_layout);
wined3d_mutex_lock(); - wined3d_device_set_vertex_declaration(device->wined3d_device, + wined3d_device_context_set_vertex_declaration(device->immediate_context.wined3d_context, layout ? layout->wined3d_decl : NULL); wined3d_mutex_unlock(); } @@ -4529,7 +4531,7 @@ static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *ifa { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]);
- wined3d_device_set_stream_source(device->wined3d_device, start_slot + i, + wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); } wined3d_mutex_unlock(); @@ -4545,7 +4547,7 @@ static void STDMETHODCALLTYPE d3d10_device_IASetIndexBuffer(ID3D10Device1 *iface iface, buffer, debug_dxgi_format(format), offset);
wined3d_mutex_lock(); - wined3d_device_set_index_buffer(device->wined3d_device, + wined3d_device_context_set_index_buffer(device->immediate_context.wined3d_context, buffer_impl ? buffer_impl->wined3d_buffer : NULL, wined3dformat_from_dxgi_format(format), offset); wined3d_mutex_unlock(); @@ -4563,9 +4565,8 @@ static void STDMETHODCALLTYPE d3d10_device_DrawIndexedInstanced(ID3D10Device1 *i base_vertex_location, start_instance_location);
wined3d_mutex_lock(); - wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_location); - wined3d_device_draw_indexed_primitive_instanced(device->wined3d_device, start_index_location, - instance_index_count, start_instance_location, instance_count); + wined3d_device_context_draw_indexed(device->immediate_context.wined3d_context, base_vertex_location, + start_index_location, instance_index_count, start_instance_location, instance_count); wined3d_mutex_unlock(); }
@@ -4580,7 +4581,7 @@ static void STDMETHODCALLTYPE d3d10_device_DrawInstanced(ID3D10Device1 *iface, start_vertex_location, start_instance_location);
wined3d_mutex_lock(); - wined3d_device_draw_primitive_instanced(device->wined3d_device, start_vertex_location, + wined3d_device_context_draw(device->immediate_context.wined3d_context, start_vertex_location, instance_vertex_count, start_instance_location, instance_count); wined3d_mutex_unlock(); } @@ -4603,7 +4604,8 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetShader(ID3D10Device1 *iface, ID3 TRACE("iface %p, shader %p.\n", iface, shader);
wined3d_mutex_lock(); - wined3d_device_set_geometry_shader(device->wined3d_device, gs ? gs->wined3d_shader : NULL); + wined3d_device_context_set_shader(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_GEOMETRY, gs ? gs->wined3d_shader : NULL); wined3d_mutex_unlock(); }
@@ -4633,8 +4635,8 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device1 *i { struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]);
- wined3d_device_set_vs_resource_view(device->wined3d_device, start_slot + i, - view ? view->wined3d_view : NULL); + wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_VERTEX, start_slot + i, view ? view->wined3d_view : NULL); } wined3d_mutex_unlock(); } @@ -4653,8 +4655,8 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetSamplers(ID3D10Device1 *iface, { struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]);
- wined3d_device_set_vs_sampler(device->wined3d_device, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); + wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_VERTEX, start_slot + i, sampler ? sampler->wined3d_sampler : NULL); } wined3d_mutex_unlock(); } @@ -4668,7 +4670,8 @@ static void STDMETHODCALLTYPE d3d10_device_SetPredication(ID3D10Device1 *iface,
query = unsafe_impl_from_ID3D10Query((ID3D10Query *)predicate); wined3d_mutex_lock(); - wined3d_device_set_predication(device->wined3d_device, query ? query->wined3d_query : NULL, value); + wined3d_device_context_set_predication(device->immediate_context.wined3d_context, + query ? query->wined3d_query : NULL, value); wined3d_mutex_unlock(); }
@@ -4686,8 +4689,8 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetShaderResources(ID3D10Device1 *i { struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]);
- wined3d_device_set_gs_resource_view(device->wined3d_device, start_slot + i, - view ? view->wined3d_view : NULL); + wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, + WINED3D_SHADER_TYPE_GEOMETRY, start_slot + i, view ? view->wined3d_view : NULL); } wined3d_mutex_unlock(); } @@ -4706,8 +4709,8 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetSamplers(ID3D10Device1 *iface, { struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]);
- wined3d_device_set_gs_sampler(device->wined3d_device, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); + wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, WINED3D_SHADER_TYPE_GEOMETRY, + start_slot + i, sampler ? sampler->wined3d_sampler : NULL); } wined3d_mutex_unlock(); } @@ -4728,16 +4731,16 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *ifa { struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D10RenderTargetView(render_target_views[i]);
- wined3d_device_set_rendertarget_view(device->wined3d_device, i, + wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, rtv ? rtv->wined3d_view : NULL, FALSE); } for (; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) { - wined3d_device_set_rendertarget_view(device->wined3d_device, i, NULL, FALSE); + wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, NULL, FALSE); }
dsv = unsafe_impl_from_ID3D10DepthStencilView(depth_stencil_view); - wined3d_device_set_depth_stencil_view(device->wined3d_device, + wined3d_device_context_set_depth_stencil_view(device->immediate_context.wined3d_context, dsv ? dsv->wined3d_view : NULL); wined3d_mutex_unlock(); } @@ -4784,13 +4787,13 @@ static void STDMETHODCALLTYPE d3d10_device_SOSetTargets(ID3D10Device1 *iface, { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(targets[i]);
- wined3d_device_set_stream_output(device->wined3d_device, i, + wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, buffer ? buffer->wined3d_buffer : NULL, offsets[i]); }
for (i = count; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i) { - wined3d_device_set_stream_output(device->wined3d_device, i, NULL, 0); + wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, NULL, 0); } wined3d_mutex_unlock(); } @@ -4835,7 +4838,7 @@ static void STDMETHODCALLTYPE d3d10_device_RSSetViewports(ID3D10Device1 *iface, }
wined3d_mutex_lock(); - wined3d_device_set_viewports(device->wined3d_device, viewport_count, wined3d_vp); + wined3d_device_context_set_viewports(device->immediate_context.wined3d_context, viewport_count, wined3d_vp); wined3d_mutex_unlock(); }
@@ -4850,7 +4853,7 @@ static void STDMETHODCALLTYPE d3d10_device_RSSetScissorRects(ID3D10Device1 *ifac return;
wined3d_mutex_lock(); - wined3d_device_set_scissor_rects(device->wined3d_device, rect_count, rects); + wined3d_device_context_set_scissor_rects(device->immediate_context.wined3d_context, rect_count, rects); wined3d_mutex_unlock(); }
Allow them to be unloaded.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 0a396cc8464..8f826c30250 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -19,6 +19,7 @@ */
#include <stdarg.h> +#include <stdlib.h>
#include "windef.h" #include "winbase.h" @@ -1692,15 +1693,38 @@ BOOL WINAPI SetupDiRegisterDeviceInfo(HDEVINFO devinfo, SP_DEVINFO_DATA *device_ */ BOOL WINAPI SetupDiRemoveDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) { + SC_HANDLE manager = NULL, service = NULL; struct device *device; + WCHAR *service_name; + DWORD size;
TRACE("devinfo %p, device_data %p.\n", devinfo, device_data);
if (!(device = get_device(devinfo, device_data))) return FALSE;
+ if (!(manager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT))) + return FALSE; + + if (!RegGetValueW(device->key, NULL, L"Service", RRF_RT_REG_SZ, NULL, NULL, &size)) + { + service_name = malloc(size); + if (!RegGetValueW(device->key, NULL, L"Service", RRF_RT_REG_SZ, NULL, service_name, &size)) + service = OpenServiceW(manager, service_name, SERVICE_USER_DEFINED_CONTROL); + free(service_name); + } + remove_device(device);
+ if (service) + { + SERVICE_STATUS status; + if (!ControlService(service, SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES, &status)) + ERR("Failed to control service %s, error %u.\n", debugstr_w(service_name), GetLastError()); + CloseServiceHandle(service); + } + CloseServiceHandle(manager); + return TRUE; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index c3ebe5b8ee1..e65dac38cec 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -43,6 +43,7 @@ static HANDLE device; static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *); static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *); static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, @@ -939,16 +940,23 @@ START_TEST(ntoskrnl) WCHAR filename[MAX_PATH], filename2[MAX_PATH]; struct testsign_context ctx; SC_HANDLE service, service2; + BOOL ret, is_wow64; DWORD written; - BOOL ret;
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U"); pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString"); pCancelIoEx = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx"); + pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetFileCompletionNotificationModes"); pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign");
+ if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) + { + skip("Running in WoW64.\n"); + return; + } + if (!testsign_create_cert(&ctx)) return;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/tests/Makefile.in | 6 +- dlls/ntoskrnl.exe/tests/driver_pnp.c | 143 +++++++++++++++ dlls/ntoskrnl.exe/tests/driver_pnp.spec | 1 + dlls/ntoskrnl.exe/tests/ntoskrnl.c | 226 ++++++++++++++++++++++++ 4 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 dlls/ntoskrnl.exe/tests/driver_pnp.c create mode 100644 dlls/ntoskrnl.exe/tests/driver_pnp.spec
diff --git a/dlls/ntoskrnl.exe/tests/Makefile.in b/dlls/ntoskrnl.exe/tests/Makefile.in index 4b2052d43f4..c799dfcaf77 100644 --- a/dlls/ntoskrnl.exe/tests/Makefile.in +++ b/dlls/ntoskrnl.exe/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = ntoskrnl.exe -IMPORTS = advapi32 crypt32 wintrust ws2_32 +IMPORTS = advapi32 crypt32 newdev setupapi wintrust ws2_32
driver_IMPORTS = winecrt0 ntoskrnl driver_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native @@ -9,6 +9,8 @@ driver3_IMPORTS = winecrt0 ntoskrnl driver3_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native driver4_IMPORTS = winecrt0 ntoskrnl netio driver4_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native +driver_pnp_IMPORTS = winecrt0 ntoskrnl +driver_pnp_EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -Wl,--subsystem,native
SOURCES = \ driver.c \ @@ -19,4 +21,6 @@ SOURCES = \ driver3.spec \ driver4.c \ driver4.spec \ + driver_pnp.c \ + driver_pnp.spec \ ntoskrnl.c diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c new file mode 100644 index 00000000000..53403d2fa7b --- /dev/null +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -0,0 +1,143 @@ +/* + * ntoskrnl.exe testing framework + * + * Copyright 2020 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "winioctl.h" +#include "ddk/wdm.h" + +#include "driver.h" + +static const GUID control_class = {0xdeadbeef, 0x29ef, 0x4538, {0xa5, 0xfd, 0xb6, 0x95, 0x73, 0xa3, 0x62, 0xc0}}; +static UNICODE_STRING control_symlink; + +static DEVICE_OBJECT *bus_fdo, *bus_pdo; + +static NTSTATUS fdo_pnp(IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + NTSTATUS ret; + + switch (stack->MinorFunction) + { + case IRP_MN_START_DEVICE: + irp->IoStatus.Status = IoSetDeviceInterfaceState(&control_symlink, TRUE); + break; + + case IRP_MN_SURPRISE_REMOVAL: + irp->IoStatus.Status = STATUS_SUCCESS; + break; + + case IRP_MN_REMOVE_DEVICE: + IoSetDeviceInterfaceState(&control_symlink, FALSE); + irp->IoStatus.Status = STATUS_SUCCESS; + IoSkipCurrentIrpStackLocation(irp); + ret = IoCallDriver(bus_pdo, irp); + IoDetachDevice(bus_pdo); + IoDeleteDevice(bus_fdo); + RtlFreeUnicodeString(&control_symlink); + return ret; + } + + IoSkipCurrentIrpStackLocation(irp); + return IoCallDriver(bus_pdo, irp); +} + +static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + NTSTATUS ret = irp->IoStatus.Status; + + switch (stack->MinorFunction) + { + case IRP_MN_START_DEVICE: + ret = STATUS_SUCCESS; + break; + + case IRP_MN_QUERY_CAPABILITIES: + case IRP_MN_SURPRISE_REMOVAL: + ret = STATUS_SUCCESS; + break; + } + + irp->IoStatus.Status = ret; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return ret; +} + +static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp) +{ + if (device == bus_fdo) + return fdo_pnp(irp); + return pdo_pnp(device, irp); +} + +static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo) +{ + NTSTATUS ret; + + if ((ret = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &bus_fdo))) + return ret; + + if ((ret = IoRegisterDeviceInterface(pdo, &control_class, NULL, &control_symlink))) + { + IoDeleteDevice(bus_fdo); + return ret; + } + + IoAttachDeviceToDeviceStack(bus_fdo, pdo); + bus_pdo = pdo; + bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING; + return STATUS_SUCCESS; +} + +static NTSTATUS WINAPI driver_create(DEVICE_OBJECT *device, IRP *irp) +{ + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static NTSTATUS WINAPI driver_close(DEVICE_OBJECT *device, IRP *irp) +{ + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static void WINAPI driver_unload(DRIVER_OBJECT *driver) +{ +} + +NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *registry) +{ + driver->DriverExtension->AddDevice = driver_add_device; + driver->DriverUnload = driver_unload; + driver->MajorFunction[IRP_MJ_PNP] = driver_pnp; + driver->MajorFunction[IRP_MJ_CREATE] = driver_create; + driver->MajorFunction[IRP_MJ_CLOSE] = driver_close; + + return STATUS_SUCCESS; +} diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.spec b/dlls/ntoskrnl.exe/tests/driver_pnp.spec new file mode 100644 index 00000000000..ad33444716a --- /dev/null +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.spec @@ -0,0 +1 @@ +# nothing here yet diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index e65dac38cec..c9f680f01e8 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -32,12 +32,16 @@ #include "ntsecapi.h" #include "mscat.h" #include "mssip.h" +#include "setupapi.h" +#include "newdev.h" #include "wine/test.h" #include "wine/heap.h" #include "wine/mssign.h"
#include "driver.h"
+static const GUID GUID_NULL; + static HANDLE device;
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *); @@ -935,6 +939,226 @@ static void test_driver4(struct testsign_context *ctx) ok(ret, "DeleteFile failed: %u\n", GetLastError()); }
+static void add_file_to_catalog(HANDLE catalog, const WCHAR *file) +{ + SIP_SUBJECTINFO subject_info = {sizeof(SIP_SUBJECTINFO)}; + SIP_INDIRECT_DATA *indirect_data; + const WCHAR *filepart = file; + CRYPTCATMEMBER *member; + WCHAR hash_buffer[100]; + GUID subject_guid; + unsigned int i; + DWORD size; + BOOL ret; + + ret = CryptSIPRetrieveSubjectGuidForCatalogFile(file, NULL, &subject_guid); + todo_wine ok(ret, "Failed to get subject guid, error %u\n", GetLastError()); + + size = 0; + subject_info.pgSubjectType = &subject_guid; + subject_info.pwsFileName = file; + subject_info.DigestAlgorithm.pszObjId = (char *)szOID_OIWSEC_sha1; + subject_info.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG | SPC_EXC_PE_PAGE_HASHES_FLAG | 0x10000; + ret = CryptSIPCreateIndirectData(&subject_info, &size, NULL); + todo_wine ok(ret, "Failed to get indirect data size, error %u\n", GetLastError()); + + indirect_data = malloc(size); + ret = CryptSIPCreateIndirectData(&subject_info, &size, indirect_data); + todo_wine ok(ret, "Failed to get indirect data, error %u\n", GetLastError()); + if (ret) + { + memset(hash_buffer, 0, sizeof(hash_buffer)); + for (i = 0; i < indirect_data->Digest.cbData; ++i) + swprintf(&hash_buffer[i * 2], 2, L"%02X", indirect_data->Digest.pbData[i]); + + member = CryptCATPutMemberInfo(catalog, (WCHAR *)file, + hash_buffer, &subject_guid, 0, size, (BYTE *)indirect_data); + ok(!!member, "Failed to write member, error %u\n", GetLastError()); + + if (wcsrchr(file, '\')) + filepart = wcsrchr(file, '\') + 1; + + ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"File", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + (wcslen(filepart) + 1) * 2, (BYTE *)filepart); + ok(ret, "Failed to write attr, error %u\n", GetLastError()); + + ret = !!CryptCATPutAttrInfo(catalog, member, (WCHAR *)L"OSAttr", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + sizeof(L"2:6.0"), (BYTE *)L"2:6.0"); + ok(ret, "Failed to write attr, error %u\n", GetLastError()); + } +} + +static void test_pnp_driver(struct testsign_context *ctx) +{ + static const char hardware_id[] = "test_hardware_id\0"; + char path[MAX_PATH], dest[MAX_PATH], *filepart; + SP_DEVINFO_DATA device = {sizeof(device)}; + char cwd[MAX_PATH], tempdir[MAX_PATH]; + WCHAR driver_filename[MAX_PATH]; + SC_HANDLE manager, service; + BOOL ret, need_reboot; + HANDLE catalog, file; + HDEVINFO set; + FILE *f; + +#ifdef __i386__ +#define EXT "x86" +#elif defined(__x86_64__) +#define EXT "amd64" +#elif defined(__arm__) +#define EXT "arm" +#elif defined(__aarch64__) +#define EXT "arm64" +#else +#define EXT +#endif + + static const char inf_text[] = + "[Version]\n" + "Signature=$Chicago$\n" + "ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}\n" + "CatalogFile=winetest.cat\n" + "DriverVer=09/21/2006,6.0.5736.1\n" + + "[Manufacturer]\n" + "Wine=mfg_section,NT" EXT "\n" + + "[mfg_section.NT" EXT "]\n" + "Wine test root driver=device_section,test_hardware_id\n" + + "[device_section.NT" EXT "]\n" + "CopyFiles=file_section\n" + + "[device_section.NT" EXT ".Services]\n" + "AddService=winetest,0x2,svc_section\n" + + "[file_section]\n" + "winetest.sys\n" + + "[SourceDisksFiles]\n" + "winetest.sys=1\n" + + "[SourceDisksNames]\n" + "1=,winetest.sys\n" + + "[DestinationDirs]\n" + "DefaultDestDir=12\n" + + "[svc_section]\n" + "ServiceBinary=%12%\winetest.sys\n" + "ServiceType=1\n" + "StartType=3\n" + "ErrorControl=1\n" + "LoadOrderGroup=Extended Base\n" + "DisplayName="winetest bus driver"\n" + "; they don't sleep anymore, on the beach\n"; + + GetCurrentDirectoryA(ARRAY_SIZE(cwd), cwd); + GetTempPathA(ARRAY_SIZE(tempdir), tempdir); + SetCurrentDirectoryA(tempdir); + + load_resource(L"driver_pnp.dll", driver_filename); + ret = MoveFileExW(driver_filename, L"winetest.sys", MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); + ok(ret, "failed to move file, error %u\n", GetLastError()); + + f = fopen("winetest.inf", "w"); + ok(!!f, "failed to open winetest.inf: %s\n", strerror(errno)); + fputs(inf_text, f); + fclose(f); + + /* Create the catalog file. */ + + catalog = CryptCATOpen((WCHAR *)L"winetest.cat", CRYPTCAT_OPEN_CREATENEW, 0, CRYPTCAT_VERSION_1, 0); + ok(catalog != INVALID_HANDLE_VALUE, "Failed to create catalog, error %#x\n", GetLastError()); + + ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"HWID1", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + sizeof(L"test_hardware_id"), (BYTE *)L"test_hardware_id"); + todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError()); + + ret = !!CryptCATPutCatAttrInfo(catalog, (WCHAR *)L"OS", + CRYPTCAT_ATTR_NAMEASCII | CRYPTCAT_ATTR_DATAASCII | CRYPTCAT_ATTR_AUTHENTICATED, + sizeof(L"VistaX64"), (BYTE *)L"VistaX64"); + todo_wine ok(ret, "failed to add attribute, error %#x\n", GetLastError()); + + add_file_to_catalog(catalog, L"winetest.sys"); + add_file_to_catalog(catalog, L"winetest.inf"); + + ret = CryptCATPersistStore(catalog); + todo_wine ok(ret, "Failed to write catalog, error %u\n", GetLastError()); + + ret = CryptCATClose(catalog); + ok(ret, "Failed to close catalog, error %u\n", GetLastError()); + + testsign_sign(ctx, L"winetest.cat"); + + /* Install the driver. */ + + set = SetupDiCreateDeviceInfoList(NULL, NULL); + ok(set != INVALID_HANDLE_VALUE, "failed to create device list, error %#x\n", GetLastError()); + + ret = SetupDiCreateDeviceInfoA(set, "root\winetest\0", &GUID_NULL, NULL, NULL, 0, &device); + ok(ret, "failed to create device, error %#x\n", GetLastError()); + + ret = SetupDiSetDeviceRegistryPropertyA( set, &device, SPDRP_HARDWAREID, + (const BYTE *)hardware_id, sizeof(hardware_id) ); + ok(ret, "failed to create set hardware ID, error %#x\n", GetLastError()); + + ret = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device); + ok(ret, "failed to register device, error %#x\n", GetLastError()); + + GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); + ret = UpdateDriverForPlugAndPlayDevicesA(NULL, hardware_id, path, INSTALLFLAG_FORCE, &need_reboot); + ok(ret, "failed to install device, error %#x\n", GetLastError()); + ok(!need_reboot, "expected no reboot necessary\n"); + + /* Tests. */ + + file = CreateFileA("\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + CloseHandle(file); + + /* Clean up. */ + + ret = SetupDiCallClassInstaller(DIF_REMOVE, set, &device); + ok(ret, "failed to remove device, error %#x\n", GetLastError()); + + file = CreateFileA("\\?\root#winetest#0#{deadbeef-29ef-4538-a5fd-b69573a362c0}", 0, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file == INVALID_HANDLE_VALUE, "expected failure\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %u\n", GetLastError()); + + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "failed to destroy set, error %#x\n", GetLastError()); + + /* Windows stops the service but does not delete it. */ + manager = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); + ok(!!manager, "failed to open service manager, error %u\n", GetLastError()); + service = OpenServiceA(manager, "winetest", SERVICE_STOP | DELETE); + ok(!!service, "failed to open service, error %u\n", GetLastError()); + unload_driver(service); + CloseServiceHandle(manager); + + GetFullPathNameA("winetest.inf", sizeof(path), path, NULL); + ret = SetupCopyOEMInfA(path, NULL, 0, 0, dest, sizeof(dest), NULL, &filepart); + ok(ret, "Failed to copy INF, error %#x\n", GetLastError()); + ret = SetupUninstallOEMInfA(filepart, 0, NULL); + ok(ret, "Failed to uninstall INF, error %u\n", GetLastError()); + + ret = DeleteFileA("winetest.cat"); + ok(ret, "Failed to delete file, error %u\n", GetLastError()); + ret = DeleteFileA("winetest.inf"); + ok(ret, "Failed to delete file, error %u\n", GetLastError()); + ret = DeleteFileA("winetest.sys"); + ok(ret, "Failed to delete file, error %u\n", GetLastError()); + /* Windows 10 apparently deletes the image in SetupUninstallOEMInf(). */ + ret = DeleteFileA("C:/windows/system32/drivers/winetest.sys"); + ok(ret || GetLastError() == ERROR_FILE_NOT_FOUND, "Failed to delete file, error %u\n", GetLastError()); + + SetCurrentDirectoryA(cwd); +} + START_TEST(ntoskrnl) { WCHAR filename[MAX_PATH], filename2[MAX_PATH]; @@ -1008,5 +1232,7 @@ START_TEST(ntoskrnl) subtest("driver4"); test_driver4(&ctx);
+ test_pnp_driver(&ctx); + testsign_cleanup(&ctx); }
Sorry, I'll resend this without both series interleaved...