1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for OpenAs_RunDLL 5 * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #include "shelltest.h" 9 #include <stdio.h> 10 #include <process.h> 11 12 // OpenAs_RunDLLA 13 typedef void (WINAPI *OPENAS_RUNDLLA)(HWND, HINSTANCE, LPCSTR, int); 14 // OpenAs_RunDLLW 15 typedef void (WINAPI *OPENAS_RUNDLLW)(HWND, HINSTANCE, LPCWSTR, int); 16 17 static OPENAS_RUNDLLA pOpenAs_RunDLLA = NULL; 18 static OPENAS_RUNDLLW pOpenAs_RunDLLW = NULL; 19 20 struct TEST_ENTRY 21 { 22 int nLine; 23 BOOL bWide; 24 HINSTANCE hInst; 25 int nRet; 26 BOOL bCreateFile; 27 LPCSTR pszFileA; 28 LPCWSTR pszFileW; 29 DWORD dwError; 30 }; 31 32 #define COUNT 5 33 #define INTERVAL 200 34 35 #define DEATH 999 36 #define OPENED 1 37 #define NOT_OPENED 0 38 39 #define BAD_INST ((HINSTANCE)0xDEAD) 40 #define BAD_SZ_A ((LPCSTR)0xDEAD) 41 #define BAD_SZ_W ((LPCWSTR)0xDEAD) 42 43 static const TEST_ENTRY s_TestEntries[] = 44 { 45 // ANSI 46 {__LINE__, FALSE, NULL, OPENED, FALSE, NULL, NULL, 0 }, 47 {__LINE__, FALSE, NULL, OPENED, FALSE, "", NULL, 0 }, 48 {__LINE__, FALSE, NULL, OPENED, FALSE, "invalid file name.txt", NULL, 0 }, 49 {__LINE__, FALSE, NULL, DEATH, FALSE, BAD_SZ_A, NULL, 0 }, 50 {__LINE__, FALSE, NULL, OPENED, TRUE, "created file.txt", NULL, 0 }, 51 {__LINE__, FALSE, BAD_INST, OPENED, FALSE, NULL, NULL, 0 }, 52 {__LINE__, FALSE, BAD_INST, OPENED, FALSE, "invalid file name.txt", NULL, 0 }, 53 {__LINE__, FALSE, BAD_INST, DEATH, FALSE, BAD_SZ_A, NULL, 0xDEADFACE }, 54 {__LINE__, FALSE, BAD_INST, OPENED, TRUE, "created file.txt", NULL, 0 }, 55 // WIDE 56 {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, NULL, 0x80070490 }, 57 {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, L"", ERROR_NO_SCROLLBARS }, 58 {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, L"invalid file name.txt", ERROR_NO_SCROLLBARS }, 59 {__LINE__, TRUE, NULL, OPENED, FALSE, NULL, BAD_SZ_W, 0xDEADFACE }, 60 {__LINE__, TRUE, NULL, OPENED, TRUE, NULL, L"created file.txt", ERROR_NO_SCROLLBARS }, 61 {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, NULL, 0x80070490 }, 62 {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, L"invalid file name.txt", ERROR_NO_SCROLLBARS }, 63 {__LINE__, TRUE, BAD_INST, OPENED, FALSE, NULL, BAD_SZ_W, 0xDEADFACE }, 64 {__LINE__, TRUE, BAD_INST, OPENED, TRUE, NULL, L"created file.txt", ERROR_NO_SCROLLBARS }, 65 }; 66 67 static HANDLE s_hThread = NULL; 68 static INT s_nRet = NOT_OPENED; 69 70 static unsigned __stdcall 71 watch_thread_proc(void *arg) 72 { 73 for (int i = 0; i < COUNT; ++i) 74 { 75 Sleep(INTERVAL); 76 77 HWND hwnd = FindWindowA("#32770", "Open With"); 78 if (hwnd == NULL) 79 continue; 80 81 if (!IsWindowVisible(hwnd)) 82 { 83 trace("not visible\n"); 84 continue; 85 } 86 87 s_nRet = OPENED; 88 PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), 0); 89 break; 90 } 91 return 0; 92 } 93 94 static void StartWatchGUI(const TEST_ENTRY *pEntry) 95 { 96 s_nRet = NOT_OPENED; 97 s_hThread = (HANDLE)_beginthreadex(NULL, 0, watch_thread_proc, NULL, 0, NULL); 98 } 99 100 static void DoEntry(const TEST_ENTRY *pEntry) 101 { 102 if (pEntry->bWide) 103 { 104 if (pEntry->bCreateFile) 105 { 106 FILE *fp = _wfopen(pEntry->pszFileW, L"wb"); 107 ok(fp != NULL, "Line %d: Unable to create file '%s'\n", pEntry->nLine, wine_dbgstr_w(pEntry->pszFileW)); 108 fclose(fp); 109 } 110 111 StartWatchGUI(pEntry); 112 SetLastError(0xDEADFACE); 113 114 _SEH2_TRY 115 { 116 (*pOpenAs_RunDLLW)(NULL, pEntry->hInst, pEntry->pszFileW, SW_SHOWDEFAULT); 117 } 118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 119 { 120 s_nRet = DEATH; 121 } 122 _SEH2_END; 123 124 DWORD dwError = GetLastError(); 125 ok(pEntry->dwError == dwError, "Line %d: error expected %ld, was %ld\n", pEntry->nLine, pEntry->dwError, dwError); 126 127 WaitForSingleObject(s_hThread, INFINITE); 128 CloseHandle(s_hThread); 129 130 if (pEntry->bCreateFile) 131 { 132 ok(DeleteFileW(pEntry->pszFileW), "Line %d: DeleteFileA failed\n", pEntry->nLine); 133 } 134 } 135 else 136 { 137 if (pEntry->bCreateFile) 138 { 139 FILE *fp = fopen(pEntry->pszFileA, "wb"); 140 ok(fp != NULL, "Line %d: Unable to create file '%s'\n", pEntry->nLine, pEntry->pszFileA); 141 fclose(fp); 142 } 143 144 StartWatchGUI(pEntry); 145 SetLastError(0xDEADFACE); 146 147 _SEH2_TRY 148 { 149 (*pOpenAs_RunDLLA)(NULL, pEntry->hInst, pEntry->pszFileA, SW_SHOWDEFAULT); 150 } 151 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 152 { 153 s_nRet = DEATH; 154 } 155 _SEH2_END; 156 157 DWORD dwError = GetLastError(); 158 ok(pEntry->dwError == dwError, "Line %d: error expected %ld, was %ld\n", pEntry->nLine, pEntry->dwError, dwError); 159 160 WaitForSingleObject(s_hThread, INFINITE); 161 CloseHandle(s_hThread); 162 163 if (pEntry->bCreateFile) 164 { 165 ok(DeleteFileA(pEntry->pszFileA), "Line %d: DeleteFileA failed\n", pEntry->nLine); 166 } 167 } 168 169 // FIXME: This function probably returns void 170 //ok(pEntry->nRet == s_nRet, "Line %d: s_nRet expected %d, was %d\n", pEntry->nLine, pEntry->nRet, s_nRet); 171 } 172 173 START_TEST(OpenAs_RunDLL) 174 { 175 HINSTANCE hShell32 = LoadLibraryA("shell32.dll"); 176 if (hShell32 == NULL) 177 { 178 skip("Unable to load shell32.dll\n"); 179 return; 180 } 181 182 pOpenAs_RunDLLA = (OPENAS_RUNDLLA)GetProcAddress(hShell32, "OpenAs_RunDLLA"); 183 if (pOpenAs_RunDLLA == NULL) 184 { 185 skip("Unable to get OpenAs_RunDLLA\n"); 186 return; 187 } 188 189 pOpenAs_RunDLLW = (OPENAS_RUNDLLW)GetProcAddress(hShell32, "OpenAs_RunDLLW"); 190 if (pOpenAs_RunDLLW == NULL) 191 { 192 skip("Unable to get OpenAs_RunDLLW\n"); 193 return; 194 } 195 196 TCHAR szCurDir[MAX_PATH], szTempDir[MAX_PATH]; 197 198 ok(GetCurrentDirectory(_countof(szCurDir), szCurDir), "GetCurrentDirectory failed\n"); 199 ok(GetTempPath(_countof(szTempDir), szTempDir), "GetTempPath failed\n"); 200 201 if (!SetCurrentDirectory(szTempDir)) 202 { 203 skip("SetCurrentDirectory failed\n"); 204 } 205 else 206 { 207 for (size_t i = 0; i < _countof(s_TestEntries); ++i) 208 { 209 const TEST_ENTRY *pEntry = &s_TestEntries[i]; 210 DoEntry(pEntry); 211 } 212 213 ok(SetCurrentDirectory(szCurDir), "SetCurrentDirectory failed\n"); 214 } 215 216 FreeLibrary(hShell32); 217 } 218