1/*
2 * Copyright (C) 2008 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. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#if USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
27
28#import "NetscapePluginHostProxy.h"
29
30#import <mach/mach.h>
31#import <wtf/StdLibExtras.h>
32
33#import "HostedNetscapePluginStream.h"
34#import "NetscapePluginHostManager.h"
35#import "NetscapePluginInstanceProxy.h"
36#import "WebFrameInternal.h"
37#import "WebHostedNetscapePluginView.h"
38#import "WebKitSystemInterface.h"
39#import <JavaScriptCore/IdentifierInlines.h>
40#import <WebCore/Frame.h>
41#import <WebCore/IdentifierRep.h>
42#import <WebCore/ScriptController.h>
43
44extern "C" {
45#import "WebKitPluginHost.h"
46#import "WebKitPluginClientServer.h"
47}
48
49using namespace JSC;
50using namespace WebCore;
51
52@interface WebPlaceholderModalWindow : NSWindow
53@end
54
55@implementation WebPlaceholderModalWindow
56// Prevent NSApp from calling requestUserAttention: when the window is shown
57// modally, even if the app is inactive. See 6823049.
58- (BOOL)_wantsUserAttention
59{
60    return NO;
61}
62@end
63
64namespace WebKit {
65
66class PluginDestroyDeferrer {
67public:
68    PluginDestroyDeferrer(NetscapePluginInstanceProxy* proxy)
69        : m_proxy(proxy)
70    {
71        m_proxy->willCallPluginFunction();
72    }
73
74    ~PluginDestroyDeferrer()
75    {
76        bool stopped;
77        m_proxy->didCallPluginFunction(stopped);
78    }
79
80private:
81    RefPtr<NetscapePluginInstanceProxy> m_proxy;
82};
83
84typedef HashMap<mach_port_t, NetscapePluginHostProxy*> PluginProxyMap;
85static PluginProxyMap& pluginProxyMap()
86{
87    DEPRECATED_DEFINE_STATIC_LOCAL(PluginProxyMap, pluginProxyMap, ());
88
89    return pluginProxyMap;
90}
91
92unsigned NetscapePluginHostProxy::s_processingRequests;
93
94NetscapePluginHostProxy::NetscapePluginHostProxy(mach_port_t clientPort, mach_port_t pluginHostPort, const ProcessSerialNumber& pluginHostPSN, bool shouldCacheMissingPropertiesAndMethods)
95    : m_clientPort(clientPort)
96    , m_portSet(MACH_PORT_NULL)
97    , m_pluginHostPort(pluginHostPort)
98    , m_isModal(false)
99    , m_menuBarIsVisible(true)
100    , m_fullscreenWindowIsShowing(false)
101    , m_pluginHostPSN(pluginHostPSN)
102    , m_shouldCacheMissingPropertiesAndMethods(shouldCacheMissingPropertiesAndMethods)
103{
104    pluginProxyMap().add(m_clientPort, this);
105
106    // FIXME: We should use libdispatch for this.
107    CFMachPortContext context = { 0, this, 0, 0, 0 };
108    m_deadNameNotificationPort = adoptCF(CFMachPortCreate(0, deadNameNotificationCallback, &context, 0));
109
110    mach_port_t previous;
111    mach_port_request_notification(mach_task_self(), pluginHostPort, MACH_NOTIFY_DEAD_NAME, 0,
112                                   CFMachPortGetPort(m_deadNameNotificationPort.get()), MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous);
113    ASSERT(previous == MACH_PORT_NULL);
114
115    RetainPtr<CFRunLoopSourceRef> deathPortSource = adoptCF(CFMachPortCreateRunLoopSource(0, m_deadNameNotificationPort.get(), 0));
116
117    CFRunLoopAddSource(CFRunLoopGetCurrent(), deathPortSource.get(), kCFRunLoopDefaultMode);
118
119    m_clientPortSource = adoptCF(WKCreateMIGServerSource((mig_subsystem_t)&WKWebKitPluginClient_subsystem, m_clientPort));
120    CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), kCFRunLoopDefaultMode);
121    CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSEventTrackingRunLoopMode);
122}
123
124NetscapePluginHostProxy::~NetscapePluginHostProxy()
125{
126    pluginProxyMap().remove(m_clientPort);
127
128    // Free the port set
129    if (m_portSet) {
130        mach_port_extract_member(mach_task_self(), m_clientPort, m_portSet);
131        mach_port_extract_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
132        mach_port_destroy(mach_task_self(), m_portSet);
133    }
134
135    ASSERT(m_clientPortSource);
136    CFRunLoopSourceInvalidate(m_clientPortSource.get());
137    m_clientPortSource = 0;
138}
139
140void NetscapePluginHostProxy::pluginHostDied()
141{
142    PluginInstanceMap instances;
143    m_instances.swap(instances);
144
145    PluginInstanceMap::const_iterator end = instances.end();
146    for (PluginInstanceMap::const_iterator it = instances.begin(); it != end; ++it)
147        it->value->pluginHostDied();
148
149    NetscapePluginHostManager::shared().pluginHostDied(this);
150
151    // The plug-in crashed while its menu bar was hidden. Make sure to show it.
152    if (!m_menuBarIsVisible)
153        setMenuBarVisible(true);
154
155    // The plug-in crashed while it had a modal dialog up.
156    if (m_isModal)
157        endModal();
158
159    delete this;
160}
161
162void NetscapePluginHostProxy::addPluginInstance(NetscapePluginInstanceProxy* instance)
163{
164    ASSERT(!m_instances.contains(instance->pluginID()));
165
166    m_instances.set(instance->pluginID(), instance);
167}
168
169void NetscapePluginHostProxy::removePluginInstance(NetscapePluginInstanceProxy* instance)
170{
171    ASSERT(m_instances.get(instance->pluginID()) == instance);
172
173    m_instances.remove(instance->pluginID());
174}
175
176NetscapePluginInstanceProxy* NetscapePluginHostProxy::pluginInstance(uint32_t pluginID)
177{
178    NetscapePluginInstanceProxy* result = m_instances.get(pluginID);
179    ASSERT(!result || result->hostProxy() == this);
180    return result;
181}
182
183void NetscapePluginHostProxy::deadNameNotificationCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
184{
185    ASSERT(msg);
186    ASSERT(static_cast<mach_msg_header_t*>(msg)->msgh_id == MACH_NOTIFY_DEAD_NAME);
187
188    static_cast<NetscapePluginHostProxy*>(info)->pluginHostDied();
189}
190
191void NetscapePluginHostProxy::setMenuBarVisible(bool visible)
192{
193    m_menuBarIsVisible = visible;
194
195    [NSMenu setMenuBarVisible:visible];
196}
197
198void NetscapePluginHostProxy::didEnterFullscreen() const
199{
200    makePluginHostProcessFrontProcess();
201}
202
203void NetscapePluginHostProxy::didExitFullscreen() const
204{
205    // If the plug-in host is the current application then we should bring ourselves to the front when it exits full-screen mode.
206    if (isPluginHostProcessFrontProcess())
207        makeCurrentProcessFrontProcess();
208}
209
210void NetscapePluginHostProxy::setFullscreenWindowIsShowing(bool isShowing)
211{
212    if (m_fullscreenWindowIsShowing == isShowing)
213        return;
214
215    m_fullscreenWindowIsShowing = isShowing;
216    if (m_fullscreenWindowIsShowing)
217        didEnterFullscreen();
218    else
219        didExitFullscreen();
220
221}
222
223void NetscapePluginHostProxy::applicationDidBecomeActive()
224{
225    makePluginHostProcessFrontProcess();
226}
227
228void NetscapePluginHostProxy::beginModal()
229{
230    ASSERT(!m_placeholderWindow);
231    ASSERT(!m_activationObserver);
232
233    m_placeholderWindow = adoptNS([[WebPlaceholderModalWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]);
234
235    m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:NSApp queue:nil
236                                                                         usingBlock:^(NSNotification *){ applicationDidBecomeActive(); }];
237
238    // We need to be able to get the setModal(false) call from the plug-in host.
239    CFRunLoopAddSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
240
241    [NSApp runModalForWindow:m_placeholderWindow.get()];
242
243    [m_placeholderWindow.get() orderOut:nil];
244    m_placeholderWindow = 0;
245}
246
247void NetscapePluginHostProxy::endModal()
248{
249    ASSERT(m_placeholderWindow);
250    ASSERT(m_activationObserver);
251
252    [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()];
253    m_activationObserver = nil;
254
255    CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_clientPortSource.get(), (CFStringRef)NSModalPanelRunLoopMode);
256
257    [NSApp stopModal];
258
259    makeCurrentProcessFrontProcess();
260}
261
262
263void NetscapePluginHostProxy::setModal(bool modal)
264{
265    if (modal == m_isModal)
266        return;
267
268    m_isModal = modal;
269
270    if (m_isModal)
271        beginModal();
272    else
273        endModal();
274}
275
276bool NetscapePluginHostProxy::processRequests()
277{
278    s_processingRequests++;
279
280   if (!m_portSet) {
281        mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &m_portSet);
282        mach_port_insert_member(mach_task_self(), m_clientPort, m_portSet);
283        mach_port_insert_member(mach_task_self(), CFMachPortGetPort(m_deadNameNotificationPort.get()), m_portSet);
284    }
285
286    char buffer[4096];
287
288    mach_msg_header_t* msg = reinterpret_cast<mach_msg_header_t*>(buffer);
289
290    kern_return_t kr = mach_msg(msg, MACH_RCV_MSG, 0, sizeof(buffer), m_portSet, 0, MACH_PORT_NULL);
291
292    if (kr != KERN_SUCCESS) {
293        LOG_ERROR("Could not receive mach message, error %x", kr);
294        s_processingRequests--;
295        return false;
296    }
297
298    if (msg->msgh_local_port == m_clientPort) {
299        __ReplyUnion__WKWebKitPluginClient_subsystem reply;
300        mach_msg_header_t* replyHeader = reinterpret_cast<mach_msg_header_t*>(&reply);
301
302        if (WebKitPluginClient_server(msg, replyHeader) && replyHeader->msgh_remote_port != MACH_PORT_NULL) {
303            kr = mach_msg(replyHeader, MACH_SEND_MSG, replyHeader->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
304
305            if (kr != KERN_SUCCESS) {
306                LOG_ERROR("Could not send mach message, error %x", kr);
307                s_processingRequests--;
308                return false;
309            }
310        }
311
312        s_processingRequests--;
313        return true;
314    }
315
316    if (msg->msgh_local_port == CFMachPortGetPort(m_deadNameNotificationPort.get())) {
317        ASSERT(msg->msgh_id == MACH_NOTIFY_DEAD_NAME);
318        pluginHostDied();
319        s_processingRequests--;
320        return false;
321    }
322
323    ASSERT_NOT_REACHED();
324    s_processingRequests--;
325    return false;
326}
327
328void NetscapePluginHostProxy::makeCurrentProcessFrontProcess()
329{
330#pragma clang diagnostic push
331#pragma clang diagnostic ignored "-Wdeprecated-declarations"
332    ProcessSerialNumber psn;
333    GetCurrentProcess(&psn);
334    SetFrontProcess(&psn);
335#pragma clang diagnostic pop
336}
337
338void NetscapePluginHostProxy::makePluginHostProcessFrontProcess() const
339{
340#pragma clang diagnostic push
341#pragma clang diagnostic ignored "-Wdeprecated-declarations"
342    SetFrontProcess(&m_pluginHostPSN);
343#pragma clang diagnostic pop
344}
345
346bool NetscapePluginHostProxy::isPluginHostProcessFrontProcess() const
347{
348#pragma clang diagnostic push
349#pragma clang diagnostic ignored "-Wdeprecated-declarations"
350    ProcessSerialNumber frontProcess;
351    GetFrontProcess(&frontProcess);
352
353    Boolean isSameProcess = 0;
354    SameProcess(&frontProcess, &m_pluginHostPSN, &isSameProcess);
355#pragma clang diagnostic pop
356
357    return isSameProcess;
358}
359
360} // namespace WebKit
361
362using namespace WebKit;
363
364// Helper class for deallocating data
365class DataDeallocator {
366public:
367    DataDeallocator(data_t data, mach_msg_type_number_t dataLength)
368        : m_data(reinterpret_cast<vm_address_t>(data))
369        , m_dataLength(dataLength)
370    {
371    }
372
373    ~DataDeallocator()
374    {
375        if (!m_data)
376            return;
377
378        vm_deallocate(mach_task_self(), m_data, m_dataLength);
379    }
380
381private:
382    vm_address_t m_data;
383    vm_size_t m_dataLength;
384};
385
386// MiG callbacks
387kern_return_t WKPCStatusText(mach_port_t clientPort, uint32_t pluginID, data_t text, mach_msg_type_number_t textCnt)
388{
389    DataDeallocator deallocator(text, textCnt);
390
391    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
392    if (!hostProxy)
393        return KERN_FAILURE;
394
395    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
396    if (!instanceProxy)
397        return KERN_FAILURE;
398
399    instanceProxy->status(text);
400    return KERN_SUCCESS;
401}
402
403kern_return_t WKPCLoadURL(mach_port_t clientPort, uint32_t pluginID, data_t url, mach_msg_type_number_t urlLength, data_t target, mach_msg_type_number_t targetLength,
404                          data_t postData, mach_msg_type_number_t postDataLength, uint32_t flags,
405                          uint16_t* outResult, uint32_t* outStreamID)
406{
407    DataDeallocator urlDeallocator(url, urlLength);
408    DataDeallocator targetDeallocator(target, targetLength);
409    DataDeallocator postDataDeallocator(postData, postDataLength);
410
411    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
412    if (!hostProxy)
413        return KERN_FAILURE;
414
415    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
416    if (!instanceProxy)
417        return KERN_FAILURE;
418
419    uint32_t streamID = 0;
420    NPError result = instanceProxy->loadURL(url, target, postData, postDataLength, static_cast<LoadURLFlags>(flags), streamID);
421
422    *outResult = result;
423    *outStreamID = streamID;
424    return KERN_SUCCESS;
425}
426
427kern_return_t WKPCCancelLoadURL(mach_port_t clientPort, uint32_t pluginID, uint32_t streamID, int16_t reason)
428{
429    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
430    if (!hostProxy)
431        return KERN_FAILURE;
432
433    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
434    if (!instanceProxy)
435        return KERN_FAILURE;
436
437    if (!instanceProxy->cancelStreamLoad(streamID, reason))
438        return KERN_FAILURE;
439
440    return KERN_SUCCESS;
441}
442
443kern_return_t WKPCInvalidateRect(mach_port_t clientPort, uint32_t pluginID, double x, double y, double width, double height)
444{
445    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
446    if (!hostProxy)
447        return KERN_SUCCESS;
448
449    if (!hostProxy->isProcessingRequests()) {
450        if (NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID))
451            instanceProxy->invalidateRect(x, y, width, height);
452        return KERN_SUCCESS;
453    }
454
455    // Defer the work
456    CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
457        if (NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort)) {
458            if (NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID))
459                instanceProxy->invalidateRect(x, y, width, height);
460        }
461    });
462
463    return KERN_SUCCESS;
464}
465
466kern_return_t WKPCGetScriptableNPObjectReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID)
467{
468    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
469    if (!hostProxy)
470        return KERN_FAILURE;
471
472    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
473    if (!instanceProxy)
474        return KERN_FAILURE;
475
476    instanceProxy->setCurrentReply(requestID, std::make_unique<NetscapePluginInstanceProxy::GetScriptableNPObjectReply>(objectID));
477    return KERN_SUCCESS;
478}
479
480kern_return_t WKPCBooleanReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, boolean_t result)
481{
482    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
483    if (!hostProxy)
484        return KERN_FAILURE;
485
486    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
487    if (!instanceProxy)
488        return KERN_FAILURE;
489
490    instanceProxy->setCurrentReply(requestID, std::make_unique<NetscapePluginInstanceProxy::BooleanReply>(result));
491    return KERN_SUCCESS;
492}
493
494kern_return_t WKPCBooleanAndDataReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, boolean_t returnValue, data_t resultData, mach_msg_type_number_t resultLength)
495{
496    DataDeallocator deallocator(resultData, resultLength);
497
498    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
499    if (!hostProxy)
500        return KERN_FAILURE;
501
502    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
503    if (!instanceProxy)
504        return KERN_FAILURE;
505
506    RetainPtr<CFDataRef> result = adoptCF(CFDataCreate(0, reinterpret_cast<UInt8*>(resultData), resultLength));
507    instanceProxy->setCurrentReply(requestID, std::make_unique<NetscapePluginInstanceProxy::BooleanAndDataReply>(returnValue, result));
508
509    return KERN_SUCCESS;
510}
511
512kern_return_t WKPCInstantiatePluginReply(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, kern_return_t result, uint32_t renderContextID, uint32_t rendererType)
513{
514    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
515    if (!hostProxy)
516        return KERN_FAILURE;
517
518    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
519    if (!instanceProxy)
520        return KERN_FAILURE;
521
522    instanceProxy->setCurrentReply(requestID, std::make_unique<NetscapePluginInstanceProxy::InstantiatePluginReply>(result, renderContextID, static_cast<RendererType>(rendererType)));
523    return KERN_SUCCESS;
524}
525
526kern_return_t WKPCGetWindowNPObject(mach_port_t clientPort, uint32_t pluginID, uint32_t* outObjectID)
527{
528    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
529    if (!hostProxy)
530        return KERN_FAILURE;
531
532    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
533    if (!instanceProxy)
534        return KERN_FAILURE;
535
536    uint32_t objectID;
537    if (!instanceProxy->getWindowNPObject(objectID))
538        return KERN_FAILURE;
539
540    *outObjectID = objectID;
541    return KERN_SUCCESS;
542}
543
544kern_return_t WKPCGetPluginElementNPObject(mach_port_t clientPort, uint32_t pluginID, uint32_t* outObjectID)
545{
546    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
547    if (!hostProxy)
548        return KERN_FAILURE;
549
550    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
551    if (!instanceProxy)
552        return KERN_FAILURE;
553
554    uint32_t objectID;
555    if (!instanceProxy->getPluginElementNPObject(objectID))
556        return KERN_FAILURE;
557
558    *outObjectID = objectID;
559    return KERN_SUCCESS;
560}
561
562kern_return_t WKPCForgetBrowserObject(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID)
563{
564    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
565    if (!hostProxy)
566        return KERN_FAILURE;
567
568    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
569    if (!instanceProxy)
570        return KERN_FAILURE;
571
572    return instanceProxy->forgetBrowserObjectID(objectID) ? KERN_SUCCESS : KERN_FAILURE;
573}
574
575kern_return_t WKPCEvaluate(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, data_t scriptData, mach_msg_type_number_t scriptLength, boolean_t allowPopups)
576{
577    DataDeallocator deallocator(scriptData, scriptLength);
578
579    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
580    if (!hostProxy)
581        return KERN_FAILURE;
582
583    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
584    if (!instanceProxy)
585        return KERN_FAILURE;
586
587    PluginDestroyDeferrer deferrer(instanceProxy);
588
589    String script = scriptLength ? String::fromUTF8WithLatin1Fallback(scriptData, scriptLength) : emptyString();
590
591    data_t resultData = 0;
592    mach_msg_type_number_t resultLength = 0;
593    boolean_t returnValue = instanceProxy->evaluate(objectID, script, resultData, resultLength, allowPopups);
594
595    hostProxy = instanceProxy->hostProxy();
596    if (!hostProxy)
597        return KERN_FAILURE;
598
599    _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
600    if (resultData)
601        mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
602
603    return KERN_SUCCESS;
604}
605
606kern_return_t WKPCGetStringIdentifier(mach_port_t clientPort, data_t name, mach_msg_type_number_t nameCnt, uint64_t* identifier)
607{
608    DataDeallocator deallocator(name, nameCnt);
609
610    COMPILE_ASSERT(sizeof(*identifier) == sizeof(IdentifierRep*), identifier_sizes);
611
612    *identifier = reinterpret_cast<uint64_t>(IdentifierRep::get(name));
613    return KERN_SUCCESS;
614}
615
616kern_return_t WKPCGetIntIdentifier(mach_port_t clientPort, int32_t value, uint64_t* identifier)
617{
618    COMPILE_ASSERT(sizeof(*identifier) == sizeof(NPIdentifier), identifier_sizes);
619
620    *identifier = reinterpret_cast<uint64_t>(IdentifierRep::get(value));
621    return KERN_SUCCESS;
622}
623
624static Identifier identifierFromIdentifierRep(IdentifierRep* identifier)
625{
626    ASSERT(IdentifierRep::isValid(identifier));
627    ASSERT(identifier->isString());
628
629    const char* str = identifier->string();
630    return Identifier(&JSDOMWindow::commonVM(), String::fromUTF8WithLatin1Fallback(str, strlen(str)));
631}
632
633kern_return_t WKPCInvoke(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier,
634                         data_t argumentsData, mach_msg_type_number_t argumentsLength)
635{
636    DataDeallocator deallocator(argumentsData, argumentsLength);
637
638    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
639    if (!hostProxy)
640        return KERN_FAILURE;
641
642    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
643    if (!instanceProxy)
644        return KERN_FAILURE;
645
646    PluginDestroyDeferrer deferrer(instanceProxy);
647
648    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
649    if (!IdentifierRep::isValid(identifier))
650        return KERN_FAILURE;
651
652    Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
653
654    data_t resultData = 0;
655    mach_msg_type_number_t resultLength = 0;
656    boolean_t returnValue = instanceProxy->invoke(objectID, methodNameIdentifier, argumentsData, argumentsLength, resultData, resultLength);
657
658    hostProxy = instanceProxy->hostProxy();
659    if (!hostProxy)
660        return KERN_FAILURE;
661
662    _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
663    if (resultData)
664        mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
665
666    return KERN_SUCCESS;
667}
668
669kern_return_t WKPCInvokeDefault(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID,
670                                data_t argumentsData, mach_msg_type_number_t argumentsLength)
671{
672    DataDeallocator deallocator(argumentsData, argumentsLength);
673
674    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
675    if (!hostProxy)
676        return KERN_FAILURE;
677
678    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
679    if (!instanceProxy)
680        return KERN_FAILURE;
681
682    PluginDestroyDeferrer deferrer(instanceProxy);
683
684    data_t resultData = 0;
685    mach_msg_type_number_t resultLength = 0;
686    boolean_t returnValue = instanceProxy->invokeDefault(objectID, argumentsData, argumentsLength, resultData, resultLength);
687
688    hostProxy = instanceProxy->hostProxy();
689    if (!hostProxy)
690        return KERN_FAILURE;
691
692    _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
693    if (resultData)
694        mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
695
696    return KERN_SUCCESS;
697}
698
699kern_return_t WKPCConstruct(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID,
700                            data_t argumentsData, mach_msg_type_number_t argumentsLength,
701                            boolean_t* returnValue, data_t* resultData, mach_msg_type_number_t* resultLength)
702{
703    DataDeallocator deallocator(argumentsData, argumentsLength);
704
705    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
706    if (!hostProxy)
707        return KERN_FAILURE;
708
709    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
710    if (!instanceProxy)
711        return KERN_FAILURE;
712
713    PluginDestroyDeferrer deferrer(instanceProxy);
714
715    *returnValue = instanceProxy->construct(objectID, argumentsData, argumentsLength, *resultData, *resultLength);
716
717    return KERN_SUCCESS;
718}
719
720kern_return_t WKPCGetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
721{
722    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
723    if (!hostProxy)
724        return KERN_FAILURE;
725
726    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
727    if (!instanceProxy)
728        return KERN_FAILURE;
729
730    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
731    if (!IdentifierRep::isValid(identifier))
732        return KERN_FAILURE;
733
734    PluginDestroyDeferrer deferrer(instanceProxy);
735
736    data_t resultData = 0;
737    mach_msg_type_number_t resultLength = 0;
738    boolean_t returnValue;
739
740    if (identifier->isString()) {
741        Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
742        returnValue = instanceProxy->getProperty(objectID, propertyNameIdentifier, resultData, resultLength);
743    } else
744        returnValue = instanceProxy->setProperty(objectID, identifier->number(), resultData, resultLength);
745
746    hostProxy = instanceProxy->hostProxy();
747    if (!hostProxy)
748        return KERN_FAILURE;
749
750    _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
751    if (resultData)
752        mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
753
754    return KERN_SUCCESS;
755}
756
757kern_return_t WKPCSetProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier, data_t valueData, mach_msg_type_number_t valueLength)
758{
759    DataDeallocator deallocator(valueData, valueLength);
760
761    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
762    if (!hostProxy)
763        return KERN_FAILURE;
764
765    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
766    if (!instanceProxy)
767        return KERN_FAILURE;
768
769    PluginDestroyDeferrer deferrer(instanceProxy);
770
771    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
772    if (!IdentifierRep::isValid(identifier))
773        return KERN_FAILURE;
774
775    bool result;
776    if (identifier->isString()) {
777        Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
778        result = instanceProxy->setProperty(objectID, propertyNameIdentifier, valueData, valueLength);
779    } else
780        result = instanceProxy->setProperty(objectID, identifier->number(), valueData, valueLength);
781
782    hostProxy = instanceProxy->hostProxy();
783    if (!hostProxy)
784        return KERN_FAILURE;
785
786    _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
787
788    return KERN_SUCCESS;
789}
790
791kern_return_t WKPCRemoveProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
792{
793    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
794    if (!hostProxy)
795        return KERN_FAILURE;
796
797    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
798    if (!instanceProxy)
799        return KERN_FAILURE;
800
801    PluginDestroyDeferrer deferrer(instanceProxy);
802
803    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
804    if (!IdentifierRep::isValid(identifier))
805        return KERN_FAILURE;
806
807    bool result;
808    if (identifier->isString()) {
809        Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
810        result = instanceProxy->removeProperty(objectID, propertyNameIdentifier);
811    } else
812        result = instanceProxy->removeProperty(objectID, identifier->number());
813
814    hostProxy = instanceProxy->hostProxy();
815    if (!hostProxy)
816        return KERN_FAILURE;
817
818    _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, result);
819
820    return KERN_SUCCESS;
821}
822
823kern_return_t WKPCHasProperty(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
824{
825    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
826    if (!hostProxy)
827        return KERN_FAILURE;
828
829    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
830    if (!instanceProxy)
831        return KERN_FAILURE;
832
833    PluginDestroyDeferrer deferrer(instanceProxy);
834
835    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
836    if (!IdentifierRep::isValid(identifier))
837        return KERN_FAILURE;
838
839    boolean_t returnValue;
840    if (identifier->isString()) {
841        Identifier propertyNameIdentifier = identifierFromIdentifierRep(identifier);
842        returnValue = instanceProxy->hasProperty(objectID, propertyNameIdentifier);
843    } else
844        returnValue = instanceProxy->hasProperty(objectID, identifier->number());
845
846    hostProxy = instanceProxy->hostProxy();
847    if (!hostProxy)
848        return KERN_FAILURE;
849
850    _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
851
852    return KERN_SUCCESS;
853}
854
855kern_return_t WKPCHasMethod(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID, uint64_t serverIdentifier)
856{
857    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
858    if (!hostProxy)
859        return KERN_FAILURE;
860
861    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
862    if (!instanceProxy)
863        return KERN_FAILURE;
864
865    PluginDestroyDeferrer deferrer(instanceProxy);
866
867    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
868    if (!IdentifierRep::isValid(identifier))
869        return KERN_FAILURE;
870
871    Identifier methodNameIdentifier = identifierFromIdentifierRep(identifier);
872    boolean_t returnValue = instanceProxy->hasMethod(objectID, methodNameIdentifier);
873
874    hostProxy = instanceProxy->hostProxy();
875    if (!hostProxy)
876        return KERN_FAILURE;
877
878    _WKPHBooleanReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue);
879
880    return KERN_SUCCESS;
881}
882
883kern_return_t WKPCIdentifierInfo(mach_port_t clientPort, uint64_t serverIdentifier, data_t* infoData, mach_msg_type_number_t* infoLength)
884{
885    IdentifierRep* identifier = reinterpret_cast<IdentifierRep*>(serverIdentifier);
886    if (!IdentifierRep::isValid(identifier))
887        return KERN_FAILURE;
888
889    id info;
890    if (identifier->isString()) {
891        const char* str = identifier->string();
892        info = [NSData dataWithBytesNoCopy:(void*)str length:strlen(str) freeWhenDone:NO];
893    } else
894        info = [NSNumber numberWithInt:identifier->number()];
895
896    NSData *data = [NSPropertyListSerialization dataWithPropertyList:info format:NSPropertyListBinaryFormat_v1_0 options:0 error:nullptr];
897    ASSERT(data);
898
899    *infoLength = data.length;
900    mig_allocate(reinterpret_cast<vm_address_t*>(infoData), *infoLength);
901
902    memcpy(*infoData, data.bytes, *infoLength);
903
904    return KERN_SUCCESS;
905}
906
907kern_return_t WKPCEnumerate(mach_port_t clientPort, uint32_t pluginID, uint32_t requestID, uint32_t objectID)
908{
909    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
910    if (!hostProxy)
911        return KERN_FAILURE;
912
913    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
914    if (!instanceProxy)
915        return KERN_FAILURE;
916
917    data_t resultData = 0;
918    mach_msg_type_number_t resultLength = 0;
919    boolean_t returnValue = instanceProxy->enumerate(objectID, resultData, resultLength);
920
921    hostProxy = instanceProxy->hostProxy();
922    if (!hostProxy)
923        return KERN_FAILURE;
924
925    _WKPHBooleanAndDataReply(hostProxy->port(), instanceProxy->pluginID(), requestID, returnValue, resultData, resultLength);
926
927    if (resultData)
928        mig_deallocate(reinterpret_cast<vm_address_t>(resultData), resultLength);
929
930    return KERN_SUCCESS;
931}
932
933kern_return_t WKPCSetMenuBarVisible(mach_port_t clientPort, boolean_t menuBarVisible)
934{
935    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
936    if (!hostProxy)
937        return KERN_FAILURE;
938
939    hostProxy->setMenuBarVisible(menuBarVisible);
940
941    return KERN_SUCCESS;
942}
943
944kern_return_t WKPCSetFullscreenWindowIsShowing(mach_port_t clientPort, boolean_t fullscreenWindowIsShowing)
945{
946    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
947    if (!hostProxy)
948        return KERN_FAILURE;
949
950    hostProxy->setFullscreenWindowIsShowing(fullscreenWindowIsShowing);
951
952    return KERN_SUCCESS;
953}
954
955kern_return_t WKPCSetModal(mach_port_t clientPort, boolean_t modal)
956{
957    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
958    if (!hostProxy)
959        return KERN_FAILURE;
960
961    if (!hostProxy->isProcessingRequests()) {
962        hostProxy->setModal(modal);
963        return KERN_SUCCESS;
964    }
965
966    // Defer the work
967    CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
968        if (NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort))
969            hostProxy->setModal(modal);
970    });
971
972    return KERN_SUCCESS;
973}
974
975kern_return_t WKPCGetCookies(mach_port_t clientPort, uint32_t pluginID,
976                             data_t urlData, mach_msg_type_number_t urlLength,
977                             boolean_t* returnValue, data_t* cookiesData, mach_msg_type_number_t* cookiesLength)
978{
979    *cookiesData = 0;
980    *cookiesLength = 0;
981
982    DataDeallocator deallocator(urlData, urlLength);
983
984    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
985    if (!hostProxy)
986        return KERN_FAILURE;
987
988    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
989    if (!instanceProxy)
990        return KERN_FAILURE;
991
992    *returnValue = instanceProxy->getCookies(urlData, urlLength, *cookiesData, *cookiesLength);
993
994    return KERN_SUCCESS;
995}
996
997kern_return_t WKPCGetProxy(mach_port_t clientPort, uint32_t pluginID,
998                           data_t urlData, mach_msg_type_number_t urlLength,
999                           boolean_t* returnValue, data_t* proxyData, mach_msg_type_number_t* proxyLength)
1000{
1001    *proxyData = 0;
1002    *proxyLength = 0;
1003
1004    DataDeallocator deallocator(urlData, urlLength);
1005
1006    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1007    if (!hostProxy)
1008        return KERN_FAILURE;
1009
1010    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1011    if (!instanceProxy)
1012        return KERN_FAILURE;
1013
1014    *returnValue = instanceProxy->getProxy(urlData, urlLength, *proxyData, *proxyLength);
1015
1016    return KERN_SUCCESS;
1017}
1018
1019kern_return_t WKPCSetCookies(mach_port_t clientPort, uint32_t pluginID,
1020                             data_t urlData, mach_msg_type_number_t urlLength,
1021                             data_t cookiesData, mach_msg_type_number_t cookiesLength,
1022                             boolean_t* returnValue)
1023{
1024    DataDeallocator urlDeallocator(urlData, urlLength);
1025    DataDeallocator cookiesDeallocator(cookiesData, cookiesLength);
1026
1027    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1028    if (!hostProxy)
1029        return KERN_FAILURE;
1030
1031    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1032    if (!instanceProxy)
1033        return KERN_FAILURE;
1034
1035    *returnValue = instanceProxy->setCookies(urlData, urlLength, cookiesData, cookiesLength);
1036    return KERN_SUCCESS;
1037}
1038
1039kern_return_t WKPCGetAuthenticationInfo(mach_port_t clientPort, uint32_t pluginID,
1040                                        data_t protocolData, mach_msg_type_number_t protocolLength,
1041                                        data_t hostData, mach_msg_type_number_t hostLength,
1042                                        uint32_t port,
1043                                        data_t schemeData, mach_msg_type_number_t schemeLength,
1044                                        data_t realmData, mach_msg_type_number_t realmLength,
1045                                        boolean_t* returnValue,
1046                                        data_t* usernameData, mach_msg_type_number_t *usernameLength,
1047                                        data_t* passwordData, mach_msg_type_number_t *passwordLength)
1048{
1049    DataDeallocator protocolDeallocator(protocolData, protocolLength);
1050    DataDeallocator hostDeallocator(hostData, hostLength);
1051    DataDeallocator schemeDeallocator(schemeData, schemeLength);
1052    DataDeallocator realmDeallocator(realmData, realmLength);
1053
1054    *usernameData = 0;
1055    *usernameLength = 0;
1056    *passwordData = 0;
1057    *passwordLength = 0;
1058
1059    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1060    if (!hostProxy)
1061        return KERN_FAILURE;
1062
1063    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1064    if (!instanceProxy)
1065        return KERN_FAILURE;
1066
1067    *returnValue = instanceProxy->getAuthenticationInfo(protocolData, hostData, port, schemeData, realmData, *usernameData, *usernameLength, *passwordData, *passwordLength);
1068
1069    return KERN_SUCCESS;
1070}
1071
1072kern_return_t WKPCConvertPoint(mach_port_t clientPort, uint32_t pluginID,
1073                               double sourceX, double sourceY, uint32_t sourceSpace,
1074                               uint32_t destSpace, boolean_t *returnValue, double *destX, double *destY)
1075{
1076    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1077    if (!hostProxy)
1078        return KERN_FAILURE;
1079
1080    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1081    if (!instanceProxy)
1082        return KERN_FAILURE;
1083
1084    *returnValue = instanceProxy->convertPoint(sourceX, sourceY, static_cast<NPCoordinateSpace>(sourceSpace),
1085                                               *destX, *destY, static_cast<NPCoordinateSpace>(destSpace));
1086    return KERN_SUCCESS;
1087}
1088
1089kern_return_t WKPCLayerHostingModeChanged(mach_port_t clientPort, uint32_t pluginID, boolean_t hostsLayersInWindowServer, uint32_t renderContextID)
1090{
1091    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1092    if (!hostProxy)
1093        return KERN_FAILURE;
1094
1095    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1096    if (!instanceProxy)
1097        return KERN_FAILURE;
1098
1099    instanceProxy->layerHostingModeChanged(hostsLayersInWindowServer, renderContextID);
1100    return KERN_SUCCESS;
1101}
1102
1103kern_return_t WKPCCheckIfAllowedToLoadURL(mach_port_t clientPort, uint32_t pluginID, data_t urlData, mach_msg_type_number_t urlLength,
1104                                          data_t targetData, mach_msg_type_number_t targetLength, uint32_t *checkID)
1105{
1106    DataDeallocator urlDeallocator(urlData, urlLength);
1107    DataDeallocator targetDeallocator(targetData, targetLength);
1108
1109    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1110    if (!hostProxy)
1111        return KERN_FAILURE;
1112
1113    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1114    if (!instanceProxy)
1115        return KERN_FAILURE;
1116
1117    *checkID = instanceProxy->checkIfAllowedToLoadURL(urlData, targetData);
1118    return KERN_SUCCESS;
1119}
1120
1121kern_return_t WKPCCancelCheckIfAllowedToLoadURL(mach_port_t clientPort, uint32_t pluginID, uint32_t checkID)
1122{
1123    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1124    if (!hostProxy)
1125        return KERN_FAILURE;
1126
1127    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1128    if (!instanceProxy)
1129        return KERN_FAILURE;
1130
1131    instanceProxy->cancelCheckIfAllowedToLoadURL(checkID);
1132    return KERN_SUCCESS;
1133}
1134
1135kern_return_t WKPCResolveURL(mach_port_t clientPort, uint32_t pluginID, data_t urlData, mach_msg_type_number_t urlLength,
1136                             data_t targetData, mach_msg_type_number_t targetLength,
1137                             data_t *resolvedURLData, mach_msg_type_number_t *resolvedURLLength)
1138{
1139    DataDeallocator urlDeallocator(urlData, urlLength);
1140    DataDeallocator targetDeallocator(targetData, targetLength);
1141
1142    *resolvedURLData = 0;
1143    *resolvedURLLength = 0;
1144
1145    NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort);
1146    if (!hostProxy)
1147        return KERN_FAILURE;
1148
1149    NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID);
1150    if (!instanceProxy)
1151        return KERN_FAILURE;
1152
1153    instanceProxy->resolveURL(urlData, targetData, *resolvedURLData, *resolvedURLLength);
1154    return KERN_SUCCESS;
1155}
1156
1157kern_return_t WKPCSetException(mach_port_t clientPort, data_t message, mach_msg_type_number_t messageCnt)
1158{
1159    DataDeallocator deallocator(message, messageCnt);
1160
1161    NetscapePluginInstanceProxy::setGlobalException(String::fromUTF8WithLatin1Fallback(message, messageCnt));
1162
1163    return KERN_SUCCESS;
1164}
1165
1166#endif // USE(PLUGIN_HOST_PROCESS) && ENABLE(NETSCAPE_PLUGIN_API)
1167