Re: cvs: php4 /ext/w32api php_w32api.h w32api.c w32api_function_definition_parser.y w32api_type_definition_parser.y
| From: | Markus Fischer | 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