diff options
Diffstat (limited to 'ext/com_dotnet/com_persist.c')
| -rw-r--r-- | ext/com_dotnet/com_persist.c | 225 |
1 files changed, 113 insertions, 112 deletions
diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c index 7834f897fa..e746814314 100644 --- a/ext/com_dotnet/com_persist.c +++ b/ext/com_dotnet/com_persist.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -20,7 +20,7 @@ /* Infrastructure for working with persistent COM objects. * Implements: IStream* wrapper for PHP streams. - * TODO: Magic __wakeup and __sleep handlers for serialization + * TODO: Magic __wakeup and __sleep handlers for serialization * (can wait till 5.1) */ #ifdef HAVE_CONFIG_H @@ -41,24 +41,23 @@ typedef struct { DWORD engine_thread; LONG refcount; php_stream *stream; - int id; + zend_resource *res; } php_istream; static int le_istream; -static void istream_destructor(php_istream *stm TSRMLS_DC); +static void istream_destructor(php_istream *stm); -static void istream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void istream_dtor(zend_resource *rsrc) { php_istream *stm = (php_istream *)rsrc->ptr; - istream_destructor(stm TSRMLS_CC); + istream_destructor(stm); } #define FETCH_STM() \ php_istream *stm = (php_istream*)This; \ - TSRMLS_FETCH(); \ if (GetCurrentThreadId() != stm->engine_thread) \ return RPC_E_WRONG_THREAD; - + #define FETCH_STM_EX() \ php_istream *stm = (php_istream*)This; \ if (GetCurrentThreadId() != stm->engine_thread) \ @@ -88,7 +87,7 @@ static ULONG STDMETHODCALLTYPE stm_addref(IStream *This) return InterlockedIncrement(&stm->refcount); } - + static ULONG STDMETHODCALLTYPE stm_release(IStream *This) { ULONG ret; @@ -97,18 +96,18 @@ static ULONG STDMETHODCALLTYPE stm_release(IStream *This) ret = InterlockedDecrement(&stm->refcount); if (ret == 0) { /* destroy it */ - if (stm->id) - zend_list_delete(stm->id); + if (stm->res) + zend_list_delete(stm->res); } return ret; } static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, ULONG *pcbRead) { - int nread; + ULONG nread; FETCH_STM(); - nread = php_stream_read(stm->stream, pv, cb); + nread = (ULONG)php_stream_read(stm->stream, pv, cb); if (pcbRead) { *pcbRead = nread > 0 ? nread : 0; @@ -121,10 +120,10 @@ static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, ULO static HRESULT STDMETHODCALLTYPE stm_write(IStream *This, void const *pv, ULONG cb, ULONG *pcbWritten) { - int nwrote; + ULONG nwrote; FETCH_STM(); - nwrote = php_stream_write(stm->stream, pv, cb); + nwrote = (ULONG)php_stream_write(stm->stream, pv, cb); if (pcbWritten) { *pcbWritten = nwrote > 0 ? nwrote : 0; @@ -150,12 +149,12 @@ static HRESULT STDMETHODCALLTYPE stm_seek(IStream *This, LARGE_INTEGER dlibMove, default: return STG_E_INVALIDFUNCTION; } - + if (dlibMove.HighPart) { /* we don't support 64-bit offsets */ return STG_E_INVALIDFUNCTION; } - + offset = (off_t) dlibMove.QuadPart; ret = php_stream_seek(stm->stream, offset, whence); @@ -174,7 +173,7 @@ static HRESULT STDMETHODCALLTYPE stm_set_size(IStream *This, ULARGE_INTEGER libN if (libNewSize.HighPart) { return STG_E_INVALIDFUNCTION; } - + if (php_stream_truncate_supported(stm->stream)) { int ret = php_stream_truncate_set_size(stm->stream, (size_t)libNewSize.QuadPart); @@ -249,12 +248,12 @@ static struct IStreamVtbl php_istream_vtbl = { stm_clone }; -static void istream_destructor(php_istream *stm TSRMLS_DC) +static void istream_destructor(php_istream *stm) { - if (stm->id) { - int id = stm->id; - stm->id = 0; - zend_list_delete(id); + if (stm->res) { + zend_resource *res = stm->res; + stm->res = NULL; + zend_list_delete(res); return; } @@ -262,15 +261,16 @@ static void istream_destructor(php_istream *stm TSRMLS_DC) CoDisconnectObject((IUnknown*)stm, 0); } - zend_list_delete(stm->stream->rsrc_id); + zend_list_delete(stm->stream->res); CoTaskMemFree(stm); } /* }}} */ -PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSRMLS_DC) +PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream) { php_istream *stm = (php_istream*)CoTaskMemAlloc(sizeof(*stm)); + zval *tmp; if (stm == NULL) return NULL; @@ -281,8 +281,9 @@ PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSR stm->refcount = 1; stm->stream = stream; - zend_list_addref(stream->rsrc_id); - stm->id = zend_list_insert(stm, le_istream TSRMLS_CC); + GC_REFCOUNT(stream->res)++; + tmp = zend_list_insert(stm, le_istream); + stm->res = Z_RES_P(tmp); return (IStream*)stm; } @@ -290,10 +291,10 @@ PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSR #define CPH_ME(fname, arginfo) PHP_ME(com_persist, fname, arginfo, ZEND_ACC_PUBLIC) #define CPH_SME(fname, arginfo) PHP_ME(com_persist, fname, arginfo, ZEND_ACC_ALLOW_STATIC|ZEND_ACC_PUBLIC) #define CPH_METHOD(fname) static PHP_METHOD(com_persist, fname) - -#define CPH_FETCH() php_com_persist_helper *helper = (php_com_persist_helper*)zend_object_store_get_object(getThis() TSRMLS_CC); -#define CPH_NO_OBJ() if (helper->unk == NULL) { php_com_throw_exception(E_INVALIDARG, "No COM object is associated with this helper instance" TSRMLS_CC); return; } +#define CPH_FETCH() php_com_persist_helper *helper = (php_com_persist_helper*)Z_OBJ_P(getThis()); + +#define CPH_NO_OBJ() if (helper->unk == NULL) { php_com_throw_exception(E_INVALIDARG, "No COM object is associated with this helper instance"); return; } typedef struct { zend_object std; @@ -341,24 +342,27 @@ CPH_METHOD(GetCurFileName) CPH_FETCH(); CPH_NO_OBJ(); - + res = get_persist_file(helper); if (helper->ipf) { res = IPersistFile_GetCurFile(helper->ipf, &olename); if (res == S_OK) { - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = php_com_olestring_to_string(olename, - &Z_STRLEN_P(return_value), helper->codepage TSRMLS_CC); + size_t len; + char *str = php_com_olestring_to_string(olename, + &len, helper->codepage); + RETVAL_STRINGL(str, len); + // TODO: avoid reallocarion??? + efree(str); CoTaskMemFree(olename); return; } else if (res == S_FALSE) { CoTaskMemFree(olename); RETURN_FALSE; } - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } else { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } } /* }}} */ @@ -370,33 +374,33 @@ CPH_METHOD(SaveToFile) { HRESULT res; char *filename, *fullpath = NULL; - int filename_len; + size_t filename_len; zend_bool remember = TRUE; OLECHAR *olefilename = NULL; CPH_FETCH(); - + CPH_NO_OBJ(); res = get_persist_file(helper); if (helper->ipf) { - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p!|b", + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "p!|b", &filename, &filename_len, &remember)) { - php_com_throw_exception(E_INVALIDARG, "Invalid arguments" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "Invalid arguments"); return; } if (filename) { - fullpath = expand_filepath(filename, NULL TSRMLS_CC); + fullpath = expand_filepath(filename, NULL); if (!fullpath) { RETURN_FALSE; } - - if (php_check_open_basedir(fullpath TSRMLS_CC)) { + + if (php_check_open_basedir(fullpath)) { efree(fullpath); RETURN_FALSE; } - olefilename = php_com_string_to_olestring(filename, strlen(fullpath), helper->codepage TSRMLS_CC); + olefilename = php_com_string_to_olestring(filename, strlen(fullpath), helper->codepage); efree(fullpath); } res = IPersistFile_Save(helper->ipf, olefilename, remember); @@ -412,17 +416,17 @@ CPH_METHOD(SaveToFile) IPersistFile_SaveCompleted(helper->ipf, olefilename); } } - + if (olefilename) { efree(olefilename); } if (FAILED(res)) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } } else { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } } /* }}} */ @@ -433,43 +437,43 @@ CPH_METHOD(LoadFromFile) { HRESULT res; char *filename, *fullpath; - int filename_len; - long flags = 0; + size_t filename_len; + zend_long flags = 0; OLECHAR *olefilename; CPH_FETCH(); - + CPH_NO_OBJ(); res = get_persist_file(helper); if (helper->ipf) { - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &filename, &filename_len, &flags)) { - php_com_throw_exception(E_INVALIDARG, "Invalid arguments" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "Invalid arguments"); return; } - if (!(fullpath = expand_filepath(filename, NULL TSRMLS_CC))) { + if (!(fullpath = expand_filepath(filename, NULL))) { RETURN_FALSE; } - if (php_check_open_basedir(fullpath TSRMLS_CC)) { + if (php_check_open_basedir(fullpath)) { efree(fullpath); RETURN_FALSE; } - olefilename = php_com_string_to_olestring(fullpath, strlen(fullpath), helper->codepage TSRMLS_CC); + olefilename = php_com_string_to_olestring(fullpath, strlen(fullpath), helper->codepage); efree(fullpath); - - res = IPersistFile_Load(helper->ipf, olefilename, flags); + + res = IPersistFile_Load(helper->ipf, olefilename, (DWORD)flags); efree(olefilename); if (FAILED(res)) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } - + } else { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } } /* }}} */ @@ -481,9 +485,9 @@ CPH_METHOD(GetMaxStreamSize) HRESULT res; ULARGE_INTEGER size; CPH_FETCH(); - + CPH_NO_OBJ(); - + res = get_persist_stream_init(helper); if (helper->ipsi) { res = IPersistStreamInit_GetSizeMax(helper->ipsi, &size); @@ -492,16 +496,16 @@ CPH_METHOD(GetMaxStreamSize) if (helper->ips) { res = IPersistStream_GetSizeMax(helper->ips, &size); } else { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); return; } } if (res != S_OK) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } else { /* TODO: handle 64 bit properly */ - RETURN_LONG((LONG)size.QuadPart); + RETURN_LONG((zend_long)size.QuadPart); } } /* }}} */ @@ -512,7 +516,7 @@ CPH_METHOD(InitNew) { HRESULT res; CPH_FETCH(); - + CPH_NO_OBJ(); res = get_persist_stream_init(helper); @@ -520,12 +524,12 @@ CPH_METHOD(InitNew) res = IPersistStreamInit_InitNew(helper->ipsi); if (res != S_OK) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } else { RETURN_TRUE; } } else { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); } } /* }}} */ @@ -539,25 +543,25 @@ CPH_METHOD(LoadFromStream) IStream *stm = NULL; HRESULT res; CPH_FETCH(); - - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstm)) { - php_com_throw_exception(E_INVALIDARG, "invalid arguments" TSRMLS_CC); + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zstm)) { + php_com_throw_exception(E_INVALIDARG, "invalid arguments"); return; } - php_stream_from_zval_no_verify(stream, &zstm); - + php_stream_from_zval_no_verify(stream, zstm); + if (stream == NULL) { - php_com_throw_exception(E_INVALIDARG, "expected a stream" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "expected a stream"); return; } - stm = php_com_wrapper_export_stream(stream TSRMLS_CC); + stm = php_com_wrapper_export_stream(stream); if (stm == NULL) { - php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" TSRMLS_CC); + php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream"); return; } - + res = S_OK; RETVAL_TRUE; @@ -568,7 +572,7 @@ CPH_METHOD(LoadFromStream) res = OleLoadFromStream(stm, &IID_IDispatch, &disp); if (SUCCEEDED(res)) { - php_com_wrap_dispatch(return_value, disp, COMG(code_page) TSRMLS_CC); + php_com_wrap_dispatch(return_value, disp, COMG(code_page)); } } else { res = get_persist_stream_init(helper); @@ -584,7 +588,7 @@ CPH_METHOD(LoadFromStream) IStream_Release(stm); if (FAILED(res)) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); RETURN_NULL(); } } @@ -599,27 +603,27 @@ CPH_METHOD(SaveToStream) IStream *stm = NULL; HRESULT res; CPH_FETCH(); - + CPH_NO_OBJ(); - - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstm)) { - php_com_throw_exception(E_INVALIDARG, "invalid arguments" TSRMLS_CC); + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zstm)) { + php_com_throw_exception(E_INVALIDARG, "invalid arguments"); return; } - php_stream_from_zval_no_verify(stream, &zstm); - + php_stream_from_zval_no_verify(stream, zstm); + if (stream == NULL) { - php_com_throw_exception(E_INVALIDARG, "expected a stream" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "expected a stream"); return; } - stm = php_com_wrapper_export_stream(stream TSRMLS_CC); + stm = php_com_wrapper_export_stream(stream); if (stm == NULL) { - php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" TSRMLS_CC); + php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream"); return; } - + res = get_persist_stream_init(helper); if (helper->ipsi) { res = IPersistStreamInit_Save(helper->ipsi, stm, TRUE); @@ -629,11 +633,11 @@ CPH_METHOD(SaveToStream) res = IPersistStream_Save(helper->ips, stm, TRUE); } } - + IStream_Release(stm); if (FAILED(res)) { - php_com_throw_exception(res, NULL TSRMLS_CC); + php_com_throw_exception(res, NULL); return; } @@ -649,20 +653,20 @@ CPH_METHOD(__construct) zval *zobj = NULL; CPH_FETCH(); - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!", + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &zobj, php_com_variant_class_entry)) { - php_com_throw_exception(E_INVALIDARG, "invalid arguments" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "invalid arguments"); return; } if (!zobj) { return; } - + obj = CDNO_FETCH(zobj); if (V_VT(&obj->v) != VT_DISPATCH || V_DISPATCH(&obj->v) == NULL) { - php_com_throw_exception(E_INVALIDARG, "parameter must represent an IDispatch COM object" TSRMLS_CC); + php_com_throw_exception(E_INVALIDARG, "parameter must represent an IDispatch COM object"); return; } @@ -688,7 +692,7 @@ static const zend_function_entry com_persist_helper_methods[] = { PHP_FE_END }; -static void helper_free_storage(void *obj TSRMLS_DC) +static void helper_free_storage(zend_object *obj) { php_com_persist_helper *object = (php_com_persist_helper*)obj; @@ -704,20 +708,18 @@ static void helper_free_storage(void *obj TSRMLS_DC) if (object->unk) { IUnknown_Release(object->unk); } - zend_object_std_dtor(&object->std TSRMLS_CC); - efree(object); + zend_object_std_dtor(&object->std); } -static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC) +static zend_object* helper_clone(zval *obj) { - php_com_persist_helper *clone, *object = (php_com_persist_helper*)obj; + php_com_persist_helper *clone, *object = (php_com_persist_helper*)Z_OBJ_P(obj); clone = emalloc(sizeof(*object)); memcpy(clone, object, sizeof(*object)); - *clone_ptr = clone; - zend_object_std_init(&clone->std, object->std.ce TSRMLS_CC); + zend_object_std_init(&clone->std, object->std.ce); if (clone->ipf) { IPersistFile_AddRef(clone->ipf); @@ -731,22 +733,20 @@ static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC) if (clone->unk) { IUnknown_AddRef(clone->unk); } + return (zend_object*)clone; } -static zend_object_value helper_new(zend_class_entry *ce TSRMLS_DC) +static zend_object* helper_new(zend_class_entry *ce) { php_com_persist_helper *helper; - zend_object_value retval; helper = emalloc(sizeof(*helper)); memset(helper, 0, sizeof(*helper)); - zend_object_std_init(&helper->std, helper_ce TSRMLS_CC); - - retval.handle = zend_objects_store_put(helper, NULL, helper_free_storage, helper_clone TSRMLS_CC); - retval.handlers = &helper_handlers; + zend_object_std_init(&helper->std, helper_ce); + helper->std.handlers = &helper_handlers; - return retval; + return &helper->std; } int php_com_persist_minit(INIT_FUNC_ARGS) @@ -754,16 +754,17 @@ int php_com_persist_minit(INIT_FUNC_ARGS) zend_class_entry ce; memcpy(&helper_handlers, zend_get_std_object_handlers(), sizeof(helper_handlers)); - helper_handlers.clone_obj = NULL; + helper_handlers.free_obj = helper_free_storage; + helper_handlers.clone_obj = helper_clone; INIT_CLASS_ENTRY(ce, "COMPersistHelper", com_persist_helper_methods); ce.create_object = helper_new; - helper_ce = zend_register_internal_class(&ce TSRMLS_CC); + helper_ce = zend_register_internal_class(&ce); helper_ce->ce_flags |= ZEND_ACC_FINAL; le_istream = zend_register_list_destructors_ex(istream_dtor, NULL, "com_dotnet_istream_wrapper", module_number); - + return SUCCESS; } |
