Threaded plugin sample code, not part of the build

This commit is contained in:
av%netscape.com 2002-03-06 03:55:03 +00:00
Родитель fa41a430d3
Коммит f071dac9bb
8 изменённых файлов: 1080 добавлений и 0 удалений

Просмотреть файл

@ -34,3 +34,128 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "action.h"
char * FormatAction(int aAction)
{
static char string[64] = {'\0'};
switch (aAction) {
case action_invalid:
strcpy(string, "invalid action");
break;
case action_npn_version:
strcpy(string, "npn_version");
break;
case action_npn_get_url_notify:
strcpy(string, "npn_get_url_notify");
break;
case action_npn_get_url:
strcpy(string, "npn_get_url");
break;
case action_npn_post_url_notify:
strcpy(string, "npn_post_url_notify");
break;
case action_npn_post_url:
strcpy(string, "npn_post_url");
break;
case action_npn_request_read:
strcpy(string, "npn_request_read");
break;
case action_npn_new_stream:
strcpy(string, "npn_new_stream");
break;
case action_npn_write:
strcpy(string, "npn_write");
break;
case action_npn_destroy_stream:
strcpy(string, "npn_destroy_stream");
break;
case action_npn_status:
strcpy(string, "npn_status");
break;
case action_npn_user_agent:
strcpy(string, "npn_user_agent");
break;
case action_npn_mem_alloc:
strcpy(string, "npn_mem_alloc");
break;
case action_npn_mem_free:
strcpy(string, "npn_mem_free");
break;
case action_npn_mem_flush:
strcpy(string, "npn_mem_flush");
break;
case action_npn_reload_plugins:
strcpy(string, "npn_reload_plugins");
break;
case action_npn_get_java_env:
strcpy(string, "npn_get_java_env");
break;
case action_npn_get_java_peer:
strcpy(string, "npn_get_java_peer");
break;
case action_npn_get_value:
strcpy(string, "npn_get_value");
break;
case action_npn_set_value:
strcpy(string, "npn_set_value");
break;
case action_npn_invalidate_rect:
strcpy(string, "npn_invalidate_rect");
break;
case action_npn_invalidate_region:
strcpy(string, "npn_invalidate_region");
break;
case action_npn_force_redraw:
strcpy(string, "npn_force_redraw");
break;
case action_npp_new:
strcpy(string, "npp_new");
break;
case action_npp_destroy:
strcpy(string, "npp_destroy");
break;
case action_npp_set_window:
strcpy(string, "npp_set_window");
break;
case action_npp_new_stream:
strcpy(string, "npp_new_stream");
break;
case action_npp_destroy_stream:
strcpy(string, "npp_destroy_stream");
break;
case action_npp_stream_as_file:
strcpy(string, "npp_stream_as_file");
break;
case action_npp_write_ready:
strcpy(string, "npp_write_ready");
break;
case action_npp_write:
strcpy(string, "npp_write");
break;
case action_npp_print:
strcpy(string, "npp_print");
break;
case action_npp_handle_event:
strcpy(string, "npp_handle_event");
break;
case action_npp_url_notify:
strcpy(string, "npp_url_notify");
break;
case action_npp_get_java_class:
strcpy(string, "npp_get_java_class");
break;
case action_npp_get_value:
strcpy(string, "npp_get_value");
break;
case action_npp_set_value:
strcpy(string, "npp_set_value");
break;
default:
strcpy(string, "Unknown action!");
break;
}
return string;
}

Просмотреть файл

@ -34,3 +34,18 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <windows.h>
#ifndef NTRACE
void __cdecl dbgOut(LPSTR format, ...) {
static char buf[1024];
va_list va;
va_start(va, format);
wvsprintf(buf, format, va);
va_end(va);
lstrcat(buf, "\n");
OutputDebugString(buf);
}
#endif // NDEBUG

Просмотреть файл

