https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d5f5161804743b1d17da3…
commit d5f5161804743b1d17da338e7f3274933b9a4a45
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Jun 7 15:48:42 2018 +0900
Commit: Mark Jansen <mark.jansen(a)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(a)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 },