简体   繁体   English

NPAPI 插件,从 web 页面中删除Child 导致 Firefox4 和 Chrome 崩溃

[英]NPAPI plugin, removeChild from web page crashes Firefox4 & Chrome

I have a html page that opens a new window and loads a basic NPAPI written plugin that I opens a Wide Save dialog and then calls NPN_GetURL with a java-script function to close the window. I have a html page that opens a new window and loads a basic NPAPI written plugin that I opens a Wide Save dialog and then calls NPN_GetURL with a java-script function to close the window. Each time Firefox crashes and Chrome displays the plugin crashed.每次 Firefox 崩溃并且 Chrome 显示插件崩溃。 I'm not sure if the problem is HTML & JS or the plugin.我不确定问题是 HTML & JS 还是插件。 I didn't find a whole lot when googling for other similar issues.在搜索其他类似问题时,我没有找到很多。 Below is my page that loads the plugin and the javascript function "removePlugin" is called by the plugin.下面是我加载插件的页面,插件调用了 javascript function “removePlugin”。 As for firefox no problems in 3.6 only in version 4至于 firefox 在 3.6 中没有问题,仅在版本 4

----Start - - 开始

<html>
 <script language="javascript">
  function removePlugin()
   {
   var plgn = document.getElementById("myplugin1");
   document.getElementById("div1").removeChild(plgn);
   setTimeout('doClose()', 2000);
   }
 function doClose()
  {
  window.close();
  }
 </script>
 <body >
  <div id="div1">
   <embed type="application/x-My-Plugin" id="myplugin1"></embed>
  </div>
 </body>
</html>

----End - - 结尾

----Start of Plugin code ----插件代码的开始

#include "npapi.h"

//Prottype
LRESULT CALLBACK    PluginWindowProc  (HWND,UINT,WPARAM,LPARAM);

//Define
#define MY_MESSAGE      WM_USER + 1000

//Global
const char*     gInstanceLookupString = "instance";
WNDPROC         fDefaultWindowProc;

//Function:    NPP_SetWindow
NPError NPP_SetWindow(NPP       instance,
                      NPWindow *window)
{
    fDefaultWindowProc = (WNDPROC)SetWindowLongPtr((HWND)window->window,
                                                   GWL_WNDPROC,
                                                   (LONG)PluginWindowProc);
    SetProp(window->window,
            gInstanceLookupString,
            (HANDLE)instance);
    SendMessage(window->window,
                MY_MESSAGE,
                0,
                0);
    return NPERR_NO_ERROR;
}

//PluginWindowProc
LRESULT CALLBACK PluginWindowProc(HWND      hWnd,
                                  UINT      Msg,
                                  WPARAM    wParam,
                                  LPARAM    lParam)
{
OPENFILENAMEW       ofn;                                                                    //Fix.3a
WCHAR               szFile[512];                                //File name that appears in the Save Dialog box //Fix.3a
NPP                 instance;

    switch(Msg)
        {
        case MY_MESSAGE:
            instance = (NPP)GetProp(hWnd,
                                    gInstanceLookupString);
            //SAVE----------------------------------------
            memset(&ofn,
                   0x00,
                   sizeof(OPENFILENAMEW));

            memset(szFile,
                   0x00,
                   sizeof(szFile));
            _snwprintf_s(szFile,                                
                        _countof(szFile),
                        _countof(szFile),
                        L"Test.Txt");
            ofn.lStructSize = sizeof(OPENFILENAME);            
            ofn.lpstrFile = szFile;
            ofn.nMaxFile = _countof(szFile);
            ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;

            GetSaveFileNameW(&ofn);


            //CLOSE---------------------------------------
            NPN_GetURL(instance,
                       "javascript:removePlugin(0);",
                       "_self");

            //--------------------------------------------
            break;
        default:
            CallWindowProc(fDefaultWindowProc,
                           hWnd,
                           Msg,
                           wParam,
                           lParam);
            break;
        }
    return 0;
    }

//Function:    NPP_Destroy
NPError NPP_Destroy(NPP instance,NPSavedData **save){return NPERR_NO_ERROR;}

//Function:    NPP_DestroyStream
NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError   reason){return NPERR_NO_ERROR;}

//Function:    NPP_HandleEvent
int16 NPP_HandleEvent(NPP instance,void* event){return 0;}

//Function:    NPP_Initialize
NPError NPP_Initialize(void){return NPERR_NO_ERROR;}

//Function:    NPP_New
NPError NPP_New(NPMIMEType pluginType,NPP instance, uint16 mode, int16 argc,char* argn[], char * argv[],NPSavedData* saved){return (NPERR_NO_ERROR);}

//Function: NPP_NewStream
NPError NPP_NewStream(NPP instance,NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype){ return NPERR_NO_ERROR;}

//Function: NPP_Print
void NPP_Print(NPP instance, NPPrint *printInfo){}

//Function: NPP_Shutdown
void NPP_Shutdown(void){}

//Function: NPP_StreamAsFile
void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname){}

//Function: NPP_URLNotify
void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData){}

//Function: NPP_Write
int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)        {return 0;}

//Function: NPP_WriteReady
int32 NPP_WriteReady(NPP instance, NPStream *stream){return 0;}

----End of Plugin code ----插件代码结束

It is really difficult to tell for sure what is going on, but I can tell you that the approach you're taking has several other problems.很难确定发生了什么,但我可以告诉你,你所采取的方法还有其他几个问题。 The first and foremost is that you must not ever block the main browser thread, which is what happens when you open a dialog in the main browser.首先也是最重要的一点是,您绝不能阻塞主浏览器线程,当您在主浏览器中打开对话框时会发生这种情况。 Now, I realize that you might be okay (and some might even be under the delusion that others would be okay) with dialog locking up (no, not just preventing input, but actually locking up) the browser while your dialog is open, but in the cases of all current browsers that run the plugin out of process and wouldn't completely lock up while the dialog box is open the browser is liable to at the very least ask the user if they want to kill the plugin, if not just kill your plugin outright like Safari 5.1 would.现在,我意识到您可能会没事(有些人甚至会错觉其他人会没事),但在对话框打开时对话框锁定(不,不仅阻止输入,而且实际上锁定)浏览器,但是在所有当前浏览器在进程外运行插件并且在对话框打开时不会完全锁定的情况下,浏览器至少会询问用户是否要杀死插件,如果不仅仅是像 Safari 5.1 那样彻底杀死你的插件。

What you really need to do if you're going to use a dialog is start another thread and put the dialog call on that, then call back into the browser (on the main thread. use NPN_PluginThreadAsyncCall) when you're done.如果要使用对话框,您真正需要做的是启动另一个线程并将对话框调用放在该线程上,然后在完成后回调到浏览器(在主线程上。使用 NPN_PluginThreadAsyncCall)。

As to the crash log, from what it is saying you've somehow borked the browser's handle to the plugin, because it's crashing when it tries to call SetWindow on your plugin.至于崩溃日志,从它所说的内容来看,您以某种方式将浏览器的句柄插入插件,因为当它尝试在您的插件上调用 SetWindow 时它会崩溃。 You might want to consider tossing this barebones attempt at NPAPI and use something like FireBreath , where the tricky NPAPI bits have already been solved for you.您可能需要考虑在 NPAPI 上放弃这个准系统尝试并使用类似FireBreath的东西,其中已经为您解决了棘手的 NPAPI 位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM