Re: cvs: php4 /ext/w32api php_w32api.h w32api.c w32api_function_definition_parser.y w32api_type_definition_parser.y

From: Date: Wed, 20 Nov 2002 18:51:02 +0000
Subject: Re: cvs: php4 /ext/w32api php_w32api.h w32api.c w32api_function_definition_parser.y w32api_type_definition_parser.y
References: 1  Groups: php.cvs 
Request: Send a blank email to php-cvs+get-16481@lists.php.net to get a copy of this message
Interestingly. Using cygwin and doing a checkout _before_ your changes gave mit dos line endings. Now, after your commit, I get unix line endings. On Wed, Nov 20, 2002 at 06:39:39PM -0000, Frank M. Kromann wrote : > fmk Wed Nov 20 13:39:39 2002 EDT > > Modified files: > /php4/ext/w32api php_w32api.h w32api.c > w32api_function_definition_parser.y > w32api_type_definition_parser.y > Log: > Changing line endings to CRLF. This allows the extension to build again. > > > Index: php4/ext/w32api/php_w32api.h > diff -u php4/ext/w32api/php_w32api.h:1.4 php4/ext/w32api/php_w32api.h:1.5 > --- php4/ext/w32api/php_w32api.h:1.4 Tue Nov 12 09:29:41 2002 > +++ php4/ext/w32api/php_w32api.h Wed Nov 20 13:39:38 2002 > @@ -1,345 +1,345 @@ > -/* > - +----------------------------------------------------------------------+ > - | PHP version 4.0 | > - +----------------------------------------------------------------------+ > - | Copyright (c) 1997-2001 The PHP Group | > - +----------------------------------------------------------------------+ > - | This source file is subject to version 2.02 of the PHP license, | > - | that is bundled with this package in the file LICENSE, and is | > - | available at through the world-wide-web at | > - | http://www.php.net/license/2_02.txt. > | > - | If you did not receive a copy of the PHP license and are unable to | > - | obtain it through the world-wide-web, please send a note to | > - | license@php.net so we can mail you a copy immediately. | > - +----------------------------------------------------------------------+ > - | Authors: James Moore <jmoore@php.net> | > - +----------------------------------------------------------------------+ > -*/ > - > -/* $Id: php_w32api.h,v 1.4 2002/11/12 14:29:41 jmoore Exp $ */ > - > -#if HAVE_W32API > - > -#ifndef PHP_W32API_H > -#define PHP_W32API_H > - > -/* > ================================================================================================ > - * Type Definitions > - * > ================================================================================================ > - */ > -typedef struct _w32api_lib_handle w32api_lib_handle; > -typedef struct _w32api_func_handle w32api_func_handle; > -typedef struct _w32api_type_handle w32api_type_handle; > -typedef struct _w32api_type_instance w32api_type_instance; > -typedef struct _arguments arguments; > -typedef struct _argument argument; > -typedef union > _w32api_parser_function_definition_union w32api_parser_function_definition_union; > -typedef struct _w32api_func_handle_ptr w32api_func_handle_ptr; > -typedef struct _w32api_type_handle_ptr w32api_type_handle_ptr; > -typedef union _w32api_parser_type_definition_union w32api_parser_type_definition_union; > -typedef struct _member member; > -typedef struct _members members; > -typedef union _w32api_result w32api_result; > -typedef struct _w32api_dynamic_param w32api_dynamic_param; > - > -struct _w32api_lib_handle > -{ > - HINSTANCE handle; /* Handle for our library */ > - char *library_name; /* name of our library */ > - int ref_count; /* reference counter */ > -}; > - > -struct _w32api_func_handle_ptr /* Temporary structure */ > -{ /* To work around problems */ > - w32api_func_handle *hnd; /* at 3am.. Ill sort it out */ > -}; /* When I can think straight */ > - > -struct _w32api_type_handle_ptr /* Ditto.. should really combine */ > -{ /* These two into a union at least */ > - w32api_type_handle *hnd; > -}; > - > -struct _w32api_type_handle > -{ > - char *type_name; /* Name of our type */ > - long size; /* Size of type */ > - members *member_list; /* Pointer List of members */ > - long member_count; /* Number of members */ > -}; > - > -struct _w32api_type_instance > -{ > - w32api_type_handle *type; /* pointer to w32api_type_handle */ > - zval **values; /* First element of an array of ptr's to zvals */ > -}; > - > -struct _w32api_func_handle > -{ > - FARPROC handle; /* Handle for our function */ > - w32api_lib_handle *lib; /* Pointer to the library handle */ > - char *function_name; /* Name of our function (Alias is store if supplied) */ > - long return_type_id; /* ID of return type */ > - char *return_type_name; /* Name of return type (if W32API_COMPLEX) */ > - long flags; /* Flags for function */ > - arguments *argument_list; /* Pointer List of arguments */ > -}; > - > -struct _arguments > -{ > - argument *arg; /* Current Argument */ > - arguments *next_arg; /* Next Arugment */ > - arguments *prev_arg; /* Previous Argument */ > -}; > - > -struct _argument > -{ > - long type_id; /* ID of the return type */ > - char *type_name; /* Name of type (if W32API_COMPLEX) */ > - char *argument_name; /* Name of argument, currently not used */ > - long flags; /* Currently used for byref/byval */ > -}; > - > -struct _member > -{ > - char *member_name; > - long member_type_id; > - char *member_type_name; > - long flags; > - long offset; > -}; > - > -struct _members > -{ > - member *member; > - members *next_member; > - members *prev_member; > -}; > - > -union _w32api_result > -{ > - int ival; > - unsigned long lval; > - DWORD dwval; > - void *ptr; > - float fval; > - double dval; > - __int64 i64val; > -}; > - > -struct _w32api_dynamic_param > -{ > - long flags; > - int width; > - union { > - unsigned long argument; > - void *argument_ptr; > - }; > -}; > - > - > -union _w32api_parser_function_definition_union > -{ > - char *s; > - arguments *arg; > -}; > - > -union _w32api_parser_type_definition_union > -{ > - char *s; > - members *type; > -}; > - > -/* > ================================================================================================ > - * Constants > - * > ================================================================================================ > - */ > - > -/* Recognised Base types */ > -#define W32API_UNKNOWN -1 > -#define W32API_NULL 1 > -#define W32API_INT 2 > -#define W32API_LONG 3 > -#define W32API_DOUBLE 4 > -#define W32API_FLOAT 5 > -#define W32API_STRING 6 > -#define W32API_BYTE 7 > -#define W32API_BOOL 8 > -#define W32API_COMPLEX 9 > - > -/* Function Flags */ > -#define W32API_ARGPTR (1<<0) > -#define W32API_BORLAND (1<<1) > -#define W32API_CDECL (1<<2) > -#define W32API_REAL4 (1<<3) > -#define W32API_REAL8 (1<<4) > - > -/* > ================================================================================================ > - * Utility Macros > - * > ================================================================================================ > - */ > -#define PROP_SET_ARGS zend_property_reference *property_reference, pval *value > -#define PROP_GET_ARGS zend_property_reference *property_reference > - > -#define W32API_PROP_SET_FUNCTION_N(class_name) w32api_set_property_handler_##class_name > -#define W32API_PROP_GET_FUNCTION_N(class_name) w32api_get_property_handler_##class_name > -#define W32API_CALL_FUNCTION_N(class_name) w32api_call_handler_##class_name > - > -#define W32API_PROP_SET_FUNCTION(class_name) PHP_W32API_API int > W32API_PROP_SET_FUNCTION_N(class_name)(PROP_SET_ARGS) > -#define W32API_PROP_GET_FUNCTION(class_name) PHP_W32API_API zval > W32API_PROP_GET_FUNCTION_N(class_name)(PROP_GET_ARGS) > -#define W32API_CALL_FUNCITON(class_name) PHP_W32API_API void > W32API_CALL_FUNCTION_N(class_name)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference > *property_reference) > - > -#define W32API_CLASS_FUNCTION(class_name, function_name) > PHP_FUNCTION(##class_name##function_name) > -#define W32API_CLASS_FN(class_name, function_name) PHP_FN(##class_name##function_name) > -#define W32API_CLASS_FE(class_name, function_name, function_args) {#function_name, > W32API_CLASS_FN(class_name, function_name), function_args}, > - > -/* > ================================================================================================ > - * Module exports, Global Variables and General Definitions > - * > ================================================================================================ > - */ > -extern zend_module_entry w32api_module_entry; > -#define phpext_w32api_ptr &w32api_module_entry; > - > -#define PHP_W32API_API __declspec(dllexport) > - > -#ifdef ZTS > -#include "TSRM.h" > -#endif /* ZTS */ > - > -ZEND_BEGIN_MODULE_GLOBALS(w32api) > - zend_class_entry *win32_ce; /* The class entry for our win32 class */ > - zend_class_entry *type_ce; /* The class entry for our type class */ > - HashTable *funcs; /* Functions we registered */ > - HashTable *libraries; /* Libraries we load using LoadLibrary */ > - HashTable *types; /* Types we have registed with us */ > - HashTable *callbacks; /* Callbacks we have registered with us */ > - long le_type_instance; /* Resource hanlde for runtime instances */ > -ZEND_END_MODULE_GLOBALS(w32api) > - > -ZEND_DECLARE_MODULE_GLOBALS(w32api) > - > -#ifdef ZTS > -#define WG(v) TSRMG(w32api_globals_id, zend_w32api_globals *, v) > -#else > -#define WG(v) (w32api_globals.v) > -#endif > - > - > -/* > ================================================================================================ > - * Startup, Shutdown and Info Functions > - * > ================================================================================================ > - */ > -PHP_MINIT_FUNCTION(w32api); > -PHP_MSHUTDOWN_FUNCTION(w32api); > -PHP_RINIT_FUNCTION(w32api); > -PHP_RSHUTDOWN_FUNCTION(w32api); > -PHP_MINFO_FUNCTION(w32api); > -static void php_w32api_init_globals(zend_w32api_globals *w32api_globals); > -static void php_w32api_hash_lib_dtor(void *data); > -static void php_w32api_hash_func_dtor(void *data); > -static void php_w32api_hash_callback_dtor(void *data); > -static void php_w32api_hash_type_dtor(void *data); > -static void w32api_type_instance_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC); > - > -/* > ================================================================================================ > - * Win32 Class Functions > - * > ================================================================================================ > - */ > -int win32_class_init(TSRMLS_D); > -int win32_class_rshutdown(TSRMLS_D); > -W32API_CLASS_FUNCTION(win32, registerfunction); > -W32API_CLASS_FUNCTION(win32, unregisterfunction); > -W32API_CLASS_FUNCTION(win32, registercallback); > -W32API_CLASS_FUNCTION(win32, definetype); > -W32API_CLASS_FUNCTION(win32, gettypesize); > -W32API_CLASS_FUNCTION(win32, inittype); > -W32API_CLASS_FUNCTION(win32, decref); > -W32API_CLASS_FUNCTION(win32, invokefunction); > - > - > -/* > ================================================================================================ > - * Type Class Functions > - * > ================================================================================================ > - */ > -int type_class_init(TSRMLS_DC); > - > -W32API_CLASS_FUNCTION(type, clone); > -W32API_PROP_SET_FUNCTION(type); > -W32API_PROP_GET_FUNCTION(type); > - > -/* > ================================================================================================ > - * Utility Functions > - * > ================================================================================================ > - */ > - > -static int php_w32api_load_function (char *definition, int definition_len, int flags > TSRMLS_DC); > -static void php_w32api_unload_function (w32api_func_handle **fh TSRMLS_DC); > - > -static int php_w32api_load_library (char *library_name, w32api_lib_handle **lh TSRMLS_DC); > -static void php_w32api_unload_library (w32api_lib_handle *lh, int flags TSRMLS_DC); > - > -static int php_w32api_register_callback(char *function_definition, int function_definition_len > TSRMLS_DC); > - > -static void php_w32api_free_arguments(arguments *argument_list); > -static void php_w32api_free_members(members *member_list); > - > -static int php_w32api_get_type_id_from_name(char *type); > -static unsigned char *php_w32api_do_arg_types(arguments **arguments); > - > -void php_w32api_marshall_zval_to_c(argument *arg, w32api_dynamic_param *dp, zval *pzval > TSRMLS_DC); > - > -static void php_w32api_init_type(w32api_type_handle *th, zval *obj TSRMLS_DC); > -static int php_w32api_do_prop_get(zval *object, zval *return_value, zend_llist_element > **element TSRMLS_DC); > -static int php_w32api_do_prop_set(zval *object, zval *value, zend_llist_element **element > TSRMLS_DC); > -static void *php_w32api_complex_marshall_zval_to_c(zval *pzval, int *width, void *data > TSRMLS_DC); > - > -/* > ================================================================================================ > - * Parser & Scanner Functions > - * > ================================================================================================ > - */ > -#define w32api_parser_load_alias_function w32api_parser_load_function_ex > -#define w32api_parser_load_function(return_type, function_name, arguments, library_name) > w32api_parser_load_function_ex (return_type, function_name, NULL, arguments, library_name) > -#define w32api_parser_make_argument_byref(arg_type, arg_name) > w32api_parser_make_argument(arg_type, arg_name, BYREF_FORCE) > -#define w32api_parser_make_argument_byval(arg_type, arg_name) > w32api_parser_make_argument(arg_type, arg_name, BYREF_NONE) > - > -#define w32api_parser_type_make_byref_value(member_name, member_type) > w32api_parser_type_make_value(member_name, member_type, BYREF_FORCE) > -#define w32api_parser_type_make_byval_value(member_name, member_type) > w32api_parser_type_make_value(member_name, member_type, BYREF_NONE) > - > -w32api_func_handle *w32api_parser_load_function_ex(char *return_type, char *function_name, > char *alias_name, arguments *argument_list, char *library_name); > -arguments *w32api_parser_make_argument(char *arg_type, char *arg_name, int byref); > -arguments *w32api_parser_join_arguments(arguments *lval, arguments *rval); > -int w32api_function_definition_error(char *s); > - > -w32api_type_handle *w32api_parser_register_type(char *type_name, members *member_list); > -members *w32api_parser_type_make_value(char *member_name, char *type_name, long flags); > -members *w32api_parser_type_join_values(members *lval, members *rval); > -int w32api_type_definition_error(char *s); > - > -struct yy_buffer_state *w32api_function_definition_scan_bytes(char *bytes, int len); /* > Definied in w32api_function_definition_scanner.c */ > -int w32api_function_definition_parse(void *fh); /* Definied in > w32api_function_definition_parser.c */ > - > -struct yy_buffer_state *w32api_type_definition_scan_bytes(char *bytes, int len); /* Definied > in w32api_type_definition_scanner.c */ > -int w32api_type_definition_parse(void *th); /* Definied in > w32api_type_definition_parser.c */ > - > - > -/* > ================================================================================================ > - * Various Debugging Functions > - * > ================================================================================================ > - */ > -#ifndef NDEBUG > -W32API_CLASS_FUNCTION(win32, dump_library_hash); > -W32API_CLASS_FUNCTION(win32, dump_function_hash); > -W32API_CLASS_FUNCTION(win32, dump_callback_hash); > -W32API_CLASS_FUNCTION(win32, dump_type_hash); > - > -int php_w32api_dump_library_hash_cb(void *pData TSRMLS_DC); > -int php_w32api_dump_function_hash_cb(void *pData TSRMLS_DC); > -int php_w32api_dump_callback_hash_cb(void *pData TSRMLS_DC); > -int php_w32api_dump_type_hash_cb(void *pData TSRMLS_DC); > - > -void php_w32api_print_arguments(arguments *argument_list); > -void php_w32api_print_members(members *member_list); > - > -#endif /* ifndef NDEBUG */ > - > -#endif /* ifndef PHP_W32API_H */ > +/* > + +----------------------------------------------------------------------+ > + | PHP version 4.0 | > + +----------------------------------------------------------------------+ > + | Copyright (c) 1997-2001 The PHP Group | > + +----------------------------------------------------------------------+ > + | This source file is subject to version 2.02 of the PHP license, | > + | that is bundled with this package in the file LICENSE, and is | > + | available at through the world-wide-web at | > + | http://www.php.net/license/2_02.txt. > | > + | If you did not receive a copy of the PHP license and are unable to | > + | obtain it through the world-wide-web, please send a note to | > + | license@php.net so we can mail you a copy immediately. | > + +----------------------------------------------------------------------+ > + | Authors: James Moore <jmoore@php.net> | > + +----------------------------------------------------------------------+ > +*/ > + > +/* $Id: php_w32api.h,v 1.5 2002/11/20 18:39:38 fmk Exp $ */ > + > +#if HAVE_W32API > + > +#ifndef PHP_W32API_H > +#define PHP_W32API_H > + > +/* > ================================================================================================ > + * Type Definitions > + * > ================================================================================================ > + */ > +typedef struct _w32api_lib_handle w32api_lib_handle; > +typedef struct _w32api_func_handle w32api_func_handle; > +typedef struct _w32api_type_handle w32api_type_handle; > +typedef struct _w32api_type_instance w32api_type_instance; > +typedef struct _arguments arguments; > +typedef struct _argument argument; > +typedef union > _w32api_parser_function_definition_union w32api_parser_function_definition_union; > +typedef struct _w32api_func_handle_ptr w32api_func_handle_ptr; > +typedef struct _w32api_type_handle_ptr w32api_type_handle_ptr; > +typedef union _w32api_parser_type_definition_union w32api_parser_type_definition_union; > +typedef struct _member member; > +typedef struct _members members; > +typedef union _w32api_result w32api_result; > +typedef struct _w32api_dynamic_param w32api_dynamic_param; > + > +struct _w32api_lib_handle > +{ > + HINSTANCE handle; /* Handle for our library */ > + char *library_name; /* name of our library */ > + int ref_count; /* reference counter */ > +}; > + > +struct _w32api_func_handle_ptr /* Temporary structure */ > +{ /* To work around problems */ > + w32api_func_handle *hnd; /* at 3am.. Ill sort it out */ > +}; /* When I can think straight */ > + > +struct _w32api_type_handle_ptr /* Ditto.. should really combine */ > +{ /* These two into a union at least */ > + w32api_type_handle *hnd; > +}; > + > +struct _w32api_type_handle > +{ > + char *type_name; /* Name of our type */ > + long size; /* Size of type */ > + members *member_list; /* Pointer List of members */ > + long member_count; /* Number of members */ > +}; > + > +struct _w32api_type_instance > +{ > + w32api_type_handle *type; /* pointer to w32api_type_handle */ > + zval **values; /* First element of an array of ptr's to zvals */ > +}; > + > +struct _w32api_func_handle > +{ > + FARPROC handle; /* Handle for our function */ > + w32api_lib_handle *lib; /* Pointer to the library handle */ > + char *function_name; /* Name of our function (Alias is store if supplied) */ > + long return_type_id; /* ID of return type */ > + char *return_type_name; /* Name of return type (if W32API_COMPLEX) */ > + long flags; /* Flags for function */ > + arguments *argument_list; /* Pointer List of arguments */ > +}; > + > +struct _arguments > +{ > + argument *arg; /* Current Argument */ > + arguments *next_arg; /* Next Arugment */ > + arguments *prev_arg; /* Previous Argument */ > +}; > + > +struct _argument > +{ > + long type_id; /* ID of the return type */ > + char *type_name; /* Name of type (if W32API_COMPLEX) */ > + char *argument_name; /* Name of argument, currently not used */ > + long flags; /* Currently used for byref/byval */ > +}; > + > +struct _member > +{ > + char *member_name; > + long member_type_id; > + char *member_type_name; > + long flags; > + long offset; > +}; > + > +struct _members > +{ > + member *member; > + members *next_member; > + members *prev_member; > +}; > + > +union _w32api_result > +{ > + int ival; > + unsigned long lval; > + DWORD dwval; > + void *ptr; > + float fval; > + double dval; > + __int64 i64val; > +}; > + > +struct _w32api_dynamic_param > +{ > + long flags; > + int width; > + union { > + unsigned long argument; > + void *argument_ptr; > + }; > +}; > + > + > +union _w32api_parser_function_definition_union > +{ > + char *s; > + arguments *arg; > +}; > + > +union _w32api_parser_type_definition_union > +{ > + char *s; > + members *type; > +}; > + > +/* > ================================================================================================ > + * Constants > + * > ================================================================================================ > + */ > + > +/* Recognised Base types */ > +#define W32API_UNKNOWN -1 > +#define W32API_NULL 1 > +#define W32API_INT 2 > +#define W32API_LONG 3 > +#define W32API_DOUBLE 4 > +#define W32API_FLOAT 5 > +#define W32API_STRING 6 > +#define W32API_BYTE 7 > +#define W32API_BOOL 8 > +#define W32API_COMPLEX 9 > + > +/* Function Flags */ > +#define W32API_ARGPTR (1<<0) > +#define W32API_BORLAND (1<<1) > +#define W32API_CDECL (1<<2) > +#define W32API_REAL4 (1<<3) > +#define W32API_REAL8 (1<<4) > + > +/* > ================================================================================================ > + * Utility Macros > + * > ================================================================================================ > + */ > +#define PROP_SET_ARGS zend_property_reference *property_reference, pval *value > +#define PROP_GET_ARGS zend_property_reference *property_reference > + > +#define W32API_PROP_SET_FUNCTION_N(class_name) w32api_set_property_handler_##class_name > +#define W32API_PROP_GET_FUNCTION_N(class_name) w32api_get_property_handler_##class_name > +#define W32API_CALL_FUNCTION_N(class_name) w32api_call_handler_##class_name > + > +#define W32API_PROP_SET_FUNCTION(class_name) PHP_W32API_API int > W32API_PROP_SET_FUNCTION_N(class_name)(PROP_SET_ARGS) > +#define W32API_PROP_GET_FUNCTION(class_name) PHP_W32API_API zval > W32API_PROP_GET_FUNCTION_N(class_name)(PROP_GET_ARGS) > +#define W32API_CALL_FUNCITON(class_name) PHP_W32API_API void > W32API_CALL_FUNCTION_N(class_name)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference > *property_reference) > + > +#define W32API_CLASS_FUNCTION(class_name, function_name) > PHP_FUNCTION(##class_name##function_name) > +#define W32API_CLASS_FN(class_name, function_name) PHP_FN(##class_name##function_name) > +#define W32API_CLASS_FE(class_name, function_name, function_args) {#function_name, > W32API_CLASS_FN(class_name, function_name), function_args}, > + > +/* > ================================================================================================ > + * Module exports, Global Variables and General Definitions > + * > ================================================================================================ > + */ > +extern zend_module_entry w32api_module_entry; > +#define phpext_w32api_ptr &w32api_module_entry; > + > +#define PHP_W32API_API __declspec(dllexport) > + > +#ifdef ZTS > +#include "TSRM.h" > +#endif /* ZTS */ > + > +ZEND_BEGIN_MODULE_GLOBALS(w32api) > + zend_class_entry *win32_ce; /* The class entry for our win32 class */ > + zend_class_entry *type_ce; /* The class entry for our type class */ > + HashTable *funcs; /* Functions we registered */ > + HashTable *libraries; /* Libraries we load using LoadLibrary */ > + HashTable *types; /* Types we have registed with us */ > + HashTable *callbacks; /* Callbacks we have registered with us */ > + long le_type_instance; /* Resource hanlde for runtime instances */ > +ZEND_END_MODULE_GLOBALS(w32api) > + > +ZEND_DECLARE_MODULE_GLOBALS(w32api) > + > +#ifdef ZTS > +#define WG(v) TSRMG(w32api_globals_id, zend_w32api_globals *, v) > +#else > +#define WG(v) (w32api_globals.v) > +#endif > + > + > +/* > ================================================================================================ > + * Startup, Shutdown and Info Functions > + * > ================================================================================================ > + */ > +PHP_MINIT_FUNCTION(w32api); > +PHP_MSHUTDOWN_FUNCTION(w32api); > +PHP_RINIT_FUNCTION(w32api); > +PHP_RSHUTDOWN_FUNCTION(w32api); > +PHP_MINFO_FUNCTION(w32api); > +static void php_w32api_init_globals(zend_w32api_globals *w32api_globals); > +static void php_w32api_hash_lib_dtor(void *data); > +static void php_w32api_hash_func_dtor(void *data); > +static void php_w32api_hash_callback_dtor(void *data); > +static void php_w32api_hash_type_dtor(void *data); > +static void w32api_type_instance_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC); > + > +/* > ================================================================================================ > + * Win32 Class Functions > + * > ================================================================================================ > + */ > +int win32_class_init(TSRMLS_D); > +int win32_class_rshutdown(TSRMLS_D); > +W32API_CLASS_FUNCTION(win32, registerfunction); > +W32API_CLASS_FUNCTION(win32, unregisterfunction); > +W32API_CLASS_FUNCTION(win32, registercallback); > +W32API_CLASS_FUNCTION(win32, definetype); > +W32API_CLASS_FUNCTION(win32, gettypesize); > +W32API_CLASS_FUNCTION(win32, inittype); > +W32API_CLASS_FUNCTION(win32, decref); > +W32API_CLASS_FUNCTION(win32, invokefunction); > + > + > +/* > ================================================================================================ > + * Type Class Functions > + * > ================================================================================================ > + */ > +int type_class_init(TSRMLS_DC); > + > +W32API_CLASS_FUNCTION(type, clone); > +W32API_PROP_SET_FUNCTION(type); > +W32API_PROP_GET_FUNCTION(type); > + > +/* > ================================================================================================ > + * Utility Functions > + * > ================================================================================================ > + */ > + > +static int php_w32api_load_function (char *definition, int definition_len, int flags > TSRMLS_DC); > +static void php_w32api_unload_function (w32api_func_handle **fh TSRMLS_DC); > + > +static int php_w32api_load_library (char *library_name, w32api_lib_handle **lh TSRMLS_DC); > +static void php_w32api_unload_library (w32api_lib_handle *lh, int flags TSRMLS_DC); > + > +static int php_w32api_register_callback(char *function_definition, int function_definition_len > TSRMLS_DC); > + > +static void php_w32api_free_arguments(arguments *argument_list); > +static void php_w32api_free_members(members *member_list); > + > +static int php_w32api_get_type_id_from_name(char *type); > +static unsigned char *php_w32api_do_arg_types(arguments **arguments); > + > +void php_w32api_marshall_zval_to_c(argument *arg, w32api_dynamic_param *dp, zval *pzval > TSRMLS_DC); > + > +static void php_w32api_init_type(w32api_type_handle *th, zval *obj TSRMLS_DC); > +static int php_w32api_do_prop_get(zval *object, zval *return_value, zend_llist_element > **element TSRMLS_DC); > +static int php_w32api_do_prop_set(zval *object, zval *value, zend_llist_element **element > TSRMLS_DC); > +static void *php_w32api_complex_marshall_zval_to_c(zval *pzval, int *width, void *data > TSRMLS_DC); > + > +/* > ================================================================================================ > + * Parser & Scanner Functions > + * > ================================================================================================ > + */ > +#define w32api_parser_load_alias_function w32api_parser_load_function_ex > +#define w32api_parser_load_function(return_type, function_name, arguments, library_name) > w32api_parser_load_function_ex (return_type, function_name, NULL, arguments, library_name) > +#define w32api_parser_make_argument_byref(arg_type, arg_name) > w32api_parser_make_argument(arg_type, arg_name, BYREF_FORCE) > +#define w32api_parser_make_argument_byval(arg_type, arg_name) > w32api_parser_make_argument(arg_type, arg_name, BYREF_NONE) > + > +#define w32api_parser_type_make_byref_value(member_name, member_type) > w32api_parser_type_make_value(member_name, member_type, BYREF_FORCE) > +#define w32api_parser_type_make_byval_value(member_name, member_type) > w32api_parser_type_make_value(member_name, member_type, BYREF_NONE) > + > +w32api_func_handle *w32api_parser_load_function_ex(char *return_type, char *function_name, > char *alias_name, arguments *argument_list, char *library_name); > +arguments *w32api_parser_make_argument(char *arg_type, char *arg_name, int byref); > +arguments *w32api_parser_join_arguments(arguments *lval, arguments *rval); > +int w32api_function_definition_error(char *s); > + > +w32api_type_handle *w32api_parser_register_type(char *type_name, members *member_list); > +members *w32api_parser_type_make_value(char *member_name, char *type_name, long flags); > +members *w32api_parser_type_join_values(members *lval, members *rval); > +int w32api_type_definition_error(char *s); > + > +struct yy_buffer_state *w32api_function_definition_scan_bytes(char *bytes, int len); /* > Definied in w32api_function_definition_scanner.c */ > +int w32api_function_definition_parse(void *fh); /* Definied in > w32api_function_definition_parser.c */ > + > +struct yy_buffer_state *w32api_type_definition_scan_bytes(char *bytes, int len); /* Definied > in w32api_type_definition_scanner.c */ > +int w32api_type_definition_parse(void *th); /* Definied in > w32api_type_definition_parser.c */ > + > + > +/* > ================================================================================================ > + * Various Debugging Functions > + * > ================================================================================================ > + */ > +#ifndef NDEBUG > +W32API_CLASS_FUNCTION(win32, dump_library_hash); > +W32API_CLASS_FUNCTION(win32, dump_function_hash); > +W32API_CLASS_FUNCTION(win32, dump_callback_hash); > +W32API_CLASS_FUNCTION(win32, dump_type_hash); > + > +int php_w32api_dump_library_hash_cb(void *pData TSRMLS_DC); > +int php_w32api_dump_function_hash_cb(void *pData TSRMLS_DC); > +int php_w32api_dump_callback_hash_cb(void *pData TSRMLS_DC); > +int php_w32api_dump_type_hash_cb(void *pData TSRMLS_DC); > + > +void php_w32api_print_arguments(arguments *argument_list); > +void php_w32api_print_members(members *member_list); > + > +#endif /* ifndef NDEBUG */ > + > +#endif /* ifndef PHP_W32API_H */ > #endif /* if HAVE_W32API */ > Index: php4/ext/w32api/w32api.c > diff -u php4/ext/w32api/w32api.c:1.5 php4/ext/w32api/w32api.c:1.6 > --- php4/ext/w32api/w32api.c:1.5 Tue Nov 12 09:29:41 2002 > +++ php4/ext/w32api/w32api.c Wed Nov 20 13:39:38 2002 > @@ -1,2287 +1,2287 @@ > -/* > - +----------------------------------------------------------------------+ > - | PHP version 4.0 | > - +----------------------------------------------------------------------+ > - | Copyright (c) 1997-2001 The PHP Group | > - +----------------------------------------------------------------------+ > - | This source file is subject to version 2.02 of the PHP license, | > - | that is bundled with this package in the file LICENSE, and is | > - | available at through the world-wide-web at | > - | http://www.php.net/license/2_02.txt. > | > - | If you did not receive a copy of the PHP license and are unable to | > - | obtain it through the world-wide-web, please send a note to | > - | license@php.net so we can mail you a copy immediately. | > - +----------------------------------------------------------------------+ > - | Authors: James Moore <jmoore@php.net> | > - +----------------------------------------------------------------------+ > - */ > - > -/* $Id: w32api.c,v 1.5 2002/11/12 14:29:41 jmoore Exp $ */ > - > -/* > - * Win32 API Extension for PHP 4 > - * ============================= > - * > - * This extension allows PHP Developers to access the underlying functions in the > - * Win32 API Dll's in a generic way, it provides a mechanism for the user to load > - * and register functions from dll's and then to call them, it also implements a > - * generic callback handler which allows the user to pass a pointer to one of > - * their PHP functions to act as a callback from the C function enabling the PHP > - * programmer to handle callbacks in PHP seemlessly. Finally the extension marshalls > - * from PHP types (Zvals) to C structures seemlessly once it has been told about them > - * > - * I would like to thank Ton Plooy for his article on a similar subject which gave me > - * the initial idea for a generic dll caller and some good pointers on how to actaully > - * implement it. > - */ > - > -/* > - * Interface the PHP Programmer Sees > - * ================================== > - * > - * To keep namespaces tidy the module will introduce two classes, the first is > - * the win32 class which has several functions to load and register functions from > - * the underlying DLL's. The Win32 class also has functions for informing the > - * module about the C types we will be using so it can marshall and demarshall to and from > - * the C Interface. . Our second class is the Type class. The type class is our container > - * for complex C types which are registered and initiated using our win32 class functions. > - * > - * Win32 Class Functions > - * ===================== > - * > - * static int Win32::RegisterFunction( string Definition, long flags ) > - * ------------------------------------------------------------------- > - * > - * This function is used for registering a dll function with the module. The Definition should > take > - * the form: > - * Definition: <return_type> <function_name> [Alias <alias_name] > (<argument_list>) From <some_dll> > - * > - * return_type :- Either a simple type or a type that has > - * been registered with the module > - * > - * function_name :- The name of the function within the dll, if this is not found > - * we append an A to the function name to check for a ASCII > version, > - * if this is not found we fail. > - * > - * alias_name :- If this is provided then we register the function under this > name > - * in the PHP Symbol table. > - * > - * argument_list :- A comma seperated list of arguments in the form > <argument_type> > - * [&]argument_name. > - * > - * argument_type :- Argument type is a type known to the module > - * > - * argument_name :- This is not currently used although if it is proceeded by > an > - * & (Ampersand) then a pointer is passed rather than the > value. > - * > - * some_dll :- This is the name of the dll to find the function in. > - * > - * On success the function returns TRUE, on error FALSE, The function issues appropriate > errors > - * to allow the PHP Progammer to catch individual errors. > - * > - * static int Win32::UnregisterFunction(string FunctionName) > - * --------------------------------------------------------- > - * > - * Allows the PHP programmer to force a funciton to be unregistered saving on memory > resources. Can > - * be useful in long running scripts. > - * > - * Returns TRUE on success, FALSE on error. > - * > - * > - * static int Win32::DefineType( string Definition ) > - * ------------------------------------------------- > - * > - * This function is used to register a C-Type which will be used when calling a function, it > only > - * supports the equivilent of C structures at this time so if you need to use a union you must > use the > - * largest member of that union as the type in the struct for this to work. > - * > - * The definition string takes the form: > - * > - * Definition: <type_name> { <type_list> } > - * > - * type_name :- A unique name for this type. > - * > - * type_list :- Takes for form <member_type> [&]<member_name> > - * > - * member_type :- The type of this member. > - * > - * member_name :- The name for this member, if an & (ampersand) preceeds > - * the name it will be stripped and a pointer rather than > - * the value will be used. > - * > - * Returns TRUE on success, FALSE on error. > - * > - * > - * static int Win32::GetTypeSize(mixed TypeHandle) > - * ----------------------------------------------- > - * > - * This function returns the size of a type registered with the module. The parameter should > - * either be the name of the type or an instance of it. The Function returns FALSE on error > - * ***USE === to distinguish between this and a size of 0*** or the size of the type on > success. > - * > - * > - * static mixed Win32::InitType(String TypeName) > - * --------------------------------------------- > - * > - * Creates an instance of the type so that the PHP Programmer can assign values and then pass > - * it to a C Function. Returns NULL on error. > - * > - * static int Win32::DecRef(mixed var) > - * ----------------------------------- > - * Decreases the reference count on a variable only if we incremented the refcount when > passing > - * the variable to a C function. > - * > - * TYPE Functions > - * ============== > - * > - * mixed Type::Type(String TypeName) > - * --------------------------------- > - * See Win32::InitType, > - * > - * mixed Type::Clone() > - * ------------------- > - * > - * Allows you to make an exact copy of the class, this should be used rather than the &= > syntax > - * Due to the nesting within classes. This function WILL become redundant in PHP 5. > - */ > - > -/* > - * Implementation Details > - * ====================== > - * > - * This module will only work on the Intel platform. > - * > - * We basically want to set up this structure: > - * > - * +-----------+ > - * | PHP | > - * +-----------+ > - * Call | /|\ > - * \|/ | call_user_function_ex > - * +------------------------+ > - * | Win 32 API Extension | > - * +------------------------+ > - * | /|\ > - * \|/ | Callback > - * +-------------+ > - * | C-Space | > - * +-------------+ > - * > - * Win32 Needs to then Marshall between zvals and > - * > - * Marshalling from ZVAL's to C Types. > - * ----------------------------------- > - * For simple types this is very easy as we either just copy the value or a pointer > - * to it onto the stack, if we copy a pointer then we must increase the refcount on > - * the zval and must also make sure we get it passed to us by reference. > - * > - * The problem here is when to dereference the zval again as we may get into the following > - * situation > - * > - * We call somefunction giving it an argument by reference (IE we pass a pointer to the value > union of a zval) > - * we must increase the ref count on the zval to avoid the possibility of a GPE (IE the zval > is dtord and then > - * the function uses the zval in some sort of callback we could end up with a GPE) > - * But if we increase the zval's refcount without dtoring it anywhere it would cause a > mem leak. > - * > - * Therefore we probably need to keep a local reference table so we can either allow the user > to call > - * Win32::DecRef($var) to decrement the reference count (We would want to keep a local table > to avoid anyone > - * breaking Zend's handling off it as well..)) > - * > - * Then at MSHUTDOWN we free this hashtable decrementing the refcount as needed.. > - * > - * Complex types are less clear cut on how to handle them. My prefered method is to always > - * keep these in a C Format but to allow access to these via a wrapper object which calculates > - * the offset of the data to allow access to it from PHP. This also allows us to do no > conversion > - * when dealing with C types coming to us allowing us to deal with pointers in a more clear > way. > - * > - * > - * Enabling C Code to call PHP Code in a generic fashion > - * ----------------------------------------------------- > - * What we do here is we use _declspec(naked) to tell the compiler we will handle all stack > operations > - * ourself, we also then create (At runtime) function prologues which we place on the heap > which push > - * extra arguments onto the stack which tell us which php_function is being called back and > the callback type > - * which has been registered with us. > - * > - */ > - > -#if HAVE_W32API > - > -#include <stdio.h> > -#include <stdlib.h> > - > -#define WINDOWS_LEAN_AND_MEAN > -#include <windows.h> > - > -#include "php.h" > -#include "php_ini.h" > -#include "ext/standard/info.h" > -#include "ext/standard/php_string.h" > -#include "php_w32api.h" > - > - > -/* > ===================================================================================================== > - * PHP Module Startup, Shutdown & Info Code > - * > ===================================================================================================== > - */ > - > -#ifdef COMPILE_DL_W32API > -ZEND_GET_MODULE(w32api) > -#endif > - > -/* {{{ w32api_module_entry > - */ > -zend_module_entry w32api_module_entry = { > - STANDARD_MODULE_HEADER, > - "Win32 API", > - NULL, /* We define no global functions */ > - PHP_MINIT(w32api), > - PHP_MSHUTDOWN(w32api), > - PHP_RINIT(w32api), > - PHP_RSHUTDOWN(w32api), > - PHP_MINFO(w32api), > - "0.2", > - STANDARD_MODULE_PROPERTIES > -}; > -/* }}} */ > - > - > -/* {{{ PHP_MINIT_FUNCTION > - */ > -PHP_MINIT_FUNCTION(w32api) > -{ > - /* Setup out module globals */ > - ZEND_INIT_MODULE_GLOBALS(w32api, php_w32api_init_globals, NULL); > - > - > - if(win32_class_init(TSRMLS_C) != SUCCESS) > - { > - return FAILURE; > - } > - > - if(type_class_init(TSRMLS_C) != SUCCESS) > - { > - return FAILURE; > - } > - > - WG(le_type_instance) = zend_register_list_destructors_ex(w32api_type_instance_dtor, NULL, > "Type Instance", module_number); > - > - /* Function Flags */ > - REGISTER_LONG_CONSTANT( "W32API_ARGPTR", W32API_ARGPTR, CONST_CS | > CONST_PERSISTENT); > - REGISTER_LONG_CONSTANT( "W32API_BORLAND", W32API_BORLAND, CONST_CS | > CONST_PERSISTENT); > - REGISTER_LONG_CONSTANT( "W32API_CDECL", W32API_CDECL, CONST_CS | > CONST_PERSISTENT); > - REGISTER_LONG_CONSTANT( "W32API_REAL4", W32API_REAL4, CONST_CS | > CONST_PERSISTENT); > - REGISTER_LONG_CONSTANT( "W32API_REAL8", W32API_REAL8, CONST_CS | > CONST_PERSISTENT); > - > - > - return SUCCESS; > - > -}; > -/* }}} */ > - > -/* {{{ PHP_MSHUTDOWN_FUNCTION > - */ > -PHP_MSHUTDOWN_FUNCTION(w32api) > -{ > - return SUCCESS; > -} > -/* }}} */ > - > -/* {{{ PHP_RINIT_FUNCTION > - */ > -PHP_RINIT_FUNCTION(w32api) > -{ > - /* Allocate Request Specific HT's here > - */ > - ALLOC_HASHTABLE(WG(funcs)); > - zend_hash_init(WG(funcs), 1, NULL, php_w32api_hash_func_dtor, 1); > - > - ALLOC_HASHTABLE(WG(libraries)); > - zend_hash_init(WG(libraries), 1, NULL, php_w32api_hash_lib_dtor, 1); > - > - ALLOC_HASHTABLE(WG(callbacks)); > - zend_hash_init(WG(callbacks), 1, NULL, php_w32api_hash_callback_dtor, 1); > - > - ALLOC_HASHTABLE(WG(types)); > - zend_hash_init(WG(types), 1, NULL, php_w32api_hash_type_dtor, 1); > - > - > - return SUCCESS; > - > -}; > -/* }}} */ > - > -/* {{{ PHP_RSHUTDOWN_FUNCTION > - */ > -PHP_RSHUTDOWN_FUNCTION(w32api) > -{ > - > - win32_class_rshutdown(TSRMLS_C); > - > - /* Must be dtor'd before libraries */ > - zend_hash_destroy(WG(funcs)); > - FREE_HASHTABLE(WG(funcs)); > - > - zend_hash_destroy(WG(libraries)); > - FREE_HASHTABLE(WG(libraries)); /* we may only want to do this on MSHUTDOWN but for now it can > be here */ > - > - zend_hash_destroy(WG(callbacks)); > - FREE_HASHTABLE(WG(callbacks)); > - > - zend_hash_destroy(WG(types)); > - FREE_HASHTABLE(WG(types)); > - > - > - return SUCCESS; > -} > -/* }}} */ > - > - > -/* {{{ PHP_MINFO_FUNCTION > - */ > -PHP_MINFO_FUNCTION(w32api) > -{ > - php_info_print_table_start(); > - php_info_print_table_row(2, "Win32 API Support", "enabled" ); > - php_info_print_table_end(); > -} > -/* }}} */ > - > -/* {{{ php_w32api_init_globals > - */ > -static void php_w32api_init_globals(zend_w32api_globals *w32api_globals) > -{ > - w32api_globals->win32_ce = NULL; > - w32api_globals->type_ce = NULL; > - w32api_globals->funcs = NULL; > - w32api_globals->libraries = NULL; > - w32api_globals->callbacks = NULL; > - w32api_globals->types = NULL; > -} > -/* }}} */ > - > -/* {{{ php_w32api_hash_lib_dtor (void *data) > - * Dtor function called when hash is destroied, unloads library > - */ > -static void php_w32api_hash_lib_dtor(void *data) > -{ > - w32api_lib_handle *lh; /* Library Handle */ > - TSRMLS_FETCH(); /* Get thread safe stuff */ > - lh = (w32api_lib_handle *)data; > - > - FreeLibrary(lh->handle); > - efree(lh->library_name); > -} > -/* }}} */ > - > -/* {{{ php_w32api_hash_func_dtor (void *data) > - * Dtor function called when hash is destroied, unloads function. > - */ > -static void php_w32api_hash_func_dtor(void *data) > -{ > - w32api_func_handle **fh; /* Function Handle */ > - TSRMLS_FETCH(); /* Get thread safe stuff */ > - > - fh = (w32api_func_handle **)data; > - php_w32api_unload_function(fh TSRMLS_CC); > -} > -/* }}} */ > - > -/* {{{ php_w32api_hash_callback_dtor > - * DTOR function called when hash is destroied, removes callback. > - */ > -static void php_w32api_hash_callback_dtor(void *data) > -{ > - w32api_func_handle **fh; > - > - fh = (w32api_func_handle **)data; > - > - php_w32api_free_arguments((*fh)->argument_list); > - efree((*fh)->function_name); > - > - if((*fh)->return_type_name) > - efree((*fh)->return_type_name); > - > - efree(*fh); > -} > - > -/* {{{ php_w32api_hash_type_dtor > - * DTOR function called when hash is destroied, removes callback. > - */ > -static void php_w32api_hash_type_dtor(void *data) > -{ > - w32api_type_handle **th; > - > - th = (w32api_type_handle **)data; > - > - php_w32api_free_members((*th)->member_list); > - efree((*th)->type_name); > - efree(*th); > -} > - > -static void w32api_type_instance_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) > -{ > - w32api_type_instance *ti; > - int i = 0; > - > - if(!rsrc || !rsrc->ptr) > - return; > - > - ti = (w32api_type_instance *)rsrc->ptr; > - > - for(i = 0; i < ti->type->member_count; i++) > - { > - if(ti->values[i]) > - zval_ptr_dtor(&ti->values[i]); > - } > - > - efree(ti); > - > - return; > -} > -/* > ===================================================================================================== > - * Utility Functions > - * > ===================================================================================================== > - */ > - > -/* {{{ php_w32api_unload_library > - * Expects two arguments, the first is the pointer to a w32api_lib_handle > - * and the second is a flag, if the flag is 0 then the reference counter is > - * use if it is one then the library is unloaded irrespective of the reference > - * counter > - */ > -static void php_w32api_unload_library (w32api_lib_handle *lh, int flags TSRMLS_DC) > -{ > - > - if(flags == 0) > - { > - lh->ref_count--; > - } > - > - if((flags == 1) || (lh->ref_count == 0)) > - { > - /* remove outselves from the hashtable */ > - zend_hash_del(WG(libraries), lh->library_name, strlen(lh->library_name) + 1); > - } > -} > -/* }}} */ > - > -/* {{{ php_w32api_unload_function > - * Expects one argument, a pointer to a w32api_func_handle, unloads this > - * function from both the function table internally and the PHP function > - * table then it decrements the reference counter on the library. > - */ > -static void php_w32api_unload_function (w32api_func_handle **fh TSRMLS_DC) > -{ > - zend_function *function = NULL; > - > - efree((*fh)->return_type_name); > - php_w32api_free_arguments((*fh)->argument_list); > - > - /* If needs be we need to retrieve function ptr from hash table > - * and free anything we allocate when creating them at runtime (most notably > - * arg_types > - */ > - if(zend_hash_find( &WG(win32_ce)->function_table, > - (*fh)->function_name, > - strlen((*fh)->function_name) + 1, > - (void **)&function) == SUCCESS) > - { > - zend_internal_function *internal_function = (zend_internal_function *)function; > - if(internal_function->arg_types) > - efree(internal_function->arg_types); > - } > - > - /* Remove from Function Table */ > - zend_hash_del(&WG(win32_ce)->function_table, (*fh)->function_name, > strlen((*fh)->function_name) + 1); > - php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); > - > - efree((*fh)->function_name); > - efree(*fh); > - > -} > -/* }}} */ > - > -/* {{{ php_w32api_load_function > - * Expects three arguments, The definition of the function in string format, the definitions > length > - * and a pointer to a pointer to a function handle. returns SUCCESS or FAILURE. > - */ > -static int php_w32api_load_function (char *definition, int definition_len, int flags > TSRMLS_DC) > -{ > - zend_function function; > - zend_internal_function *internal_function = (zend_internal_function *)&function; > - w32api_func_handle **fh; > - w32api_func_handle_ptr hnd; > - > - fh = emalloc(sizeof(w32api_func_handle *)); > - *fh = NULL; > - > - /* Parse function */ > - w32api_function_definition_scan_bytes(definition, definition_len); > - if((w32api_function_definition_parse((void *)&hnd) != 0)) > - { > - *fh = hnd.hnd; > - if(*fh != NULL) > - efree(*fh); > - > - efree(fh); > - return FAILURE; > - } > - *fh = hnd.hnd; > - > - if(!*fh) > - return FAILURE; > - > - > - if(zend_hash_exists(&WG(win32_ce)->function_table, (*fh)->function_name, > strlen((*fh)->function_name) + 1)) > - { > - php_error( E_WARNING, > - "A function by the name %s already has been registered, cannot redefine > function", > - (*fh)->function_name); > - > - /* We dont want to unload function as it already exists so lets just free it ourselves */ > - php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); > - php_w32api_free_arguments((*fh)->argument_list); > - efree((*fh)->return_type_name); > - efree((*fh)->function_name); > - efree(*fh); > - efree(fh); > - > - return FAILURE; > - } > - > - /* Insert it into our hash table */ > - if(zend_hash_add( WG(funcs), > - (*fh)->function_name, > - strlen((*fh)->function_name) + 1, > - fh, > - sizeof(w32api_func_handle), > - NULL) != SUCCESS) > - { > - > - php_error( E_WARNING, > - "Loading of function %s failed: Could not insert function handle into hash", > - (*fh)->function_name); > - > - /* Tidy up */ > - zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); > - return FAILURE; > - } > - > - /* Insert function into win32_ce's function_table */ > - internal_function->type = ZEND_INTERNAL_FUNCTION; > - internal_function->handler = W32API_CLASS_FN(win32, invokefunction); > - internal_function->function_name = (*fh)->function_name; > - internal_function->arg_types = php_w32api_do_arg_types(&(*fh)->argument_list); > - > - if(zend_hash_add(&WG(win32_ce)->function_table, (*fh)->function_name, > - strlen((*fh)->function_name) + 1, &function, sizeof(zend_function), NULL) == > FAILURE) > - { > - php_error(E_ERROR, "Could not register funciton %s into function table", > (*fh)->function_name); > - zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); > - > - return FAILURE;; > - } > - > - if(flags) > - { > - (*fh)->flags = (*fh)->flags | flags; > - } > - > - > - return SUCCESS; > -} > -/* }}} */ > - > -/* {{{ php_w32api_unload_type > - * Expects one argument, a pointer to a w32api_type_handle, unloads this > - * type. > - */ > -static void php_w32api_unload_type (w32api_type_handle **th TSRMLS_DC) > -{ > - php_w32api_free_members((*th)->member_list); > - > - zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1); > - > -} > -/* }}} */ > - > -/* {{{ php_w32api_register_type > - */ > -static int php_w32api_register_type(char *type_definition, int type_definition_len TSRMLS_DC) > -{ > - w32api_type_handle **th; > - w32api_type_handle_ptr hnd; > - > - th = emalloc(sizeof(w32api_type_handle *)); > - *th = NULL; > - > - w32api_type_definition_scan_bytes(type_definition, type_definition_len); > - if(w32api_type_definition_parse((void *)&hnd) != 0) > - { > - *th = hnd.hnd; > - > - /* Leaks */ > - if(*th != NULL) > - efree(*th); > - > - efree(th); > - return FAILURE; > - } > - > - *th = hnd.hnd; > - > - if(!*th) > - return FAILURE; > - > - if((zend_hash_exists(WG(callbacks), (*th)->type_name, strlen((*th)->type_name) +1)) || > - (zend_hash_exists(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1))) > - { > - php_error( E_WARNING, > - "A type or callback by the name %s already has been registered, cannot redefine > type or callback", > - (*th)->type_name); > - > - /* We dont want to unload function as it already exists so lets just free it ourselves */ > - php_w32api_free_members((*th)->member_list); > - efree((*th)->type_name); > - efree(*th); > - efree(th); > - > - return FAILURE; > - } > - > - /* Insert it into our hash table */ > - if(zend_hash_add( WG(types), > - (*th)->type_name, > - strlen((*th)->type_name) + 1, > - th, > - sizeof(w32api_type_handle *), > - NULL) != SUCCESS) > - { > - > - php_error( E_WARNING, > - "Loading of type %s failed: Could not insert type handle into hash", > - (*th)->type_name); > - > - /* Tidy up */ > - zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1); > - return FAILURE; > - } > - > - return SUCCESS; > - > -} > -/* }}} */ > - > - > -/* {{{ php_w32api_register_callback > - */ > -static int php_w32api_register_callback(char *function_definition, int function_definition_len > TSRMLS_DC) > -{ > - w32api_func_handle **fh; > - w32api_func_handle_ptr hnd; > - > - char *new_definition = NULL; > - > - fh = emalloc(sizeof(w32api_func_handle *)); > - *fh = NULL; > - > - new_definition = emalloc(function_definition_len + sizeof(" from cb.cb")); > - > - snprintf(new_definition, function_definition_len + sizeof(" from cb.cb"), "%s > from cb.cb", function_definition); > - > - > - /* Parse function */ > - w32api_function_definition_scan_bytes(new_definition, function_definition_len + sizeof(" > from cb.cb")); > - if(w32api_function_definition_parse((void *)&hnd) != 0) > - { > - *fh = hnd.hnd; > - > - /* Leaks */ > - if(*fh != NULL) > - efree(*fh); > - > - efree(fh); > - return FAILURE; > - } > - *fh = hnd.hnd; > - > - if(!*fh) > - return FAILURE; > - > - > - if(zend_hash_exists(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + > 1)) > - { > - php_error( E_WARNING, > - "A callback by the name %s already has been registered, cannot redefine > type", > - (*fh)->function_name); > - > - /* We dont want to unload function as it already exists so lets just free it ourselves */ > - php_w32api_free_arguments((*fh)->argument_list); > - efree((*fh)->return_type_name); > - efree((*fh)->function_name); > - efree(*fh); > - efree(fh); > - > - return FAILURE; > - } > - > - /* Insert it into our hash table */ > - if(zend_hash_add( WG(callbacks), > - (*fh)->function_name, > - strlen((*fh)->function_name) + 1, > - fh, > - sizeof(w32api_func_handle *), > - NULL) != SUCCESS) > - { > - > - php_error( E_WARNING, > - "Loading of function %s failed: Could not insert function handle into hash", > - (*fh)->function_name); > - > - /* Tidy up */ > - zend_hash_del(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + 1); > - return FAILURE; > - } > - > - return SUCCESS; > - > - > - > -} > -/* }}} */ > - > - > -/* {{{ php_w32api_free_arguments > - * Expects one argument, the head of a list of arguments to free > - */ > -static void php_w32api_free_arguments(arguments *argument_list) > -{ > - if(argument_list == NULL) > - return; > - > - efree(argument_list->arg->argument_name); > - efree(argument_list->arg->type_name); > - efree(argument_list->arg); > - > - if(argument_list->next_arg != NULL) > - { > - php_w32api_free_arguments(argument_list->next_arg); > - } > - > - efree(argument_list); > - > - return; > -} > -/* }}} */ > - > -/* {{{ php_w32api_free_members > - * Expects one argument, the head of a list of members to free > - */ > -static void php_w32api_free_members(members *member_list) > -{ > - if(member_list == NULL) > - return; > - > - efree(member_list->member->member_name); > - > - if(member_list->member->member_type_name != NULL) > - efree(member_list->member->member_type_name); > - > - efree(member_list->member); > - > - php_w32api_free_members(member_list->next_member); > - efree(member_list); > - return; > -} > -/* }}} */ > - > -/* {{{ php_w32api_load_library > - * Expects two parameters, first is libraries name the second is a pointer > - * to a pointer to w32api_lib_handle which will recieve the resultant handle. > - * returns SUCCESS on success and FAILURE on failure. > - */ > -static int php_w32api_load_library (char *library_name, w32api_lib_handle **lh TSRMLS_DC) > -{ > - if(zend_hash_find(WG(libraries), library_name, strlen(library_name) + 1, (void **)lh) == > SUCCESS) > - { > - (*lh)->ref_count++; > - return SUCCESS; > - } > - > - *lh = (w32api_lib_handle *) emalloc( sizeof(w32api_lib_handle) ); > - (*lh)->ref_count = 1; > - (*lh)->library_name = estrdup(library_name); > - > - (*lh)->handle = LoadLibrary((*lh)->library_name); > - > - if(!(*lh)->handle) /* Could not load library */ > - { > - LPVOID message_buffer; > - FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | > - FORMAT_MESSAGE_FROM_SYSTEM | > - FORMAT_MESSAGE_IGNORE_INSERTS, > - NULL, > - GetLastError(), > - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language > - (LPTSTR)&message_buffer, > - 0, > - NULL); > - > - /* Tidy up */ > - efree((*lh)->library_name); > - efree(*lh); > - efree(lh); > - > - php_error(E_WARNING, "Loading of library failed: %s", message_buffer); > - LocalFree(message_buffer); > - > - return FAILURE; > - } > - > - /* Add to hash */ > - if(zend_hash_add( WG(libraries), > - (*lh)->library_name, > - strlen((*lh)->library_name) + 1, > - *lh, > - sizeof(w32api_lib_handle), > - NULL) != SUCCESS) > - { > - > - php_error( E_WARNING, > - "Loading of library %s failed: Could not insert library handle into hash", > - (*lh)->library_name); > - > - /* Tidy up */ > - efree((*lh)->library_name); > - efree(*lh); > - efree(lh); > - > - return FAILURE; > - } > - > - > - return SUCCESS; > - > -} > -/* }}} */ > - > - > -/* {{{ php_w32api_do_arg_types > - */ > -static unsigned char *php_w32api_do_arg_types(arguments **argument_list) > -{ > - int i = 0; > - int j = 0; > - arguments *curr_arg = NULL; > - unsigned char *retval = NULL; > - > - if(!(argument_list) || !(*argument_list)) > - return NULL; > - > - curr_arg = *argument_list; > - > - /* See how much room we need to emalloc */ > - while(curr_arg) > - { > - i++; > - > - if(curr_arg->arg->flags & BYREF_FORCE) > - { > - j = i; > - } > - > - curr_arg = curr_arg->next_arg; > - } > - > - /* Check to see if any args are by ref */ > - if( j == 0 ) > - return NULL; > - > - retval = (unsigned char *)emalloc(sizeof(unsigned char) * j + 1); > - retval[0] = (unsigned char)j; > - > - curr_arg = *argument_list; > - > - for(i=1; i <= j; i++) > - { > - > - retval[i] = (unsigned char)curr_arg->arg->flags; > - curr_arg = curr_arg->next_arg; > - > - } > - > - return retval; > -} > -/* }}} */ > - > -static int php_w32api_get_type_size(int type_id, char *type_name, int flags) > -{ > - TSRMLS_FETCH(); > - > - if(flags & BYREF_FORCE) > - { > - return sizeof(void *); /* Pointers are always the same size */ > - } > - > - switch(type_id) > - { > - case W32API_NULL: > - return sizeof(void *); > - case W32API_INT: > - return sizeof(int); > - case W32API_LONG: > - return sizeof(long); > - case W32API_DOUBLE: > - return sizeof(double); > - case W32API_FLOAT: > - return sizeof(float); > - case W32API_STRING: > - return sizeof(char *); > - case W32API_BYTE: > - return sizeof(char); > - case W32API_BOOL: > - return sizeof(int); > - case W32API_COMPLEX: > - { > - w32api_type_handle **th; > - > - if(zend_hash_find(WG(types), type_name, strlen(type_name) +1, (void **)&th) != > SUCCESS) > - { > - php_error(E_ERROR, "Unknown type %s", type_name); > - return -1; > - } > - > - return (*th)->size; > - > - } > - break; > - case W32API_UNKNOWN: > - default: > - php_error(E_ERROR, "Unknown type %s", type_name); > - return -1; > - } > -} > - > -static int php_w32api_get_type_id_from_name(char *type) > -{ > - > - TSRMLS_FETCH(); > - > - if(!strcmp(type, "long")) > - { > - return W32API_LONG; > - } > - else if(!strcmp(type, "int")) > - { > - return W32API_INT; > - } > - else if (!strcmp(type, "string")) > - { > - return W32API_STRING; > - } > - else if (!strcmp(type, "byte")) > - { > - return W32API_BYTE; > - } > - else if (!strcmp(type, "bool")) > - { > - return W32API_BOOL; > - } > - else if (!strcmp(type, "double")) > - { > - return W32API_DOUBLE; > - } > - else if (!strcmp(type, "float")) > - { > - return W32API_FLOAT; > - } > - else if (!strcmp(type, "void")) > - { > - return W32API_NULL; > - } > - else > - { > - if(zend_hash_exists(WG(types), type, strlen(type) +1)) > - { > - return W32API_COMPLEX; > - } > - else > - { > - return W32API_UNKNOWN; > - } > - } > -} > - > -static void php_w32api_init_type(w32api_type_handle *th, zval *obj TSRMLS_DC) > -{ > - w32api_type_instance *ti; > - zval *rsrc_handle = NULL; > - > - ti = emalloc(sizeof(w32api_type_instance)); > - > - if(!obj) > - MAKE_STD_ZVAL(obj); > - > - object_init_ex(obj, WG(type_ce)); > - > - ti->type = th; > - ti->values = emalloc(sizeof(zval *) * th->member_count); > - memset(ti->values, '\0', sizeof(zval *) * th->member_count); > - > - MAKE_STD_ZVAL(rsrc_handle); > - ZEND_REGISTER_RESOURCE(rsrc_handle, ti, WG(le_type_instance)); > - > - zend_hash_index_update(Z_OBJPROP_P(obj), 0, &rsrc_handle, sizeof(zval *), NULL); > -} > - > - > -static int php_w32api_do_prop_get(zval *object, zval *return_value, zend_llist_element > **element TSRMLS_DC) > -{ > - w32api_type_instance *th; > - zval **type_instance_handle; > - members *current_member; > - char *property_name; > - int i = 0; > - > - zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > - > - th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > - -1, "Complex Type Instance", NULL, > - 1, WG(le_type_instance)); > - > - if(!th) > - return FAILURE; > - > - property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element); > - > - current_member = th->type->member_list; > - > - while(strcmp(current_member->member->member_name, property_name) != 0) > - { > - i++; > - > - if(current_member->next_member != NULL) > - current_member = current_member->next_member; > - else > - return FAILURE; > - } > - > - *return_value = *(th->values[i]); > - zval_copy_ctor(return_value); > - > - return SUCCESS; > -} > - > -static int php_w32api_do_prop_set(zval *object, zval *value, zend_llist_element **element > TSRMLS_DC) > -{ > - w32api_type_instance *th; > - zval **type_instance_handle; > - zval *new_var; > - members *current_member; > - char *property_name; > - int i = 0; > - > - zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > - > - th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > - -1, "Complex Type Instance", NULL, > - 1, WG(le_type_instance)); > - > - if(!th) > - return FAILURE; > - > - property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element); > - > - current_member = th->type->member_list; > - > - while(strcmp(current_member->member->member_name, property_name) != 0) > - { > - i++; > - > - if(current_member->next_member != NULL) > - current_member = current_member->next_member; > - else > - return FAILURE; > - } > - > - if(current_member->member->flags & BYREF_FORCE) > - { > - if(th->values[i]) > - zval_ptr_dtor(&th->values[i]); > - > - MAKE_STD_ZVAL(new_var); > - *new_var = *value; > - zval_copy_ctor(new_var); > - th->values[i] = new_var; > - > - } > - else > - { > - th->values[i] = value; > - zval_add_ref(&value); > - } > - > - return SUCCESS; > -} > - > -w32api_result php_w32api_do_dynamic_dll_call(w32api_func_handle *fh, int argc, > w32api_dynamic_param *params, void *return_buffer, int return_buffer_size) > -{ > - > - /** > - * Theory Behind Implementation > - * ============================ > - * We have four main jobs: > - * 1) Push arguments onto stach aligned at 4 bytes. > - * 2) Call Function > - * 3) Get Return Values > - * 4) Perform any cleanup needed. > - * > - * Pushing arguments onto the stack is fairly simple, just push from right to left > - * so for a function with the prototype int sum(int a, int b) we would push b and > - * then a in that order. > - * > - * Calling the function is fine as we already have the pointer to the function which > - * we can use with call [function_pointer] to make the actual call. > - * > - * Return values are where we begin to get complicated. Now for simple return values up > - * to 8 bytes they are returned via the EAX/EDX register pair. This means we can just > - * copy the EAX/EDX pair to the win32_result sturcture and be sure we get any simple > - * return type. If the return type is more than 8 bytes then things get complicated. > - * When calling we must pass a hidden argument on the stach which points to a tempory > - * buffer with enough memory to hold the return value, this return value is then copied > - * to the correct varaible by us. Microsoft being the nice bunnies they are, decided to > - * copy an optimization Borland introduced under win16 which is to pass structs of under > - * 8 bytes directly via EAX/EDX pair. One final notable exception is dealing with floating > - * point return types where we need to retrive the floating point number of the systems > - * math coprocessor stack using the fstp call. > - * > - * Finally if its a __cdecl call we have to clean up the stack, otherwise the callee does > this. > - * > - */ > - > - w32api_result result = { 0 }; > - DWORD *stack_pointer, stack_size = 0, eaxv, edxv; > - BYTE *arg_ptr = NULL; > - int size = 0, i = 0; > - FARPROC fp = fh->handle; > - > - _asm mov stack_pointer, esp // Store stack pointer (esp) in stack_pointer > - _asm sub esp, 0x100 // Give ourselves 256 bytes on the stack > - > - > - for(i = (argc - 1); i >= 0; i--) > - { > - size = (params[i].width + 3)/4 * 4; > - arg_ptr = (unsigned char *)params[i].argument_ptr + size - 4; > - stack_size += (unsigned long)size; > - > - while(size > 0) > - { > - stack_pointer--; > - if(params[i].flags == W32API_ARGPTR) > - { > - *stack_pointer = *(unsigned long *)arg_ptr; > - arg_ptr -= 4; > - } > - else > - { > - *stack_pointer = params[i].argument; > - } > - > - size -= 4; > - } > - } > - > - if((return_buffer) && ((fh->flags & W32API_BORLAND) || (return_buffer_size > > 8))) > - { > - > - stack_size += 4; > - stack_pointer--; > - *stack_pointer = (unsigned long)return_buffer; > - } > - > - _asm add esp, 0x100 > - _asm sub esp, stack_size > - _asm call [fp] > - _asm mov eaxv, eax > - _asm mov edxv, edx > - > - if(fh->flags & W32API_CDECL) > - { > - _asm add esp, stack_size > - } > - > - if(fh->flags & W32API_REAL4) > - _asm fstp dword ptr [result] > - else if (fh->flags & W32API_REAL8) > - _asm fstp qword ptr [result] > - else if (!return_buffer) > - { > - _asm mov eax, [eaxv] > - _asm mov edx, [edxv] > - _asm mov DWORD PTR [result], eax > - _asm mov DWORD PTR [result + 4], edx > - } > - else if (!(fh->flags & W32API_BORLAND) && (return_buffer_size <= 8)) > - { > - _asm mov ecx, DWORD PTR [return_buffer] > - _asm mov eax, [eaxv] > - _asm mov DWORD PTR [ecx], eax > - _asm mov edx, [edxv] > - _asm mov DWORD PTR [ecx + 4], edx > - } > - > - return result; > -} > - > -void php_w32api_marshall_zval_to_c(argument *arg, w32api_dynamic_param *dp, zval *pzval > TSRMLS_DC) > -{ > - dp->flags = 0; > - > - /* We should have been passed a write reference when > - * BYREF_FORCE is Set so we just add a reference > - * when we pass it to the function, > - * TODO: register the reference internally for safe unreferencing > - */ > - > - switch(arg->type_id) > - { > - case W32API_INT: > - convert_to_long_ex(&pzval); > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&pzval->value.lval; > - dp->width = sizeof(int *); > - > - } > - else > - { > - dp->argument = (int)pzval->value.lval; > - dp->width = sizeof(int); > - } > - break; > - case W32API_LONG: > - convert_to_long_ex(&pzval); > - > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&pzval->value.lval; > - dp->width = sizeof(int *); > - zval_add_ref(&pzval); > - } > - else > - { > - dp->argument = pzval->value.lval; > - dp->width = sizeof(int); > - } > - break; > - case W32API_STRING: > - > - convert_to_string_ex(&pzval); > - if(!(arg->flags & BYREF_FORCE)) > - { > - /* Need to free this when we demarshall */ > - dp->argument = (unsigned long)estrndup(Z_STRVAL_P(pzval), Z_STRLEN_P(pzval)); > - } > - else > - { > - dp->argument = (unsigned long)Z_STRVAL_P(pzval); > - zval_add_ref(&pzval); > - } > - > - dp->width = sizeof(char *); > - break; > - > - case W32API_DOUBLE: > - convert_to_double_ex(&pzval); > - > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&pzval->value.dval; > - dp->width = sizeof(double *); > - zval_add_ref(&pzval); > - } > - else > - { > - dp->argument_ptr = &pzval->value.dval; > - dp->width = sizeof(double); > - dp->flags = W32API_ARGPTR; > - } > - break; > - case W32API_FLOAT: > - convert_to_double_ex(&pzval); > - > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&pzval->value.dval; > - dp->width = sizeof(double *); > - zval_add_ref(&pzval); > - } > - else > - { > - dp->argument_ptr = &pzval->value.dval; > - dp->width = sizeof(float); > - dp->flags = W32API_ARGPTR; > - } > - break; > - case W32API_BYTE: > - /* Thanks sterling */ > - convert_to_string_ex(&pzval); > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&Z_STRVAL_P(pzval); > - dp->width = sizeof(char *); > - zval_add_ref(&pzval); > - } > - else > - { > - dp->argument = (char)Z_STRVAL_P(pzval)[0]; > - dp->width = sizeof(char); > - } > - break; > - case W32API_BOOL: > - convert_to_boolean_ex(&pzval); > - > - if(arg->flags & BYREF_FORCE) > - { > - dp->argument = (unsigned long)&pzval->value.lval; > - dp->width = sizeof(int *); > - zval_add_ref(&pzval); > - } > - else > - { > - dp->argument = (int)pzval->value.lval; > - dp->width = sizeof(int); > - } > - break; > - case W32API_COMPLEX: > - if(Z_TYPE_P(pzval) != IS_OBJECT) > - { > - php_error(E_ERROR, "Variable passed as complex value is not an object"); > - break; > - } > - > - if(arg->flags & BYREF_FORCE) > - { > - int width= 0; > - void **ptr = NULL; > - ptr = emalloc(sizeof(void *)); > - *ptr = php_w32api_complex_marshall_zval_to_c(pzval, &width, NULL TSRMLS_CC); > - dp->argument = (unsigned long)ptr; > - dp->width = width; > - } > - else > - { > - int width= 0; > - dp->argument_ptr = php_w32api_complex_marshall_zval_to_c(pzval, &width, NULL > TSRMLS_CC); > - dp->width = width; > - } > - break; > - > - case W32API_UNKNOWN: > - php_error(E_ERROR, "Unknown type when calling function, marshalling failed"); > - break; > - } > - > -} > - > -static void *php_w32api_complex_marshall_zval_to_c(zval *pzval, int *width, void *return_value > TSRMLS_DC) > -{ > - w32api_type_instance *th; > - zval **type_instance_handle; > - members *current_member; > - char *offset = return_value; > - int i = 0; > - > - > - if(return_value == NULL) > - { > - /* First call */ > -/* return_value = emalloc(th->type->size); > - > - zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > - th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > - -1, "Complex Type Instance", NULL, > - 1, WG(le_type_instance)); > - > - if(!th) > - return NULL; > - > - > - for(i = 0; i < th->type->member_count; i++) > - { > - > - > - } > -*/ } > - > - > -} > - > - > -/* > ===================================================================================================== > - * Win32 Class Code > - * > ===================================================================================================== > - */ > - > -/* {{{ win32_class_functions[] > - */ > -function_entry win32_class_functions[] = { > - W32API_CLASS_FE(win32, registerfunction, NULL) > - W32API_CLASS_FE(win32, unregisterfunction, NULL) > - W32API_CLASS_FE(win32, registercallback, NULL) > - W32API_CLASS_FE(win32, definetype, NULL) > - W32API_CLASS_FE(win32, gettypesize, NULL) > - W32API_CLASS_FE(win32, inittype, NULL) > - W32API_CLASS_FE(win32, decref, NULL) > -#ifndef NDEBUG > - W32API_CLASS_FE(win32, dump_function_hash, NULL) > - W32API_CLASS_FE(win32, dump_library_hash, NULL) > - W32API_CLASS_FE(win32, dump_callback_hash, NULL) > - W32API_CLASS_FE(win32, dump_type_hash, NULL) > -#endif > - {NULL, NULL, NULL} > -}; > -/* }}} */ > - > -/* {{{ win32_class_init(TSRMLS_D) > - */ > -int win32_class_init(TSRMLS_D) > -{ > - zend_class_entry ce; > - > - INIT_CLASS_ENTRY(ce, > - "win32", > - win32_class_functions); > - > - WG(win32_ce) = zend_register_internal_class(&ce TSRMLS_CC); > - > - return SUCCESS; > -} > -/* }}} */ > - > -/* {{{ win32_class_rshutdown(TSRMLS_D) > - * Cleans up at the end of the shutdown removing and freeing anything we added to the function > - * table. > - */ > -int win32_class_rshutdown(TSRMLS_D) > -{ > - > - return SUCCESS; > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::RegisterFunction(string definition [, int flags]) > - * Registers and Loads a function from an underlying Dll > - */ > -W32API_CLASS_FUNCTION(win32, registerfunction) > -{ > - char *function_definition = NULL; > - int function_definition_len; > - long flags = 0; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > - &function_definition, > - &function_definition_len, > - &flags) == FAILURE) > - { > - return; > - } > - > - if(php_w32api_load_function(function_definition, function_definition_len, flags TSRMLS_CC) != > SUCCESS) > - { > - php_error(E_ERROR, "Registering Function %s failed", function_definition); > - RETURN_FALSE; > - } > - > - RETURN_TRUE; > - > - > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::UnregisterFunction(string function_name) > - * Unregisters a previously loaded function > - */ > -W32API_CLASS_FUNCTION(win32, unregisterfunction) > -{ > - char *function_name = NULL; > - int function_name_len; > - w32api_func_handle **fh = NULL; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > - &function_name, > - &function_name_len) == FAILURE) > - { > - return; > - } > - > - /* Our deleteor handler removes us from the WG(win32_ce)->function_table > - * so no need to delete specifically from there > - */ > - zend_hash_del(WG(funcs), function_name, strlen(function_name) + 1); > - > - RETURN_TRUE; > - > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::RegisterCallback(string definition) > - * Registers a callback type > - */ > -W32API_CLASS_FUNCTION(win32, registercallback) > -{ > - char *function_definition = NULL; > - int function_definition_len; > - w32api_func_handle **fh = NULL; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > - &function_definition, > - &function_definition_len) == FAILURE) > - { > - return; > - } > - > - if(php_w32api_register_callback(function_definition, function_definition_len TSRMLS_CC) != > SUCCESS) > - { > - RETURN_FALSE; > - } > - > - RETURN_TRUE; > - > -} > -/* }}} */ > - > - > -/* {{{ proto: int Win32::DefineType(string definition) > - * Defines a C Like Type for use. > - */ > -W32API_CLASS_FUNCTION(win32, definetype) > -{ > - char *type_definition = NULL; > - int type_definition_len; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > - &type_definition, > - &type_definition_len) == FAILURE) > - { > - return; > - } > - > - if(php_w32api_register_type(type_definition, type_definition_len TSRMLS_CC) != SUCCESS) > - { > - php_error(E_ERROR, "Registering Type %s failed", type_definition); > - RETURN_FALSE; > - } > - > - RETURN_TRUE; > - > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::GetTypeSize(string type_name) > - * Returns the size of a registered type > - */ > -W32API_CLASS_FUNCTION(win32, gettypesize) > -{ > - char *type = NULL; > - int type_len; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > - &type, > - &type_len) == FAILURE) > - { > - return; > - } > - > - RETURN_LONG(php_w32api_get_type_size(php_w32api_get_type_id_from_name(type), type, > BYREF_NONE)); > - > - > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::InitType(string TypeName) > - * Creates an instance of type TypeName > - */ > -W32API_CLASS_FUNCTION(win32, inittype) > -{ > - char *type_name = NULL; > - int type_name_len = 0; > - w32api_type_handle **th = NULL; > - > - if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > - &type_name, &type_name_len) == FAILURE) > - { > - return; > - } > - > - if(zend_hash_find(WG(types), type_name, type_name_len +1, (void **)&th) == FAILURE) > - { > - php_error(E_ERROR, "Could not retrieve type handle for type %s from hash table", > type_name); > - RETURN_FALSE; > - } > - > - php_w32api_init_type(*th, return_value TSRMLS_CC); > - > -} > -/* }}} */ > - > -/* {{{ proto: int Win32::DecRef(mixed Variable) > - * Decreases the reference count on a variable > - */ > -W32API_CLASS_FUNCTION(win32, decref) > -{ > - > -} > -/* }}} */ > - > -/* {{{ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX > - * THIS FUNCTION IS NOT PUBLICALLY ACCESSABLE > - * IT IS USED AS A GENERIC HANDLER FOR W32API > - * CALLS. > - */ > -W32API_CLASS_FUNCTION(win32, invokefunction) > -{ > - char *function_name = get_active_function_name(TSRMLS_C); > - int argc = ZEND_NUM_ARGS(); > - int i = 0; > - w32api_dynamic_param *params = NULL; > - w32api_dynamic_param *current_dynamic_param = NULL; > - w32api_func_handle **fh = NULL; > - w32api_result res = {0}; > - void *w32api_return_buffer = NULL; > - int w32api_return_buffer_size = 0; > - zval **func_arguments = NULL; > - zval *current_zval = NULL; > - arguments *curr_arg = NULL; > - w32api_type_handle *th = NULL; > - > - if(zend_hash_find(WG(funcs), function_name, strlen(function_name) +1, (void **)&fh) == > FAILURE) > - { > - php_error(E_ERROR, "Could not retrieve function handle from hash table"); > - RETURN_FALSE; > - } > - > - if(argc) > - { > - if(zend_get_parameters_array_ex(argc, &func_arguments) == FAILURE) > - { > - WRONG_PARAM_COUNT > - } > - > - params = (w32api_dynamic_param *)emalloc(sizeof(w32api_dynamic_param) * argc); > - > - curr_arg = (*fh)->argument_list; > - current_dynamic_param = params; > - > - for(i = 0; i < argc; i++) > - { > - current_zval = func_arguments[i]; > - php_w32api_marshall_zval_to_c(curr_arg->arg, current_dynamic_param, current_zval > TSRMLS_CC); > - > - current_dynamic_param++; > - curr_arg = curr_arg->next_arg; > - } > - } > - else > - { > - params = NULL; > - } > - > - if((*fh)->return_type_id == W32API_COMPLEX) > - { > - if(zend_hash_find(WG(types), (*fh)->return_type_name, strlen((*fh)->return_type_name) > +1, (void **)&th) != SUCCESS) > - php_error(E_ERROR, "Could not find type handle for type %s", > (*fh)->return_type_name); > - > - w32api_return_buffer = emalloc(th->size); > - w32api_return_buffer_size = th->size; > - } > - > - > - > - res = php_w32api_do_dynamic_dll_call(*fh, argc, params, w32api_return_buffer, > w32api_return_buffer_size); > - > - if(argc) > - /* We should demarshall here not just efree */ > - efree(params); > - > - switch((*fh)->return_type_id) > - { > - case W32API_LONG: > - RETURN_LONG(res.lval); > - break; > - case W32API_INT: > - RETURN_LONG(res.ival); > - break; > - case W32API_STRING: > - case W32API_BYTE: > - RETURN_STRING(res.ptr, 1); > - break; > - case W32API_DOUBLE: > - RETURN_DOUBLE(res.dval); > - break; > - case W32API_FLOAT: > - RETURN_DOUBLE(res.fval); > - break; > - case W32API_BOOL: > - if(res.ival) > - { > - RETURN_TRUE; > - } > - else > - { > - RETURN_FALSE; > - } > - break; > - case W32API_COMPLEX: > - break; > - default: > - php_error(E_WARNING, "Unknown return type %s", (*fh)->return_type_name); > - } > - > -} > -/* }}} */ > - > -#ifndef NDEBUG > -W32API_CLASS_FUNCTION(win32, dump_library_hash) > -{ > - zend_hash_apply(WG(libraries), (apply_func_t)php_w32api_dump_library_hash_cb TSRMLS_CC); > -} > - > -W32API_CLASS_FUNCTION(win32, dump_function_hash) > -{ > - zend_hash_apply(WG(funcs), (apply_func_t)php_w32api_dump_function_hash_cb TSRMLS_CC); > -} > - > -W32API_CLASS_FUNCTION(win32, dump_callback_hash) > -{ > - > - zend_hash_apply(WG(callbacks), (apply_func_t)php_w32api_dump_callback_hash_cb TSRMLS_CC); > -} > - > - > -W32API_CLASS_FUNCTION(win32, dump_type_hash) > -{ > - > - zend_hash_apply(WG(types), (apply_func_t)php_w32api_dump_type_hash_cb TSRMLS_CC); > -} > - > -int php_w32api_dump_library_hash_cb(void *pData TSRMLS_DC) > -{ > - w32api_lib_handle *lh = pData; > - > - printf("=====================================================================\n"); > - printf("Library Name: \t\t%s\n", lh->library_name); > - printf("Reference Count: \t\t%d\n", lh->ref_count); > - printf("Library Handle: \t\t%p\n", lh->handle); > - printf("Lib ptr loc \t\t%p\n", lh); > - printf("ll n loc \t\t%p\n", &lh->ref_count); > - > - printf("=====================================================================\n"); > - > - return 0; > -} > - > -int php_w32api_dump_function_hash_cb(void *pData TSRMLS_DC) > -{ > - w32api_func_handle **fh = pData; > - > - printf("=====================================================================\n"); > - printf("Function Name: \t\t%s\n", (*fh)->function_name); > - printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > - printf("Library Name: \t\t%s\n", (*fh)->lib->library_name ); > - printf("Function Flags: \t\t%d\n", (*fh)->flags); > - printf("Function Handle: \t\t%p\n", (*fh)->handle); > - printf("Return Type ID: \t\t%d\n", (*fh)->return_type_id); > - printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > - printf("## Arguments ##\n"); > - printf("---------------------------------------------------------------------\n"); > - php_w32api_print_arguments((*fh)->argument_list); > > - printf("=====================================================================\n\n"); > - > - return 0; > -} > - > -int php_w32api_dump_callback_hash_cb(void *pData TSRMLS_DC) > -{ > - w32api_func_handle **fh = pData; > - > - printf("=====================================================================\n"); > - printf("Callback Name: \t\t%s\n", (*fh)->function_name); > - printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > - printf("Callback Flags: \t\t%d\n", (*fh)->flags); > - printf("Return Type ID: \t\t%d\n", (*fh)->return_type_id); > - printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > - printf("## Arguments ##\n"); > - printf("---------------------------------------------------------------------\n"); > - php_w32api_print_arguments((*fh)->argument_list); > > - printf("=====================================================================\n\n"); > - > - return 0; > -} > - > -int php_w32api_dump_type_hash_cb(void *pData TSRMLS_DC) > -{ > - w32api_type_handle **th = pData; > - > - > - printf("=====================================================================\n"); > - printf("Type Name: \t\t%s\n", (*th)->type_name); > - printf("Type Size: \t\t%d\n", (*th)->size); > - printf("Member Count: \t\t%d\n", (*th)->member_count); > - printf("## Members ##\n"); > - printf("---------------------------------------------------------------------\n"); > - php_w32api_print_members((*th)->member_list); > > - printf("=====================================================================\n\n"); > - > - return 0; > -} > - > -void php_w32api_print_members(members *member_list) > -{ > - if(member_list == NULL) > - return; > - > - printf("\tMember Name: \t%s\n", member_list->member->member_name); > - printf("\tMember Flags: \t%d\n", member_list->member->flags); > - printf("\tMember Type ID: \t%d\n", member_list->member->member_type_id); > - printf("\tMember Type Name:\t%s\n", member_list->member->member_type_name); > - printf("\tMember Offset: \t%d\n", member_list->member->offset); > - printf("---------------------------------------------------------------------\n"); > - > - php_w32api_print_members(member_list->next_member); > - > -} > -void php_w32api_print_arguments(arguments *argument_list) > -{ > - if(argument_list == NULL) > - return; > - > - printf("\tArgument Name: \t%s\n", argument_list->arg->argument_name); > - printf("\tArgument Flags: \t%d\n", argument_list->arg->flags); > - printf("\tArgument Type ID:\t%d\n", argument_list->arg->type_id); > - printf("\tArg Type Name: \t%s\n", argument_list->arg->type_name); > - printf("---------------------------------------------------------------------\n"); > - > - php_w32api_print_arguments(argument_list->next_arg); > -} > -#endif > -/* > ===================================================================================================== > - * Type Class Code > - * > ===================================================================================================== > - */ > - > -/* {{{ type_class_functions[] > - */ > -function_entry type_class_functions[] = { > - W32API_CLASS_FE(type, clone, NULL) > - {NULL, NULL, NULL} > -}; > -/* }}} */ > - > - > -/* {{{ type_class_init(TSRMLS_DC) > - */ > -int type_class_init(TSRMLS_D) > -{ > - zend_class_entry ce; > - > - INIT_OVERLOADED_CLASS_ENTRY(ce, > - "type", > - type_class_functions, > - NULL, > - W32API_PROP_GET_FUNCTION_N(type), > - W32API_PROP_SET_FUNCTION_N(type)); > - > - WG(type_ce) = zend_register_internal_class(&ce TSRMLS_CC); > - > - return SUCCESS; > -} > -/* }}} */ > - > -/* {{{ W32API_PROP_SET_FUNCTION(type) > - */ > -/* Most of this code is borrowed from php-gtk. Thanks to Andrei and Zeev for their > - * help with the prop-get/set functions > - */ > -W32API_PROP_SET_FUNCTION(type) > -{ > - zval result, temp; > - zval *temp_ptr = &temp; > - zval *new_val; > - zend_overloaded_element *overloaded_property; > - zend_llist_element *element; > - zval **object = &property_reference->object; > - int setter_retval, getter_retval; > - TSRMLS_FETCH(); > - > - > - /* If we have $foo->bar->baz->boo->bin we have to do sucessive propgets > - * Until we can do our prop set (thanks Zeev, Andrei) > - */ > - for (element=property_reference->elements_list->head; element != > property_reference->elements_list->tail; element=element->next) { > - overloaded_property = (zend_overloaded_element *)element->data; > - > - getter_retval = FAILURE; > - if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) { > - if (Z_TYPE_PP(object) == IS_NULL || > - (Z_TYPE_PP(object) == IS_BOOL && Z_LVAL_PP(object) == 0) || > - (Z_TYPE_PP(object) == IS_STRING && Z_STRLEN_PP(object) == 0)) { > - object_init(*object); > - } > - > - > - /* Trying to access a property on a non-object. */ > - if (Z_TYPE_PP(object) != IS_OBJECT) { > - return FAILURE; > - } > - > - getter_retval = php_w32api_do_prop_get(*object, &result, &element TSRMLS_CC); > - > - if (getter_retval == SUCCESS) { > - temp = result; > - object = &temp_ptr; > - } else { > - if ((getter_retval = zend_hash_find(Z_OBJPROP_PP(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - (void **)&object)) == FAILURE) { > - MAKE_STD_ZVAL(new_val); > - ZVAL_NULL(new_val); > - zend_hash_update(Z_OBJPROP_PP(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - &new_val, sizeof(void *), (void **)&object); > - } > - } > - > - } else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) { > - if (Z_TYPE_PP(object) == IS_NULL || > - (Z_TYPE_PP(object) == IS_BOOL && Z_LVAL_PP(object) == 0) || > - (Z_TYPE_PP(object) == IS_STRING && Z_STRLEN_PP(object) == 0)) { > - array_init(*object); > - } > - > - /* Trying to access index on a non-array. */ > - if (Z_TYPE_PP(object) != IS_ARRAY) { > - return FAILURE; > - } > - > - if (Z_TYPE(overloaded_property->element) == IS_STRING) { > - getter_retval = zend_hash_find(Z_ARRVAL_PP(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - (void **)&object); > - } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > - getter_retval = zend_hash_index_find(Z_ARRVAL_PP(object), > - Z_LVAL(overloaded_property->element), > - (void **)&object); > - } > - > - if (getter_retval == FAILURE) { > - MAKE_STD_ZVAL(new_val); > - ZVAL_NULL(new_val); > - > - if (Z_TYPE(overloaded_property->element) == IS_STRING) { > - zend_hash_update(Z_ARRVAL_PP(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - &new_val, sizeof(void *), (void **)&object); > - } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > - zend_hash_index_update(Z_ARRVAL_PP(object), > - Z_LVAL(overloaded_property->element), > - &new_val, sizeof(void *), (void **)&object); > - } > - } > - } > - > - zval_dtor(&overloaded_property->element); > - } > - > - /* object is now the object we want to set our property on */ > - overloaded_property = (zend_overloaded_element *) element->data; > - setter_retval = php_w32api_do_prop_set(*object, value, &element TSRMLS_CC); > - zval_dtor(&overloaded_property->element); > - > - return setter_retval; > - > -} > -/* }}} */ > - > -/* {{{ W32API_PROP_GET_FUNCTION(type) > - */ > -W32API_PROP_GET_FUNCTION(type) > -{ > - zval result; > - zval *result_ptr = &result; > - zval **prop_result; > - zend_overloaded_element *overloaded_property; > - zend_llist_element *element; > - zval object = *property_reference->object; > - int getter_retval; > - TSRMLS_FETCH(); > - > - for (element=property_reference->elements_list->head; element; > element=element->next) { > - overloaded_property = (zend_overloaded_element *) element->data; > - > - getter_retval = FAILURE; > - ZVAL_NULL(&result); > - if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) { > - /* Trying to access a property on a non-object. */ > - if (Z_TYPE(object) != IS_OBJECT || > - Z_TYPE(overloaded_property->element) != IS_STRING) { > - return result; > - } > - > - if ((getter_retval = php_w32api_do_prop_get(&object, &result, &element > TSRMLS_CC) == FAILURE)) { > - if ((getter_retval = zend_hash_find(Z_OBJPROP(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - (void **)&prop_result)) == SUCCESS) { > - result = **prop_result; > - } > - } > - } else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) { > - /* Trying to access index on a non-array. */ > - if (Z_TYPE(object) != IS_ARRAY) { > - return result; > - } > - > - if (Z_TYPE(overloaded_property->element) == IS_STRING) { > - getter_retval = zend_hash_find(Z_ARRVAL(object), > - Z_STRVAL(overloaded_property->element), > - Z_STRLEN(overloaded_property->element)+1, > - (void **)&prop_result); > - } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > - getter_retval = zend_hash_index_find(Z_ARRVAL(object), > - Z_LVAL(overloaded_property->element), > - (void **)&prop_result); > - } > - if (getter_retval == SUCCESS) > - result = **prop_result; > - } > - > - zval_dtor(&overloaded_property->element); > - > - object = result; > - > - if (getter_retval == FAILURE) { > - return result; > - } > - } > - > - zval_add_ref(&result_ptr); > - SEPARATE_ZVAL(&result_ptr); > - return *result_ptr; > -} > -/* }}} */ > - > -/* {{{ proto: Type Type::Clone() > - * Creates an exact clone of the object. > - */ > -W32API_CLASS_FUNCTION(type, clone) > -{ > - > -} > -/* }}} */ > - > -/* > ===================================================================================================== > - * Scanner & Parser Functions > - * > ===================================================================================================== > - */ > - > -/* ----------------------------- > - * Function Definition Functions > - * ----------------------------- > - */ > - > -/* {{{ w32api_parser_load_function_ex > - * Callback for the parser, if the library name is cb.cb we are registering a > - * callback so the LoadLibary and GetProcAddress code is skipped > - */ > -w32api_func_handle *w32api_parser_load_function_ex(char *return_type, char *function_name, > char *alias_name, arguments *argument_list, char *library_name) > -{ > - w32api_func_handle *return_value; > - TSRMLS_FETCH(); > - > - return_value = (w32api_func_handle *)emalloc(sizeof(w32api_func_handle)); > - memset(return_value, '\0', sizeof(w32api_func_handle)); > - > - return_value->argument_list = argument_list; > - return_value->flags = 0; > - return_value->function_name = (alias_name)?alias_name:function_name; /* This is > estrdup'd in the Scanner already!! */ > - return_value->return_type_name = return_type; /* This is estrdup'd in the > Scanner already!! */ > - return_value->return_type_id = php_w32api_get_type_id_from_name(return_type); > - > - if(strcmp("cb.cb", library_name)) /* Bit of a hack but we are > registering a callback */ > - { > - php_w32api_load_library(library_name, &return_value->lib TSRMLS_CC); > - > - if(!return_value->lib) > - { > - /* php_w32api_load_library has already given error */ > - efree(return_value); > - return NULL; > - } > - > - return_value->handle = GetProcAddress(return_value->lib->handle, function_name); > - > - if(!return_value->handle) > - { > - /* Check for variation ending with A */ > - char *ascii_name = NULL; > - > - ascii_name = emalloc(strlen(function_name) + 2); > - strcpy(ascii_name, function_name); > - ascii_name[strlen(function_name)] = 'A'; > - ascii_name[strlen(function_name) + 1] = '\0'; > - return_value->handle = GetProcAddress(return_value->lib->handle, ascii_name); > - efree(ascii_name); > - > - if(!return_value->handle) > - { > - /* TODO: php_error_docref and GetLastError etc */ > - php_error(E_WARNING, "Could not load function %s", function_name); > - efree(return_value); > - return NULL; > - } > - } > - } > - > - /* We want function_name in lowercase now */ > - php_strtolower(return_value->function_name, strlen(return_value->function_name)); > - > - /* Free it if we have a alias */ > - if(alias_name) > - efree(function_name); > - > - return return_value; > -} > -/* }}} */ > - > -/* {{{ w32api_parser_make_argument > - * Helper function for the parser > - */ > -arguments *w32api_parser_make_argument(char *arg_type, char *arg_name, int byref) > -{ > - arguments *return_value = NULL; /* Pointer to our return value */ > - argument *argument_value = NULL; /* Our actual argument */ > - > - argument_value = emalloc(sizeof(argument)); > - return_value = emalloc(sizeof(arguments)); > - > - return_value->arg = argument_value; > - return_value->next_arg = return_value->prev_arg = NULL; > - > - argument_value->flags = byref; > - argument_value->argument_name = arg_name; > - argument_value->type_name = arg_type; > - argument_value->type_id = php_w32api_get_type_id_from_name(arg_type); > - > - if(argument_value->type_id == W32API_UNKNOWN) > - { > - php_error(E_NOTICE, "Unknown type %s used as arugment type", arg_type); > - } > - > - return return_value; > -} > -/* }}} */ > - > -/* {{{ w32api_parser_join_arguments > - * Helper function for the parser > - */ > -arguments *w32api_parser_join_arguments(arguments *lval, arguments *rval) > -{ > - lval->next_arg = rval; > - rval->prev_arg = lval; > - > - return lval; > -} > -/* }}} */ > - > -/* {{{ w32api_function_definition_error > - * Error function for the parser > - */ > -int w32api_function_definition_error(char *s) > -{ > - php_error(E_ERROR, "Function Definition Parse Error: %s", s); > - return 0; > -} > -/* }}} */ > - > -/* ------------------------- > - * Type Definition Functions > - * ------------------------- > - */ > -w32api_type_handle *w32api_parser_register_type(char *type_name, members *member_list) > -{ > - w32api_type_handle *return_value = NULL; > - members *current_member; > - int offset = 0; > - int member_count = 0; > - > - return_value = emalloc(sizeof(w32api_type_handle)); > - > - return_value->member_list = member_list; > - return_value->type_name = type_name; /* estrdup'd in parser */ > - return_value->member_count = 0; > - > - current_member = return_value->member_list; > - > - > - while(current_member != NULL) > - { > - return_value->member_count++; > - current_member->member->offset = offset; > - offset += php_w32api_get_type_size(current_member->member->member_type_id, > current_member->member->member_type_name, current_member->member->flags); > - current_member = current_member->next_member; > - } > - > - > - return_value->size = offset; > - > - return return_value; > - > - > -} > - > -members *w32api_parser_type_make_value(char *type_name, char *member_name, long flags) > -{ > - members *return_value = NULL; /* Pointer to our return value */ > - member *member_value = NULL; /* Our actual member */ > - > - member_value = emalloc(sizeof(member)); > - return_value = emalloc(sizeof(members)); > - > - return_value->member = member_value; > - return_value->next_member = return_value->prev_member = NULL; > - > - member_value->member_name = member_name; /* estrdup'd in parser */ > - member_value->member_type_name = type_name; /* estrdup'd in parser */ > - member_value->member_type_id = php_w32api_get_type_id_from_name(type_name); > - member_value->flags = flags; > - > - return return_value; > -} > - > - > -members *w32api_parser_type_join_values(members *lval, members *rval) > -{ > - lval->next_member = rval; > - rval->prev_member = lval; > - > - return lval; > -} > - > -/* {{{ w32api_function_definition_error > - * Error function for the parser > - */ > -int w32api_type_definition_error(char *s) > -{ > - php_error(E_ERROR, "Type Definition Parse Error: %s", s); > - return 0; > -} > -/* }}} */ > - > - > +/* > + +----------------------------------------------------------------------+ > + | PHP version 4.0 | > + +----------------------------------------------------------------------+ > + | Copyright (c) 1997-2001 The PHP Group | > + +----------------------------------------------------------------------+ > + | This source file is subject to version 2.02 of the PHP license, | > + | that is bundled with this package in the file LICENSE, and is | > + | available at through the world-wide-web at | > + | http://www.php.net/license/2_02.txt. > | > + | If you did not receive a copy of the PHP license and are unable to | > + | obtain it through the world-wide-web, please send a note to | > + | license@php.net so we can mail you a copy immediately. | > + +----------------------------------------------------------------------+ > + | Authors: James Moore <jmoore@php.net> | > + +----------------------------------------------------------------------+ > + */ > + > +/* $Id: w32api.c,v 1.6 2002/11/20 18:39:38 fmk Exp $ */ > + > +/* > + * Win32 API Extension for PHP 4 > + * ============================= > + * > + * This extension allows PHP Developers to access the underlying functions in the > + * Win32 API Dll's in a generic way, it provides a mechanism for the user to load > + * and register functions from dll's and then to call them, it also implements a > + * generic callback handler which allows the user to pass a pointer to one of > + * their PHP functions to act as a callback from the C function enabling the PHP > + * programmer to handle callbacks in PHP seemlessly. Finally the extension marshalls > + * from PHP types (Zvals) to C structures seemlessly once it has been told about them > + * > + * I would like to thank Ton Plooy for his article on a similar subject which gave me > + * the initial idea for a generic dll caller and some good pointers on how to actaully > + * implement it. > + */ > + > +/* > + * Interface the PHP Programmer Sees > + * ================================== > + * > + * To keep namespaces tidy the module will introduce two classes, the first is > + * the win32 class which has several functions to load and register functions from > + * the underlying DLL's. The Win32 class also has functions for informing the > + * module about the C types we will be using so it can marshall and demarshall to and from > + * the C Interface. . Our second class is the Type class. The type class is our container > + * for complex C types which are registered and initiated using our win32 class functions. > + * > + * Win32 Class Functions > + * ===================== > + * > + * static int Win32::RegisterFunction( string Definition, long flags ) > + * ------------------------------------------------------------------- > + * > + * This function is used for registering a dll function with the module. The Definition should > take > + * the form: > + * Definition: <return_type> <function_name> [Alias <alias_name] > (<argument_list>) From <some_dll> > + * > + * return_type :- Either a simple type or a type that has > + * been registered with the module > + * > + * function_name :- The name of the function within the dll, if this is not found > + * we append an A to the function name to check for a ASCII > version, > + * if this is not found we fail. > + * > + * alias_name :- If this is provided then we register the function under this > name > + * in the PHP Symbol table. > + * > + * argument_list :- A comma seperated list of arguments in the form > <argument_type> > + * [&]argument_name. > + * > + * argument_type :- Argument type is a type known to the module > + * > + * argument_name :- This is not currently used although if it is proceeded by > an > + * & (Ampersand) then a pointer is passed rather than the > value. > + * > + * some_dll :- This is the name of the dll to find the function in. > + * > + * On success the function returns TRUE, on error FALSE, The function issues appropriate > errors > + * to allow the PHP Progammer to catch individual errors. > + * > + * static int Win32::UnregisterFunction(string FunctionName) > + * --------------------------------------------------------- > + * > + * Allows the PHP programmer to force a funciton to be unregistered saving on memory > resources. Can > + * be useful in long running scripts. > + * > + * Returns TRUE on success, FALSE on error. > + * > + * > + * static int Win32::DefineType( string Definition ) > + * ------------------------------------------------- > + * > + * This function is used to register a C-Type which will be used when calling a function, it > only > + * supports the equivilent of C structures at this time so if you need to use a union you must > use the > + * largest member of that union as the type in the struct for this to work. > + * > + * The definition string takes the form: > + * > + * Definition: <type_name> { <type_list> } > + * > + * type_name :- A unique name for this type. > + * > + * type_list :- Takes for form <member_type> [&]<member_name> > + * > + * member_type :- The type of this member. > + * > + * member_name :- The name for this member, if an & (ampersand) preceeds > + * the name it will be stripped and a pointer rather than > + * the value will be used. > + * > + * Returns TRUE on success, FALSE on error. > + * > + * > + * static int Win32::GetTypeSize(mixed TypeHandle) > + * ----------------------------------------------- > + * > + * This function returns the size of a type registered with the module. The parameter should > + * either be the name of the type or an instance of it. The Function returns FALSE on error > + * ***USE === to distinguish between this and a size of 0*** or the size of the type on > success. > + * > + * > + * static mixed Win32::InitType(String TypeName) > + * --------------------------------------------- > + * > + * Creates an instance of the type so that the PHP Programmer can assign values and then pass > + * it to a C Function. Returns NULL on error. > + * > + * static int Win32::DecRef(mixed var) > + * ----------------------------------- > + * Decreases the reference count on a variable only if we incremented the refcount when > passing > + * the variable to a C function. > + * > + * TYPE Functions > + * ============== > + * > + * mixed Type::Type(String TypeName) > + * --------------------------------- > + * See Win32::InitType, > + * > + * mixed Type::Clone() > + * ------------------- > + * > + * Allows you to make an exact copy of the class, this should be used rather than the &= > syntax > + * Due to the nesting within classes. This function WILL become redundant in PHP 5. > + */ > + > +/* > + * Implementation Details > + * ====================== > + * > + * This module will only work on the Intel platform. > + * > + * We basically want to set up this structure: > + * > + * +-----------+ > + * | PHP | > + * +-----------+ > + * Call | /|\ > + * \|/ | call_user_function_ex > + * +------------------------+ > + * | Win 32 API Extension | > + * +------------------------+ > + * | /|\ > + * \|/ | Callback > + * +-------------+ > + * | C-Space | > + * +-------------+ > + * > + * Win32 Needs to then Marshall between zvals and > + * > + * Marshalling from ZVAL's to C Types. > + * ----------------------------------- > + * For simple types this is very easy as we either just copy the value or a pointer > + * to it onto the stack, if we copy a pointer then we must increase the refcount on > + * the zval and must also make sure we get it passed to us by reference. > + * > + * The problem here is when to dereference the zval again as we may get into the following > + * situation > + * > + * We call somefunction giving it an argument by reference (IE we pass a pointer to the value > union of a zval) > + * we must increase the ref count on the zval to avoid the possibility of a GPE (IE the zval > is dtord and then > + * the function uses the zval in some sort of callback we could end up with a GPE) > + * But if we increase the zval's refcount without dtoring it anywhere it would cause a > mem leak. > + * > + * Therefore we probably need to keep a local reference table so we can either allow the user > to call > + * Win32::DecRef($var) to decrement the reference count (We would want to keep a local table > to avoid anyone > + * breaking Zend's handling off it as well..)) > + * > + * Then at MSHUTDOWN we free this hashtable decrementing the refcount as needed.. > + * > + * Complex types are less clear cut on how to handle them. My prefered method is to always > + * keep these in a C Format but to allow access to these via a wrapper object which calculates > + * the offset of the data to allow access to it from PHP. This also allows us to do no > conversion > + * when dealing with C types coming to us allowing us to deal with pointers in a more clear > way. > + * > + * > + * Enabling C Code to call PHP Code in a generic fashion > + * ----------------------------------------------------- > + * What we do here is we use _declspec(naked) to tell the compiler we will handle all stack > operations > + * ourself, we also then create (At runtime) function prologues which we place on the heap > which push > + * extra arguments onto the stack which tell us which php_function is being called back and > the callback type > + * which has been registered with us. > + * > + */ > + > +#if HAVE_W32API > + > +#include <stdio.h> > +#include <stdlib.h> > + > +#define WINDOWS_LEAN_AND_MEAN > +#include <windows.h> > + > +#include "php.h" > +#include "php_ini.h" > +#include "ext/standard/info.h" > +#include "ext/standard/php_string.h" > +#include "php_w32api.h" > + > + > +/* > ===================================================================================================== > + * PHP Module Startup, Shutdown & Info Code > + * > ===================================================================================================== > + */ > + > +#ifdef COMPILE_DL_W32API > +ZEND_GET_MODULE(w32api) > +#endif > + > +/* {{{ w32api_module_entry > + */ > +zend_module_entry w32api_module_entry = { > + STANDARD_MODULE_HEADER, > + "Win32 API", > + NULL, /* We define no global functions */ > + PHP_MINIT(w32api), > + PHP_MSHUTDOWN(w32api), > + PHP_RINIT(w32api), > + PHP_RSHUTDOWN(w32api), > + PHP_MINFO(w32api), > + "0.2", > + STANDARD_MODULE_PROPERTIES > +}; > +/* }}} */ > + > + > +/* {{{ PHP_MINIT_FUNCTION > + */ > +PHP_MINIT_FUNCTION(w32api) > +{ > + /* Setup out module globals */ > + ZEND_INIT_MODULE_GLOBALS(w32api, php_w32api_init_globals, NULL); > + > + > + if(win32_class_init(TSRMLS_C) != SUCCESS) > + { > + return FAILURE; > + } > + > + if(type_class_init(TSRMLS_C) != SUCCESS) > + { > + return FAILURE; > + } > + > + WG(le_type_instance) = zend_register_list_destructors_ex(w32api_type_instance_dtor, NULL, > "Type Instance", module_number); > + > + /* Function Flags */ > + REGISTER_LONG_CONSTANT( "W32API_ARGPTR", W32API_ARGPTR, CONST_CS | > CONST_PERSISTENT); > + REGISTER_LONG_CONSTANT( "W32API_BORLAND", W32API_BORLAND, CONST_CS | > CONST_PERSISTENT); > + REGISTER_LONG_CONSTANT( "W32API_CDECL", W32API_CDECL, CONST_CS | > CONST_PERSISTENT); > + REGISTER_LONG_CONSTANT( "W32API_REAL4", W32API_REAL4, CONST_CS | > CONST_PERSISTENT); > + REGISTER_LONG_CONSTANT( "W32API_REAL8", W32API_REAL8, CONST_CS | > CONST_PERSISTENT); > + > + > + return SUCCESS; > + > +}; > +/* }}} */ > + > +/* {{{ PHP_MSHUTDOWN_FUNCTION > + */ > +PHP_MSHUTDOWN_FUNCTION(w32api) > +{ > + return SUCCESS; > +} > +/* }}} */ > + > +/* {{{ PHP_RINIT_FUNCTION > + */ > +PHP_RINIT_FUNCTION(w32api) > +{ > + /* Allocate Request Specific HT's here > + */ > + ALLOC_HASHTABLE(WG(funcs)); > + zend_hash_init(WG(funcs), 1, NULL, php_w32api_hash_func_dtor, 1); > + > + ALLOC_HASHTABLE(WG(libraries)); > + zend_hash_init(WG(libraries), 1, NULL, php_w32api_hash_lib_dtor, 1); > + > + ALLOC_HASHTABLE(WG(callbacks)); > + zend_hash_init(WG(callbacks), 1, NULL, php_w32api_hash_callback_dtor, 1); > + > + ALLOC_HASHTABLE(WG(types)); > + zend_hash_init(WG(types), 1, NULL, php_w32api_hash_type_dtor, 1); > + > + > + return SUCCESS; > + > +}; > +/* }}} */ > + > +/* {{{ PHP_RSHUTDOWN_FUNCTION > + */ > +PHP_RSHUTDOWN_FUNCTION(w32api) > +{ > + > + win32_class_rshutdown(TSRMLS_C); > + > + /* Must be dtor'd before libraries */ > + zend_hash_destroy(WG(funcs)); > + FREE_HASHTABLE(WG(funcs)); > + > + zend_hash_destroy(WG(libraries)); > + FREE_HASHTABLE(WG(libraries)); /* we may only want to do this on MSHUTDOWN but for now it can > be here */ > + > + zend_hash_destroy(WG(callbacks)); > + FREE_HASHTABLE(WG(callbacks)); > + > + zend_hash_destroy(WG(types)); > + FREE_HASHTABLE(WG(types)); > + > + > + return SUCCESS; > +} > +/* }}} */ > + > + > +/* {{{ PHP_MINFO_FUNCTION > + */ > +PHP_MINFO_FUNCTION(w32api) > +{ > + php_info_print_table_start(); > + php_info_print_table_row(2, "Win32 API Support", "enabled" ); > + php_info_print_table_end(); > +} > +/* }}} */ > + > +/* {{{ php_w32api_init_globals > + */ > +static void php_w32api_init_globals(zend_w32api_globals *w32api_globals) > +{ > + w32api_globals->win32_ce = NULL; > + w32api_globals->type_ce = NULL; > + w32api_globals->funcs = NULL; > + w32api_globals->libraries = NULL; > + w32api_globals->callbacks = NULL; > + w32api_globals->types = NULL; > +} > +/* }}} */ > + > +/* {{{ php_w32api_hash_lib_dtor (void *data) > + * Dtor function called when hash is destroied, unloads library > + */ > +static void php_w32api_hash_lib_dtor(void *data) > +{ > + w32api_lib_handle *lh; /* Library Handle */ > + TSRMLS_FETCH(); /* Get thread safe stuff */ > + lh = (w32api_lib_handle *)data; > + > + FreeLibrary(lh->handle); > + efree(lh->library_name); > +} > +/* }}} */ > + > +/* {{{ php_w32api_hash_func_dtor (void *data) > + * Dtor function called when hash is destroied, unloads function. > + */ > +static void php_w32api_hash_func_dtor(void *data) > +{ > + w32api_func_handle **fh; /* Function Handle */ > + TSRMLS_FETCH(); /* Get thread safe stuff */ > + > + fh = (w32api_func_handle **)data; > + php_w32api_unload_function(fh TSRMLS_CC); > +} > +/* }}} */ > + > +/* {{{ php_w32api_hash_callback_dtor > + * DTOR function called when hash is destroied, removes callback. > + */ > +static void php_w32api_hash_callback_dtor(void *data) > +{ > + w32api_func_handle **fh; > + > + fh = (w32api_func_handle **)data; > + > + php_w32api_free_arguments((*fh)->argument_list); > + efree((*fh)->function_name); > + > + if((*fh)->return_type_name) > + efree((*fh)->return_type_name); > + > + efree(*fh); > +} > + > +/* {{{ php_w32api_hash_type_dtor > + * DTOR function called when hash is destroied, removes callback. > + */ > +static void php_w32api_hash_type_dtor(void *data) > +{ > + w32api_type_handle **th; > + > + th = (w32api_type_handle **)data; > + > + php_w32api_free_members((*th)->member_list); > + efree((*th)->type_name); > + efree(*th); > +} > + > +static void w32api_type_instance_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) > +{ > + w32api_type_instance *ti; > + int i = 0; > + > + if(!rsrc || !rsrc->ptr) > + return; > + > + ti = (w32api_type_instance *)rsrc->ptr; > + > + for(i = 0; i < ti->type->member_count; i++) > + { > + if(ti->values[i]) > + zval_ptr_dtor(&ti->values[i]); > + } > + > + efree(ti); > + > + return; > +} > +/* > ===================================================================================================== > + * Utility Functions > + * > ===================================================================================================== > + */ > + > +/* {{{ php_w32api_unload_library > + * Expects two arguments, the first is the pointer to a w32api_lib_handle > + * and the second is a flag, if the flag is 0 then the reference counter is > + * use if it is one then the library is unloaded irrespective of the reference > + * counter > + */ > +static void php_w32api_unload_library (w32api_lib_handle *lh, int flags TSRMLS_DC) > +{ > + > + if(flags == 0) > + { > + lh->ref_count--; > + } > + > + if((flags == 1) || (lh->ref_count == 0)) > + { > + /* remove outselves from the hashtable */ > + zend_hash_del(WG(libraries), lh->library_name, strlen(lh->library_name) + 1); > + } > +} > +/* }}} */ > + > +/* {{{ php_w32api_unload_function > + * Expects one argument, a pointer to a w32api_func_handle, unloads this > + * function from both the function table internally and the PHP function > + * table then it decrements the reference counter on the library. > + */ > +static void php_w32api_unload_function (w32api_func_handle **fh TSRMLS_DC) > +{ > + zend_function *function = NULL; > + > + efree((*fh)->return_type_name); > + php_w32api_free_arguments((*fh)->argument_list); > + > + /* If needs be we need to retrieve function ptr from hash table > + * and free anything we allocate when creating them at runtime (most notably > + * arg_types > + */ > + if(zend_hash_find( &WG(win32_ce)->function_table, > + (*fh)->function_name, > + strlen((*fh)->function_name) + 1, > + (void **)&function) == SUCCESS) > + { > + zend_internal_function *internal_function = (zend_internal_function *)function; > + if(internal_function->arg_types) > + efree(internal_function->arg_types); > + } > + > + /* Remove from Function Table */ > + zend_hash_del(&WG(win32_ce)->function_table, (*fh)->function_name, > strlen((*fh)->function_name) + 1); > + php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); > + > + efree((*fh)->function_name); > + efree(*fh); > + > +} > +/* }}} */ > + > +/* {{{ php_w32api_load_function > + * Expects three arguments, The definition of the function in string format, the definitions > length > + * and a pointer to a pointer to a function handle. returns SUCCESS or FAILURE. > + */ > +static int php_w32api_load_function (char *definition, int definition_len, int flags > TSRMLS_DC) > +{ > + zend_function function; > + zend_internal_function *internal_function = (zend_internal_function *)&function; > + w32api_func_handle **fh; > + w32api_func_handle_ptr hnd; > + > + fh = emalloc(sizeof(w32api_func_handle *)); > + *fh = NULL; > + > + /* Parse function */ > + w32api_function_definition_scan_bytes(definition, definition_len); > + if((w32api_function_definition_parse((void *)&hnd) != 0)) > + { > + *fh = hnd.hnd; > + if(*fh != NULL) > + efree(*fh); > + > + efree(fh); > + return FAILURE; > + } > + *fh = hnd.hnd; > + > + if(!*fh) > + return FAILURE; > + > + > + if(zend_hash_exists(&WG(win32_ce)->function_table, (*fh)->function_name, > strlen((*fh)->function_name) + 1)) > + { > + php_error( E_WARNING, > + "A function by the name %s already has been registered, cannot redefine > function", > + (*fh)->function_name); > + > + /* We dont want to unload function as it already exists so lets just free it ourselves */ > + php_w32api_unload_library((*fh)->lib, 0 TSRMLS_CC); > + php_w32api_free_arguments((*fh)->argument_list); > + efree((*fh)->return_type_name); > + efree((*fh)->function_name); > + efree(*fh); > + efree(fh); > + > + return FAILURE; > + } > + > + /* Insert it into our hash table */ > + if(zend_hash_add( WG(funcs), > + (*fh)->function_name, > + strlen((*fh)->function_name) + 1, > + fh, > + sizeof(w32api_func_handle), > + NULL) != SUCCESS) > + { > + > + php_error( E_WARNING, > + "Loading of function %s failed: Could not insert function handle into hash", > + (*fh)->function_name); > + > + /* Tidy up */ > + zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); > + return FAILURE; > + } > + > + /* Insert function into win32_ce's function_table */ > + internal_function->type = ZEND_INTERNAL_FUNCTION; > + internal_function->handler = W32API_CLASS_FN(win32, invokefunction); > + internal_function->function_name = (*fh)->function_name; > + internal_function->arg_types = php_w32api_do_arg_types(&(*fh)->argument_list); > + > + if(zend_hash_add(&WG(win32_ce)->function_table, (*fh)->function_name, > + strlen((*fh)->function_name) + 1, &function, sizeof(zend_function), NULL) == > FAILURE) > + { > + php_error(E_ERROR, "Could not register funciton %s into function table", > (*fh)->function_name); > + zend_hash_del(WG(funcs), (*fh)->function_name, strlen((*fh)->function_name) +1); > + > + return FAILURE;; > + } > + > + if(flags) > + { > + (*fh)->flags = (*fh)->flags | flags; > + } > + > + > + return SUCCESS; > +} > +/* }}} */ > + > +/* {{{ php_w32api_unload_type > + * Expects one argument, a pointer to a w32api_type_handle, unloads this > + * type. > + */ > +static void php_w32api_unload_type (w32api_type_handle **th TSRMLS_DC) > +{ > + php_w32api_free_members((*th)->member_list); > + > + zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1); > + > +} > +/* }}} */ > + > +/* {{{ php_w32api_register_type > + */ > +static int php_w32api_register_type(char *type_definition, int type_definition_len TSRMLS_DC) > +{ > + w32api_type_handle **th; > + w32api_type_handle_ptr hnd; > + > + th = emalloc(sizeof(w32api_type_handle *)); > + *th = NULL; > + > + w32api_type_definition_scan_bytes(type_definition, type_definition_len); > + if(w32api_type_definition_parse((void *)&hnd) != 0) > + { > + *th = hnd.hnd; > + > + /* Leaks */ > + if(*th != NULL) > + efree(*th); > + > + efree(th); > + return FAILURE; > + } > + > + *th = hnd.hnd; > + > + if(!*th) > + return FAILURE; > + > + if((zend_hash_exists(WG(callbacks), (*th)->type_name, strlen((*th)->type_name) +1)) || > + (zend_hash_exists(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1))) > + { > + php_error( E_WARNING, > + "A type or callback by the name %s already has been registered, cannot redefine > type or callback", > + (*th)->type_name); > + > + /* We dont want to unload function as it already exists so lets just free it ourselves */ > + php_w32api_free_members((*th)->member_list); > + efree((*th)->type_name); > + efree(*th); > + efree(th); > + > + return FAILURE; > + } > + > + /* Insert it into our hash table */ > + if(zend_hash_add( WG(types), > + (*th)->type_name, > + strlen((*th)->type_name) + 1, > + th, > + sizeof(w32api_type_handle *), > + NULL) != SUCCESS) > + { > + > + php_error( E_WARNING, > + "Loading of type %s failed: Could not insert type handle into hash", > + (*th)->type_name); > + > + /* Tidy up */ > + zend_hash_del(WG(types), (*th)->type_name, strlen((*th)->type_name) + 1); > + return FAILURE; > + } > + > + return SUCCESS; > + > +} > +/* }}} */ > + > + > +/* {{{ php_w32api_register_callback > + */ > +static int php_w32api_register_callback(char *function_definition, int function_definition_len > TSRMLS_DC) > +{ > + w32api_func_handle **fh; > + w32api_func_handle_ptr hnd; > + > + char *new_definition = NULL; > + > + fh = emalloc(sizeof(w32api_func_handle *)); > + *fh = NULL; > + > + new_definition = emalloc(function_definition_len + sizeof(" from cb.cb")); > + > + snprintf(new_definition, function_definition_len + sizeof(" from cb.cb"), "%s > from cb.cb", function_definition); > + > + > + /* Parse function */ > + w32api_function_definition_scan_bytes(new_definition, function_definition_len + sizeof(" > from cb.cb")); > + if(w32api_function_definition_parse((void *)&hnd) != 0) > + { > + *fh = hnd.hnd; > + > + /* Leaks */ > + if(*fh != NULL) > + efree(*fh); > + > + efree(fh); > + return FAILURE; > + } > + *fh = hnd.hnd; > + > + if(!*fh) > + return FAILURE; > + > + > + if(zend_hash_exists(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + > 1)) > + { > + php_error( E_WARNING, > + "A callback by the name %s already has been registered, cannot redefine > type", > + (*fh)->function_name); > + > + /* We dont want to unload function as it already exists so lets just free it ourselves */ > + php_w32api_free_arguments((*fh)->argument_list); > + efree((*fh)->return_type_name); > + efree((*fh)->function_name); > + efree(*fh); > + efree(fh); > + > + return FAILURE; > + } > + > + /* Insert it into our hash table */ > + if(zend_hash_add( WG(callbacks), > + (*fh)->function_name, > + strlen((*fh)->function_name) + 1, > + fh, > + sizeof(w32api_func_handle *), > + NULL) != SUCCESS) > + { > + > + php_error( E_WARNING, > + "Loading of function %s failed: Could not insert function handle into hash", > + (*fh)->function_name); > + > + /* Tidy up */ > + zend_hash_del(WG(callbacks), (*fh)->function_name, strlen((*fh)->function_name) + 1); > + return FAILURE; > + } > + > + return SUCCESS; > + > + > + > +} > +/* }}} */ > + > + > +/* {{{ php_w32api_free_arguments > + * Expects one argument, the head of a list of arguments to free > + */ > +static void php_w32api_free_arguments(arguments *argument_list) > +{ > + if(argument_list == NULL) > + return; > + > + efree(argument_list->arg->argument_name); > + efree(argument_list->arg->type_name); > + efree(argument_list->arg); > + > + if(argument_list->next_arg != NULL) > + { > + php_w32api_free_arguments(argument_list->next_arg); > + } > + > + efree(argument_list); > + > + return; > +} > +/* }}} */ > + > +/* {{{ php_w32api_free_members > + * Expects one argument, the head of a list of members to free > + */ > +static void php_w32api_free_members(members *member_list) > +{ > + if(member_list == NULL) > + return; > + > + efree(member_list->member->member_name); > + > + if(member_list->member->member_type_name != NULL) > + efree(member_list->member->member_type_name); > + > + efree(member_list->member); > + > + php_w32api_free_members(member_list->next_member); > + efree(member_list); > + return; > +} > +/* }}} */ > + > +/* {{{ php_w32api_load_library > + * Expects two parameters, first is libraries name the second is a pointer > + * to a pointer to w32api_lib_handle which will recieve the resultant handle. > + * returns SUCCESS on success and FAILURE on failure. > + */ > +static int php_w32api_load_library (char *library_name, w32api_lib_handle **lh TSRMLS_DC) > +{ > + if(zend_hash_find(WG(libraries), library_name, strlen(library_name) + 1, (void **)lh) == > SUCCESS) > + { > + (*lh)->ref_count++; > + return SUCCESS; > + } > + > + *lh = (w32api_lib_handle *) emalloc( sizeof(w32api_lib_handle) ); > + (*lh)->ref_count = 1; > + (*lh)->library_name = estrdup(library_name); > + > + (*lh)->handle = LoadLibrary((*lh)->library_name); > + > + if(!(*lh)->handle) /* Could not load library */ > + { > + LPVOID message_buffer; > + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | > + FORMAT_MESSAGE_FROM_SYSTEM | > + FORMAT_MESSAGE_IGNORE_INSERTS, > + NULL, > + GetLastError(), > + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language > + (LPTSTR)&message_buffer, > + 0, > + NULL); > + > + /* Tidy up */ > + efree((*lh)->library_name); > + efree(*lh); > + efree(lh); > + > + php_error(E_WARNING, "Loading of library failed: %s", message_buffer); > + LocalFree(message_buffer); > + > + return FAILURE; > + } > + > + /* Add to hash */ > + if(zend_hash_add( WG(libraries), > + (*lh)->library_name, > + strlen((*lh)->library_name) + 1, > + *lh, > + sizeof(w32api_lib_handle), > + NULL) != SUCCESS) > + { > + > + php_error( E_WARNING, > + "Loading of library %s failed: Could not insert library handle into hash", > + (*lh)->library_name); > + > + /* Tidy up */ > + efree((*lh)->library_name); > + efree(*lh); > + efree(lh); > + > + return FAILURE; > + } > + > + > + return SUCCESS; > + > +} > +/* }}} */ > + > + > +/* {{{ php_w32api_do_arg_types > + */ > +static unsigned char *php_w32api_do_arg_types(arguments **argument_list) > +{ > + int i = 0; > + int j = 0; > + arguments *curr_arg = NULL; > + unsigned char *retval = NULL; > + > + if(!(argument_list) || !(*argument_list)) > + return NULL; > + > + curr_arg = *argument_list; > + > + /* See how much room we need to emalloc */ > + while(curr_arg) > + { > + i++; > + > + if(curr_arg->arg->flags & BYREF_FORCE) > + { > + j = i; > + } > + > + curr_arg = curr_arg->next_arg; > + } > + > + /* Check to see if any args are by ref */ > + if( j == 0 ) > + return NULL; > + > + retval = (unsigned char *)emalloc(sizeof(unsigned char) * j + 1); > + retval[0] = (unsigned char)j; > + > + curr_arg = *argument_list; > + > + for(i=1; i <= j; i++) > + { > + > + retval[i] = (unsigned char)curr_arg->arg->flags; > + curr_arg = curr_arg->next_arg; > + > + } > + > + return retval; > +} > +/* }}} */ > + > +static int php_w32api_get_type_size(int type_id, char *type_name, int flags) > +{ > + TSRMLS_FETCH(); > + > + if(flags & BYREF_FORCE) > + { > + return sizeof(void *); /* Pointers are always the same size */ > + } > + > + switch(type_id) > + { > + case W32API_NULL: > + return sizeof(void *); > + case W32API_INT: > + return sizeof(int); > + case W32API_LONG: > + return sizeof(long); > + case W32API_DOUBLE: > + return sizeof(double); > + case W32API_FLOAT: > + return sizeof(float); > + case W32API_STRING: > + return sizeof(char *); > + case W32API_BYTE: > + return sizeof(char); > + case W32API_BOOL: > + return sizeof(int); > + case W32API_COMPLEX: > + { > + w32api_type_handle **th; > + > + if(zend_hash_find(WG(types), type_name, strlen(type_name) +1, (void **)&th) != > SUCCESS) > + { > + php_error(E_ERROR, "Unknown type %s", type_name); > + return -1; > + } > + > + return (*th)->size; > + > + } > + break; > + case W32API_UNKNOWN: > + default: > + php_error(E_ERROR, "Unknown type %s", type_name); > + return -1; > + } > +} > + > +static int php_w32api_get_type_id_from_name(char *type) > +{ > + > + TSRMLS_FETCH(); > + > + if(!strcmp(type, "long")) > + { > + return W32API_LONG; > + } > + else if(!strcmp(type, "int")) > + { > + return W32API_INT; > + } > + else if (!strcmp(type, "string")) > + { > + return W32API_STRING; > + } > + else if (!strcmp(type, "byte")) > + { > + return W32API_BYTE; > + } > + else if (!strcmp(type, "bool")) > + { > + return W32API_BOOL; > + } > + else if (!strcmp(type, "double")) > + { > + return W32API_DOUBLE; > + } > + else if (!strcmp(type, "float")) > + { > + return W32API_FLOAT; > + } > + else if (!strcmp(type, "void")) > + { > + return W32API_NULL; > + } > + else > + { > + if(zend_hash_exists(WG(types), type, strlen(type) +1)) > + { > + return W32API_COMPLEX; > + } > + else > + { > + return W32API_UNKNOWN; > + } > + } > +} > + > +static void php_w32api_init_type(w32api_type_handle *th, zval *obj TSRMLS_DC) > +{ > + w32api_type_instance *ti; > + zval *rsrc_handle = NULL; > + > + ti = emalloc(sizeof(w32api_type_instance)); > + > + if(!obj) > + MAKE_STD_ZVAL(obj); > + > + object_init_ex(obj, WG(type_ce)); > + > + ti->type = th; > + ti->values = emalloc(sizeof(zval *) * th->member_count); > + memset(ti->values, '\0', sizeof(zval *) * th->member_count); > + > + MAKE_STD_ZVAL(rsrc_handle); > + ZEND_REGISTER_RESOURCE(rsrc_handle, ti, WG(le_type_instance)); > + > + zend_hash_index_update(Z_OBJPROP_P(obj), 0, &rsrc_handle, sizeof(zval *), NULL); > +} > + > + > +static int php_w32api_do_prop_get(zval *object, zval *return_value, zend_llist_element > **element TSRMLS_DC) > +{ > + w32api_type_instance *th; > + zval **type_instance_handle; > + members *current_member; > + char *property_name; > + int i = 0; > + > + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > + > + th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > + -1, "Complex Type Instance", NULL, > + 1, WG(le_type_instance)); > + > + if(!th) > + return FAILURE; > + > + property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element); > + > + current_member = th->type->member_list; > + > + while(strcmp(current_member->member->member_name, property_name) != 0) > + { > + i++; > + > + if(current_member->next_member != NULL) > + current_member = current_member->next_member; > + else > + return FAILURE; > + } > + > + *return_value = *(th->values[i]); > + zval_copy_ctor(return_value); > + > + return SUCCESS; > +} > + > +static int php_w32api_do_prop_set(zval *object, zval *value, zend_llist_element **element > TSRMLS_DC) > +{ > + w32api_type_instance *th; > + zval **type_instance_handle; > + zval *new_var; > + members *current_member; > + char *property_name; > + int i = 0; > + > + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > + > + th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > + -1, "Complex Type Instance", NULL, > + 1, WG(le_type_instance)); > + > + if(!th) > + return FAILURE; > + > + property_name = Z_STRVAL(((zend_overloaded_element *)(*element)->data)->element); > + > + current_member = th->type->member_list; > + > + while(strcmp(current_member->member->member_name, property_name) != 0) > + { > + i++; > + > + if(current_member->next_member != NULL) > + current_member = current_member->next_member; > + else > + return FAILURE; > + } > + > + if(current_member->member->flags & BYREF_FORCE) > + { > + if(th->values[i]) > + zval_ptr_dtor(&th->values[i]); > + > + MAKE_STD_ZVAL(new_var); > + *new_var = *value; > + zval_copy_ctor(new_var); > + th->values[i] = new_var; > + > + } > + else > + { > + th->values[i] = value; > + zval_add_ref(&value); > + } > + > + return SUCCESS; > +} > + > +w32api_result php_w32api_do_dynamic_dll_call(w32api_func_handle *fh, int argc, > w32api_dynamic_param *params, void *return_buffer, int return_buffer_size) > +{ > + > + /** > + * Theory Behind Implementation > + * ============================ > + * We have four main jobs: > + * 1) Push arguments onto stach aligned at 4 bytes. > + * 2) Call Function > + * 3) Get Return Values > + * 4) Perform any cleanup needed. > + * > + * Pushing arguments onto the stack is fairly simple, just push from right to left > + * so for a function with the prototype int sum(int a, int b) we would push b and > + * then a in that order. > + * > + * Calling the function is fine as we already have the pointer to the function which > + * we can use with call [function_pointer] to make the actual call. > + * > + * Return values are where we begin to get complicated. Now for simple return values up > + * to 8 bytes they are returned via the EAX/EDX register pair. This means we can just > + * copy the EAX/EDX pair to the win32_result sturcture and be sure we get any simple > + * return type. If the return type is more than 8 bytes then things get complicated. > + * When calling we must pass a hidden argument on the stach which points to a tempory > + * buffer with enough memory to hold the return value, this return value is then copied > + * to the correct varaible by us. Microsoft being the nice bunnies they are, decided to > + * copy an optimization Borland introduced under win16 which is to pass structs of under > + * 8 bytes directly via EAX/EDX pair. One final notable exception is dealing with floating > + * point return types where we need to retrive the floating point number of the systems > + * math coprocessor stack using the fstp call. > + * > + * Finally if its a __cdecl call we have to clean up the stack, otherwise the callee does > this. > + * > + */ > + > + w32api_result result = { 0 }; > + DWORD *stack_pointer, stack_size = 0, eaxv, edxv; > + BYTE *arg_ptr = NULL; > + int size = 0, i = 0; > + FARPROC fp = fh->handle; > + > + _asm mov stack_pointer, esp // Store stack pointer (esp) in stack_pointer > + _asm sub esp, 0x100 // Give ourselves 256 bytes on the stack > + > + > + for(i = (argc - 1); i >= 0; i--) > + { > + size = (params[i].width + 3)/4 * 4; > + arg_ptr = (unsigned char *)params[i].argument_ptr + size - 4; > + stack_size += (unsigned long)size; > + > + while(size > 0) > + { > + stack_pointer--; > + if(params[i].flags == W32API_ARGPTR) > + { > + *stack_pointer = *(unsigned long *)arg_ptr; > + arg_ptr -= 4; > + } > + else > + { > + *stack_pointer = params[i].argument; > + } > + > + size -= 4; > + } > + } > + > + if((return_buffer) && ((fh->flags & W32API_BORLAND) || (return_buffer_size > > 8))) > + { > + > + stack_size += 4; > + stack_pointer--; > + *stack_pointer = (unsigned long)return_buffer; > + } > + > + _asm add esp, 0x100 > + _asm sub esp, stack_size > + _asm call [fp] > + _asm mov eaxv, eax > + _asm mov edxv, edx > + > + if(fh->flags & W32API_CDECL) > + { > + _asm add esp, stack_size > + } > + > + if(fh->flags & W32API_REAL4) > + _asm fstp dword ptr [result] > + else if (fh->flags & W32API_REAL8) > + _asm fstp qword ptr [result] > + else if (!return_buffer) > + { > + _asm mov eax, [eaxv] > + _asm mov edx, [edxv] > + _asm mov DWORD PTR [result], eax > + _asm mov DWORD PTR [result + 4], edx > + } > + else if (!(fh->flags & W32API_BORLAND) && (return_buffer_size <= 8)) > + { > + _asm mov ecx, DWORD PTR [return_buffer] > + _asm mov eax, [eaxv] > + _asm mov DWORD PTR [ecx], eax > + _asm mov edx, [edxv] > + _asm mov DWORD PTR [ecx + 4], edx > + } > + > + return result; > +} > + > +void php_w32api_marshall_zval_to_c(argument *arg, w32api_dynamic_param *dp, zval *pzval > TSRMLS_DC) > +{ > + dp->flags = 0; > + > + /* We should have been passed a write reference when > + * BYREF_FORCE is Set so we just add a reference > + * when we pass it to the function, > + * TODO: register the reference internally for safe unreferencing > + */ > + > + switch(arg->type_id) > + { > + case W32API_INT: > + convert_to_long_ex(&pzval); > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&pzval->value.lval; > + dp->width = sizeof(int *); > + > + } > + else > + { > + dp->argument = (int)pzval->value.lval; > + dp->width = sizeof(int); > + } > + break; > + case W32API_LONG: > + convert_to_long_ex(&pzval); > + > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&pzval->value.lval; > + dp->width = sizeof(int *); > + zval_add_ref(&pzval); > + } > + else > + { > + dp->argument = pzval->value.lval; > + dp->width = sizeof(int); > + } > + break; > + case W32API_STRING: > + > + convert_to_string_ex(&pzval); > + if(!(arg->flags & BYREF_FORCE)) > + { > + /* Need to free this when we demarshall */ > + dp->argument = (unsigned long)estrndup(Z_STRVAL_P(pzval), Z_STRLEN_P(pzval)); > + } > + else > + { > + dp->argument = (unsigned long)Z_STRVAL_P(pzval); > + zval_add_ref(&pzval); > + } > + > + dp->width = sizeof(char *); > + break; > + > + case W32API_DOUBLE: > + convert_to_double_ex(&pzval); > + > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&pzval->value.dval; > + dp->width = sizeof(double *); > + zval_add_ref(&pzval); > + } > + else > + { > + dp->argument_ptr = &pzval->value.dval; > + dp->width = sizeof(double); > + dp->flags = W32API_ARGPTR; > + } > + break; > + case W32API_FLOAT: > + convert_to_double_ex(&pzval); > + > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&pzval->value.dval; > + dp->width = sizeof(double *); > + zval_add_ref(&pzval); > + } > + else > + { > + dp->argument_ptr = &pzval->value.dval; > + dp->width = sizeof(float); > + dp->flags = W32API_ARGPTR; > + } > + break; > + case W32API_BYTE: > + /* Thanks sterling */ > + convert_to_string_ex(&pzval); > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&Z_STRVAL_P(pzval); > + dp->width = sizeof(char *); > + zval_add_ref(&pzval); > + } > + else > + { > + dp->argument = (char)Z_STRVAL_P(pzval)[0]; > + dp->width = sizeof(char); > + } > + break; > + case W32API_BOOL: > + convert_to_boolean_ex(&pzval); > + > + if(arg->flags & BYREF_FORCE) > + { > + dp->argument = (unsigned long)&pzval->value.lval; > + dp->width = sizeof(int *); > + zval_add_ref(&pzval); > + } > + else > + { > + dp->argument = (int)pzval->value.lval; > + dp->width = sizeof(int); > + } > + break; > + case W32API_COMPLEX: > + if(Z_TYPE_P(pzval) != IS_OBJECT) > + { > + php_error(E_ERROR, "Variable passed as complex value is not an object"); > + break; > + } > + > + if(arg->flags & BYREF_FORCE) > + { > + int width= 0; > + void **ptr = NULL; > + ptr = emalloc(sizeof(void *)); > + *ptr = php_w32api_complex_marshall_zval_to_c(pzval, &width, NULL TSRMLS_CC); > + dp->argument = (unsigned long)ptr; > + dp->width = width; > + } > + else > + { > + int width= 0; > + dp->argument_ptr = php_w32api_complex_marshall_zval_to_c(pzval, &width, NULL > TSRMLS_CC); > + dp->width = width; > + } > + break; > + > + case W32API_UNKNOWN: > + php_error(E_ERROR, "Unknown type when calling function, marshalling failed"); > + break; > + } > + > +} > + > +static void *php_w32api_complex_marshall_zval_to_c(zval *pzval, int *width, void *return_value > TSRMLS_DC) > +{ > + w32api_type_instance *th; > + zval **type_instance_handle; > + members *current_member; > + char *offset = return_value; > + int i = 0; > + > + > + if(return_value == NULL) > + { > + /* First call */ > +/* return_value = emalloc(th->type->size); > + > + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &type_instance_handle); > + th = (w32api_type_instance *)zend_fetch_resource(type_instance_handle TSRMLS_CC, > + -1, "Complex Type Instance", NULL, > + 1, WG(le_type_instance)); > + > + if(!th) > + return NULL; > + > + > + for(i = 0; i < th->type->member_count; i++) > + { > + > + > + } > +*/ } > + > + > +} > + > + > +/* > ===================================================================================================== > + * Win32 Class Code > + * > ===================================================================================================== > + */ > + > +/* {{{ win32_class_functions[] > + */ > +function_entry win32_class_functions[] = { > + W32API_CLASS_FE(win32, registerfunction, NULL) > + W32API_CLASS_FE(win32, unregisterfunction, NULL) > + W32API_CLASS_FE(win32, registercallback, NULL) > + W32API_CLASS_FE(win32, definetype, NULL) > + W32API_CLASS_FE(win32, gettypesize, NULL) > + W32API_CLASS_FE(win32, inittype, NULL) > + W32API_CLASS_FE(win32, decref, NULL) > +#ifndef NDEBUG > + W32API_CLASS_FE(win32, dump_function_hash, NULL) > + W32API_CLASS_FE(win32, dump_library_hash, NULL) > + W32API_CLASS_FE(win32, dump_callback_hash, NULL) > + W32API_CLASS_FE(win32, dump_type_hash, NULL) > +#endif > + {NULL, NULL, NULL} > +}; > +/* }}} */ > + > +/* {{{ win32_class_init(TSRMLS_D) > + */ > +int win32_class_init(TSRMLS_D) > +{ > + zend_class_entry ce; > + > + INIT_CLASS_ENTRY(ce, > + "win32", > + win32_class_functions); > + > + WG(win32_ce) = zend_register_internal_class(&ce TSRMLS_CC); > + > + return SUCCESS; > +} > +/* }}} */ > + > +/* {{{ win32_class_rshutdown(TSRMLS_D) > + * Cleans up at the end of the shutdown removing and freeing anything we added to the function > + * table. > + */ > +int win32_class_rshutdown(TSRMLS_D) > +{ > + > + return SUCCESS; > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::RegisterFunction(string definition [, int flags]) > + * Registers and Loads a function from an underlying Dll > + */ > +W32API_CLASS_FUNCTION(win32, registerfunction) > +{ > + char *function_definition = NULL; > + int function_definition_len; > + long flags = 0; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > + &function_definition, > + &function_definition_len, > + &flags) == FAILURE) > + { > + return; > + } > + > + if(php_w32api_load_function(function_definition, function_definition_len, flags TSRMLS_CC) != > SUCCESS) > + { > + php_error(E_ERROR, "Registering Function %s failed", function_definition); > + RETURN_FALSE; > + } > + > + RETURN_TRUE; > + > + > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::UnregisterFunction(string function_name) > + * Unregisters a previously loaded function > + */ > +W32API_CLASS_FUNCTION(win32, unregisterfunction) > +{ > + char *function_name = NULL; > + int function_name_len; > + w32api_func_handle **fh = NULL; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > + &function_name, > + &function_name_len) == FAILURE) > + { > + return; > + } > + > + /* Our deleteor handler removes us from the WG(win32_ce)->function_table > + * so no need to delete specifically from there > + */ > + zend_hash_del(WG(funcs), function_name, strlen(function_name) + 1); > + > + RETURN_TRUE; > + > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::RegisterCallback(string definition) > + * Registers a callback type > + */ > +W32API_CLASS_FUNCTION(win32, registercallback) > +{ > + char *function_definition = NULL; > + int function_definition_len; > + w32api_func_handle **fh = NULL; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", > + &function_definition, > + &function_definition_len) == FAILURE) > + { > + return; > + } > + > + if(php_w32api_register_callback(function_definition, function_definition_len TSRMLS_CC) != > SUCCESS) > + { > + RETURN_FALSE; > + } > + > + RETURN_TRUE; > + > +} > +/* }}} */ > + > + > +/* {{{ proto: int Win32::DefineType(string definition) > + * Defines a C Like Type for use. > + */ > +W32API_CLASS_FUNCTION(win32, definetype) > +{ > + char *type_definition = NULL; > + int type_definition_len; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > + &type_definition, > + &type_definition_len) == FAILURE) > + { > + return; > + } > + > + if(php_w32api_register_type(type_definition, type_definition_len TSRMLS_CC) != SUCCESS) > + { > + php_error(E_ERROR, "Registering Type %s failed", type_definition); > + RETURN_FALSE; > + } > + > + RETURN_TRUE; > + > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::GetTypeSize(string type_name) > + * Returns the size of a registered type > + */ > +W32API_CLASS_FUNCTION(win32, gettypesize) > +{ > + char *type = NULL; > + int type_len; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > + &type, > + &type_len) == FAILURE) > + { > + return; > + } > + > + RETURN_LONG(php_w32api_get_type_size(php_w32api_get_type_id_from_name(type), type, > BYREF_NONE)); > + > + > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::InitType(string TypeName) > + * Creates an instance of type TypeName > + */ > +W32API_CLASS_FUNCTION(win32, inittype) > +{ > + char *type_name = NULL; > + int type_name_len = 0; > + w32api_type_handle **th = NULL; > + > + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", > + &type_name, &type_name_len) == FAILURE) > + { > + return; > + } > + > + if(zend_hash_find(WG(types), type_name, type_name_len +1, (void **)&th) == FAILURE) > + { > + php_error(E_ERROR, "Could not retrieve type handle for type %s from hash table", > type_name); > + RETURN_FALSE; > + } > + > + php_w32api_init_type(*th, return_value TSRMLS_CC); > + > +} > +/* }}} */ > + > +/* {{{ proto: int Win32::DecRef(mixed Variable) > + * Decreases the reference count on a variable > + */ > +W32API_CLASS_FUNCTION(win32, decref) > +{ > + > +} > +/* }}} */ > + > +/* {{{ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX > + * THIS FUNCTION IS NOT PUBLICALLY ACCESSABLE > + * IT IS USED AS A GENERIC HANDLER FOR W32API > + * CALLS. > + */ > +W32API_CLASS_FUNCTION(win32, invokefunction) > +{ > + char *function_name = get_active_function_name(TSRMLS_C); > + int argc = ZEND_NUM_ARGS(); > + int i = 0; > + w32api_dynamic_param *params = NULL; > + w32api_dynamic_param *current_dynamic_param = NULL; > + w32api_func_handle **fh = NULL; > + w32api_result res = {0}; > + void *w32api_return_buffer = NULL; > + int w32api_return_buffer_size = 0; > + zval **func_arguments = NULL; > + zval *current_zval = NULL; > + arguments *curr_arg = NULL; > + w32api_type_handle *th = NULL; > + > + if(zend_hash_find(WG(funcs), function_name, strlen(function_name) +1, (void **)&fh) == > FAILURE) > + { > + php_error(E_ERROR, "Could not retrieve function handle from hash table"); > + RETURN_FALSE; > + } > + > + if(argc) > + { > + if(zend_get_parameters_array_ex(argc, &func_arguments) == FAILURE) > + { > + WRONG_PARAM_COUNT > + } > + > + params = (w32api_dynamic_param *)emalloc(sizeof(w32api_dynamic_param) * argc); > + > + curr_arg = (*fh)->argument_list; > + current_dynamic_param = params; > + > + for(i = 0; i < argc; i++) > + { > + current_zval = func_arguments[i]; > + php_w32api_marshall_zval_to_c(curr_arg->arg, current_dynamic_param, current_zval > TSRMLS_CC); > + > + current_dynamic_param++; > + curr_arg = curr_arg->next_arg; > + } > + } > + else > + { > + params = NULL; > + } > + > + if((*fh)->return_type_id == W32API_COMPLEX) > + { > + if(zend_hash_find(WG(types), (*fh)->return_type_name, strlen((*fh)->return_type_name) > +1, (void **)&th) != SUCCESS) > + php_error(E_ERROR, "Could not find type handle for type %s", > (*fh)->return_type_name); > + > + w32api_return_buffer = emalloc(th->size); > + w32api_return_buffer_size = th->size; > + } > + > + > + > + res = php_w32api_do_dynamic_dll_call(*fh, argc, params, w32api_return_buffer, > w32api_return_buffer_size); > + > + if(argc) > + /* We should demarshall here not just efree */ > + efree(params); > + > + switch((*fh)->return_type_id) > + { > + case W32API_LONG: > + RETURN_LONG(res.lval); > + break; > + case W32API_INT: > + RETURN_LONG(res.ival); > + break; > + case W32API_STRING: > + case W32API_BYTE: > + RETURN_STRING(res.ptr, 1); > + break; > + case W32API_DOUBLE: > + RETURN_DOUBLE(res.dval); > + break; > + case W32API_FLOAT: > + RETURN_DOUBLE(res.fval); > + break; > + case W32API_BOOL: > + if(res.ival) > + { > + RETURN_TRUE; > + } > + else > + { > + RETURN_FALSE; > + } > + break; > + case W32API_COMPLEX: > + break; > + default: > + php_error(E_WARNING, "Unknown return type %s", (*fh)->return_type_name); > + } > + > +} > +/* }}} */ > + > +#ifndef NDEBUG > +W32API_CLASS_FUNCTION(win32, dump_library_hash) > +{ > + zend_hash_apply(WG(libraries), (apply_func_t)php_w32api_dump_library_hash_cb TSRMLS_CC); > +} > + > +W32API_CLASS_FUNCTION(win32, dump_function_hash) > +{ > + zend_hash_apply(WG(funcs), (apply_func_t)php_w32api_dump_function_hash_cb TSRMLS_CC); > +} > + > +W32API_CLASS_FUNCTION(win32, dump_callback_hash) > +{ > + > + zend_hash_apply(WG(callbacks), (apply_func_t)php_w32api_dump_callback_hash_cb TSRMLS_CC); > +} > + > + > +W32API_CLASS_FUNCTION(win32, dump_type_hash) > +{ > + > + zend_hash_apply(WG(types), (apply_func_t)php_w32api_dump_type_hash_cb TSRMLS_CC); > +} > + > +int php_w32api_dump_library_hash_cb(void *pData TSRMLS_DC) > +{ > + w32api_lib_handle *lh = pData; > + > + printf("=====================================================================\n"); > + printf("Library Name: \t\t%s\n", lh->library_name); > + printf("Reference Count: \t\t%d\n", lh->ref_count); > + printf("Library Handle: \t\t%p\n", lh->handle); > + printf("Lib ptr loc \t\t%p\n", lh); > + printf("ll n loc \t\t%p\n", &lh->ref_count); > + > + printf("=====================================================================\n"); > + > + return 0; > +} > + > +int php_w32api_dump_function_hash_cb(void *pData TSRMLS_DC) > +{ > + w32api_func_handle **fh = pData; > + > + printf("=====================================================================\n"); > + printf("Function Name: \t\t%s\n", (*fh)->function_name); > + printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > + printf("Library Name: \t\t%s\n", (*fh)->lib->library_name ); > + printf("Function Flags: \t\t%d\n", (*fh)->flags); > + printf("Function Handle: \t\t%p\n", (*fh)->handle); > + printf("Return Type ID: \t\t%d\n", (*fh)->return_type_id); > + printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > + printf("## Arguments ##\n"); > + printf("---------------------------------------------------------------------\n"); > + php_w32api_print_arguments((*fh)->argument_list); > > + printf("=====================================================================\n\n"); > + > + return 0; > +} > + > +int php_w32api_dump_callback_hash_cb(void *pData TSRMLS_DC) > +{ > + w32api_func_handle **fh = pData; > + > + printf("=====================================================================\n"); > + printf("Callback Name: \t\t%s\n", (*fh)->function_name); > + printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > + printf("Callback Flags: \t\t%d\n", (*fh)->flags); > + printf("Return Type ID: \t\t%d\n", (*fh)->return_type_id); > + printf("Return Type Name: \t\t%s\n", (*fh)->return_type_name); > + printf("## Arguments ##\n"); > + printf("---------------------------------------------------------------------\n"); > + php_w32api_print_arguments((*fh)->argument_list); > > + printf("=====================================================================\n\n"); > + > + return 0; > +} > + > +int php_w32api_dump_type_hash_cb(void *pData TSRMLS_DC) > +{ > + w32api_type_handle **th = pData; > + > + > + printf("=====================================================================\n"); > + printf("Type Name: \t\t%s\n", (*th)->type_name); > + printf("Type Size: \t\t%d\n", (*th)->size); > + printf("Member Count: \t\t%d\n", (*th)->member_count); > + printf("## Members ##\n"); > + printf("---------------------------------------------------------------------\n"); > + php_w32api_print_members((*th)->member_list); > > + printf("=====================================================================\n\n"); > + > + return 0; > +} > + > +void php_w32api_print_members(members *member_list) > +{ > + if(member_list == NULL) > + return; > + > + printf("\tMember Name: \t%s\n", member_list->member->member_name); > + printf("\tMember Flags: \t%d\n", member_list->member->flags); > + printf("\tMember Type ID: \t%d\n", member_list->member->member_type_id); > + printf("\tMember Type Name:\t%s\n", member_list->member->member_type_name); > + printf("\tMember Offset: \t%d\n", member_list->member->offset); > + printf("---------------------------------------------------------------------\n"); > + > + php_w32api_print_members(member_list->next_member); > + > +} > +void php_w32api_print_arguments(arguments *argument_list) > +{ > + if(argument_list == NULL) > + return; > + > + printf("\tArgument Name: \t%s\n", argument_list->arg->argument_name); > + printf("\tArgument Flags: \t%d\n", argument_list->arg->flags); > + printf("\tArgument Type ID:\t%d\n", argument_list->arg->type_id); > + printf("\tArg Type Name: \t%s\n", argument_list->arg->type_name); > + printf("---------------------------------------------------------------------\n"); > + > + php_w32api_print_arguments(argument_list->next_arg); > +} > +#endif > +/* > ===================================================================================================== > + * Type Class Code > + * > ===================================================================================================== > + */ > + > +/* {{{ type_class_functions[] > + */ > +function_entry type_class_functions[] = { > + W32API_CLASS_FE(type, clone, NULL) > + {NULL, NULL, NULL} > +}; > +/* }}} */ > + > + > +/* {{{ type_class_init(TSRMLS_DC) > + */ > +int type_class_init(TSRMLS_D) > +{ > + zend_class_entry ce; > + > + INIT_OVERLOADED_CLASS_ENTRY(ce, > + "type", > + type_class_functions, > + NULL, > + W32API_PROP_GET_FUNCTION_N(type), > + W32API_PROP_SET_FUNCTION_N(type)); > + > + WG(type_ce) = zend_register_internal_class(&ce TSRMLS_CC); > + > + return SUCCESS; > +} > +/* }}} */ > + > +/* {{{ W32API_PROP_SET_FUNCTION(type) > + */ > +/* Most of this code is borrowed from php-gtk. Thanks to Andrei and Zeev for their > + * help with the prop-get/set functions > + */ > +W32API_PROP_SET_FUNCTION(type) > +{ > + zval result, temp; > + zval *temp_ptr = &temp; > + zval *new_val; > + zend_overloaded_element *overloaded_property; > + zend_llist_element *element; > + zval **object = &property_reference->object; > + int setter_retval, getter_retval; > + TSRMLS_FETCH(); > + > + > + /* If we have $foo->bar->baz->boo->bin we have to do sucessive propgets > + * Until we can do our prop set (thanks Zeev, Andrei) > + */ > + for (element=property_reference->elements_list->head; element != > property_reference->elements_list->tail; element=element->next) { > + overloaded_property = (zend_overloaded_element *)element->data; > + > + getter_retval = FAILURE; > + if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) { > + if (Z_TYPE_PP(object) == IS_NULL || > + (Z_TYPE_PP(object) == IS_BOOL && Z_LVAL_PP(object) == 0) || > + (Z_TYPE_PP(object) == IS_STRING && Z_STRLEN_PP(object) == 0)) { > + object_init(*object); > + } > + > + > + /* Trying to access a property on a non-object. */ > + if (Z_TYPE_PP(object) != IS_OBJECT) { > + return FAILURE; > + } > + > + getter_retval = php_w32api_do_prop_get(*object, &result, &element TSRMLS_CC); > + > + if (getter_retval == SUCCESS) { > + temp = result; > + object = &temp_ptr; > + } else { > + if ((getter_retval = zend_hash_find(Z_OBJPROP_PP(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + (void **)&object)) == FAILURE) { > + MAKE_STD_ZVAL(new_val); > + ZVAL_NULL(new_val); > + zend_hash_update(Z_OBJPROP_PP(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + &new_val, sizeof(void *), (void **)&object); > + } > + } > + > + } else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) { > + if (Z_TYPE_PP(object) == IS_NULL || > + (Z_TYPE_PP(object) == IS_BOOL && Z_LVAL_PP(object) == 0) || > + (Z_TYPE_PP(object) == IS_STRING && Z_STRLEN_PP(object) == 0)) { > + array_init(*object); > + } > + > + /* Trying to access index on a non-array. */ > + if (Z_TYPE_PP(object) != IS_ARRAY) { > + return FAILURE; > + } > + > + if (Z_TYPE(overloaded_property->element) == IS_STRING) { > + getter_retval = zend_hash_find(Z_ARRVAL_PP(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + (void **)&object); > + } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > + getter_retval = zend_hash_index_find(Z_ARRVAL_PP(object), > + Z_LVAL(overloaded_property->element), > + (void **)&object); > + } > + > + if (getter_retval == FAILURE) { > + MAKE_STD_ZVAL(new_val); > + ZVAL_NULL(new_val); > + > + if (Z_TYPE(overloaded_property->element) == IS_STRING) { > + zend_hash_update(Z_ARRVAL_PP(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + &new_val, sizeof(void *), (void **)&object); > + } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > + zend_hash_index_update(Z_ARRVAL_PP(object), > + Z_LVAL(overloaded_property->element), > + &new_val, sizeof(void *), (void **)&object); > + } > + } > + } > + > + zval_dtor(&overloaded_property->element); > + } > + > + /* object is now the object we want to set our property on */ > + overloaded_property = (zend_overloaded_element *) element->data; > + setter_retval = php_w32api_do_prop_set(*object, value, &element TSRMLS_CC); > + zval_dtor(&overloaded_property->element); > + > + return setter_retval; > + > +} > +/* }}} */ > + > +/* {{{ W32API_PROP_GET_FUNCTION(type) > + */ > +W32API_PROP_GET_FUNCTION(type) > +{ > + zval result; > + zval *result_ptr = &result; > + zval **prop_result; > + zend_overloaded_element *overloaded_property; > + zend_llist_element *element; > + zval object = *property_reference->object; > + int getter_retval; > + TSRMLS_FETCH(); > + > + for (element=property_reference->elements_list->head; element; > element=element->next) { > + overloaded_property = (zend_overloaded_element *) element->data; > + > + getter_retval = FAILURE; > + ZVAL_NULL(&result); > + if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) { > + /* Trying to access a property on a non-object. */ > + if (Z_TYPE(object) != IS_OBJECT || > + Z_TYPE(overloaded_property->element) != IS_STRING) { > + return result; > + } > + > + if ((getter_retval = php_w32api_do_prop_get(&object, &result, &element > TSRMLS_CC) == FAILURE)) { > + if ((getter_retval = zend_hash_find(Z_OBJPROP(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + (void **)&prop_result)) == SUCCESS) { > + result = **prop_result; > + } > + } > + } else if (Z_TYPE_P(overloaded_property) == OE_IS_ARRAY) { > + /* Trying to access index on a non-array. */ > + if (Z_TYPE(object) != IS_ARRAY) { > + return result; > + } > + > + if (Z_TYPE(overloaded_property->element) == IS_STRING) { > + getter_retval = zend_hash_find(Z_ARRVAL(object), > + Z_STRVAL(overloaded_property->element), > + Z_STRLEN(overloaded_property->element)+1, > + (void **)&prop_result); > + } else if (Z_TYPE(overloaded_property->element) == IS_LONG) { > + getter_retval = zend_hash_index_find(Z_ARRVAL(object), > + Z_LVAL(overloaded_property->element), > + (void **)&prop_result); > + } > + if (getter_retval == SUCCESS) > + result = **prop_result; > + } > + > + zval_dtor(&overloaded_property->element); > + > + object = result; > + > + if (getter_retval == FAILURE) { > + return result; > + } > + } > + > + zval_add_ref(&result_ptr); > + SEPARATE_ZVAL(&result_ptr); > + return *result_ptr; > +} > +/* }}} */ > + > +/* {{{ proto: Type Type::Clone() > + * Creates an exact clone of the object. > + */ > +W32API_CLASS_FUNCTION(type, clone) > +{ > + > +} > +/* }}} */ > + > +/* > ===================================================================================================== > + * Scanner & Parser Functions > + * > ===================================================================================================== > + */ > + > +/* ----------------------------- > + * Function Definition Functions > + * ----------------------------- > + */ > + > +/* {{{ w32api_parser_load_function_ex > + * Callback for the parser, if the library name is cb.cb we are registering a > + * callback so the LoadLibary and GetProcAddress code is skipped > + */ > +w32api_func_handle *w32api_parser_load_function_ex(char *return_type, char *function_name, > char *alias_name, arguments *argument_list, char *library_name) > +{ > + w32api_func_handle *return_value; > + TSRMLS_FETCH(); > + > + return_value = (w32api_func_handle *)emalloc(sizeof(w32api_func_handle)); > + memset(return_value, '\0', sizeof(w32api_func_handle)); > + > + return_value->argument_list = argument_list; > + return_value->flags = 0; > + return_value->function_name = (alias_name)?alias_name:function_name; /* This is > estrdup'd in the Scanner already!! */ > + return_value->return_type_name = return_type; /* This is estrdup'd in the > Scanner already!! */ > + return_value->return_type_id = php_w32api_get_type_id_from_name(return_type); > + > + if(strcmp("cb.cb", library_name)) /* Bit of a hack but we are > registering a callback */ > + { > + php_w32api_load_library(library_name, &return_value->lib TSRMLS_CC); > + > + if(!return_value->lib) > + { > + /* php_w32api_load_library has already given error */ > + efree(return_value); > + return NULL; > + } > + > + return_value->handle = GetProcAddress(return_value->lib->handle, function_name); > + > + if(!return_value->handle) > + { > + /* Check for variation ending with A */ > + char *ascii_name = NULL; > + > + ascii_name = emalloc(strlen(function_name) + 2); > + strcpy(ascii_name, function_name); > + ascii_name[strlen(function_name)] = 'A'; > + ascii_name[strlen(function_name) + 1] = '\0'; > + return_value->handle = GetProcAddress(return_value->lib->handle, ascii_name); > + efree(ascii_name); > + > + if(!return_value->handle) > + { > + /* TODO: php_error_docref and GetLastError etc */ > + php_error(E_WARNING, "Could not load function %s", function_name); > + efree(return_value); > + return NULL; > + } > + } > + } > + > + /* We want function_name in lowercase now */ > + php_strtolower(return_value->function_name, strlen(return_value->function_name)); > + > + /* Free it if we have a alias */ > + if(alias_name) > + efree(function_name); > + > + return return_value; > +} > +/* }}} */ > + > +/* {{{ w32api_parser_make_argument > + * Helper function for the parser > + */ > +arguments *w32api_parser_make_argument(char *arg_type, char *arg_name, int byref) > +{ > + arguments *return_value = NULL; /* Pointer to our return value */ > + argument *argument_value = NULL; /* Our actual argument */ > + > + argument_value = emalloc(sizeof(argument)); > + return_value = emalloc(sizeof(arguments)); > + > + return_value->arg = argument_value; > + return_value->next_arg = return_value->prev_arg = NULL; > + > + argument_value->flags = byref; > + argument_value->argument_name = arg_name; > + argument_value->type_name = arg_type; > + argument_value->type_id = php_w32api_get_type_id_from_name(arg_type); > + > + if(argument_value->type_id == W32API_UNKNOWN) > + { > + php_error(E_NOTICE, "Unknown type %s used as arugment type", arg_type); > + } > + > + return return_value; > +} > +/* }}} */ > + > +/* {{{ w32api_parser_join_arguments > + * Helper function for the parser > + */ > +arguments *w32api_parser_join_arguments(arguments *lval, arguments *rval) > +{ > + lval->next_arg = rval; > + rval->prev_arg = lval; > + > + return lval; > +} > +/* }}} */ > + > +/* {{{ w32api_function_definition_error > + * Error function for the parser > + */ > +int w32api_function_definition_error(char *s) > +{ > + php_error(E_ERROR, "Function Definition Parse Error: %s", s); > + return 0; > +} > +/* }}} */ > + > +/* ------------------------- > + * Type Definition Functions > + * ------------------------- > + */ > +w32api_type_handle *w32api_parser_register_type(char *type_name, members *member_list) > +{ > + w32api_type_handle *return_value = NULL; > + members *current_member; > + int offset = 0; > + int member_count = 0; > + > + return_value = emalloc(sizeof(w32api_type_handle)); > + > + return_value->member_list = member_list; > + return_value->type_name = type_name; /* estrdup'd in parser */ > + return_value->member_count = 0; > + > + current_member = return_value->member_list; > + > + > + while(current_member != NULL) > + { > + return_value->member_count++; > + current_member->member->offset = offset; > + offset += php_w32api_get_type_size(current_member->member->member_type_id, > current_member->member->member_type_name, current_member->member->flags); > + current_member = current_member->next_member; > + } > + > + > + return_value->size = offset; > + > + return return_value; > + > + > +} > + > +members *w32api_parser_type_make_value(char *type_name, char *member_name, long flags) > +{ > + members *return_value = NULL; /* Pointer to our return value */ > + member *member_value = NULL; /* Our actual member */ > + > + member_value = emalloc(sizeof(member)); > + return_value = emalloc(sizeof(members)); > + > + return_value->member = member_value; > + return_value->next_member = return_value->prev_member = NULL; > + > + member_value->member_name = member_name; /* estrdup'd in parser */ > + member_value->member_type_name = type_name; /* estrdup'd in parser */ > + member_value->member_type_id = php_w32api_get_type_id_from_name(type_name); > + member_value->flags = flags; > + > + return return_value; > +} > + > + > +members *w32api_parser_type_join_values(members *lval, members *rval) > +{ > + lval->next_member = rval; > + rval->prev_member = lval; > + > + return lval; > +} > + > +/* {{{ w32api_function_definition_error > + * Error function for the parser > + */ > +int w32api_type_definition_error(char *s) > +{ > + php_error(E_ERROR, "Type Definition Parse Error: %s", s); > + return 0; > +} > +/* }}} */ > + > + > #endif /* HAVE_W32API */ > Index: php4/ext/w32api/w32api_function_definition_parser.y > diff -u php4/ext/w32api/w32api_function_definition_parser.y:1.1 > php4/ext/w32api/w32api_function_definition_parser.y:1.2 > --- php4/ext/w32api/w32api_function_definition_parser.y:1.1 Tue Nov 12 09:31:33 2002 > +++ php4/ext/w32api/w32api_function_definition_parser.y Wed Nov 20 13:39:38 2002 > @@ -1,67 +1,67 @@ > -%{ > -/* > - +----------------------------------------------------------------------+ > - | PHP version 4.0 | > - +----------------------------------------------------------------------+ > - | Copyright (c) 1997-2001 The PHP Group | > - +----------------------------------------------------------------------+ > - | This source file is subject to version 2.02 of the PHP license, | > - | that is bundled with this package in the file LICENSE, and is | > - | available at through the world-wide-web at | > - | http://www.php.net/license/2_02.txt. > | > - | If you did not receive a copy of the PHP license and are unable to | > - | obtain it through the world-wide-web, please send a note to | > - | license@php.net so we can mail you a copy immediately. | > - +----------------------------------------------------------------------+ > - | Authors: James Moore <jmoore@php.net> | > - +----------------------------------------------------------------------+ > - */ > - > -/* $Id: w32api_function_definition_parser.y,v 1.1 2002/11/12 14:31:33 jmoore Exp $ */ > - > -#include <stdio.h> > -#include <stdlib.h> > -#define WIN32_LEAN_AND_MEAN > -#include <windows.h> > -#include <string.h> > - > -#include "php.h" > -#include "php_ini.h" > -#include "ext/standard/info.h" > -#include "ext/standard/php_string.h" > -#include "php_w32api.h" > - > - > -#define YYSTYPE w32api_parser_function_definition_union > -#define YYPARSE_PARAM fh > - > -int w32api_function_definition_lex(w32api_parser_function_definition_union *funcdef_lval); > - > -%} > - > -%pure_parser > - > -%token tFROM > -%token tBYREF > -%token tALIAS > -%token <s> tIDENTIFIER > -%token <s> tFILENAME > - > -%type <arg> argument argument_list > - > -%start funcdef > - > -%% > - > -funcdef: tIDENTIFIER tIDENTIFIER tALIAS tIDENTIFIER'(' argument_list ')' > tFROM tFILENAME {((w32api_func_handle_ptr *)fh)->hnd = w32api_parser_load_alias_function($1, $2, > $4, $6, $9);} > - | tIDENTIFIER tIDENTIFIER '(' argument_list ')' tFROM tFILENAME > {((w32api_func_handle_ptr *)fh)->hnd = w32api_parser_load_function($1, $2, $4, $7);} > -; > - > -argument_list: argument ',' argument_list { $$ = w32api_parser_join_arguments($1, > $3);} > - | argument {$$ = $1;} > - | {$$ = NULL} > -; > - > -argument: tIDENTIFIER tIDENTIFIER { $$ = w32api_parser_make_argument_byval($1, $2); } > - | tIDENTIFIER tBYREF tIDENTIFIER { $$ = w32api_parser_make_argument_byref($1, $3); } > -; > +%{ > +/* > + +----------------------------------------------------------------------+ > + | PHP version 4.0 | > + +----------------------------------------------------------------------+ > + | Copyright (c) 1997-2001 The PHP Group | > + +----------------------------------------------------------------------+ > + | This source file is subject to version 2.02 of the PHP license, | > + | that is bundled with this package in the file LICENSE, and is | > + | available at through the world-wide-web at | > + | http://www.php.net/license/2_02.txt. > | > + | If you did not receive a copy of the PHP license and are unable to | > + | obtain it through the world-wide-web, please send a note to | > + | license@php.net so we can mail you a copy immediately. | > + +----------------------------------------------------------------------+ > + | Authors: James Moore <jmoore@php.net> | > + +----------------------------------------------------------------------+ > + */ > + > +/* $Id: w32api_function_definition_parser.y,v 1.2 2002/11/20 18:39:38 fmk Exp $ */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#define WIN32_LEAN_AND_MEAN > +#include <windows.h> > +#include <string.h> > + > +#include "php.h" > +#include "php_ini.h" > +#include "ext/standard/info.h" > +#include "ext/standard/php_string.h" > +#include "php_w32api.h" > + > + > +#define YYSTYPE w32api_parser_function_definition_union > +#define YYPARSE_PARAM fh > + > +int w32api_function_definition_lex(w32api_parser_function_definition_union *funcdef_lval); > + > +%} > + > +%pure_parser > + > +%token tFROM > +%token tBYREF > +%token tALIAS > +%token <s> tIDENTIFIER > +%token <s> tFILENAME > + > +%type <arg> argument argument_list > + > +%start funcdef > + > +%% > + > +funcdef: tIDENTIFIER tIDENTIFIER tALIAS tIDENTIFIER'(' argument_list ')' > tFROM tFILENAME {((w32api_func_handle_ptr *)fh)->hnd = w32api_parser_load_alias_function($1, $2, > $4, $6, $9);} > + | tIDENTIFIER tIDENTIFIER '(' argument_list ')' tFROM tFILENAME > {((w32api_func_handle_ptr *)fh)->hnd = w32api_parser_load_function($1, $2, $4, $7);} > +; > + > +argument_list: argument ',' argument_list { $$ = w32api_parser_join_arguments($1, > $3);} > + | argument {$$ = $1;} > + | {$$ = NULL} > +; > + > +argument: tIDENTIFIER tIDENTIFIER { $$ = w32api_parser_make_argument_byval($1, $2); } > + | tIDENTIFIER tBYREF tIDENTIFIER { $$ = w32api_parser_make_argument_byref($1, $3); } > +; > Index: php4/ext/w32api/w32api_type_definition_parser.y > diff -u php4/ext/w32api/w32api_type_definition_parser.y:1.1 > php4/ext/w32api/w32api_type_definition_parser.y:1.2 > --- php4/ext/w32api/w32api_type_definition_parser.y:1.1 Tue Nov 12 09:31:34 2002 > +++ php4/ext/w32api/w32api_type_definition_parser.y Wed Nov 20 13:39:38 2002 > @@ -1,67 +1,67 @@ > -%{ > -/* > - +----------------------------------------------------------------------+ > - | PHP version 4.0 | > - +----------------------------------------------------------------------+ > - | Copyright (c) 1997-2001 The PHP Group | > - +----------------------------------------------------------------------+ > - | This source file is subject to version 2.02 of the PHP license, | > - | that is bundled with this package in the file LICENSE, and is | > - | available at through the world-wide-web at | > - | http://www.php.net/license/2_02.txt. > | > - | If you did not receive a copy of the PHP license and are unable to | > - | obtain it through the world-wide-web, please send a note to | > - | license@php.net so we can mail you a copy immediately. | > - +----------------------------------------------------------------------+ > - | Authors: James Moore <jmoore@php.net> | > - +----------------------------------------------------------------------+ > - */ > - > -/* $Id: w32api_type_definition_parser.y,v 1.1 2002/11/12 14:31:34 jmoore Exp $ */ > - > -#include <stdio.h> > -#include <stdlib.h> > -#define WIN32_LEAN_AND_MEAN > -#include <windows.h> > -#include <string.h> > - > -#include "php.h" > -#include "php_ini.h" > -#include "ext/standard/info.h" > -#include "ext/standard/php_string.h" > -#include "php_w32api.h" > - > -#define YYSTYPE w32api_parser_type_definition_union > -#define YYPARSE_PARAM th > - > -int w32api_type_definition_lex(w32api_parser_type_definition_union *typedef_lval); > - > -%} > - > -%pure_parser > - > -%token <s> tTYPEID > -%token tBYREF > - > -%type <type> value_list value > - > -%% > - > -start: > - type_definition > -; > - > -type_definition: > - tTYPEID '{' value_list '}' {((w32api_type_handle_ptr *)th)->hnd = > w32api_parser_register_type($1, $3);} > -; > - > -value_list: > - value ';' value_list {$$ = w32api_parser_type_join_values($1, $3);} > - | value ';' {$$ = $1;} > -; > - > -value: > - tTYPEID tTYPEID {$$ = w32api_parser_type_make_byval_value($1, $2);} > - | tTYPEID tBYREF tTYPEID {$$ = w32api_parser_type_make_byref_value($1, $3);} > -; > - > +%{ > +/* > + +----------------------------------------------------------------------+ > + | PHP version 4.0 | > + +----------------------------------------------------------------------+ > + | Copyright (c) 1997-2001 The PHP Group | > + +----------------------------------------------------------------------+ > + | This source file is subject to version 2.02 of the PHP license, | > + | that is bundled with this package in the file LICENSE, and is | > + | available at through the world-wide-web at | > + | http://www.php.net/license/2_02.txt. > | > + | If you did not receive a copy of the PHP license and are unable to | > + | obtain it through the world-wide-web, please send a note to | > + | license@php.net so we can mail you a copy immediately. | > + +----------------------------------------------------------------------+ > + | Authors: James Moore <jmoore@php.net> | > + +----------------------------------------------------------------------+ > + */ > + > +/* $Id: w32api_type_definition_parser.y,v 1.2 2002/11/20 18:39:38 fmk Exp $ */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#define WIN32_LEAN_AND_MEAN > +#include <windows.h> > +#include <string.h> > + > +#include "php.h" > +#include "php_ini.h" > +#include "ext/standard/info.h" > +#include "ext/standard/php_string.h" > +#include "php_w32api.h" > + > +#define YYSTYPE w32api_parser_type_definition_union > +#define YYPARSE_PARAM th > + > +int w32api_type_definition_lex(w32api_parser_type_definition_union *typedef_lval); > + > +%} > + > +%pure_parser > + > +%token <s> tTYPEID > +%token tBYREF > + > +%type <type> value_list value > + > +%% > + > +start: > + type_definition > +; > + > +type_definition: > + tTYPEID '{' value_list '}' {((w32api_type_handle_ptr *)th)->hnd = > w32api_parser_register_type($1, $3);} > +; > + > +value_list: > + value ';' value_list {$$ = w32api_parser_type_join_values($1, $3);} > + | value ';' {$$ = $1;} > +; > + > +value: > + tTYPEID tTYPEID {$$ = w32api_parser_type_make_byval_value($1, $2);} > + | tTYPEID tBYREF tTYPEID {$$ = w32api_parser_type_make_byref_value($1, $3);} > +; > + > > -- > PHP CVS Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php

« previous php.cvs (#16481) next »