[Win] Remove -DUCHAR_TYPE=wchar_t stopgap and learn to live with char16_t.
[WebKit-https.git] / Source / WebKit / UIProcess / Launcher / win / ProcessLauncherWin.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2017 Sony Interactive Entertainment Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "ProcessLauncher.h"
29
30 #include "Connection.h"
31 #include <WTF/RunLoop.h>
32 #include <shlwapi.h>
33 #include <wtf/text/StringBuilder.h>
34
35 namespace WebKit {
36
37 static LPCWSTR processName(ProcessLauncher::ProcessType processType)
38 {
39     switch (processType) {
40     case ProcessLauncher::ProcessType::Web:
41         return L"WebKitWebProcess.exe";
42     case ProcessLauncher::ProcessType::Network:
43         return L"WebKitNetworkProcess.exe";
44     }
45     return L"WebKitWebProcess.exe";
46 }
47
48 void ProcessLauncher::launchProcess()
49 {
50     // First, create the server and client identifiers.
51     HANDLE serverIdentifier, clientIdentifier;
52     if (!IPC::Connection::createServerAndClientIdentifiers(serverIdentifier, clientIdentifier)) {
53         // FIXME: What should we do here?
54         ASSERT_NOT_REACHED();
55     }
56
57     // Ensure that the child process inherits the client identifier.
58     ::SetHandleInformation(clientIdentifier, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
59
60     // To get the full file path to WebKit2WebProcess.exe, we fild the location of WebKit2.dll,
61     // remove the last path component.
62     HMODULE webKitModule = ::GetModuleHandle(L"WebKit2.dll");
63     ASSERT(webKitModule);
64     if (!webKitModule)
65         return;
66
67     WCHAR pathStr[MAX_PATH];
68     if (!::GetModuleFileName(webKitModule, pathStr, WTF_ARRAY_LENGTH(pathStr)))
69         return;
70
71     ::PathRemoveFileSpec(pathStr);
72     if (!::PathAppend(pathStr, processName(m_launchOptions.processType)))
73         return;
74
75     StringBuilder commandLineBuilder;
76     commandLineBuilder.append("\"");
77     commandLineBuilder.append(String(pathStr));
78     commandLineBuilder.append("\"");
79     commandLineBuilder.append(" -type ");
80     commandLineBuilder.append(String::number(static_cast<int>(m_launchOptions.processType)));
81     commandLineBuilder.append(" -processIdentifier ");
82     commandLineBuilder.append(String::number(m_launchOptions.processIdentifier.toUInt64()));
83     commandLineBuilder.append(" -clientIdentifier ");
84     commandLineBuilder.append(String::number(reinterpret_cast<uintptr_t>(clientIdentifier)));
85     commandLineBuilder.append('\0');
86
87     auto commandLine = commandLineBuilder.toString().wideCharacters();
88
89     STARTUPINFO startupInfo { };
90     startupInfo.cb = sizeof(startupInfo);
91     startupInfo.dwFlags = STARTF_USESHOWWINDOW;
92     startupInfo.wShowWindow = SW_HIDE;
93     PROCESS_INFORMATION processInformation { };
94     BOOL result = ::CreateProcess(0, commandLine.data(), 0, 0, true, 0, 0, 0, &startupInfo, &processInformation);
95
96     // We can now close the client identifier handle.
97     ::CloseHandle(clientIdentifier);
98
99     if (!result) {
100         // FIXME: What should we do here?
101         DWORD error = ::GetLastError();
102         ASSERT_NOT_REACHED();
103     }
104
105     // Don't leak the thread handle.
106     ::CloseHandle(processInformation.hThread);
107
108     // We've finished launching the process, message back to the run loop.
109     RefPtr<ProcessLauncher> protectedThis(this);
110     m_hProcess = processInformation.hProcess;
111     WTF::ProcessID pid = processInformation.dwProcessId;
112
113     RunLoop::main().dispatch([protectedThis, pid, serverIdentifier] {
114         protectedThis->didFinishLaunchingProcess(pid, serverIdentifier);
115     });
116 }
117
118 void ProcessLauncher::terminateProcess()
119 {
120     if (!m_hProcess.isValid())
121         return;
122
123     ::TerminateProcess(m_hProcess.get(), 0);
124 }
125
126 void ProcessLauncher::platformInvalidate()
127 {
128     m_hProcess.clear();
129 }
130
131 } // namespace WebKit