ReactOS.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
2024
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
List overview
Download
Ros-diffs
June 2018
----- 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
ros-diffs@reactos.org
26 participants
174 discussions
Start a n
N
ew thread
01/01: [PROPSYS] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be43e1385fe4f30181265…
commit be43e1385fe4f30181265a4bf79395db82f201c0 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:47:25 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:47:25 2018 +0100 [PROPSYS] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/propsys/propsys.spec | 2 +- dll/win32/propsys/propsys_main.c | 6 ++++++ media/doc/README.WINE | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dll/win32/propsys/propsys.spec b/dll/win32/propsys/propsys.spec index 791618e5f5..73161a87a8 100644 --- a/dll/win32/propsys/propsys.spec +++ b/dll/win32/propsys/propsys.spec @@ -84,7 +84,7 @@ @ stub PSGetPropertyDescriptionByName @ stdcall PSGetPropertyDescriptionListFromString(wstr ptr ptr) @ stub PSGetPropertyFromPropertyStorage -@ stub PSGetPropertyKeyFromName +@ stdcall PSGetPropertyKeyFromName(wstr ptr) @ stdcall PSGetPropertySystem(ptr ptr) @ stub PSGetPropertyValue @ stub PSLookupPropertyHandlerCLSID diff --git a/dll/win32/propsys/propsys_main.c b/dll/win32/propsys/propsys_main.c index 7631023b83..1dbaee433f 100644 --- a/dll/win32/propsys/propsys_main.c +++ b/dll/win32/propsys/propsys_main.c @@ -268,6 +268,12 @@ HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID r return E_NOTIMPL; } +HRESULT WINAPI PSGetPropertyKeyFromName(PCWSTR name, PROPERTYKEY *key) +{ + FIXME("%s, %p\n", debugstr_w(name), key); + return E_NOTIMPL; +} + HRESULT WINAPI PSRefreshPropertySchema(void) { FIXME("\n"); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 66344e960a..58991828bb 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -151,7 +151,7 @@ reactos/dll/win32/pdh # Synced to WineStaging-3.3 reactos/dll/win32/pidgen # Synced to WineStaging-3.9 reactos/dll/win32/powrprof # Forked at Wine-1.0rc5 reactos/dll/win32/printui # Synced to WineStaging-3.3 -reactos/dll/win32/propsys # Synced to WineStaging-3.3 +reactos/dll/win32/propsys # Synced to WineStaging-3.9 reactos/dll/win32/pstorec # Synced to WineStaging-3.3 reactos/dll/win32/qmgr # Synced to WineStaging-3.3 reactos/dll/win32/qmgrprxy # Synced to WineStaging-2.9
6 years, 5 months
1
0
0
0
01/01: [PIDGEN] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=452324662809497607cf4…
commit 452324662809497607cf46fba15fc222f4ed3407 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:46:44 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:46:44 2018 +0100 [PIDGEN] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/pidgen/main.c | 7 +++++++ dll/win32/pidgen/pidgen.spec | 2 +- media/doc/README.WINE | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dll/win32/pidgen/main.c b/dll/win32/pidgen/main.c index 3aa3e84444..cf165eae13 100644 --- a/dll/win32/pidgen/main.c +++ b/dll/win32/pidgen/main.c @@ -43,3 +43,10 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) } return TRUE; } + +int WINAPI PIDGenSimpA(LPCSTR str, int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) +{ + FIXME("%s,%d,%d,%d,%d,%d,%d,%d,%d\n", debugstr_a(str), p1, p2, p3, p4, p5, p6, p7, p8); + + return 0; +} diff --git a/dll/win32/pidgen/pidgen.spec b/dll/win32/pidgen/pidgen.spec index ad5c3694a9..8b7e778b91 100644 --- a/dll/win32/pidgen/pidgen.spec +++ b/dll/win32/pidgen/pidgen.spec @@ -1,6 +1,6 @@ @ stub PIDGenA @ stub PIDGenW -@ stub PIDGenSimpA +@ stdcall PIDGenSimpA(str long long long long long long long long) @ stub PIDGenSimpW @ stub SetupPIDGenA @ stub SetupPIDGenW diff --git a/media/doc/README.WINE b/media/doc/README.WINE index c3ec642a03..66344e960a 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -148,7 +148,7 @@ reactos/dll/win32/olepro32 # Synced to WineStaging-3.3 reactos/dll/win32/olesvr32 # Synced to WineStaging-3.3 reactos/dll/win32/olethk32 # Synced to WineStaging-3.3 reactos/dll/win32/pdh # Synced to WineStaging-3.3 -reactos/dll/win32/pidgen # Synced to WineStaging-3.3 +reactos/dll/win32/pidgen # Synced to WineStaging-3.9 reactos/dll/win32/powrprof # Forked at Wine-1.0rc5 reactos/dll/win32/printui # Synced to WineStaging-3.3 reactos/dll/win32/propsys # Synced to WineStaging-3.3
6 years, 5 months
1
0
0
0
01/01: [OLE32_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a6cdf4ff0885008788ea2…
commit a6cdf4ff0885008788ea2ea876a14edad7fd512e Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:46:11 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:46:11 2018 +0100 [OLE32_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/ole32/compobj.c | 293 +++++---------- modules/rostests/winetests/ole32/marshal.c | 573 +++++++++++++++++++++++++++-- modules/rostests/winetests/ole32/ole2.c | 116 +++++- 3 files changed, 759 insertions(+), 223 deletions(-) diff --git a/modules/rostests/winetests/ole32/compobj.c b/modules/rostests/winetests/ole32/compobj.c index 06d1914240..aedbc08f07 100644 --- a/modules/rostests/winetests/ole32/compobj.c +++ b/modules/rostests/winetests/ole32/compobj.c @@ -608,28 +608,8 @@ static void test_StringFromGUID2(void) ok(len == 0, "len: %d (expected 0)\n", len); } -struct info -{ - HANDLE wait, stop; -}; - -static DWORD CALLBACK ole_initialize_thread(LPVOID pv) -{ - HRESULT hr; - struct info *info = pv; - - hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); - - SetEvent(info->wait); - WaitForSingleObject(info->stop, 10000); - - CoUninitialize(); - return hr; -} - -#define test_apt_type(t, q, t_t, t_q) _test_apt_type(t, q, t_t, t_q, __LINE__) -static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, BOOL todo_type, - BOOL todo_qualifier, int line) +#define test_apt_type(t, q) _test_apt_type(t, q, __LINE__) +static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, int line) { APTTYPEQUALIFIER qualifier = ~0u; APTTYPE type = ~0u; @@ -640,9 +620,7 @@ static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qual hr = pCoGetApartmentType(&type, &qualifier); ok_(__FILE__, line)(hr == S_OK || hr == CO_E_NOTINITIALIZED, "Unexpected return code: 0x%08x\n", hr); -todo_wine_if(todo_type) ok_(__FILE__, line)(type == expected_type, "Wrong apartment type %d, expected %d\n", type, expected_type); -todo_wine_if(todo_qualifier) ok_(__FILE__, line)(qualifier == expected_qualifier, "Wrong apartment qualifier %d, expected %d\n", qualifier, expected_qualifier); } @@ -650,10 +628,7 @@ todo_wine_if(todo_qualifier) static void test_CoCreateInstance(void) { HRESULT hr; - HANDLE thread; - DWORD tid, exitcode; IUnknown *pUnk; - struct info info; REFCLSID rclsid = &CLSID_InternetZoneManager; pUnk = (IUnknown *)0xdeadbeef; @@ -688,51 +663,15 @@ static void test_CoCreateInstance(void) hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - pUnk = (IUnknown *)0xdeadbeef; - hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); - ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr); - if (pUnk) IUnknown_Release(pUnk); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); + test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE); } static void test_CoGetClassObject(void) { HRESULT hr; - HANDLE thread, handle; - DWORD tid, exitcode; + HANDLE handle; ULONG_PTR cookie; IUnknown *pUnk; - struct info info; REFCLSID rclsid = &CLSID_InternetZoneManager; HKEY hkey; LONG res; @@ -746,46 +685,7 @@ static void test_CoGetClassObject(void) broken(hr == CO_E_NOTINITIALIZED), /* win9x */ "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - pUnk = (IUnknown *)0xdeadbeef; - hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk); - if(hr == REGDB_E_CLASSNOTREG) - skip("IE not installed so can't test CoGetClassObject\n"); - else - { - ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr); - if (pUnk) IUnknown_Release(pUnk); - } - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); + test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE); if (!pRegOverridePredefKey) { @@ -1886,9 +1786,6 @@ static void test_CoGetObjectContext(void) IObjContext *pObjContext; APTTYPE apttype; THDTYPE thdtype; - struct info info; - HANDLE thread; - DWORD tid, exitcode; GUID id, id2; if (!pCoGetObjectContext) @@ -1901,27 +1798,12 @@ static void test_CoGetObjectContext(void) ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr); ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n"); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); + pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); + test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE); - pComThreadingInfo = NULL; hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok_ole_success(hr, "CoGetObjectContext"); threadinginfo2 = NULL; hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&threadinginfo2); @@ -1939,28 +1821,6 @@ static void test_CoGetObjectContext(void) hr = CoGetCurrentLogicalThreadId(&id2); ok(IsEqualGUID(&id, &id2), "got %s, expected %s\n", wine_dbgstr_guid(&id), wine_dbgstr_guid(&id2)); - IComThreadingInfo_Release(pComThreadingInfo); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - - test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); - ok_ole_success(hr, "CoGetObjectContext"); - hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype); ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType"); ok(apttype == APTTYPE_MAINSTA, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype); @@ -2124,9 +1984,6 @@ static void test_CoGetContextToken(void) ULONG refs; ULONG_PTR token, token2; IObjContext *ctx; - struct info info; - HANDLE thread; - DWORD tid, exitcode; if (!pCoGetContextToken) { @@ -2139,49 +1996,11 @@ static void test_CoGetContextToken(void) ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr); ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - token = 0; - hr = pCoGetContextToken(&token); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); - - token2 = 0; - hr = pCoGetContextToken(&token2); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); - ok(token == token2, "got different token\n"); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); + test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE); CoInitialize(NULL); - test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE); + test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE); hr = pCoGetContextToken(NULL); ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr); @@ -3185,14 +3004,36 @@ static void test_CoWaitForMultipleHandles(void) ok(index == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); CloseHandle(thread); + CoUninitialize(); + + /* If COM was not initialized, messages are neither pumped nor peeked at */ + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr); + success = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE); + ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(success, "PeekMessage failed: %u\n", GetLastError()); + + /* same in an MTA */ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 100, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "got %#x\n", hr); + success = MsgWaitForMultipleObjectsEx(0, NULL, 2, QS_ALLPOSTMESSAGE, MWMO_ALERTABLE); + ok(success == 0, "MsgWaitForMultipleObjects returned %x\n", success); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(success, "PeekMessage failed: %u\n", GetLastError()); + + CoUninitialize(); + CloseHandle(handles[0]); CloseHandle(handles[1]); DestroyWindow(hWnd); success = UnregisterClassA(cls_name, GetModuleHandleA(0)); ok(success, "UnregisterClass failed %u\n", GetLastError()); - - CoUninitialize(); } static void test_CoGetMalloc(void) @@ -3880,6 +3721,71 @@ static void init_funcs(void) pReleaseActCtx = (void*)GetProcAddress(hkernel32, "ReleaseActCtx"); } +static DWORD CALLBACK implicit_mta_proc(void *param) +{ + IComThreadingInfo *threading_info; + ULONG_PTR token; + IUnknown *unk; + DWORD cookie; + CLSID clsid; + HRESULT hr; + + test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA); + + hr = CoCreateInstance(&CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + ok_ole_success(hr, "CoCreateInstance"); + IUnknown_Release(unk); + + hr = CoGetClassObject(&CLSID_InternetZoneManager, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&unk); + ok_ole_success(hr, "CoGetClassObject"); + IUnknown_Release(unk); + + hr = CoGetObjectContext(&IID_IComThreadingInfo, (void **)&threading_info); + ok_ole_success(hr, "CoGetObjectContext"); + IComThreadingInfo_Release(threading_info); + + hr = CoGetContextToken(&token); + ok_ole_success(hr, "CoGetContextToken"); + + hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer); + ok_ole_success(hr, "CoRegisterPSClsid"); + + hr = CoGetPSClsid(&IID_IClassFactory, &clsid); + ok_ole_success(hr, "CoGetPSClsid"); + + hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&Test_ClassFactory, + CLSCTX_INPROC_SERVER, REGCLS_SINGLEUSE, &cookie); + ok_ole_success(hr, "CoRegisterClassObject"); + + hr = CoRevokeClassObject(cookie); + ok_ole_success(hr, "CoRevokeClassObject"); + + hr = CoRegisterMessageFilter(NULL, NULL); + ok(hr == CO_E_NOT_SUPPORTED, "got %#x\n", hr); + + hr = CoLockObjectExternal((IUnknown *)&Test_Unknown, TRUE, TRUE); + ok_ole_success(hr, "CoLockObjectExternal"); + + hr = CoDisconnectObject((IUnknown *)&Test_Unknown, 0); + ok_ole_success(hr, "CoDisconnectObject"); + + return 0; +} + +/* Some COM functions (perhaps even all of them?) can make use of an "implicit" + * multi-threaded apartment created by another thread in the same process. */ +static void test_implicit_mta(void) +{ + HANDLE thread; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + thread = CreateThread(NULL, 0, implicit_mta_proc, NULL, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + + CoUninitialize(); +} + START_TEST(compobj) { init_funcs(); @@ -3929,4 +3835,5 @@ START_TEST(compobj) test_IInitializeSpy(); test_CoGetInstanceFromFile(); test_GlobalOptions(); + test_implicit_mta(); } diff --git a/modules/rostests/winetests/ole32/marshal.c b/modules/rostests/winetests/ole32/marshal.c index 12c46e92df..1fcf9a392a 100644 --- a/modules/rostests/winetests/ole32/marshal.c +++ b/modules/rostests/winetests/ole32/marshal.c @@ -34,10 +34,37 @@ #include "initguid.h" #include "wine/test.h" +#include "wine/heap.h" + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + expect_ ## func = TRUE + +#define CHECK_EXPECT2(func) \ + do { \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) DEFINE_GUID(CLSID_StdGlobalInterfaceTable,0x00000323,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_ManualResetEvent, 0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +static const GUID CLSID_WineTestPSFactoryBuffer = { 0x22222222, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } }; + /* functions that are not present on all versions of Windows */ static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID); @@ -281,6 +308,253 @@ static const IClassFactoryVtbl TestClassFactory_Vtbl = static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl }; +DEFINE_EXPECT(Invoke); +DEFINE_EXPECT(CreateStub); +DEFINE_EXPECT(CreateProxy); +DEFINE_EXPECT(GetWindow); +DEFINE_EXPECT(Disconnect); + +static HRESULT WINAPI OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv) +{ + ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI OleWindow_AddRef(IOleWindow *iface) +{ + return 2; +} + +static ULONG WINAPI OleWindow_Release(IOleWindow *iface) +{ + return 1; +} + +static HRESULT WINAPI OleWindow_GetWindow(IOleWindow *iface, HWND *hwnd) +{ + CHECK_EXPECT(GetWindow); + *hwnd = (HWND)0xdeadbeef; + return S_OK; +} + +static const IOleWindowVtbl OleWindowVtbl = { + OleWindow_QueryInterface, + OleWindow_AddRef, + OleWindow_Release, + OleWindow_GetWindow, + /* not needed */ +}; + +static IOleWindow Test_OleWindow = { &OleWindowVtbl }; + +static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IOleClientSite)) + *ppv = iface; + else if (IsEqualGUID(riid, &IID_IOleWindow)) + *ppv = &Test_OleWindow; + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface) +{ + return 2; +} + +static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface) +{ + return 1; +} + +static const IOleClientSiteVtbl OleClientSiteVtbl = { + OleClientSite_QueryInterface, + OleClientSite_AddRef, + OleClientSite_Release, + /* we don't need the rest, we never call it */ +}; + +static IOleClientSite Test_OleClientSite = { &OleClientSiteVtbl }; + +typedef struct { + IRpcStubBuffer IRpcStubBuffer_iface; + LONG ref; + IRpcStubBuffer *buffer; +} StubBufferWrapper; + +static StubBufferWrapper *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface) +{ + return CONTAINING_RECORD(iface, StubBufferWrapper, IRpcStubBuffer_iface); +} + +static HRESULT WINAPI RpcStubBuffer_QueryInterface(IRpcStubBuffer *iface, REFIID riid, void **ppv) +{ + StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface); + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRpcStubBuffer, riid)) { + *ppv = &This->IRpcStubBuffer_iface; + }else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI RpcStubBuffer_AddRef(IRpcStubBuffer *iface) +{ + StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI RpcStubBuffer_Release(IRpcStubBuffer *iface) +{ + StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface); + LONG ref = InterlockedDecrement(&This->ref); + if(!ref) { + IRpcStubBuffer_Release(This->buffer); + heap_free(This); + } + return ref; +} + +static HRESULT WINAPI RpcStubBuffer_Connect(IRpcStubBuffer *iface, IUnknown *pUnkServer) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static void WINAPI RpcStubBuffer_Disconnect(IRpcStubBuffer *iface) +{ + CHECK_EXPECT(Disconnect); +} + +static HRESULT WINAPI RpcStubBuffer_Invoke(IRpcStubBuffer *iface, RPCOLEMESSAGE *_prpcmsg, + IRpcChannelBuffer *_pRpcChannelBuffer) +{ + StubBufferWrapper *This = impl_from_IRpcStubBuffer(iface); + void *dest_context_data; + DWORD dest_context; + HRESULT hr; + + CHECK_EXPECT(Invoke); + + hr = IRpcChannelBuffer_GetDestCtx(_pRpcChannelBuffer, &dest_context, &dest_context_data); + ok(hr == S_OK, "GetDestCtx failed: %08x\n", hr); + ok(dest_context == MSHCTX_INPROC, "desc_context = %x\n", dest_context); + ok(!dest_context_data, "desc_context_data = %p\n", dest_context_data); + + return IRpcStubBuffer_Invoke(This->buffer, _prpcmsg, _pRpcChannelBuffer); +} + +static IRpcStubBuffer *WINAPI RpcStubBuffer_IsIIDSupported(IRpcStubBuffer *iface, REFIID riid) +{ + ok(0, "unexpected call\n"); + return NULL; +} + +static ULONG WINAPI RpcStubBuffer_CountRefs(IRpcStubBuffer *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI RpcStubBuffer_DebugServerQueryInterface(IRpcStubBuffer *iface, void **ppv) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static void WINAPI RpcStubBuffer_DebugServerRelease(IRpcStubBuffer *iface, void *pv) +{ + ok(0, "unexpected call\n"); +} + +static const IRpcStubBufferVtbl RpcStubBufferVtbl = { + RpcStubBuffer_QueryInterface, + RpcStubBuffer_AddRef, + RpcStubBuffer_Release, + RpcStubBuffer_Connect, + RpcStubBuffer_Disconnect, + RpcStubBuffer_Invoke, + RpcStubBuffer_IsIIDSupported, + RpcStubBuffer_CountRefs, + RpcStubBuffer_DebugServerQueryInterface, + RpcStubBuffer_DebugServerRelease +}; + +static IPSFactoryBuffer *ps_factory_buffer; + +static HRESULT WINAPI PSFactoryBuffer_QueryInterface(IPSFactoryBuffer *iface, REFIID riid, void **ppv) +{ + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPSFactoryBuffer)) + *ppv = iface; + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI PSFactoryBuffer_AddRef(IPSFactoryBuffer *iface) +{ + return 2; +} + +static ULONG WINAPI PSFactoryBuffer_Release(IPSFactoryBuffer *iface) +{ + return 1; +} + +static HRESULT WINAPI PSFactoryBuffer_CreateProxy(IPSFactoryBuffer *iface, IUnknown *outer, + REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv) +{ + CHECK_EXPECT(CreateProxy); + return IPSFactoryBuffer_CreateProxy(ps_factory_buffer, outer, riid, ppProxy, ppv); +} + +static HRESULT WINAPI PSFactoryBuffer_CreateStub(IPSFactoryBuffer *iface, REFIID riid, + IUnknown *server, IRpcStubBuffer **ppStub) +{ + StubBufferWrapper *stub; + HRESULT hr; + + CHECK_EXPECT(CreateStub); + + ok(server == (IUnknown*)&Test_OleClientSite, "unexpected server %p\n", server); + + stub = heap_alloc(sizeof(*stub)); + stub->IRpcStubBuffer_iface.lpVtbl = &RpcStubBufferVtbl; + stub->ref = 1; + + hr = IPSFactoryBuffer_CreateStub(ps_factory_buffer, riid, server, &stub->buffer); + ok(hr == S_OK, "CreateStub failed: %08x\n", hr); + + *ppStub = &stub->IRpcStubBuffer_iface; + return S_OK; +} + +static IPSFactoryBufferVtbl PSFactoryBufferVtbl = +{ + PSFactoryBuffer_QueryInterface, + PSFactoryBuffer_AddRef, + PSFactoryBuffer_Release, + PSFactoryBuffer_CreateProxy, + PSFactoryBuffer_CreateStub +}; + +static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl }; + #define RELEASEMARSHALDATA WM_USER struct host_object_data @@ -289,18 +563,31 @@ struct host_object_data IID iid; IUnknown *object; MSHLFLAGS marshal_flags; - HANDLE marshal_event; IMessageFilter *filter; + IUnknown *register_object; + CLSID register_clsid; + HANDLE marshal_event; }; +#ifndef __REACTOS__ /* FIXME: Inspect */ +static IPSFactoryBuffer PSFactoryBuffer; +#endif + static DWORD CALLBACK host_object_proc(LPVOID p) { struct host_object_data *data = p; + DWORD registration_key; HRESULT hr; MSG msg; pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if(data->register_object) { + hr = CoRegisterClassObject(&data->register_clsid, data->register_object, + CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®istration_key); + ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr); + } + if (data->filter) { IMessageFilter * prev_filter = NULL; @@ -335,31 +622,27 @@ static DWORD CALLBACK host_object_proc(LPVOID p) return hr; } -static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread) +static DWORD start_host_object2(struct host_object_data *object_data, HANDLE *thread) { DWORD tid = 0; - HANDLE marshal_event = CreateEventA(NULL, FALSE, FALSE, NULL); - struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); - - data->stream = stream; - data->iid = *riid; - data->object = object; - data->marshal_flags = marshal_flags; - data->marshal_event = marshal_event; - data->filter = filter; + struct host_object_data *data; + data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data)); + *data = *object_data; + data->marshal_event = CreateEventA(NULL, FALSE, FALSE, NULL); *thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid); /* wait for marshaling to complete before returning */ - ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" ); - CloseHandle(marshal_event); + ok( !WaitForSingleObject(data->marshal_event, 10000), "wait timed out\n" ); + CloseHandle(data->marshal_event); return tid; } static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread) { - return start_host_object2(stream, riid, object, marshal_flags, NULL, thread); + struct host_object_data object_data = { stream, *riid, object, marshal_flags }; + return start_host_object2(&object_data, thread); } /* asks thread to release the marshal data because it has to be done by the @@ -962,6 +1245,75 @@ static void test_marshal_proxy_mta_apartment_shutdown(void) pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); } +static void test_marshal_channel_buffer(void) +{ + DWORD registration_key; + IUnknown *proxy = NULL; + IOleWindow *ole_window; + HWND hwnd; + CLSID clsid; + DWORD tid; + HANDLE thread; + HRESULT hr; + + struct host_object_data object_data = { NULL, IID_IOleClientSite, (IUnknown*)&Test_OleClientSite, + MSHLFLAGS_NORMAL, NULL, (IUnknown*)&PSFactoryBuffer, + CLSID_WineTestPSFactoryBuffer }; + + cLocks = 0; + external_connections = 0; + + hr = CoGetPSClsid(&IID_IOleWindow, &clsid); + ok_ole_success(hr, "CoGetPSClsid"); + + hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, + (void **)&ps_factory_buffer); + ok_ole_success(hr, "CoGetClassObject"); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream); + ok_ole_success(hr, CreateStreamOnHGlobal); + tid = start_host_object2(&object_data, &thread); + + IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(object_data.stream, &IID_IUnknown, (void **)&proxy); + ok_ole_success(hr, CoUnmarshalInterface); + IStream_Release(object_data.stream); + + hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer, + CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®istration_key); + ok(hr == S_OK, "CoRegisterClassObject failed: %08x\n", hr); + + hr = CoRegisterPSClsid(&IID_IOleWindow, &CLSID_WineTestPSFactoryBuffer); + ok(hr == S_OK, "CoRegisterPSClsid failed: %08x\n", hr); + + SET_EXPECT(CreateStub); + SET_EXPECT(CreateProxy); + hr = IUnknown_QueryInterface(proxy, &IID_IOleWindow, (void**)&ole_window); + ok(hr == S_OK, "Could not get IOleWindow iface: %08x\n", hr); + CHECK_CALLED(CreateStub); + CHECK_CALLED(CreateProxy); + + SET_EXPECT(Invoke); + SET_EXPECT(GetWindow); + hr = IOleWindow_GetWindow(ole_window, &hwnd); + ok(hr == S_OK, "GetWindow failed: %08x\n", hr); + ok(hwnd == (HWND)0xdeadbeef, "hwnd = %p\n", hwnd); + CHECK_CALLED(Invoke); + CHECK_CALLED(GetWindow); + + IOleWindow_Release(ole_window); + + SET_EXPECT(Disconnect); + IUnknown_Release(proxy); +todo_wine + CHECK_CALLED(Disconnect); + + hr = CoRevokeClassObject(registration_key); + ok(hr == S_OK, "CoRevokeClassObject failed: %08x\n", hr); + + end_host_object(tid, thread); +} + struct ncu_params { LPSTREAM stream; @@ -1965,25 +2317,27 @@ static IMessageFilter MessageFilter = { &MessageFilter_Vtbl }; static void test_message_filter(void) { HRESULT hr; - IStream *pStream = NULL; IClassFactory *cf = NULL; DWORD tid; IUnknown *proxy = NULL; IMessageFilter *prev_filter = NULL; HANDLE thread; + struct host_object_data object_data = { NULL, IID_IClassFactory, (IUnknown*)&Test_ClassFactory, + MSHLFLAGS_NORMAL, &MessageFilter }; + cLocks = 0; - hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); + hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream); ok_ole_success(hr, CreateStreamOnHGlobal); - tid = start_host_object2(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &MessageFilter, &thread); + tid = start_host_object2(&object_data, &thread); ok_more_than_one_lock(); - IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); - hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&cf); + IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf); ok_ole_success(hr, CoUnmarshalInterface); - IStream_Release(pStream); + IStream_Release(object_data.stream); ok_more_than_one_lock(); @@ -3419,6 +3773,169 @@ static void test_manualresetevent(void) ok(!ref, "Got nonzero ref: %d\n", ref); } +static DWORD CALLBACK implicit_mta_unmarshal_proc(void *param) +{ + IStream *stream = param; + IClassFactory *cf; + IUnknown *proxy; + HRESULT hr; + + IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(stream, &IID_IClassFactory, (void **)&cf); + ok_ole_success(hr, CoUnmarshalInterface); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok_ole_success(hr, IClassFactory_CreateInstance); + + IUnknown_Release(proxy); + + /* But if we initialize an STA in this apartment, it becomes the wrong one. */ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok(hr == RPC_E_WRONG_THREAD, "got %#x\n", hr); + + CoUninitialize(); + + ok_more_than_one_lock(); + ok_non_zero_external_conn(); + + IClassFactory_Release(cf); + + ok_no_locks(); + ok_zero_external_conn(); + ok_last_release_closes(TRUE); + return 0; +} + +static DWORD CALLBACK implicit_mta_use_proc(void *param) +{ + IClassFactory *cf = param; + IUnknown *proxy; + HRESULT hr; + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok_ole_success(hr, IClassFactory_CreateInstance); + + IUnknown_Release(proxy); + + /* But if we initialize an STA in this apartment, it becomes the wrong one. */ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok(hr == RPC_E_WRONG_THREAD, "got %#x\n", hr); + + CoUninitialize(); + return 0; +} + +struct implicit_mta_marshal_data +{ + IStream *stream; + HANDLE start; + HANDLE stop; +}; + +static DWORD CALLBACK implicit_mta_marshal_proc(void *param) +{ + struct implicit_mta_marshal_data *data = param; + HRESULT hr; + + hr = CoMarshalInterface(data->stream, &IID_IClassFactory, + (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); + ok_ole_success(hr, CoMarshalInterface); + + SetEvent(data->start); + + ok(!WaitForSingleObject(data->stop, 1000), "wait failed\n"); + return 0; +} + +static void test_implicit_mta(void) +{ + struct implicit_mta_marshal_data data; + HANDLE host_thread, thread; + IClassFactory *cf; + IUnknown *proxy; + IStream *stream; + HRESULT hr; + DWORD tid; + + cLocks = 0; + external_connections = 0; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + /* Firstly: we can unmarshal and use an object while in the implicit MTA. */ + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok_ole_success(hr, CreateStreamOnHGlobal); + tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread); + + ok_more_than_one_lock(); + ok_non_zero_external_conn(); + + thread = CreateThread(NULL, 0, implicit_mta_unmarshal_proc, stream, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + CloseHandle(thread); + + IStream_Release(stream); + end_host_object(tid, host_thread); + + /* Secondly: we can unmarshal an object into the real MTA and then use it + * from the implicit MTA. */ + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok_ole_success(hr, CreateStreamOnHGlobal); + tid = start_host_object(stream, &IID_IClassFactory, (IUnknown *)&Test_ClassFactory, MSHLFLAGS_NORMAL, &host_thread); + + ok_more_than_one_lock(); + ok_non_zero_external_conn(); + + IStream_Seek(stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(stream, &IID_IClassFactory, (void **)&cf); + ok_ole_success(hr, CoUnmarshalInterface); + + thread = CreateThread(NULL, 0, implicit_mta_use_proc, cf, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + CloseHandle(thread); + + IClassFactory_Release(cf); + IStream_Release(stream); + + ok_no_locks(); + ok_non_zero_external_conn(); + ok_last_release_closes(TRUE); + + end_host_object(tid, host_thread); + + /* Thirdly: we can marshal an object from the implicit MTA and then + * unmarshal it into the real one. */ + data.start = CreateEventA(NULL, FALSE, FALSE, NULL); + data.stop = CreateEventA(NULL, FALSE, FALSE, NULL); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &data.stream); + ok_ole_success(hr, CreateStreamOnHGlobal); + + thread = CreateThread(NULL, 0, implicit_mta_marshal_proc, &data, 0, NULL); + ok(!WaitForSingleObject(data.start, 1000), "wait failed\n"); + + IStream_Seek(data.stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(data.stream, &IID_IClassFactory, (void **)&cf); + ok_ole_success(hr, CoUnmarshalInterface); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok_ole_success(hr, IClassFactory_CreateInstance); + + IUnknown_Release(proxy); + + SetEvent(data.stop); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + CloseHandle(thread); + + IStream_Release(data.stream); + + CoUninitialize(); +} + static const char *debugstr_iid(REFIID riid) { static char name[256]; @@ -3692,13 +4209,15 @@ static IChannelHook TestChannelHook = { &TestChannelHookVtbl }; static void test_channel_hook(void) { - IStream *pStream = NULL; IClassFactory *cf = NULL; DWORD tid; IUnknown *proxy = NULL; HANDLE thread; HRESULT hr; + struct host_object_data object_data = { NULL, IID_IClassFactory, (IUnknown*)&Test_ClassFactory, + MSHLFLAGS_NORMAL, &MessageFilter }; + hr = CoRegisterChannelHook(&EXTENTID_WineTest, &TestChannelHook); ok_ole_success(hr, CoRegisterChannelHook); @@ -3707,17 +4226,17 @@ static void test_channel_hook(void) cLocks = 0; - hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); + hr = CreateStreamOnHGlobal(NULL, TRUE, &object_data.stream); ok_ole_success(hr, CreateStreamOnHGlobal); - tid = start_host_object2(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &MessageFilter, &thread); + tid = start_host_object2(&object_data, &thread); server_tid = tid; ok_more_than_one_lock(); - IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL); - hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&cf); + IStream_Seek(object_data.stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(object_data.stream, &IID_IClassFactory, (void **)&cf); ok_ole_success(hr, CoUnmarshalInterface); - IStream_Release(pStream); + IStream_Release(object_data.stream); ok_more_than_one_lock(); @@ -3765,6 +4284,7 @@ START_TEST(marshal) register_test_window(); test_cocreateinstance_proxy(); + test_implicit_mta(); pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); @@ -3802,6 +4322,7 @@ START_TEST(marshal) with_external_conn = !with_external_conn; } while (with_external_conn); + test_marshal_channel_buffer(); test_hresult_marshaling(); test_proxy_used_in_wrong_thread(); test_message_filter(); diff --git a/modules/rostests/winetests/ole32/ole2.c b/modules/rostests/winetests/ole32/ole2.c index 231f9d2531..dd9257dff8 100644 --- a/modules/rostests/winetests/ole32/ole2.c +++ b/modules/rostests/winetests/ole32/ole2.c @@ -4082,6 +4082,83 @@ static void check_storage_contents(IStorage *stg, const struct storage_def *stg_ } } +static HRESULT stgmedium_cmp(const STGMEDIUM *med1, STGMEDIUM *med2) +{ + BYTE *data1, *data2; + ULONG datasize1, datasize2; + + if (med1->tymed != med2->tymed) + return E_FAIL; + + if (med1->tymed == TYMED_MFPICT) + { + METAFILEPICT *mfpict1 = GlobalLock(U(med1)->hMetaFilePict); + METAFILEPICT *mfpict2 = GlobalLock(U(med2)->hMetaFilePict); + + datasize1 = GetMetaFileBitsEx(mfpict1->hMF, 0, NULL); + datasize2 = GetMetaFileBitsEx(mfpict2->hMF, 0, NULL); + if (datasize1 == datasize2) + { + data1 = HeapAlloc(GetProcessHeap(), 0, datasize1); + data2 = HeapAlloc(GetProcessHeap(), 0, datasize2); + GetMetaFileBitsEx(mfpict1->hMF, datasize1, data1); + GetMetaFileBitsEx(mfpict2->hMF, datasize2, data2); + } + else return E_FAIL; + } + else if (med1->tymed == TYMED_ENHMF) + { + datasize1 = GetEnhMetaFileBits(med1->hEnhMetaFile, 0, NULL); + datasize2 = GetEnhMetaFileBits(med2->hEnhMetaFile, 0, NULL); + if (datasize1 == datasize2) + { + data1 = HeapAlloc(GetProcessHeap(), 0, datasize1); + data2 = HeapAlloc(GetProcessHeap(), 0, datasize2); + GetEnhMetaFileBits(med1->hEnhMetaFile, datasize1, data1); + GetEnhMetaFileBits(med2->hEnhMetaFile, datasize2, data2); + } + else return E_FAIL; + } + else if (med1->tymed == TYMED_HGLOBAL) + { + datasize1 = GlobalSize(med1->hGlobal); + datasize2 = GlobalSize(med2->hGlobal); + + if (datasize1 == datasize2) + { + data1 = GlobalLock(med1->hGlobal); + data2 = GlobalLock(med2->hGlobal); + } + else + return E_FAIL; + } + else + return E_NOTIMPL; + + if (memcmp(data1, data2, datasize1) != 0) + return E_FAIL; + + if (med1->tymed == TYMED_HGLOBAL) + { + GlobalUnlock(U(med1)->hGlobal); + GlobalUnlock(U(med2)->hGlobal); + } + else if (med1->tymed == TYMED_MFPICT) + { + HeapFree(GetProcessHeap(), 0, data1); + HeapFree(GetProcessHeap(), 0, data2); + GlobalUnlock(U(med1)->hMetaFilePict); + GlobalUnlock(U(med2)->hMetaFilePict); + } + else + { + HeapFree(GetProcessHeap(), 0, data1); + HeapFree(GetProcessHeap(), 0, data2); + } + + return S_OK; +} + static IStorage *create_storage_from_def(const struct storage_def *stg_def) { HRESULT hr; @@ -4254,8 +4331,10 @@ static void test_data_cache_save_data(void) IStorage *doc; IOleCache2 *cache; IPersistStorage *persist; + IDataObject *odata; int enumerated_streams, matched_streams, i; DWORD dummy; + STGMEDIUM stgmeds[MAX_FMTS]; struct tests_data_cache { FORMATETC fmts[MAX_FMTS]; @@ -4370,9 +4449,9 @@ static void test_data_cache_save_data(void) ok(SUCCEEDED(hr), "unexpected %#x\n", hr); if (i < pdata->num_set) { - get_stgmedium(pdata->fmts[i].cfFormat, &stgmed); - get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmed, i); - hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmed, TRUE); + get_stgmedium(pdata->fmts[i].cfFormat, &stgmeds[i]); + get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmeds[i], i); + hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmeds[i], FALSE); ok(hr == S_OK, "unexpected %#x\n", hr); } } @@ -4403,12 +4482,41 @@ static void test_data_cache_save_data(void) ok(enumerated_streams == pdata->stg_def.stream_count, "created %d != def streams %d\n", enumerated_streams, pdata->stg_def.stream_count); + IPersistStorage_Release(persist); + IOleCache2_Release(cache); + + /* now test _Load/_GetData using the storage we used for _Save */ + hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStorage_SetClass(doc, pdata->clsid); + ok(hr == S_OK, "unexpected %#x\n", hr); + trace("IPersistStorage_Load\n"); + hr = IPersistStorage_Load(persist, doc); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IOleCache2_QueryInterface(cache, &IID_IDataObject, (void **)&odata); + ok(hr == S_OK, "unexpected %#x\n", hr); for (i = 0; i < pdata->num_set; i++) - HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); + { + hr = IDataObject_GetData(odata, &pdata->fmts[i], &stgmed); + ok(hr == S_OK, "unexpected %#x\n", hr); + hr = stgmedium_cmp(&stgmeds[i], &stgmed); + ok(hr == S_OK, "unexpected %#x\n", hr); + ReleaseStgMedium(&stgmed); + ReleaseStgMedium(&stgmeds[i]); + } + + IDataObject_Release(odata); IPersistStorage_Release(persist); IStorage_Release(doc); IOleCache2_Release(cache); + for (i = 0; i < pdata->num_set; i++) + HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); + } }
6 years, 5 months
1
0
0
0
01/01: [OLE32] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=85037eb74503634e8c16f…
commit 85037eb74503634e8c16f489f70faa926f7c32a6 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:45:35 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:45:35 2018 +0100 [OLE32] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/ole32/compobj.c | 167 ++++++++++++++++------------ dll/win32/ole32/compobj_private.h | 6 +- dll/win32/ole32/datacache.c | 225 ++++++++++++++++++++++++++------------ dll/win32/ole32/marshal.c | 37 +++++-- dll/win32/ole32/rpc.c | 14 ++- dll/win32/ole32/stubmanager.c | 64 +++++------ dll/win32/ole32/usrmarshal.c | 6 +- media/doc/README.WINE | 2 +- 8 files changed, 326 insertions(+), 195 deletions(-) diff --git a/dll/win32/ole32/compobj.c b/dll/win32/ole32/compobj.c index 4cb8f4be64..2f4a69aa73 100644 --- a/dll/win32/ole32/compobj.c +++ b/dll/win32/ole32/compobj.c @@ -723,6 +723,36 @@ static inline BOOL apartment_is_model(const APARTMENT *apt, DWORD model) return (apt->multi_threaded == !(model & COINIT_APARTMENTTHREADED)); } +/* gets the multi-threaded apartment if it exists. The caller must + * release the reference from the apartment as soon as the apartment pointer + * is no longer required. */ +static APARTMENT *apartment_find_mta(void) +{ + APARTMENT *apt; + + EnterCriticalSection(&csApartment); + + if ((apt = MTA)) + apartment_addref(apt); + + LeaveCriticalSection(&csApartment); + + return apt; +} + +/* Return the current apartment if it exists, or, failing that, the MTA. Caller + * must free the returned apartment in either case. */ +APARTMENT *apartment_get_current_or_mta(void) +{ + APARTMENT *apt = COM_CurrentApt(); + if (apt) + { + apartment_addref(apt); + return apt; + } + return apartment_find_mta(); +} + static void COM_RevokeRegisteredClassObject(RegisteredClass *curClass) { list_remove(&curClass->entry); @@ -1065,8 +1095,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject( TRACE("(%08x)\n",dwRegister); - apt = COM_CurrentApt(); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("COM was not initialized\n"); return CO_E_NOTINITIALIZED; @@ -1097,7 +1126,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject( } LeaveCriticalSection( &csRegisteredClassList ); - + apartment_release(apt); return hr; } @@ -1151,9 +1180,17 @@ DWORD apartment_release(struct apartment *apt) ret = InterlockedDecrement(&apt->refs); TRACE("%s: after = %d\n", wine_dbgstr_longlong(apt->oxid), ret); + + if (apt->being_destroyed) + { + LeaveCriticalSection(&csApartment); + return ret; + } + /* destruction stuff that needs to happen under csApartment CS */ if (ret == 0) { + apt->being_destroyed = TRUE; if (apt == MTA) MTA = NULL; else if (apt == MainApartment) MainApartment = NULL; list_remove(&apt->entry); @@ -1301,31 +1338,6 @@ static APARTMENT *apartment_findmain(void) return result; } -/* gets the multi-threaded apartment if it exists. The caller must - * release the reference from the apartment as soon as the apartment pointer - * is no longer required. */ -static APARTMENT *apartment_find_multi_threaded(void) -{ - APARTMENT *result = NULL; - struct list *cursor; - - EnterCriticalSection(&csApartment); - - LIST_FOR_EACH( cursor, &apts ) - { - struct apartment *apt = LIST_ENTRY( cursor, struct apartment, entry ); - if (apt->multi_threaded) - { - result = apt; - apartment_addref(result); - break; - } - } - - LeaveCriticalSection(&csApartment); - return result; -} - /* gets the specified class object by loading the appropriate DLL, if * necessary and calls the DllGetClassObject function for the DLL */ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, @@ -1345,7 +1357,7 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, hr = DllGetClassObject(rclsid, riid, ppv); if (hr != S_OK) - ERR("DllGetClassObject returned error 0x%08x\n", hr); + ERR("DllGetClassObject returned error 0x%08x for dll %s\n", hr, debugstr_w(dllpath)); return hr; } @@ -1394,7 +1406,7 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, hr = apartment_loaded_dll->dll->DllGetClassObject(rclsid, riid, ppv); if (hr != S_OK) - ERR("DllGetClassObject returned error 0x%08x\n", hr); + ERR("DllGetClassObject returned error 0x%08x for dll %s\n", hr, debugstr_w(dllpath)); } return hr; @@ -2065,9 +2077,11 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved ) return hr; } - apt = COM_CurrentApt(); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) + { + ERR("apartment not initialised\n"); return CO_E_NOTINITIALIZED; + } manager = get_stub_manager_from_object(apt, lpUnk, FALSE); if (manager) { @@ -2082,6 +2096,7 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved ) * not found, making apps think that the object was disconnected, when * it actually wasn't */ + apartment_release(apt); return S_OK; } @@ -2589,7 +2604,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0}; static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0}; WCHAR path[ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAYSIZE(wszPSC)]; - APARTMENT *apt = COM_CurrentApt(); + APARTMENT *apt; struct registered_psclsid *registered_psclsid; ACTCTX_SECTION_KEYED_DATA data; HRESULT hr; @@ -2598,11 +2613,12 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("apartment not initialised\n"); return CO_E_NOTINITIALIZED; } + apartment_release(apt); if (!pclsid) return E_INVALIDARG; @@ -2673,16 +2689,17 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) */ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid) { - APARTMENT *apt = COM_CurrentApt(); + APARTMENT *apt; struct registered_psclsid *registered_psclsid; TRACE("(%s, %s)\n", debugstr_guid(riid), debugstr_guid(rclsid)); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("apartment not initialised\n"); return CO_E_NOTINITIALIZED; } + apartment_release(apt); EnterCriticalSection(&cs_registered_psclsid_list); @@ -2808,8 +2825,7 @@ HRESULT WINAPI CoRegisterClassObject( if ( (lpdwRegister==0) || (pUnk==0) ) return E_INVALIDARG; - apt = COM_CurrentApt(); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("COM was not initialized\n"); return CO_E_NOTINITIALIZED; @@ -2832,16 +2848,21 @@ HRESULT WINAPI CoRegisterClassObject( if (dwClsContext & CLSCTX_LOCAL_SERVER) hr = CoLockObjectExternal(foundObject, TRUE, FALSE); IUnknown_Release(foundObject); + apartment_release(apt); return hr; } IUnknown_Release(foundObject); ERR("object already registered for class %s\n", debugstr_guid(rclsid)); + apartment_release(apt); return CO_E_OBJISREG; } newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass)); if ( newClass == NULL ) + { + apartment_release(apt); return E_OUTOFMEMORY; + } newClass->classIdentifier = *rclsid; newClass->apartment_id = apt->oxid; @@ -2870,7 +2891,10 @@ HRESULT WINAPI CoRegisterClassObject( hr = get_local_server_stream(apt, &marshal_stream); if(FAILED(hr)) + { + apartment_release(apt); return hr; + } hr = RPC_StartLocalServer(&newClass->classIdentifier, marshal_stream, @@ -2878,6 +2902,7 @@ HRESULT WINAPI CoRegisterClassObject( &newClass->RpcRegistration); IStream_Release(marshal_stream); } + apartment_release(apt); return S_OK; } @@ -2995,7 +3020,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( IUnknown *regClassObject; HRESULT hres = E_UNEXPECTED; APARTMENT *apt; - BOOL release_apt = FALSE; TRACE("CLSID: %s,IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid)); @@ -3004,14 +3028,10 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( *ppv = NULL; - if (!(apt = COM_CurrentApt())) + if (!(apt = apartment_get_current_or_mta())) { - if (!(apt = apartment_find_multi_threaded())) - { - ERR("apartment not initialised\n"); - return CO_E_NOTINITIALIZED; - } - release_apt = TRUE; + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; } if (pServerInfo) { @@ -3023,7 +3043,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( { if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler)) { - if (release_apt) apartment_release(apt); + apartment_release(apt); return FTMarshalCF_Create(iid, ppv); } if (IsEqualCLSID(rclsid, &CLSID_GlobalOptions)) @@ -3049,7 +3069,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( hres = get_inproc_class_object(apt, &clsreg, &comclass->clsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv); ReleaseActCtx(data.hActCtx); - if (release_apt) apartment_release(apt); + apartment_release(apt); return hres; } } @@ -3070,7 +3090,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( * is good since we are not returning it in the "out" parameter. */ IUnknown_Release(regClassObject); - if (release_apt) apartment_release(apt); + apartment_release(apt); return hres; } @@ -3105,7 +3125,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( * other types */ if (SUCCEEDED(hres)) { - if (release_apt) apartment_release(apt); + apartment_release(apt); return hres; } } @@ -3141,11 +3161,11 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( * other types */ if (SUCCEEDED(hres)) { - if (release_apt) apartment_release(apt); + apartment_release(apt); return hres; } } - if (release_apt) apartment_release(apt); + apartment_release(apt); /* Next try out of process */ if (CLSCTX_LOCAL_SERVER & dwClsContext) @@ -3304,15 +3324,12 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx( if(FAILED(hres)) clsid = *rclsid; - if (!(apt = COM_CurrentApt())) + if (!(apt = apartment_get_current_or_mta())) { - if (!(apt = apartment_find_multi_threaded())) - { - ERR("apartment not initialised\n"); - return CO_E_NOTINITIALIZED; - } - apartment_release(apt); + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; } + apartment_release(apt); /* * The Standard Global Interface Table (GIT) object is a process-wide singleton. @@ -3646,8 +3663,11 @@ HRESULT WINAPI CoLockObjectExternal( TRACE("pUnk=%p, fLock=%s, fLastUnlockReleases=%s\n", pUnk, fLock ? "TRUE" : "FALSE", fLastUnlockReleases ? "TRUE" : "FALSE"); - apt = COM_CurrentApt(); - if (!apt) return CO_E_NOTINITIALIZED; + if (!(apt = apartment_get_current_or_mta())) + { + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; + } stubmgr = get_stub_manager_from_object(apt, pUnk, fLock); if (!stubmgr) @@ -3656,6 +3676,7 @@ HRESULT WINAPI CoLockObjectExternal( /* Note: native is pretty broken here because it just silently * fails, without returning an appropriate error code, making apps * think that the object was disconnected, when it actually wasn't */ + apartment_release(apt); return S_OK; } @@ -3665,6 +3686,7 @@ HRESULT WINAPI CoLockObjectExternal( stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases); stub_manager_int_release(stubmgr); + apartment_release(apt); return S_OK; } @@ -5004,22 +5026,19 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv) HRESULT WINAPI CoGetContextToken( ULONG_PTR *token ) { struct oletls *info = COM_CurrentInfo(); + APARTMENT *apt; TRACE("(%p)\n", token); if (!info) return E_OUTOFMEMORY; - if (!info->apt) + if (!(apt = apartment_get_current_or_mta())) { - APARTMENT *apt; - if (!(apt = apartment_find_multi_threaded())) - { - ERR("apartment not initialised\n"); - return CO_E_NOTINITIALIZED; - } - apartment_release(apt); + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; } + apartment_release(apt); if (!token) return E_POINTER; @@ -5095,8 +5114,9 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier) { struct oletls *info = COM_CurrentInfo(); + APARTMENT *apt; - FIXME("(%p, %p): semi-stub\n", type, qualifier); + TRACE("(%p, %p)\n", type, qualifier); if (!type || !qualifier) return E_INVALIDARG; @@ -5115,6 +5135,13 @@ HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier) *qualifier = APTTYPEQUALIFIER_NONE; + if (!info->apt && (apt = apartment_find_mta())) + { + apartment_release(apt); + *type = APTTYPE_MTA; + *qualifier = APTTYPEQUALIFIER_IMPLICIT_MTA; + } + return info->apt ? S_OK : CO_E_NOTINITIALIZED; } diff --git a/dll/win32/ole32/compobj_private.h b/dll/win32/ole32/compobj_private.h index 9e65c3ec0c..212d328317 100644 --- a/dll/win32/ole32/compobj_private.h +++ b/dll/win32/ole32/compobj_private.h @@ -142,6 +142,7 @@ struct apartment DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */ HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */ LocalServer *local_server; /* A marshallable object exposing local servers (CS cs) */ + BOOL being_destroyed; /* is currently being destroyed */ /* FIXME: OIDs should be given out by RPCSS */ OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */ @@ -199,7 +200,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN; HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN; -HRESULT start_apartment_remote_unknown(void) DECLSPEC_HIDDEN; +HRESULT start_apartment_remote_unknown(APARTMENT *apt) DECLSPEC_HIDDEN; HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN; @@ -211,7 +212,7 @@ void RPC_StartRemoting(struct apartment *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, DWORD dest_context, void *dest_context_data, - IRpcChannelBuffer **chan) DECLSPEC_HIDDEN; + IRpcChannelBuffer **chan, APARTMENT *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN; void RPC_ExecuteCall(struct dispatch_params *params) DECLSPEC_HIDDEN; HRESULT RPC_RegisterInterface(REFIID riid) DECLSPEC_HIDDEN; @@ -247,6 +248,7 @@ HRESULT apartment_createwindowifneeded(struct apartment *apt) DECLSPEC_HIDDEN; HWND apartment_getwindow(const struct apartment *apt) DECLSPEC_HIDDEN; HRESULT enter_apartment(struct oletls *info, DWORD model) DECLSPEC_HIDDEN; void leave_apartment(struct oletls *info) DECLSPEC_HIDDEN; +APARTMENT *apartment_get_current_or_mta(void) DECLSPEC_HIDDEN; /* DCOM messages used by the apartment window (not compatible with native) */ #define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */ diff --git a/dll/win32/ole32/datacache.c b/dll/win32/ole32/datacache.c index 325a98b33b..b72b8ff2ef 100644 --- a/dll/win32/ole32/datacache.c +++ b/dll/win32/ole32/datacache.c @@ -547,6 +547,41 @@ static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm ); } +static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) +{ + METAFILEPICT *pict; + HRESULT hr = E_FAIL; + UINT size; + void *bits; + + if (!(pict = GlobalLock( data ))) return hr; + + size = GetMetaFileBitsEx( pict->hMF, 0, NULL ); + if ((bits = HeapAlloc( GetProcessHeap(), 0, size ))) + { + GetMetaFileBitsEx( pict->hMF, size, bits ); + med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict ); + HeapFree( GetProcessHeap(), 0, bits ); + med->tymed = TYMED_ENHMF; + med->pUnkForRelease = NULL; + hr = S_OK; + } + + GlobalUnlock( data ); + return hr; +} +#include <pshpack2.h> +struct meta_placeable +{ + DWORD key; + WORD hwmf; + WORD bounding_box[4]; + WORD inch; + DWORD reserved; + WORD checksum; +}; +#include <poppack.h> + static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; @@ -559,25 +594,26 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) CLIPFORMAT clipformat; static const LARGE_INTEGER offset_zero; ULONG read; - - if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS) - { - FIXME( "Unimplemented for CONTENTS stream\n" ); - return E_FAIL; - } + struct meta_placeable mf_place; hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); if (FAILED( hr )) return hr; - hr = read_clipformat( stm, &clipformat ); - if (FAILED( hr )) return hr; - - hr = IStream_Read( stm, &header, sizeof(header), &read ); - if (hr != S_OK || read != sizeof(header)) return E_FAIL; + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + hr = read_clipformat( stm, &clipformat ); + if (hr != S_OK) return hr; + hr = IStream_Read( stm, &header, sizeof(header), &read ); + if (hr != S_OK) return hr; + } + else + { + hr = IStream_Read( stm, &mf_place, sizeof(mf_place), &read ); + if (hr != S_OK) return hr; + } hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos ); if (FAILED( hr )) return hr; - stat.cbSize.QuadPart -= current_pos.QuadPart; hmfpict = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) ); @@ -592,14 +628,23 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm ) } hr = IStream_Read( stm, bits, stat.cbSize.u.LowPart, &read ); - if (hr != S_OK || read != stat.cbSize.u.LowPart) hr = E_FAIL; if (SUCCEEDED( hr )) { - /* FIXME: get this from the stream */ mfpict->mm = MM_ANISOTROPIC; - mfpict->xExt = header.dwObjectExtentX; - mfpict->yExt = header.dwObjectExtentY; + /* FIXME: get this from the stream */ + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + mfpict->xExt = header.dwObjectExtentX; + mfpict->yExt = header.dwObjectExtentY; + } + else + { + mfpict->xExt = ((mf_place.bounding_box[2] - mf_place.bounding_box[0]) + * 2540) / mf_place.inch; + mfpict->yExt = ((mf_place.bounding_box[3] - mf_place.bounding_box[1]) + * 2540) / mf_place.inch; + } mfpict->hMF = SetMetaFileBitsEx( stat.cbSize.u.LowPart, bits ); if (!mfpict->hMF) hr = E_FAIL; @@ -623,48 +668,61 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) { HRESULT hr; STATSTG stat; - void *dib; + BYTE *dib; HGLOBAL hglobal; ULONG read, info_size, bi_size; BITMAPFILEHEADER file; BITMAPINFOHEADER *info; + CLIPFORMAT cf; + PresentationDataHeader pres; + ULARGE_INTEGER current_pos; + static const LARGE_INTEGER offset_zero; + + hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); + if (FAILED( hr )) return hr; if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) { - FIXME( "Unimplemented for presentation stream\n" ); - return E_FAIL; + hr = read_clipformat( stm, &cf ); + if (hr != S_OK) return hr; + hr = IStream_Read( stm, &pres, sizeof(pres), &read ); + if (hr != S_OK) return hr; + } + else + { + hr = IStream_Read( stm, &file, sizeof(BITMAPFILEHEADER), &read ); + if (hr != S_OK) return hr; } - hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); + hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos ); if (FAILED( hr )) return hr; - - if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL; - hr = IStream_Read( stm, &file, sizeof(file), &read ); - if (hr != S_OK || read != sizeof(file)) return E_FAIL; - stat.cbSize.QuadPart -= sizeof(file); + stat.cbSize.QuadPart -= current_pos.QuadPart; hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart ); if (!hglobal) return E_OUTOFMEMORY; dib = GlobalLock( hglobal ); + /* read first DWORD of BITMAPINFOHEADER */ hr = IStream_Read( stm, dib, sizeof(DWORD), &read ); - if (hr != S_OK || read != sizeof(DWORD)) goto fail; + if (hr != S_OK) goto fail; bi_size = *(DWORD *)dib; if (stat.cbSize.QuadPart < bi_size) goto fail; - hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read ); - if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail; + /* read rest of BITMAPINFOHEADER */ + hr = IStream_Read( stm, dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read ); + if (hr != S_OK) goto fail; - info_size = bitmap_info_size( dib, DIB_RGB_COLORS ); + info_size = bitmap_info_size( (BITMAPINFO *)dib, DIB_RGB_COLORS ); if (stat.cbSize.QuadPart < info_size) goto fail; if (info_size > bi_size) { - hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read ); - if (hr != S_OK || read != info_size - bi_size) goto fail; + hr = IStream_Read( stm, dib + bi_size, info_size - bi_size, &read ); + if (hr != S_OK) goto fail; } stat.cbSize.QuadPart -= info_size; - if (file.bfOffBits) + /* set Stream pointer to beginning of bitmap bits */ + if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS && file.bfOffBits) { LARGE_INTEGER skip; @@ -675,8 +733,8 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) stat.cbSize.QuadPart -= skip.QuadPart; } - hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read ); - if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail; + hr = IStream_Read( stm, dib + info_size, stat.cbSize.u.LowPart, &read ); + if (hr != S_OK) goto fail; if (bi_size >= sizeof(*info)) { @@ -695,15 +753,69 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm ) cache_entry->stgmedium.tymed = TYMED_HGLOBAL; cache_entry->stgmedium.u.hGlobal = hglobal; - return S_OK; + return hr; fail: GlobalUnlock( hglobal ); GlobalFree( hglobal ); - return E_FAIL; + return hr; } +static HRESULT load_emf( DataCacheEntry *cache_entry, IStream *stm ) +{ + HRESULT hr; + + if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS) + { + STGMEDIUM stgmed; + + hr = load_mf_pict( cache_entry, stm ); + if (SUCCEEDED( hr )) + { + hr = synthesize_emf( cache_entry->stgmedium.u.hMetaFilePict, &stgmed ); + ReleaseStgMedium( &cache_entry->stgmedium ); + } + if (SUCCEEDED( hr )) + cache_entry->stgmedium = stgmed; + } + else + { + STATSTG stat; + BYTE *data; + ULONG read, size_bits; + + hr = IStream_Stat( stm, &stat, STATFLAG_NONAME ); + + if (SUCCEEDED( hr )) + { + data = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart ); + if (!data) return E_OUTOFMEMORY; + + hr = IStream_Read( stm, data, stat.cbSize.u.LowPart, &read ); + if (hr != S_OK) + { + HeapFree( GetProcessHeap(), 0, data ); + return hr; + } + + if (read <= sizeof(DWORD) + sizeof(ENHMETAHEADER)) + { + HeapFree( GetProcessHeap(), 0, data ); + return E_FAIL; + } + size_bits = read - sizeof(DWORD) - sizeof(ENHMETAHEADER); + cache_entry->stgmedium.u.hEnhMetaFile = SetEnhMetaFileBits( size_bits, data + (read - size_bits) ); + cache_entry->stgmedium.tymed = TYMED_ENHMF; + cache_entry->stgmedium.pUnkForRelease = NULL; + + HeapFree( GetProcessHeap(), 0, data ); + } + } + + return hr; +} + /************************************************************************ * DataCacheEntry_LoadData * @@ -736,6 +848,10 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *st hr = load_dib( cache_entry, stm ); break; + case CF_ENHMETAFILE: + hr = load_emf( cache_entry, stm ); + break; + default: FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat ); hr = E_NOTIMPL; @@ -817,18 +933,6 @@ end: return hr; } -#include <pshpack2.h> -struct meta_placeable -{ - DWORD key; - WORD hwmf; - WORD bounding_box[4]; - WORD inch; - DWORD reserved; - WORD checksum; -}; -#include <poppack.h> - static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream) { HRESULT hr = S_OK; @@ -1118,30 +1222,6 @@ static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med ) return hr; } -static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med ) -{ - METAFILEPICT *pict; - HRESULT hr = E_FAIL; - UINT size; - void *bits; - - if (!(pict = GlobalLock( data ))) return hr; - - size = GetMetaFileBitsEx( pict->hMF, 0, NULL ); - if ((bits = HeapAlloc( GetProcessHeap(), 0, size ))) - { - GetMetaFileBitsEx( pict->hMF, size, bits ); - med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict ); - HeapFree( GetProcessHeap(), 0, bits ); - med->tymed = TYMED_ENHMF; - med->pUnkForRelease = NULL; - hr = S_OK; - } - - GlobalUnlock( data ); - return hr; -} - static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry, const FORMATETC *formatetc, STGMEDIUM *stgmedium, @@ -1763,6 +1843,7 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *stg ) LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry ) DataCacheEntry_Destroy( This, entry ); + This->clsid = CLSID_NULL; ReadClassStg( stg, &clsid ); hr = create_automatic_entry( This, &clsid ); diff --git a/dll/win32/ole32/marshal.c b/dll/win32/ole32/marshal.c index b39dac0a27..7c0f541359 100644 --- a/dll/win32/ole32/marshal.c +++ b/dll/win32/ole32/marshal.c @@ -313,13 +313,15 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL * the interfaces were returned */ if (SUCCEEDED(hr)) { + APARTMENT *apt = apartment_get_current_or_mta(); + /* try to unmarshal each object returned to us */ for (i = 0; i < nonlocal_mqis; i++) { ULONG index = mapping[i]; HRESULT hrobj = qiresults[i].hResult; if (hrobj == S_OK) - hrobj = unmarshal_object(&qiresults[i].std, COM_CurrentApt(), + hrobj = unmarshal_object(&qiresults[i].std, apt, This->dest_context, This->dest_context_data, pMQIs[index].pIID, &This->oxid_info, @@ -331,6 +333,8 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL ERR("Failed to get pointer to interface %s\n", debugstr_guid(pMQIs[index].pIID)); pMQIs[index].hr = hrobj; } + + apartment_release(apt); } /* free the memory allocated by the proxy */ @@ -1010,8 +1014,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk if (This->sorflags & SORFP_NOLIFETIMEMGMT) return S_FALSE; - apt = COM_CurrentApt(); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) return CO_E_NOTINITIALIZED; called_in_original_apt = This->parent && (This->parent->oxid == apt->oxid); @@ -1046,7 +1049,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk stdobjref.ipid = This->oxid_info.ipidRemUnknown; /* do the unmarshal */ - hr = unmarshal_object(&stdobjref, COM_CurrentApt(), This->dest_context, + hr = unmarshal_object(&stdobjref, apt, This->dest_context, This->dest_context_data, &IID_IRemUnknown, &This->oxid_info, (void**)remunk); if (hr == S_OK && called_in_original_apt) @@ -1056,6 +1059,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk } } LeaveCriticalSection(&This->cs); + apartment_release(apt); TRACE("got IRemUnknown* pointer %p, hr = 0x%08x\n", *remunk, hr); @@ -1221,11 +1225,11 @@ StdMarshalImpl_MarshalInterface( STDOBJREF stdobjref; ULONG res; HRESULT hres; - APARTMENT *apt = COM_CurrentApt(); + APARTMENT *apt; TRACE("(...,%s,...)\n", debugstr_guid(riid)); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("Apartment not initialized\n"); return CO_E_NOTINITIALIZED; @@ -1235,6 +1239,7 @@ StdMarshalImpl_MarshalInterface( RPC_StartRemoting(apt); hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags); + apartment_release(apt); if (hres != S_OK) { ERR("Failed to create ifstub, hres=0x%x\n", hres); @@ -1288,7 +1293,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, &proxy_manager->oxid_info, proxy_manager->dest_context, proxy_manager->dest_context_data, - &chanbuf); + &chanbuf, apt); if (hr == S_OK) hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref, riid, chanbuf, &ifproxy); @@ -1324,14 +1329,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v STDOBJREF stdobjref; ULONG res; HRESULT hres; - APARTMENT *apt = COM_CurrentApt(); + APARTMENT *apt; APARTMENT *stub_apt; OXID oxid; TRACE("(...,%s,....)\n", debugstr_guid(riid)); /* we need an apartment to unmarshal into */ - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("Apartment not initialized\n"); return CO_E_NOTINITIALIZED; @@ -1339,10 +1344,18 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v /* read STDOBJREF from wire */ hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); - if (hres != S_OK) return STG_E_READFAULT; + if (hres != S_OK) + { + apartment_release(apt); + return STG_E_READFAULT; + } hres = apartment_getoxid(apt, &oxid); - if (hres != S_OK) return hres; + if (hres != S_OK) + { + apartment_release(apt); + return hres; + } /* check if we're marshalling back to ourselves */ if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid))) @@ -1357,6 +1370,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE); stub_manager_int_release(stubmgr); + apartment_release(apt); return hres; } @@ -1395,6 +1409,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v if (hres != S_OK) WARN("Failed with error 0x%08x\n", hres); else TRACE("Successfully created proxy %p\n", *ppv); + apartment_release(apt); return hres; } diff --git a/dll/win32/ole32/rpc.c b/dll/win32/ole32/rpc.c index 8d8276e0cb..a73d23ce68 100644 --- a/dll/win32/ole32/rpc.c +++ b/dll/win32/ole32/rpc.c @@ -830,14 +830,16 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac ORPC_EXTENT_ARRAY orpc_ext_array; WIRE_ORPC_EXTENT *first_wire_orpc_extent = NULL; HRESULT hrFault = S_OK; + APARTMENT *apt = apartment_get_current_or_mta(); TRACE("(%p) iMethod=%d\n", olemsg, olemsg->iMethod); - hr = ClientRpcChannelBuffer_IsCorrectApartment(This, COM_CurrentApt()); + hr = ClientRpcChannelBuffer_IsCorrectApartment(This, apt); if (hr != S_OK) { ERR("called from wrong apartment, should have been 0x%s\n", wine_dbgstr_longlong(This->oxid)); + if (apt) apartment_release(apt); return RPC_E_WRONG_THREAD; } /* This situation should be impossible in multi-threaded apartments, @@ -845,11 +847,12 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac * Note: doing a COM call during the processing of a sent message is * only disallowed if a client call is already being waited for * completion */ - if (!COM_CurrentApt()->multi_threaded && + if (!apt->multi_threaded && COM_CurrentInfo()->pending_call_count_client && InSendMessage()) { ERR("can't make an outgoing COM call in response to a sent message\n"); + apartment_release(apt); return RPC_E_CANTCALLOUT_ININPUTSYNCCALL; } @@ -967,6 +970,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac TRACE("-- 0x%08x\n", hr); + apartment_release(apt); return hr; } @@ -1094,7 +1098,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl = HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, DWORD dest_context, void *dest_context_data, - IRpcChannelBuffer **chan) + IRpcChannelBuffer **chan, APARTMENT *apt) { ClientRpcChannelBuffer *This; WCHAR endpoint[200]; @@ -1148,7 +1152,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, This->super.dest_context = dest_context; This->super.dest_context_data = dest_context_data; This->bind = bind; - apartment_getoxid(COM_CurrentApt(), &This->oxid); + apartment_getoxid(apt, &This->oxid); This->server_pid = oxid_info->dwPid; This->event = NULL; @@ -1644,7 +1648,7 @@ void RPC_StartRemoting(struct apartment *apt) /* FIXME: move remote unknown exporting into this function */ } - start_apartment_remote_unknown(); + start_apartment_remote_unknown(apt); } diff --git a/dll/win32/ole32/stubmanager.c b/dll/win32/ole32/stubmanager.c index 57048c6306..5f604d4291 100644 --- a/dll/win32/ole32/stubmanager.c +++ b/dll/win32/ole32/stubmanager.c @@ -73,7 +73,8 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s struct ifstub *stub; HRESULT hr; - TRACE("oid=%s, stubbuffer=%p, iid=%s\n", wine_dbgstr_longlong(m->oid), sb, debugstr_guid(iid)); + TRACE("oid=%s, stubbuffer=%p, iid=%s, dest_context=%x\n", wine_dbgstr_longlong(m->oid), sb, + debugstr_guid(iid), dest_context); stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub)); if (!stub) return NULL; @@ -470,7 +471,7 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea /* gets the stub manager associated with an ipid - caller must have * a reference to the apartment while a reference to the stub manager is held. * it must also call release on the stub manager when it is no longer needed */ -static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPID *ipid) +static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPID *ipid, struct ifstub **ifstub) { struct stub_manager *result = NULL; struct list *cursor; @@ -480,7 +481,7 @@ static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPI { struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry ); - if (stub_manager_ipid_to_ifstub(m, ipid)) + if ((*ifstub = stub_manager_ipid_to_ifstub(m, ipid))) { result = m; stub_manager_int_addref(result); @@ -497,7 +498,8 @@ static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPI return result; } -static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret) +static HRESULT ipid_to_ifstub(const IPID *ipid, APARTMENT **stub_apt, + struct stub_manager **stubmgr_ret, struct ifstub **ifstub) { /* FIXME: hack for IRemUnknown */ if (ipid->Data2 == 0xffff) @@ -509,7 +511,7 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, stru TRACE("Couldn't find apartment corresponding to TID 0x%04x\n", ipid->Data2); return RPC_E_INVALID_OBJECT; } - *stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid); + *stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid, ifstub); if (!*stubmgr_ret) { apartment_release(*stub_apt); @@ -519,6 +521,12 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, stru return S_OK; } +static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stub) +{ + struct ifstub *ifstub; + return ipid_to_ifstub(ipid, stub_apt, stub, &ifstub); +} + /* gets the apartment, stub and channel of an object. the caller must * release the references to all objects (except iface) if the function * returned success, otherwise no references are returned. */ @@ -532,32 +540,22 @@ HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, APARTMENT *apt; HRESULT hr; - hr = ipid_to_stub_manager(ipid, &apt, &stubmgr); + hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub); if (hr != S_OK) return RPC_E_DISCONNECTED; - ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid); - if (ifstub) - { - *stub = ifstub->stubbuffer; - IRpcStubBuffer_AddRef(*stub); - *chan = ifstub->chan; - IRpcChannelBuffer_AddRef(*chan); - *stub_apt = apt; - *iid = ifstub->iid; - *iface = ifstub->iface; - - if (manager) - *manager = stubmgr; - else - stub_manager_int_release(stubmgr); - return S_OK; - } + *stub = ifstub->stubbuffer; + IRpcStubBuffer_AddRef(*stub); + *chan = ifstub->chan; + IRpcChannelBuffer_AddRef(*chan); + *stub_apt = apt; + *iid = ifstub->iid; + *iface = ifstub->iface; + + if (manager) + *manager = stubmgr; else - { stub_manager_int_release(stubmgr); - apartment_release(apt); - return RPC_E_DISCONNECTED; - } + return S_OK; } /* returns TRUE if it is possible to unmarshal, FALSE otherwise. */ @@ -707,18 +705,23 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface, USHORT successful_qis = 0; APARTMENT *apt; struct stub_manager *stubmgr; + struct ifstub *ifstub; + DWORD dest_context; + void *dest_context_data; TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults); - hr = ipid_to_stub_manager(ripid, &apt, &stubmgr); + hr = ipid_to_ifstub(ripid, &apt, &stubmgr, &ifstub); if (hr != S_OK) return hr; + IRpcChannelBuffer_GetDestCtx(ifstub->chan, &dest_context, &dest_context_data); + *ppQIResults = CoTaskMemAlloc(sizeof(REMQIRESULT) * cIids); for (i = 0; i < cIids; i++) { HRESULT hrobj = marshal_object(apt, &(*ppQIResults)[i].std, &iids[i], - stubmgr->object, MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL); + stubmgr->object, dest_context, dest_context_data, MSHLFLAGS_NORMAL); if (hrobj == S_OK) successful_qis++; (*ppQIResults)[i].hResult = hrobj; @@ -812,11 +815,10 @@ static const IRemUnknownVtbl RemUnknown_Vtbl = }; /* starts the IRemUnknown listener for the current apartment */ -HRESULT start_apartment_remote_unknown(void) +HRESULT start_apartment_remote_unknown(APARTMENT *apt) { IRemUnknown *pRemUnknown; HRESULT hr = S_OK; - APARTMENT *apt = COM_CurrentApt(); EnterCriticalSection(&apt->cs); if (!apt->remunk_exported) diff --git a/dll/win32/ole32/usrmarshal.c b/dll/win32/ole32/usrmarshal.c index 63eead1b84..8d36e13441 100644 --- a/dll/win32/ole32/usrmarshal.c +++ b/dll/win32/ole32/usrmarshal.c @@ -387,7 +387,7 @@ ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *ph size += sizeof(ULONG); - if (LOWORD(*pFlags == MSHCTX_INPROC)) + if (LOWORD(*pFlags) == MSHCTX_INPROC) size += sizeof(HGLOBAL); else { @@ -429,7 +429,7 @@ unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBu ALIGN_POINTER(pBuffer, 3); - if (LOWORD(*pFlags == MSHCTX_INPROC)) + if (LOWORD(*pFlags) == MSHCTX_INPROC) { if (sizeof(*phGlobal) == 8) *(ULONG *)pBuffer = WDT_INPROC64_CALL; @@ -572,7 +572,7 @@ void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal) { TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phGlobal); - if (LOWORD(*pFlags != MSHCTX_INPROC) && *phGlobal) + if (LOWORD(*pFlags) != MSHCTX_INPROC && *phGlobal) GlobalFree(*phGlobal); } diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 829a9882a5..c3ec642a03 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9 reactos/dll/win32/objsel # Synced to WineStaging-3.3 reactos/dll/win32/odbc32 # Synced to WineStaging-3.3. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-3.9 -reactos/dll/win32/ole32 # Synced to WineStaging-3.3 +reactos/dll/win32/ole32 # Synced to WineStaging-3.9 reactos/dll/win32/oleacc # Synced to WineStaging-3.3 reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3 reactos/dll/win32/olecli32 # Synced to WineStaging-3.3
6 years, 5 months
1
0
0
0
01/01: [ODBCCP32_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9ce306e4cccfdb507c685…
commit 9ce306e4cccfdb507c68504150046010d4609a5e Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:44:42 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:44:42 2018 +0100 [ODBCCP32_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/odbccp32/misc.c | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/modules/rostests/winetests/odbccp32/misc.c b/modules/rostests/winetests/odbccp32/misc.c index 4a72ad038b..c12ff4961b 100644 --- a/modules/rostests/winetests/odbccp32/misc.c +++ b/modules/rostests/winetests/odbccp32/misc.c @@ -27,6 +27,15 @@ static const WCHAR abcd_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','a','b','c','d','.','I','N','I','\\','w','i','n','e','o','d','b','c',0}; static const WCHAR abcdini_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','a','b','c','d','.','I','N','I',0 }; +static void check_error_(int line, DWORD expect) +{ + RETCODE ret; + DWORD err; + ret = SQLInstallerError(1, &err, NULL, 0, NULL); + ok_(__FILE__, line)(ret == SQL_SUCCESS_WITH_INFO, "got %d\n", ret); + ok_(__FILE__, line)(err == expect, "expected %u, got %u\n", expect, ret); +} +#define check_error(a) check_error_(__LINE__, a) static void test_SQLConfigMode(void) { @@ -605,6 +614,63 @@ static void test_SQLInstallTranslatorEx(void) } +static void test_SQLGetInstalledDrivers(void) +{ + char buffer[1000], *p; + WORD written, len; + int found = 0; + BOOL ret; + + SQLInstallDriverEx("Wine test\0Driver=test.dll\0\0", NULL, buffer, + sizeof(buffer), &written, ODBC_INSTALL_COMPLETE, NULL); + + ret = SQLGetInstalledDrivers(NULL, sizeof(buffer), &written); + ok(!ret, "got %d\n", ret); + check_error(ODBC_ERROR_INVALID_BUFF_LEN); + + ret = SQLGetInstalledDrivers(buffer, 0, &written); + ok(!ret, "got %d\n", ret); + check_error(ODBC_ERROR_INVALID_BUFF_LEN); + + ret = SQLGetInstalledDrivers(buffer, 10, &written); + ok(ret, "got %d\n", ret); + ok(strlen(buffer) == 8, "got len %u\n", lstrlenA(buffer)); + ok(written == 10, "got written %d\n", written); + ok(!buffer[9], "buffer not doubly null-terminated\n"); + + ret = SQLGetInstalledDrivers(buffer, sizeof(buffer), &written); + ok(ret, "got %d\n", ret); + ok(!buffer[written-1] && !buffer[written-2], "buffer not doubly null-terminated\n"); + len = strlen(buffer); + + for (p = buffer; *p; p += strlen(p) + 1) + { + if (!strcmp(p, "Wine test")) + found = 1; + } + ok(found, "installed driver not found\n"); + + ret = SQLGetInstalledDrivers(buffer, len, &written); + ok(ret, "got %d\n", ret); + ok(strlen(buffer) == len-2, "expected len %d, got %u\n", len-2, lstrlenA(buffer)); + ok(written == len, "expected written %d, got %d\n", len, written); + ok(!buffer[len-1], "buffer not doubly null-terminated\n"); + + ret = SQLGetInstalledDrivers(buffer, len+1, &written); + ok(ret, "got %d\n", ret); + ok(strlen(buffer) == len-1, "expected len %d, got %u\n", len-1, lstrlenA(buffer)); + ok(written == len+1, "expected written %d, got %d\n", len+1, written); + ok(!buffer[len], "buffer not doubly null-terminated\n"); + + ret = SQLGetInstalledDrivers(buffer, len+2, &written); + ok(ret, "got %d\n", ret); + ok(strlen(buffer) == len, "expected len %d, got %u\n", len, lstrlenA(buffer)); + ok(written == len+2, "expected written %d, got %d\n", len+2, written); + ok(!buffer[len+1], "buffer not doubly null-terminated\n"); + + SQLRemoveDriver("Wine test", TRUE, NULL); +} + START_TEST(misc) { test_SQLConfigMode(); @@ -615,4 +681,5 @@ START_TEST(misc) test_SQLGetPrivateProfileStringW(); test_SQLInstallDriverEx(); test_SQLInstallTranslatorEx(); + test_SQLGetInstalledDrivers(); }
6 years, 5 months
1
0
0
0
01/01: [ODBCCP32] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d52f5b708bf6e0c8a364a…
commit d52f5b708bf6e0c8a364a7bb0433f98bfc19708b Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:44:04 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:44:04 2018 +0100 [ODBCCP32] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/odbccp32/odbccp32.c | 144 ++++++++++++++++++++++-------------------- media/doc/README.WINE | 2 +- 2 files changed, 75 insertions(+), 71 deletions(-) diff --git a/dll/win32/odbccp32/odbccp32.c b/dll/win32/odbccp32/odbccp32.c index f9a2269345..862237c677 100644 --- a/dll/win32/odbccp32/odbccp32.c +++ b/dll/win32/odbccp32/odbccp32.c @@ -482,99 +482,103 @@ BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode) return TRUE; } -/* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations - * e.g. The Microsoft one occasionally actually adds a third nul character (possibly beyond the buffer). - * e.g. If the key has no drivers then version 3.525.1117.0 does not modify the buffer at all, not even a nul character. - */ -BOOL WINAPI SQLGetInstalledDriversW(LPWSTR lpszBuf, WORD cbBufMax, - WORD *pcbBufOut) +BOOL WINAPI SQLGetInstalledDriversW(WCHAR *buf, WORD size, WORD *sizeout) { - HKEY hDrivers; /* Registry handle to the Drivers key */ - LONG reg_ret; /* Return code from registry functions */ - BOOL success = FALSE; /* The value we will return */ + WORD written = 0; + DWORD index = 0; + BOOL ret = TRUE; + DWORD valuelen; + WCHAR *value; + HKEY drivers; + DWORD len; + LONG res; clear_errors(); - TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut); + TRACE("%p %d %p\n", buf, size, sizeout); - if (!lpszBuf || cbBufMax == 0) + if (!buf || !size) { push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len); + return FALSE; } - else if ((reg_ret = RegOpenKeyExW (HKEY_LOCAL_MACHINE /* The drivers does not depend on the config mode */, - drivers_key, 0, KEY_READ /* Maybe overkill */, - &hDrivers)) == ERROR_SUCCESS) + + res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, drivers_key, 0, KEY_QUERY_VALUE, &drivers); + if (res) { - DWORD index = 0; - cbBufMax--; - success = TRUE; - while (cbBufMax > 0) - { - DWORD size_name; - size_name = cbBufMax; - if ((reg_ret = RegEnumValueW(hDrivers, index, lpszBuf, &size_name, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) - { - index++; - assert (size_name < cbBufMax && *(lpszBuf + size_name) == 0); - size_name++; - cbBufMax-= size_name; - lpszBuf+=size_name; - } - else - { - if (reg_ret != ERROR_NO_MORE_ITEMS) - { - success = FALSE; - push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err); - } - break; - } - } - *lpszBuf = 0; - if ((reg_ret = RegCloseKey (hDrivers)) != ERROR_SUCCESS) - TRACE ("Error %d closing ODBC Drivers key\n", reg_ret); + push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found); + return FALSE; } - else + + valuelen = 256; + value = heap_alloc(valuelen * sizeof(WCHAR)); + + size--; + + while (1) { - /* MSDN states that it returns failure with COMPONENT_NOT_FOUND in this case. - * Version 3.525.1117.0 (Windows 2000) does not; it actually returns success. - * I doubt if it will actually be an issue. - */ - push_error(ODBC_ERROR_COMPONENT_NOT_FOUND, odbc_error_component_not_found); + len = valuelen; + res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL); + while (res == ERROR_MORE_DATA) + { + value = heap_realloc(value, ++len * sizeof(WCHAR)); + res = RegEnumValueW(drivers, index, value, &len, NULL, NULL, NULL, NULL); + } + if (res == ERROR_SUCCESS) + { + lstrcpynW(buf + written, value, size - written); + written += min(len + 1, size - written); + } + else if (res == ERROR_NO_MORE_ITEMS) + break; + else + { + push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err); + ret = FALSE; + break; + } + index++; } - return success; + + buf[written++] = 0; + + heap_free(value); + RegCloseKey(drivers); + if (sizeout) + *sizeout = written; + return ret; } -BOOL WINAPI SQLGetInstalledDrivers(LPSTR lpszBuf, WORD cbBufMax, - WORD *pcbBufOut) +BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout) { + WORD written; + WCHAR *wbuf; BOOL ret; - int size_wbuf = cbBufMax; - LPWSTR wbuf; - WORD size_used; - TRACE("%p %d %p\n", lpszBuf, cbBufMax, pcbBufOut); + TRACE("%p %d %p\n", buf, size, sizeout); - wbuf = HeapAlloc(GetProcessHeap(), 0, size_wbuf*sizeof(WCHAR)); - if (wbuf) + if (!buf || !size) { - ret = SQLGetInstalledDriversW(wbuf, size_wbuf, &size_used); - if (ret) - { - if (!(ret = SQLInstall_narrow(2, lpszBuf, wbuf, size_used, cbBufMax, pcbBufOut))) - { - push_error(ODBC_ERROR_GENERAL_ERR, odbc_error_general_err); - } - } - HeapFree(GetProcessHeap(), 0, wbuf); - /* ignore failure; we have achieved the aim */ + push_error(ODBC_ERROR_INVALID_BUFF_LEN, odbc_error_invalid_buff_len); + return FALSE; } - else + + wbuf = heap_alloc(size * sizeof(WCHAR)); + if (!wbuf) { push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem); - ret = FALSE; + return FALSE; } - return ret; + + ret = SQLGetInstalledDriversW(wbuf, size, &written); + if (!ret) + return FALSE; + + *sizeout = WideCharToMultiByte(CP_ACP, 0, wbuf, written, NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, wbuf, written, buf, size, NULL, NULL); + + heap_free(wbuf); + return TRUE; } static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 969d46559e..829a9882a5 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -138,7 +138,7 @@ reactos/dll/win32/npptools # Synced to WineStaging-3.3 reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9 reactos/dll/win32/objsel # Synced to WineStaging-3.3 reactos/dll/win32/odbc32 # Synced to WineStaging-3.3. Depends on port of Linux ODBC. -reactos/dll/win32/odbccp32 # Synced to WineStaging-3.3 +reactos/dll/win32/odbccp32 # Synced to WineStaging-3.9 reactos/dll/win32/ole32 # Synced to WineStaging-3.3 reactos/dll/win32/oleacc # Synced to WineStaging-3.3 reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3
6 years, 5 months
1
0
0
0
01/01: [NTDSAPI] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33bcb8c53a3524faa9f3f…
commit 33bcb8c53a3524faa9f3f25fbdaee807d8060917 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:43:22 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:43:22 2018 +0100 [NTDSAPI] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/ntdsapi/ntdsapi.c | 23 +++++++++++++++++++++++ dll/win32/ntdsapi/ntdsapi.spec | 4 ++-- media/doc/README.WINE | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dll/win32/ntdsapi/ntdsapi.c b/dll/win32/ntdsapi/ntdsapi.c index ee0c8379c3..003b1a2361 100644 --- a/dll/win32/ntdsapi/ntdsapi.c +++ b/dll/win32/ntdsapi/ntdsapi.c @@ -204,6 +204,9 @@ DWORD WINAPI DsServerRegisterSpnW(DS_SPN_WRITE_OP operation, LPCWSTR ServiceClas return ERROR_CALL_NOT_IMPLEMENTED; } +/*********************************************************************** + * DsClientMakeSpnForTargetServerW (NTDSAPI.@) + */ DWORD WINAPI DsClientMakeSpnForTargetServerW(LPCWSTR class, LPCWSTR name, DWORD *buflen, LPWSTR buf) { DWORD len; @@ -229,3 +232,23 @@ DWORD WINAPI DsClientMakeSpnForTargetServerW(LPCWSTR class, LPCWSTR name, DWORD return ERROR_SUCCESS; } + +/*********************************************************************** + * DsCrackNamesA (NTDSAPI.@) + */ +DWORD WINAPI DsCrackNamesA(HANDLE handle, DS_NAME_FLAGS flags, DS_NAME_FORMAT offered, DS_NAME_FORMAT desired, + DWORD num, const CHAR **names, PDS_NAME_RESULTA *result) +{ + FIXME("(%p %u %u %u %u %p %p stub\n", handle, flags, offered, desired, num, names, result); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +/*********************************************************************** + * DsCrackNamesW (NTDSAPI.@) + */ +DWORD WINAPI DsCrackNamesW(HANDLE handle, DS_NAME_FLAGS flags, DS_NAME_FORMAT offered, DS_NAME_FORMAT desired, + DWORD num, const WCHAR **names, PDS_NAME_RESULTW *result) +{ + FIXME("(%p %u %u %u %u %p %p stub\n", handle, flags, offered, desired, num, names, result); + return ERROR_CALL_NOT_IMPLEMENTED; +} diff --git a/dll/win32/ntdsapi/ntdsapi.spec b/dll/win32/ntdsapi/ntdsapi.spec index 925cb71358..bc7827d232 100644 --- a/dll/win32/ntdsapi/ntdsapi.spec +++ b/dll/win32/ntdsapi/ntdsapi.spec @@ -8,8 +8,8 @@ @ stub DsBindWithSpnW @ stub DsClientMakeSpnForTargetServerA @ stdcall DsClientMakeSpnForTargetServerW(wstr wstr ptr ptr) -@ stub DsCrackNamesA -@ stub DsCrackNamesW +@ stdcall DsCrackNamesA(ptr long long long long ptr ptr) +@ stdcall DsCrackNamesW(ptr long long long long ptr ptr) @ stub DsCrackSpn2A @ stub DsCrackSpn2W @ stub DsCrackSpn3W diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 080c7c8341..969d46559e 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -135,7 +135,7 @@ reactos/dll/win32/msxml6 # Synced to WineStaging-3.3 reactos/dll/win32/nddeapi # Synced to WineStaging-3.3 reactos/dll/win32/netapi32 # Forked at Wine-1.3.34 reactos/dll/win32/npptools # Synced to WineStaging-3.3 -reactos/dll/win32/ntdsapi # Synced to WineStaging-3.3 +reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9 reactos/dll/win32/objsel # Synced to WineStaging-3.3 reactos/dll/win32/odbc32 # Synced to WineStaging-3.3. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-3.3
6 years, 5 months
1
0
0
0
01/01: [PSDK] Update ntdsapi.h. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2e5bae69dab4b696a7bdb…
commit 2e5bae69dab4b696a7bdbb6192a4a7e33001e9ea Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:42:29 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:42:29 2018 +0100 [PSDK] Update ntdsapi.h. CORE-14656 --- sdk/include/psdk/ntdsapi.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/sdk/include/psdk/ntdsapi.h b/sdk/include/psdk/ntdsapi.h index 672ea635d2..099c20575c 100644 --- a/sdk/include/psdk/ntdsapi.h +++ b/sdk/include/psdk/ntdsapi.h @@ -33,6 +33,30 @@ DWORD WINAPI DsMakeSpnA(LPCSTR, LPCSTR, LPCSTR, USHORT, LPCSTR, DWORD*, LPSTR); DWORD WINAPI DsMakeSpnW(LPCWSTR, LPCWSTR, LPCWSTR, USHORT, LPCWSTR, DWORD*, LPWSTR); #define DsMakeSpn WINELIB_NAME_AW(DsMakeSpn) +typedef enum +{ + DS_NAME_NO_FLAGS = 0x0, + DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1, + DS_NAME_FLAG_EVAL_AT_DC = 0x2, + DS_NAME_FLAG_GCVERIFY = 0x4, + DS_NAME_FLAG_TRUST_REFERRAL = 0x8 +} DS_NAME_FLAGS; + +typedef enum +{ + DS_UNKNOWN_NAME = 0, + DS_FQDN_1779_NAME = 1, + DS_NT4_ACCOUNT_NAME = 2, + DS_DISPLAY_NAME = 3, + DS_UNIQUE_ID_NAME = 6, + DS_CANONICAL_NAME = 7, + DS_USER_PRINCIPAL_NAME = 8, + DS_CANONICAL_NAME_EX = 9, + DS_SERVICE_PRINCIPAL_NAME = 10, + DS_SID_OR_SID_HISTORY_NAME = 11, + DS_DNS_DOMAIN_NAME = 12 +} DS_NAME_FORMAT; + typedef enum { DS_SPN_DNS_HOST = 0, @@ -50,6 +74,41 @@ typedef enum DS_SPN_DELETE_SPN_OP = 2 } DS_SPN_WRITE_OP; +typedef struct +{ + DWORD status; + LPSTR pDomain; + LPSTR pName; +} DS_NAME_RESULT_ITEMA, *PDS_NAME_RESULT_ITEMA; + +typedef struct +{ + DWORD status; + LPWSTR pDomain; + LPWSTR pName; +} DS_NAME_RESULT_ITEMW, *PDS_NAME_RESULT_ITEMW; + +DECL_WINELIB_TYPE_AW(DS_NAME_RESULT_ITEM) +DECL_WINELIB_TYPE_AW(PDS_NAME_RESULT_ITEM) + +typedef struct +{ + DWORD cItems; + PDS_NAME_RESULT_ITEMA rItems; +} DS_NAME_RESULTA, *PDS_NAME_RESULTA; + +typedef struct +{ + DWORD cItems; + PDS_NAME_RESULT_ITEMW rItems; +} DS_NAME_RESULTW, *PDS_NAME_RESULTW; + +DECL_WINELIB_TYPE_AW(DS_NAME_RESULT) +DECL_WINELIB_TYPE_AW(PDS_NAME_RESULT) + +DWORD WINAPI DsCrackNamesA(HANDLE handle, DS_NAME_FLAGS flags, DS_NAME_FORMAT offered, DS_NAME_FORMAT desired, DWORD num, const CHAR **names, PDS_NAME_RESULTA *result); +DWORD WINAPI DsCrackNamesW(HANDLE handle, DS_NAME_FLAGS flags, DS_NAME_FORMAT offered, DS_NAME_FORMAT desired, DWORD num, const WCHAR **names, PDS_NAME_RESULTW *result); +#define DsCrackNames WINELIB_NAME_AW(DsCrackNames) DWORD WINAPI DsServerRegisterSpnA(DS_SPN_WRITE_OP operation, LPCSTR ServiceClass, LPCSTR UserObjectDN); DWORD WINAPI DsServerRegisterSpnW(DS_SPN_WRITE_OP operation, LPCWSTR ServiceClass, LPCWSTR UserObjectDN); #define DsServerRegisterSpn WINELIB_NAME_AW(DsServerRegisterSpn)
6 years, 5 months
1
0
0
0
01/01: [MSCTF_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9b29365701a0f39313ac8…
commit 9b29365701a0f39313ac8d96984eec8e61e02b8d Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:41:36 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:41:36 2018 +0100 [MSCTF_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/msctf/inputprocessor.c | 59 ++++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/modules/rostests/winetests/msctf/inputprocessor.c b/modules/rostests/winetests/msctf/inputprocessor.c index 9bd112c830..8a02f95117 100644 --- a/modules/rostests/winetests/msctf/inputprocessor.c +++ b/modules/rostests/winetests/msctf/inputprocessor.c @@ -64,6 +64,7 @@ static DWORD tmSinkCookie; static DWORD tmSinkRefCount; static DWORD dmSinkCookie; static DWORD documentStatus; +static DWORD key_trace_sink_cookie; static ITfDocumentMgr *test_CurrentFocus = NULL; static ITfDocumentMgr *test_PrevFocus = NULL; static ITfDocumentMgr *test_LastCurrentFocus = FOCUS_SAVE; @@ -625,6 +626,51 @@ static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut) return S_OK; } +static HRESULT WINAPI TfKeyTraceEventSink_QueryInterface(ITfKeyTraceEventSink *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITfKeyTraceEventSink, riid)) { + *ppv = iface; + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI TfKeyTraceEventSink_AddRef(ITfKeyTraceEventSink *iface) +{ + return 2; +} + +static ULONG WINAPI TfKeyTraceEventSink_Release(ITfKeyTraceEventSink *iface) +{ + return 1; +} + +static HRESULT WINAPI TfKeyTraceEventSink_OnKeyTraceDown(ITfKeyTraceEventSink *iface, + WPARAM wparam, LPARAM lparam) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI TfKeyTraceEventSink_OnKeyTraceUp(ITfKeyTraceEventSink *iface, + WPARAM wparam, LPARAM lparam) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const ITfKeyTraceEventSinkVtbl TfKeyTraceEventSinkVtbl = { + TfKeyTraceEventSink_QueryInterface, + TfKeyTraceEventSink_AddRef, + TfKeyTraceEventSink_Release, + TfKeyTraceEventSink_OnKeyTraceDown, + TfKeyTraceEventSink_OnKeyTraceUp +}; + +static ITfKeyTraceEventSink TfKeyTraceEventSink = { &TfKeyTraceEventSinkVtbl }; + static HRESULT WINAPI TfTransitoryExtensionSink_QueryInterface(ITfTransitoryExtensionSink *iface, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITfTransitoryExtensionSink, riid)) { @@ -1070,13 +1116,18 @@ static void test_ThreadMgrAdviseSinks(void) tmSinkRefCount = 1; tmSinkCookie = 0; hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to Advise Sink\n"); + ok(hr == S_OK, "Failed to Advise Sink\n"); ok(tmSinkCookie!=0,"Failed to get sink cookie\n"); /* Advising the sink adds a ref, Releasing here lets the object be deleted when unadvised */ tmSinkRefCount = 2; IUnknown_Release(sink); + + hr = ITfSource_AdviseSink(source, &IID_ITfKeyTraceEventSink, (IUnknown*)&TfKeyTraceEventSink, + &key_trace_sink_cookie); + ok(hr == S_OK, "Failed to Advise Sink\n"); + ITfSource_Release(source); } @@ -1092,7 +1143,11 @@ static void test_ThreadMgrUnadviseSinks(void) tmSinkRefCount = 1; hr = ITfSource_UnadviseSink(source, tmSinkCookie); - ok(SUCCEEDED(hr),"Failed to unadvise Sink\n"); + ok(hr == S_OK, "Failed to unadvise Sink\n"); + + hr = ITfSource_UnadviseSink(source, key_trace_sink_cookie); + ok(hr == S_OK, "Failed to unadvise Sink\n"); + ITfSource_Release(source); }
6 years, 5 months
1
0
0
0
01/01: [MSCTF] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4335e46944d1b3aeb1a1b…
commit 4335e46944d1b3aeb1a1bb62e2e73e7bfac5c1fc Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:41:08 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:41:08 2018 +0100 [MSCTF] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/msctf/context.c | 6 +++--- dll/win32/msctf/msctf_internal.h | 1 + dll/win32/msctf/threadmgr.c | 12 +++++++++++- media/doc/README.WINE | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dll/win32/msctf/context.c b/dll/win32/msctf/context.c index 54052f6302..452895c07e 100644 --- a/dll/win32/msctf/context.c +++ b/dll/win32/msctf/context.c @@ -758,14 +758,14 @@ static HRESULT WINAPI TextStoreACPSink_OnTextChange(ITextStoreACPSink *iface, { Context *This = impl_from_ITextStoreACPSink(iface); FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI TextStoreACPSink_OnSelectionChange(ITextStoreACPSink *iface) { Context *This = impl_from_ITextStoreACPSink(iface); FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface, @@ -773,7 +773,7 @@ static HRESULT WINAPI TextStoreACPSink_OnLayoutChange(ITextStoreACPSink *iface, { Context *This = impl_from_ITextStoreACPSink(iface); FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI TextStoreACPSink_OnStatusChange(ITextStoreACPSink *iface, diff --git a/dll/win32/msctf/msctf_internal.h b/dll/win32/msctf/msctf_internal.h index d5e7fe0d03..9d37548361 100644 --- a/dll/win32/msctf/msctf_internal.h +++ b/dll/win32/msctf/msctf_internal.h @@ -31,6 +31,7 @@ #define COOKIE_MAGIC_COMPARTMENTSINK 0x0060 #define COOKIE_MAGIC_DMSINK 0x0070 #define COOKIE_MAGIC_THREADFOCUSSINK 0x0080 +#define COOKIE_MAGIC_KEYTRACESINK 0x0090 extern DWORD tlsIndex DECLSPEC_HIDDEN; extern TfClientId processId DECLSPEC_HIDDEN; diff --git a/dll/win32/msctf/threadmgr.c b/dll/win32/msctf/threadmgr.c index 8ca12ac078..5338e7271c 100644 --- a/dll/win32/msctf/threadmgr.c +++ b/dll/win32/msctf/threadmgr.c @@ -621,6 +621,13 @@ static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface, return advise_sink(&This->ThreadFocusSink, &IID_ITfThreadFocusSink, COOKIE_MAGIC_THREADFOCUSSINK, punk, pdwCookie); } + if (IsEqualIID(riid, &IID_ITfKeyTraceEventSink)) + { + WARN("semi-stub for ITfKeyTraceEventSink: sink won't be used.\n"); + return advise_sink(&This->KeyTraceEventSink, &IID_ITfKeyTraceEventSink, + COOKIE_MAGIC_KEYTRACESINK, punk, pdwCookie); + } + FIXME("(%p) Unhandled Sink: %s\n",This,debugstr_guid(riid)); return E_NOTIMPL; } @@ -628,10 +635,13 @@ static HRESULT WINAPI ThreadMgrSource_AdviseSink(ITfSource *iface, static HRESULT WINAPI ThreadMgrSource_UnadviseSink(ITfSource *iface, DWORD pdwCookie) { ThreadMgr *This = impl_from_ITfSource(iface); + DWORD magic; TRACE("(%p) %x\n",This,pdwCookie); - if (get_Cookie_magic(pdwCookie) != COOKIE_MAGIC_TMSINK && get_Cookie_magic(pdwCookie) != COOKIE_MAGIC_THREADFOCUSSINK) + magic = get_Cookie_magic(pdwCookie); + if (magic != COOKIE_MAGIC_TMSINK && magic != COOKIE_MAGIC_THREADFOCUSSINK + && magic != COOKIE_MAGIC_KEYTRACESINK) return E_INVALIDARG; return unadvise_sink(pdwCookie); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 3db38f6dd3..080c7c8341 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -106,7 +106,7 @@ reactos/dll/win32/msadp32.acm # Synced to WineStaging-3.3 reactos/dll/win32/mscat32 # Synced to WineStaging-3.3 reactos/dll/win32/mscms # Synced to WineStaging-3.3 reactos/dll/win32/mscoree # Synced to Wine-1.5.4 -reactos/dll/win32/msctf # Synced to WineStaging-3.3 +reactos/dll/win32/msctf # Synced to WineStaging-3.9 reactos/dll/win32/msftedit # Synced to WineStaging-3.3 reactos/dll/win32/msg711.acm # Synced to WineStaging-3.3 reactos/dll/win32/msgsm32.acm # Synced to WineStaging-3.3
6 years, 5 months
1
0
0
0
← Newer
1
...
11
12
13
14
15
16
17
18
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Results per page:
10
25
50
100
200