From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 + dlls/ntoskrnl.exe/pnp.c | 22 ++++++++ dlls/ntoskrnl.exe/tests/driver_pnp.c | 75 ++++++++++++++++++++++++++++ include/ddk/wdm.h | 2 + 4 files changed, 101 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 77d387174c7..95ba78f6a24 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -403,6 +403,7 @@ @ stdcall IoGetCurrentProcess() @ stub IoGetDeviceAttachmentBaseRef @ stub IoGetDeviceInterfaceAlias +@ stdcall IoGetDeviceInterfacePropertyData(ptr ptr long long long ptr ptr ptr) @ stdcall IoGetDeviceInterfaces(ptr ptr long ptr) @ stdcall IoGetDeviceObjectPointer(ptr long ptr ptr) @ stdcall IoGetDeviceProperty(ptr long long ptr ptr) @@ -470,6 +471,7 @@ @ stub IoRequestDeviceEject @ stdcall IoReuseIrp(ptr long) @ stub IoSetCompletionRoutineEx +@ stdcall IoSetDeviceInterfacePropertyData(ptr ptr long long long long ptr) @ stdcall IoSetDeviceInterfaceState(ptr long) @ stdcall IoSetDevicePropertyData(ptr ptr long long long long ptr) @ stub IoSetDeviceToVerify diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 49af547d4fa..fa0e0cf0b0d 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -756,6 +756,28 @@ static void send_devicechange( const WCHAR *path, DWORD code, void *data, unsign __ENDTRY }
+/*********************************************************************** + * IoSetDeviceInterfacePropertyData (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoSetDeviceInterfacePropertyData( UNICODE_STRING *name, const DEVPROPKEY *key, LCID lcid, ULONG flags, + DEVPROPTYPE type, ULONG len, void *buf ) +{ + FIXME( "name %s, key %s, lcid %#lx, flags %#lx, type %#lx, len %lu, buf %p: stub!\n", debugstr_us( name ), + debugstr_propkey( key ), lcid, flags, type, len, buf ); + return STATUS_NOT_IMPLEMENTED; +} + +/*********************************************************************** + * IoGetDeviceInterfacePropertyData (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoGetDeviceInterfacePropertyData( UNICODE_STRING *name, const DEVPROPKEY *key, LCID lcid, ULONG flags, + ULONG size, void *buf, ULONG *required, DEVPROPTYPE *type ) +{ + FIXME( "name %s, key %s, lcid %#lx, flags %#lx, size %lu, buf %p, required %p, type %p: stub!\n", + debugstr_us( name ), debugstr_propkey( key ), lcid, flags, size, buf, required, type ); + return STATUS_NOT_IMPLEMENTED; +} + /*********************************************************************** * IoSetDeviceInterfaceState (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index a5fb145c387..0af1e4d6ebf 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -727,6 +727,67 @@ static void test_child_device_properties(DEVICE_OBJECT *device) ok(status == STATUS_SUCCESS, "failed to delete device property, status %#lx\n", status); }
+static void test_device_interface_properties( UNICODE_STRING *name ) +{ + DEVPROP_BOOLEAN val = DEVPROP_FALSE; + DEVPROPTYPE type = DEVPROP_TYPE_EMPTY; + ULONG req_size = 0; + NTSTATUS status; + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( deviceprops ); i++) + { + ULONG size = deviceprops[i].size; + DEVPROPTYPE type = deviceprops[i].type; + const DEVPROPKEY *key = deviceprops[i].key; + void *value = &deviceprops[i].value; + + winetest_push_context( "deviceprops[%lu]", (DWORD)i ); + status = IoSetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, type, size, value ); + todo_wine ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); + if (!status) + { + void *buf; + ULONG req_size = 0; + DEVPROPTYPE stored_type = DEVPROP_TYPE_EMPTY; + + status = IoGetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, 0, NULL, &req_size, &stored_type ); + todo_wine ok( status == STATUS_BUFFER_TOO_SMALL, "got status %#lx != %#lx\n", status, STATUS_BUFFER_TOO_SMALL ); + todo_wine ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); + todo_wine ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type ); + + buf = ExAllocatePool( NonPagedPool, size ); + ok( !!buf, "Failed to allocate memory\n" ); + if (buf) + { + req_size = 0; + stored_type = DEVPROP_TYPE_EMPTY; + memset( buf, 0, size ); + status = IoGetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, size, buf, &req_size, + &stored_type ); + todo_wine ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); + todo_wine ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); + todo_wine ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type ); + + if (!status) ok( !kmemcmp( buf, value, size ), "Got unexpected device interface property value.\n" ); + ExFreePool( buf ); + } + status = IoSetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, type, 0, NULL ); + todo_wine ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); + } + winetest_pop_context(); + } + + req_size = 0; + type = DEVPROP_TYPE_EMPTY; + status = IoGetDeviceInterfacePropertyData( name, &DEVPKEY_DeviceInterface_Enabled, LOCALE_NEUTRAL, 0, sizeof( val ), + &val, &req_size, &type ); + todo_wine ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); + todo_wine ok( req_size == sizeof( val ), "got req_size %lu\n", req_size ); + todo_wine ok( type == DEVPROP_TYPE_BOOLEAN, "got type %#lx\n", type ); + todo_wine ok( val == DEVPROP_TRUE, "got val %d\n", val ); +} + static void test_enumerator_name(void) { static const WCHAR root[] = L"ROOT"; @@ -857,11 +918,25 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code)
case IOCTL_WINETEST_BUS_ENABLE_IFACE: IoSetDeviceInterfaceState(&bus_symlink, TRUE); + test_device_interface_properties(&bus_symlink); return STATUS_SUCCESS;
case IOCTL_WINETEST_BUS_DISABLE_IFACE: + { + DEVPROP_BOOLEAN val = DEVPROP_TRUE; + DEVPROPTYPE type = DEVPROP_TYPE_EMPTY; + NTSTATUS status; + DWORD req_size = 0; + IoSetDeviceInterfaceState(&bus_symlink, FALSE); + status = IoGetDeviceInterfacePropertyData(&bus_symlink, &DEVPKEY_DeviceInterface_Enabled, LOCALE_NEUTRAL, 0, + sizeof(val), &val, &req_size, &type); + todo_wine ok(!status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status); + todo_wine ok(req_size == sizeof(val), "got req_size = %lu\n", req_size); + todo_wine ok(type == DEVPROP_TYPE_BOOLEAN, "got type = %#lx\n", type); + todo_wine ok(val == DEVPROP_FALSE, "got val %d\n", val); return STATUS_SUCCESS; + }
case IOCTL_WINETEST_BUS_ADD_CHILD: { diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index caf569a102c..116facaff38 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1790,6 +1790,7 @@ NTSTATUS WINAPI IoDeleteSymbolicLink(UNICODE_STRING*); DEVICE_OBJECT * WINAPI IoGetAttachedDeviceReference(DEVICE_OBJECT*); PEPROCESS WINAPI IoGetCurrentProcess(void); NTSTATUS WINAPI IoGetDeviceInterfaces(const GUID*,PDEVICE_OBJECT,ULONG,PWSTR*); +NTSTATUS WINAPI IoGetDeviceInterfacePropertyData(UNICODE_STRING*,const DEVPROPKEY*,LCID,ULONG,ULONG,void*,ULONG*,DEVPROPTYPE*); NTSTATUS WINAPI IoGetDeviceObjectPointer(UNICODE_STRING*,ACCESS_MASK,PFILE_OBJECT*,PDEVICE_OBJECT*); NTSTATUS WINAPI IoGetDeviceProperty(PDEVICE_OBJECT,DEVICE_REGISTRY_PROPERTY,ULONG,PVOID,PULONG); NTSTATUS WINAPI IoGetDevicePropertyData(PDEVICE_OBJECT,const DEVPROPKEY*,LCID,ULONG,ULONG,void*,ULONG*,DEVPROPTYPE*); @@ -1811,6 +1812,7 @@ void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG); NTSTATUS WINAPI IoReportTargetDeviceChange(DEVICE_OBJECT*,void*); NTSTATUS WINAPI IoReportTargetDeviceChangeAsynchronous(DEVICE_OBJECT*,void*,PDEVICE_CHANGE_COMPLETE_CALLBACK,void*); void WINAPI IoReuseIrp(IRP*,NTSTATUS); +NTSTATUS WINAPI IoSetDeviceInterfacePropertyData(UNICODE_STRING*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*); NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN); NTSTATUS WINAPI IoSetDevicePropertyData(DEVICE_OBJECT*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*); NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntoskrnl.exe/pnp.c | 54 ++++++++++++++++++++++++++-- dlls/ntoskrnl.exe/tests/driver_pnp.c | 16 ++++----- 2 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index fa0e0cf0b0d..6f84284b57a 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -773,9 +773,59 @@ NTSTATUS WINAPI IoSetDeviceInterfacePropertyData( UNICODE_STRING *name, const DE NTSTATUS WINAPI IoGetDeviceInterfacePropertyData( UNICODE_STRING *name, const DEVPROPKEY *key, LCID lcid, ULONG flags, ULONG size, void *buf, ULONG *required, DEVPROPTYPE *type ) { - FIXME( "name %s, key %s, lcid %#lx, flags %#lx, size %lu, buf %p, required %p, type %p: stub!\n", + SP_DEVICE_INTERFACE_DATA iface_data = {0}; + WCHAR device_path[MAX_PATH]; + struct wine_rb_entry *entry; + DWORD err = ERROR_SUCCESS; + HDEVINFO set; + + TRACE( "name %s, key %s, lcid %#lx, flags %#lx, size %lu, buf %p, required %p, type %p\n", debugstr_us( name ), debugstr_propkey( key ), lcid, flags, size, buf, required, type ); - return STATUS_NOT_IMPLEMENTED; + + if (!(entry = wine_rb_get( &device_interfaces, name ))) + return STATUS_OBJECT_NAME_NOT_FOUND; + + swprintf( device_path, ARRAY_SIZE( device_path ), L"\\%s", &name->Buffer[2] ); + + if ((set = SetupDiCreateDeviceInfoListExW( NULL, NULL, NULL, NULL )) == INVALID_HANDLE_VALUE) + { + err = GetLastError(); + ERR( "Failed to create device list, error %lu.\n", err ); + goto done; + } + iface_data.cbSize = sizeof( iface_data ); + if (!SetupDiOpenDeviceInterfaceW( set, device_path, 0, &iface_data )) + { + err = GetLastError(); + ERR( "Failed to open device interface, error %lu.\n", err ); + goto done; + } + if (!SetupDiGetDeviceInterfacePropertyW( set, &iface_data, key, type, (BYTE *)buf, size, required, flags )) + err = GetLastError(); + +done: + if (set != INVALID_HANDLE_VALUE) + { + SetupDiDeleteDeviceInterfaceData( set, &iface_data ); + SetupDiDestroyDeviceInfoList( set ); + } + switch (err) + { + case ERROR_SUCCESS: + return STATUS_SUCCESS; + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_FLAGS: + return STATUS_INVALID_PARAMETER; + case ERROR_NOT_ENOUGH_MEMORY: + return STATUS_NO_MEMORY; + case ERROR_NO_SUCH_DEVICE_INTERFACE: + return STATUS_OBJECT_NAME_NOT_FOUND; + case ERROR_INSUFFICIENT_BUFFER: + return STATUS_BUFFER_TOO_SMALL; + default: + FIXME( "Unhandled error: %lu\n", err ); + return STATUS_INTERNAL_ERROR; + } }
/*********************************************************************** diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index 0af1e4d6ebf..e254938bea7 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -782,10 +782,10 @@ static void test_device_interface_properties( UNICODE_STRING *name ) type = DEVPROP_TYPE_EMPTY; status = IoGetDeviceInterfacePropertyData( name, &DEVPKEY_DeviceInterface_Enabled, LOCALE_NEUTRAL, 0, sizeof( val ), &val, &req_size, &type ); - todo_wine ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); - todo_wine ok( req_size == sizeof( val ), "got req_size %lu\n", req_size ); - todo_wine ok( type == DEVPROP_TYPE_BOOLEAN, "got type %#lx\n", type ); - todo_wine ok( val == DEVPROP_TRUE, "got val %d\n", val ); + ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); + ok( req_size == sizeof( val ), "got req_size %lu\n", req_size ); + ok( type == DEVPROP_TYPE_BOOLEAN, "got type %#lx\n", type ); + ok( val == DEVPROP_TRUE, "got val %d\n", val ); }
static void test_enumerator_name(void) @@ -931,10 +931,10 @@ static NTSTATUS fdo_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG code) IoSetDeviceInterfaceState(&bus_symlink, FALSE); status = IoGetDeviceInterfacePropertyData(&bus_symlink, &DEVPKEY_DeviceInterface_Enabled, LOCALE_NEUTRAL, 0, sizeof(val), &val, &req_size, &type); - todo_wine ok(!status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status); - todo_wine ok(req_size == sizeof(val), "got req_size = %lu\n", req_size); - todo_wine ok(type == DEVPROP_TYPE_BOOLEAN, "got type = %#lx\n", type); - todo_wine ok(val == DEVPROP_FALSE, "got val %d\n", val); + ok(!status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status); + ok(req_size == sizeof(val), "got req_size = %lu\n", req_size); + ok(type == DEVPROP_TYPE_BOOLEAN, "got type = %#lx\n", type); + ok(val == DEVPROP_FALSE, "got val %d\n", val); return STATUS_SUCCESS; }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntoskrnl.exe/pnp.c | 59 +++++++++++++++++++++++++++- dlls/ntoskrnl.exe/tests/driver_pnp.c | 16 ++++---- 2 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 6f84284b57a..86067a35692 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -762,9 +762,64 @@ static void send_devicechange( const WCHAR *path, DWORD code, void *data, unsign NTSTATUS WINAPI IoSetDeviceInterfacePropertyData( UNICODE_STRING *name, const DEVPROPKEY *key, LCID lcid, ULONG flags, DEVPROPTYPE type, ULONG len, void *buf ) { - FIXME( "name %s, key %s, lcid %#lx, flags %#lx, type %#lx, len %lu, buf %p: stub!\n", debugstr_us( name ), + SP_DEVICE_INTERFACE_DATA iface_data = {0}; + WCHAR device_path[MAX_PATH]; + struct wine_rb_entry *entry; + DWORD err = ERROR_SUCCESS; + HDEVINFO set; + + TRACE( "name %s, key %s, lcid %#lx, flags %#lx, type %#lx, len %lu, buf %p\n", debugstr_us( name ), debugstr_propkey( key ), lcid, flags, type, len, buf ); - return STATUS_NOT_IMPLEMENTED; + + if (lcid != LOCALE_NEUTRAL) FIXME( "only LOCALE_NEUTRAL is supported\n" ); + + if (!(entry = wine_rb_get( &device_interfaces, name ))) + return STATUS_OBJECT_NAME_NOT_FOUND; + + swprintf( device_path, ARRAY_SIZE( device_path ), L"\\%s", &name->Buffer[2] ); + + if ((set = SetupDiCreateDeviceInfoListExW( NULL, NULL, NULL, NULL )) == INVALID_HANDLE_VALUE) + { + err = GetLastError(); + ERR( "Failed to create device list, error %lu.\n", err ); + goto done; + } + iface_data.cbSize = sizeof( iface_data ); + if (!SetupDiOpenDeviceInterfaceW( set, device_path, 0, &iface_data )) + { + err = GetLastError(); + ERR( "Failed to open device interface, error %lu.\n", err ); + goto done; + } + if (!SetupDiSetDeviceInterfacePropertyW( set, &iface_data, key, buf ? type : DEVPROP_TYPE_EMPTY, (BYTE *)buf, len, 0 )) + err = GetLastError(); + +done: + if (set != INVALID_HANDLE_VALUE) + { + SetupDiDeleteDeviceInterfaceData( set, &iface_data ); + SetupDiDestroyDeviceInfoList( set ); + } + switch (err) + { + case ERROR_SUCCESS: + return STATUS_SUCCESS; + case ERROR_INVALID_PARAMETER: + case ERROR_INVALID_DATA: + case ERROR_INVALID_FLAGS: + return STATUS_INVALID_PARAMETER; + case ERROR_NOT_ENOUGH_MEMORY: + return STATUS_NO_MEMORY; + case ERROR_NO_SUCH_DEVICE_INTERFACE: + return STATUS_OBJECT_NAME_NOT_FOUND; + case ERROR_INSUFFICIENT_BUFFER: + return STATUS_BUFFER_TOO_SMALL; + case ERROR_INVALID_ACCESS: + return STATUS_ACCESS_DENIED; + default: + FIXME( "Unhandled error: %lu\n", err ); + return STATUS_INTERNAL_ERROR; + } }
/*********************************************************************** diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index e254938bea7..1a0717656c5 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -744,7 +744,7 @@ static void test_device_interface_properties( UNICODE_STRING *name )
winetest_push_context( "deviceprops[%lu]", (DWORD)i ); status = IoSetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, type, size, value ); - todo_wine ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); + ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); if (!status) { void *buf; @@ -752,9 +752,9 @@ static void test_device_interface_properties( UNICODE_STRING *name ) DEVPROPTYPE stored_type = DEVPROP_TYPE_EMPTY;
status = IoGetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, 0, NULL, &req_size, &stored_type ); - todo_wine ok( status == STATUS_BUFFER_TOO_SMALL, "got status %#lx != %#lx\n", status, STATUS_BUFFER_TOO_SMALL ); - todo_wine ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); - todo_wine ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got status %#lx != %#lx\n", status, STATUS_BUFFER_TOO_SMALL ); + ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); + ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type );
buf = ExAllocatePool( NonPagedPool, size ); ok( !!buf, "Failed to allocate memory\n" ); @@ -765,15 +765,15 @@ static void test_device_interface_properties( UNICODE_STRING *name ) memset( buf, 0, size ); status = IoGetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, size, buf, &req_size, &stored_type ); - todo_wine ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); - todo_wine ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); - todo_wine ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type ); + ok( !status, "IoGetDeviceInterfacePropertyData failed: %#lx\n", status ); + ok( req_size == size, "got req_size %lu != %lu\n", req_size, size ); + ok( stored_type == type, "got stored_type %#lx != %#lx\n", stored_type, type );
if (!status) ok( !kmemcmp( buf, value, size ), "Got unexpected device interface property value.\n" ); ExFreePool( buf ); } status = IoSetDeviceInterfacePropertyData( name, key, LOCALE_NEUTRAL, 0, type, 0, NULL ); - todo_wine ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); + ok( !status, "IoSetDeviceInterfacePropertyData failed: %#lx\n", status ); } winetest_pop_context(); }
This merge request was approved by Elizabeth Figura.