@ -34,3 +34,85 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "npapi.h"
#include "npupp.h"
#include "dbg.h"
NPNetscapeFuncs NPNFuncs;
NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* aPluginFuncs)
{
dbgOut1("wrapper: NP_GetEntryPoints");
if(aPluginFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if(aPluginFuncs->size < sizeof(NPPluginFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
aPluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
aPluginFuncs->newp = NPP_New;
aPluginFuncs->destroy = NPP_Destroy;
aPluginFuncs->setwindow = NPP_SetWindow;
aPluginFuncs->newstream = NPP_NewStream;
aPluginFuncs->destroystream = NPP_DestroyStream;
aPluginFuncs->asfile = NPP_StreamAsFile;
aPluginFuncs->writeready = NPP_WriteReady;
aPluginFuncs->write = NPP_Write;
aPluginFuncs->print = NPP_Print;
aPluginFuncs->event = NPP_HandleEvent;
aPluginFuncs->urlnotify = NPP_URLNotify;
aPluginFuncs->getvalue = NPP_GetValue;
aPluginFuncs->setvalue = NPP_SetValue;
aPluginFuncs->javaClass = NULL;
return NPERR_NO_ERROR;
}
NPError WINAPI NP_Initialize(NPNetscapeFuncs* aNetscapeFuncs)
{
dbgOut1("wrapper: NP_Initalize");
if(aNetscapeFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if(HIBYTE(aNetscapeFuncs->version) > NP_VERSION_MAJOR)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
if(aNetscapeFuncs->size < sizeof NPNetscapeFuncs)
return NPERR_INVALID_FUNCTABLE_ERROR;
NPNFuncs.size = aNetscapeFuncs->size;
NPNFuncs.version = aNetscapeFuncs->version;
NPNFuncs.geturlnotify = aNetscapeFuncs->geturlnotify;
NPNFuncs.geturl = aNetscapeFuncs->geturl;
NPNFuncs.posturlnotify = aNetscapeFuncs->posturlnotify;
NPNFuncs.posturl = aNetscapeFuncs->posturl;
NPNFuncs.requestread = aNetscapeFuncs->requestread;
NPNFuncs.newstream = aNetscapeFuncs->newstream;
NPNFuncs.write = aNetscapeFuncs->write;
NPNFuncs.destroystream = aNetscapeFuncs->destroystream;
NPNFuncs.status = aNetscapeFuncs->status;
NPNFuncs.uagent = aNetscapeFuncs->uagent;
NPNFuncs.memalloc = aNetscapeFuncs->memalloc;
NPNFuncs.memfree = aNetscapeFuncs->memfree;
NPNFuncs.memflush = aNetscapeFuncs->memflush;
NPNFuncs.reloadplugins = aNetscapeFuncs->reloadplugins;
NPNFuncs.getJavaEnv = aNetscapeFuncs->getJavaEnv;
NPNFuncs.getJavaPeer = aNetscapeFuncs->getJavaPeer;
NPNFuncs.getvalue = aNetscapeFuncs->getvalue;
NPNFuncs.setvalue = aNetscapeFuncs->setvalue;
NPNFuncs.invalidaterect = aNetscapeFuncs->invalidaterect;
NPNFuncs.invalidateregion = aNetscapeFuncs->invalidateregion;
NPNFuncs.forceredraw = aNetscapeFuncs->forceredraw;
return NPERR_NO_ERROR;
}
NPError WINAPI NP_Shutdown()
{
dbgOut1("wrapper:NP_Shutdown");
return NPERR_NO_ERROR;
}

Просмотреть файл

@ -34,3 +34,227 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "npapi.h"
#include "npupp.h"
#include "dbg.h"
extern NPNetscapeFuncs NPNFuncs;
void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor)
{
dbgOut1("wrapper: NPN_Version");
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
*netscape_major = HIBYTE(NPNFuncs.version);
*netscape_minor = LOBYTE(NPNFuncs.version);
}
NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData)
{
dbgOut1("wrapper: NPN_GetURLNotify");
int navMinorVers = NPNFuncs.version & 0xFF;
NPError rv = NPERR_NO_ERROR;
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
rv = NPNFuncs.geturlnotify(instance, url, target, notifyData);
else
rv = NPERR_INCOMPATIBLE_VERSION_ERROR;
return rv;
}
NPError NPN_GetURL(NPP instance, const char *url, const char *target)
{
dbgOut1("wrapper: NPN_GetURL");
NPError rv = NPNFuncs.geturl(instance, url, target);
return rv;
}
NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData)
{
dbgOut1("wrapper: NPN_PostURLNotify");
int navMinorVers = NPNFuncs.version & 0xFF;
NPError rv = NPERR_NO_ERROR;
if( navMinorVers >= NPVERS_HAS_NOTIFICATION )
rv = NPNFuncs.posturlnotify(instance, url, window, len, buf, file, notifyData);
else
rv = NPERR_INCOMPATIBLE_VERSION_ERROR;
return rv;
}
NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file)
{
dbgOut1("wrapper: NPN_PostURL");
NPError rv = NPNFuncs.posturl(instance, url, window, len, buf, file);
return rv;
}
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
dbgOut1("wrapper: NPN_RequestRead");
NPError rv = NPNFuncs.requestread(stream, rangeList);
return rv;
}
NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream)
{
dbgOut1("wrapper: NPN_NewStream");
int navMinorVersion = NPNFuncs.version & 0xFF;
NPError rv = NPERR_NO_ERROR;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT )
rv = NPNFuncs.newstream(instance, type, target, stream);
else
rv = NPERR_INCOMPATIBLE_VERSION_ERROR;
return rv;
}
int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer)
{
dbgOut1("wrapper: NPN_Write");
int navMinorVersion = NPNFuncs.version & 0xFF;
int32 rv = 0;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT )
rv = NPNFuncs.write(instance, stream, len, buffer);
else
rv = -1;
return rv;
}
NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
dbgOut1("wrapper: NPN_DestroyStream");
int navMinorVersion = NPNFuncs.version & 0xFF;
NPError rv = NPERR_NO_ERROR;
if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT )
rv = NPNFuncs.destroystream(instance, stream, reason);
else
rv = NPERR_INCOMPATIBLE_VERSION_ERROR;
return rv;
}
void NPN_Status(NPP instance, const char *message)
{
dbgOut1("wrapper: NPN_Status");
NPNFuncs.status(instance, message);
}
const char* NPN_UserAgent(NPP instance)
{
dbgOut1("wrapper: NPN_UserAgent");
const char * rv = NULL;
rv = NPNFuncs.uagent(instance);
return rv;
}
void* NPN_MemAlloc(uint32 size)
{
//bgOut1("wrapper: NPN_MemAlloc");
void * rv = NULL;
rv = NPNFuncs.memalloc(size);
return rv;
}
void NPN_MemFree(void* ptr)
{
//dbgOut1("wrapper: NPN_MemFree");
NPNFuncs.memfree(ptr);
}
uint32 NPN_MemFlush(uint32 size)
{
dbgOut1("wrapper: NPN_MemFlush");
uint32 rv = NPNFuncs.memflush(size);
return rv;
}
void NPN_ReloadPlugins(NPBool reloadPages)
{
dbgOut1("wrapper: NPN_ReloadPlugins");
NPNFuncs.reloadplugins(reloadPages);
}
JRIEnv* NPN_GetJavaEnv(void)
{
dbgOut1("wrapper: NPN_GetJavaEnv");
JRIEnv * rv = NULL;
rv = NPNFuncs.getJavaEnv();
return rv;
}
jref NPN_GetJavaPeer(NPP instance)
{
dbgOut1("wrapper: NPN_GetJavaPeer");
jref rv;
rv = NPNFuncs.getJavaPeer(instance);
return rv;
}
NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value)
{
dbgOut1("wrapper: NPN_GetValue");
NPError rv = NPERR_NO_ERROR;
rv = NPNFuncs.getvalue(instance, variable, value);
return rv;
}
NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value)
{
dbgOut1("wrapper: NPN_SetValue");
NPError rv = NPERR_NO_ERROR;
rv = NPNFuncs.setvalue(instance, variable, value);
return rv;
}
void NPN_InvalidateRect(NPP instance, NPRect *invalidRect)
{
dbgOut1("wrapper: NPN_InvalidateRect");
NPNFuncs.invalidaterect(instance, invalidRect);
}
void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion)
{
dbgOut1("wrapper: NPN_InvalidateRegion");
NPNFuncs.invalidateregion(instance, invalidRegion);
}
void NPN_ForceRedraw(NPP instance)
{
dbgOut1("wrapper: ForceRedraw");
NPNFuncs.forceredraw(instance);
}

