diff options
author | Harald Radi <phanto@php.net> | 2001-06-05 12:53:44 +0000 |
---|---|---|
committer | Harald Radi <phanto@php.net> | 2001-06-05 12:53:44 +0000 |
commit | 4efe6f7e6b53496fb1c4f6990b3ad0771bd9be67 (patch) | |
tree | 068043fc9220ebb3b29f85df02230be8d907cc61 | |
parent | 088280c3645b31c8f4d1884e0d621a2fc3aef3a4 (diff) | |
download | php-git-4efe6f7e6b53496fb1c4f6990b3ad0771bd9be67.tar.gz |
typelib is loaded automatically (depends on ini setting)
added com_load_typelib()
# i must get rid of duplicate defines()
@ fixed a bug when com.allow_dcom is set to false
@ added a further parameter to the constructor to load typelibs
@ from file when instantiating components (e.g. DCOM Components
@ without local registration). (phanto)
-rw-r--r-- | ext/com/COM.c | 229 | ||||
-rw-r--r-- | ext/rpc/com/com_wrapper.c | 229 |
2 files changed, 332 insertions, 126 deletions
diff --git a/ext/com/COM.c b/ext/com/COM.c index 0428228412..f79d300234 100644 --- a/ext/com/COM.c +++ b/ext/com/COM.c @@ -71,10 +71,11 @@ PHP_FUNCTION(com_addref); PHP_FUNCTION(com_release); PHP_FUNCTION(com_propget); PHP_FUNCTION(com_propput); +PHP_FUNCTION(com_load_typelib); 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 php_COM_load_typelib(ITypeLib *TypeLib, int mode); static int le_idispatch; static int codepage; @@ -86,6 +87,7 @@ function_entry COM_functions[] = { PHP_FE(com_release, NULL) PHP_FE(com_propget, NULL) PHP_FE(com_propput, NULL) + PHP_FE(com_load_typelib, NULL) PHP_FALIAS(com_get, com_propget, NULL) PHP_FALIAS(com_propset, com_propput, NULL) @@ -214,7 +216,7 @@ 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))); + obj->typelib = SUCCEEDED(obj->i.dispatch->lpVtbl->GetTypeInfo(obj->i.dispatch, 0, LANG_NEUTRAL, &obj->i.typeinfo)); if(!cleanup) { @@ -314,12 +316,13 @@ static PHP_INI_MH(OnTypelibFileChange) } #endif - typelib_name_buffer = (char *) malloc(sizeof(char)*1024); + typelib_name_buffer = (char *) emalloc(sizeof(char)*1024); while(fgets(typelib_name_buffer, 1024, typelib_file)) { + ITypeLib *pTL; char *typelib_name; - char *modifier; + char *modifier, *ptr; int mode = CONST_PERSISTENT|CONST_CS; if(typelib_name_buffer[0]==';') @@ -327,25 +330,47 @@ static PHP_INI_MH(OnTypelibFileChange) continue; } typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */ + if (typelib_name == NULL) + { + continue; + } typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf); modifier = php_strtok_r(NULL, "#", &strtok_buf); - if(modifier) + if(modifier != NULL) { if(!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) { mode &= ~CONST_CS; } } + + /* Remove leading/training white spaces on search_string */ + while (isspace(*typelib_name)) /* Ends on '\0' in worst case */ + { + typelib_name ++; + } + ptr = typelib_name + strlen(typelib_name) - 1; + while ((ptr != typelib_name) && isspace(*ptr)) + { + *ptr = '\0'; + ptr--; + } + + #if SUPPORT_INTERACTIVE if(interactive) { printf("\rLoading %-60s\r", typelib_name); } #endif - php_COM_load_typelib(typelib_name, mode); + if((pTL = php_COM_find_typelib(typelib_name, mode)) != NULL) + { + php_COM_load_typelib(pTL, mode); + pTL->lpVtbl->Release(pTL); + } } - free(typelib_name_buffer); + efree(typelib_name_buffer); fclose(typelib_file); #if SUPPORT_INTERACTIVE @@ -361,65 +386,80 @@ static PHP_INI_MH(OnTypelibFileChange) PHP_INI_BEGIN() PHP_INI_ENTRY_EX("com.allow_dcom", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) +PHP_INI_ENTRY_EX("com.autoregister_typelib", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) +PHP_INI_ENTRY_EX("com.autoregister_casesensitive", "1", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypelibFileChange) PHP_INI_END() -/* {{{ proto int com_load(string module_name [, string remote_host [, int codepage]]) +/* {{{ proto int com_load(string module_name [, string remote_host [, int codepage[, string typelib]]]) Loads a COM module */ PHP_FUNCTION(com_load) { - pval *module_name, *server_name=NULL, *code_page; + pval *module_name, *code_page, *typelib = NULL, *server_name = NULL; CLSID clsid; HRESULT hr; OLECHAR *ProgID; i_dispatch *obj; char *error_message; char *clsid_str; + int mode = CONST_PERSISTENT; + ITypeLib *pTL; + + codepage = CP_ACP; + switch(ZEND_NUM_ARGS()) { case 1: getParameters(ht, 1, &module_name); - codepage = CP_ACP; break; + case 2: - if(!INI_INT("com.allow_dcom")) - { - php_error(E_WARNING, "DCOM is disabled"); - RETURN_FALSE; - } getParameters(ht, 2, &module_name, &server_name); - convert_to_string(server_name); - codepage = CP_ACP; break; + case 3: getParameters(ht, 3, &module_name, &server_name, &code_page); - if(server_name->type == IS_NULL) - { - efree(server_name); - server_name = NULL; - } - else - { - if(!INI_INT("com.allow_dcom")) - { - php_error(E_WARNING, "DCOM is disabled"); - RETURN_FALSE; - } - convert_to_string(server_name); - } + convert_to_long_ex(&code_page); + codepage = code_page->value.lval; + break; - convert_to_long(code_page); + case 4: + getParameters(ht, 4, &module_name, &server_name, &code_page, &typelib); + + convert_to_string_ex(&typelib); + convert_to_long_ex(&code_page); codepage = code_page->value.lval; + break; + default: WRONG_PARAM_COUNT; - break; } - convert_to_string(module_name); + if(server_name != NULL) + { + if(server_name->type == IS_NULL) + { + server_name = NULL; + } + else + { + if(!INI_INT("com.allow_dcom")) + { + php_error(E_WARNING, "DCOM is disabled"); + RETURN_FALSE; + } + else + { + convert_to_string_ex(&server_name); + } + } + } + + convert_to_string_ex(&module_name); ProgID = php_char_to_OLECHAR(module_name->value.str.val, module_name->value.str.len, codepage); hr=CLSIDFromProgID(ProgID, &clsid); efree(ProgID); @@ -474,6 +514,43 @@ PHP_FUNCTION(com_load) } php_COM_set(obj, obj->i.dispatch, TRUE); + + if(INI_INT("com.autoregister_casesensitive")) + { + mode |= CONST_CS; + } + + if(obj->typelib) + { + if(INI_INT("com.autoregister_typelib")) + { + unsigned int idx; + + if(obj->i.typeinfo->lpVtbl->GetContainingTypeLib(obj->i.typeinfo, &pTL, &idx) == S_OK) + { + php_COM_load_typelib(pTL, mode); + pTL->lpVtbl->Release(pTL); + } + } + } + else + { + if(typelib != NULL) + { + ITypeLib *pTL; + + if((pTL = php_COM_find_typelib(typelib->value.str.val, mode)) != NULL) + { + obj->typelib = SUCCEEDED(pTL->lpVtbl->GetTypeInfo(pTL, 0, &obj->i.typeinfo)); + /* idx 0 should deliver the ITypeInfo for the IDispatch Interface */ + if(INI_INT("com.autoregister_typelib")) + { + php_COM_load_typelib(pTL, mode); + } + pTL->lpVtbl->Release(pTL); + } + } + } RETURN_LONG(zend_list_insert(obj, le_idispatch)); } @@ -568,7 +645,7 @@ PHP_FUNCTION(com_invoke) } /* obtain property/method handler */ - convert_to_string(function_name); + convert_to_string_ex(&function_name); if(do_COM_invoke(obj, function_name, &var_result, arguments+2, arg_count-2)==FAILURE) { @@ -804,7 +881,7 @@ PHP_FUNCTION(com_propget) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } - convert_to_string(arg_property); + convert_to_string_ex(&arg_property); if(do_COM_propget(&var_result, obj, arg_property, 0)==FAILURE) { @@ -836,12 +913,50 @@ PHP_FUNCTION(com_propput) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } - convert_to_string(arg_property); + convert_to_string_ex(&arg_property); do_COM_propput(return_value, obj, arg_property, arg_value); } /* }}} */ +/* {{{ proto bool com_load_typelib(string typelib_name[, int case_insensitiv]) */ +PHP_FUNCTION(com_load_typelib) +{ + pval *arg_typelib, *arg_cis; + ITypeLib *pTL; + int mode; + + switch(ZEND_NUM_ARGS()) + { + case 1: + getParameters(ht, 1, &arg_typelib); + mode = CONST_PERSISTENT|CONST_CS; + break; + case 2: + getParameters(ht, 2, &arg_typelib, &arg_cis); + convert_to_boolean_ex(&arg_cis); + if(arg_cis->value.lval) + { + mode &= ~CONST_CS; + } + default: + WRONG_PARAM_COUNT; + } + + convert_to_string_ex(&arg_typelib); + pTL = php_COM_find_typelib(arg_typelib->value.str.val, mode); + if(php_COM_load_typelib(pTL, mode) == SUCCESS) + { + pTL->lpVtbl->Release(pTL); + RETVAL_TRUE; + } + else + { + RETVAL_FALSE; + } +} +/* }}} */ + PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_reference) { zend_overloaded_element *overloaded_property; @@ -1135,7 +1250,6 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) char *strtok_buf, *major, *minor; CLSID clsid; OLECHAR *p; - char *ptr; /* Type Libraries: * The string we have is either: @@ -1146,24 +1260,14 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) * 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); - /* 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; @@ -1172,7 +1276,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* We have a valid GUID, check to see if a major/minor */ /* version was specified otherwise assume 1,0 */ - if(major && minor) + if((major != NULL) && (minor != NULL)) { major_i = (WORD) atoi(major); minor_i = (WORD) atoi(minor); @@ -1234,6 +1338,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* 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 */ @@ -1244,8 +1349,9 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) RegCloseKey(hkey); return NULL; } - keyname = malloc(MaxSubKeyLength); - libname = malloc(strlen(search_string)+1); + MaxSubKeyLength++; /* \0 is not counted */ + keyname = emalloc(MaxSubKeyLength); + libname = emalloc(strlen(search_string)+1); for (ii=0;ii<SubKeys;ii++) { if (ERROR_SUCCESS != RegEnumKey(hkey, ii, keyname, MaxSubKeyLength)) @@ -1284,6 +1390,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* 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 */ @@ -1294,11 +1401,11 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) major = 1; minor = 0; } - str = malloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ + str = emalloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ sprintf(str, "%s,%d,%d", keyname, major, minor); - free(keyname); + efree(keyname); TypeLib = php_COM_find_typelib(str, mode); - free(str); + efree(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" */ @@ -1313,8 +1420,8 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) } RegCloseKey(hsubkey); } - free(keyname); - free(libname); + efree(keyname); + efree(libname); return NULL; } } @@ -1322,15 +1429,13 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) return TypeLib; } -static int php_COM_load_typelib(char *typelib_name, int mode) +static int php_COM_load_typelib(ITypeLib *TypeLib, 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; @@ -1390,8 +1495,6 @@ static int php_COM_load_typelib(char *typelib_name, int mode) } } - - TypeLib->lpVtbl->Release(TypeLib); return SUCCESS; } diff --git a/ext/rpc/com/com_wrapper.c b/ext/rpc/com/com_wrapper.c index 0428228412..f79d300234 100644 --- a/ext/rpc/com/com_wrapper.c +++ b/ext/rpc/com/com_wrapper.c @@ -71,10 +71,11 @@ PHP_FUNCTION(com_addref); PHP_FUNCTION(com_release); PHP_FUNCTION(com_propget); PHP_FUNCTION(com_propput); +PHP_FUNCTION(com_load_typelib); 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 php_COM_load_typelib(ITypeLib *TypeLib, int mode); static int le_idispatch; static int codepage; @@ -86,6 +87,7 @@ function_entry COM_functions[] = { PHP_FE(com_release, NULL) PHP_FE(com_propget, NULL) PHP_FE(com_propput, NULL) + PHP_FE(com_load_typelib, NULL) PHP_FALIAS(com_get, com_propget, NULL) PHP_FALIAS(com_propset, com_propput, NULL) @@ -214,7 +216,7 @@ 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))); + obj->typelib = SUCCEEDED(obj->i.dispatch->lpVtbl->GetTypeInfo(obj->i.dispatch, 0, LANG_NEUTRAL, &obj->i.typeinfo)); if(!cleanup) { @@ -314,12 +316,13 @@ static PHP_INI_MH(OnTypelibFileChange) } #endif - typelib_name_buffer = (char *) malloc(sizeof(char)*1024); + typelib_name_buffer = (char *) emalloc(sizeof(char)*1024); while(fgets(typelib_name_buffer, 1024, typelib_file)) { + ITypeLib *pTL; char *typelib_name; - char *modifier; + char *modifier, *ptr; int mode = CONST_PERSISTENT|CONST_CS; if(typelib_name_buffer[0]==';') @@ -327,25 +330,47 @@ static PHP_INI_MH(OnTypelibFileChange) continue; } typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */ + if (typelib_name == NULL) + { + continue; + } typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf); modifier = php_strtok_r(NULL, "#", &strtok_buf); - if(modifier) + if(modifier != NULL) { if(!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) { mode &= ~CONST_CS; } } + + /* Remove leading/training white spaces on search_string */ + while (isspace(*typelib_name)) /* Ends on '\0' in worst case */ + { + typelib_name ++; + } + ptr = typelib_name + strlen(typelib_name) - 1; + while ((ptr != typelib_name) && isspace(*ptr)) + { + *ptr = '\0'; + ptr--; + } + + #if SUPPORT_INTERACTIVE if(interactive) { printf("\rLoading %-60s\r", typelib_name); } #endif - php_COM_load_typelib(typelib_name, mode); + if((pTL = php_COM_find_typelib(typelib_name, mode)) != NULL) + { + php_COM_load_typelib(pTL, mode); + pTL->lpVtbl->Release(pTL); + } } - free(typelib_name_buffer); + efree(typelib_name_buffer); fclose(typelib_file); #if SUPPORT_INTERACTIVE @@ -361,65 +386,80 @@ static PHP_INI_MH(OnTypelibFileChange) PHP_INI_BEGIN() PHP_INI_ENTRY_EX("com.allow_dcom", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) +PHP_INI_ENTRY_EX("com.autoregister_typelib", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) +PHP_INI_ENTRY_EX("com.autoregister_casesensitive", "1", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb) PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypelibFileChange) PHP_INI_END() -/* {{{ proto int com_load(string module_name [, string remote_host [, int codepage]]) +/* {{{ proto int com_load(string module_name [, string remote_host [, int codepage[, string typelib]]]) Loads a COM module */ PHP_FUNCTION(com_load) { - pval *module_name, *server_name=NULL, *code_page; + pval *module_name, *code_page, *typelib = NULL, *server_name = NULL; CLSID clsid; HRESULT hr; OLECHAR *ProgID; i_dispatch *obj; char *error_message; char *clsid_str; + int mode = CONST_PERSISTENT; + ITypeLib *pTL; + + codepage = CP_ACP; + switch(ZEND_NUM_ARGS()) { case 1: getParameters(ht, 1, &module_name); - codepage = CP_ACP; break; + case 2: - if(!INI_INT("com.allow_dcom")) - { - php_error(E_WARNING, "DCOM is disabled"); - RETURN_FALSE; - } getParameters(ht, 2, &module_name, &server_name); - convert_to_string(server_name); - codepage = CP_ACP; break; + case 3: getParameters(ht, 3, &module_name, &server_name, &code_page); - if(server_name->type == IS_NULL) - { - efree(server_name); - server_name = NULL; - } - else - { - if(!INI_INT("com.allow_dcom")) - { - php_error(E_WARNING, "DCOM is disabled"); - RETURN_FALSE; - } - convert_to_string(server_name); - } + convert_to_long_ex(&code_page); + codepage = code_page->value.lval; + break; - convert_to_long(code_page); + case 4: + getParameters(ht, 4, &module_name, &server_name, &code_page, &typelib); + + convert_to_string_ex(&typelib); + convert_to_long_ex(&code_page); codepage = code_page->value.lval; + break; + default: WRONG_PARAM_COUNT; - break; } - convert_to_string(module_name); + if(server_name != NULL) + { + if(server_name->type == IS_NULL) + { + server_name = NULL; + } + else + { + if(!INI_INT("com.allow_dcom")) + { + php_error(E_WARNING, "DCOM is disabled"); + RETURN_FALSE; + } + else + { + convert_to_string_ex(&server_name); + } + } + } + + convert_to_string_ex(&module_name); ProgID = php_char_to_OLECHAR(module_name->value.str.val, module_name->value.str.len, codepage); hr=CLSIDFromProgID(ProgID, &clsid); efree(ProgID); @@ -474,6 +514,43 @@ PHP_FUNCTION(com_load) } php_COM_set(obj, obj->i.dispatch, TRUE); + + if(INI_INT("com.autoregister_casesensitive")) + { + mode |= CONST_CS; + } + + if(obj->typelib) + { + if(INI_INT("com.autoregister_typelib")) + { + unsigned int idx; + + if(obj->i.typeinfo->lpVtbl->GetContainingTypeLib(obj->i.typeinfo, &pTL, &idx) == S_OK) + { + php_COM_load_typelib(pTL, mode); + pTL->lpVtbl->Release(pTL); + } + } + } + else + { + if(typelib != NULL) + { + ITypeLib *pTL; + + if((pTL = php_COM_find_typelib(typelib->value.str.val, mode)) != NULL) + { + obj->typelib = SUCCEEDED(pTL->lpVtbl->GetTypeInfo(pTL, 0, &obj->i.typeinfo)); + /* idx 0 should deliver the ITypeInfo for the IDispatch Interface */ + if(INI_INT("com.autoregister_typelib")) + { + php_COM_load_typelib(pTL, mode); + } + pTL->lpVtbl->Release(pTL); + } + } + } RETURN_LONG(zend_list_insert(obj, le_idispatch)); } @@ -568,7 +645,7 @@ PHP_FUNCTION(com_invoke) } /* obtain property/method handler */ - convert_to_string(function_name); + convert_to_string_ex(&function_name); if(do_COM_invoke(obj, function_name, &var_result, arguments+2, arg_count-2)==FAILURE) { @@ -804,7 +881,7 @@ PHP_FUNCTION(com_propget) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } - convert_to_string(arg_property); + convert_to_string_ex(&arg_property); if(do_COM_propget(&var_result, obj, arg_property, 0)==FAILURE) { @@ -836,12 +913,50 @@ PHP_FUNCTION(com_propput) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } - convert_to_string(arg_property); + convert_to_string_ex(&arg_property); do_COM_propput(return_value, obj, arg_property, arg_value); } /* }}} */ +/* {{{ proto bool com_load_typelib(string typelib_name[, int case_insensitiv]) */ +PHP_FUNCTION(com_load_typelib) +{ + pval *arg_typelib, *arg_cis; + ITypeLib *pTL; + int mode; + + switch(ZEND_NUM_ARGS()) + { + case 1: + getParameters(ht, 1, &arg_typelib); + mode = CONST_PERSISTENT|CONST_CS; + break; + case 2: + getParameters(ht, 2, &arg_typelib, &arg_cis); + convert_to_boolean_ex(&arg_cis); + if(arg_cis->value.lval) + { + mode &= ~CONST_CS; + } + default: + WRONG_PARAM_COUNT; + } + + convert_to_string_ex(&arg_typelib); + pTL = php_COM_find_typelib(arg_typelib->value.str.val, mode); + if(php_COM_load_typelib(pTL, mode) == SUCCESS) + { + pTL->lpVtbl->Release(pTL); + RETVAL_TRUE; + } + else + { + RETVAL_FALSE; + } +} +/* }}} */ + PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_reference) { zend_overloaded_element *overloaded_property; @@ -1135,7 +1250,6 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) char *strtok_buf, *major, *minor; CLSID clsid; OLECHAR *p; - char *ptr; /* Type Libraries: * The string we have is either: @@ -1146,24 +1260,14 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) * 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); - /* 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; @@ -1172,7 +1276,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* We have a valid GUID, check to see if a major/minor */ /* version was specified otherwise assume 1,0 */ - if(major && minor) + if((major != NULL) && (minor != NULL)) { major_i = (WORD) atoi(major); minor_i = (WORD) atoi(minor); @@ -1234,6 +1338,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* 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 */ @@ -1244,8 +1349,9 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) RegCloseKey(hkey); return NULL; } - keyname = malloc(MaxSubKeyLength); - libname = malloc(strlen(search_string)+1); + MaxSubKeyLength++; /* \0 is not counted */ + keyname = emalloc(MaxSubKeyLength); + libname = emalloc(strlen(search_string)+1); for (ii=0;ii<SubKeys;ii++) { if (ERROR_SUCCESS != RegEnumKey(hkey, ii, keyname, MaxSubKeyLength)) @@ -1284,6 +1390,7 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) /* 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 */ @@ -1294,11 +1401,11 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) major = 1; minor = 0; } - str = malloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ + str = emalloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */ sprintf(str, "%s,%d,%d", keyname, major, minor); - free(keyname); + efree(keyname); TypeLib = php_COM_find_typelib(str, mode); - free(str); + efree(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" */ @@ -1313,8 +1420,8 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) } RegCloseKey(hsubkey); } - free(keyname); - free(libname); + efree(keyname); + efree(libname); return NULL; } } @@ -1322,15 +1429,13 @@ static ITypeLib *php_COM_find_typelib(char *search_string, int mode) return TypeLib; } -static int php_COM_load_typelib(char *typelib_name, int mode) +static int php_COM_load_typelib(ITypeLib *TypeLib, 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; @@ -1390,8 +1495,6 @@ static int php_COM_load_typelib(char *typelib_name, int mode) } } - - TypeLib->lpVtbl->Release(TypeLib); return SUCCESS; } |