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);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/setupapi/devinst.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 9f77669..c69304b 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -91,6 +91,8 @@ static const WCHAR UpperFilters[] = {'U','p','p','e','r','F','i','l','t','e','r' static const WCHAR LowerFilters[] = {'L','o','w','e','r','F','i','l','t','e','r','s',0}; static const WCHAR Phantom[] = {'P','h','a','n','t','o','m',0}; static const WCHAR SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n','k',0}; +static const WCHAR Control[] = {'C','o','n','t','r','o','l',0}; +static const WCHAR Linked[] = {'L','i','n','k','e','d',0};
/* is used to identify if a DeviceInfoSet pointer is valid or not */ @@ -299,6 +301,25 @@ static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId, return ret; }
+static BOOL is_linked(HKEY key) +{ + DWORD linked, type, size; + HKEY control_key; + BOOL ret = FALSE; + + if (!RegOpenKeyW(key, Control, &control_key)) + { + size = sizeof(DWORD); + if (!RegQueryValueExW(control_key, Linked, NULL, &type, (BYTE *)&linked, &size) + && type == REG_DWORD && linked) + ret = TRUE; + + RegCloseKey(control_key); + } + + return ret; +} + static struct device_iface *SETUPDI_CreateDeviceInterface(struct device *device, const GUID *class, const WCHAR *refstr) { @@ -334,7 +355,7 @@ static struct device_iface *SETUPDI_CreateDeviceInterface(struct device *device, iface->symlink = symlink; iface->device = device; iface->class = *class; - iface->flags = SPINT_ACTIVE; /* FIXME */ + iface->flags = 0;
if (!(path = get_iface_key_path(iface))) { @@ -365,6 +386,10 @@ static struct device_iface *SETUPDI_CreateDeviceInterface(struct device *device, } RegSetValueExW(key, SymbolicLink, 0, REG_SZ, (BYTE *)iface->symlink, lstrlenW(iface->symlink) * sizeof(WCHAR)); + + if (is_linked(key)) + iface->flags |= SPINT_ACTIVE; + RegCloseKey(key); heap_free(path);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/setupapi/devinst.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index c69304b..4d53bd7 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -1986,7 +1986,8 @@ end: return ret; }
-static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, const GUID *guid) +static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, + const GUID *guid, DWORD flags) { DWORD i, len; WCHAR subKeyName[MAX_PATH]; @@ -2004,19 +2005,23 @@ static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, const G if (*subKeyName == '#') { /* The subkey name is the reference string, with a '#' prepended */ - iface = SETUPDI_CreateDeviceInterface(device, guid, subKeyName + 1); l = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey); if (!l) { WCHAR symbolicLink[MAX_PATH]; DWORD dataType;
- len = sizeof(symbolicLink); - l = RegQueryValueExW(subKey, SymbolicLink, NULL, &dataType, - (BYTE *)symbolicLink, &len); - if (!l && dataType == REG_SZ) - SETUPDI_SetInterfaceSymbolicLink(iface, symbolicLink); - RegCloseKey(subKey); + if (!(flags & DIGCF_PRESENT) || is_linked(subKey)) + { + iface = SETUPDI_CreateDeviceInterface(device, guid, subKeyName + 1); + + len = sizeof(symbolicLink); + l = RegQueryValueExW(subKey, SymbolicLink, NULL, &dataType, + (BYTE *)symbolicLink, &len); + if (!l && dataType == REG_SZ) + SETUPDI_SetInterfaceSymbolicLink(iface, symbolicLink); + RegCloseKey(subKey); + } } } /* Allow enumeration to continue */ @@ -2027,7 +2032,7 @@ static void SETUPDI_AddDeviceInterfaces(struct device *device, HKEY key, const G }
static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet, - HKEY key, const GUID *guid, LPCWSTR enumstr) + HKEY key, const GUID *guid, const WCHAR *enumstr, DWORD flags) { struct DeviceInfoSet *set = DeviceInfoSet; DWORD i, len; @@ -2084,7 +2089,7 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet, &deviceClass); if ((device = SETUPDI_CreateDeviceInfo(set, &deviceClass, deviceInst, FALSE))) - SETUPDI_AddDeviceInterfaces(device, subKey, guid); + SETUPDI_AddDeviceInterfaces(device, subKey, guid, flags); } RegCloseKey(deviceKey); } @@ -2139,7 +2144,7 @@ static void SETUPDI_EnumerateInterfaces(HDEVINFO DeviceInfoSet, if (!l) { SETUPDI_EnumerateMatchingInterfaces(DeviceInfoSet, - interfaceKey, &interfaceGuid, enumstr); + interfaceKey, &interfaceGuid, enumstr, flags); RegCloseKey(interfaceKey); } } @@ -2152,7 +2157,7 @@ static void SETUPDI_EnumerateInterfaces(HDEVINFO DeviceInfoSet, * interface's key, so just pass that long */ SETUPDI_EnumerateMatchingInterfaces(DeviceInfoSet, - interfacesKey, guid, enumstr); + interfacesKey, guid, enumstr, flags); } RegCloseKey(interfacesKey); } @@ -2328,8 +2333,7 @@ HDEVINFO WINAPI SetupDiGetClassDevsW(const GUID *class, LPCWSTR enumstr, HWND pa HDEVINFO WINAPI SetupDiGetClassDevsExW(const GUID *class, PCWSTR enumstr, HWND parent, DWORD flags, HDEVINFO deviceset, PCWSTR machine, void *reserved) { - static const DWORD unsupportedFlags = DIGCF_DEFAULT | DIGCF_PRESENT | - DIGCF_PROFILE; + static const DWORD unsupportedFlags = DIGCF_DEFAULT | DIGCF_PROFILE; HDEVINFO set;
TRACE("%s %s %p 0x%08x %p %s %p\n", debugstr_guid(class),
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/hid/tests/device.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/hid/tests/device.c b/dlls/hid/tests/device.c index ce9b3a5..f20677f 100644 --- a/dlls/hid/tests/device.c +++ b/dlls/hid/tests/device.c @@ -66,7 +66,7 @@ static void run_for_each_device(device_test *test) data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); while (SetupDiEnumDeviceInterfaces(info_set, NULL, &hid_guid, index, &interface_data)) { index ++; @@ -74,11 +74,13 @@ static void run_for_each_device(device_test *test) if (SetupDiGetDeviceInterfaceDetailW(info_set, &interface_data, data, sizeof(*data) + detail_size, NULL, NULL)) { HANDLE file = CreateFileW(data->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); - if (file == INVALID_HANDLE_VALUE) + if (file == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) { - trace("Failed to access device %s, likely not plugged in or access is denied.\n", wine_dbgstr_w(data->DevicePath)); + trace("Not enough permissions to read device %s.\n", wine_dbgstr_w(data->DevicePath)); continue; } + ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", + wine_dbgstr_w(data->DevicePath), GetLastError());
test(file);
@@ -108,7 +110,7 @@ static HANDLE get_device(USHORT page, USHORT usages[], UINT usage_count, DWORD a data = HeapAlloc(GetProcessHeap(), 0 , sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); while (SetupDiEnumDeviceInterfaces(info_set, NULL, &hid_guid, index, &interface_data)) { index ++; @@ -118,11 +120,13 @@ static HANDLE get_device(USHORT page, USHORT usages[], UINT usage_count, DWORD a PHIDP_PREPARSED_DATA ppd; HIDP_CAPS Caps; HANDLE file = CreateFileW(data->DevicePath, access, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - if (file == INVALID_HANDLE_VALUE) + if (file == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) { - trace("Failed to access device %s, likely not plugged in or access is denied.\n", wine_dbgstr_w(data->DevicePath)); + trace("Not enough permissions to read device %s.\n", wine_dbgstr_w(data->DevicePath)); continue; } + ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError()); + rc = HidD_GetPreparsedData(file, &ppd); ok(rc, "Failed to get preparsed data(0x%x)\n", GetLastError()); status = HidP_GetCaps(ppd, &Caps);
Signed-off-by: Aric Stewart aric@codeweavers.com
On 8/16/18 5:53 PM, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/hid/tests/device.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/hid/tests/device.c b/dlls/hid/tests/device.c index ce9b3a5..f20677f 100644 --- a/dlls/hid/tests/device.c +++ b/dlls/hid/tests/device.c @@ -66,7 +66,7 @@ static void run_for_each_device(device_test *test) data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); while (SetupDiEnumDeviceInterfaces(info_set, NULL, &hid_guid, index, &interface_data)) { index ++;
@@ -74,11 +74,13 @@ static void run_for_each_device(device_test *test) if (SetupDiGetDeviceInterfaceDetailW(info_set, &interface_data, data, sizeof(*data) + detail_size, NULL, NULL)) { HANDLE file = CreateFileW(data->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
if (file == INVALID_HANDLE_VALUE)
if (file == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) {
trace("Failed to access device %s, likely not plugged in or access is denied.\n", wine_dbgstr_w(data->DevicePath));
trace("Not enough permissions to read device %s.\n", wine_dbgstr_w(data->DevicePath)); continue; }
ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n",
wine_dbgstr_w(data->DevicePath), GetLastError()); test(file);
@@ -108,7 +110,7 @@ static HANDLE get_device(USHORT page, USHORT usages[], UINT usage_count, DWORD a data = HeapAlloc(GetProcessHeap(), 0 , sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
- info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); while (SetupDiEnumDeviceInterfaces(info_set, NULL, &hid_guid, index, &interface_data)) { index ++;
@@ -118,11 +120,13 @@ static HANDLE get_device(USHORT page, USHORT usages[], UINT usage_count, DWORD a PHIDP_PREPARSED_DATA ppd; HIDP_CAPS Caps; HANDLE file = CreateFileW(data->DevicePath, access, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (file == INVALID_HANDLE_VALUE)
if (file == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) {
trace("Failed to access device %s, likely not plugged in or access is denied.\n", wine_dbgstr_w(data->DevicePath));
trace("Not enough permissions to read device %s.\n", wine_dbgstr_w(data->DevicePath)); continue; }
ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
rc = HidD_GetPreparsedData(file, &ppd); ok(rc, "Failed to get preparsed data(0x%x)\n", GetLastError()); status = HidP_GetCaps(ppd, &Caps);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/xinput1_3/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index 3c54890..8a35443 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -241,7 +241,7 @@ void HID_find_gamepads(xinput_controller *devices)
EnterCriticalSection(&hid_xinput_crit);
- device_info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE); + device_info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
data = HeapAlloc(GetProcessHeap(), 0 , sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
Signed-off-by: Aric Stewart aric@codeweavers.com
On 8/16/18 5:53 PM, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
dlls/xinput1_3/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/xinput1_3/hid.c b/dlls/xinput1_3/hid.c index 3c54890..8a35443 100644 --- a/dlls/xinput1_3/hid.c +++ b/dlls/xinput1_3/hid.c @@ -241,7 +241,7 @@ void HID_find_gamepads(xinput_controller *devices)
EnterCriticalSection(&hid_xinput_crit);
- device_info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
device_info_set = SetupDiGetClassDevsW(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
data = HeapAlloc(GetProcessHeap(), 0 , sizeof(*data) + detail_size); data->cbSize = sizeof(*data);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/hidclass.sys/device.c | 3 +++ dlls/hidclass.sys/pnp.c | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 2d98666..1522676 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -30,6 +30,7 @@
#include "ddk/hidsdi.h" #include "ddk/hidtypes.h" +#include "ddk/wdm.h"
#include "wine/debug.h" #include "wine/server.h" @@ -168,6 +169,8 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device TRACE("Delete link %s\n", debugstr_w(ext->link_name)); RtlInitUnicodeString(&linkW, ext->link_name);
+ IoSetDeviceInterfaceState(&linkW, FALSE); + status = IoDeleteSymbolicLink(&linkW); if (status != STATUS_SUCCESS) ERR("Delete Symbolic Link failed (%x)\n",status); diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c index 6ee89c1..34bd944 100644 --- a/dlls/hidclass.sys/pnp.c +++ b/dlls/hidclass.sys/pnp.c @@ -23,6 +23,7 @@ #include <stdarg.h> #include "hid.h" #include "ddk/hidtypes.h" +#include "ddk/wdm.h" #include "regstr.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -282,6 +283,17 @@ NTSTATUS WINAPI HID_PNP_Dispatch(DEVICE_OBJECT *device, IRP *irp) } break; } + case IRP_MN_START_DEVICE: + { + BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + UNICODE_STRING linkU; + + rc = minidriver->PNPDispatch(device, irp); + + RtlInitUnicodeString(&linkU, ext->link_name); + IoSetDeviceInterfaceState(&linkU, TRUE); + return rc; + } case IRP_MN_REMOVE_DEVICE: { return PNP_RemoveDevice(minidriver, device, irp);
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=40804
Your paranoid android.
=== debian9 (build) === error: patch failed: dlls/hidclass.sys/device.c:30 Task: Patch failed to apply
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ntoskrnl.exe/Makefile.in | 1 + dlls/ntoskrnl.exe/ntoskrnl.c | 93 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+)
diff --git a/dlls/ntoskrnl.exe/Makefile.in b/dlls/ntoskrnl.exe/Makefile.in index b459c54..5b03c59 100644 --- a/dlls/ntoskrnl.exe/Makefile.in +++ b/dlls/ntoskrnl.exe/Makefile.in @@ -1,6 +1,7 @@ MODULE = ntoskrnl.exe IMPORTLIB = ntoskrnl IMPORTS = advapi32 +DELAYIMPORTS = user32
C_SRCS = \ instr.c \ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index f92dd58..280bf27 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -36,6 +36,9 @@ #include "winternl.h" #include "excpt.h" #include "winioctl.h" +#include "winbase.h" +#include "winuser.h" +#include "dbt.h" #include "ddk/csq.h" #include "ddk/ntddk.h" #include "ddk/ntifs.h" @@ -145,6 +148,77 @@ static inline LPCSTR debugstr_us( const UNICODE_STRING *us ) return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) ); }
+static inline BOOL is_valid_hex(WCHAR c) +{ + if (!(((c >= '0') && (c <= '9')) || + ((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F')))) + return FALSE; + return TRUE; +} + +static const BYTE guid_conv_table[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */ + 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* 0x60 */ +}; + +static BOOL guid_from_string(const WCHAR *s, GUID *id) +{ + int i; + + if (!s || s[0] != '{') + { + memset( id, 0, sizeof (CLSID) ); + return FALSE; + } + + id->Data1 = 0; + for (i = 1; i < 9; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data1 = (id->Data1 << 4) | guid_conv_table[s[i]]; + } + if (s[9] != '-') return FALSE; + + id->Data2 = 0; + for (i = 10; i < 14; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data2 = (id->Data2 << 4) | guid_conv_table[s[i]]; + } + if (s[14] != '-') return FALSE; + + id->Data3 = 0; + for (i = 15; i < 19; i++) + { + if (!is_valid_hex(s[i])) return FALSE; + id->Data3 = (id->Data3 << 4) | guid_conv_table[s[i]]; + } + if (s[19] != '-') return FALSE; + + for (i = 20; i < 37; i += 2) + { + if (i == 24) + { + if (s[i] != '-') return FALSE; + i++; + } + if (!is_valid_hex(s[i]) || !is_valid_hex(s[i+1])) return FALSE; + id->Data4[(i-20)/2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]]; + } + + if (s[37] == '}') + return TRUE; + + return FALSE; +} + static HANDLE get_device_manager(void) { static HANDLE device_manager; @@ -1208,17 +1282,22 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable const WCHAR hashW[] = {'#',0};
size_t namelen = name->Length / sizeof(WCHAR); + DEV_BROADCAST_DEVICEINTERFACE_W *broadcast; HANDLE iface_key, control_key; OBJECT_ATTRIBUTES attr = {0}; WCHAR *path, *refstr, *p; UNICODE_STRING string; NTSTATUS ret; size_t len; + GUID class;
TRACE("(%s, %d)\n", debugstr_us(name), enable);
refstr = memrchrW(name->Buffer + 4, '\', namelen - 4);
+ if (!guid_from_string( (refstr ? refstr : name->Buffer + namelen) - 38, &class )) + return STATUS_INVALID_PARAMETER; + len = strlenW(DeviceClassesW) + 38 + 1 + namelen + 2;
if (!(path = heap_alloc( len * sizeof(WCHAR) ))) @@ -1255,6 +1334,20 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable }
heap_free( path ); + + len = offsetof(DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_name[namelen + 1]); + + if ((broadcast = heap_alloc( len ))) + { + broadcast->dbcc_size = len; + broadcast->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + broadcast->dbcc_classguid = class; + lstrcpynW( broadcast->dbcc_name, name->Buffer, namelen + 1 ); + BroadcastSystemMessageW( BSF_FORCEIFHUNG | BSF_QUERY, NULL, WM_DEVICECHANGE, + enable ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, (LPARAM)broadcast ); + + heap_free( broadcast ); + } return ret; }
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=40805
Your paranoid android.
=== debian9 (build) === error: patch failed: dlls/hidclass.sys/device.c:30 Task: Patch failed to apply