https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d5f5161804743b1d17da33...
commit d5f5161804743b1d17da338e7f3274933b9a4a45 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Thu Jun 7 15:48:42 2018 +0900 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Thu Jun 14 19:59:11 2018 +0200
[SHELL32][APITESTS] Add tests of OpenAs_RunDLL --- modules/rostests/apitests/shell32/CMakeLists.txt | 1 + .../rostests/apitests/shell32/OpenAs_RunDLL.cpp | 216 +++++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + 3 files changed, 219 insertions(+)
diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 7526df1bad..ba7096b0c1 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND SOURCE CUserNotification.cpp IShellFolderViewCB.cpp menu.cpp + OpenAs_RunDLL.cpp PathResolve.cpp SHCreateFileExtractIconW.cpp ShellExecuteEx.cpp diff --git a/modules/rostests/apitests/shell32/OpenAs_RunDLL.cpp b/modules/rostests/apitests/shell32/OpenAs_RunDLL.cpp new file mode 100644 index 0000000000..f66d4585f5 --- /dev/null +++ b/modules/rostests/apitests/shell32/OpenAs_RunDLL.cpp @@ -0,0 +1,216 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for OpenAs_RunDLL + * PROGRAMMERS: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ + +#include "shelltest.h" +#include <stdio.h> +#include <process.h> + +// OpenAs_RunDLLA +typedef void (WINAPI *OPENAS_RUNDLLA)(HWND, HINSTANCE, LPCSTR, int); +// OpenAs_RunDLLW +typedef void (WINAPI *OPENAS_RUNDLLW)(HWND, HINSTANCE, LPCWSTR, int); + +static OPENAS_RUNDLLA pOpenAs_RunDLLA = NULL; +static OPENAS_RUNDLLW pOpenAs_RunDLLW = NULL; + +struct TEST_ENTRY +{ + int nLine; + BOOL bWide; + HINSTANCE hInst; + int nRet; + BOOL bCreateFile; + LPCSTR pszFileA; + LPCWSTR pszFileW; + DWORD dwError; +}; + +#define COUNT 5 +#define INTERVAL 200 + +#define DEATH 999 +#define OPENED 1 +#define NOT_OPENED 0 + +#define BAD_INST ((HINSTANCE)0xDEAD) +#define BAD_SZ_A ((LPCSTR)0xDEAD) +#define BAD_SZ_W ((LPCWSTR)0xDEAD) + +static const TEST_ENTRY s_TestEntries[] = +{ + // ANSI + {__LINE__, FALSE, NULL, OPENED, FALSE, NULL, NULL, 0 }, + {__LINE__, FALSE, NULL, OPENED, FALSE, "", NULL, 0 }, + {__LINE__, FALSE, NULL, OPENED, FALSE, "invalid file name.txt", NULL, 0 }, + {__LINE__, FALSE, NULL, DEATH, FALSE, BAD_SZ_A, NULL, 0 }, + {__LINE__, FALSE, NULL, OPENED, TRUE, "created file.txt", NULL, 0 }, + {__LINE__, FALSE, BAD_INST, OPENED, FALSE, NULL, NULL, 0 }, + {__LINE__, FALSE, BAD_INST, OPENED, FALSE, "invalid file name.txt", NULL, 0 }, + {__LINE__, FALSE, BAD_INST, DEATH, FALSE, BAD_SZ_A, NULL, 0xDEADFACE }, + {__LINE__, FALSE, BAD_INST, OPENED, TRUE, "created file.txt", NULL, 0 }, + // WIDE + {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, NULL, 0x80070490 }, + {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, L"", ERROR_NO_SCROLLBARS }, + {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, L"invalid file name.txt", ERROR_NO_SCROLLBARS }, + {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, BAD_SZ_W, 0xDEADFACE }, + {__LINE__, TRUE, NULL, OPENED, TRUE, NULL, L"created file.txt", ERROR_NO_SCROLLBARS }, + {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, NULL, 0x80070490 }, + {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, L"invalid file name.txt", ERROR_NO_SCROLLBARS }, + {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, BAD_SZ_W, 0xDEADFACE }, + {__LINE__, TRUE, BAD_INST, OPENED, TRUE, NULL, L"created file.txt", ERROR_NO_SCROLLBARS }, +}; + +static HANDLE s_hThread = NULL; +static INT s_nRet = NOT_OPENED; + +static unsigned __stdcall +watch_thread_proc(void *arg) +{ + for (int i = 0; i < COUNT; ++i) + { + Sleep(INTERVAL); + + HWND hwnd = FindWindowA("#32770", "Open With"); + if (hwnd == NULL) + continue; + + if (!IsWindowVisible(hwnd)) + { + trace("not visible\n"); + continue; + } + + s_nRet = OPENED; + PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), 0); + break; + } + return 0; +} + +static void StartWatchGUI(const TEST_ENTRY *pEntry) +{ + s_nRet = NOT_OPENED; + s_hThread = (HANDLE)_beginthreadex(NULL, 0, watch_thread_proc, NULL, 0, NULL); +} + +static void DoEntry(const TEST_ENTRY *pEntry) +{ + if (pEntry->bWide) + { + if (pEntry->bCreateFile) + { + FILE *fp = _wfopen(pEntry->pszFileW, L"wb"); + ok(fp != NULL, "Line %d: Unable to create file '%s'\n", pEntry->nLine, wine_dbgstr_w(pEntry->pszFileW)); + fclose(fp); + } + + StartWatchGUI(pEntry); + SetLastError(0xDEADFACE); + + _SEH2_TRY + { + (*pOpenAs_RunDLLW)(NULL, pEntry->hInst, pEntry->pszFileW, SW_SHOWDEFAULT); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + s_nRet = DEATH; + } + _SEH2_END; + + DWORD dwError = GetLastError(); + ok(pEntry->dwError == dwError, "Line %d: error expected %ld, was %ld\n", pEntry->nLine, pEntry->dwError, dwError); + + WaitForSingleObject(s_hThread, INFINITE); + CloseHandle(s_hThread); + + if (pEntry->bCreateFile) + { + ok(DeleteFileW(pEntry->pszFileW), "Line %d: DeleteFileA failed\n", pEntry->nLine); + } + } + else + { + if (pEntry->bCreateFile) + { + FILE *fp = fopen(pEntry->pszFileA, "wb"); + ok(fp != NULL, "Line %d: Unable to create file '%s'\n", pEntry->nLine, pEntry->pszFileA); + fclose(fp); + } + + StartWatchGUI(pEntry); + SetLastError(0xDEADFACE); + + _SEH2_TRY + { + (*pOpenAs_RunDLLA)(NULL, pEntry->hInst, pEntry->pszFileA, SW_SHOWDEFAULT); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + s_nRet = DEATH; + } + _SEH2_END; + + DWORD dwError = GetLastError(); + ok(pEntry->dwError == dwError, "Line %d: error expected %ld, was %ld\n", pEntry->nLine, pEntry->dwError, dwError); + + WaitForSingleObject(s_hThread, INFINITE); + CloseHandle(s_hThread); + + if (pEntry->bCreateFile) + { + ok(DeleteFileA(pEntry->pszFileA), "Line %d: DeleteFileA failed\n", pEntry->nLine); + } + } + + ok(pEntry->nRet == s_nRet, "Line %d: s_nRet expected %d, was %d\n", pEntry->nLine, pEntry->nRet, s_nRet); +} + +START_TEST(OpenAs_RunDLL) +{ + HINSTANCE hShell32 = LoadLibraryA("shell32.dll"); + if (hShell32 == NULL) + { + skip("Unable to load shell32.dll\n"); + return; + } + + pOpenAs_RunDLLA = (OPENAS_RUNDLLA)GetProcAddress(hShell32, "OpenAs_RunDLLA"); + if (pOpenAs_RunDLLA == NULL) + { + skip("Unable to get OpenAs_RunDLLA\n"); + return; + } + + pOpenAs_RunDLLW = (OPENAS_RUNDLLW)GetProcAddress(hShell32, "OpenAs_RunDLLW"); + if (pOpenAs_RunDLLW == NULL) + { + skip("Unable to get OpenAs_RunDLLW\n"); + return; + } + + TCHAR szCurDir[MAX_PATH], szTempDir[MAX_PATH]; + + ok(GetCurrentDirectory(_countof(szCurDir), szCurDir), "GetCurrentDirectory failed\n"); + ok(GetTempPath(_countof(szTempDir), szTempDir), "GetTempPath failed\n"); + + if (!SetCurrentDirectory(szTempDir)) + { + skip("SetCurrentDirectory failed\n"); + } + else + { + for (size_t i = 0; i < _countof(s_TestEntries); ++i) + { + const TEST_ENTRY *pEntry = &s_TestEntries[i]; + DoEntry(pEntry); + } + + ok(SetCurrentDirectory(szCurDir), "SetCurrentDirectory failed\n"); + } + + FreeLibrary(hShell32); +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index 7db323ad99..975b933f3f 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -12,6 +12,7 @@ extern void func_CShellLink(void); extern void func_CUserNotification(void); extern void func_IShellFolderViewCB(void); extern void func_menu(void); +extern void func_OpenAs_RunDLL(void); extern void func_PathResolve(void); extern void func_SHCreateFileExtractIconW(void); extern void func_ShellExecuteEx(void); @@ -28,6 +29,7 @@ const struct test winetest_testlist[] = { "CUserNotification", func_CUserNotification }, { "IShellFolderViewCB", func_IShellFolderViewCB }, { "menu", func_menu }, + { "OpenAs_RunDLL", func_OpenAs_RunDLL }, { "PathResolve", func_PathResolve }, { "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW }, { "ShellExecuteEx", func_ShellExecuteEx },