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