diff options
-rw-r--r-- | ext/com/COM.c | 240 | ||||
-rw-r--r-- | ext/rpc/com/com_wrapper.c | 240 |
2 files changed, 414 insertions, 66 deletions
diff --git a/ext/com/COM.c b/ext/com/COM.c index b0be9e5f44..0428228412 100644 --- a/ext/com/COM.c +++ b/ext/com/COM.c @@ -45,6 +45,11 @@ * VARIANT datatype and pass_by_reference support */ +/* + * 03.6.2001 + * Enhanced Typelib support to include a search by name + */ + #ifdef PHP_WIN32 #define _WIN32_DCOM @@ -68,6 +73,7 @@ PHP_FUNCTION(com_propget); PHP_FUNCTION(com_propput); PHPAPI int php_COM_get_le_idispatch(); +static ITypeLib *php_COM_find_typelib(char *search_string, int mode); static int php_COM_load_typelib(char *typelib_name, int mode); static int le_idispatch; @@ -96,19 +102,37 @@ static PHP_MINFO_FUNCTION(COM) PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult) { HRESULT hr; + int failed = FALSE; if(obj->referenced) { - if(obj->typelib) { + if(obj->typelib) + { hr = obj->i.typeinfo->lpVtbl->Invoke(obj->i.typeinfo, obj->i.dispatch, dispIdMember, wFlags, pDispParams, pVarResult, NULL, NULL); - if(!FAILED(hr)) + if(FAILED(hr)) { - return hr; + hr = obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + wFlags, pDispParams, pVarResult, NULL, NULL); + if(SUCCEEDED(hr)) + { + /* + * ITypLib doesn't work + * Release ITypeLib and fall back to IDispatch + */ + + obj->i.typeinfo->lpVtbl->Release(obj->i.typeinfo); + obj->typelib = FALSE; + } } } - return obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, - wFlags, pDispParams, pVarResult, NULL, NULL); + else + { + hr = obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + wFlags, pDispParams, pVarResult, NULL, NULL); + } + + return hr; } else { @@ -122,14 +146,32 @@ PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszN if(obj->referenced) { - if(obj->typelib) { + if(obj->typelib) + { hr = obj->i.typeinfo->lpVtbl->GetIDsOfNames(obj->i.typeinfo, rgszNames, 1, rgDispId); - if(!FAILED(hr)) + + if(FAILED(hr)) { - return hr; + hr = obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + + if(SUCCEEDED(hr)) + { + /* + * ITypLib doesn't work + * Release ITypeLib and fall back to IDispatch + */ + + obj->i.typeinfo->lpVtbl->Release(obj->i.typeinfo); + obj->typelib = FALSE; + } } } - return obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + else + { + hr = obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + } + + return hr; } else { @@ -172,7 +214,6 @@ PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup) obj->i.dispatch = pDisp; obj->referenced = 1; - obj->typelib = !FAILED(obj->i.dispatch->lpVtbl->GetTypeInfo(obj->i.dispatch, 0, LANG_NEUTRAL, &(obj->i.typeinfo))); if(!cleanup) @@ -1012,7 +1053,6 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro PHP_FN(com_load)(INTERNAL_FUNCTION_PARAM_PASSTHRU); if(!zend_is_true(return_value)) { - pval_destructor(&function_name->element); var_reset(object); return; } @@ -1041,10 +1081,7 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro if(!obj || (type!=le_idispatch)) { - if(property.refcount == 1) - { - pval_destructor(&property); - } + pval_destructor(&property); pval_destructor(&function_name->element); return; } @@ -1092,39 +1129,61 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro pval_destructor(&function_name->element); } - -static int php_COM_load_typelib(char *typelib_name, int mode) +static ITypeLib *php_COM_find_typelib(char *search_string, int mode) { - ITypeLib *TypeLib; - ITypeComp *TypeComp; - OLECHAR *p; - CLSID clsid; + ITypeLib *TypeLib = NULL; char *strtok_buf, *major, *minor; - int i; - int interfaces; - ELS_FETCH(); - - - typelib_name = php_strtok_r(typelib_name, ",", &strtok_buf); + CLSID clsid; + OLECHAR *p; + char *ptr; + + /* Type Libraries: + * The string we have is either: + * a) a file name + * b) a CLSID, major, minor e.g. "{00000200-0000-0010-8000-00AA006D2EA4},2,0" + * c) a Type Library name e.g. "Microsoft OLE DB ActiveX Data Objects 1.0 Library" + * Searching for the name will be more expensive that the + * other two, so we will do that when both other attempts + * fail. + */ + search_string = php_strtok_r(search_string, ",", &strtok_buf); major = php_strtok_r(NULL, ",", &strtok_buf); minor = php_strtok_r(NULL, ",", &strtok_buf); - p = php_char_to_OLECHAR(typelib_name, strlen(typelib_name), codepage); + /* Remove leading/training white spaces on search_string */ + while (isspace(*search_string)) /* Ends on '\0' in worst case */ + { + search_string ++; + } + ptr = search_string + strlen(search_string) - 1; + while ((ptr != search_string) && isspace(*ptr)) + { + *ptr = '\0'; + ptr--; + } + p = php_char_to_OLECHAR(search_string, strlen(search_string), codepage); + /* Is the string a GUID ? */ if(!FAILED(CLSIDFromString(p, &clsid))) { HRESULT hr; WORD major_i = 1; WORD minor_i = 0; + /* We have a valid GUID, check to see if a major/minor */ + /* version was specified otherwise assume 1,0 */ if(major && minor) { major_i = (WORD) atoi(major); minor_i = (WORD) atoi(minor); } + /* The GUID will either be a typelibrary or a CLSID */ hr = LoadRegTypeLib((REFGUID) &clsid, major_i, minor_i, LANG_NEUTRAL, &TypeLib); + /* If the LoadRegTypeLib fails, let's try to instantiate */ + /* the class itself and then QI for the TypeInfo and */ + /* retrieve the type info from that interface */ if(FAILED(hr) && (!major || !minor)) { IDispatch *Dispatch; @@ -1134,20 +1193,20 @@ static int php_COM_load_typelib(char *typelib_name, int mode) if(FAILED(CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &Dispatch))) { efree(p); - return FAILURE; + return NULL; } if(FAILED(Dispatch->lpVtbl->GetTypeInfo(Dispatch, 0, LANG_NEUTRAL, &TypeInfo))) { Dispatch->lpVtbl->Release(Dispatch); efree(p); - return FAILURE; + return NULL; } Dispatch->lpVtbl->Release(Dispatch); if(FAILED(TypeInfo->lpVtbl->GetContainingTypeLib(TypeInfo, &TypeLib, &idx))) { TypeInfo->lpVtbl->Release(TypeInfo); efree(p); - return FAILURE; + return NULL; } TypeInfo->lpVtbl->Release(TypeInfo); } @@ -1156,10 +1215,126 @@ static int php_COM_load_typelib(char *typelib_name, int mode) { if(FAILED(LoadTypeLib(p, &TypeLib))) { + /* Walk HKCR/TypeLib looking for the string */ + /* If that succeeds, call ourself recursively */ + /* using the CLSID found, else give up and bail */ + HKEY hkey, hsubkey; + DWORD SubKeys, MaxSubKeyLength; + char *keyname; + register unsigned int ii, jj; + DWORD VersionCount; + char version[20]; /* All the version keys are 1.0, 4.6, ... */ + char *libname; + DWORD libnamelen; + + /* No Need for Unicode version any more */ efree(p); - return FAILURE; + + /* Starting at HKEY_CLASSES_ROOT/TypeLib */ + /* Walk all subkeys (Typelib GUIDs) looking */ + /* at each version for a string match to the */ + /* supplied argument */ + if (ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "TypeLib",&hkey)) + { + /* This is pretty bad - better bail */ + return NULL; + } + if (ERROR_SUCCESS != RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys, &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) + { + RegCloseKey(hkey); + return NULL; + } + keyname = malloc(MaxSubKeyLength); + libname = malloc(strlen(search_string)+1); + for (ii=0;ii<SubKeys;ii++) + { + if (ERROR_SUCCESS != RegEnumKey(hkey, ii, keyname, MaxSubKeyLength)) + { + /* Failed - who cares */ + continue; + } + if (ERROR_SUCCESS != RegOpenKey(hkey, keyname, &hsubkey)) + { + /* Failed - who cares */ + continue; + } + if (ERROR_SUCCESS != RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) + { + /* Failed - who cares */ + RegCloseKey(hsubkey); + continue; + } + for (jj=0;jj<VersionCount;jj++) + { + if (ERROR_SUCCESS != RegEnumKey(hsubkey, jj, version, sizeof(version))) + { + /* Failed - who cares */ + continue; + } + /* OK we just need to retrieve the default */ + /* value for this key and see if it matches */ + libnamelen = strlen(search_string)+1; + if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) + { + if ((mode & CONST_CS) ? (strcmp(libname, search_string) == 0) : (stricmp(libname, search_string) == 0)) + { + char *str; + int major, minor; + + /* Found it */ + RegCloseKey(hkey); + RegCloseKey(hsubkey); + efree(libname); + /* We can either open up the "win32" key and find the DLL name */ + /* Or just parse the version string and pass that in */ + /* The version string seems like a more portable solution */ + /* Given that there is a COM on Unix */ + if (2 != sscanf(version, "%d.%d", &major, &minor)) + { + major = 1; + minor = 0; + } + str = malloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ + sprintf(str, "%s,%d,%d", keyname, major, minor); + free(keyname); + TypeLib = php_COM_find_typelib(str, mode); + free(str); + /* This is probbaly much harder to read and follow */ + /* But it is MUCH more effiecient than trying to */ + /* test for errors and leave through a single "return" */ + return TypeLib; + } + } + else + { + /* Failed - perhaps too small abuffer */ + /* But if too small, then the name does not match */ + } + } + RegCloseKey(hsubkey); + } + free(keyname); + free(libname); + return NULL; } } + efree(p); + return TypeLib; +} + +static int php_COM_load_typelib(char *typelib_name, int mode) +{ + ITypeLib *TypeLib; + ITypeComp *TypeComp; + int i; + int interfaces; + ELS_FETCH(); + + TypeLib = php_COM_find_typelib(typelib_name, mode); + if (NULL == TypeLib) + { + return FAILURE; + } interfaces = TypeLib->lpVtbl->GetTypeInfoCount(TypeLib); @@ -1217,7 +1392,6 @@ static int php_COM_load_typelib(char *typelib_name, int mode) TypeLib->lpVtbl->Release(TypeLib); - efree(p); return SUCCESS; } diff --git a/ext/rpc/com/com_wrapper.c b/ext/rpc/com/com_wrapper.c index b0be9e5f44..0428228412 100644 --- a/ext/rpc/com/com_wrapper.c +++ b/ext/rpc/com/com_wrapper.c @@ -45,6 +45,11 @@ * VARIANT datatype and pass_by_reference support */ +/* + * 03.6.2001 + * Enhanced Typelib support to include a search by name + */ + #ifdef PHP_WIN32 #define _WIN32_DCOM @@ -68,6 +73,7 @@ PHP_FUNCTION(com_propget); PHP_FUNCTION(com_propput); PHPAPI int php_COM_get_le_idispatch(); +static ITypeLib *php_COM_find_typelib(char *search_string, int mode); static int php_COM_load_typelib(char *typelib_name, int mode); static int le_idispatch; @@ -96,19 +102,37 @@ static PHP_MINFO_FUNCTION(COM) PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult) { HRESULT hr; + int failed = FALSE; if(obj->referenced) { - if(obj->typelib) { + if(obj->typelib) + { hr = obj->i.typeinfo->lpVtbl->Invoke(obj->i.typeinfo, obj->i.dispatch, dispIdMember, wFlags, pDispParams, pVarResult, NULL, NULL); - if(!FAILED(hr)) + if(FAILED(hr)) { - return hr; + hr = obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + wFlags, pDispParams, pVarResult, NULL, NULL); + if(SUCCEEDED(hr)) + { + /* + * ITypLib doesn't work + * Release ITypeLib and fall back to IDispatch + */ + + obj->i.typeinfo->lpVtbl->Release(obj->i.typeinfo); + obj->typelib = FALSE; + } } } - return obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, - wFlags, pDispParams, pVarResult, NULL, NULL); + else + { + hr = obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + wFlags, pDispParams, pVarResult, NULL, NULL); + } + + return hr; } else { @@ -122,14 +146,32 @@ PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszN if(obj->referenced) { - if(obj->typelib) { + if(obj->typelib) + { hr = obj->i.typeinfo->lpVtbl->GetIDsOfNames(obj->i.typeinfo, rgszNames, 1, rgDispId); - if(!FAILED(hr)) + + if(FAILED(hr)) { - return hr; + hr = obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + + if(SUCCEEDED(hr)) + { + /* + * ITypLib doesn't work + * Release ITypeLib and fall back to IDispatch + */ + + obj->i.typeinfo->lpVtbl->Release(obj->i.typeinfo); + obj->typelib = FALSE; + } } } - return obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + else + { + hr = obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, &IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + } + + return hr; } else { @@ -172,7 +214,6 @@ PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup) obj->i.dispatch = pDisp; obj->referenced = 1; - obj->typelib = !FAILED(obj->i.dispatch->lpVtbl->GetTypeInfo(obj->i.dispatch, 0, LANG_NEUTRAL, &(obj->i.typeinfo))); if(!cleanup) @@ -1012,7 +1053,6 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro PHP_FN(com_load)(INTERNAL_FUNCTION_PARAM_PASSTHRU); if(!zend_is_true(return_value)) { - pval_destructor(&function_name->element); var_reset(object); return; } @@ -1041,10 +1081,7 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro if(!obj || (type!=le_idispatch)) { - if(property.refcount == 1) - { - pval_destructor(&property); - } + pval_destructor(&property); pval_destructor(&function_name->element); return; } @@ -1092,39 +1129,61 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro pval_destructor(&function_name->element); } - -static int php_COM_load_typelib(char *typelib_name, int mode) +static ITypeLib *php_COM_find_typelib(char *search_string, int mode) { - ITypeLib *TypeLib; - ITypeComp *TypeComp; - OLECHAR *p; - CLSID clsid; + ITypeLib *TypeLib = NULL; char *strtok_buf, *major, *minor; - int i; - int interfaces; - ELS_FETCH(); - - - typelib_name = php_strtok_r(typelib_name, ",", &strtok_buf); + CLSID clsid; + OLECHAR *p; + char *ptr; + + /* Type Libraries: + * The string we have is either: + * a) a file name + * b) a CLSID, major, minor e.g. "{00000200-0000-0010-8000-00AA006D2EA4},2,0" + * c) a Type Library name e.g. "Microsoft OLE DB ActiveX Data Objects 1.0 Library" + * Searching for the name will be more expensive that the + * other two, so we will do that when both other attempts + * fail. + */ + search_string = php_strtok_r(search_string, ",", &strtok_buf); major = php_strtok_r(NULL, ",", &strtok_buf); minor = php_strtok_r(NULL, ",", &strtok_buf); - p = php_char_to_OLECHAR(typelib_name, strlen(typelib_name), codepage); + /* Remove leading/training white spaces on search_string */ + while (isspace(*search_string)) /* Ends on '\0' in worst case */ + { + search_string ++; + } + ptr = search_string + strlen(search_string) - 1; + while ((ptr != search_string) && isspace(*ptr)) + { + *ptr = '\0'; + ptr--; + } + p = php_char_to_OLECHAR(search_string, strlen(search_string), codepage); + /* Is the string a GUID ? */ if(!FAILED(CLSIDFromString(p, &clsid))) { HRESULT hr; WORD major_i = 1; WORD minor_i = 0; + /* We have a valid GUID, check to see if a major/minor */ + /* version was specified otherwise assume 1,0 */ if(major && minor) { major_i = (WORD) atoi(major); minor_i = (WORD) atoi(minor); } + /* The GUID will either be a typelibrary or a CLSID */ hr = LoadRegTypeLib((REFGUID) &clsid, major_i, minor_i, LANG_NEUTRAL, &TypeLib); + /* If the LoadRegTypeLib fails, let's try to instantiate */ + /* the class itself and then QI for the TypeInfo and */ + /* retrieve the type info from that interface */ if(FAILED(hr) && (!major || !minor)) { IDispatch *Dispatch; @@ -1134,20 +1193,20 @@ static int php_COM_load_typelib(char *typelib_name, int mode) if(FAILED(CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &Dispatch))) { efree(p); - return FAILURE; + return NULL; } if(FAILED(Dispatch->lpVtbl->GetTypeInfo(Dispatch, 0, LANG_NEUTRAL, &TypeInfo))) { Dispatch->lpVtbl->Release(Dispatch); efree(p); - return FAILURE; + return NULL; } Dispatch->lpVtbl->Release(Dispatch); if(FAILED(TypeInfo->lpVtbl->GetContainingTypeLib(TypeInfo, &TypeLib, &idx))) { TypeInfo->lpVtbl->Release(TypeInfo); efree(p); - return FAILURE; + return NULL; } TypeInfo->lpVtbl->Release(TypeInfo); } @@ -1156,10 +1215,126 @@ static int php_COM_load_typelib(char *typelib_name, int mode) { if(FAILED(LoadTypeLib(p, &TypeLib))) { + /* Walk HKCR/TypeLib looking for the string */ + /* If that succeeds, call ourself recursively */ + /* using the CLSID found, else give up and bail */ + HKEY hkey, hsubkey; + DWORD SubKeys, MaxSubKeyLength; + char *keyname; + register unsigned int ii, jj; + DWORD VersionCount; + char version[20]; /* All the version keys are 1.0, 4.6, ... */ + char *libname; + DWORD libnamelen; + + /* No Need for Unicode version any more */ efree(p); - return FAILURE; + + /* Starting at HKEY_CLASSES_ROOT/TypeLib */ + /* Walk all subkeys (Typelib GUIDs) looking */ + /* at each version for a string match to the */ + /* supplied argument */ + if (ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "TypeLib",&hkey)) + { + /* This is pretty bad - better bail */ + return NULL; + } + if (ERROR_SUCCESS != RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys, &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) + { + RegCloseKey(hkey); + return NULL; + } + keyname = malloc(MaxSubKeyLength); + libname = malloc(strlen(search_string)+1); + for (ii=0;ii<SubKeys;ii++) + { + if (ERROR_SUCCESS != RegEnumKey(hkey, ii, keyname, MaxSubKeyLength)) + { + /* Failed - who cares */ + continue; + } + if (ERROR_SUCCESS != RegOpenKey(hkey, keyname, &hsubkey)) + { + /* Failed - who cares */ + continue; + } + if (ERROR_SUCCESS != RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) + { + /* Failed - who cares */ + RegCloseKey(hsubkey); + continue; + } + for (jj=0;jj<VersionCount;jj++) + { + if (ERROR_SUCCESS != RegEnumKey(hsubkey, jj, version, sizeof(version))) + { + /* Failed - who cares */ + continue; + } + /* OK we just need to retrieve the default */ + /* value for this key and see if it matches */ + libnamelen = strlen(search_string)+1; + if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) + { + if ((mode & CONST_CS) ? (strcmp(libname, search_string) == 0) : (stricmp(libname, search_string) == 0)) + { + char *str; + int major, minor; + + /* Found it */ + RegCloseKey(hkey); + RegCloseKey(hsubkey); + efree(libname); + /* We can either open up the "win32" key and find the DLL name */ + /* Or just parse the version string and pass that in */ + /* The version string seems like a more portable solution */ + /* Given that there is a COM on Unix */ + if (2 != sscanf(version, "%d.%d", &major, &minor)) + { + major = 1; + minor = 0; + } + str = malloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ + sprintf(str, "%s,%d,%d", keyname, major, minor); + free(keyname); + TypeLib = php_COM_find_typelib(str, mode); + free(str); + /* This is probbaly much harder to read and follow */ + /* But it is MUCH more effiecient than trying to */ + /* test for errors and leave through a single "return" */ + return TypeLib; + } + } + else + { + /* Failed - perhaps too small abuffer */ + /* But if too small, then the name does not match */ + } + } + RegCloseKey(hsubkey); + } + free(keyname); + free(libname); + return NULL; } } + efree(p); + return TypeLib; +} + +static int php_COM_load_typelib(char *typelib_name, int mode) +{ + ITypeLib *TypeLib; + ITypeComp *TypeComp; + int i; + int interfaces; + ELS_FETCH(); + + TypeLib = php_COM_find_typelib(typelib_name, mode); + if (NULL == TypeLib) + { + return FAILURE; + } interfaces = TypeLib->lpVtbl->GetTypeInfoCount(TypeLib); @@ -1217,7 +1392,6 @@ static int php_COM_load_typelib(char *typelib_name, int mode) TypeLib->lpVtbl->Release(TypeLib); - efree(p); return SUCCESS; } |