2011-01-24 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / Tools / WebKitTestRunner / win / TestControllerWin.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "TestController.h"
27
28 #include <fcntl.h>
29 #include <io.h>
30 #include <shlwapi.h>
31 #include <string>
32 #include <WebKit2/WKContextPrivateWin.h>
33 #include <WebKit2/WKStringCF.h>
34 #include <wtf/RetainPtr.h>
35 #include <wtf/Vector.h>
36
37 using namespace std;
38
39 namespace WTR {
40
41 #ifdef DEBUG_ALL
42 const LPWSTR testPluginDirectoryName = L"TestNetscapePlugin_Debug";
43 const char* injectedBundleDLL = "\\InjectedBundle_debug.dll";
44 #else
45 const LPWSTR testPluginDirectoryName = L"TestNetscapePlugin";
46 const char* injectedBundleDLL = "\\InjectedBundle.dll";
47 #endif
48
49 static void addQTDirToPATH()
50 {
51     static LPCWSTR pathEnvironmentVariable = L"PATH";
52     static LPCWSTR quickTimeKeyName = L"Software\\Apple Computer, Inc.\\QuickTime";
53     static LPCWSTR quickTimeSysDir = L"QTSysDir";
54     static bool initialized;
55
56     if (initialized)
57         return;
58     initialized = true;
59
60     // Get the QuickTime dll directory from the registry. The key can be in either HKLM or HKCU.
61     WCHAR qtPath[MAX_PATH];
62     DWORD qtPathBufferLen = sizeof(qtPath);
63     DWORD keyType;
64     HRESULT result = ::SHGetValueW(HKEY_LOCAL_MACHINE, quickTimeKeyName, quickTimeSysDir, &keyType, (LPVOID)qtPath, &qtPathBufferLen);
65     if (result != ERROR_SUCCESS || !qtPathBufferLen || keyType != REG_SZ) {
66         qtPathBufferLen = sizeof(qtPath);
67         result = ::SHGetValueW(HKEY_CURRENT_USER, quickTimeKeyName, quickTimeSysDir, &keyType, (LPVOID)qtPath, &qtPathBufferLen);
68         if (result != ERROR_SUCCESS || !qtPathBufferLen || keyType != REG_SZ)
69             return;
70     }
71
72     // Read the current PATH.
73     DWORD pathSize = ::GetEnvironmentVariableW(pathEnvironmentVariable, 0, 0);
74     Vector<WCHAR> oldPath(pathSize);
75     if (!::GetEnvironmentVariableW(pathEnvironmentVariable, oldPath.data(), oldPath.size()))
76         return;
77
78     // And add the QuickTime dll.
79     wstring newPath;
80     newPath.append(qtPath);
81     newPath.append(L";");
82     newPath.append(oldPath.data(), oldPath.size());
83     ::SetEnvironmentVariableW(pathEnvironmentVariable, newPath.data());
84 }
85
86 static LONG WINAPI exceptionFilter(EXCEPTION_POINTERS*)
87 {
88     fputs("#CRASHED\n", stderr);
89     fflush(stderr);
90     return EXCEPTION_CONTINUE_SEARCH;
91 }
92
93 void TestController::notifyDone()
94 {
95 }
96
97 void TestController::platformInitialize()
98 {
99     ::SetUnhandledExceptionFilter(exceptionFilter);
100
101     _setmode(1, _O_BINARY);
102     _setmode(2, _O_BINARY);
103
104     // Add the QuickTime dll directory to PATH or QT 7.6 will fail to initialize on systems
105     // linked with older versions of qtmlclientlib.dll.
106     addQTDirToPATH();
107 }
108
109 void TestController::initializeInjectedBundlePath()
110 {
111     CFStringRef exeContainerPath = CFURLCopyFileSystemPath(CFURLCreateCopyDeletingLastPathComponent(0, CFBundleCopyExecutableURL(CFBundleGetMainBundle())), kCFURLWindowsPathStyle);
112     CFMutableStringRef bundlePath = CFStringCreateMutableCopy(0, 0, exeContainerPath);
113     CFStringAppendCString(bundlePath, injectedBundleDLL, kCFStringEncodingWindowsLatin1);
114     m_injectedBundlePath.adopt(WKStringCreateWithCFString(bundlePath));
115 }
116
117 void TestController::initializeTestPluginDirectory()
118 {
119     RetainPtr<CFURLRef> bundleURL(AdoptCF, CFBundleCopyExecutableURL(CFBundleGetMainBundle()));
120     RetainPtr<CFURLRef> bundleDirectoryURL(AdoptCF, CFURLCreateCopyDeletingLastPathComponent(0, bundleURL.get()));
121     RetainPtr<CFStringRef> testPluginDirectoryNameString(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(testPluginDirectoryName), wcslen(testPluginDirectoryName)));
122     RetainPtr<CFURLRef> testPluginDirectoryURL(AdoptCF, CFURLCreateCopyAppendingPathComponent(0, bundleDirectoryURL.get(), testPluginDirectoryNameString.get(), true));
123     RetainPtr<CFStringRef> testPluginDirectoryPath(AdoptCF, CFURLCopyFileSystemPath(testPluginDirectoryURL.get(), kCFURLWindowsPathStyle));
124     m_testPluginDirectory.adopt(WKStringCreateWithCFString(testPluginDirectoryPath.get()));
125 }
126
127 void TestController::platformRunUntil(bool& done, double timeout)
128 {
129     DWORD end = ::GetTickCount() + timeout * 1000;
130     while (!done) {
131         DWORD now = ::GetTickCount();
132         if (now > end)
133             return;
134
135         DWORD result = ::MsgWaitForMultipleObjectsEx(0, 0, end - now, QS_ALLINPUT, 0);
136         if (result == WAIT_TIMEOUT)
137             return;
138
139         ASSERT(result == WAIT_OBJECT_0);
140         // There are messages in the queue. Process them.
141         MSG msg;
142         while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) {
143             ::TranslateMessage(&msg);
144             ::DispatchMessageW(&msg);
145         }
146     }
147 }
148
149 void TestController::platformInitializeContext()
150 {
151     // FIXME: Make DRT pass with Windows native controls. <http://webkit.org/b/25592>
152     WKContextSetShouldPaintNativeControls(m_context.get(), false);
153 }
154
155 void TestController::runModal(PlatformWebView*)
156 {
157     // FIXME: Need to implement this to test showModalDialog.
158 }
159
160 const char* TestController::platformLibraryPathForTesting()
161 {
162     return 0;
163 }
164
165 } // namespace WTR