wez             Tue Oct  7 14:50:08 2003 EDT

  Modified files:              
    /php-src/ext/com_dotnet     com_com.c 
  Log:
  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.
  
Index: php-src/ext/com_dotnet/com_com.c
diff -u php-src/ext/com_dotnet/com_com.c:1.3 php-src/ext/com_dotnet/com_com.c:1.4
--- php-src/ext/com_dotnet/com_com.c:1.3        Mon Oct  6 11:10:38 2003
+++ php-src/ext/com_dotnet/com_com.c    Tue Oct  7 14:50:07 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: com_com.c,v 1.3 2003/10/06 15:10:38 wez Exp $ */
+/* $Id: com_com.c,v 1.4 2003/10/07 18:50:07 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -45,6 +45,13 @@
        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 @@
 
        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,24 +150,72 @@
                } 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)) {
                        V_VT(&obj->v) = VT_DISPATCH;
                }
+       }
+
+       if (server_name) {
+               STR_FREE((char*)info.pwszName);
+               STR_FREE((char*)authid.User);
        }
 
        efree(moniker);

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to