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);