mirror of
https://github.com/php/php-src.git
synced 2025-08-19 08:49:28 +02:00
no message
This commit is contained in:
parent
6cfba2a3ea
commit
23c65b60a0
2 changed files with 278 additions and 64 deletions
149
ext/com/COM.c
149
ext/com/COM.c
|
@ -69,6 +69,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC);
|
||||||
static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC);
|
static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC);
|
||||||
static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC);
|
static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC);
|
||||||
static void php_register_COM_class(TSRMLS_D);
|
static void php_register_COM_class(TSRMLS_D);
|
||||||
|
static void php_COM_init(int module_number TSRMLS_DC);
|
||||||
|
|
||||||
static int le_comval;
|
static int le_comval;
|
||||||
static int codepage;
|
static int codepage;
|
||||||
|
@ -130,7 +131,7 @@ PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DIS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
switch (hr) {
|
switch (hr) {
|
||||||
case DISP_E_EXCEPTION: {
|
case DISP_E_EXCEPTION: {
|
||||||
int srclen;
|
int srclen;
|
||||||
char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC);
|
char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC);
|
||||||
|
@ -253,13 +254,13 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup
|
||||||
ALLOC_VARIANT(var_result);
|
ALLOC_VARIANT(var_result);
|
||||||
|
|
||||||
if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
|
if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
|
||||||
DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
|
DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
|
||||||
if (V_VT(var_result) == VT_UNKNOWN) {
|
if (V_VT(var_result) == VT_UNKNOWN) {
|
||||||
C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
|
C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
|
||||||
(void**)&C_ENUMVARIANT(obj)));
|
(void**)&C_ENUMVARIANT(obj)));
|
||||||
} else if (V_VT(var_result) == VT_DISPATCH) {
|
} else if (V_VT(var_result) == VT_DISPATCH) {
|
||||||
C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
|
C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
|
||||||
(void**)&C_ENUMVARIANT(obj)));
|
(void**)&C_ENUMVARIANT(obj)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +314,7 @@ PHPAPI char *php_COM_error_message(HRESULT hr TSRMLS_DC)
|
||||||
void *pMsgBuf;
|
void *pMsgBuf;
|
||||||
|
|
||||||
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
||||||
hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) {
|
hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) {
|
||||||
char error_string[] = "No description available";
|
char error_string[] = "No description available";
|
||||||
|
|
||||||
pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string));
|
pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string));
|
||||||
|
@ -376,7 +377,7 @@ static PHP_INI_MH(OnTypelibFileChange)
|
||||||
|
|
||||||
typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
|
typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
|
||||||
|
|
||||||
while(fgets(typelib_name_buffer, 1024, typelib_file)) {
|
while (fgets(typelib_name_buffer, 1024, typelib_file)) {
|
||||||
ITypeLib *pTL;
|
ITypeLib *pTL;
|
||||||
char *typelib_name;
|
char *typelib_name;
|
||||||
char *modifier, *ptr;
|
char *modifier, *ptr;
|
||||||
|
@ -398,11 +399,11 @@ static PHP_INI_MH(OnTypelibFileChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove leading/training white spaces on search_string */
|
/* Remove leading/training white spaces on search_string */
|
||||||
while(isspace(*typelib_name)) {/* Ends on '\0' in worst case */
|
while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
|
||||||
typelib_name ++;
|
typelib_name ++;
|
||||||
}
|
}
|
||||||
ptr = typelib_name + strlen(typelib_name) - 1;
|
ptr = typelib_name + strlen(typelib_name) - 1;
|
||||||
while((ptr != typelib_name) && isspace(*ptr)) {
|
while ((ptr != typelib_name) && isspace(*ptr)) {
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
ptr--;
|
ptr--;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +442,7 @@ PHP_INI_END()
|
||||||
Loads a COM module */
|
Loads a COM module */
|
||||||
PHP_FUNCTION(com_load)
|
PHP_FUNCTION(com_load)
|
||||||
{
|
{
|
||||||
pval *module_name, *code_page, *typelib = NULL, *server_name = NULL;
|
pval *module_name, *code_page, *typelib = NULL, *server_name = NULL, *user_name=NULL, *password=NULL, *domain=NULL;
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
OLECHAR *ProgID;
|
OLECHAR *ProgID;
|
||||||
|
@ -450,7 +451,7 @@ PHP_FUNCTION(com_load)
|
||||||
char *clsid_str;
|
char *clsid_str;
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
ITypeLib *pTL;
|
ITypeLib *pTL;
|
||||||
|
CLSCTX flags = CLSCTX_SERVER;
|
||||||
|
|
||||||
codepage = CP_ACP;
|
codepage = CP_ACP;
|
||||||
|
|
||||||
|
@ -483,8 +484,75 @@ PHP_FUNCTION(com_load)
|
||||||
ZEND_WRONG_PARAM_COUNT();
|
ZEND_WRONG_PARAM_COUNT();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_name != NULL)
|
if (server_name != NULL) {
|
||||||
{
|
/* if a server is passed, one obviously wants to instanciate a
|
||||||
|
* remote server
|
||||||
|
*/
|
||||||
|
flags = CTX_REMOTE_SERVER;
|
||||||
|
|
||||||
|
/* What is server name? A String or an array? */
|
||||||
|
|
||||||
|
if (Z_TYPE_P(server_name) == IS_ARRAY) {
|
||||||
|
pval **tmp;
|
||||||
|
/* DAB: 22 Sept 2001 */
|
||||||
|
/* Aha - we have a number of possible */
|
||||||
|
/* arguments. They are in the hash */
|
||||||
|
/* By name: Server, Domain, Username, Password */
|
||||||
|
/* Flags. */
|
||||||
|
/* This has been crafted to maintian maximum backward */
|
||||||
|
/* compatability, If the server name is specified as a */
|
||||||
|
/* string, then the function shoule behave as before */
|
||||||
|
/* by defaulting username and password and using the */
|
||||||
|
/* (I believe) incorrect CLSCTX_SERVER instantiation */
|
||||||
|
/* paramter. However if server is specified in this array */
|
||||||
|
/* then we use either CLSCTX_REMOTE_SERVER or whatever */
|
||||||
|
/* flags are specified in the array */
|
||||||
|
HashTable *ht = Z_ARRVAL(*server_name);
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Server", 7, (void **) &tmp)) {
|
||||||
|
server_name = NULL;
|
||||||
|
} else {
|
||||||
|
server_name = *tmp;
|
||||||
|
convert_to_string_ex(&server_name);
|
||||||
|
/* CLSCTX_SERVER includes INPROC and LOCAL */
|
||||||
|
/* SERVER. This means that any local server */
|
||||||
|
/* will be instantiated BEFORE even looking */
|
||||||
|
/* on a remote server. Thus if we have a */
|
||||||
|
/* server name, probably we want to access */
|
||||||
|
/* a remote machine or we would not have */
|
||||||
|
/* bothered specifying it. So it would be */
|
||||||
|
/* wrong to to connect locally. Futher, */
|
||||||
|
/* unless the name passed is a GUID, there has */
|
||||||
|
/* to be something to map the Prog.Id to GUID */
|
||||||
|
/* and unless that has been modified to remove */
|
||||||
|
/* the information about local instantiation */
|
||||||
|
/* CLSCTX_SERVER would force a local instantiation */
|
||||||
|
/* This setting can be overridden below if the user */
|
||||||
|
/* specifies a flags element */
|
||||||
|
flags = CLSCTX_REMOTE_SERVER;
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Username", 9, (void **) &tmp)) {
|
||||||
|
user_name = NULL;
|
||||||
|
} else {
|
||||||
|
user_name = *tmp;
|
||||||
|
convert_to_string_ex(&user_name);
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Domain", 7, (void **) &tmp)) {
|
||||||
|
domain = NULL;
|
||||||
|
} else {
|
||||||
|
domain = *tmp;
|
||||||
|
convert_to_string_ex(&domain);
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Password", 9, (void **) &tmp)) {
|
||||||
|
password=NULL;
|
||||||
|
} else {
|
||||||
|
password = *tmp;
|
||||||
|
convert_to_string_ex(&password);
|
||||||
|
}
|
||||||
|
if (SUCCESS == zend_hash_find(ht, "Flags", 6, (void **) &tmp)) {
|
||||||
|
convert_to_long_ex(tmp);
|
||||||
|
flags = (CLSCTX) Z_LVAL_P(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Z_TYPE_P(server_name) == IS_NULL) {
|
if (Z_TYPE_P(server_name) == IS_NULL) {
|
||||||
server_name = NULL;
|
server_name = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -541,20 +609,46 @@ PHP_FUNCTION(com_load)
|
||||||
efree(ProgID);
|
efree(ProgID);
|
||||||
/* obtain IDispatch */
|
/* obtain IDispatch */
|
||||||
if (!server_name) {
|
if (!server_name) {
|
||||||
hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));
|
hr = CoCreateInstance(&clsid, NULL, flags, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));
|
||||||
} else {
|
} else {
|
||||||
COSERVERINFO server_info;
|
COSERVERINFO server_info;
|
||||||
MULTI_QI pResults;
|
MULTI_QI pResults;
|
||||||
|
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};
|
||||||
|
|
||||||
server_info.dwReserved1=0;
|
server_info.dwReserved1=0;
|
||||||
server_info.dwReserved2=0;
|
server_info.dwReserved2=0;
|
||||||
server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);
|
server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);
|
||||||
server_info.pAuthInfo=NULL;
|
if (user_name) {
|
||||||
|
/* Z_STRVAL_P(user_name); */
|
||||||
|
/* Parse Username into domain\username */
|
||||||
|
authid.User = (WCHAR *) Z_STRVAL_P(user_name);
|
||||||
|
authid.UserLength = Z_STRLEN_P(user_name);
|
||||||
|
if (password) {
|
||||||
|
authid.Password = (USHORT *) Z_STRVAL_P(password);
|
||||||
|
authid.PasswordLength = Z_STRLEN_P(password);
|
||||||
|
} else {
|
||||||
|
authid.Password = (USHORT *) "";
|
||||||
|
authid.PasswordLength = 0;
|
||||||
|
}
|
||||||
|
if (domain) {
|
||||||
|
authid.Domain = (USHORT *) Z_STRVAL_P(domain);
|
||||||
|
authid.DomainLength = Z_STRLEN_P(domain);
|
||||||
|
} else {
|
||||||
|
authid.Domain = (USHORT *) "";
|
||||||
|
authid.DomainLength = 0;
|
||||||
|
}
|
||||||
|
authid.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||||
|
|
||||||
|
server_info.pAuthInfo=&authinfo;
|
||||||
|
} else {
|
||||||
|
server_info.pAuthInfo=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pResults.pIID = &IID_IDispatch;
|
pResults.pIID = &IID_IDispatch;
|
||||||
pResults.pItf = NULL;
|
pResults.pItf = NULL;
|
||||||
pResults.hr = S_OK;
|
pResults.hr = S_OK;
|
||||||
hr = CoCreateInstanceEx(&clsid, NULL, CLSCTX_REMOTE_SERVER, &server_info, 1, &pResults);
|
hr=CoCreateInstanceEx(&clsid, NULL, flags, &server_info, 1, &pResults);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = pResults.hr;
|
hr = pResults.hr;
|
||||||
C_DISPATCH(obj) = (IDispatch *) pResults.pItf;
|
C_DISPATCH(obj) = (IDispatch *) pResults.pItf;
|
||||||
|
@ -1367,7 +1461,7 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
|
||||||
&& !strcmp(Z_STRVAL_P(&function_name->element), "release")) {
|
&& !strcmp(Z_STRVAL_P(&function_name->element), "release")) {
|
||||||
RETVAL_LONG(php_COM_release(obj TSRMLS_CC));
|
RETVAL_LONG(php_COM_release(obj TSRMLS_CC));
|
||||||
} else if (zend_llist_count(property_reference->elements_list)==1
|
} else if (zend_llist_count(property_reference->elements_list)==1
|
||||||
&& !strcmp(Z_STRVAL_P(&function_name->element), "addref")) {
|
&& !strcmp(Z_STRVAL_P(&function_name->element), "addref")) {
|
||||||
RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));
|
RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));
|
||||||
} else {
|
} else {
|
||||||
pval **arguments;
|
pval **arguments;
|
||||||
|
@ -1595,7 +1689,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC)
|
||||||
TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
|
TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
|
||||||
|
|
||||||
j=0;
|
j=0;
|
||||||
while(SUCCEEDED(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc))) {
|
while (SUCCEEDED(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc))) {
|
||||||
BSTR bstr_ids;
|
BSTR bstr_ids;
|
||||||
zend_constant c;
|
zend_constant c;
|
||||||
zval exists, results;
|
zval exists, results;
|
||||||
|
@ -1682,14 +1776,27 @@ static void php_register_COM_class(TSRMLS_D)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PHP_MINIT_FUNCTION(COM)
|
static void php_COM_init(int module_number TSRMLS_DC)
|
||||||
{
|
{
|
||||||
le_comval = zend_register_list_destructors_ex(php_comval_destructor, NULL, "COM", module_number);
|
le_comval = zend_register_list_destructors_ex(php_comval_destructor, NULL, "COM", module_number);
|
||||||
php_register_COM_class(TSRMLS_C);
|
php_register_COM_class(TSRMLS_C);
|
||||||
|
}
|
||||||
|
|
||||||
php_VARIANT_init(module_number, TSRMLS_C);
|
|
||||||
|
PHP_MINIT_FUNCTION(COM)
|
||||||
|
{
|
||||||
|
php_COM_init(module_number TSRMLS_CC);
|
||||||
|
php_VARIANT_init(module_number TSRMLS_CC);
|
||||||
|
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_INPROC_SERVER", CLSCTX_INPROC_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_INPROC_HANDLER", CLSCTX_INPROC_HANDLER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_LOCAL_SERVER", CLSCTX_LOCAL_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_REMOTE_SERVER", CLSCTX_REMOTE_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_SERVER", CLSCTX_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_ALL", CLSCTX_ALL, CONST_CS | CONST_PERSISTENT);
|
||||||
|
|
||||||
REGISTER_INI_ENTRIES();
|
REGISTER_INI_ENTRIES();
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC);
|
||||||
static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC);
|
static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC);
|
||||||
static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC);
|
static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC);
|
||||||
static void php_register_COM_class(TSRMLS_D);
|
static void php_register_COM_class(TSRMLS_D);
|
||||||
|
static void php_COM_init(int module_number TSRMLS_DC);
|
||||||
|
|
||||||
static int le_comval;
|
static int le_comval;
|
||||||
static int codepage;
|
static int codepage;
|
||||||
|
@ -130,7 +131,7 @@ PHPAPI HRESULT php_COM_invoke(comval *obj, DISPID dispIdMember, WORD wFlags, DIS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
switch (hr) {
|
switch (hr) {
|
||||||
case DISP_E_EXCEPTION: {
|
case DISP_E_EXCEPTION: {
|
||||||
int srclen;
|
int srclen;
|
||||||
char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC);
|
char *src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC);
|
||||||
|
@ -253,13 +254,13 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup
|
||||||
ALLOC_VARIANT(var_result);
|
ALLOC_VARIANT(var_result);
|
||||||
|
|
||||||
if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
|
if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
|
||||||
DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
|
DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
|
||||||
if (V_VT(var_result) == VT_UNKNOWN) {
|
if (V_VT(var_result) == VT_UNKNOWN) {
|
||||||
C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
|
C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
|
||||||
(void**)&C_ENUMVARIANT(obj)));
|
(void**)&C_ENUMVARIANT(obj)));
|
||||||
} else if (V_VT(var_result) == VT_DISPATCH) {
|
} else if (V_VT(var_result) == VT_DISPATCH) {
|
||||||
C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
|
C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
|
||||||
(void**)&C_ENUMVARIANT(obj)));
|
(void**)&C_ENUMVARIANT(obj)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +314,7 @@ PHPAPI char *php_COM_error_message(HRESULT hr TSRMLS_DC)
|
||||||
void *pMsgBuf;
|
void *pMsgBuf;
|
||||||
|
|
||||||
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
||||||
hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) {
|
hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) {
|
||||||
char error_string[] = "No description available";
|
char error_string[] = "No description available";
|
||||||
|
|
||||||
pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string));
|
pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string));
|
||||||
|
@ -376,7 +377,7 @@ static PHP_INI_MH(OnTypelibFileChange)
|
||||||
|
|
||||||
typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
|
typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
|
||||||
|
|
||||||
while(fgets(typelib_name_buffer, 1024, typelib_file)) {
|
while (fgets(typelib_name_buffer, 1024, typelib_file)) {
|
||||||
ITypeLib *pTL;
|
ITypeLib *pTL;
|
||||||
char *typelib_name;
|
char *typelib_name;
|
||||||
char *modifier, *ptr;
|
char *modifier, *ptr;
|
||||||
|
@ -398,11 +399,11 @@ static PHP_INI_MH(OnTypelibFileChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove leading/training white spaces on search_string */
|
/* Remove leading/training white spaces on search_string */
|
||||||
while(isspace(*typelib_name)) {/* Ends on '\0' in worst case */
|
while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
|
||||||
typelib_name ++;
|
typelib_name ++;
|
||||||
}
|
}
|
||||||
ptr = typelib_name + strlen(typelib_name) - 1;
|
ptr = typelib_name + strlen(typelib_name) - 1;
|
||||||
while((ptr != typelib_name) && isspace(*ptr)) {
|
while ((ptr != typelib_name) && isspace(*ptr)) {
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
ptr--;
|
ptr--;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +442,7 @@ PHP_INI_END()
|
||||||
Loads a COM module */
|
Loads a COM module */
|
||||||
PHP_FUNCTION(com_load)
|
PHP_FUNCTION(com_load)
|
||||||
{
|
{
|
||||||
pval *module_name, *code_page, *typelib = NULL, *server_name = NULL;
|
pval *module_name, *code_page, *typelib = NULL, *server_name = NULL, *user_name=NULL, *password=NULL, *domain=NULL;
|
||||||
CLSID clsid;
|
CLSID clsid;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
OLECHAR *ProgID;
|
OLECHAR *ProgID;
|
||||||
|
@ -450,7 +451,7 @@ PHP_FUNCTION(com_load)
|
||||||
char *clsid_str;
|
char *clsid_str;
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
ITypeLib *pTL;
|
ITypeLib *pTL;
|
||||||
|
CLSCTX flags = CLSCTX_SERVER;
|
||||||
|
|
||||||
codepage = CP_ACP;
|
codepage = CP_ACP;
|
||||||
|
|
||||||
|
@ -483,8 +484,75 @@ PHP_FUNCTION(com_load)
|
||||||
ZEND_WRONG_PARAM_COUNT();
|
ZEND_WRONG_PARAM_COUNT();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_name != NULL)
|
if (server_name != NULL) {
|
||||||
{
|
/* if a server is passed, one obviously wants to instanciate a
|
||||||
|
* remote server
|
||||||
|
*/
|
||||||
|
flags = CTX_REMOTE_SERVER;
|
||||||
|
|
||||||
|
/* What is server name? A String or an array? */
|
||||||
|
|
||||||
|
if (Z_TYPE_P(server_name) == IS_ARRAY) {
|
||||||
|
pval **tmp;
|
||||||
|
/* DAB: 22 Sept 2001 */
|
||||||
|
/* Aha - we have a number of possible */
|
||||||
|
/* arguments. They are in the hash */
|
||||||
|
/* By name: Server, Domain, Username, Password */
|
||||||
|
/* Flags. */
|
||||||
|
/* This has been crafted to maintian maximum backward */
|
||||||
|
/* compatability, If the server name is specified as a */
|
||||||
|
/* string, then the function shoule behave as before */
|
||||||
|
/* by defaulting username and password and using the */
|
||||||
|
/* (I believe) incorrect CLSCTX_SERVER instantiation */
|
||||||
|
/* paramter. However if server is specified in this array */
|
||||||
|
/* then we use either CLSCTX_REMOTE_SERVER or whatever */
|
||||||
|
/* flags are specified in the array */
|
||||||
|
HashTable *ht = Z_ARRVAL(*server_name);
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Server", 7, (void **) &tmp)) {
|
||||||
|
server_name = NULL;
|
||||||
|
} else {
|
||||||
|
server_name = *tmp;
|
||||||
|
convert_to_string_ex(&server_name);
|
||||||
|
/* CLSCTX_SERVER includes INPROC and LOCAL */
|
||||||
|
/* SERVER. This means that any local server */
|
||||||
|
/* will be instantiated BEFORE even looking */
|
||||||
|
/* on a remote server. Thus if we have a */
|
||||||
|
/* server name, probably we want to access */
|
||||||
|
/* a remote machine or we would not have */
|
||||||
|
/* bothered specifying it. So it would be */
|
||||||
|
/* wrong to to connect locally. Futher, */
|
||||||
|
/* unless the name passed is a GUID, there has */
|
||||||
|
/* to be something to map the Prog.Id to GUID */
|
||||||
|
/* and unless that has been modified to remove */
|
||||||
|
/* the information about local instantiation */
|
||||||
|
/* CLSCTX_SERVER would force a local instantiation */
|
||||||
|
/* This setting can be overridden below if the user */
|
||||||
|
/* specifies a flags element */
|
||||||
|
flags = CLSCTX_REMOTE_SERVER;
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Username", 9, (void **) &tmp)) {
|
||||||
|
user_name = NULL;
|
||||||
|
} else {
|
||||||
|
user_name = *tmp;
|
||||||
|
convert_to_string_ex(&user_name);
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Domain", 7, (void **) &tmp)) {
|
||||||
|
domain = NULL;
|
||||||
|
} else {
|
||||||
|
domain = *tmp;
|
||||||
|
convert_to_string_ex(&domain);
|
||||||
|
}
|
||||||
|
if (FAILURE == zend_hash_find(ht, "Password", 9, (void **) &tmp)) {
|
||||||
|
password=NULL;
|
||||||
|
} else {
|
||||||
|
password = *tmp;
|
||||||
|
convert_to_string_ex(&password);
|
||||||
|
}
|
||||||
|
if (SUCCESS == zend_hash_find(ht, "Flags", 6, (void **) &tmp)) {
|
||||||
|
convert_to_long_ex(tmp);
|
||||||
|
flags = (CLSCTX) Z_LVAL_P(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Z_TYPE_P(server_name) == IS_NULL) {
|
if (Z_TYPE_P(server_name) == IS_NULL) {
|
||||||
server_name = NULL;
|
server_name = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -541,20 +609,46 @@ PHP_FUNCTION(com_load)
|
||||||
efree(ProgID);
|
efree(ProgID);
|
||||||
/* obtain IDispatch */
|
/* obtain IDispatch */
|
||||||
if (!server_name) {
|
if (!server_name) {
|
||||||
hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));
|
hr = CoCreateInstance(&clsid, NULL, flags, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));
|
||||||
} else {
|
} else {
|
||||||
COSERVERINFO server_info;
|
COSERVERINFO server_info;
|
||||||
MULTI_QI pResults;
|
MULTI_QI pResults;
|
||||||
|
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};
|
||||||
|
|
||||||
server_info.dwReserved1=0;
|
server_info.dwReserved1=0;
|
||||||
server_info.dwReserved2=0;
|
server_info.dwReserved2=0;
|
||||||
server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);
|
server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);
|
||||||
server_info.pAuthInfo=NULL;
|
if (user_name) {
|
||||||
|
/* Z_STRVAL_P(user_name); */
|
||||||
|
/* Parse Username into domain\username */
|
||||||
|
authid.User = (WCHAR *) Z_STRVAL_P(user_name);
|
||||||
|
authid.UserLength = Z_STRLEN_P(user_name);
|
||||||
|
if (password) {
|
||||||
|
authid.Password = (USHORT *) Z_STRVAL_P(password);
|
||||||
|
authid.PasswordLength = Z_STRLEN_P(password);
|
||||||
|
} else {
|
||||||
|
authid.Password = (USHORT *) "";
|
||||||
|
authid.PasswordLength = 0;
|
||||||
|
}
|
||||||
|
if (domain) {
|
||||||
|
authid.Domain = (USHORT *) Z_STRVAL_P(domain);
|
||||||
|
authid.DomainLength = Z_STRLEN_P(domain);
|
||||||
|
} else {
|
||||||
|
authid.Domain = (USHORT *) "";
|
||||||
|
authid.DomainLength = 0;
|
||||||
|
}
|
||||||
|
authid.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||||
|
|
||||||
|
server_info.pAuthInfo=&authinfo;
|
||||||
|
} else {
|
||||||
|
server_info.pAuthInfo=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pResults.pIID = &IID_IDispatch;
|
pResults.pIID = &IID_IDispatch;
|
||||||
pResults.pItf = NULL;
|
pResults.pItf = NULL;
|
||||||
pResults.hr = S_OK;
|
pResults.hr = S_OK;
|
||||||
hr = CoCreateInstanceEx(&clsid, NULL, CLSCTX_REMOTE_SERVER, &server_info, 1, &pResults);
|
hr=CoCreateInstanceEx(&clsid, NULL, flags, &server_info, 1, &pResults);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
hr = pResults.hr;
|
hr = pResults.hr;
|
||||||
C_DISPATCH(obj) = (IDispatch *) pResults.pItf;
|
C_DISPATCH(obj) = (IDispatch *) pResults.pItf;
|
||||||
|
@ -1367,7 +1461,7 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
|
||||||
&& !strcmp(Z_STRVAL_P(&function_name->element), "release")) {
|
&& !strcmp(Z_STRVAL_P(&function_name->element), "release")) {
|
||||||
RETVAL_LONG(php_COM_release(obj TSRMLS_CC));
|
RETVAL_LONG(php_COM_release(obj TSRMLS_CC));
|
||||||
} else if (zend_llist_count(property_reference->elements_list)==1
|
} else if (zend_llist_count(property_reference->elements_list)==1
|
||||||
&& !strcmp(Z_STRVAL_P(&function_name->element), "addref")) {
|
&& !strcmp(Z_STRVAL_P(&function_name->element), "addref")) {
|
||||||
RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));
|
RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));
|
||||||
} else {
|
} else {
|
||||||
pval **arguments;
|
pval **arguments;
|
||||||
|
@ -1595,7 +1689,7 @@ static int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC)
|
||||||
TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
|
TypeLib->lpVtbl->GetTypeInfo(TypeLib, i, &TypeInfo);
|
||||||
|
|
||||||
j=0;
|
j=0;
|
||||||
while(SUCCEEDED(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc))) {
|
while (SUCCEEDED(TypeInfo->lpVtbl->GetVarDesc(TypeInfo, j, &pVarDesc))) {
|
||||||
BSTR bstr_ids;
|
BSTR bstr_ids;
|
||||||
zend_constant c;
|
zend_constant c;
|
||||||
zval exists, results;
|
zval exists, results;
|
||||||
|
@ -1682,14 +1776,27 @@ static void php_register_COM_class(TSRMLS_D)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PHP_MINIT_FUNCTION(COM)
|
static void php_COM_init(int module_number TSRMLS_DC)
|
||||||
{
|
{
|
||||||
le_comval = zend_register_list_destructors_ex(php_comval_destructor, NULL, "COM", module_number);
|
le_comval = zend_register_list_destructors_ex(php_comval_destructor, NULL, "COM", module_number);
|
||||||
php_register_COM_class(TSRMLS_C);
|
php_register_COM_class(TSRMLS_C);
|
||||||
|
}
|
||||||
|
|
||||||
php_VARIANT_init(module_number, TSRMLS_C);
|
|
||||||
|
PHP_MINIT_FUNCTION(COM)
|
||||||
|
{
|
||||||
|
php_COM_init(module_number TSRMLS_CC);
|
||||||
|
php_VARIANT_init(module_number TSRMLS_CC);
|
||||||
|
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_INPROC_SERVER", CLSCTX_INPROC_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_INPROC_HANDLER", CLSCTX_INPROC_HANDLER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_LOCAL_SERVER", CLSCTX_LOCAL_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_REMOTE_SERVER", CLSCTX_REMOTE_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_SERVER", CLSCTX_SERVER, CONST_CS | CONST_PERSISTENT);
|
||||||
|
REGISTER_LONG_CONSTANT("CLSCTX_ALL", CLSCTX_ALL, CONST_CS | CONST_PERSISTENT);
|
||||||
|
|
||||||
REGISTER_INI_ENTRIES();
|
REGISTER_INI_ENTRIES();
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue