From: Amine Khaldi Date: Sat, 19 May 2012 14:35:44 +0000 (+0000) Subject: [STI_WINETEST] X-Git-Tag: backups/ros-csrss@57560~911 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=70bd3dabc79961f024ba3c03377d58a07f3c5a12 [STI_WINETEST] * Import from Wine 1.5.4. svn path=/trunk/; revision=56632 --- diff --git a/rostests/winetests/CMakeLists.txt b/rostests/winetests/CMakeLists.txt index f274d67531a..28c48f5008e 100644 --- a/rostests/winetests/CMakeLists.txt +++ b/rostests/winetests/CMakeLists.txt @@ -85,6 +85,7 @@ add_subdirectory(shell32) add_subdirectory(shlwapi) add_subdirectory(snmpapi) add_subdirectory(spoolss) +add_subdirectory(sti) add_subdirectory(twain_32) if(NOT MSVC) add_subdirectory(urlmon) # FIXME: msvc build. diff --git a/rostests/winetests/sti/CMakeLists.txt b/rostests/winetests/sti/CMakeLists.txt new file mode 100644 index 00000000000..a29b8b3fef2 --- /dev/null +++ b/rostests/winetests/sti/CMakeLists.txt @@ -0,0 +1,10 @@ + +add_definitions( + -D__ROS_LONG64__ + -D_DLL -D__USE_CRTIMP) + +add_executable(sti_winetest sti.c testlist.c) +target_link_libraries(sti_winetest wine uuid) +set_module_type(sti_winetest win32cui) +add_importlibs(sti_winetest ole32 msvcrt kernel32 ntdll) +add_cd_file(TARGET sti_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/sti/sti.c b/rostests/winetests/sti/sti.c new file mode 100644 index 00000000000..c74f7938a06 --- /dev/null +++ b/rostests/winetests/sti/sti.c @@ -0,0 +1,279 @@ +/* + * General still image implementation + * + * Copyright 2009 Damjan Jovanovic + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "windef.h" +#include "winbase.h" +#define COBJMACROS +#include +#include +#include +#include +#include + +#include "wine/test.h" + +static HMODULE sti_dll; +static HRESULT (WINAPI *pStiCreateInstance)(HINSTANCE,DWORD,PSTIW*,LPUNKNOWN); +static HRESULT (WINAPI *pStiCreateInstanceA)(HINSTANCE,DWORD,PSTIA*,LPUNKNOWN); +static HRESULT (WINAPI *pStiCreateInstanceW)(HINSTANCE,DWORD,PSTIW*,LPUNKNOWN); + +static BOOL aggregator_addref_called; + +static HRESULT WINAPI aggregator_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject) +{ + return E_NOTIMPL; +} + +static ULONG WINAPI aggregator_AddRef(IUnknown *iface) +{ + aggregator_addref_called = TRUE; + return 2; +} + +static ULONG WINAPI aggregator_Release(IUnknown *iface) +{ + return 1; +} + +static struct IUnknownVtbl aggregator_vtbl = +{ + aggregator_QueryInterface, + aggregator_AddRef, + aggregator_Release +}; + +static BOOL init_function_pointers(void) +{ + sti_dll = LoadLibrary("sti.dll"); + if (sti_dll) + { + pStiCreateInstance = (void*) + GetProcAddress(sti_dll, "StiCreateInstance"); + pStiCreateInstanceA = (void*) + GetProcAddress(sti_dll, "StiCreateInstanceA"); + pStiCreateInstanceW = (void*) + GetProcAddress(sti_dll, "StiCreateInstanceW"); + return TRUE; + } + return FALSE; +} + +static void test_version_flag_versus_aw(void) +{ + HRESULT hr; + + /* Who wins, the STI_VERSION_FLAG_UNICODE or the A/W function? And what about the neutral StiCreateInstance function? */ + + if (pStiCreateInstance) + { + PSTIW pStiW; + hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, NULL); + if (SUCCEEDED(hr)) + { + IUnknown *pUnknown; + hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown); + if (SUCCEEDED(hr)) + { + ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n"); + IUnknown_Release(pUnknown); + } + IUnknown_Release((IUnknown*)pStiW); + } + else + ok(0, "could not create StillImageA, hr = 0x%X\n", hr); + hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL); + if (SUCCEEDED(hr)) + { + IUnknown *pUnknown; + hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown); + if (SUCCEEDED(hr)) + { + ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n"); + IUnknown_Release(pUnknown); + } + IUnknown_Release((IUnknown*)pStiW); + } + else + ok(0, "could not create StillImageW, hr = 0x%X\n", hr); + } + else + skip("No StiCreateInstance function\n"); + + if (pStiCreateInstanceA) + { + PSTIA pStiA; + hr = pStiCreateInstanceA(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiA, NULL); + if (SUCCEEDED(hr)) + { + IUnknown *pUnknown; + hr = IUnknown_QueryInterface((IUnknown*)pStiA, &IID_IStillImageA, (void**)&pUnknown); + if (SUCCEEDED(hr)) + { + ok(pUnknown == (IUnknown*)pStiA, "created interface was not IID_IStillImageA\n"); + IUnknown_Release(pUnknown); + } + IUnknown_Release((IUnknown*)pStiA); + } + else + todo_wine ok(0, "could not create StillImageA, hr = 0x%X\n", hr); + } + else + skip("No StiCreateInstanceA function\n"); + + if (pStiCreateInstanceW) + { + PSTIW pStiW; + hr = pStiCreateInstanceW(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, NULL); + if (SUCCEEDED(hr)) + { + IUnknown *pUnknown; + hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown); + if (SUCCEEDED(hr)) + { + ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n"); + IUnknown_Release((IUnknown*)pUnknown); + } + IUnknown_Release((IUnknown*)pStiW); + } + else + ok(0, "could not create StillImageW, hr = 0x%X\n", hr); + } + else + skip("No StiCreateInstanceW function\n"); +} + +static void test_stillimage_aggregation(void) +{ + if (pStiCreateInstanceW) + { + IUnknown aggregator = { &aggregator_vtbl }; + IStillImageW *pStiW; + IUnknown *pUnknown; + HRESULT hr; + + /* When aggregating, the outer object must get the non-delegating IUnknown to be + able to control the inner object's reference count and query its interfaces. + But StiCreateInstance* only take PSTI. So how does the non-delegating IUnknown + come back to the outer object calling this function? */ + + hr = pStiCreateInstanceW(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, &aggregator); + if (SUCCEEDED(hr)) + { + IStillImageW *pStiW2 = NULL; + + /* Does this interface delegate? */ + aggregator_addref_called = FALSE; + IStillImage_AddRef(pStiW); + ok(!aggregator_addref_called, "the aggregated IStillImageW shouldn't delegate\n"); + IStillImage_Release(pStiW); + + /* Tests show calling IStillImageW_WriteToErrorLog on the interface segfaults on Windows, so I guess it's an IUnknown. + But querying for an IUnknown returns a different interface, which also delegates. + So much for COM being reflexive... + Anyway I doubt apps depend on any of this. */ + + /* And what about the IStillImageW interface? */ + hr = IStillImage_QueryInterface(pStiW, &IID_IStillImageW, (void**)&pStiW2); + if (SUCCEEDED(hr)) + { + ok(pStiW != pStiW2, "the aggregated IStillImageW and its queried IStillImageW unexpectedly match\n"); + /* Does it delegate? */ + aggregator_addref_called = FALSE; + IStillImage_AddRef(pStiW2); + ok(aggregator_addref_called, "the created IStillImageW's IStillImageW should delegate\n"); + IStillImage_Release(pStiW2); + IStillImage_Release(pStiW2); + } + else + ok(0, "could not query for IID_IStillImageW, hr = 0x%x\n", hr); + + IStillImage_Release(pStiW); + } + else + ok(0, "could not create StillImageW, hr = 0x%X\n", hr); + + /* Now do the above tests prove that STI.DLL isn't picky about querying for IUnknown + in CoCreateInterface when aggregating? */ + hr = CoCreateInstance(&CLSID_Sti, &aggregator, CLSCTX_ALL, &IID_IStillImageW, (void**)&pStiW); + ok(FAILED(hr), "CoCreateInstance unexpectedly succeeded when querying for IStillImageW during aggregation\n"); + if (SUCCEEDED(hr)) + IStillImage_Release(pStiW); + hr = CoCreateInstance(&CLSID_Sti, &aggregator, CLSCTX_ALL, &IID_IUnknown, (void**)&pUnknown); + ok(SUCCEEDED(hr) || + broken(hr == CLASS_E_NOAGGREGATION), /* Win 2000 */ + "CoCreateInstance unexpectedly failed when querying for IUnknown during aggregation, hr = 0x%x\n", hr); + if (SUCCEEDED(hr)) + IUnknown_Release(pUnknown); + } + else + skip("No StiCreateInstanceW function\n"); +} + +static void test_launch_app_registry(void) +{ + static WCHAR appName[] = {'w','i','n','e','s','t','i','t','e','s','t','a','p','p',0}; + IStillImageW *pStiW = NULL; + HRESULT hr; + + if (pStiCreateInstanceW == NULL) + { + win_skip("No StiCreateInstanceW function\n"); + return; + } + + hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL); + if (SUCCEEDED(hr)) + { + hr = IStillImage_RegisterLaunchApplication(pStiW, appName, appName); + if (hr == E_ACCESSDENIED) + skip("Not authorized to register a launch application\n"); + else if (SUCCEEDED(hr)) + { + hr = IStillImage_UnregisterLaunchApplication(pStiW, appName); + ok(SUCCEEDED(hr), "could not unregister launch application, error 0x%X\n", hr); + } + else + ok(0, "could not register launch application, error 0x%X\n", hr); + IStillImage_Release(pStiW); + } + else + ok(0, "could not create StillImageW, hr = 0x%X\n", hr); +} + +START_TEST(sti) +{ + if (SUCCEEDED(CoInitialize(NULL))) + { + if (init_function_pointers()) + { + test_version_flag_versus_aw(); + test_stillimage_aggregation(); + test_launch_app_registry(); + FreeLibrary(sti_dll); + } + else + skip("could not load sti.dll\n"); + CoUninitialize(); + } + else + skip("CoInitialize failed\n"); +} diff --git a/rostests/winetests/sti/testlist.c b/rostests/winetests/sti/testlist.c new file mode 100644 index 00000000000..14e95dd8e73 --- /dev/null +++ b/rostests/winetests/sti/testlist.c @@ -0,0 +1,13 @@ +#define WIN32_LEAN_AND_MEAN +#include + +#define STANDALONE +#include "wine/test.h" + +extern void func_sti(void); + +const struct test winetest_testlist[] = +{ + { "sti", func_sti }, + { 0, 0 } +};