1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
22 * Adam Lock <adamlock@eircom.net>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 #include "nsPluginHostWnd.h"
41 #include "nsURLDataCallback.h"
45 #define NS_4XPLUGIN_CALLBACK(_type, _name) _type (__stdcall * _name)
47 typedef NS_4XPLUGIN_CALLBACK(NPError
, NP_GETENTRYPOINTS
) (NPPluginFuncs
* pCallbacks
);
48 typedef NS_4XPLUGIN_CALLBACK(NPError
, NP_PLUGININIT
) (const NPNetscapeFuncs
* pCallbacks
);
49 typedef NS_4XPLUGIN_CALLBACK(NPError
, NP_PLUGINSHUTDOWN
) (void);
51 const kArraySizeIncrement
= 10;
53 nsSimpleArray
<nsPluginHostWnd::LoadedPluginInfo
*> nsPluginHostWnd::m_LoadedPlugins
;
55 nsPluginHostWnd::nsPluginHostWnd() :
56 m_bPluginIsAlive(false),
57 m_bCreatePluginFromStreamData(false),
58 m_bPluginIsWindowless(false),
59 m_bPluginIsTransparent(false),
60 m_pLoadedPlugin(NULL
),
66 InitPluginCallbacks();
67 memset(&m_NPPFuncs
, 0, sizeof(m_NPPFuncs
));
70 nsPluginHostWnd::~nsPluginHostWnd()
74 LRESULT
nsPluginHostWnd::OnCreate(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
76 SetWindowLong(GWL_STYLE
, GetWindowLong(GWL_STYLE
) | WS_CLIPCHILDREN
);
78 // Load a list of plugins
80 PLUGINS_FROM_IE
| PLUGINS_FROM_NS4X
|
81 PLUGINS_FROM_FIREFOX
| PLUGINS_FROM_MOZILLA
);
84 if (m_bstrContentType
.Length() == 0 &&
85 m_bstrSource
.Length() != 0)
88 // Do a late instantiation of the plugin based on the content type of
90 m_bCreatePluginFromStreamData
= true;
91 hr
= OpenURLStream(OLE2T(m_bstrSource
), NULL
, NULL
, 0);
95 // Create a plugin based upon the specified content type property
97 hr
= LoadPluginByContentType(OLE2T(m_bstrContentType
));
100 hr
= CreatePluginInstance();
101 if (m_bstrSource
.Length())
103 OpenURLStream(OLE2T(m_bstrSource
), NULL
, NULL
, 0);
108 return SUCCEEDED(hr
) ? 0 : -1;
111 LRESULT
nsPluginHostWnd::OnDestroy(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
113 DestroyPluginInstance();
119 LRESULT
nsPluginHostWnd::OnSize(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
121 SizeToFitPluginInstance();
125 LRESULT
nsPluginHostWnd::OnPaint(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& bHandled
)
128 HDC hdc
= BeginPaint(&ps
);
133 if (m_bPluginIsWindowless
&& m_NPPFuncs
.event
)
135 if (this->m_bPluginIsTransparent
)
139 for (int i
= rc
.left
; i
< rc
.right
; i
+= inc
)
141 const COLORREF c1
= RGB(255, 120, 120);
142 const COLORREF c2
= RGB(120, 120, 255);
144 HBRUSH hbr
= CreateSolidBrush(x
% 2 ? c1
: c2
);
146 rcStrip
.right
= i
+ inc
;
147 FillRect(hdc
, &rcStrip
, hbr
);
154 FillRect(hdc
, &rc
, (HBRUSH
) GetStockObject(GRAY_BRUSH
));
157 m_NPWindow
.type
= NPWindowTypeDrawable
;
158 m_NPWindow
.window
= hdc
;
161 m_NPWindow
.width
= rc
.right
- rc
.left
;
162 m_NPWindow
.height
= rc
.bottom
- rc
.top
;
163 m_NPWindow
.clipRect
.left
= 0;
164 m_NPWindow
.clipRect
.top
= 0;
165 m_NPWindow
.clipRect
.right
= m_NPWindow
.width
;
166 m_NPWindow
.clipRect
.bottom
= m_NPWindow
.height
;
168 if (m_NPPFuncs
.setwindow
)
170 NPError npres
= m_NPPFuncs
.setwindow(&m_NPP
, &m_NPWindow
);
174 paintRect
.left
= rc
.left
;
175 paintRect
.top
= rc
.top
;
176 paintRect
.right
= rc
.right
;
177 paintRect
.bottom
= rc
.bottom
;
180 evt
.event
= WM_PAINT
;
182 evt
.lParam
= (LPARAM
) &paintRect
;
183 m_NPPFuncs
.event(&m_NPP
, &evt
);
187 FillRect(hdc
, &rc
, (HBRUSH
) GetStockObject(GRAY_BRUSH
));
195 LRESULT
nsPluginHostWnd::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& /*bHandled*/)
197 if (m_bPluginIsWindowless
&& m_NPPFuncs
.event
)
203 m_NPPFuncs
.event(&m_NPP
, &evt
);
208 LRESULT
nsPluginHostWnd::OnLButtonDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& /*bHandled*/)
210 if (m_bPluginIsWindowless
&& m_NPPFuncs
.event
)
216 m_NPPFuncs
.event(&m_NPP
, &evt
);
221 LRESULT
nsPluginHostWnd::OnLButtonUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& /*bHandled*/)
223 if (m_bPluginIsWindowless
&& m_NPPFuncs
.event
)
229 m_NPPFuncs
.event(&m_NPP
, &evt
);
235 ///////////////////////////////////////////////////////////////////////////////
237 NPNetscapeFuncs
nsPluginHostWnd::g_NPNFuncs
;
239 HRESULT
nsPluginHostWnd::InitPluginCallbacks()
241 static BOOL gCallbacksSet
= FALSE
;
247 gCallbacksSet
= TRUE
;
249 memset(&g_NPNFuncs
, 0, sizeof(g_NPNFuncs
));
250 g_NPNFuncs
.size
= sizeof(g_NPNFuncs
);
251 g_NPNFuncs
.version
= (NP_VERSION_MAJOR
<< 8) + NP_VERSION_MINOR
;
253 g_NPNFuncs
.geturl
= NewNPN_GetURLProc(NPN_GetURL
);
254 g_NPNFuncs
.posturl
= NewNPN_PostURLProc(NPN_PostURL
);
255 g_NPNFuncs
.requestread
= NewNPN_RequestReadProc(NPN_RequestRead
);
256 g_NPNFuncs
.newstream
= NewNPN_NewStreamProc(NPN_NewStream
);
257 g_NPNFuncs
.write
= NewNPN_WriteProc(NPN_Write
);
258 g_NPNFuncs
.destroystream
= NewNPN_DestroyStreamProc(NPN_DestroyStream
);
259 g_NPNFuncs
.status
= NewNPN_StatusProc(NPN_Status
);
260 g_NPNFuncs
.uagent
= NewNPN_UserAgentProc(NPN_UserAgent
);
261 g_NPNFuncs
.memalloc
= NewNPN_MemAllocProc(NPN_MemAlloc
);
262 g_NPNFuncs
.memfree
= NewNPN_MemFreeProc(NPN_MemFree
);
263 g_NPNFuncs
.memflush
= NewNPN_MemFlushProc(NPN_MemFlush
);
264 g_NPNFuncs
.reloadplugins
= NewNPN_ReloadPluginsProc(NPN_ReloadPlugins
);
265 g_NPNFuncs
.getJavaEnv
= NewNPN_GetJavaEnvProc(NPN_GetJavaEnv
);
266 g_NPNFuncs
.getJavaPeer
= NewNPN_GetJavaPeerProc(NPN_GetJavaPeer
);
267 g_NPNFuncs
.geturlnotify
= NewNPN_GetURLNotifyProc(NPN_GetURLNotify
);
268 g_NPNFuncs
.posturlnotify
= NewNPN_PostURLNotifyProc(NPN_PostURLNotify
);
269 g_NPNFuncs
.getvalue
= NewNPN_GetValueProc(NPN_GetValue
);
270 g_NPNFuncs
.setvalue
= NewNPN_SetValueProc(NPN_SetValue
);
271 g_NPNFuncs
.invalidaterect
= NewNPN_InvalidateRectProc(NPN_InvalidateRect
);
272 g_NPNFuncs
.invalidateregion
= NewNPN_InvalidateRegionProc(NPN_InvalidateRegion
);
273 g_NPNFuncs
.forceredraw
= NewNPN_ForceRedrawProc(NPN_ForceRedraw
);
278 HRESULT
nsPluginHostWnd::GetWebBrowserApp(IWebBrowserApp
**pBrowser
)
280 // Override this method if there is a way to get this iface
290 void nsPluginHostWnd::SetPluginWindowless(bool bWindowless
)
292 m_bPluginIsWindowless
= bWindowless
;
295 void nsPluginHostWnd::SetPluginTransparent(bool bTransparent
)
297 m_bPluginIsTransparent
= bTransparent
;
300 HRESULT
nsPluginHostWnd::GetBaseURL(TCHAR
**ppszBaseURL
)
302 ATLASSERT(ppszBaseURL
);
305 CComPtr
<IWebBrowserApp
> cpWebBrowser
;
306 GetWebBrowserApp(&cpWebBrowser
);
314 cpWebBrowser
->get_LocationURL(&bstrURL
);
316 DWORD cbBaseURL
= (bstrURL
.Length() + 1) * sizeof(WCHAR
);
317 DWORD cbBaseURLUsed
= 0;
318 WCHAR
*pszBaseURL
= (WCHAR
*) malloc(cbBaseURL
);
319 ATLASSERT(pszBaseURL
);
330 *ppszBaseURL
= _tcsdup(W2T(pszBaseURL
));
336 HRESULT
nsPluginHostWnd::LoadPluginByContentType(const TCHAR
*pszContentType
)
338 TCHAR
* pszPluginPath
= NULL
;
340 // Set the content type
342 SetPluginContentType(T2OLE(pszContentType
));
344 // Search for a plugin that can handle this content
345 HRESULT hr
= FindPluginPathByContentType(pszContentType
, &pszPluginPath
);
348 // Try the default 'catch-all' plugin
349 hr
= FindPluginPathByContentType(_T("*"), &pszPluginPath
);
356 hr
= LoadPlugin(pszPluginPath
);
364 HRESULT
nsPluginHostWnd::GetPluginContentType(BSTR
*pVal
)
370 *pVal
= m_bstrContentType
.Copy();
374 HRESULT
nsPluginHostWnd::SetPluginContentType(BSTR newVal
)
376 // Security. Copying the source BSTR this way ensures that embedded NULL
377 // characters do not end up in the destination BSTR. SysAllocString will
378 // create a copy truncated at the first NULL char.
379 m_bstrContentType
.Empty();
380 m_bstrContentType
.Attach(SysAllocString(newVal
));
384 HRESULT
nsPluginHostWnd::GetPluginSource(BSTR
*pVal
)
390 *pVal
= m_bstrSource
.Copy();
394 HRESULT
nsPluginHostWnd::SetPluginSource(BSTR newVal
)
396 // Security. Copying the source BSTR this way ensures that embedded NULL
397 // characters do not end up in the destination BSTR. SysAllocString will
398 // create a copy truncated at the first NULL char.
399 m_bstrSource
.Empty();
400 m_bstrSource
.Attach(SysAllocString(newVal
));
404 HRESULT
nsPluginHostWnd::GetPluginsPage(BSTR
*pVal
)
410 *pVal
= m_bstrPluginsPage
.Copy();
414 HRESULT
nsPluginHostWnd::SetPluginsPage(BSTR newVal
)
416 // Security. Copying the source BSTR this way ensures that embedded NULL
417 // characters do not end up in the destination BSTR. SysAllocString will
418 // create a copy truncated at the first NULL char.
419 m_bstrPluginsPage
.Empty();
420 m_bstrPluginsPage
.Attach(SysAllocString(newVal
));
424 HRESULT
nsPluginHostWnd::ReadPluginsFromGeckoAppPath(const TCHAR
*szAppName
)
426 const TCHAR szGeneralKey
[] = _T("SOFTWARE\\Mozilla\\");
427 const size_t nGeneralKeyLen
= sizeof(szGeneralKey
) / sizeof(TCHAR
);
429 const size_t nMainKeyLen
= nGeneralKeyLen
+ _tcslen(szAppName
);
431 TCHAR
*szMainKey
= new TCHAR
[nMainKeyLen
];
432 memset(szMainKey
, 0, nMainKeyLen
* sizeof(TCHAR
));
433 _tcscpy(szMainKey
, szGeneralKey
);
434 _tcscat(szMainKey
, szAppName
);
437 if (keyGeneral
.Open(HKEY_LOCAL_MACHINE
, szMainKey
, KEY_READ
) == ERROR_SUCCESS
)
439 // First find the Current Version
441 const size_t nVersionLen
= sizeof(szVersion
) / sizeof(szVersion
[0]);
442 memset(szVersion
, 0, sizeof(szVersion
));
444 DWORD nVersion
= nVersionLen
;
445 keyGeneral
.QueryStringValue(_T("CurrentVersion"), szVersion
, &nVersion
);
448 TCHAR
*szBracket
= _tcschr(szVersion
, TCHAR('('));
451 while (szBracket
>= szVersion
)
453 if (*szBracket
== TCHAR(' ') || *szBracket
== TCHAR('('))
455 *szBracket
= TCHAR('\0');
462 nVersion
= _tcslen(szVersion
);
464 TCHAR
*szKey
= new TCHAR
[nMainKeyLen
+ nVersion
+ 32];
465 _tcscpy(szKey
, szMainKey
);
466 _tcscat(szKey
, _T(" "));
467 _tcscat(szKey
, szVersion
);
468 _tcscat(szKey
, _T("\\Extensions"));
471 if (key
.Open(HKEY_LOCAL_MACHINE
, szKey
, KEY_READ
) == ERROR_SUCCESS
)
473 TCHAR szPluginsDir
[_MAX_PATH
];
474 memset(szPluginsDir
, 0, sizeof(szPluginsDir
));
475 DWORD nPluginsDir
= sizeof(szPluginsDir
) / sizeof(szPluginsDir
[0]);
476 key
.QueryStringValue(_T("Plugins"), szPluginsDir
, &nPluginsDir
);
479 CreatePluginListFrom(szPluginsDir
);
489 HRESULT
nsPluginHostWnd::CreatePluginList(unsigned long ulFlags
)
491 // This function trawls through the plugin directory and builds a list
492 // of plugins and what MIME types each plugin handles.
497 if (ulFlags
& PLUGINS_FROM_FIREFOX
)
499 ReadPluginsFromGeckoAppPath(_T("Mozilla Firefox"));
503 if (ulFlags
& PLUGINS_FROM_MOZILLA
)
505 ReadPluginsFromGeckoAppPath(_T("Mozilla"));
508 // Try and obtain a path to the plugins in Netscape 4.x
509 if (ulFlags
& PLUGINS_FROM_NS4X
)
511 TCHAR szPluginsDir
[_MAX_PATH
];
512 memset(szPluginsDir
, 0, sizeof(szPluginsDir
));
515 const TCHAR
*kNav4xKey
= _T("Software\\Netscape\\Netscape Navigator");
516 if (keyNS
.Open(HKEY_LOCAL_MACHINE
, kNav4xKey
, KEY_READ
) == ERROR_SUCCESS
)
519 DWORD nVersion
= sizeof(szVersion
) / sizeof(szVersion
[0]);
520 keyNS
.QueryValue(szVersion
, _T("CurrentVersion"), &nVersion
);
523 if (keyVersion
.Open(keyNS
, szVersion
, KEY_READ
) == ERROR_SUCCESS
)
526 if (keyMain
.Open(keyVersion
, _T("Main"), KEY_READ
) == ERROR_SUCCESS
)
528 DWORD nPluginsDir
= sizeof(szPluginsDir
) / sizeof(szPluginsDir
[0]);
529 keyMain
.QueryValue(szPluginsDir
, _T("Plugins Directory"), &nPluginsDir
);
538 CreatePluginListFrom(szPluginsDir
);
542 // Try and obtain a path to the plugins in Internet Explorer
543 if (ulFlags
& PLUGINS_FROM_IE
)
545 TCHAR szPluginsDir
[_MAX_PATH
];
546 memset(szPluginsDir
, 0, sizeof(szPluginsDir
));
549 const TCHAR
*kIEKey
= _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE");
550 if (keyIE
.Open(HKEY_LOCAL_MACHINE
, kIEKey
, KEY_READ
) == ERROR_SUCCESS
)
552 DWORD nPluginsDir
= sizeof(szPluginsDir
) / sizeof(szPluginsDir
[0]);
553 keyIE
.QueryValue(szPluginsDir
, _T("Path"), &nPluginsDir
);
555 TCHAR
*szSemiColon
= _tcschr(szPluginsDir
, _TCHAR(';'));
558 *szSemiColon
= _TCHAR('\0');
561 ULONG nLen
= _tcslen(szPluginsDir
);
562 if (nLen
> 0 && szPluginsDir
[nLen
- 1] == _TCHAR('\\'))
564 szPluginsDir
[nLen
- 1] = _TCHAR('\0');
566 _tcscat(szPluginsDir
, _T("\\Plugins"));
572 CreatePluginListFrom(szPluginsDir
);
579 HRESULT
nsPluginHostWnd::CreatePluginListFrom(const TCHAR
*szPluginsDir
)
582 WIN32_FIND_DATA finddata
;
584 // Change to the plugin directory
585 TCHAR szCurrentDir
[MAX_PATH
+ 1];
586 GetCurrentDirectory(sizeof(szCurrentDir
) / sizeof(szCurrentDir
[0]), szCurrentDir
);
587 SetCurrentDirectory(szPluginsDir
);
589 // Search for files matching the "np*dll" pattern
590 hFind
= FindFirstFile(_T("np*dll"), &finddata
);
591 if (hFind
!= INVALID_HANDLE_VALUE
)
594 PluginInfo
*pInfo
= new PluginInfo
;
598 SetCurrentDirectory(szCurrentDir
);
599 return E_OUTOFMEMORY
;
601 if (SUCCEEDED(GetPluginInfo(finddata
.cFileName
, pInfo
)))
603 pInfo
->szPluginName
= _tcsdup(finddata
.cFileName
);
604 pInfo
->szPluginPath
= _tcsdup(szPluginsDir
);
605 m_Plugins
.AppendElement(pInfo
);
609 ATLTRACE(_T("Error: Cannot plugin info for \"%s\".\n"), finddata
.cFileName
);
612 } while (FindNextFile(hFind
, &finddata
));
616 SetCurrentDirectory(szCurrentDir
);
622 HRESULT
nsPluginHostWnd::CleanupPluginList()
624 // Free the memory used by the plugin info list
625 for (unsigned long i
= 0; i
< m_Plugins
.Count(); i
++)
627 PluginInfo
*pI
= m_Plugins
[i
];
629 free(pI
->szMIMEType
);
630 if (pI
->szPluginName
)
631 free(pI
->szPluginName
);
632 if (pI
->szPluginPath
)
633 free(pI
->szPluginPath
);
641 HRESULT
nsPluginHostWnd::GetPluginInfo(const TCHAR
*pszPluginPath
, PluginInfo
*pInfo
)
643 // Get the version info from the plugin
645 DWORD nVersionInfoSize
;
647 void *pVersionInfo
= NULL
;
648 nVersionInfoSize
= GetFileVersionInfoSize((TCHAR
*)pszPluginPath
, &nZero
);
649 if (nVersionInfoSize
)
651 pVersionInfo
= malloc(nVersionInfoSize
);
655 return E_OUTOFMEMORY
;
658 GetFileVersionInfo((TCHAR
*)pszPluginPath
, NULL
, nVersionInfoSize
, pVersionInfo
);
660 // Extract the MIMEType info
661 TCHAR
*szValue
= NULL
;
662 UINT nValueLength
= 0;
663 if (!VerQueryValue(pVersionInfo
,
664 _T("\\StringFileInfo\\040904E4\\MIMEType"),
665 (void **) &szValue
, &nValueLength
))
672 pInfo
->szMIMEType
= _tcsdup(szValue
);
680 HRESULT
nsPluginHostWnd::FindPluginPathByContentType(const TCHAR
*pszContentType
, TCHAR
**ppszPluginPath
)
682 *ppszPluginPath
= NULL
;
684 if (pszContentType
== NULL
)
689 // Search the list of plugins for one that will handle the content type
690 TCHAR szPluginPath
[_MAX_PATH
+ 1];
691 unsigned long nContentType
= _tcslen(pszContentType
);
692 for (unsigned long i
= 0; i
< m_Plugins
.Count(); i
++)
694 PluginInfo
*pI
= m_Plugins
[i
];
697 TCHAR
*pszMIMEType
= pI
->szMIMEType
;
699 if (_tcsncmp(pszContentType
, pszMIMEType
, nContentType
) == 0)
702 _tmakepath(szPluginPath
, NULL
,
703 pI
->szPluginPath
, pI
->szPluginName
, NULL
);
704 *ppszPluginPath
= _tcsdup(szPluginPath
);
707 // Check the other types the plugin handles
708 pszMIMEType
= _tcschr(pszMIMEType
, TCHAR('|'));
713 } while (pszMIMEType
&& *pszMIMEType
);
720 HRESULT
nsPluginHostWnd::LoadPlugin(const TCHAR
*szPluginPath
)
722 ATLASSERT(m_pLoadedPlugin
== NULL
);
728 // TODO critical section
730 // Test if the plugin has already been loaded
731 for (unsigned long i
= 0; i
< m_LoadedPlugins
.Count(); i
++)
733 if (_tcscmp(m_LoadedPlugins
[i
]->szFullPath
, szPluginPath
) == 0)
735 m_pLoadedPlugin
= m_LoadedPlugins
[i
];
736 memcpy(&m_NPPFuncs
, &m_pLoadedPlugin
->NPPFuncs
, sizeof(m_NPPFuncs
));
737 m_pLoadedPlugin
->nRefCount
++;
742 // Plugin library is being loaded for the first time so initialise it
743 // and store an entry in the loaded plugins array.
745 HINSTANCE hInstance
= LoadLibrary(szPluginPath
);
751 m_pLoadedPlugin
= new LoadedPluginInfo
;
752 if (!m_pLoadedPlugin
)
754 ATLASSERT(m_pLoadedPlugin
);
755 return E_OUTOFMEMORY
;
758 // Get the plugin function entry points
759 NP_GETENTRYPOINTS pfnGetEntryPoints
=
760 (NP_GETENTRYPOINTS
) GetProcAddress(hInstance
, "NP_GetEntryPoints");
761 if (pfnGetEntryPoints
)
763 pfnGetEntryPoints(&m_NPPFuncs
);
766 // Tell the plugin to initialize itself
767 NP_PLUGININIT pfnInitialize
= (NP_PLUGININIT
)
768 GetProcAddress(hInstance
, "NP_Initialize");
771 pfnInitialize
= (NP_PLUGININIT
)
772 GetProcAddress(hInstance
, "NP_PluginInit");
776 pfnInitialize(&g_NPNFuncs
);
779 // Create a new entry for the plugin
780 m_pLoadedPlugin
->szFullPath
= _tcsdup(szPluginPath
);
781 m_pLoadedPlugin
->nRefCount
= 1;
782 m_pLoadedPlugin
->hInstance
= hInstance
;
783 memcpy(&m_pLoadedPlugin
->NPPFuncs
, &m_NPPFuncs
, sizeof(m_NPPFuncs
));
785 // Add it to the array
786 m_LoadedPlugins
.AppendElement(m_pLoadedPlugin
);
791 HRESULT
nsPluginHostWnd::UnloadPlugin()
793 if (!m_pLoadedPlugin
)
798 // TODO critical section
800 ATLASSERT(m_pLoadedPlugin
->nRefCount
> 0);
801 if (m_pLoadedPlugin
->nRefCount
== 1)
803 NP_PLUGINSHUTDOWN pfnShutdown
= (NP_PLUGINSHUTDOWN
)
805 m_pLoadedPlugin
->hInstance
,
811 FreeLibrary(m_pLoadedPlugin
->hInstance
);
813 // Delete the entry from the array
814 m_LoadedPlugins
.RemoveElement(m_pLoadedPlugin
);
815 free(m_pLoadedPlugin
->szFullPath
);
816 delete m_pLoadedPlugin
;
820 m_pLoadedPlugin
->nRefCount
--;
823 m_pLoadedPlugin
= NULL
;
829 HRESULT
nsPluginHostWnd::AddPluginParam(const char *szName
, const char *szValue
)
833 if (!szName
|| !szValue
)
838 // Skip params that already there
839 for (unsigned long i
= 0; i
< m_nArgs
; i
++)
841 if (stricmp(szName
, m_pszArgNames
[i
]) == 0)
850 ATLASSERT(!m_pszArgValues
);
851 m_nArgsMax
= kArraySizeIncrement
;
852 m_pszArgNames
= (char **) malloc(sizeof(char *) * m_nArgsMax
);
853 m_pszArgValues
= (char **) malloc(sizeof(char *) * m_nArgsMax
);
855 else if (m_nArgs
== m_nArgsMax
)
857 m_nArgsMax
+= kArraySizeIncrement
;
858 m_pszArgNames
= (char **) realloc(m_pszArgNames
, sizeof(char *) * m_nArgsMax
);
859 m_pszArgValues
= (char **) realloc(m_pszArgValues
, sizeof(char *) * m_nArgsMax
);
861 if (!m_pszArgNames
|| !m_pszArgValues
)
863 return E_OUTOFMEMORY
;
866 m_pszArgNames
[m_nArgs
] = strdup(szName
);
867 m_pszArgValues
[m_nArgs
] = strdup(szValue
);
875 HRESULT
nsPluginHostWnd::CreatePluginInstance()
881 char *szContentType
= strdup(OLE2A(m_bstrContentType
.m_str
));
883 // Create a child window to house the plugin
886 // m_wndPlugin.Create(m_hWnd, rc, NULL, WS_CHILD | WS_VISIBLE);
888 // m_NPWindow.window = (void *) m_wndPlugin.m_hWnd;
889 m_NPWindow
.window
= (void *) m_hWnd
;
890 m_NPWindow
.type
= NPWindowTypeWindow
;
894 // Create the arguments to be fed into the plugin
895 if (m_bstrSource
.m_str
)
897 AddPluginParam("SRC", OLE2A(m_bstrSource
.m_str
));
899 if (m_bstrContentType
.m_str
)
901 AddPluginParam("TYPE", OLE2A(m_bstrContentType
.m_str
));
903 if (m_bstrPluginsPage
.m_str
)
905 AddPluginParam("PLUGINSPAGE", OLE2A(m_bstrPluginsPage
.m_str
));
908 sprintf(szTmp
, "%d", (int) (rc
.right
- rc
.left
));
909 AddPluginParam("WIDTH", szTmp
);
910 sprintf(szTmp
, "%d", (int) (rc
.bottom
- rc
.top
));
911 AddPluginParam("HEIGHT", szTmp
);
913 NPSavedData
*pSaved
= NULL
;
915 // Create the plugin instance
916 NPError npres
= m_NPPFuncs
.newp(szContentType
, &m_NPP
, NP_EMBED
,
917 (short) m_nArgs
, m_pszArgNames
, m_pszArgValues
, pSaved
);
919 if (npres
!= NPERR_NO_ERROR
)
925 m_bPluginIsAlive
= true;
927 SizeToFitPluginInstance();
932 HRESULT
nsPluginHostWnd::DestroyPluginInstance()
934 if (!m_bPluginIsAlive
)
939 // Destroy the plugin
940 if (m_NPPFuncs
.destroy
)
942 NPSavedData
*pSavedData
= NULL
;
943 NPError npres
= m_NPPFuncs
.destroy(&m_NPP
, &pSavedData
);
945 // TODO could store saved data instead of just deleting it.
946 if (pSavedData
&& pSavedData
->buf
)
948 NPN_MemFree(pSavedData
->buf
);
952 // Destroy the arguments
955 for (unsigned long i
= 0; i
< m_nArgs
; i
++)
957 free(m_pszArgNames
[i
]);
960 m_pszArgNames
= NULL
;
964 for (unsigned long i
= 0; i
< m_nArgs
; i
++)
966 free(m_pszArgValues
[i
]);
968 free(m_pszArgValues
);
969 m_pszArgValues
= NULL
;
972 //m_wndPlugin.DestroyWindow();
974 m_bPluginIsAlive
= false;
979 HRESULT
nsPluginHostWnd::SizeToFitPluginInstance()
981 if (!m_bPluginIsAlive
)
986 // Resize the plugin to fit the window
991 //m_wndPlugin.SetWindowPos(HWND_TOP,
992 // rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
997 m_NPWindow
.width
= rc
.right
- rc
.left
;
998 m_NPWindow
.height
= rc
.bottom
- rc
.top
;
999 m_NPWindow
.clipRect
.left
= 0;
1000 m_NPWindow
.clipRect
.top
= 0;
1001 m_NPWindow
.clipRect
.right
= m_NPWindow
.width
;
1002 m_NPWindow
.clipRect
.bottom
= m_NPWindow
.height
;
1004 if (m_NPPFuncs
.setwindow
)
1006 NPError npres
= m_NPPFuncs
.setwindow(&m_NPP
, &m_NPWindow
);
1012 HRESULT
nsPluginHostWnd::OpenURLStream(const TCHAR
*szURL
, void *pNotifyData
, const void *pPostData
, unsigned long nPostDataLength
)
1014 nsURLDataCallback::OpenURL(this, szURL
, pNotifyData
, pPostData
, nPostDataLength
);