Просмотреть файл

@ -34,3 +34,156 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "windows.h"
#include "npupp.h"
#include "npapi.h"
#include "plugin.h"
#include "dbg.h"
nsPluginThread * thePluginThread = NULL;
jref NPP_GetJavaClass ()
{
dbgOut1("wrapper: NPP_GetJavaClass");
jref rv = (jref)thePluginThread->callNPP(action_npp_get_java_class);
return NULL;
}
NPError NPP_New(NPMIMEType aType,
NPP aInstance,
uint16 aMode,
int16 aArgc,
char* aArgn[],
char* aArgv[],
NPSavedData* aSaved)
{
dbgOut1("wrapper: NPP_New");
NPError rv = NPERR_NO_ERROR;
// lamely assuming there is only one embed tag on the page!
// if it is first time in, we don't have it yet
// initiate a thread with plugin running in it
thePluginThread = new nsPluginThread((DWORD)aType);
if (!thePluginThread)
return NPERR_GENERIC_ERROR;
rv = (NPError)thePluginThread->callNPP(action_npp_new,
(DWORD)aType,
(DWORD)aInstance,
(DWORD)aMode,
(DWORD)aArgc,
(DWORD)aArgn,
(DWORD)aArgv,
(DWORD)aSaved);
return rv;
}
NPError NPP_Destroy (NPP aInstance, NPSavedData** aSave)
{
dbgOut1("wrapper: NPP_Destroy");
if (!thePluginThread)
return NPERR_GENERIC_ERROR;
NPError ret = (NPError)thePluginThread->callNPP(action_npp_destroy, (DWORD)aInstance, (DWORD)aSave);
delete thePluginThread;
thePluginThread = NULL;
return ret;
}
NPError NPP_SetWindow (NPP aInstance, NPWindow* aNPWindow)
{
dbgOut1("wrapper: NPP_SetWindow");
NPError rv = (NPError)thePluginThread->callNPP(action_npp_set_window, (DWORD)aInstance, (DWORD)aNPWindow);
return rv;
}
NPError NPP_NewStream(NPP aInstance,
NPMIMEType aType,
NPStream* aStream,
NPBool aSeekable,
uint16* aStype)
{
dbgOut1("wrapper: NPP_NewStream");
NPError rv = (NPError)thePluginThread->callNPP(action_npp_new_stream, (DWORD)aInstance, (DWORD)aType, (DWORD)aStream, (DWORD)aSeekable, (DWORD)aStype);
return rv;
}
int32 NPP_WriteReady (NPP aInstance, NPStream *aStream)
{
dbgOut1("wrapper: NPP_WriteReady");
int32 rv = (int32)thePluginThread->callNPP(action_npp_write_ready, (DWORD)aInstance, (DWORD)aStream);
return rv;
}
int32 NPP_Write (NPP aInstance, NPStream *aStream, int32 aOffset, int32 len, void *aBuffer)
{
dbgOut1("wrapper: NPP_Write");
int32 rv = (int32)thePluginThread->callNPP(action_npp_write, (DWORD)aInstance, (DWORD)aStream, (DWORD)aOffset, (DWORD)len, (DWORD)aBuffer);
return rv;
}
NPError NPP_DestroyStream (NPP aInstance, NPStream *aStream, NPError aReason)
{
dbgOut1("wrapper: NPP_DestroyStream");
NPError rv = (NPError)thePluginThread->callNPP(action_npp_destroy_stream, (DWORD)aInstance, (DWORD)aStream, (DWORD)aReason);
return rv;
}
void NPP_StreamAsFile (NPP aInstance, NPStream* aStream, const char* aName)
{
dbgOut1("wrapper: NPP_StreamAsFile");
thePluginThread->callNPP(action_npp_stream_as_file, (DWORD)aInstance, (DWORD)aStream, (DWORD)aName);
}
void NPP_Print (NPP aInstance, NPPrint* aPrintInfo)
{
dbgOut1("wrapper: NPP_Print");
thePluginThread->callNPP(action_npp_print, (DWORD)aInstance, (DWORD)aPrintInfo);
}
void NPP_URLNotify(NPP aInstance, const char* aUrl, NPReason aReason, void* aNotifyData)
{
dbgOut1("wrapper: NPP_URLNotify");
thePluginThread->callNPP(action_npp_url_notify, (DWORD)aInstance, (DWORD)aUrl, (DWORD)aReason, (DWORD)aNotifyData);
}
NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void *aValue)
{
dbgOut1("wrapper: NPP_GetValue");
NPError rv = (NPError)thePluginThread->callNPP(action_npp_get_value, (DWORD)aInstance, (DWORD)aVariable, (DWORD)aValue);
return rv;
}
NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void *aValue)
{
dbgOut1("wrapper: NPP_SetValue");
NPError rv = (NPError)thePluginThread->callNPP(action_npp_set_value, (DWORD)aInstance, (DWORD)aVariable, (DWORD)aValue);
return rv;
}
int16 NPP_HandleEvent(NPP aInstance, void* aEvent)
{
dbgOut1("wrapper: NPP_HandleEvent");
int16 rv = (int16)thePluginThread->callNPP(action_npp_handle_event, (DWORD)aInstance, (DWORD)aEvent);
return rv;
}

