summaryrefslogtreecommitdiff
path: root/ext/com_dotnet/com_com.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-10-07 18:50:07 (GMT)
committerWez Furlong <wez@php.net>2003-10-07 18:50:07 (GMT)
commit18bfcc8897cdebfbb13a45b92dc80dd370017b44 (patch)
tree6c4545e29a885a66f0a3d2093676a8cc8dcbc8b0 /ext/com_dotnet/com_com.c
parent146ba0e875540d291b7cb5557833a3403ae3b762 (diff)
downloadphp-18bfcc8897cdebfbb13a45b92dc80dd370017b44.tar.gz
A much better fix for moniker based COM object creation.
We now support binding monikers to remote machines. However, MSDN docs indicate that this isn't yet implemented as of Win2000.
Diffstat (limited to 'ext/com_dotnet/com_com.c')
-rw-r--r--ext/com_dotnet/com_com.c96
1 files changed, 60 insertions, 36 deletions
diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c
index b02132f..b2465f8 100644
--- a/ext/com_dotnet/com_com.c
+++ b/ext/com_dotnet/com_com.c
@@ -45,6 +45,13 @@ PHP_FUNCTION(com_create_instance)
HRESULT res = E_FAIL;
int mode = COMG(autoreg_case_sensitive) ? CONST_CS : 0;
ITypeLib *TL = NULL;
+ COSERVERINFO info;
+ COAUTHIDENTITY authid = {0};
+ COAUTHINFO authinfo = {
+ RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
+ RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
+ &authid, EOAC_NONE
+ };
obj = CDNO_FETCH(object);
@@ -112,40 +119,9 @@ PHP_FUNCTION(com_create_instance)
moniker = php_com_string_to_olestring(module_name, module_name_len, obj->code_page TSRMLS_CC);
- if (FAILED(CLSIDFromString(moniker, &clsid))) {
- /* try to use it as a moniker */
- IBindCtx *pBindCtx = NULL;
- IMoniker *pMoniker = NULL;
- ULONG ulEaten;
-
- if (server_params != NULL) {
- /* TODO: review this.
- * The assumption seems to be that monikers cannot be invoked for remote servers.
- * The BindCtx might allow this however */
- res = MK_E_SYNTAX;
- } else if (SUCCEEDED(res = CreateBindCtx(0, &pBindCtx)) &&
- SUCCEEDED(res = MkParseDisplayName(pBindCtx, moniker, &ulEaten, &pMoniker))) {
- res = IMoniker_BindToObject(pMoniker, pBindCtx, NULL, &IID_IDispatch, (LPVOID*)&V_DISPATCH(&obj->v));
-
- if (SUCCEEDED(res)) {
- V_VT(&obj->v) = VT_DISPATCH;
- }
-
- IMoniker_Release(pMoniker);
- }
- if (pBindCtx) {
- IBindCtx_Release(pBindCtx);
- }
- } else if (server_name) {
- COSERVERINFO info;
- MULTI_QI qi;
- COAUTHIDENTITY authid;
- COAUTHINFO authinfo = {
- RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
- RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
- &authid, EOAC_NONE
- };
-
+ /* if instantiating a remote object, either directly, or via
+ * a moniker, fill in the relevant info */
+ if (server_name) {
info.dwReserved1 = 0;
info.dwReserved2 = 0;
info.pwszName = php_com_string_to_olestring(server_name, server_name_len, obj->code_page TSRMLS_CC);
@@ -174,19 +150,62 @@ PHP_FUNCTION(com_create_instance)
} else {
info.pAuthInfo = NULL;
}
+ }
+
+ if (FAILED(CLSIDFromString(moniker, &clsid))) {
+ /* try to use it as a moniker */
+ IBindCtx *pBindCtx = NULL;
+ IMoniker *pMoniker = NULL;
+ ULONG ulEaten;
+ BIND_OPTS2 bopt = {0};
+
+ if (SUCCEEDED(res = CreateBindCtx(0, &pBindCtx))) {
+ if (server_name) {
+ /* fill in the remote server info.
+ * MSDN docs indicate that this might be ignored in
+ * current win32 implementations, but at least we are
+ * doing the right thing in readiness for the day that
+ * it does work */
+ bopt.cbStruct = sizeof(bopt);
+ IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS*)&bopt);
+ bopt.pServerInfo = &info;
+ /* apparently, GetBindOptions will only ever return
+ * a regular BIND_OPTS structure. My gut feeling is
+ * that it will modify the size field to reflect that
+ * so lets be safe and set it to the BIND_OPTS2 size
+ * again */
+ bopt.cbStruct = sizeof(bopt);
+ IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS*)&bopt);
+ }
+
+ if (SUCCEEDED(res = MkParseDisplayName(pBindCtx, moniker, &ulEaten, &pMoniker))) {
+ res = IMoniker_BindToObject(pMoniker, pBindCtx,
+ NULL, &IID_IDispatch, (LPVOID*)&V_DISPATCH(&obj->v));
+
+ if (SUCCEEDED(res)) {
+ V_VT(&obj->v) = VT_DISPATCH;
+ }
+
+ IMoniker_Release(pMoniker);
+ }
+ }
+ if (pBindCtx) {
+ IBindCtx_Release(pBindCtx);
+ }
+ } else if (server_name) {
+ MULTI_QI qi;
+
qi.pIID = &IID_IDispatch;
qi.pItf = NULL;
qi.hr = S_OK;
res = CoCreateInstanceEx(&clsid, NULL, ctx, &info, 1, &qi);
- efree(info.pwszName);
if (SUCCEEDED(res)) {
res = qi.hr;
V_DISPATCH(&obj->v) = (IDispatch*)qi.pItf;
V_VT(&obj->v) = VT_DISPATCH;
}
-
} else {
res = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&V_DISPATCH(&obj->v));
if (SUCCEEDED(res)) {
@@ -194,6 +213,11 @@ PHP_FUNCTION(com_create_instance)
}
}
+ if (server_name) {
+ STR_FREE((char*)info.pwszName);
+ STR_FREE((char*)authid.User);
+ }
+
efree(moniker);
if (FAILED(res)) {