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