winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
April 2021
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
2 participants
865 discussions
Start a n
N
ew thread
Rémi Bernon : user32/tests: Factor GetKeyState test checks together.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: c19cba3f0387246b5c88b89e35cdd7c7e558ebe9 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=c19cba3f0387246b5c88b89e…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Fri Apr 2 10:07:56 2021 +0200 user32/tests: Factor GetKeyState test checks together. Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=26269
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=27238
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=31899
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=35907
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=45385
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/user32/tests/input.c | 128 +++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 65 deletions(-) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 9d75daa0bd5..9540566867f 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3739,15 +3739,48 @@ struct get_key_state_thread_params int index; }; +#define check_get_keyboard_state(i, c, x, todo) check_get_keyboard_state_(i, c, x, todo, __LINE__) +static void check_get_keyboard_state_(int i, int c, int x, int todo, int line) +{ + unsigned char keystate[256]; + BOOL ret; + + memset(keystate, 0, sizeof(keystate)); + ret = GetKeyboardState(keystate); + ok_(__FILE__, line)(ret, "GetKeyboardState failed, %u\n", GetLastError()); + todo_wine_if(todo) ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d: expected that X keystate is %s\n", i, x ? "set" : "unset"); + ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d: expected that C keystate is %s\n", i, c ? "set" : "unset"); + + /* calling it twice shouldn't change */ + memset(keystate, 0, sizeof(keystate)); + ret = GetKeyboardState(keystate); + ok_(__FILE__, line)(ret, "GetKeyboardState failed, %u\n", GetLastError()); + todo_wine_if(todo) ok_(__FILE__, line)(!(keystate['X'] & 0x80) == !x, "%d: expected that X keystate is %s\n", i, x ? "set" : "unset"); + ok_(__FILE__, line)(!(keystate['C'] & 0x80) == !c, "%d: expected that C keystate is %s\n", i, c ? "set" : "unset"); +} + +#define check_get_key_state(i, c, x, todo) check_get_key_state_(i, c, x, todo, __LINE__) +static void check_get_key_state_(int i, int c, int x, int todo, int line) +{ + SHORT state; + + state = GetKeyState('X'); + todo_wine_if(todo) ok_(__FILE__, line)(!(state & 0x8000) == !x, "%d: expected that X highest bit is %s, got %#x\n", i, x ? "set" : "unset", state); + ok_(__FILE__, line)(!(state & 0x007e), "%d: expected that X undefined bits are unset, got %#x\n", i, state); + + state = GetKeyState('C'); + ok_(__FILE__, line)(!(state & 0x8000) == !c, "%d: expected that C highest bit is %s, got %#x\n", i, c ? "set" : "unset", state); + ok_(__FILE__, line)(!(state & 0x007e), "%d: expected that C undefined bits are unset, got %#x\n", i, state); +} + static DWORD WINAPI get_key_state_thread(void *arg) { struct get_key_state_thread_params *params = arg; struct get_key_state_test_desc* test; HANDLE *semaphores = params->semaphores; DWORD result; - BYTE keystate[256]; BOOL has_queue; - BOOL ret; + BOOL expect_x; MSG msg; int i = params->index; @@ -3770,67 +3803,21 @@ static DWORD WINAPI get_key_state_thread(void *arg) result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "%d: WaitForSingleObject returned %u\n", i, result); - memset(keystate, 0, sizeof(keystate)); - ret = GetKeyboardState(keystate); - ok(ret, "GetKeyboardState failed, %u\n", GetLastError()); - result = keystate['X']; - todo_wine_if(!has_queue) - ok(!result, "%d: expected that keystate is not set, got %#x\n", i, result); - - result = keystate['C']; - ok(!result, "%d: expected that C keystate is not set, got %#x\n", i, result); + if (!has_queue) expect_x = FALSE; + else expect_x = TRUE; - result = GetKeyState('X'); - if (!has_queue) todo_wine ok(!(result & 0x8000), "%d: expected that highest bit is unset, got %#x\n", i, result); - else todo_wine ok((result & 0x8000), "%d: expected that highest bit is set, got %#x\n", i, result); - ok(!(result & 0x007e), "%d: expected that undefined bits are unset, got %#x\n", i, result); - - result = GetKeyState('C'); - ok(!(result & 0x8000), "%d: expected that C highest bit is unset, got %#x\n", i, result); - ok(!(result & 0x007e), "%d: expected that C undefined bits are unset, got %#x\n", i, result); - - memset(keystate, 0, sizeof(keystate)); - ret = GetKeyboardState(keystate); - ok(ret, "GetKeyboardState failed, %u\n", GetLastError()); - result = keystate['X']; - if (!has_queue) todo_wine ok(!result, "%d: expected that keystate is unset, got %#x\n", i, result); - else todo_wine ok(result, "%d: expected that keystate is set, got %#x\n", i, result); - - result = keystate['C']; - ok(!result, "%d: expected that C keystate is not set, got %#x\n", i, result); + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ !has_queue); + check_get_key_state(i, FALSE, expect_x, /* todo */ TRUE); + check_get_keyboard_state(i, FALSE, expect_x, /* todo */ TRUE); /* key released */ ReleaseSemaphore(semaphores[0], 1, NULL); result = WaitForSingleObject(semaphores[1], 1000); ok(result == WAIT_OBJECT_0, "%d: WaitForSingleObject returned %u\n", i, result); - memset(keystate, 0, sizeof(keystate)); - ret = GetKeyboardState(keystate); - ok(ret, "GetKeyboardState failed, %u\n", GetLastError()); - result = keystate['X']; - if (!has_queue) ok(!result, "%d: expected that keystate is unset, got %#x\n", i, result); - else todo_wine ok(result, "%d: expected that keystate is set, got %#x\n", i, result); - - result = keystate['C']; - ok(!result, "%d: expected that C keystate is not set, got %#x\n", i, result); - - result = GetKeyState('X'); - ok(!(result & 0x8000), "%d: expected that highest bit is unset, got %#x\n", i, result); - ok(!(result & 0x007e), "%d: expected that undefined bits are unset, got %#x\n", i, result); - - result = GetKeyState('C'); - ok(!(result & 0x8000), "%d: expected that C highest bit is unset, got %#x\n", i, result); - ok(!(result & 0x007e), "%d: expected that C undefined bits are unset, got %#x\n", i, result); - - memset(keystate, 0, sizeof(keystate)); - ret = GetKeyboardState(keystate); - ok(ret, "GetKeyboardState failed, %u\n", GetLastError()); - result = keystate['X']; - if (!has_queue) ok(!result || broken(result) /* w2008 */, "%d: expected that keystate is unset, got %#x\n", i, result); - else todo_wine ok(result || broken(!result) /* w2008 */, "%d: expected that keystate is set, got %#x\n", i, result); - - result = keystate['C']; - ok(!result, "%d: expected that C keystate is not set, got %#x\n", i, result); + check_get_keyboard_state(i, FALSE, expect_x, /* todo */ has_queue); + check_get_key_state(i, FALSE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ FALSE); return 0; } @@ -3841,6 +3828,7 @@ static void test_GetKeyState(void) HANDLE thread; DWORD result; BYTE keystate[256]; + BOOL expect_x; HWND hwnd; MSG msg; int i; @@ -3888,13 +3876,19 @@ static void test_GetKeyState(void) keybd_event('X', 0, 0, 0); keystate['C'] = 0xff; SetKeyboardState(keystate); + + check_get_keyboard_state(i, TRUE, FALSE, /* todo */ FALSE); + check_get_key_state(i, TRUE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, TRUE, FALSE, /* todo */ FALSE); + if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - result = GetKeyState('C'); - ok((result & 0x8000), "%d: expected that highest bit is set, got %#x\n", i, result); - result = GetKeyState('X'); - if (test->peek_message_main) ok((result & 0x8000), "%d: expected that highest bit is set, got %#x\n", i, result); - else ok(!(result & 0x8000), "%d: expected that highest bit is unset, got %#x\n", i, result); + if (test->peek_message_main) expect_x = TRUE; + else expect_x = FALSE; + + check_get_keyboard_state(i, TRUE, expect_x, /* todo */ FALSE); + check_get_key_state(i, TRUE, expect_x, /* todo */ FALSE); + check_get_keyboard_state(i, TRUE, expect_x, /* todo */ FALSE); ReleaseSemaphore(params.semaphores[1], 1, NULL); @@ -3905,12 +3899,16 @@ static void test_GetKeyState(void) keybd_event('X', 0, KEYEVENTF_KEYUP, 0); keystate['C'] = 0x00; SetKeyboardState(keystate); + + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ FALSE); + check_get_key_state(i, FALSE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ FALSE); + if (test->peek_message_main) while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - result = GetKeyState('C'); - ok(!(result & 0x8000), "%d: expected that highest bit is unset, got %#x\n", i, result); - result = GetKeyState('X'); - ok(!(result & 0x8000), "%d: expected that highest bit is unset, got %#x\n", i, result); + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ FALSE); + check_get_key_state(i, FALSE, FALSE, /* todo */ FALSE); + check_get_keyboard_state(i, FALSE, FALSE, /* todo */ FALSE); ReleaseSemaphore(params.semaphores[1], 1, NULL);
1
0
0
0
Zebediah Figura : ntoskrnl/tests: Add a basic PnP test driver.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: c4986ee2d5a31980d6b879b1fa0d1a6931b53813 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=c4986ee2d5a31980d6b879b1…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:41 2021 -0500 ntoskrnl/tests: Add a basic PnP test driver. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntoskrnl.exe/tests/Makefile.in | 6 +- dlls/ntoskrnl.exe/tests/driver_pnp.c | 143 ++++++++++++++++++++ dlls/ntoskrnl.exe/tests/driver_pnp.spec | 1 + dlls/ntoskrnl.exe/tests/ntoskrnl.c | 226 ++++++++++++++++++++++++++++++++ 4 files changed, 375 insertions(+), 1 deletion(-) Diff:
https://source.winehq.org/git/wine.git/?a=commitdiff;h=c4986ee2d5a31980d6b8…
1
0
0
0
Zebediah Figura : ntoskrnl/tests: Skip all tests under WoW64.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: eb5ff50276ee6c388cd277aaa2e8154f135b4a3d URL:
https://source.winehq.org/git/wine.git/?a=commit;h=eb5ff50276ee6c388cd277aa…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:40 2021 -0500 ntoskrnl/tests: Skip all tests under WoW64. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index c3ebe5b8ee1..e65dac38cec 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -43,6 +43,7 @@ static HANDLE device; static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR *, UNICODE_STRING *, WCHAR **, CURDIR *); static BOOL (WINAPI *pRtlFreeUnicodeString)(UNICODE_STRING *); static BOOL (WINAPI *pCancelIoEx)(HANDLE, OVERLAPPED *); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); static HRESULT (WINAPI *pSignerSign)(SIGNER_SUBJECT_INFO *subject, SIGNER_CERT *cert, SIGNER_SIGNATURE_INFO *signature, SIGNER_PROVIDER_INFO *provider, @@ -939,16 +940,23 @@ START_TEST(ntoskrnl) WCHAR filename[MAX_PATH], filename2[MAX_PATH]; struct testsign_context ctx; SC_HANDLE service, service2; + BOOL ret, is_wow64; DWORD written; - BOOL ret; pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlDosPathNameToNtPathName_U"); pRtlFreeUnicodeString = (void *)GetProcAddress(GetModuleHandleA("ntdll"), "RtlFreeUnicodeString"); pCancelIoEx = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CancelIoEx"); + pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); pSetFileCompletionNotificationModes = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "SetFileCompletionNotificationModes"); pSignerSign = (void *)GetProcAddress(LoadLibraryA("mssign32"), "SignerSign"); + if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) + { + skip("Running in WoW64.\n"); + return; + } + if (!testsign_create_cert(&ctx)) return;
1
0
0
0
Zebediah Figura : setupapi: Reënumerate root PnP devices in SetupDiRemoveDevice().
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: f0230286403e56c1935418cded95e9e05dfadc0f URL:
https://source.winehq.org/git/wine.git/?a=commit;h=f0230286403e56c1935418cd…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:39 2021 -0500 setupapi: Reënumerate root PnP devices in SetupDiRemoveDevice(). Allow them to be unloaded. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/setupapi/devinst.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 0a396cc8464..8f826c30250 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -19,6 +19,7 @@ */ #include <stdarg.h> +#include <stdlib.h> #include "windef.h" #include "winbase.h" @@ -1692,15 +1693,38 @@ BOOL WINAPI SetupDiRegisterDeviceInfo(HDEVINFO devinfo, SP_DEVINFO_DATA *device_ */ BOOL WINAPI SetupDiRemoveDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) { + SC_HANDLE manager = NULL, service = NULL; struct device *device; + WCHAR *service_name; + DWORD size; TRACE("devinfo %p, device_data %p.\n", devinfo, device_data); if (!(device = get_device(devinfo, device_data))) return FALSE; + if (!(manager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT))) + return FALSE; + + if (!RegGetValueW(device->key, NULL, L"Service", RRF_RT_REG_SZ, NULL, NULL, &size)) + { + service_name = malloc(size); + if (!RegGetValueW(device->key, NULL, L"Service", RRF_RT_REG_SZ, NULL, service_name, &size)) + service = OpenServiceW(manager, service_name, SERVICE_USER_DEFINED_CONTROL); + free(service_name); + } + remove_device(device); + if (service) + { + SERVICE_STATUS status; + if (!ControlService(service, SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES, &status)) + ERR("Failed to control service %s, error %u.\n", debugstr_w(service_name), GetLastError()); + CloseServiceHandle(service); + } + CloseServiceHandle(manager); + return TRUE; }
1
0
0
0
Zebediah Figura : setupapi: Reënumerate root PnP devices in SetupDiInstallDevice().
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: 304b094d1633361d7a6ea69451b48b48d88686f5 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=304b094d1633361d7a6ea694…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:37 2021 -0500 setupapi: Reënumerate root PnP devices in SetupDiInstallDevice(). If the service is already running, starting it has no effect. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/setupapi/devinst.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index de0413e74f5..0a396cc8464 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -104,6 +104,8 @@ static const WCHAR AddInterface[] = {'A','d','d','I','n','t','e','r','f','a','c' static const WCHAR backslashW[] = {'\\',0}; static const WCHAR emptyW[] = {0}; +#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128 + struct driver { WCHAR inf_path[MAX_PATH]; @@ -5123,13 +5125,20 @@ BOOL WINAPI SetupDiInstallDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) if (!wcsnicmp(device->instanceId, rootW, lstrlenW(rootW)) && svc_name[0] && (manager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT))) { - if ((service = OpenServiceW(manager, svc_name, SERVICE_START))) + if ((service = OpenServiceW(manager, svc_name, SERVICE_START | SERVICE_USER_DEFINED_CONTROL))) { + SERVICE_STATUS status; + if (!StartServiceW(service, 0, NULL) && GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { ERR("Failed to start service %s for device %s, error %u.\n", debugstr_w(svc_name), debugstr_w(device->instanceId), GetLastError()); } + if (!ControlService(service, SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES, &status)) + { + ERR("Failed to control service %s for device %s, error %u.\n", + debugstr_w(svc_name), debugstr_w(device->instanceId), GetLastError()); + } CloseServiceHandle(service); } else
1
0
0
0
Zebediah Figura : winedevice: Introduce a custom service control to reënumerate root PnP devices.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: 73bfe36eab54e28b8deddc3ad1cf1d2df29f6956 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=73bfe36eab54e28b8deddc3a…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:35 2021 -0500 winedevice: Introduce a custom service control to reënumerate root PnP devices. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntoskrnl.exe/ntoskrnl.c | 2 +- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 + dlls/ntoskrnl.exe/ntoskrnl_private.h | 3 ++- dlls/ntoskrnl.exe/pnp.c | 23 +++++++++++++++++++---- programs/winedevice/device.c | 6 ++++++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 1ddd3f4d4f0..bb9f4bf5259 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3824,7 +3824,7 @@ NTSTATUS WINAPI ZwLoadDriver( const UNICODE_STRING *service_name ) driver = WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry ); driver->service_handle = service_handle; - pnp_manager_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) ); + wine_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) ); set_service_status( service_handle, SERVICE_RUNNING, SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ); diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 0f5ab76a195..6dea87f347b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -1686,3 +1686,4 @@ # or 'wine_' (for user-visible functions) to avoid namespace conflicts. @ cdecl wine_ntoskrnl_main_loop(long) +@ cdecl wine_enumerate_root_devices(wstr) diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index c0b588f3135..c736a9805a0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -101,11 +101,12 @@ struct wine_driver void ObReferenceObject( void *obj ) DECLSPEC_HIDDEN; -void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) DECLSPEC_HIDDEN; void pnp_manager_start(void) DECLSPEC_HIDDEN; void pnp_manager_stop_driver( struct wine_driver *driver ) DECLSPEC_HIDDEN; void pnp_manager_stop(void) DECLSPEC_HIDDEN; +void CDECL wine_enumerate_root_devices( const WCHAR *driver_name ); + struct wine_driver *get_driver( const WCHAR *name ) DECLSPEC_HIDDEN; static const WCHAR servicesW[] = {'\\','R','e','g','i','s','t','r','y', diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index dce6bb90c68..7994a8b85b9 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -1047,13 +1047,14 @@ void pnp_manager_stop(void) RpcBindingFree( &plugplay_binding_handle ); } -void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) +void CDECL wine_enumerate_root_devices( const WCHAR *driver_name ) { static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0}; static const WCHAR rootW[] = {'R','O','O','T',0}; WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN]; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; - struct root_pnp_device *pnp_device; + struct list new_list = LIST_INIT(new_list); + struct root_pnp_device *pnp_device, *next; struct wine_driver *driver; DEVICE_OBJECT *device; NTSTATUS status; @@ -1082,8 +1083,13 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL ); - if (find_root_pnp_device( driver, id )) + if ((pnp_device = find_root_pnp_device( driver, id ))) + { + TRACE("Found device %s already enumerated.\n", debugstr_w(id)); + list_remove( &pnp_device->entry ); + list_add_tail( &new_list, &pnp_device->entry ); continue; + } TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id)); @@ -1097,10 +1103,19 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - list_add_tail( &driver->root_pnp_devices, &pnp_device->entry ); + list_add_tail( &new_list, &pnp_device->entry ); start_device( device, set, &sp_device ); } + LIST_FOR_EACH_ENTRY_SAFE( pnp_device, next, &driver->root_pnp_devices, struct root_pnp_device, entry ) + { + TRACE("Removing device %s.\n", debugstr_w(pnp_device->id)); + + remove_device( pnp_device->device ); + } + + list_move_head( &driver->root_pnp_devices, &new_list ); + SetupDiDestroyDeviceInfoList(set); } diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c index 3acc5e8a799..509cab96308 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedevice); static const WCHAR servicesW[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ); +extern void CDECL wine_enumerate_root_devices( const WCHAR *driver_name ); static WCHAR winedeviceW[] = L"winedevice"; static SERVICE_STATUS_HANDLE service_handle; @@ -55,6 +56,8 @@ static void set_service_status( SERVICE_STATUS_HANDLE handle, DWORD state, DWORD SetServiceStatus( handle, &status ); } +#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128 + static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name ) { UNICODE_STRING service_name; @@ -78,6 +81,9 @@ static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name ) result = RtlNtStatusToDosError(ZwUnloadDriver( &service_name )); break; + case SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES: + wine_enumerate_root_devices( driver_name ); + default: FIXME( "got driver ctrl %x for %s\n", ctrl, wine_dbgstr_w(driver_name) ); break;
1
0
0
0
Zebediah Figura : ntoskrnl: Store root PnP devices per driver.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: 6977b81807009883c3fb1bfde0c02541a095007d URL:
https://source.winehq.org/git/wine.git/?a=commit;h=6977b81807009883c3fb1bfd…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:33 2021 -0500 ntoskrnl: Store root PnP devices per driver. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntoskrnl.exe/ntoskrnl.c | 52 +++++++++++++++++++----------------- dlls/ntoskrnl.exe/ntoskrnl_private.h | 26 ++++++++++++++++++ dlls/ntoskrnl.exe/pnp.c | 37 ++++++++++--------------- dlls/ntoskrnl.exe/sync.c | 13 +-------- 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 685f7d4345b..1ddd3f4d4f0 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -21,34 +21,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <stdarg.h> #include <assert.h> #define NONAMELESSUNION #define NONAMELESSSTRUCT -#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winsvc.h" -#include "winternl.h" +#include "ntoskrnl_private.h" #include "excpt.h" -#include "winioctl.h" -#include "winbase.h" #include "winreg.h" #include "ntsecapi.h" #include "ddk/csq.h" -#include "ddk/ntddk.h" -#include "ddk/ntifs.h" -#include "ddk/wdm.h" #include "wine/server.h" -#include "wine/debug.h" #include "wine/heap.h" -#include "wine/rbtree.h" #include "wine/svcctl.h" -#include "ntoskrnl_private.h" - WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); WINE_DECLARE_DEBUG_CHANNEL(relay); @@ -90,14 +76,6 @@ static void *ldr_notify_cookie; static PLOAD_IMAGE_NOTIFY_ROUTINE load_image_notify_routines[8]; static unsigned int load_image_notify_routine_count; -struct wine_driver -{ - DRIVER_OBJECT driver_obj; - DRIVER_EXTENSION driver_extension; - SERVICE_STATUS_HANDLE service_handle; - struct wine_rb_entry entry; -}; - static int wine_drivers_rb_compare( const void *key, const struct wine_rb_entry *entry ) { const struct wine_driver *driver = WINE_RB_ENTRY_VALUE( entry, const struct wine_driver, entry ); @@ -110,6 +88,24 @@ static struct wine_rb_tree wine_drivers = { wine_drivers_rb_compare }; DECLARE_CRITICAL_SECTION(drivers_cs); +struct wine_driver *get_driver( const WCHAR *name ) +{ + static const WCHAR driverW[] = L"\\Driver\\"; + struct wine_rb_entry *entry; + UNICODE_STRING drv_name; + + drv_name.Length = (wcslen( driverW ) + wcslen( name )) * sizeof(WCHAR); + if (!(drv_name.Buffer = malloc( drv_name.Length + sizeof(WCHAR) ))) + return NULL; + wcscpy( drv_name.Buffer, driverW ); + wcscat( drv_name.Buffer, name ); + entry = wine_rb_get( &wine_drivers, &drv_name ); + free( drv_name.Buffer ); + + if (entry) return WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry ); + return NULL; +} + static HANDLE get_device_manager(void) { static HANDLE device_manager; @@ -902,6 +898,7 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) HANDLE manager = get_device_manager(); struct dispatch_context context; NTSTATUS status = STATUS_SUCCESS; + struct wine_driver *driver; HANDLE handles[2]; context.handle = NULL; @@ -983,9 +980,13 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) done: /* Native PnP drivers expect that all of their devices will be removed when - * their unload routine is called, so we must stop the PnP manager first. */ - pnp_manager_stop(); + * their unload routine is called. Moreover, we cannot unload a module + * until we have removed devices for all lower drivers, so we have to stop + * all devices first, and then unload all drivers. */ + WINE_RB_FOR_EACH_ENTRY( driver, &wine_drivers, struct wine_driver, entry ) + pnp_manager_stop_driver( driver ); wine_rb_destroy( &wine_drivers, unload_driver, NULL ); + pnp_manager_stop(); return status; } @@ -1486,6 +1487,7 @@ NTSTATUS WINAPI IoCreateDriver( UNICODE_STRING *name, PDRIVER_INITIALIZE init ) build_driver_keypath( driver->driver_obj.DriverName.Buffer, &driver->driver_extension.ServiceKeyName ); for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) driver->driver_obj.MajorFunction[i] = unhandled_irp; + list_init( &driver->root_pnp_devices ); EnterCriticalSection( &drivers_cs ); if (wine_rb_put( &wine_drivers, &driver->driver_obj.DriverName, &driver->entry )) diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index a1e1b892e8c..c0b588f3135 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -21,7 +21,21 @@ #ifndef __WINE_NTOSKRNL_PRIVATE_H #define __WINE_NTOSKRNL_PRIVATE_H +#include <stdarg.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winioctl.h" +#include "winbase.h" +#include "winsvc.h" +#include "winternl.h" +#include "ddk/ntifs.h" +#include "ddk/wdm.h" + #include "wine/asm.h" +#include "wine/debug.h" +#include "wine/list.h" +#include "wine/rbtree.h" static inline LPCSTR debugstr_us( const UNICODE_STRING *us ) { @@ -76,12 +90,24 @@ extern POBJECT_TYPE SeTokenObjectType; 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \ static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 }; +struct wine_driver +{ + DRIVER_OBJECT driver_obj; + DRIVER_EXTENSION driver_extension; + SERVICE_STATUS_HANDLE service_handle; + struct wine_rb_entry entry; + struct list root_pnp_devices; +}; + void ObReferenceObject( void *obj ) DECLSPEC_HIDDEN; void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) DECLSPEC_HIDDEN; void pnp_manager_start(void) DECLSPEC_HIDDEN; +void pnp_manager_stop_driver( struct wine_driver *driver ) DECLSPEC_HIDDEN; void pnp_manager_stop(void) DECLSPEC_HIDDEN; +struct wine_driver *get_driver( const WCHAR *name ) DECLSPEC_HIDDEN; + static const WCHAR servicesW[] = {'\\','R','e','g','i','s','t','r','y', '\\','M','a','c','h','i','n','e', '\\','S','y','s','t','e','m', diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 913a63e8f0d..dce6bb90c68 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -20,31 +20,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <stdarg.h> - #define NONAMELESSUNION -#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winbase.h" -#include "winioctl.h" +#include "ntoskrnl_private.h" #include "winreg.h" #include "winuser.h" -#include "winsvc.h" -#include "winternl.h" #include "setupapi.h" #include "cfgmgr32.h" #include "dbt.h" -#include "ddk/wdm.h" -#include "ddk/ntifs.h" -#include "wine/debug.h" #include "wine/exception.h" #include "wine/heap.h" -#include "wine/rbtree.h" -#include "wine/list.h" -#include "ntoskrnl_private.h" #include "plugplay.h" #include "initguid.h" @@ -928,13 +914,11 @@ struct root_pnp_device DEVICE_OBJECT *device; }; -static struct list root_pnp_devices = LIST_INIT(root_pnp_devices); - -static struct root_pnp_device *find_root_pnp_device( const WCHAR *id ) +static struct root_pnp_device *find_root_pnp_device( struct wine_driver *driver, const WCHAR *id ) { struct root_pnp_device *device; - LIST_FOR_EACH_ENTRY( device, &root_pnp_devices, struct root_pnp_device, entry ) + LIST_FOR_EACH_ENTRY( device, &driver->root_pnp_devices, struct root_pnp_device, entry ) { if (!wcsicmp( id, device->id )) return device; @@ -1049,12 +1033,16 @@ void pnp_manager_start(void) ERR("RpcBindingFromStringBinding() failed, error %#x\n", err); } -void pnp_manager_stop(void) +void pnp_manager_stop_driver( struct wine_driver *driver ) { struct root_pnp_device *device, *next; - LIST_FOR_EACH_ENTRY_SAFE( device, next, &root_pnp_devices, struct root_pnp_device, entry ) + LIST_FOR_EACH_ENTRY_SAFE( device, next, &driver->root_pnp_devices, struct root_pnp_device, entry ) remove_device( device->device ); +} + +void pnp_manager_stop(void) +{ IoDeleteDriver( pnp_manager ); RpcBindingFree( &plugplay_binding_handle ); } @@ -1066,6 +1054,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN]; SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; struct root_pnp_device *pnp_device; + struct wine_driver *driver; DEVICE_OBJECT *device; NTSTATUS status; unsigned int i; @@ -1073,6 +1062,8 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) TRACE("Searching for new root-enumerated devices for driver %s.\n", debugstr_w(driver_name)); + driver = get_driver( driver_name ); + set = SetupDiGetClassDevsW( NULL, rootW, NULL, DIGCF_ALLCLASSES ); if (set == INVALID_HANDLE_VALUE) { @@ -1091,7 +1082,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL ); - if (find_root_pnp_device( id )) + if (find_root_pnp_device( driver, id )) continue; TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id)); @@ -1106,7 +1097,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - list_add_tail( &root_pnp_devices, &pnp_device->entry ); + list_add_tail( &driver->root_pnp_devices, &pnp_device->entry ); start_device( device, set, &sp_device ); } diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index 2aa60a0f2a0..445c8d890ab 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -19,24 +19,13 @@ */ #include <limits.h> -#include <stdarg.h> -#include "ntstatus.h" -#define WIN32_NO_STATUS -#include "windef.h" -#include "winbase.h" -#include "winternl.h" +#include "ntoskrnl_private.h" #include "ddk/ntddk.h" -#include "ddk/wdm.h" -#include "ddk/ntifs.h" -#include "wine/asm.h" -#include "wine/debug.h" #include "wine/heap.h" #include "wine/server.h" -#include "ntoskrnl_private.h" - WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl); enum object_type
1
0
0
0
Zebediah Figura : ntoskrnl: Store root PnP devices in a linked list.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: 414003e2d950be18a262624c24b7f391981e4380 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=414003e2d950be18a262624c…
Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Fri Apr 2 10:53:30 2021 -0500 ntoskrnl: Store root PnP devices in a linked list. It is quite rare to have more than one or two of these, and lists are slightly easier to work with. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntoskrnl.exe/pnp.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 6652be73c47..913a63e8f0d 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -42,6 +42,7 @@ #include "wine/exception.h" #include "wine/heap.h" #include "wine/rbtree.h" +#include "wine/list.h" #include "ntoskrnl_private.h" #include "plugplay.h" @@ -923,19 +924,24 @@ static DRIVER_OBJECT *pnp_manager; struct root_pnp_device { WCHAR id[MAX_DEVICE_ID_LEN]; - struct wine_rb_entry entry; + struct list entry; DEVICE_OBJECT *device; }; -static int root_pnp_devices_rb_compare( const void *key, const struct wine_rb_entry *entry ) +static struct list root_pnp_devices = LIST_INIT(root_pnp_devices); + +static struct root_pnp_device *find_root_pnp_device( const WCHAR *id ) { - const struct root_pnp_device *device = WINE_RB_ENTRY_VALUE( entry, const struct root_pnp_device, entry ); - const WCHAR *k = key; + struct root_pnp_device *device; - return wcsicmp( k, device->id ); -} + LIST_FOR_EACH_ENTRY( device, &root_pnp_devices, struct root_pnp_device, entry ) + { + if (!wcsicmp( id, device->id )) + return device; + } -static struct wine_rb_tree root_pnp_devices = { root_pnp_devices_rb_compare }; + return NULL; +} static NTSTATUS WINAPI pnp_manager_device_pnp( DEVICE_OBJECT *device, IRP *irp ) { @@ -1043,15 +1049,12 @@ void pnp_manager_start(void) ERR("RpcBindingFromStringBinding() failed, error %#x\n", err); } -static void destroy_root_pnp_device( struct wine_rb_entry *entry, void *context ) -{ - struct root_pnp_device *device = WINE_RB_ENTRY_VALUE(entry, struct root_pnp_device, entry); - remove_device( device->device ); -} - void pnp_manager_stop(void) { - wine_rb_destroy( &root_pnp_devices, destroy_root_pnp_device, NULL ); + struct root_pnp_device *device, *next; + + LIST_FOR_EACH_ENTRY_SAFE( device, next, &root_pnp_devices, struct root_pnp_device, entry ) + remove_device( device->device ); IoDeleteDriver( pnp_manager ); RpcBindingFree( &plugplay_binding_handle ); } @@ -1088,7 +1091,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL ); - if (wine_rb_get( &root_pnp_devices, id )) + if (find_root_pnp_device( id )) continue; TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id)); @@ -1103,12 +1106,7 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) pnp_device = device->DeviceExtension; wcscpy( pnp_device->id, id ); pnp_device->device = device; - if (wine_rb_put( &root_pnp_devices, id, &pnp_device->entry )) - { - ERR("Failed to insert device %s into tree.\n", debugstr_w(id)); - IoDeleteDevice( device ); - continue; - } + list_add_tail( &root_pnp_devices, &pnp_device->entry ); start_device( device, set, &sp_device ); }
1
0
0
0
Nikolay Sivov : mfreadwrite/reader: Improve decoder output samples handling.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: b50b65ab9360c9bd17d51425b93ac84559a43841 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=b50b65ab9360c9bd17d51425…
Author: Nikolay Sivov <nsivov(a)codeweavers.com> Date: Fri Apr 2 21:35:00 2021 +0300 mfreadwrite/reader: Improve decoder output samples handling. Equivalent of 706fd3dcce52c0deec7c98143d715a1d9016d3ad, but for the reader. Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/mfreadwrite/reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index d3df7abd9fc..ffe91f5d265 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -667,7 +667,7 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s { memset(&out_buffer, 0, sizeof(out_buffer)); - if (!(stream_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)) + if (!(stream_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES))) { if (FAILED(hr = MFCreateSample(&out_buffer.pSample))) break;
1
0
0
0
Jacek Caban : jscript: Add Object.isFrozen and Object.isSealed implementation.
by Alexandre Julliard
02 Apr '21
02 Apr '21
Module: wine Branch: master Commit: 1f49903e66b0a401e47e5951634c804a4b0d242c URL:
https://source.winehq.org/git/wine.git/?a=commit;h=1f49903e66b0a401e47e5951…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Fri Apr 2 20:24:37 2021 +0200 jscript: Add Object.isFrozen and Object.isSealed implementation. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/jscript/dispex.c | 20 ++++++++++++++ dlls/jscript/jscript.h | 1 + dlls/jscript/object.c | 46 ++++++++++++++++++++++++++++++++ dlls/mshtml/tests/es5.js | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+) diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index b62fcee0b04..188de659c4a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2646,6 +2646,26 @@ void jsdisp_freeze(jsdisp_t *obj, BOOL seal) obj->extensible = FALSE; } +BOOL jsdisp_is_frozen(jsdisp_t *obj, BOOL sealed) +{ + unsigned int i; + + if(obj->extensible) + return FALSE; + + for(i = 0; i < obj->prop_cnt; i++) { + if(obj->props[i].type == PROP_JSVAL) { + if(!sealed && (obj->props[i].flags & PROPF_WRITABLE)) + return FALSE; + }else if(obj->props[i].type != PROP_ACCESSOR) + continue; + if(obj->props[i].flags & PROPF_CONFIGURABLE) + return FALSE; + } + + return TRUE; +} + HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r) { dispex_prop_t *prop = get_prop(obj, id); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index ec5001af117..3c870a68a54 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -318,6 +318,7 @@ HRESULT jsdisp_define_data_property(jsdisp_t*,const WCHAR*,unsigned,jsval_t) DEC HRESULT jsdisp_next_prop(jsdisp_t*,DISPID,BOOL,DISPID*) DECLSPEC_HIDDEN; HRESULT jsdisp_get_prop_name(jsdisp_t*,DISPID,jsstr_t**); void jsdisp_freeze(jsdisp_t*,BOOL) DECLSPEC_HIDDEN; +BOOL jsdisp_is_frozen(jsdisp_t*,BOOL) DECLSPEC_HIDDEN; HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD, jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 86c656a719a..b957ea58bdf 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -760,6 +760,50 @@ static HRESULT Object_isExtensible(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag return S_OK; } +static HRESULT Object_isFrozen(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, + jsval_t *argv, jsval_t *r) +{ + jsdisp_t *obj; + + if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) { + WARN("argument is not an object\n"); + return JS_E_OBJECT_EXPECTED; + } + + TRACE("(%s)\n", debugstr_jsval(argv[0])); + + obj = to_jsdisp(get_object(argv[0])); + if(!obj) { + FIXME("Non-JS object\n"); + return E_NOTIMPL; + } + + if(r) *r = jsval_bool(jsdisp_is_frozen(obj, FALSE)); + return S_OK; +} + +static HRESULT Object_isSealed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, + jsval_t *argv, jsval_t *r) +{ + jsdisp_t *obj; + + if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) { + WARN("argument is not an object\n"); + return JS_E_OBJECT_EXPECTED; + } + + TRACE("(%s)\n", debugstr_jsval(argv[0])); + + obj = to_jsdisp(get_object(argv[0])); + if(!obj) { + FIXME("Non-JS object\n"); + return E_NOTIMPL; + } + + if(r) *r = jsval_bool(jsdisp_is_frozen(obj, TRUE)); + return S_OK; +} + static const builtin_prop_t ObjectConstr_props[] = { {L"create", Object_create, PROPF_ES5|PROPF_METHOD|2}, {L"defineProperties", Object_defineProperties, PROPF_ES5|PROPF_METHOD|2}, @@ -768,6 +812,8 @@ static const builtin_prop_t ObjectConstr_props[] = { {L"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor, PROPF_ES5|PROPF_METHOD|2}, {L"getPrototypeOf", Object_getPrototypeOf, PROPF_ES5|PROPF_METHOD|1}, {L"isExtensible", Object_isExtensible, PROPF_ES5|PROPF_METHOD|1}, + {L"isFrozen", Object_isFrozen, PROPF_ES5|PROPF_METHOD|1}, + {L"isSealed", Object_isSealed, PROPF_ES5|PROPF_METHOD|1}, {L"keys", Object_keys, PROPF_ES5|PROPF_METHOD|1}, {L"preventExtensions", Object_preventExtensions, PROPF_ES5|PROPF_METHOD|1}, {L"seal", Object_seal, PROPF_ES5|PROPF_METHOD|1}, diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 9227fa7e5a5..474c09d3bd7 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -1104,6 +1104,74 @@ sync_test("seal", function() { ok(o.length === 1, "o.length = " + o.length); }); +sync_test("isFrozen", function() { + ok(Object.isFrozen.length === 1, "Object.isFrozen.length = " + Object.isFrozen.length); + ok(Object.isSealed.length === 1, "Object.isSealed.length = " + Object.isSealed.length); + + var o = Object.freeze({}); + ok(Object.isFrozen(o) === true, "o is not frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + ok(Object.isFrozen({}) === false, "{} is frozen"); + ok(Object.isSealed({}) === false, "{} is sealed"); + + o = Object.preventExtensions({}); + ok(Object.isFrozen(o) === true, "o is not frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = Object.preventExtensions({ prop: 1 }); + ok(Object.isFrozen(o) === false, "o is frozen"); + ok(Object.isSealed(o) === false, "o is sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = Object.freeze({ prop: 1 }); + ok(Object.isFrozen(o) === true, "o is not frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = Object.seal({ prop: 1 }); + ok(Object.isFrozen(o) === false, "o is frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = {}; + Object.defineProperty(o, "prop", { value: 1 }); + Object.preventExtensions(o); + ok(Object.isFrozen(o) === true, "o is not frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = {}; + Object.defineProperty(o, "prop", { value: 1, writable: true }); + Object.preventExtensions(o); + ok(Object.isFrozen(o) === false, "o is frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = {}; + Object.defineProperty(o, "prop", { value: 1, writable: true, configurable: true }); + Object.preventExtensions(o); + ok(Object.isFrozen(o) === false, "o is frozen"); + ok(Object.isSealed(o) === false, "o is sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = {}; + Object.defineProperty(o, "prop", { value: 1, configurable: true }); + Object.preventExtensions(o); + ok(Object.isFrozen(o) === false, "o is frozen"); + ok(Object.isSealed(o) === false, "o is sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); + + o = {}; + Object.defineProperty(o, "prop", { get: function() {}, set: function() {} }); + Object.preventExtensions(o); + ok(Object.isFrozen(o) === true, "o is not frozen"); + ok(Object.isSealed(o) === true, "o is not sealed"); + ok(Object.isExtensible(o) === false, "o is extensible"); +}); + sync_test("head_setter", function() { document.head = ""; ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head));
1
0
0
0
← Newer
1
...
80
81
82
83
84
85
86
87
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Results per page:
10
25
50
100
200