Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 69 ++++++++++++++++++++++++++++++++++++- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- include/ddk/wdm.h | 1 + 3 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 80e9b9e..f92dd58 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -43,7 +43,7 @@ #include "wine/unicode.h" #include "wine/server.h" #include "wine/debug.h" - +#include "wine/heap.h" #include "wine/rbtree.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); @@ -1193,6 +1193,73 @@ NTSTATUS WINAPI IoDeleteSymbolicLink( UNICODE_STRING *name )
/*********************************************************************** + * IoSetDeviceInterfaceState (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable ) +{ + const WCHAR DeviceClassesW[] = {'\','R','E','G','I','S','T','R','Y','\', + 'M','a','c','h','i','n','e','\','S','y','s','t','e','m','\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\', + 'C','o','n','t','r','o','l','\', + 'D','e','v','i','c','e','C','l','a','s','s','e','s','\',0}; + const WCHAR controlW[] = {'C','o','n','t','r','o','l',0}; + const WCHAR linkedW[] = {'L','i','n','k','e','d',0}; + const WCHAR slashW[] = {'\',0}; + const WCHAR hashW[] = {'#',0}; + + size_t namelen = name->Length / sizeof(WCHAR); + HANDLE iface_key, control_key; + OBJECT_ATTRIBUTES attr = {0}; + WCHAR *path, *refstr, *p; + UNICODE_STRING string; + NTSTATUS ret; + size_t len; + + TRACE("(%s, %d)\n", debugstr_us(name), enable); + + refstr = memrchrW(name->Buffer + 4, '\', namelen - 4); + + len = strlenW(DeviceClassesW) + 38 + 1 + namelen + 2; + + if (!(path = heap_alloc( len * sizeof(WCHAR) ))) + return STATUS_NO_MEMORY; + + strcpyW( path, DeviceClassesW ); + lstrcpynW( path + strlenW( path ), (refstr ? refstr : name->Buffer + namelen) - 38, 39 ); + strcatW( path, slashW ); + p = path + strlenW( path ); + lstrcpynW( path + strlenW( path ), name->Buffer, (refstr ? (refstr - name->Buffer) : namelen) + 1 ); + p[0] = p[1] = p[3] = '#'; + strcatW( path, slashW ); + strcatW( path, hashW ); + if (refstr) + lstrcpynW( path + strlenW( path ), refstr, name->Buffer + namelen - refstr + 1 ); + + attr.Length = sizeof(attr); + attr.ObjectName = &string; + RtlInitUnicodeString( &string, path ); + ret = NtOpenKey( &iface_key, KEY_CREATE_SUB_KEY, &attr ); + if (!ret) + { + attr.RootDirectory = iface_key; + RtlInitUnicodeString( &string, controlW ); + ret = NtCreateKey( &control_key, KEY_SET_VALUE, &attr, 0, NULL, 0, NULL ); + if (!ret) + { + DWORD data = enable; + RtlInitUnicodeString( &string, linkedW ); + ret = NtSetValueKey( control_key, &string, 0, REG_DWORD, &data, sizeof(data) ); + NtClose( control_key ); + } + NtClose( iface_key ); + } + + heap_free( path ); + return ret; +} + + +/*********************************************************************** * IoGetDeviceInterfaces (NTOSKRNL.EXE.@) */ NTSTATUS WINAPI IoGetDeviceInterfaces( const GUID *InterfaceClassGuid, diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 662445a..71ac860 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -449,7 +449,7 @@ @ stub IoRequestDeviceEject @ stub IoReuseIrp @ stub IoSetCompletionRoutineEx -@ stub IoSetDeviceInterfaceState +@ stdcall IoSetDeviceInterfaceState(ptr long) @ stub IoSetDeviceToVerify @ stub IoSetFileOrigin @ stub IoSetHardErrorOrVerifyDevice diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 5abe18b..39734de 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1405,6 +1405,7 @@ void WINAPI IoInitializeIrp(IRP*,USHORT,CCHAR); VOID WINAPI IoInitializeRemoveLockEx(PIO_REMOVE_LOCK,ULONG,ULONG,ULONG,ULONG); void WINAPI IoInvalidateDeviceRelations(PDEVICE_OBJECT,DEVICE_RELATION_TYPE); void WINAPI IoReleaseCancelSpinLock(KIRQL); +NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING *name, BOOLEAN enable); NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
PKTHREAD WINAPI KeGetCurrentThread(void);