diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 3505a58b9d6..2f7e27e0d87 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -465,6 +465,7 @@ @ stdcall IoReuseIrp(ptr long) @ stub IoSetCompletionRoutineEx @ stdcall IoSetDeviceInterfaceState(ptr long) +@ stdcall IoSetDevicePropertyData(ptr ptr long long long long ptr) @ stub IoSetDeviceToVerify @ stub IoSetFileOrigin @ stub IoSetHardErrorOrVerifyDevice diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 095344b1073..e425712d738 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -38,6 +38,12 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); WINE_DEFAULT_DEBUG_CHANNEL(plugplay); +static inline const char *debugstr_propkey( const DEVPROPKEY *id ) +{ + if (!id) return "(null)"; + return wine_dbg_sprintf( "{%s,%04x}", wine_dbgstr_guid( &id->fmtid ), id->pid ); +} + #define MAX_SERVICE_NAME 260 struct device_interface @@ -783,6 +789,51 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable return ret; } +/*********************************************************************** + * IoSetDevicePropertyData (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoSetDevicePropertyData( DEVICE_OBJECT *device, const DEVPROPKEY *property_key, LCID lcid, + ULONG flags, DEVPROPTYPE type, ULONG size, void *data ) +{ + SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; + WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; + NTSTATUS status; + HDEVINFO set; + + TRACE( "device %p, property_key %s, lcid %#x, flags %#x, type %#x, size %u, data %p.\n", + device, debugstr_propkey(property_key), lcid, flags, type, size, data ); + + /* flags is always treated as PLUGPLAY_PROPERTY_PERSISTENT starting with Win 8 / 2012 */ + + if (lcid != LOCALE_NEUTRAL) FIXME( "only LOCALE_NEUTRAL is supported\n" ); + + if ((status = get_device_instance_id( device, device_instance_id ))) return status; + + if ((set = SetupDiCreateDeviceInfoList( &GUID_NULL, NULL )) == INVALID_HANDLE_VALUE) + { + ERR( "Failed to create device list, error %#x.\n", GetLastError() ); + return GetLastError(); + } + + if (!SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) + { + ERR( "Failed to open device, error %#x.\n", GetLastError() ); + SetupDiDestroyDeviceInfoList( set ); + return GetLastError(); + } + + if (!SetupDiSetDevicePropertyW( set, &sp_device, property_key, type, data, size, 0 )) + { + ERR( "Failed to set property, error %#x.\n", GetLastError() ); + SetupDiDestroyDeviceInfoList( set ); + return GetLastError(); + } + + SetupDiDestroyDeviceInfoList( set ); + + return STATUS_SUCCESS; +} + /*********************************************************************** * IoRegisterDeviceInterface (NTOSKRNL.EXE.@) */ diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 51097bfe3ab..447833c4bc9 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -21,6 +21,7 @@ #define _NTDDK_ #include +#include #ifdef _WIN64 #define POINTER_ALIGNMENT DECLSPEC_ALIGN(8) @@ -1681,6 +1682,8 @@ void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN); void WINAPI ExUnregisterCallback(void*); +#define PLUGPLAY_PROPERTY_PERSISTENT 0x0001 + void WINAPI IoAcquireCancelSpinLock(KIRQL*); NTSTATUS WINAPI IoAcquireRemoveLockEx(IO_REMOVE_LOCK*,void*,const char*,ULONG, ULONG); NTSTATUS WINAPI IoAllocateDriverObjectExtension(PDRIVER_OBJECT,PVOID,ULONG,PVOID*); @@ -1728,6 +1731,7 @@ void WINAPI IoReleaseRemoveLockAndWaitEx(IO_REMOVE_LOCK*,void*,ULONG); void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG); void WINAPI IoReuseIrp(IRP*,NTSTATUS); NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN); +NTSTATUS WINAPI IoSetDevicePropertyData(DEVICE_OBJECT*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*); NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG); void FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(KSPIN_LOCK*,KLOCK_QUEUE_HANDLE*);