Просмотреть файл

@ -34,3 +34,200 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "windows.h"
#include "npupp.h"
#include "npapi.h"
#include "plugin.h"
#include "plugload.h"
#include "dbg.h"
extern NPNetscapeFuncs NPNFuncs;
NPNetscapeFuncs wrapperNPNFuncs;
NPPluginFuncs pluginNPPFuncs;
typedef NPError (__stdcall * NP_GETENTRYPOINTS)(NPPluginFuncs *);
typedef NPError (__stdcall * NP_INITIALIZE)(NPNetscapeFuncs *);
typedef NPError (__stdcall * NP_SHUTDOWN)(void);
NP_SHUTDOWN plugin_NP_Shutdown = NULL;
HINSTANCE pluginLibrary = NULL;
nsPluginThread::nsPluginThread(DWORD aP1) : CThread(),
mP1(aP1),
mP2(0),
mP3(0),
mP4(0),
mP5(0),
mP6(0),
mP7(0)
{
dbgOut1("nsPluginThread::nsPluginThread");
open(this);
}
nsPluginThread::~nsPluginThread()
{
dbgOut1("nsPluginThread::~nsPluginThread");
close(this);
}
BOOL nsPluginThread::init()
{
dbgOut1("nsPluginThread::init");
// scan plugins dir for available plugins to see if we have anything
// for the given mimetype
pluginLibrary = LoadRealPlugin((NPMIMEType)mP1);
if(!pluginLibrary)
return FALSE;
NP_GETENTRYPOINTS plugin_NP_GetEntryPoints = (NP_GETENTRYPOINTS)GetProcAddress(pluginLibrary, "NP_GetEntryPoints");
if(!plugin_NP_GetEntryPoints)
return FALSE;
NP_INITIALIZE plugin_NP_Initialize = (NP_INITIALIZE)GetProcAddress(pluginLibrary, "NP_Initialize");
if(!plugin_NP_Initialize)
return FALSE;
plugin_NP_Shutdown = (NP_SHUTDOWN)GetProcAddress(pluginLibrary, "NP_Shutdown");
if(!plugin_NP_Shutdown)
return FALSE;
// fill callbacks structs
memset(&pluginNPPFuncs, 0, sizeof(NPPluginFuncs));
pluginNPPFuncs.size = sizeof(NPPluginFuncs);
plugin_NP_GetEntryPoints(&pluginNPPFuncs);
// inform the plugin about our entry point it should call
memset((void *)&wrapperNPNFuncs, 0, sizeof(wrapperNPNFuncs));
wrapperNPNFuncs.size = sizeof(wrapperNPNFuncs);
wrapperNPNFuncs.version = NPNFuncs.version;
wrapperNPNFuncs.geturlnotify = NPN_GetURLNotify;
wrapperNPNFuncs.geturl = NPN_GetURL;
wrapperNPNFuncs.posturlnotify = NPN_PostURLNotify;
wrapperNPNFuncs.posturl = NPN_PostURL;
wrapperNPNFuncs.requestread = NPN_RequestRead;
wrapperNPNFuncs.newstream = NPN_NewStream;
wrapperNPNFuncs.write = NPN_Write;
wrapperNPNFuncs.destroystream = NPN_DestroyStream;
wrapperNPNFuncs.status = NPN_Status;
wrapperNPNFuncs.uagent = NPN_UserAgent;
wrapperNPNFuncs.memalloc = NPN_MemAlloc;
wrapperNPNFuncs.memfree = NPN_MemFree;
wrapperNPNFuncs.memflush = NPN_MemFlush;
wrapperNPNFuncs.reloadplugins = NPN_ReloadPlugins;
wrapperNPNFuncs.getJavaEnv = NPN_GetJavaEnv;
wrapperNPNFuncs.getJavaPeer = NPN_GetJavaPeer;
wrapperNPNFuncs.getvalue = NPN_GetValue;
wrapperNPNFuncs.setvalue = NPN_SetValue;
wrapperNPNFuncs.invalidaterect = NPN_InvalidateRect;
wrapperNPNFuncs.invalidateregion = NPN_InvalidateRegion;
wrapperNPNFuncs.forceredraw = NPN_ForceRedraw;
plugin_NP_Initialize(&wrapperNPNFuncs);
return TRUE;
}
void nsPluginThread::shut()
{
dbgOut1("nsPluginThread::shut");
if (!plugin_NP_Shutdown)
plugin_NP_Shutdown();
if (!pluginLibrary)
UnloadRealPlugin(pluginLibrary);
}
// NPP_ call translator
DWORD nsPluginThread::callNPP(npapiAction aAction, DWORD aP1, DWORD aP2,
DWORD aP3, DWORD aP4, DWORD aP5,
DWORD aP6, DWORD aP7)
{
// don't enter untill thread is ready
while (isBusy()) {
Sleep(0);
}
mP1 = aP1;
mP2 = aP2;
mP3 = aP3;
mP4 = aP4;
mP5 = aP5;
mP6 = aP6;
mP7 = aP7;
doAction(aAction);
// don't return untill thread is ready
while (isBusy()) {
Sleep(0);
}
return NPERR_NO_ERROR;
}
void nsPluginThread::dispatch()
{
dbgOut2("nsPluginThread::dispatch: %s", FormatAction(mAction));
switch (mAction) {
case action_npp_new:
pluginNPPFuncs.newp((NPMIMEType)mP1, (NPP)mP2, (uint16)mP3, (int16)mP4, (char**)mP5, (char**)mP6, (NPSavedData*)mP7);
break;
case action_npp_destroy:
pluginNPPFuncs.destroy((NPP)mP1, (NPSavedData**)mP2);
break;
case action_npp_set_window:
pluginNPPFuncs.setwindow((NPP)mP1, (NPWindow*)mP2);
break;
case action_npp_new_stream:
pluginNPPFuncs.newstream((NPP)mP1, (NPMIMEType)mP2, (NPStream*)mP3, (NPBool)mP4, (uint16*)mP5);
break;
case action_npp_destroy_stream:
{
NPStream * stream = (NPStream *)mP2;
pluginNPPFuncs.destroystream((NPP)mP1, stream, (NPError)mP3);
break;
}
case action_npp_stream_as_file:
{
NPStream * stream = (NPStream *)mP2;
pluginNPPFuncs.asfile((NPP)mP1, stream, (char*)mP3);
break;
}
case action_npp_write_ready:
pluginNPPFuncs.writeready((NPP)mP1, (NPStream *)mP2);
break;
case action_npp_write:
pluginNPPFuncs.write((NPP)mP1, (NPStream *)mP2, (int32)mP3, (int32)mP4, (void *)mP5);
break;
case action_npp_print:
pluginNPPFuncs.print((NPP)mP1, (NPPrint*)mP2);
break;
case action_npp_handle_event:
pluginNPPFuncs.event((NPP)mP1, (void *)mP2);
break;
case action_npp_url_notify:
pluginNPPFuncs.urlnotify((NPP)mP1, (const char*)mP2, (NPReason)mP3, (void*)mP4);
break;
case action_npp_get_java_class:
//pluginNPPFuncs.javaClass;
break;
case action_npp_get_value:
pluginNPPFuncs.getvalue((NPP)mP1, (NPPVariable)mP2, (void *)mP3);
break;
case action_npp_set_value:
pluginNPPFuncs.setvalue((NPP)mP1, (NPNVariable)mP2, (void *)mP3);
break;
default:
dbgOut1("Unexpected action!");
break;
}
}

