⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w32api.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*   +----------------------------------------------------------------------+   | PHP version 4.0                                                      |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.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.2.4.2.2 2007/01/01 09:46:49 sebastian 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 function 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_W32APIZEND_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){	HashTable *tmp;	WG(funcs) = WG(libraries) = WG(callbacks) = WG(types) = NULL;		/* Allocate Request Specific HT's here	 */	ALLOC_HASHTABLE(tmp);	zend_hash_init(tmp, 1, NULL, php_w32api_hash_func_dtor, 1);	WG(funcs) = tmp;	ALLOC_HASHTABLE(tmp);	zend_hash_init(tmp, 1, NULL, php_w32api_hash_lib_dtor, 1);	WG(libraries) = tmp;	ALLOC_HASHTABLE(tmp);	zend_hash_init(tmp, 1, NULL, php_w32api_hash_callback_dtor, 1);	WG(callbacks) = tmp;	ALLOC_HASHTABLE(tmp);	zend_hash_init(tmp, 1, NULL, php_w32api_hash_type_dtor, 1);	WG(types) = tmp;	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));	WG(funcs) = WG(libraries) = WG(callbacks) = WG(types) = NULL;	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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -