diff options
Diffstat (limited to 'sapi/activescript')
| -rw-r--r-- | sapi/activescript/CREDITS | 2 | ||||
| -rw-r--r-- | sapi/activescript/EXPERIMENTAL | 5 | ||||
| -rw-r--r-- | sapi/activescript/README | 59 | ||||
| -rw-r--r-- | sapi/activescript/classfactory.cpp | 373 | ||||
| -rw-r--r-- | sapi/activescript/config.w32 | 13 | ||||
| -rwxr-xr-x | sapi/activescript/marshal.cpp | 428 | ||||
| -rw-r--r-- | sapi/activescript/php5activescript.c | 171 | ||||
| -rw-r--r-- | sapi/activescript/php5activescript.def | 5 | ||||
| -rw-r--r-- | sapi/activescript/php5activescript.dsp | 185 | ||||
| -rw-r--r-- | sapi/activescript/php5activescript.h | 25 | ||||
| -rw-r--r-- | sapi/activescript/php5as_classfactory.h | 63 | ||||
| -rw-r--r-- | sapi/activescript/php5as_scriptengine.h | 214 | ||||
| -rw-r--r-- | sapi/activescript/scriptengine.cpp | 2039 |
13 files changed, 0 insertions, 3582 deletions
diff --git a/sapi/activescript/CREDITS b/sapi/activescript/CREDITS deleted file mode 100644 index ef347bac0d..0000000000 --- a/sapi/activescript/CREDITS +++ /dev/null @@ -1,2 +0,0 @@ -ActiveScript -Wez Furlong diff --git a/sapi/activescript/EXPERIMENTAL b/sapi/activescript/EXPERIMENTAL deleted file mode 100644 index 293159a693..0000000000 --- a/sapi/activescript/EXPERIMENTAL +++ /dev/null @@ -1,5 +0,0 @@ -this module is experimental, -its functions may change their names -or move to extension all together -so do not rely to much on them -you have been warned! diff --git a/sapi/activescript/README b/sapi/activescript/README deleted file mode 100644 index a0d9d0f14f..0000000000 --- a/sapi/activescript/README +++ /dev/null @@ -1,59 +0,0 @@ -This is the ActiveScript SAPI for PHP. -====================================== - -Once registered on your system (using regsvr32), you will be able to use -PHP script in any ActiveScript compliant host. The list includes: - -o. Windows Script Host -o. ASP and ASP.NET -o. Windows Script Components / Behaviours -o. MS Scriptlet control - -Probably the most useful of these will be using it with the scriptlet -control, or in your own activescript host, so that you can very easily -embed PHP into your win32 application. - -Installation. -============= - -Build and install it somewhere; then register the engine like this: - - regsvr32 php5activescript.dll - -Configuration. -============== - -PHPScript will not use the default php.ini file. -Instead, it will look only in the same directory as the .exe that caused it to -load. - -You should create php-activescript.ini and place it in that folder, if you wish -to load extensions etc. - -Usage. -====== - -o. Windows Script Host - - Create a .wsf file like this: - - <job id="test"> - <script language="PHPScript"> - $WScript->Echo("Hello"); - </script> - </job> - -o. ASP and ASP.NET - - <%@language=PHPScript %> - <% $Response->Write("Hello"); %> - -o. Windows Script Components / Behaviours - - Use language="PHPScript" on your <script> tags - -o. MS Scriptlet control - - Set the language property to "PHPScript" - - diff --git a/sapi/activescript/classfactory.cpp b/sapi/activescript/classfactory.cpp deleted file mode 100644 index f4e2c9bd87..0000000000 --- a/sapi/activescript/classfactory.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -/* IClassFactory Implementation, and DllXXX function implementation */ - -#define DEBUG_CLASS_FACTORY 0 -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> -#include <objbase.h> -#define INITGUID -#include <initguid.h> - -extern "C" { -HINSTANCE module_handle; -} - -#include <comcat.h> -#include "TSRM.h" -#include "php5as_classfactory.h" -#include "php5as_scriptengine.h" - -volatile LONG TPHPClassFactory::factory_count = 0; -volatile LONG TPHPClassFactory::object_count = 0; - -/* {{{ Class Factory Implementation */ -TPHPClassFactory::TPHPClassFactory() -{ - m_refcount = 1; - InterlockedIncrement(const_cast<long*> (&factory_count)); -} - -TPHPClassFactory::~TPHPClassFactory() -{ - InterlockedDecrement(const_cast<long*> (&factory_count)); -} - -void TPHPClassFactory::AddToObjectCount(void) -{ - InterlockedIncrement(const_cast<long*> (&object_count)); -} - -void TPHPClassFactory::RemoveFromObjectCount(void) -{ - InterlockedDecrement(const_cast<long*> (&object_count)); -} - -STDMETHODIMP_(DWORD) TPHPClassFactory::AddRef(void) -{ - return InterlockedIncrement(const_cast<long*> (&m_refcount)); -} - -STDMETHODIMP_(DWORD) TPHPClassFactory::Release(void) -{ - DWORD ret = InterlockedDecrement(const_cast<long*> (&m_refcount)); - if (ret == 0) - delete this; - return ret; -} - -STDMETHODIMP TPHPClassFactory::QueryInterface(REFIID iid, void **ppvObject) -{ - *ppvObject = NULL; - - if (IsEqualGUID(IID_IClassFactory, iid)) { - *ppvObject = (IClassFactory*)this; - } else if (IsEqualGUID(IID_IUnknown, iid)) { - *ppvObject = this; - } - if (*ppvObject) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - -STDMETHODIMP TPHPClassFactory::LockServer(BOOL fLock) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppvObject) -{ - IUnknown *punk = create_scripting_engine(NULL); - HRESULT ret; - - if (punk) { - ret = punk->QueryInterface(iid, ppvObject); - punk->Release(); - } else { - ret = E_UNEXPECTED; - } - - return ret; -} - -int TPHPClassFactory::CanUnload(void) -{ - return (object_count + factory_count) == 0 ? 1 : 0; -} - -/* }}} */ - -/* {{{ Registration structures */ -struct reg_entry { - HKEY root_key; - char *sub_key; - char *value_name; - char *data; -}; - -struct reg_class { - /* REFIID here causes compilation errors */ - const GUID *class_id; - char *class_name; - char *threading; - const struct reg_entry *reg; - const GUID **cats; -}; - -#define MAX_REG_SUBST 8 -struct reg_subst { - int count; - char *names[MAX_REG_SUBST]; - char *values[MAX_REG_SUBST]; -}; -/* }}} */ - -/* {{{ Registration information */ -/* This registers the sapi as a scripting engine that can be instantiated using it's progid */ -static const struct reg_entry engine_entries[] = { - { HKEY_CLASSES_ROOT, "CLSID\\[CLSID]", NULL, "[CLASSNAME]" }, - { HKEY_CLASSES_ROOT, "CLSID\\[CLSID]\\InprocServer32", NULL, "[MODULENAME]" }, - { HKEY_CLASSES_ROOT, "CLSID\\[CLSID]\\InprocServer32", "ThreadingModel", "[THREADING]" }, - { HKEY_CLASSES_ROOT, "CLSID\\[CLSID]\\OLEScript", NULL, NULL }, - { HKEY_CLASSES_ROOT, "CLSID\\[CLSID]\\ProgID", NULL, "PHPScript" }, - { HKEY_CLASSES_ROOT, "PHPScript", NULL, "PHPScript" }, - { HKEY_CLASSES_ROOT, "PHPScript\\CLSID", NULL, "[CLSID]"}, - { HKEY_CLASSES_ROOT, "PHPScript\\OLEScript", NULL, NULL}, - - { 0, NULL, NULL, NULL } -}; - -static const GUID *script_engine_categories[] = { - &CATID_ActiveScript, - &CATID_ActiveScriptParse, - NULL -}; - -static const struct reg_class classes_to_register[] = { - { &CLSID_PHPActiveScriptEngine, "PHP Active Script Engine", -#if ACTIVEPHP_THREADING_MODE == COINIT_MULTITHREADED - "Both", -#else - "Apartment", -#endif - engine_entries, script_engine_categories }, - { NULL, NULL, NULL, 0, NULL } -}; -/* }}} */ - -/* {{{ Registration code */ -static void substitute(struct reg_subst *subst, char *srcstring, char *deststring) -{ - int i; - char *srcpos = srcstring; - char *destpos = deststring; - - while(1) { - char *repstart = strchr(srcpos, '['); - - if (repstart == NULL) { - strcpy(destpos, srcpos); - break; - } - - /* copy everything up until that character to the dest */ - strncpy(destpos, srcpos, repstart - srcpos); - destpos += repstart - srcpos; - *destpos = 0; - - /* search for replacement strings in the table */ - for (i = 0; i < subst->count; i++) { - int len = strlen(subst->names[i]); - if (strncmp(subst->names[i], repstart + 1, len) == 0) { - /* append the replacement value to the buffer */ - strcpy(destpos, subst->values[i]); - destpos += strlen(subst->values[i]); - srcpos = repstart + len + 2; - - break; - } - } - } -#if DEBUG_CLASS_FACTORY - MessageBox(0, deststring, srcstring, MB_ICONHAND); -#endif -} - -static int reg_string(BOOL do_reg, struct reg_subst *subst, const struct reg_entry *entry) -{ - char subbuf[MAX_PATH], valuebuf[MAX_PATH], databuf[MAX_PATH]; - char *sub = NULL, *value = NULL, *data = NULL; - LRESULT res; - HKEY hkey; - DWORD disp; - - if (entry->sub_key) { - substitute(subst, entry->sub_key, subbuf); - sub = subbuf; - } - - if (entry->value_name) { - substitute(subst, entry->value_name, valuebuf); - value = valuebuf; - } - - if (entry->data) { - substitute(subst, entry->data, databuf); - data = databuf; - } - - if (do_reg) { - res = RegCreateKeyEx(entry->root_key, sub, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WRITE, NULL, &hkey, &disp); - if (res == NOERROR) { - if (data) - res = RegSetValueEx(hkey, value, 0, REG_SZ, (LPBYTE)data, strlen(data) + 1); - RegCloseKey(hkey); - } - } else { - res = RegDeleteKey(entry->root_key, sub); - } - return res == NOERROR ? 1 : 0; -} - -static int perform_registration(BOOL do_reg) -{ - char module_name[MAX_PATH]; - char classid[40]; - int ret = 1; - int i, j; - struct reg_subst subst = {0}; - LPOLESTR classidw; - ICatRegister *catreg = NULL; - CATID cats[8]; - int ncats; - - CoInitialize(NULL); - CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (LPVOID*)&catreg); - - GetModuleFileName(module_handle, module_name, sizeof(module_name)); - - subst.names[0] = "CLSID"; - subst.values[0] = classid; - - subst.names[1] = "MODULENAME"; - subst.values[1] = module_name; - - subst.names[2] = "CLASSNAME"; - subst.names[3] = "THREADING"; - - subst.count = 4; - - for (i = 0; classes_to_register[i].class_id; i++) { - StringFromCLSID(*classes_to_register[i].class_id, &classidw); - WideCharToMultiByte(CP_ACP, 0, classidw, -1, classid, sizeof(classid), NULL, NULL); - classid[39] = 0; - CoTaskMemFree(classidw); - - subst.values[2] = classes_to_register[i].class_name; - subst.values[3] = classes_to_register[i].threading; - - if (catreg && classes_to_register[i].cats) { - ncats = 0; - while(classes_to_register[i].cats[ncats]) { - CopyMemory(&cats[ncats], classes_to_register[i].cats[ncats], sizeof(CATID)); - ncats++; - } - } - - if (do_reg) { - for (j = 0; classes_to_register[i].reg[j].root_key; j++) { - if (!reg_string(do_reg, &subst, &classes_to_register[i].reg[j])) { - ret = 0; - break; - } - } - - if (catreg && ncats) { - catreg->RegisterClassImplCategories(*classes_to_register[i].class_id, ncats, cats); - } - - } else { - - if (catreg && ncats) { - catreg->UnRegisterClassImplCategories(*classes_to_register[i].class_id, ncats, cats); - } - - /* do it in reverse order, so count the number of entries first */ - for (j = 0; classes_to_register[i].reg[j].root_key; j++) - ; - while(j-- > 0) { - if (!reg_string(do_reg, &subst, &classes_to_register[i].reg[j])) { - ret = 0; - break; - } - } - } - } - - if (catreg) - catreg->Release(); - CoUninitialize(); - - return ret; -} -/* }}} */ - -/* {{{ Standard COM server DllXXX entry points */ - -STDAPI DllCanUnloadNow(void) -{ - if (TPHPClassFactory::CanUnload()) - return S_OK; - return S_FALSE; -} - -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) -{ - HRESULT ret = E_FAIL; - - if (IsEqualCLSID(CLSID_PHPActiveScriptEngine, rclsid)) { - TPHPClassFactory *factory = new TPHPClassFactory(); - - if (factory) { - ret = factory->QueryInterface(riid, ppv); - factory->Release(); - } - } - return ret; -} - - - -STDAPI DllRegisterServer(void) -{ - return perform_registration(TRUE) ? S_OK : S_FALSE; -} - -STDAPI DllUnregisterServer(void) -{ - return perform_registration(FALSE) ? S_OK : S_FALSE; -} - -/* }}} */ diff --git a/sapi/activescript/config.w32 b/sapi/activescript/config.w32 deleted file mode 100644 index 0dbfc5851c..0000000000 --- a/sapi/activescript/config.w32 +++ /dev/null @@ -1,13 +0,0 @@ -// vim:ft=javascript -// $Id$ - -ARG_ENABLE('activescript', 'Build ActiveScript version of PHP', 'no'); - -if (PHP_ACTIVESCRIPT == "yes") { - if (PHP_ZTS == "no") { - ERROR("ActiveScript module requires an --enable-zts build of PHP"); - } - - SAPI('activescript', 'classfactory.cpp php5activescript.c scriptengine.cpp marshal.cpp', 'php' + PHP_VERSION + 'activescript.dll', '/D PHP5ISAPI_EXPORTS /D ACTIVEPHP_OBJECT_SAFETY=1'); - ADD_FLAG('LDFLAGS_ACTIVESCRIPT', 'oleaut32.lib ole32.lib user32.lib advapi32.lib /DEF:' + configure_module_dirname + '\\php5activescript.def'); -} diff --git a/sapi/activescript/marshal.cpp b/sapi/activescript/marshal.cpp deleted file mode 100755 index da9ed16c56..0000000000 --- a/sapi/activescript/marshal.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -/* Fun with threads */ - -#define _WIN32_DCOM -#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS -#include <winsock2.h> -#include "php5as_scriptengine.h" -#include "php5as_classfactory.h" -#include <objbase.h> -#undef php_win_err - -extern "C" char *php_win_err(HRESULT ret); - -#define APHPM_IN 1 -#define APHPM_OUT 2 - -#define APHPT_TERM 0 -#define APHPT_UNK 1 /* IUnknown * */ -#define APHPT_DISP 2 /* IDispatch * */ -#define APHPT_VAR 3 /* PVARIANT */ - -static inline void trace(char *fmt, ...) -{ - va_list ap; - char buf[4096]; - - sprintf(buf, "T=%08x [MARSHAL] ", tsrm_thread_id()); - OutputDebugString(buf); - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - - OutputDebugString(buf); - - va_end(ap); -} -struct marshal_arg { - int type; - int argno; - int direction; -}; - -static int parse_script_text_mdef[] = { - APHPT_UNK, 2, APHPM_IN, - APHPT_VAR, 7, APHPM_OUT, - APHPT_TERM -}; - -static int get_script_dispatch_mdef[] = { - APHPT_DISP, 1, APHPM_OUT, - APHPT_TERM -}; - -static int parse_procedure_text_mdef[] = { - APHPT_UNK, 4, APHPM_IN, - APHPT_DISP, 9, APHPM_OUT, - APHPT_TERM -}; - -static int *mdef_by_func[APHP__Max] = { - parse_script_text_mdef, - NULL, /* InitNew */ - NULL, /* AddNamedItem */ - NULL, /* SetScriptState */ - get_script_dispatch_mdef, - NULL, /* Close */ - NULL, /* AddTypeLib */ - NULL, /* AddScriptlet */ - parse_procedure_text_mdef, -}; - -static HRESULT do_marshal_in(int stub, void *args[16], int *mdef, LPSTREAM *ppstm) -{ - int i = 0; - int want; - HRESULT ret = S_OK; - LPSTREAM stm = NULL; - - if (!mdef) - return S_OK; - - trace("marshalling ... \n"); - - ret = CreateStreamOnHGlobal(NULL, TRUE, &stm); - if (FAILED(ret)) { - trace(" failed to create stm %s", php_win_err(ret)); - return ret; - } - - *ppstm = stm; - - /* if stub is true, we are the stub and are marshaling OUT params, - * otherwise, we are the proxy and are marshalling IN params */ - - if (stub) { - want = APHPM_OUT; - } else { - want = APHPM_IN; - } - - while (mdef[i] != APHPT_TERM) { - if ((mdef[i+2] & want) == want) { - int argno = mdef[i+1]; - int isout = (mdef[i+2] & APHPM_OUT) == APHPM_OUT; - -#undef OUT_IFACE -#define OUT_IFACE (isout ? *(IUnknown**)args[argno] : (IUnknown*)args[argno]) -#define IFACE_PRESENT args[argno] && (!isout || *(IUnknown**)args[argno]) - switch (mdef[i]) { - case APHPT_UNK: - if (IFACE_PRESENT) { - ret = CoMarshalInterface(stm, IID_IUnknown, OUT_IFACE, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); - trace(" arg=%d IUnknown --> %s", argno, php_win_err(ret)); - } else { - trace(" arg=%d IUnknown(NULL) - skip\n", argno); - } - break; - - case APHPT_DISP: - if (IFACE_PRESENT) { - ret = CoMarshalInterface(stm, IID_IDispatch, OUT_IFACE, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); - trace(" arg=%d IDispatch --> %s", argno, php_win_err(ret)); - } else { - trace(" arg=%d IDispatch(NULL) - skip\n", argno); - } - break; - - case APHPT_VAR: - if (args[argno]) - ret = E_NOTIMPL; - break; - - default: - ret = E_NOTIMPL; - } - - if (FAILED(ret)) - break; - } else { - trace(" -- skipping (this param is not needed in this direction)\n"); - } - i += 3; - } - - if (FAILED(ret)) { - /* TODO: rollback (refcounts are held during marshalling) */ - trace(" rolling back\n"); - stm->Release(); - *ppstm = NULL; - } else { - LARGE_INTEGER pos = {0}; - stm->Seek(pos, STREAM_SEEK_SET, NULL); - } - - return ret; -} - -static HRESULT do_marshal_out(int stub, void *args[16], int *mdef, LPSTREAM stm) -{ - int i = 0; - int want; - HRESULT ret = S_OK; - - if (!mdef) - return S_OK; - - trace(" unmarshalling...\n"); - - /* if stub is true, we are the stub and are unmarshaling IN params, - * otherwise, we are the proxy and are unmarshalling OUT params */ - - if (!stub) { - want = APHPM_OUT; - } else { - want = APHPM_IN; - } - - while (mdef[i] != APHPT_TERM) { - if ((mdef[i+2] & want) == want) { - int argno = mdef[i+1]; - int isout = (mdef[i+2] & APHPM_OUT) == APHPM_OUT; -#undef OUT_IFACE -#define OUT_IFACE (isout ? (void**)args[argno] : &args[argno]) - - switch (mdef[i]) { - case APHPT_UNK: - if (IFACE_PRESENT) { - ret = CoUnmarshalInterface(stm, IID_IUnknown, OUT_IFACE); - trace(" unmarshal arg=%d IUnknown --> %s", argno, php_win_err(ret)); - } else { - trace(" unmarshal arg=%d IUnknown(NULL) - skip\n", argno); - } - break; - - case APHPT_DISP: - if (IFACE_PRESENT) { - trace(" unmarshal dispatch: args[%d]=%p *args[%d]=%p\n", - argno, args[argno], argno, args[argno] ? *(void**)args[argno] : NULL); - ret = CoUnmarshalInterface(stm, IID_IDispatch, OUT_IFACE); - trace(" unmarshal arg=%d IDispatch --> %s: args[%d]=%p *args[%d]=%p\n", argno, php_win_err(ret), - argno, args[argno], argno, args[argno] ? *(void**)args[argno] : NULL); - } else { - trace(" unmarshal arg=%d IDispatch(NULL) - skip\n", argno); - } - break; - - case APHPT_VAR: - if (args[argno]) - ret = E_NOTIMPL; - break; - - default: - ret = E_NOTIMPL; - } - if (FAILED(ret)) - break; - } - i += 3; - } - - return ret; -} - - -struct activephp_serialize_msg { - class TPHPScriptingEngine *engine; - void *args[16]; - int nargs; - enum activephp_engine_func func; - int *marshal_defs; - LPSTREAM instm, outstm; - - HANDLE evt; - HRESULT ret; -}; - -static const char *func_names[APHP__Max] = { - "ParseScriptText", - "InitNew", - "AddnamedItem", - "SetScriptState", - "GetScriptDispatch", - "Close", - "AddTypeLib", - "AddScriptlet", - "ParseProcedureText", -}; - -HRESULT marshal_call(class TPHPScriptingEngine *engine, enum activephp_engine_func func, int nargs, ...) -{ - va_list ap; - struct activephp_serialize_msg msg ; - HRESULT ret; - - memset(&msg, 0, sizeof(msg)); - - msg.engine = engine; - msg.func = func; - msg.marshal_defs = mdef_by_func[func]; - - trace(" prepping for function code %d %s, %d args, marshal defs at %p\n", func, func_names[func], nargs, msg.marshal_defs); - - va_start(ap, nargs); - for (msg.nargs = 0; msg.nargs < nargs; msg.nargs++) { - msg.args[msg.nargs] = va_arg(ap, void*); - } - va_end(ap); - - ret = do_marshal_in(0, msg.args, msg.marshal_defs, &msg.instm); - - if (FAILED(ret)) { - return ret; - } - -#if 1 - msg.evt = CreateEvent(NULL, TRUE, FALSE, NULL); - PostMessage(engine->m_queue, WM_ACTIVEPHP_SERIALIZE, 0, (LPARAM)&msg); - - while (WAIT_OBJECT_0 != WaitForSingleObject(msg.evt, 0)) { - DWORD status = MsgWaitForMultipleObjects(1, &msg.evt, FALSE, INFINITE, QS_ALLEVENTS|QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SENDMESSAGE|QS_POSTMESSAGE); - - if (status == WAIT_OBJECT_0) - break; - - MSG msg; - - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - CloseHandle(msg.evt); -#else - ret = SendMessage(engine->m_queue, WM_ACTIVEPHP_SERIALIZE, 0, (LPARAM)&msg); -#endif - - if (msg.outstm) { - ret = do_marshal_out(0, msg.args, msg.marshal_defs, msg.outstm); - msg.outstm->Release(); - } - - if (msg.instm) - msg.instm->Release(); - - trace("marshall call to %s completed %s", func_names[func], php_win_err(ret)); - - return ret; -} - -HRESULT marshal_stub(LPARAM lparam) -{ - struct activephp_serialize_msg *msg = (struct activephp_serialize_msg*)lparam; - - if (msg->instm) { - msg->ret = do_marshal_out(1, msg->args, msg->marshal_defs, msg->instm); - - if (FAILED(msg->ret)) { - SetEvent(msg->evt); - return msg->ret; - } - } - - switch (msg->func) { - case APHP_ParseScriptText: - msg->ret = msg->engine->ParseScriptText( - (LPCOLESTR)msg->args[0], - (LPCOLESTR)msg->args[1], - (IUnknown*)msg->args[2], - (LPCOLESTR)msg->args[3], - (DWORD)msg->args[4], - (ULONG)msg->args[5], - (DWORD)msg->args[6], - (VARIANT*)msg->args[7], - (EXCEPINFO*)msg->args[8]); - break; - - case APHP_InitNew: - msg->ret = msg->engine->InitNew(); - break; - - case APHP_AddNamedItem: - msg->ret = msg->engine->AddNamedItem( - (LPCOLESTR)msg->args[0], - (DWORD)msg->args[1]); - break; - - case APHP_SetScriptState: - msg->ret = msg->engine->SetScriptState((SCRIPTSTATE)(LONG)msg->args[0]); - break; - - case APHP_GetScriptDispatch: - msg->ret = msg->engine->GetScriptDispatch( - (LPCOLESTR)msg->args[0], - (IDispatch**)msg->args[1]); - break; - - case APHP_Close: - msg->ret = msg->engine->Close(); - break; - - case APHP_AddTypeLib: - msg->ret = msg->engine->AddTypeLib( - (REFGUID)msg->args[0], - (DWORD)msg->args[1], - (DWORD)msg->args[2], - (DWORD)msg->args[3]); - break; - - case APHP_AddScriptlet: - msg->ret = msg->engine->AddScriptlet( - (LPCOLESTR)msg->args[0], - (LPCOLESTR)msg->args[1], - (LPCOLESTR)msg->args[2], - (LPCOLESTR)msg->args[3], - (LPCOLESTR)msg->args[4], - (LPCOLESTR)msg->args[5], - (DWORD)msg->args[6], - (ULONG)msg->args[7], - (DWORD)msg->args[8], - (BSTR*)msg->args[9], - (EXCEPINFO*)msg->args[10]); - break; - - case APHP_ParseProcedureText: - msg->ret = msg->engine->ParseProcedureText( - (LPCOLESTR)msg->args[0], - (LPCOLESTR)msg->args[1], - (LPCOLESTR)msg->args[2], - (LPCOLESTR)msg->args[3], - (IUnknown*)msg->args[4], - (LPCOLESTR)msg->args[5], - (DWORD)msg->args[6], - (ULONG)msg->args[7], - (DWORD)msg->args[8], - (IDispatch**)msg->args[9]); - break; - - default: - msg->ret = E_NOTIMPL; - } - - if (SUCCEEDED(msg->ret)) { - msg->ret = do_marshal_in(1, msg->args, msg->marshal_defs, &msg->outstm); - } - - SetEvent(msg->evt); - - return msg->ret; -} - diff --git a/sapi/activescript/php5activescript.c b/sapi/activescript/php5activescript.c deleted file mode 100644 index 237887ac6d..0000000000 --- a/sapi/activescript/php5activescript.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -#include "php.h" -#include "php_main.h" -#include "SAPI.h" -#include "php_globals.h" -#include "ext/standard/info.h" -#include "php_variables.h" -#include "php_ini.h" -#include "php5activescript.h" - -/* SAPI definitions and DllMain */ - -static int php_activescript_startup(sapi_module_struct *sapi_module) -{ - if (php_module_startup(sapi_module, &php_activescript_module, 1) == FAILURE) { - return FAILURE; - } else { - return SUCCESS; - } -} - -static int sapi_activescript_ub_write(const char *str, uint str_length TSRMLS_DC) -{ - /* In theory, this is a blackhole. In practice, I want to see the output - * in the debugger! */ -#if ZEND_DEBUG - char buf[1024]; - uint l, a = str_length; - - while(a) { - l = a; - if (l > sizeof(buf) - 1) - l = sizeof(buf) - 1; - memcpy(buf, str, l); - buf[l] = 0; - OutputDebugString(buf); - a -= l; - } -#endif - return str_length; -} - -static void sapi_activescript_register_server_variables(zval *track_vars_array TSRMLS_DC) -{ -} - -static char *sapi_activescript_read_cookies(TSRMLS_D) -{ - return NULL; -} - -static int sapi_activescript_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) -{ - return SAPI_HEADER_ADD; -} - -static int sapi_activescript_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) -{ - return SAPI_HEADER_SENT_SUCCESSFULLY; -} - -zend_module_entry php_activescript_module = { - STANDARD_MODULE_HEADER, - "ActiveScript", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - STANDARD_MODULE_PROPERTIES -}; - - -sapi_module_struct activescript_sapi_module = { - "activescript", /* name */ - "ActiveScript", /* pretty name */ - - php_activescript_startup, /* startup */ - php_module_shutdown_wrapper, /* shutdown */ - - NULL, /* activate */ - NULL, /* deactivate */ - - sapi_activescript_ub_write, /* unbuffered write */ - NULL, /* flush */ - NULL, /* get uid */ - NULL, /* getenv */ - - zend_error, /* error handler */ - - sapi_activescript_header_handler, /* header handler */ - sapi_activescript_send_headers, /* send headers handler */ - NULL, /* send header handler */ - - NULL, /* read POST data */ - sapi_activescript_read_cookies, /* read Cookies */ - - sapi_activescript_register_server_variables, /* register server variables */ - NULL, /* Log message */ - - STANDARD_SAPI_MODULE_PROPERTIES -}; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - module_handle = hinstDLL; - - tsrm_startup(128, 32, TSRM_ERROR_LEVEL_CORE, "C:\\TSRM.log"); - - /* useful behaviour for the host: we take the application path - * and use that dir as the override for the php.ini, so that - * we don't pick up a global .ini file */ - { - char module_dir[MAXPATHLEN]; - char *slash; - - GetModuleFileName(0, module_dir, sizeof(module_dir)); - slash = strrchr(module_dir, '\\'); - if (slash) { - slash[1] = '\0'; - } - - activescript_sapi_module.php_ini_path_override = strdup(module_dir); - } - - sapi_startup(&activescript_sapi_module); - if (activescript_sapi_module.startup) { - activescript_sapi_module.startup(&sapi_module); - } - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - //OutputDebugString("THREAD_DETACH\n"); - ts_free_thread(); - break; - case DLL_PROCESS_DETACH: - if (activescript_sapi_module.shutdown) { - activescript_sapi_module.shutdown(&sapi_module); - } - //OutputDebugString("PROCESS_DETACH\n"); - sapi_shutdown(); - tsrm_shutdown(); - break; - } - return TRUE; -} - - diff --git a/sapi/activescript/php5activescript.def b/sapi/activescript/php5activescript.def deleted file mode 100644 index f111b68db7..0000000000 --- a/sapi/activescript/php5activescript.def +++ /dev/null @@ -1,5 +0,0 @@ -EXPORTS -DllCanUnloadNow PRIVATE -DllGetClassObject PRIVATE -DllRegisterServer PRIVATE -DllUnregisterServer PRIVATE diff --git a/sapi/activescript/php5activescript.dsp b/sapi/activescript/php5activescript.dsp deleted file mode 100644 index 3f7687e50f..0000000000 --- a/sapi/activescript/php5activescript.dsp +++ /dev/null @@ -1,185 +0,0 @@ -# Microsoft Developer Studio Project File - Name="php5activescript" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=php5activescript - Win32 Debug_TS
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "php5activescript.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "php5activescript.mak" CFG="php5activescript - Win32 Debug_TS"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "php5activescript - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "php5activescript - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "php5activescript - Win32 Release_TS_inline" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "php5activescript - Win32 Release_TSDbg" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "php5activescript - Win32 Debug_TS"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug_TS"
-# PROP BASE Intermediate_Dir "Debug_TS"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\Debug_TS"
-# PROP Intermediate_Dir "Debug_TS"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\win32" /I "..\..\Zend" /I "..\.." /I "..\..\main" /I "..\..\TSRM" /D "_DEBUG" /D "COMPILE_LIBZEND" /D ZEND_DEBUG=1 /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_MBCS" /D ACTIVEPHP_OBJECT_SAFETY=1 /FR /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x40d /d "_DEBUG"
-# ADD RSC /l 0x40d /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts_debug.lib /nologo /version:4.0 /dll /debug /machine:I386 /nodefaultlib:"libcmt" /pdbtype:sept /libpath:"..\..\Debug_TS"
-
-!ELSEIF "$(CFG)" == "php5activescript - Win32 Release_TS"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release_TS"
-# PROP BASE Intermediate_Dir "Release_TS"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\Release_TS"
-# PROP Intermediate_Dir "Release_TS"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "...\..\include" /I "..\..\win32" /I "..\..\Zend" /I "..\.." /I "..\..\main" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_MBCS" /D ACTIVEPHP_OBJECT_SAFETY=1 /FR /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x40d /d "NDEBUG"
-# ADD RSC /l 0x40d /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /version:4.0 /dll /machine:I386 /libpath:"..\..\Release_TS"
-
-!ELSEIF "$(CFG)" == "php5activescript - Win32 Release_TS_inline"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "php5activescript___Win32_Release_TS_inline"
-# PROP BASE Intermediate_Dir "php5activescript___Win32_Release_TS_inline"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\Release_TS_inline"
-# PROP Intermediate_Dir "Release_TS_inline"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "...\..\include" /I "..\..\win32" /I "..\..\Zend" /I "..\.." /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /FR /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "...\..\include" /I "..\..\win32" /I "..\..\Zend" /I "..\.." /I "..\..\main" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_MBCS" /D ACTIVEPHP_OBJECT_SAFETY=1 /FR /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x40d /d "NDEBUG"
-# ADD RSC /l 0x40d /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386 /libpath:"..\..\Release_TS"
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /version:4.0 /dll /machine:I386 /libpath:"..\..\Release_TS_inline"
-
-!ELSEIF "$(CFG)" == "php5activescript - Win32 Release_TSDbg"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "php5activescript___Win32_Release_TSDbg"
-# PROP BASE Intermediate_Dir "php5activescript___Win32_Release_TSDbg"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\Release_TSDbg"
-# PROP Intermediate_Dir "Release_TSDbg"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "...\..\include" /I "..\..\win32" /I "..\..\Zend" /I "..\.." /I "..\..\main" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_MBCS" /FR /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "...\..\include" /I "..\..\win32" /I "..\..\Zend" /I "..\.." /I "..\..\main" /I "..\..\TSRM" /D "NDEBUG" /D ZEND_DEBUG=0 /D "_WINDOWS" /D "_USRDLL" /D "PHP5ISAPI_EXPORTS" /D "MSVC5" /D "ZTS" /D "ZEND_WIN32" /D "PHP_WIN32" /D "WIN32" /D "_MBCS" /D ACTIVEPHP_OBJECT_SAFETY=1 /FR /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x40d /d "NDEBUG"
-# ADD RSC /l 0x40d /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /version:4.0 /dll /machine:I386 /libpath:"..\..\Release_TS"
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib wsock32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /version:4.0 /dll /debug /machine:I386 /libpath:"..\..\Release_TSDbg"
-
-!ENDIF
-
-# Begin Target
-
-# Name "php5activescript - Win32 Debug_TS"
-# Name "php5activescript - Win32 Release_TS"
-# Name "php5activescript - Win32 Release_TS_inline"
-# Name "php5activescript - Win32 Release_TSDbg"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\classfactory.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\php5activescript.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\php5activescript.def
-# End Source File
-# Begin Source File
-
-SOURCE=.\scriptengine.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\php5activescript.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\php5as_classfactory.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\php5as_scriptengine.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/sapi/activescript/php5activescript.h b/sapi/activescript/php5activescript.h deleted file mode 100644 index ba8be9b51e..0000000000 --- a/sapi/activescript/php5activescript.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -extern zend_module_entry php_activescript_module; -extern sapi_module_struct activescript_sapi_module; -extern HINSTANCE module_handle; -extern void activescript_error_func(int type, const char *error_msg, ...); -extern void activescript_error_handler(int type, const char *error_filename, - const uint error_lineno, const char *format, va_list args); diff --git a/sapi/activescript/php5as_classfactory.h b/sapi/activescript/php5as_classfactory.h deleted file mode 100644 index 048d38b7e5..0000000000 --- a/sapi/activescript/php5as_classfactory.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -/* IClassFactory Implementation */ - -#include <unknwn.h> - -// {CF108A38-59A9-468a-AF45-1368D7855DAE} -DEFINE_GUID(CLSID_PHPActiveScriptEngine, -0xcf108a38, 0x59a9, 0x468a, 0xaf, 0x45, 0x13, 0x68, 0xd7, 0x85, 0x5d, 0xae); - -// {AD504760-D6B9-4537-AEAC-512FFB359009} -DEFINE_GUID(CLSID_PHPActiveScriptEngineMarshal, -0xad504760, 0xd6b9, 0x4537, 0xae, 0xac, 0x51, 0x2f, 0xfb, 0x35, 0x90, 0x9); - -#if 0 -/* this was for PHP 4 */ -// {A0AD8E7A-95EC-4819-986F-78D93895F2AE} -DEFINE_GUID(CLSID_PHPActiveScriptEngine, -0xa0ad8e7a, 0x95ec, 0x4819, 0x98, 0x6f, 0x78, 0xd9, 0x38, 0x95, 0xf2, 0xae); -#endif - -class TPHPClassFactory: - public IClassFactory -{ -protected: - volatile LONG m_refcount; - - static volatile LONG factory_count; - static volatile LONG object_count; - -public: /* IUnknown */ - STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject); - STDMETHODIMP_(DWORD) AddRef(void); - STDMETHODIMP_(DWORD) Release(void); -public: /* IClassFactory */ - STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppvObject); - STDMETHODIMP LockServer(BOOL fLock); - - TPHPClassFactory(); - ~TPHPClassFactory(); - - static void AddToObjectCount(void); - static void RemoveFromObjectCount(void); - static int CanUnload(void); -}; - diff --git a/sapi/activescript/php5as_scriptengine.h b/sapi/activescript/php5as_scriptengine.h deleted file mode 100644 index 55019743b8..0000000000 --- a/sapi/activescript/php5as_scriptengine.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -#include <activscp.h> -#include <objsafe.h> -#include "zend.h" - -#if 0 -#define ACTIVEPHP_THREADING_MODE COINIT_MULTITHREADED -#else -#define ACTIVEPHP_THREADING_MODE COINIT_APARTMENTTHREADED -#endif - -#define WM_ACTIVEPHP_SERIALIZE WM_USER + 200 - -enum activephp_engine_func { /* if you change the order, change marshal.cpp too */ - APHP_ParseScriptText, - APHP_InitNew, - APHP_AddNamedItem, - APHP_SetScriptState, - APHP_GetScriptDispatch, - APHP_Close, - APHP_AddTypeLib, - APHP_AddScriptlet, - APHP_ParseProcedureText, - APHP__Max -}; - -HRESULT marshal_call(class TPHPScriptingEngine *engine, enum activephp_engine_func func, int nargs, ...); -HRESULT marshal_stub(LPARAM lparam); - -class TPHPScriptingEngine: - public IActiveScript, - public IActiveScriptParse, - public IActiveScriptParseProcedure, - public IObjectSafety, - public IDispatch -#if 0 - , public IMarshal -#endif -{ -public: - volatile LONG m_refcount; - IActiveScriptSite *m_pass; - SCRIPTSTATE m_scriptstate; - - void add_to_global_namespace(IDispatch *disp, DWORD flags, char *name TSRMLS_DC); - - THREAD_T m_enginethread, m_basethread; - HashTable m_frags; - ULONG m_lambda_count; - DWORD m_gitcookie, m_asscookie; - HWND m_queue; - - int m_done_init; - - int m_in_main, m_stop_main; - - void do_clone(TPHPScriptingEngine *src); -void setup_engine_state(void); - int create_id(OLECHAR *name, DISPID *dispid TSRMLS_DC); - - char *m_names[1024]; - int m_lens[1024]; - int m_ids; - -public: /* IUnknown */ - STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject); - STDMETHODIMP_(DWORD) AddRef(void); - STDMETHODIMP_(DWORD) Release(void); -public: /* IActiveScript */ - STDMETHODIMP SetScriptSite( - /* [in] */ IActiveScriptSite *pass); - - STDMETHODIMP GetScriptSite( - /* [in] */ REFIID riid, - /* [iid_is][out] */ void **ppvObject); - - STDMETHODIMP SetScriptState( - /* [in] */ SCRIPTSTATE ss); - - STDMETHODIMP GetScriptState( - /* [out] */ SCRIPTSTATE *pssState); - - STDMETHODIMP Close( void); - - STDMETHODIMP AddNamedItem( - /* [in] */ LPCOLESTR pstrName, - /* [in] */ DWORD dwFlags); - - STDMETHODIMP AddTypeLib( - /* [in] */ REFGUID rguidTypeLib, - /* [in] */ DWORD dwMajor, - /* [in] */ DWORD dwMinor, - /* [in] */ DWORD dwFlags); - - STDMETHODIMP GetScriptDispatch( - /* [in] */ LPCOLESTR pstrItemName, - /* [out] */ IDispatch **ppdisp); - - STDMETHODIMP GetCurrentScriptThreadID( - /* [out] */ SCRIPTTHREADID *pstidThread); - - STDMETHODIMP GetScriptThreadID( - /* [in] */ DWORD dwWin32ThreadId, - /* [out] */ SCRIPTTHREADID *pstidThread); - - STDMETHODIMP GetScriptThreadState( - /* [in] */ SCRIPTTHREADID stidThread, - /* [out] */ SCRIPTTHREADSTATE *pstsState); - - STDMETHODIMP InterruptScriptThread( - /* [in] */ SCRIPTTHREADID stidThread, - /* [in] */ const EXCEPINFO *pexcepinfo, - /* [in] */ DWORD dwFlags); - - STDMETHODIMP Clone( - /* [out] */ IActiveScript **ppscript); - -public: /* IActiveScriptParse */ - STDMETHODIMP InitNew( void); - - STDMETHODIMP AddScriptlet( - /* [in] */ LPCOLESTR pstrDefaultName, - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ LPCOLESTR pstrSubItemName, - /* [in] */ LPCOLESTR pstrEventName, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ BSTR *pbstrName, - /* [out] */ EXCEPINFO *pexcepinfo); - - STDMETHODIMP ParseScriptText( - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ IUnknown *punkContext, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ VARIANT *pvarResult, - /* [out] */ EXCEPINFO *pexcepinfo); -public: /* IActiveScriptParseProcedure */ - STDMETHODIMP ParseProcedureText( - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrFormalParams, - /* [in] */ LPCOLESTR pstrProcedureName, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ IUnknown *punkContext, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ IDispatch **ppdisp); - -public: /* IObjectSafety */ - STDMETHODIMP GetInterfaceSafetyOptions( - /* [in] */ REFIID riid, // Interface that we want options for - /* [out] */ DWORD *pdwSupportedOptions, // Options meaningful on this interface - /* [out] */ DWORD *pdwEnabledOptions); // current option values on this interface - - STDMETHODIMP SetInterfaceSafetyOptions( - /* [in] */ REFIID riid, // Interface to set options for - /* [in] */ DWORD dwOptionSetMask, // Options to change - /* [in] */ DWORD dwEnabledOptions); // New option values -#if 0 -public: /* IMarshal */ - STDMETHODIMP GetUnmarshalClass( - REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid); - STDMETHODIMP GetMarshalSizeMax( - REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, ULONG *pSize); - STDMETHODIMP MarshalInterface( - IStream *pStm, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshflags); - STDMETHODIMP UnmarshalInterface( - IStream *pStm, REFIID riid, void **ppv); - STDMETHODIMP ReleaseMarshalData(IStream *pStm); - STDMETHODIMP DisconnectObject(DWORD dwReserved); -#endif - -public: /* IDispatch */ - STDMETHODIMP GetIDsOfNames( REFIID riid, OLECHAR **rgszNames, unsigned int cNames, LCID lcid, DISPID *rgDispId); - STDMETHODIMP Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS FAR* pdp, VARIANT FAR* pvarRes, EXCEPINFO FAR* pei, - unsigned int FAR* puArgErr); - STDMETHODIMP GetTypeInfoCount(unsigned int * pctinfo); - STDMETHODIMP GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo **ppTInfo); - -public: - TPHPScriptingEngine(); - ~TPHPScriptingEngine(); - -}; - -IUnknown *create_scripting_engine(TPHPScriptingEngine *tobecloned); - diff --git a/sapi/activescript/scriptengine.cpp b/sapi/activescript/scriptengine.cpp deleted file mode 100644 index 3838169486..0000000000 --- a/sapi/activescript/scriptengine.cpp +++ /dev/null @@ -1,2039 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ -/* $Id$ */ - -/* Implementation Notes: - * - * PHP stores scripting engine state in thread-local storage. That means - * that we need to create a dedicated thread per-engine so that a host can - * use more than one engine object per thread. - * - * There are some interesting synchronization issues: Anything to do with - * running script in the PHP/Zend engine must take place on the engine - * thread. Likewise, calling back to the host must take place on the base - * thread - the thread that set the script site. - * */ - -#define _WIN32_DCOM -#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS - -#include "php.h" -extern "C" { -#include "php_main.h" -#include "SAPI.h" -#include "zend.h" -#include "zend_execute.h" -#include "zend_compile.h" -#include "php_globals.h" -#include "php_variables.h" -#include "php_ini.h" -#include "php5activescript.h" -#include "ext/com_dotnet/php_com_dotnet.h" -#include "ext/com_dotnet/php_com_dotnet_internal.h" -#include "zend_exceptions.h" -} -#include "php_ticks.h" -#include "php5as_scriptengine.h" -#include "php5as_classfactory.h" -#include <objbase.h> -#undef php_win_err - -static int clone_frags(void *pDest, void *arg TSRMLS_DC); - -#define ENGINE_THREAD_ONLY(type, method) \ - if (tsrm_thread_id() != m_enginethread) { \ - trace("WRONG THREAD !! " #type "::" #method "\n"); \ - return RPC_E_WRONG_THREAD; \ - } \ - trace("[direct] " #type "::" #method "\n"); - -#define ASS_CALL_(ret, eng, method, args) \ - if (tsrm_thread_id() == eng->m_basethread) { \ - trace("Calling [direct] m_pass->" #method "\n"); \ - ret = eng->m_pass->method args; \ - } else { \ - IActiveScriptSite *ass; \ - trace("Calling [marshall] m_pass->" #method "\n"); \ - ret = GIT_get(eng->m_asscookie, IID_IActiveScriptSite, (void**)&ass); \ - if (SUCCEEDED(ret)) { \ - ret = ass->method args; \ - ass->Release(); \ - } \ - } \ - trace("--- done calling m_pass->" #method "\n"); -#define ASS_CALL(ret, method, args) ASS_CALL_(ret, this, method, args) - -/* {{{ trace */ -static inline void trace(char *fmt, ...) -{ - va_list ap; - char buf[4096]; - - sprintf(buf, "T=%08x ", tsrm_thread_id()); - OutputDebugString(buf); - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - - OutputDebugString(buf); - - va_end(ap); -} -/* }}} */ -/* {{{ scriptstate_to_string */ -static const char *scriptstate_to_string(SCRIPTSTATE ss) -{ - switch(ss) { - case SCRIPTSTATE_UNINITIALIZED: return "SCRIPTSTATE_UNINITIALIZED"; - case SCRIPTSTATE_INITIALIZED: return "SCRIPTSTATE_INITIALIZED"; - case SCRIPTSTATE_STARTED: return "SCRIPTSTATE_STARTED"; - case SCRIPTSTATE_CONNECTED: return "SCRIPTSTATE_CONNECTED"; - case SCRIPTSTATE_DISCONNECTED: return "SCRIPTSTATE_DISCONNECTED"; - case SCRIPTSTATE_CLOSED: return "SCRIPTSTATE_CLOSED"; - default: - return "unknown"; - } -} -/* }}} */ -/* {{{ TWideString */ -/* This class helps manipulate strings from OLE. - * It does not use emalloc, so it is better suited for passing pointers - * between threads. */ -class TWideString { - public: - LPOLESTR m_ole; - char *m_ansi; - int m_ansi_strlen; - - TWideString(LPOLESTR olestr) { - m_ole = olestr; - m_ansi = NULL; - m_ansi_strlen = 0; - } - TWideString(LPCOLESTR olestr) { - m_ole = (LPOLESTR)olestr; - m_ansi = NULL; - m_ansi_strlen = 0; - } - - ~TWideString() { - if (m_ansi) { - CoTaskMemFree(m_ansi); - } - m_ansi = NULL; - m_ansi_strlen = 0; - } - - char *safe_ansi_string() { - char *ret = ansi_string(); - if (ret == NULL) - return "<NULL>"; - return ret; - } - - int ansi_len(void) { - /* force conversion if it has not already occurred */ - if (m_ansi == NULL) - ansi_string(); - return m_ansi_strlen; - } - - static BSTR bstr_from_ansi(char *ansi) { - OLECHAR *ole = NULL; - BSTR bstr = NULL; - - int req = MultiByteToWideChar(CP_ACP, 0, ansi, -1, NULL, 0); - if (req) { - ole = (OLECHAR*)CoTaskMemAlloc((req + 1) * sizeof(OLECHAR)); - if (ole) { - req = MultiByteToWideChar(CP_ACP, 0, ansi, -1, ole, req); - req--; - ole[req] = 0; - - bstr = SysAllocString(ole); - CoTaskMemFree(ole); - } - } - return bstr; - } - - char *ansi_string(void) - { - if (m_ansi) - return m_ansi; - - if (m_ole == NULL) - return NULL; - - int bufrequired = WideCharToMultiByte(CP_ACP, 0, m_ole, -1, NULL, 0, NULL, NULL); - if (bufrequired) { - - m_ansi = (char*)CoTaskMemAlloc(bufrequired + 1); - if (m_ansi) { - m_ansi_strlen = WideCharToMultiByte(CP_ACP, 0, m_ole, -1, m_ansi, bufrequired + 1, NULL, NULL); - - if (m_ansi_strlen) { - m_ansi_strlen--; - } else { - trace("conversion failed with return code %08x\n", GetLastError()); - } - } - if (m_ansi) { - m_ansi[m_ansi_strlen] = 0; - } - } - return m_ansi; - } -}; -/* }}} */ - -/* {{{ code fragment structures */ -enum fragtype { - FRAG_MAIN, - FRAG_SCRIPTLET, - FRAG_PROCEDURE -}; - -typedef struct { - enum fragtype fragtype; - zend_op_array *opcodes; - char *code; - int persistent; /* should be retained for Clone */ - int executed; /* for "main" */ - char *functionname; - unsigned int codelen; - unsigned int starting_line; - TPHPScriptingEngine *engine; - void *ptr; -} code_frag; - -#define FRAG_CREATE_FUNC (char*)-1 -static code_frag *compile_code_fragment( - enum fragtype fragtype, - char *functionname, - LPCOLESTR code, - ULONG starting_line, - EXCEPINFO *excepinfo, - TPHPScriptingEngine *engine - TSRMLS_DC); - -static int execute_code_fragment(code_frag *frag, - VARIANT *varResult, - EXCEPINFO *excepinfo - TSRMLS_DC); -static void free_code_fragment(code_frag *frag TSRMLS_DC); -static code_frag *clone_code_fragment(code_frag *frag, TPHPScriptingEngine *engine TSRMLS_DC); - -/* }}} */ - -/* These functions do some magic so that interfaces can be - * used across threads without worrying about marshalling - * or not marshalling, as appropriate. - * Win95 without DCOM 1.1, and NT SP 2 or lower do not have - * the GIT; so we emulate the GIT using other means. - * If you trace problems back to this code, installing the relevant - * SP should solve them. - * */ -static inline HRESULT GIT_get(DWORD cookie, REFIID riid, void **obj) -{ - IGlobalInterfaceTable *git; - HRESULT ret; - - if (SUCCEEDED(CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, - CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, - (void**)&git))) { - - ret = git->GetInterfaceFromGlobal(cookie, riid, obj); - git->Release(); - return ret; - } - return CoGetInterfaceAndReleaseStream((LPSTREAM)cookie, riid, obj); -} - -static inline HRESULT GIT_put(IUnknown *unk, REFIID riid, DWORD *cookie) -{ - IGlobalInterfaceTable *git; - HRESULT ret; - - if (SUCCEEDED(CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, - CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, - (void**)&git))) { - - ret = git->RegisterInterfaceInGlobal(unk, riid, cookie); - git->Release(); - return ret; - } - return CoMarshalInterThreadInterfaceInStream(riid, unk, (LPSTREAM*)cookie); -} - -static inline HRESULT GIT_revoke(DWORD cookie, IUnknown *unk, int kill) -{ - IGlobalInterfaceTable *git; - HRESULT ret; - - if (SUCCEEDED(CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, - CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, - (void**)&git))) { - - ret = git->RevokeInterfaceFromGlobal(cookie); - git->Release(); - } - /* Kill remote clients */ - if (kill) - return CoDisconnectObject(unk, 0); - return ret; -} - - - -/* {{{ A generic stupid IDispatch implementation */ -class IDispatchImpl: - public IDispatch -{ -protected: - volatile LONG m_refcount; -public: - /* IUnknown */ - STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) { - *ppvObject = NULL; - - if (IsEqualGUID(IID_IDispatch, iid)) { - *ppvObject = (IDispatch*)this; - } else if (IsEqualGUID(IID_IUnknown, iid)) { - *ppvObject = this; - } - if (*ppvObject) { - AddRef(); - return S_OK; - } - return E_NOINTERFACE; - } - - STDMETHODIMP_(DWORD) AddRef(void) { - return InterlockedIncrement(const_cast<long*> (&m_refcount)); - } - - STDMETHODIMP_(DWORD) Release(void) { - DWORD ret = InterlockedDecrement(const_cast<long*> (&m_refcount)); - trace("%08x: IDispatchImpl: release ref count is now %d\n", this, ret); - if (ret == 0) - delete this; - return ret; - } - /* IDispatch */ - STDMETHODIMP GetTypeInfoCount(unsigned int * pctinfo) { - *pctinfo = 0; - trace("%08x: IDispatchImpl: GetTypeInfoCount\n", this); - return S_OK; - } - STDMETHODIMP GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - trace("%08x: IDispatchImpl: GetTypeInfo\n", this); - return DISP_E_BADINDEX; - } - STDMETHODIMP GetIDsOfNames( REFIID riid, OLECHAR **rgszNames, unsigned int cNames, LCID lcid, DISPID *rgDispId) - { - unsigned int i; - trace("%08x: IDispatchImpl: GetIDsOfNames: \n", this); - for (i = 0; i < cNames; i++) { - TWideString name(rgszNames[i]); - trace(" %s\n", name.ansi_string()); - } - trace("----\n"); - return DISP_E_UNKNOWNNAME; - } - STDMETHODIMP Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, - unsigned int FAR* puArgErr) - { - trace("%08x: IDispatchImpl: Invoke dispid %08x\n", this, dispIdMember); - return S_OK; - } - - - IDispatchImpl() { - m_refcount = 1; - } - - virtual ~IDispatchImpl() { - } -}; -/* }}} */ - -STDMETHODIMP TPHPScriptingEngine::GetTypeInfoCount(unsigned int * pctinfo) { - *pctinfo = 0; - trace("%08x: ScriptDispatch: GetTypeInfoCount\n", this); - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::GetTypeInfo( unsigned int iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - trace("%08x: ScriptDispatch: GetTypeInfo\n", this); - return DISP_E_BADINDEX; -} - -static int function_exists(char *name TSRMLS_DC) -{ - int ex; - int l = strlen(name); - char *lcname; - - lcname = zend_str_tolower_dup(name, l); - ex = zend_hash_exists(EG(function_table), lcname, l+1); - efree(lcname); - - return ex; -} - -int TPHPScriptingEngine::create_id(OLECHAR *name, DISPID *dispid TSRMLS_DC) -{ - int ex = 0; - int l; - - if (m_ids >= 1023) { - trace("too many ids\n"); - return 0; - } - - TWideString aname(name); - - if (!function_exists(aname.ansi_string() TSRMLS_CC)) { - trace("no such id %s\n", aname.ansi_string()); - return 0; - } - - /* do we already have an id for this name? */ - int i; - for (i = 0; i < m_ids; i++) { - if (!strcasecmp(m_names[i], aname.ansi_string())) { - trace("already had ID %d for %s\n", i, m_names[i]); - return i; - } - } - - m_lens[m_ids] = aname.ansi_len(); - m_names[m_ids] = aname.ansi_string(); - trace("created ID %d for name %s\n", m_ids, m_names[m_ids]); - aname.m_ansi = NULL; - *dispid = m_ids; - m_ids++; - return 1; -} - -STDMETHODIMP TPHPScriptingEngine::GetIDsOfNames( REFIID riid, OLECHAR **rgszNames, unsigned int cNames, LCID lcid, DISPID *rgDispId) -{ - unsigned int i; - HRESULT ret = S_OK; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) { - trace("GetIDsOfNames called from wrong thread\n"); - return RPC_E_WRONG_THREAD; - } - - trace("%08x: ScriptDispatch: GetIDsOfNames %d names: \n", this, cNames); - for (i = 0; i < cNames; i++) { - if (!create_id(rgszNames[i], &rgDispId[i] TSRMLS_CC)) { - ret = DISP_E_UNKNOWNNAME; - break; - } - } - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS FAR* pdp, VARIANT FAR* pvarRes, EXCEPINFO FAR* pei, - unsigned int FAR* puArgErr) -{ - UINT i; - zval *retval = NULL; - zval ***params = NULL; - HRESULT dummy, ret = DISP_E_MEMBERNOTFOUND; - char *name; - int namelen; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) { - trace("Invoke called from wrong thread\n"); - return RPC_E_WRONG_THREAD; - } - - name = m_names[dispIdMember]; - namelen = m_lens[dispIdMember]; - - trace("%08x: ScriptDispatch: Invoke dispid %08x [%s]\n", this, dispIdMember, name); - /* this code is similar to that of our com_wrapper InvokeEx implementation */ - - /* convert args into zvals. - * Args are in reverse order */ - if (pdp->cArgs) { - params = (zval ***)safe_emalloc(sizeof(zval **), pdp->cArgs, 0); - for (i = 0; i < pdp->cArgs; i++) { - VARIANT *arg; - zval *zarg; - - arg = &pdp->rgvarg[ pdp->cArgs - 1 - i]; - - trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg)); - - ALLOC_INIT_ZVAL(zarg); - php_com_wrap_variant(zarg, arg, CP_ACP TSRMLS_CC); - params[i] = &zarg; - } - } - - trace("arguments processed, prepare to do some work\n"); - - /* TODO: if PHP raises an exception here, we should catch it - * and expose it as a COM exception */ - -#if 0 - if (wFlags & DISPATCH_PROPERTYGET) { - retval = zend_read_property(Z_OBJCE_P(disp->object), disp->object, m_names[dispIdMember], m_lens[dispIdMember]+1, 1 TSRMLS_CC); - } else if (wFlags & DISPATCH_PROPERTYPUT) { - zend_update_property(Z_OBJCE_P(disp->object), disp->object, m_names[dispIdMember], m_lens[dispIdMember]+1, *params[0] TSRMLS_CC); - } else -#endif - if (wFlags & DISPATCH_METHOD) { - zval *zname; - MAKE_STD_ZVAL(zname); - ZVAL_STRINGL(zname, (char*)name, namelen, 1); - trace("invoke function %s\n", Z_STRVAL_P(zname)); - - ASS_CALL(dummy, OnEnterScript, ()); - - zend_try { - - if (SUCCESS == call_user_function_ex(CG(function_table), NULL, zname, - &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) { - ret = S_OK; - trace("we ran it\n"); - } else { - ret = DISP_E_EXCEPTION; - trace("no such function\n"); - } - - } zend_catch { - ret = DISP_E_EXCEPTION; - /* need to populate the exception here */ - trace("bork\n"); - } zend_end_try(); - - ASS_CALL(dummy, OnLeaveScript, ()); - - zval_ptr_dtor(&zname); - } else { - trace("Don't know how to handle this invocation %08x\n", wFlags); - ret = E_UNEXPECTED; - } - - /* release arguments */ - for (i = 0; i < pdp->cArgs; i++) - zval_ptr_dtor(params[i]); - - if (params) - efree(params); - - /* return value */ - if (retval) { - if (pvarRes) { - VariantInit(pvarRes); - trace("setting up return value\n"); - php_com_variant_from_zval(pvarRes, retval, CP_ACP TSRMLS_CC); - } - zval_ptr_dtor(&retval); - } else if (pvarRes) { - VariantInit(pvarRes); - } - - trace("Invocation complete\n"); - - return ret; -} - -/* {{{ This object is used in conjunction with IActiveScriptParseProcedure to - * allow scriptlets to be bound to events. IE uses this for declaring - * event handlers such as onclick="...". - * The compiled code is stored in this object; IE will call - * IDispatch::Invoke when the element is clicked. - * */ -class ScriptProcedureDispatch: - public IDispatchImpl -{ -public: - code_frag *m_frag; - DWORD m_procflags; - TPHPScriptingEngine *m_engine; - DWORD m_gitcookie; - - STDMETHODIMP Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, - unsigned int FAR* puArgErr) - { - TSRMLS_FETCH(); - HRESULT dummy; - - if (m_frag) { - trace("%08x: Procedure Dispatch: Invoke dispid %08x\n", this, dispIdMember); - ASS_CALL_(dummy, m_engine, OnEnterScript, ()); - execute_code_fragment(m_frag, NULL, NULL TSRMLS_CC); - ASS_CALL_(dummy, m_engine, OnLeaveScript, ()); - } - return S_OK; - } - ScriptProcedureDispatch() { - m_refcount = 1; - GIT_put((IDispatch*)this, IID_IDispatch, &m_gitcookie); - } -}; -/* }}} */ - -/* {{{ code fragment management */ -static code_frag *compile_code_fragment( - enum fragtype fragtype, - char *functionname, - LPCOLESTR code, - ULONG starting_line, - EXCEPINFO *excepinfo, - TPHPScriptingEngine *engine - TSRMLS_DC) -{ - zval pv; - int code_offs = 0; - char namebuf[256]; - - code_frag *frag = (code_frag*)CoTaskMemAlloc(sizeof(code_frag)); - memset(frag, 0, sizeof(code_frag)); - - frag->engine = engine; - - /* handle the function name */ - if (functionname) { - int namelen; - if (functionname == FRAG_CREATE_FUNC) { - ULONG n = ++engine->m_lambda_count; - - sprintf(namebuf, "__frag_%08x_%u", engine, n); - functionname = namebuf; - } - - namelen = strlen(functionname); - code_offs = namelen + sizeof("function (){"); - - frag->functionname = (char*)CoTaskMemAlloc((namelen + 1) * sizeof(char)); - memcpy(frag->functionname, functionname, namelen+1); - } - - frag->functionname = functionname; - -trace("%08x: COMPILED FRAG\n", frag); - - frag->codelen = WideCharToMultiByte(CP_ACP, 0, code, -1, NULL, 0, NULL, NULL); - frag->code = (char*)CoTaskMemAlloc(sizeof(char) * (frag->codelen + code_offs + 1)); - - if (functionname) { - sprintf(frag->code, "function %s(){ ", functionname); - } - - frag->codelen = WideCharToMultiByte(CP_ACP, 0, code, -1, frag->code + code_offs, frag->codelen, NULL, NULL) - 1; - - if (functionname) { - frag->codelen += code_offs + 1; - frag->code[frag->codelen-1] = '}'; - frag->code[frag->codelen] = 0; - } - -trace("code to compile is:\ncode_offs=%d func=%s\n%s\n", code_offs, functionname, frag->code); - - frag->fragtype = fragtype; - frag->starting_line = starting_line; - - pv.type = IS_STRING; - pv.value.str.val = frag->code; - pv.value.str.len = frag->codelen; - - frag->opcodes = compile_string(&pv, "fragment" TSRMLS_CC); - - if (frag->opcodes == NULL) { - free_code_fragment(frag TSRMLS_CC); - - if (excepinfo) { - memset(excepinfo, 0, sizeof(EXCEPINFO)); - excepinfo->wCode = 1000; - excepinfo->bstrSource = TWideString::bstr_from_ansi("fragment"); - excepinfo->bstrDescription = TWideString::bstr_from_ansi("Problem while parsing/compiling"); - } - - return NULL; - } - - return frag; -} - -static void free_code_fragment(code_frag *frag TSRMLS_DC) -{ - switch(frag->fragtype) { - case FRAG_PROCEDURE: - if (frag->ptr) { - ScriptProcedureDispatch *disp = (ScriptProcedureDispatch*)frag->ptr; - disp->Release(); - GIT_revoke(disp->m_gitcookie, (IDispatch*)disp, 1); - frag->ptr = NULL; - } - break; - } - - if (frag->opcodes) { - destroy_op_array(frag->opcodes TSRMLS_CC); - frag->opcodes = NULL; - } - - if (frag->functionname) { - CoTaskMemFree(frag->functionname); - frag->functionname = NULL; - } - - CoTaskMemFree(frag->code); - CoTaskMemFree(frag); -} - -static code_frag *clone_code_fragment(code_frag *frag, TPHPScriptingEngine *engine TSRMLS_DC) -{ - zval pv; - code_frag *newfrag = (code_frag*)CoTaskMemAlloc(sizeof(code_frag)); - memset(newfrag, 0, sizeof(code_frag)); - - newfrag->engine = engine; -trace("%08x: CLONED FRAG\n", newfrag); - - newfrag->persistent = frag->persistent; - newfrag->codelen = frag->codelen; - newfrag->code = (char*)CoTaskMemAlloc(sizeof(char) * frag->codelen + 1); - memcpy(newfrag->code, frag->code, frag->codelen + 1); - - if (frag->functionname) { - int namelen = strlen(frag->functionname); - newfrag->functionname = (char*)CoTaskMemAlloc(sizeof(char) * (namelen + 1)); - memcpy(newfrag->functionname, frag->functionname, namelen+1); - } else { - newfrag->functionname = NULL; - } - - newfrag->fragtype = frag->fragtype; - newfrag->starting_line = frag->starting_line; - - pv.type = IS_STRING; - pv.value.str.val = newfrag->code; - pv.value.str.len = newfrag->codelen; - - /* we defer compilation until we are ready to execute, - * as we need the host to AddNamedItem certain autoglobals - * BEFORE we compile */ - newfrag->opcodes = NULL; - - return newfrag; -} - -static int execute_code_fragment(code_frag *frag, - VARIANT *varResult, - EXCEPINFO *excepinfo - TSRMLS_DC) -{ - zval *retval_ptr = NULL; - - if (frag->fragtype == FRAG_MAIN && frag->executed) - return 1; - - /* compiled cloned fragment, JIT */ - if (frag->persistent && frag->opcodes == NULL) { - zval pv; - pv.type = IS_STRING; - pv.value.str.val = frag->code; - pv.value.str.len = frag->codelen; - - frag->opcodes = compile_string(&pv, "fragment" TSRMLS_CC); - - if (!frag->opcodes) { - trace("*** JIT compilation of cloned opcodes failed??"); - return 0; - } - } - - zend_try { - trace("*** Executing code in thread %08x\n", tsrm_thread_id()); - - if (frag->functionname) { - - zval fname; - - fname.type = IS_STRING; - fname.value.str.val = frag->functionname; - fname.value.str.len = strlen(frag->functionname); - - call_user_function_ex(CG(function_table), NULL, &fname, &retval_ptr, 0, NULL, 1, NULL TSRMLS_CC); - - } else { - zend_fcall_info_cache fci_cache; - zend_fcall_info fci; - - memset(&fci, 0, sizeof(fci)); - memset(&fci_cache, 0, sizeof(fci_cache)); - - fci.size = sizeof(fci); - fci.function_table = CG(function_table); - fci.retval_ptr_ptr = &retval_ptr; - fci.no_separation = 1; - - fci_cache.initialized = 1; - fci_cache.function_handler = (zend_function*)frag->opcodes; - frag->opcodes->type = ZEND_USER_FUNCTION; // mini hack - - zend_call_function(&fci, &fci_cache TSRMLS_CC); - - } - } zend_catch { - trace("*** --> caught error while executing\n"); - if (frag->engine->m_in_main) - frag->engine->m_stop_main = 1; - } zend_end_try(); - - if (frag->fragtype == FRAG_MAIN) - frag->executed = 1; - - if (varResult) - VariantInit(varResult); - - if (retval_ptr) { - if (varResult) - php_com_variant_from_zval(varResult, retval_ptr, CP_ACP TSRMLS_CC); - zval_ptr_dtor(&retval_ptr); - } - - return 1; -} - -static void frag_dtor(void *pDest) -{ - TSRMLS_FETCH(); - code_frag *frag = *(code_frag**)pDest; - free_code_fragment(frag TSRMLS_CC); -} -/* }}} */ - -void TPHPScriptingEngine::do_clone(TPHPScriptingEngine *src) -{ - TSRMLS_FETCH(); - zend_hash_apply_with_argument(&src->m_frags, clone_frags, this TSRMLS_CC); -} - -struct engine_startup { - HANDLE evt; - HRESULT ret; - TPHPScriptingEngine *toclone; - TPHPScriptingEngine *localref; -}; - -static WNDCLASS wc = {0}; - -static LRESULT CALLBACK script_thread_msg_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - switch (message) { - case WM_ACTIVEPHP_SERIALIZE: - return marshal_stub(lparam); - - case WM_DESTROY: - PostQuitMessage(0); - return 0; - - default: - return DefWindowProc(hwnd, message, wparam, lparam); - } -} - -static DWORD WINAPI script_thread(LPVOID param) -{ - struct engine_startup *su = (struct engine_startup*)param; - TPHPScriptingEngine *engine; - IUnknown *punk = NULL; - MSG msg; - - trace("firing up engine thread/apartment\n"); - - /* set up COM in this apartment */ - CoInitializeEx(0, COINIT_APARTMENTTHREADED); - - /* create a window for message queueing */ - wc.lpfnWndProc = script_thread_msg_proc; - wc.lpszClassName = "ActivePHP Message Window"; - RegisterClass(&wc); - - /* create the engine state */ - engine = new TPHPScriptingEngine; - - engine->m_enginethread = tsrm_thread_id(); - engine->m_basethread = 0; - engine->m_queue = CreateWindow(wc.lpszClassName, wc.lpszClassName, - 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, NULL, NULL); - - /* marshall it for another apartment */ - engine->QueryInterface(IID_IUnknown, (void**)&punk); - su->ret = GIT_put(punk, IID_IUnknown, &engine->m_gitcookie); - punk->Release(); - su->localref = engine; - - /* do we need to clone ? */ - if (su->toclone) { - engine->do_clone(su->toclone); - } - - /* tell whoever spawned us that we're ready and waiting */ - SetEvent(su->evt); - - /* pump COM messages */ - while (GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - trace("terminating engine thread\n"); - - CoUninitialize(); - - return 0; -} - -IUnknown *create_scripting_engine(TPHPScriptingEngine *tobecloned) -{ - IUnknown *punk = NULL; - struct engine_startup su; - HANDLE hthr; - DWORD thid; - - su.evt = CreateEvent(NULL, TRUE, FALSE, NULL); - su.toclone = tobecloned; - - hthr = CreateThread(NULL, 0, script_thread, &su, 0, &thid); - if (hthr) - CloseHandle(hthr); - - WaitForSingleObject(su.evt, INFINITE); - - if (SUCCEEDED(su.ret)) { - punk = (IUnknown*)(void*)su.localref; - } - - CloseHandle(su.evt); - return punk; -} - -void TPHPScriptingEngine::setup_engine_state(void) -{ - TSRMLS_FETCH(); - - m_enginethread = tsrm_thread_id(); - trace("initializing zend engine on this thread\n"); - - SG(options) |= SAPI_OPTION_NO_CHDIR; - SG(headers_sent) = 1; - SG(request_info).no_headers = 1; - - SG(server_context) = this; - - /* override the default PHP error callback */ - zend_error_cb = activescript_error_handler; - - zend_alter_ini_entry("register_argc_argv", 19, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - - php_request_startup(TSRMLS_C); - PG(during_request_startup) = 0; - zend_hash_init(&m_frags, 0, NULL, frag_dtor, 0); - - m_done_init = 1; - - trace("---- init done\n"); -} - -TPHPScriptingEngine::TPHPScriptingEngine() -{ - TSRMLS_FETCH(); - - /* CTOR */ - - trace("*** NEW this=%08x\n", this); - - m_scriptstate = SCRIPTSTATE_UNINITIALIZED; - m_pass = NULL; - m_in_main = 0; - m_done_init = 0; - m_stop_main = 0; - m_lambda_count = 0; - m_refcount = 1; - m_ids = 0; - TPHPClassFactory::AddToObjectCount(); - - setup_engine_state(); -} - -TPHPScriptingEngine::~TPHPScriptingEngine() -{ - /* DTOR */ - - trace("\n\n *** Engine Destructor Called\n\n"); - - if (m_done_init && m_scriptstate != SCRIPTSTATE_CLOSED) { - Close(); - } - - while (m_ids--) { - CoTaskMemFree(m_names[m_ids]); - } - - TPHPClassFactory::RemoveFromObjectCount(); - - DestroyWindow(m_queue); -} - -/* Set some executor globals and execute a zend_op_array. - * The declaration looks wierd because this can be invoked from - * zend_hash_apply_with_argument */ -static int execute_main(void *pDest, void *arg TSRMLS_DC) -{ - code_frag *frag = *(code_frag**)pDest; - - if (frag->fragtype == FRAG_MAIN && !(frag->engine->m_in_main && frag->engine->m_stop_main)) - execute_code_fragment(frag, NULL, NULL TSRMLS_CC); - - return ZEND_HASH_APPLY_KEEP; -} - -static int clone_frags(void *pDest, void *arg TSRMLS_DC) -{ - code_frag *frag, *src = *(code_frag**)pDest; - TPHPScriptingEngine *engine = (TPHPScriptingEngine*)arg; - - if (src->persistent) { - frag = clone_code_fragment(src, engine TSRMLS_CC); - if (frag) - zend_hash_next_index_insert(&engine->m_frags, &frag, sizeof(code_frag*), NULL); - else - trace("WARNING: clone failed!\n"); - } - - return ZEND_HASH_APPLY_KEEP; -} - -/* Only call this in the context of the engine thread, or you'll be sorry. - * - * When SCRIPTITEM_GLOBALMEMBERS is set, we're only adding COM objects to the namespace. - * We could add *all* properties, but I don't like this idea; what if the value changes - * while the page is running? We'd be left with stale data. - * */ - -static inline void make_auto_global(char *name, zval *val TSRMLS_DC) -{ - int namelen = strlen(name); -trace("make_auto_global %s\n", name); - zend_register_auto_global(name, namelen, NULL TSRMLS_CC); - zend_auto_global_disable_jit(name, namelen TSRMLS_CC); - ZEND_SET_SYMBOL(&EG(symbol_table), name, val); -} - -void TPHPScriptingEngine::add_to_global_namespace(IDispatch *disp, DWORD flags, char *name TSRMLS_DC) -{ - zval *val; - ITypeInfo *typ; - int i; - unsigned int namelen; - FUNCDESC *func; - BSTR funcname; - TYPEATTR *attr; - DISPPARAMS dispparams; - VARIANT vres; - ITypeInfo *rettyp; - TYPEATTR *retattr; - -trace("Add %s to global namespace\n", name); - - MAKE_STD_ZVAL(val); - php_com_wrap_dispatch(val, disp, CP_ACP TSRMLS_CC); - - if (val == NULL) { - disp->Release(); - return; - } - - make_auto_global(name, val TSRMLS_CC); - - if ((flags & SCRIPTITEM_GLOBALMEMBERS) == 0) { - disp->Release(); - return; - } - - /* Enumerate properties and add those too */ - if (FAILED(disp->GetTypeInfo(0, 0, &typ))) { - disp->Release(); - return; - } - - if (SUCCEEDED(typ->GetTypeAttr(&attr))) { - for (i = 0; i < attr->cFuncs; i++) { - if (FAILED(typ->GetFuncDesc(i, &func))) - continue; - - /* Look at its type */ - if (func->invkind == INVOKE_PROPERTYGET - && VT_PTR == func->elemdescFunc.tdesc.vt - && VT_USERDEFINED == func->elemdescFunc.tdesc.lptdesc->vt - && SUCCEEDED(typ->GetRefTypeInfo(func->elemdescFunc.tdesc.lptdesc->hreftype, &rettyp))) - { - if (SUCCEEDED(rettyp->GetTypeAttr(&retattr))) { - if (retattr->typekind == TKIND_DISPATCH) { - /* It's dispatchable */ - - /* get the value */ - dispparams.cArgs = 0; - dispparams.cNamedArgs = 0; - VariantInit(&vres); - - if (SUCCEEDED(disp->Invoke(func->memid, IID_NULL, 0, func->invkind, - &dispparams, &vres, NULL, NULL))) { - - /* Get its dispatch */ - IDispatch *sub = NULL; - - if (V_VT(&vres) == VT_UNKNOWN) - V_UNKNOWN(&vres)->QueryInterface(IID_IDispatch, (void**)&sub); - else if (V_VT(&vres) == VT_DISPATCH) - sub = V_DISPATCH(&vres); - - if (sub) { - /* find out its name */ - typ->GetDocumentation(func->memid, &funcname, NULL, NULL, NULL); - name = php_com_olestring_to_string(funcname, &namelen, CP_ACP, 0); - - /* add to namespace */ - zval *subval; - - MAKE_STD_ZVAL(subval); - - php_com_wrap_dispatch(subval, sub, CP_ACP TSRMLS_CC); - if (subval) { - make_auto_global(name, subval TSRMLS_CC); - } - - efree(name); - SysFreeString(funcname); - } - VariantClear(&vres); - } - } - rettyp->ReleaseTypeAttr(retattr); - } - rettyp->Release(); - } - typ->ReleaseFuncDesc(func); - } - typ->ReleaseTypeAttr(attr); - } - disp->Release(); -} - -STDMETHODIMP_(DWORD) TPHPScriptingEngine::AddRef(void) -{ - DWORD ret; - ret = InterlockedIncrement(const_cast<long*> (&m_refcount)); - trace("AddRef --> %d\n", ret); - return ret; -} - -STDMETHODIMP_(DWORD) TPHPScriptingEngine::Release(void) -{ - DWORD ret = InterlockedDecrement(const_cast<long*> (&m_refcount)); - if (ret == 0) { - trace("%08x: Release: zero refcount, destroy the engine!\n", this); - delete this; - } - trace("Release --> %d\n", ret); - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::QueryInterface(REFIID iid, void **ppvObject) -{ - *ppvObject = NULL; - - if (IsEqualGUID(IID_IActiveScript, iid)) { - *ppvObject = (IActiveScript*)this; - } else if (IsEqualGUID(IID_IActiveScriptParse, iid)) { - *ppvObject = (IActiveScriptParse*)this; - } else if (IsEqualGUID(IID_IActiveScriptParseProcedure, iid)) { - *ppvObject = (IActiveScriptParseProcedure*)this; - } else if (IsEqualGUID(IID_IObjectSafety, iid)) { - *ppvObject = (IObjectSafety*)this; - } else if (IsEqualGUID(IID_IUnknown, iid)) { - *ppvObject = this; - } else if (IsEqualGUID(IID_IDispatch, iid)) { - *ppvObject = (IDispatch*)this; - } else { - LPOLESTR guidw; - StringFromCLSID(iid, &guidw); - { - TWideString guid(guidw); - trace("%08x: QueryInterface for unsupported %s\n", this, guid.ansi_string()); - } - CoTaskMemFree(guidw); - } - if (*ppvObject) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - -/* This is called by the host to set the scrite site. - * It also defines the base thread. */ -STDMETHODIMP TPHPScriptingEngine::SetScriptSite(IActiveScriptSite *pass) -{ - HRESULT ret = S_OK; - TSRMLS_FETCH(); - - if (m_pass && pass) { - trace("SetScriptSite: we're already set\n"); - return E_FAIL; - } - - trace("%08x: SetScriptSite(%08x) -----> Base thread is %08x\n", this, pass, tsrm_thread_id()); - - if (pass) { - m_basethread = tsrm_thread_id(); - } - - if (m_pass) { - trace("killing off ass cookie\n"); - GIT_revoke(m_asscookie, m_pass, 0); - m_pass->Release(); - m_pass = NULL; - } - - if (pass == NULL) { - trace("Closing down site; we should have no references to objects from the host\n" - " m_pass=%08x\n What about named items??\n", - m_pass); - } - - if (pass) { - trace("taking a ref on pass\n"); - ret = pass->QueryInterface(IID_IActiveScriptSite, (void**)&m_pass); - trace("----> %s", php_win_err(ret)); - - if (SUCCEEDED(ret)) { - GIT_put(m_pass, IID_IActiveScriptSite, &m_asscookie); - SetScriptState(SCRIPTSTATE_INITIALIZED); - } - } - - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::GetScriptSite(REFIID riid, void **ppvObject) -{ - HRESULT ret = S_FALSE; - - trace("%08x: GetScriptSite()\n", this); - - if (m_pass) { - ASS_CALL(ret, QueryInterface, (riid, ppvObject)) - } - - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::SetScriptState(SCRIPTSTATE ss) -{ - HRESULT dummy = E_UNEXPECTED; - int start_running = 0; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_SetScriptState, 1, ss); - - trace("%08x: SetScriptState(current=%s, new=%s)\n", - this, - scriptstate_to_string(m_scriptstate), - scriptstate_to_string(ss)); - - if (m_scriptstate == SCRIPTSTATE_INITIALIZED && (ss == SCRIPTSTATE_STARTED || ss == SCRIPTSTATE_CONNECTED)) - start_running = 1; - - m_scriptstate = ss; - - if (start_running) { - /* run "main()", as described in the docs */ - ASS_CALL(dummy, OnEnterScript, ()); - trace("%08x: apply execute main to m_frags\n", this); - m_in_main = 1; - m_stop_main = 0; - zend_hash_apply_with_argument(&m_frags, execute_main, this TSRMLS_CC); - m_in_main = 0; - trace("%08x: --- done execute main\n", this); - ASS_CALL(dummy, OnLeaveScript, ()); - } - - /* inform host/site of the change */ - if (m_pass) { -#if 0 - if (ss == SCRIPTSTATE_INITIALIZED) { - VARIANT varRes; - VariantInit(&varRes); - -// ASS_CALL(dummy, OnScriptTerminate, (&varRes, NULL)); - } -#endif - - ASS_CALL(dummy, OnStateChange, (m_scriptstate)); - } - - - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::GetScriptState(SCRIPTSTATE *pssState) -{ - trace("%08x: GetScriptState(current=%s)\n", this, scriptstate_to_string(m_scriptstate)); - *pssState = m_scriptstate; - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::Close(void) -{ - TSRMLS_FETCH(); - - trace("Close() refcount = %d\n", m_refcount); - - if (m_scriptstate == SCRIPTSTATE_CLOSED) - return E_UNEXPECTED; - - if (m_done_init) { - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_Close, 0); - - m_done_init = 0; - m_scriptstate = SCRIPTSTATE_CLOSED; - zend_hash_destroy(&m_frags); - php_request_shutdown(NULL); - m_enginethread = 0; - } - - - if (m_pass && tsrm_thread_id() == m_basethread) { - m_pass->OnStateChange(m_scriptstate); - } - - trace("%08x: release site \n", this); - - if (m_pass && tsrm_thread_id() == m_basethread) { - m_pass->Release(); - m_pass = NULL; - } - - return S_OK; -} - -/* The Host uses this to add objects to the global namespace. Some objects are - * intended to have their child properties globally visible, so we add those to - * the global namespace too. */ - -STDMETHODIMP TPHPScriptingEngine::AddNamedItem(LPCOLESTR pstrName, DWORD dwFlags) -{ - HRESULT res; - IUnknown *punk = NULL; - ITypeInfo *ti = NULL; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_AddNamedItem, 2, pstrName, dwFlags); - - TWideString name(pstrName); - trace("AddNamedItem: %s (%08x) m_pass=%08x\n", name.ansi_string(), dwFlags, m_pass); - - ASS_CALL(res, GetItemInfo, (pstrName, SCRIPTINFO_IUNKNOWN, &punk, &ti)); - - if (SUCCEEDED(res)) { - IDispatch *disp = NULL; - - trace("ADD_NAMED_ITEM\n"); - - res = punk->QueryInterface(IID_IDispatch, (void**)&disp); - if (SUCCEEDED(res) && disp) { - add_to_global_namespace(disp, dwFlags, name.ansi_string() TSRMLS_CC); - disp->Release(); - } else { - trace("Ouch: failed to get IDispatch for %s from GIT '%s'\n", name.ansi_string(), php_win_err(res)); - } - - } else { - trace("failed to get named item, %s", php_win_err(res)); - } - return res; -} - -/* Bind to a type library */ -STDMETHODIMP TPHPScriptingEngine::AddTypeLib( - /* [in] */ REFGUID rguidTypeLib, - /* [in] */ DWORD dwMajor, - /* [in] */ DWORD dwMinor, - /* [in] */ DWORD dwFlags) -{ - HRESULT ret; - ITypeLib *TypeLib; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_AddTypeLib, 4, rguidTypeLib, dwMajor, dwMinor, dwFlags); - - ENGINE_THREAD_ONLY(IActiveScript, AddTypeLib); - - trace("AddTypeLib\n"); - ret = LoadRegTypeLib(rguidTypeLib, (USHORT)dwMajor, (USHORT)dwMinor, LANG_NEUTRAL, &TypeLib); - - if (SUCCEEDED(ret)) { - php_com_import_typelib(TypeLib, CONST_CS, CP_ACP TSRMLS_CC); - TypeLib->Release(); - } - - - return ret; -} - -/* Returns an object representing the PHP Scripting Engine. - * Optionally, a client can request a particular item directly. - * For the moment, we only do the bare minimum amount of work - * for the engine to work correctly; we can flesh out this part - * a little later. */ -STDMETHODIMP TPHPScriptingEngine::GetScriptDispatch( - /* [in] */ LPCOLESTR pstrItemName, - /* [out] */ IDispatch **ppdisp) -{ - zend_function *func = NULL; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) { - return marshal_call(this, APHP_GetScriptDispatch, 2, pstrItemName, ppdisp); - } - - *ppdisp = NULL; - - if (pstrItemName != NULL) { - zval **tmp; - TWideString itemname(pstrItemName); - trace("GetScriptDispatch %s\n", itemname.ansi_string()); - - /* Get that item from the global namespace. - * If it is an object, export it as a dispatchable object. - * */ - - if (zend_hash_find(&EG(symbol_table), itemname.ansi_string(), - itemname.ansi_len() + 1, (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_OBJECT) { - *ppdisp = php_com_wrapper_export(*tmp TSRMLS_CC); - } - } else if (zend_hash_find(EG(function_table), itemname.ansi_string(), - itemname.ansi_len() + 1, (void**)&func) == SUCCESS) { - trace("The host wants a function, but we don't have one\n"); - } - - } else { - trace("GetScriptDispatch NULL\n"); - /* This object represents PHP global namespace */ - *ppdisp = (IDispatch*)this; - } - - - if (*ppdisp) { - return S_OK; - } - return S_FALSE; -} - -STDMETHODIMP TPHPScriptingEngine::GetCurrentScriptThreadID( - /* [out] */ SCRIPTTHREADID *pstidThread) -{ - trace("%08x: GetCurrentScriptThreadID()\n", this); - *pstidThread = GetCurrentThreadId();//m_enginethread; - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::GetScriptThreadID( - /* [in] */ DWORD dwWin32ThreadId, - /* [out] */ SCRIPTTHREADID *pstidThread) -{ - trace("%08x: GetScriptThreadID()\n", this); - *pstidThread = dwWin32ThreadId; - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::GetScriptThreadState( - /* [in] */ SCRIPTTHREADID stidThread, - /* [out] */ SCRIPTTHREADSTATE *pstsState) -{ - trace("%08x: GetScriptThreadState()\n", this); - *pstsState = SCRIPTTHREADSTATE_NOTINSCRIPT; - switch(stidThread) { - case SCRIPTTHREADID_BASE: - stidThread = m_basethread; - break; - case SCRIPTTHREADID_CURRENT: - stidThread = m_enginethread; - break; - }; - if (stidThread == m_basethread) { - *pstsState = SCRIPTTHREADSTATE_NOTINSCRIPT; - } else if (stidThread == m_enginethread) { - *pstsState = SCRIPTTHREADSTATE_NOTINSCRIPT; - } - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::InterruptScriptThread( - /* [in] */ SCRIPTTHREADID stidThread, - /* [in] */ const EXCEPINFO *pexcepinfo, - /* [in] */ DWORD dwFlags) -{ - /* do not serialize this method, or call into the script site */ - trace("%08x: InterruptScriptThread()\n", this); - return S_OK; -} - -/* Clone is essential when running under Windows Script Host. - * It creates an engine to parse the code. Once it is parsed, - * the host clones other engines from the original and runs those. - * It is intended to be a fast method of running the same script - * multiple times in multiple threads. */ -STDMETHODIMP TPHPScriptingEngine::Clone( - /* [out] */ IActiveScript **ppscript) -{ - HRESULT ret = E_FAIL; - IUnknown *punk; - - trace("************* Clone this[%08x]\n", this); - - punk = create_scripting_engine(this); - - if (punk) { - ret = punk->QueryInterface(IID_IActiveScript, (void**)ppscript); - punk->Release(); - } - - return ret; -} - - -STDMETHODIMP TPHPScriptingEngine::InitNew( void) -{ - TSRMLS_FETCH(); - trace("InitNew() this=%08x\n", this); - if (m_done_init) { - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_InitNew, 0); - - zend_hash_destroy(&m_frags); - php_request_shutdown(NULL); - setup_engine_state(); - } - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::AddScriptlet( - /* [in] */ LPCOLESTR pstrDefaultName, - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ LPCOLESTR pstrSubItemName, - /* [in] */ LPCOLESTR pstrEventName, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ BSTR *pbstrName, - /* [out] */ EXCEPINFO *pexcepinfo) -{ - HRESULT ret; - TSRMLS_FETCH(); - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_AddScriptlet, 11, pstrDefaultName, pstrCode, pstrItemName, pstrSubItemName, pstrEventName, pstrDelimiter, dwSourceContextCookie, ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo); - - ENGINE_THREAD_ONLY(IActiveScriptParse, AddScriptlet); - -trace("AddScriptlet\n"); - - /* Parse/compile a chunk of script that will act as an event handler. - * If the host supports IActiveScriptParseProcedure, this code will - * not be called. - * The docs are (typically) vague: AFAICT, once the code has been - * compiled, we are supposed to arrange for an IConnectionPoint - * advisory connection to the item/subitem, once the script - * moves into SCRIPTSTATE_CONNECTED. - * That's a lot of work! - * - * FIXME: this is currently almost useless - * */ - - TWideString - default_name(pstrDefaultName), - code(pstrCode), - item_name(pstrItemName), - sub_item_name(pstrSubItemName), - event_name(pstrEventName), - delimiter(pstrDelimiter); - - /* lets invent a function name for the scriptlet */ - char sname[256]; - - if (pstrDefaultName && !function_exists(default_name.ansi_string() TSRMLS_CC)) - strcpy(sname, default_name.ansi_string()); - else { - sname[0] = 0; - strcat(sname, "__"); - if (pstrItemName) { - strcat(sname, item_name.ansi_string()); - strcat(sname, "_"); - } - if (pstrSubItemName) { - strcat(sname, sub_item_name.ansi_string()); - strcat(sname, "_"); - } - if (pstrEventName) - strcat(sname, event_name.ansi_string()); - } - - - trace("%08x: AddScriptlet: [%s]\n state=%s\n name=%s\n code=%s\n item=%s\n subitem=%s\n event=%s\n delim=%s\n line=%d\n", - this, sname, - scriptstate_to_string(m_scriptstate), - default_name.safe_ansi_string(), code.safe_ansi_string(), item_name.safe_ansi_string(), - sub_item_name.safe_ansi_string(), event_name.safe_ansi_string(), delimiter.safe_ansi_string(), - ulStartingLineNumber); - - - code_frag *frag = compile_code_fragment( - FRAG_SCRIPTLET, - sname, - pstrCode, - ulStartingLineNumber, - pexcepinfo, - this - TSRMLS_CC); - - if (frag) { - - frag->persistent = (dwFlags & SCRIPTTEXT_ISPERSISTENT); - - zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL); - - /* - ScriptProcedureDispatch *disp = new ScriptProcedureDispatch; - - disp->AddRef(); - disp->m_frag = frag; - disp->m_procflags = info->dwFlags; - disp->m_engine = this; - frag->ptr = disp; - - *ppdisp = disp; - */ - ret = S_OK; - } else { - ret = DISP_E_EXCEPTION; - } - - *pbstrName = TWideString::bstr_from_ansi(sname); - - trace("%08x: done with scriptlet %s\n", this, sname); - - - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::ParseScriptText( - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ IUnknown *punkContext, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ VARIANT *pvarResult, - /* [out] */ EXCEPINFO *pexcepinfo) -{ -trace("ParseScriptText\n"); - int doexec; - TWideString - code(pstrCode), - item_name(pstrItemName), - delimiter(pstrDelimiter); - HRESULT ret, dummy; - TSRMLS_FETCH(); - - trace("pstrCode=%p pstrItemName=%p punkContext=%p pstrDelimiter=%p pvarResult=%p pexcepinfo=%p\n", - pstrCode, pstrItemName, punkContext, pstrDelimiter, pvarResult, pexcepinfo); - - if (tsrm_thread_id() != m_enginethread) { - return marshal_call(this, APHP_ParseScriptText, 9, - pstrCode, pstrItemName, punkContext, pstrDelimiter, - dwSourceContextCookie, ulStartingLineNumber, - dwFlags, pvarResult, pexcepinfo); - } - - trace("%08x: ParseScriptText:\n state=%s\ncode=%.*s\n item=%s\n delim=%s\n line=%d\n", - this, scriptstate_to_string(m_scriptstate), - code.m_ansi_strlen, - code.safe_ansi_string(), item_name.safe_ansi_string(), delimiter.safe_ansi_string(), - ulStartingLineNumber); - - code_frag *frag = compile_code_fragment( - FRAG_MAIN, - dwFlags & SCRIPTTEXT_ISEXPRESSION ? FRAG_CREATE_FUNC : NULL, - pstrCode, - ulStartingLineNumber, - pexcepinfo, - this - TSRMLS_CC); - - doexec = (dwFlags & SCRIPTTEXT_ISEXPRESSION) || - m_scriptstate == SCRIPTSTATE_STARTED || - m_scriptstate == SCRIPTSTATE_CONNECTED || - m_scriptstate == SCRIPTSTATE_DISCONNECTED; - - if (frag) { - frag->persistent = (dwFlags & SCRIPTTEXT_ISPERSISTENT); - ret = S_OK; - - if (dwFlags & SCRIPTTEXT_ISEXPRESSION) { - if (m_scriptstate == SCRIPTSTATE_INITIALIZED) { - /* not allowed to execute code in this state */ - ret = E_UNEXPECTED; - doexec = 0; - } - } - - if (doexec) { - /* execute the code as an expression */ - ASS_CALL(dummy, OnEnterScript, ()); - if (!execute_code_fragment(frag, pvarResult, pexcepinfo TSRMLS_CC)) - ret = DISP_E_EXCEPTION; - ASS_CALL(dummy, OnLeaveScript, ()); - } - - zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL); - } else { - ret = DISP_E_EXCEPTION; - } - - if (pvarResult) { - VariantInit(pvarResult); - } - - - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::ParseProcedureText( - /* [in] */ LPCOLESTR pstrCode, - /* [in] */ LPCOLESTR pstrFormalParams, - /* [in] */ LPCOLESTR pstrProcedureName, - /* [in] */ LPCOLESTR pstrItemName, - /* [in] */ IUnknown *punkContext, - /* [in] */ LPCOLESTR pstrDelimiter, - /* [in] */ DWORD dwSourceContextCookie, - /* [in] */ ULONG ulStartingLineNumber, - /* [in] */ DWORD dwFlags, - /* [out] */ IDispatch **ppdisp) -{ - TSRMLS_FETCH(); -trace("ParseProcedureText\n"); - - if (tsrm_thread_id() != m_enginethread) - return marshal_call(this, APHP_ParseProcedureText, 10, - pstrCode, pstrFormalParams, pstrProcedureName, pstrItemName, - punkContext, pstrDelimiter, dwSourceContextCookie, - ulStartingLineNumber, dwFlags, ppdisp); - - ENGINE_THREAD_ONLY(IActiveScriptParseProcedure, ParseProcedureText); - /* This is the IActiveScriptParseProcedure implementation. - * IE uses this to request for an IDispatch that it will invoke in - * response to some event, and tells us the code that it wants to - * run. - * We compile the code and pass it back a dispatch object. - * The object will then serialize access to the engine thread and - * execute the opcodes */ - TWideString - formal_params(pstrFormalParams), - procedure_name(pstrProcedureName), - item_name(pstrItemName), - delimiter(pstrDelimiter); - HRESULT ret; - - trace("%08x: ParseProc:\n state=%s\nparams=%s\nproc=%s\nitem=%s\n delim=%s\n line=%d\n", - this, scriptstate_to_string(m_scriptstate), - formal_params.ansi_string(), procedure_name.ansi_string(), - item_name.safe_ansi_string(), delimiter.safe_ansi_string(), - ulStartingLineNumber); - - code_frag *frag = compile_code_fragment( - FRAG_PROCEDURE, - NULL, - pstrCode, - ulStartingLineNumber, - NULL, - this - TSRMLS_CC); - - if (frag) { - - frag->persistent = (dwFlags & SCRIPTTEXT_ISPERSISTENT); - zend_hash_next_index_insert(&m_frags, &frag, sizeof(code_frag*), NULL); - - ScriptProcedureDispatch *disp = new ScriptProcedureDispatch; - - disp->m_frag = frag; - disp->m_procflags = dwFlags; - disp->m_engine = this; - frag->ptr = disp; - - *ppdisp = (IDispatch*)disp; - } else { - ret = DISP_E_EXCEPTION; - } - - - trace("ParseProc: ret=%08x disp=%08x\n", ret, *ppdisp); - return ret; -} - -STDMETHODIMP TPHPScriptingEngine::GetInterfaceSafetyOptions( - /* [in] */ REFIID riid, // Interface that we want options for - /* [out] */ DWORD *pdwSupportedOptions, // Options meaningful on this interface - /* [out] */ DWORD *pdwEnabledOptions) // current option values on this interface -{ - /* PHP isn't really safe for untrusted anything */ - trace("GetInterfaceSafetyOptions called\n"); - *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER; - *pdwEnabledOptions = 0; - return S_OK; -} - -STDMETHODIMP TPHPScriptingEngine::SetInterfaceSafetyOptions( - /* [in] */ REFIID riid, // Interface to set options for - /* [in] */ DWORD dwOptionSetMask, // Options to change - /* [in] */ DWORD dwEnabledOptions) // New option values -{ - /* PHP isn't really safe for untrusted anything */ - trace("SetInterfaceSafetyOptions mask=%08x enabled=%08x\n", dwOptionSetMask, dwEnabledOptions); - if (dwEnabledOptions == 0) { - return S_OK; - } - trace("can't set those options; we're not safe enough\n"); - return E_FAIL; -} - -#if 0 -STDMETHODIMP TPHPScriptingEngine::GetUnmarshalClass( - REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPScriptingEngine::GetMarshalSizeMax( - REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, ULONG *pSize) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPScriptingEngine::MarshalInterface( - IStream *pStm, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshflags) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPScriptingEngine::UnmarshalInterface( - IStream *pStm, REFIID riid, void **ppv) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPScriptingEngine::ReleaseMarshalData(IStream *pStm) -{ - return E_NOTIMPL; -} - -STDMETHODIMP TPHPScriptingEngine::DisconnectObject(DWORD dwReserved) -{ - return E_NOTIMPL; -} -#endif - -class TActiveScriptError: - public IActiveScriptError -{ -protected: - volatile LONG m_refcount; -public: - /* IUnknown */ - STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) { - *ppvObject = NULL; - - if (IsEqualGUID(IID_IActiveScriptError, iid)) { - *ppvObject = (IActiveScriptError*)this; - } else if (IsEqualGUID(IID_IUnknown, iid)) { - *ppvObject = this; - } - if (*ppvObject) { - AddRef(); - return S_OK; - } - return E_NOINTERFACE; - } - - STDMETHODIMP_(DWORD) AddRef(void) { - return InterlockedIncrement(const_cast<long*> (&m_refcount)); - } - - STDMETHODIMP_(DWORD) Release(void) { - DWORD ret = InterlockedDecrement(const_cast<long*> (&m_refcount)); - trace("Release: errobj refcount=%d\n", ret); - if (ret == 0) - delete this; - return ret; - } - - HRESULT STDMETHODCALLTYPE GetExceptionInfo( - /* [out] */ EXCEPINFO *pexcepinfo) - { - memset(pexcepinfo, 0, sizeof(EXCEPINFO)); - pexcepinfo->bstrDescription = SysAllocString(m_message); - pexcepinfo->bstrSource = SysAllocString(m_filename); - pexcepinfo->wCode = 1000; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetSourcePosition( - /* [out] */ DWORD *pdwSourceContext, - /* [out] */ ULONG *pulLineNumber, - /* [out] */ LONG *plCharacterPosition) - { - if (pdwSourceContext) - *pdwSourceContext = 0; - if (pulLineNumber) - *pulLineNumber = m_lineno; - if (plCharacterPosition) - *plCharacterPosition = 0; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE GetSourceLineText( - /* [out] */ BSTR *pbstrSourceLine) - { - *pbstrSourceLine = NULL; - return E_FAIL; - } - - BSTR m_filename, m_message; - UINT m_lineno; - - TActiveScriptError(const char *filename, const uint lineno, const char *message) - { - char *extra_buf, *dest; - int msglen = strlen(message); - - extra_buf = (char*)emalloc(2 * msglen + 1); - - /* convert line endings so multi-line output looks reasonable in a GUI */ - dest = extra_buf; - while (*message) { - if (*message == '\n') { - *dest++ = '\r'; - *dest++ = '\n'; - message++; - } else if (*message == '\r' && message[1] == '\n') { - *dest++ = '\r'; - *dest++ = '\n'; - message+=2; - } else { - *dest++ = *message++; - } - } - *dest = '\0'; - - m_refcount = 0; /* start with zero refcount because this object is passed - * directly to the script site; it will call addref */ - m_filename = TWideString::bstr_from_ansi((char*)filename); - m_message = TWideString::bstr_from_ansi(extra_buf); - m_lineno = lineno; - - efree(extra_buf); - } - - ~TActiveScriptError() - { - trace("%08x: cleaning up error object\n", this); - SysFreeString(m_filename); - SysFreeString(m_message); - } -}; - -extern "C" -void activescript_error_handler(int type, const char *error_filename, - const uint error_lineno, const char *format, va_list args) -{ - TSRMLS_FETCH(); - char *buf; - int buflen; - HRESULT dummy; - TPHPScriptingEngine *engine = (TPHPScriptingEngine*)SG(server_context); - - /* ugly way to detect an exception for an eval'd fragment */ - if (type == E_ERROR && EG(exception) && strstr("Exception thrown without a stack frame", format)) { - zend_exception_error(EG(exception) TSRMLS_CC); - /* NOTREACHED -- recursive E_ERROR */ - } else { - buflen = vspprintf(&buf, PG(log_errors_max_len), format, args); - trace("%08x: PHP Error: %s\n", engine, buf); - } - - TActiveScriptError *eobj = new TActiveScriptError(error_filename, error_lineno, buf); - trace("raising error object!\n"); - if (engine->m_pass) { - ASS_CALL_(dummy, engine, OnScriptError, (eobj)); - } - - switch(type) { - case E_ERROR: - case E_CORE_ERROR: - case E_COMPILE_ERROR: - case E_USER_ERROR: - case E_PARSE: - /* now throw the exception to abort execution */ - zend_bailout(); - break; - } - efree(buf); -} - |