Просмотреть файл

@ -34,3 +34,120 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "windows.h"
DWORD GetPluginsDir(char * path, DWORD maxsize)
{
if(!path)
return 0;
path[0] = '\0';
DWORD res = GetModuleFileName(NULL, path, maxsize);
if(res == 0)
return 0;
if(path[strlen(path) - 1] == '\\')
path[lstrlen(path) - 1] = '\0';
char *p = strrchr(path, '\\');
if(p)
*p = '\0';
strcat(path, "\\plugins");
res = strlen(path);
return res;
}
HINSTANCE LoadRealPlugin(char * mimetype)
{
if(!mimetype || !strlen(mimetype))
return NULL;
BOOL bDone = FALSE;
WIN32_FIND_DATA ffdataStruct;
char szPath[_MAX_PATH];
char szFileName[_MAX_PATH];
GetPluginsDir(szPath, _MAX_PATH);
strcpy(szFileName, szPath);
strcat(szFileName, "\\00*");
HANDLE handle = FindFirstFile(szFileName, &ffdataStruct);
if(handle == INVALID_HANDLE_VALUE) {
FindClose(handle);
return NULL;
}
DWORD versize = 0L;
DWORD zero = 0L;
char * verbuf = NULL;
do {
strcpy(szFileName, szPath);
strcat(szFileName, "\\");
strcat(szFileName, ffdataStruct.cFileName);
if(!(ffdataStruct. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
versize = GetFileVersionInfoSize(szFileName, &zero);
if (versize > 0)
verbuf = new char[versize];
else
continue;
if(!verbuf)
continue;
GetFileVersionInfo(szFileName, NULL, versize, verbuf);
char *mimetypes = NULL;
UINT len = 0;
if(!VerQueryValue(verbuf, "\\StringFileInfo\\040904E4\\MIMEType", (void **)&mimetypes, &len)
|| !mimetypes || !len) {
delete [] verbuf;
continue;
}
// browse through a string of mimetypes
mimetypes[len] = '\0';
char * type = mimetypes;
BOOL more = TRUE;
while(more) {
char * p = strchr(type, '|');
if(p)
*p = '\0';
else
more = FALSE;
if(0 == stricmp(mimetype, type)) {
// this is it!
delete [] verbuf;
FindClose(handle);
HINSTANCE hLib = LoadLibrary(szFileName);
return hLib;
}
type = p;
type++;
}
delete [] verbuf;
}
} while(FindNextFile(handle, &ffdataStruct));
FindClose(handle);
return NULL;
}
void UnloadRealPlugin(HINSTANCE hLib)
{
if(!hLib)
FreeLibrary(hLib);
}

Просмотреть файл

@ -34,3 +34,170 @@
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <windows.h>
#include <windowsx.h>
#include <process.h>
#include "thread.h"
#include "dbg.h"
static DWORD WINAPI ThreadFunction(void * lp)
{
if (lp == NULL)
return 0L;
CThread * thread = (CThread *)lp;
BOOL res = thread->init();
thread->setInitEvent();
if(res)
thread->run();
thread->shut();
DWORD ret;
GetExitCodeThread(thread->getHandle(), &ret);
thread->setShutEvent();
return ret;
}
CThread::CThread(DWORD aInitTimeOut, DWORD aShutTimeOut) :
mThread(NULL),
mID(0),
mState(ts_dead),
mEventThreadInitializationFinished(NULL),
mEventThreadShutdownFinished(NULL),
mInitTimeOut(aInitTimeOut),
mShutTimeOut(aShutTimeOut),
mEventDo(NULL),
mAction(0)
{
dbgOut1("CThread::CThread");
}
CThread::~CThread()
{
dbgOut1("CThread::~CThread");
}
BOOL CThread::open(CThread * aThread)
{
dbgOut1("CThread::open");
mEventThreadInitializationFinished = CreateEvent(NULL, TRUE, FALSE, NULL);
mEventThreadShutdownFinished = CreateEvent(NULL, TRUE, FALSE, NULL);
mEventDo = CreateEvent(NULL, TRUE, FALSE, NULL);
mThread = (HANDLE)::_beginthreadex(0, 1024, (UINT (__stdcall *)(void *))ThreadFunction, aThread, 0L, (UINT *)&mID);
if(mThread == NULL)
return FALSE;
SetThreadPriority(mThread, THREAD_PRIORITY_NORMAL);
if(mEventThreadInitializationFinished != NULL)
WaitForSingleObject(mEventThreadInitializationFinished, mInitTimeOut);
return TRUE;
}
void CThread::close(CThread * aThread)
{
switch (mState) {
case ts_dead:
break;
case ts_ready:
mState = ts_dead;
SetEvent(mEventDo);
if(mEventThreadShutdownFinished != NULL)
WaitForSingleObject(mEventThreadShutdownFinished, mShutTimeOut);
break;
case ts_busy:
{
aThread->shut();
DWORD ret;
GetExitCodeThread(aThread->getHandle(), &ret);
TerminateThread(mThread, ret);
mState = ts_dead;
break;
}
default:
break;
}
mThread = NULL;
CloseHandle(mEventThreadInitializationFinished);
CloseHandle(mEventThreadShutdownFinished);
CloseHandle(mEventDo);
dbgOut1("CThread::close");
}
BOOL CThread::setInitEvent()
{
return SetEvent(mEventThreadInitializationFinished);
}
BOOL CThread::setShutEvent()
{
return SetEvent(mEventThreadShutdownFinished);
}
BOOL CThread::isAlive()
{
return (mThread != NULL);
}
BOOL CThread::isBusy()
{
return (mState == ts_busy);
}
HANDLE CThread::getHandle()
{
return mThread;
}
void CThread::run()
{
mState = ts_ready;
while(mState != ts_dead) {
WaitForSingleObject(mEventDo, INFINITE);
//dbgOut2("CThread::run(): Do event signalled, %u", mState);
ResetEvent(mEventDo);
if(mState == ts_dead)
return;
mState = ts_busy;
dispatch();
mState = ts_ready;
}
mState = ts_dead;
}
BOOL CThread::tryAction(int aAction)
{
if(mState != ts_ready)
return FALSE;
mAction = aAction;
SetEvent(mEventDo);
return TRUE;
}
BOOL CThread::doAction(int aAction)
{
while(mState != ts_ready) {
//dbgOut2("CThread::doAction %i -- waiting...", aAction);
if(mState == ts_dead)
return FALSE;
Sleep(0);
}
mState = ts_busy;
mAction = aAction;
//dbgOut2("CThread::doAction -- about to signal %i", aAction);
SetEvent(mEventDo);
return TRUE;
}