summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2003-10-07 18:50:07 +0000
committerWez Furlong <wez@php.net>2003-10-07 18:50:07 +0000
commit18bfcc8897cdebfbb13a45b92dc80dd370017b44 (patch)
tree6c4545e29a885a66f0a3d2093676a8cc8dcbc8b0
parent146ba0e875540d291b7cb5557833a3403ae3b762 (diff)
downloadphp-git-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.
-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 b02132f350..b2465f82bd 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)) {