📄 classfactory.cpp
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2006 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 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_01.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: classfactory.cpp,v 1.2.4.1.8.1 2006/01/01 13:47:01 sniper Exp $ *//* IClassFactory Implementation, and DllXXX function implementation */#define INITGUID#define DEBUG_CLASS_FACTORY 0#include <windows.h>#include <initguid.h>extern "C" {HINSTANCE module_handle;}#include <comcat.h>#include "TSRM.h"#include "php4as_classfactory.h"#include "php4as_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){ TPHPScriptingEngine *engine = new TPHPScriptingEngine; HRESULT ret = engine->QueryInterface(iid, ppvObject); engine->Release(); 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 8struct 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, "ActivePHP" }, { HKEY_CLASSES_ROOT, "ActivePHP", NULL, "ActivePHP" }, { HKEY_CLASSES_ROOT, "ActivePHP\\CLSID", NULL, "[CLSID]"}, { HKEY_CLASSES_ROOT, "ActivePHP\\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", "Both", 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;}/* }}} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -