From 70941fe41b93d6a7c6809780b17c6323127977cd Mon Sep 17 00:00:00 2001 From: James Moore Date: Wed, 7 Nov 2001 14:31:03 +0000 Subject: [PATCH] @ - Add generic Win 32 API extension (jmoore) --- ext/w32api/CREDITS | 2 + ext/w32api/EXPERIMENTAL | 0 ext/w32api/README | 49 ++ ext/w32api/TODO | 5 + ext/w32api/examples/uptime.php | 64 +++ ext/w32api/php_w32api.h | 137 +++++ ext/w32api/test_dll/dll_test.h | 31 ++ ext/w32api/test_dll/test.php | 10 + ext/w32api/test_dll/test_dll.c | 33 ++ ext/w32api/test_dll/test_dll.def | 2 + ext/w32api/test_dll/test_dll.dsp | 110 ++++ ext/w32api/test_dll/test_dll.dsw | 29 + ext/w32api/w32api.c | 898 +++++++++++++++++++++++++++++++ ext/w32api/w32api.dsp | 114 ++++ 14 files changed, 1484 insertions(+) create mode 100644 ext/w32api/CREDITS create mode 100644 ext/w32api/EXPERIMENTAL create mode 100644 ext/w32api/README create mode 100644 ext/w32api/TODO create mode 100644 ext/w32api/examples/uptime.php create mode 100644 ext/w32api/php_w32api.h create mode 100644 ext/w32api/test_dll/dll_test.h create mode 100644 ext/w32api/test_dll/test.php create mode 100644 ext/w32api/test_dll/test_dll.c create mode 100644 ext/w32api/test_dll/test_dll.def create mode 100644 ext/w32api/test_dll/test_dll.dsp create mode 100644 ext/w32api/test_dll/test_dll.dsw create mode 100644 ext/w32api/w32api.c create mode 100644 ext/w32api/w32api.dsp diff --git a/ext/w32api/CREDITS b/ext/w32api/CREDITS new file mode 100644 index 0000000000..e046aad54c --- /dev/null +++ b/ext/w32api/CREDITS @@ -0,0 +1,2 @@ +W32API +James Moore diff --git a/ext/w32api/EXPERIMENTAL b/ext/w32api/EXPERIMENTAL new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ext/w32api/README b/ext/w32api/README new file mode 100644 index 0000000000..0e77cfe750 --- /dev/null +++ b/ext/w32api/README @@ -0,0 +1,49 @@ +Win 32 API Extension +==================== +/* $Revision$ */ + +This extension is a generic extension api to dll's. This was originally written to allow access to the Win32 API from PHP. Although you can also access other functions exported via other DLL's. + +An example of getting the amount of time the system has been running and displaying it in a message box: + +========================== Example.php ===================================== + +============================================================================ + +Currently supported types are generic PHP types (strings, bools, doubles, longs and null's) others will be added as and when I can figure out the best way of converting between types. + +Thanks to Ton Plooy for the base code for the generic calling function. + +- James Moore diff --git a/ext/w32api/TODO b/ext/w32api/TODO new file mode 100644 index 0000000000..76b2562d9b --- /dev/null +++ b/ext/w32api/TODO @@ -0,0 +1,5 @@ + TODO + ==== + - ByVal and ByRef Passing. + - Better type checking. + - Fix Mem leaks. diff --git a/ext/w32api/examples/uptime.php b/ext/w32api/examples/uptime.php new file mode 100644 index 0000000000..24ef0e5422 --- /dev/null +++ b/ext/w32api/examples/uptime.php @@ -0,0 +1,64 @@ + | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +/** + * A little example that registers MessageBoxA and GetTickCount then using + * these two API functions tells you how long you computer has been + * running + */ + /** + * Define constants needed + * Taken from Visual Studio/Tools/Winapi/WIN32API.txt + */ + + define("MB_OK", 0); + + + dl("php_w32api.dll"); + + w32api_register_function("kernel32.dll", + "GetTickCount", + "long"); + + w32api_register_function("User32.dll", + "MessageBoxA", + "long"); + + $ticks = GetTickCount(); + + $secs = floor($ticks / 1000); + $mins = floor($secs / 60); + $hours = floor($mins / 60); + + $str = sprintf("You have been using your computer for:". + "\r\n %d Milliseconds, or \r\n %d Seconds". + "or \r\n %d mins or\r\n %d hours %d mins.", + $ticks, + $secs, + $mins, + $hours, + $mins - ($hours*60)); + + MessageBoxA(NULL, + $str, + "Uptime Information", + MB_OK); +?> diff --git a/ext/w32api/php_w32api.h b/ext/w32api/php_w32api.h new file mode 100644 index 0000000000..3eb7de4177 --- /dev/null +++ b/ext/w32api/php_w32api.h @@ -0,0 +1,137 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + + /* $Id$ */ + +#if HAVE_W32API + +#ifndef PHP_W32API_H +#define PHP_W32API_H + +extern zend_module_entry w32api_module_entry; +#define phpext_w32api_ptr &w32api_module_entry + +#ifdef PHP_WIN32 +#define PHP_W32API_API __declspec(dllexport) +#else +#define PHP_W32API_API +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + +ZEND_BEGIN_MODULE_GLOBALS(w32api) + HashTable *regfuncs; // HashTable of Registered function handles + HashTable *libraries; // HashTable holding pointers to the libariers + HashTable *types; // Handles for users' types + int le_dynaparm; // Resource handle + DWORD call_type; // Type of call we use when calling a DLL. +ZEND_END_MODULE_GLOBALS(w32api) + +#ifdef ZTS +#define W32_G(v) TSRMG(w32api_globals_id, zend_w32api_globals *, v) +#else +#define W32_G(v) (w32api_globals.v) +#endif + +#define W32_REG_CONST(cname) REGISTER_LONG_CONSTANT(#cname, cname, CONST_CS | CONST_PERSISTENT); + +#define DC_MICROSOFT 0x0000 // Default +#define DC_BORLAND 0x0001 // Borland compat +#define DC_CALL_CDECL 0x0010 // __cdecl +#define DC_CALL_STD 0x0020 // __stdcall +#define DC_RETVAL_MATH4 0x0100 // Return value in ST +#define DC_RETVAL_MATH8 0x0200 // Return value in ST + +#define DC_CALL_STD_BO (DC_CALL_STD | DC_BORLAND) +#define DC_CALL_STD_MS (DC_CALL_STD | DC_MICROSOFT) +#define DC_CALL_STD_M8 (DC_CALL_STD | DC_RETVAL_MATH8) + +#define DC_FLAG_ARGPTR 0x00000002 + +typedef struct W32APIFE { + FARPROC fp; // Pointer to the function + char *rettype; // return value type + int retvaltype; // if complex = 1 if simple = 0 +} W32APIFE; + +typedef struct _field { + char *fname; // Fields name + char *type; // Type of field + int fsize; // size of field +} field; + +typedef struct runtime_struct { + char *name; // structs name + long size; // structs size + void *fields; // pointer to an array of fields +} runtime_struct; + +#pragma pack(1) // Set struct packing to one byte + +typedef union RESULT { // Various result types + int Int; // Generic four-byte type + long Long; // Four-byte long + void *Pointer; // 32-bit pointer + float Float; // Four byte real + double Double; // 8-byte real + __int64 int64; // big int (64-bit) +} RESULT; + + +typedef struct DYNAPARM { + DWORD dwFlags; // Parameter flags + int nWidth; // Byte width + union { // + DWORD dwArg; // 4-byte argument + void *pArg; // Pointer to argument + }; +} DYNAPARM; + + +PHP_W32API_API RESULT php_w32api_dynamic_dll_call( + int Flags, + DWORD lpFunction, + int nArgs, + DYNAPARM Param[], + LPVOID pRet, + int nRetSize + ); + +static void php_w32api_init_globals(zend_w32api_globals *w32api_globals); +static void php_w32api_dtor_libary(void *data); +static void php_w32api_unload_libraries(); + +PHP_MINFO_FUNCTION(w32api); +PHP_MINIT_FUNCTION(w32api); +PHP_MSHUTDOWN_FUNCTION(w32api); + +PHP_FUNCTION(w32api_register_function); +PHP_FUNCTION(w32api_invoke_function); +PHP_FUNCTION(w32api_deftype); +PHP_FUNCTION(w32api_init_dtype); +PHP_FUNCTION(w32api_set_call_method); + +static void register_constants(int module_number); +static void w32api_free_dynaparm(zend_rsrc_list_entry *rsrc TSRMLS_DC); +void get_arg_pointer(zval **value, void ** argument); +DYNAPARM w32api_convert_zval_to_dynparam(zval ** carg TSRMLS_DC); + +#endif /* PHP_W32API_H */ +#endif /* HAVE_W32API */ \ No newline at end of file diff --git a/ext/w32api/test_dll/dll_test.h b/ext/w32api/test_dll/dll_test.h new file mode 100644 index 0000000000..e443c1784a --- /dev/null +++ b/ext/w32api/test_dll/dll_test.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ +*/ + +#ifndef _TEST_DLL_H +#define _TEST_DLL_H + +#define TEST_DLL_API __declspec(dllexport) + +typedef struct _name { + char *fname; + char *lname; +} name; + +TEST_DLL_API void print_names(name *n); + +#endif _TEST_DLL_H \ No newline at end of file diff --git a/ext/w32api/test_dll/test.php b/ext/w32api/test_dll/test.php new file mode 100644 index 0000000000..9f85acaf03 --- /dev/null +++ b/ext/w32api/test_dll/test.php @@ -0,0 +1,10 @@ + diff --git a/ext/w32api/test_dll/test_dll.c b/ext/w32api/test_dll/test_dll.c new file mode 100644 index 0000000000..39b29c416e --- /dev/null +++ b/ext/w32api/test_dll/test_dll.c @@ -0,0 +1,33 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include +#include "dll_test.h" + +/** + * Test DLL for w32api functions. Functions below are used to test + * Various parts of the extension. + */ + +/* Test for complex type passing */ +TEST_DLL_API void print_names(name *n) +{ + printf("%s %s", n->fname, n->lname); +} \ No newline at end of file diff --git a/ext/w32api/test_dll/test_dll.def b/ext/w32api/test_dll/test_dll.def new file mode 100644 index 0000000000..7ffba76950 --- /dev/null +++ b/ext/w32api/test_dll/test_dll.def @@ -0,0 +1,2 @@ +EXPORTS + print_name \ No newline at end of file diff --git a/ext/w32api/test_dll/test_dll.dsp b/ext/w32api/test_dll/test_dll.dsp new file mode 100644 index 0000000000..945dc7efc1 --- /dev/null +++ b/ext/w32api/test_dll/test_dll.dsp @@ -0,0 +1,110 @@ +# Microsoft Developer Studio Project File - Name="test_dll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=test_dll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "test_dll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "test_dll.mak" CFG="test_dll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "test_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "test_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "test_dll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_DLL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_DLL_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "test_dll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_DLL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_DLL_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "test_dll - Win32 Release" +# Name "test_dll - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\test_dll.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\dll_test.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/ext/w32api/test_dll/test_dll.dsw b/ext/w32api/test_dll/test_dll.dsw new file mode 100644 index 0000000000..e22c7b49ee --- /dev/null +++ b/ext/w32api/test_dll/test_dll.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "test_dll"=.\test_dll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ext/w32api/w32api.c b/ext/w32api/w32api.c new file mode 100644 index 0000000000..068ae3193f --- /dev/null +++ b/ext/w32api/w32api.c @@ -0,0 +1,898 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_W32API +#include +#include +#define WIN32_LEAN_AND_MEAN +#include + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "php_w32api.h" + +/* {{{ w32api_functions[] + */ +function_entry w32api_functions[] = { + PHP_FE(w32api_register_function, NULL) + PHP_FE(w32api_deftype, NULL) + PHP_FE(w32api_init_dtype, NULL) + PHP_FE(w32api_set_call_method, NULL) + {NULL, NULL, NULL} +}; +/* }}} */ + +/* {{{ w32api_module_entry + */ +zend_module_entry w32api_module_entry = { + STANDARD_MODULE_HEADER, + "w32api", + w32api_functions, + PHP_MINIT(w32api), + PHP_MSHUTDOWN(w32api), + NULL, + NULL, + PHP_MINFO(w32api), + "0.1", /* Replace with version number for your extension */ + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +ZEND_DECLARE_MODULE_GLOBALS(w32api) + +#ifdef COMPILE_DL_W32API +ZEND_GET_MODULE(w32api) +#endif + +/* {{{ 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_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(w32api) +{ + ZEND_INIT_MODULE_GLOBALS(w32api, php_w32api_init_globals, NULL); + register_constants(module_number); + + W32_G(le_dynaparm) = zend_register_list_destructors_ex(w32api_free_dynaparm, NULL, "dynaparm", module_number); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(w32api) +{ + if(W32_G(regfuncs)) + { + FREE_HASHTABLE(W32_G(regfuncs)); + } + + if(W32_G(libraries)) + { + php_w32api_unload_libraries(); + FREE_HASHTABLE(W32_G(libraries)); + } + + if(W32_G(libraries)) + { + FREE_HASHTABLE(W32_G(types)); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ DYNAPARM dtor */ +static void w32api_free_dynaparm(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + DYNAPARM *dparam; + + dparam = (DYNAPARM *)rsrc->ptr; + + if(dparam->pArg) + efree(dparam->pArg); + + efree(dparam); +} +/* }}} */ + +/* {{{ */ +static void php_w32api_unload_libraries() +{ + TSRMLS_FETCH(); + zend_hash_destroy(W32_G(libraries)); +} +/* }}} */ + +/* {{{ */ +static void php_w32api_dtor_library(void *data) +{ + FreeLibrary((HINSTANCE)data); +} +/* }}} */ + +/* {{{ */ +static void php_w32api_init_globals(zend_w32api_globals *w32api_globals) +{ + TSRMLS_FETCH(); + + w32api_globals->regfuncs = NULL; + w32api_globals->libraries = NULL; + w32api_globals->types = NULL; + w32api_globals->call_type = DC_CALL_STD; + + ALLOC_HASHTABLE(W32_G(regfuncs)); + zend_hash_init(W32_G(regfuncs), 1, NULL, NULL, 1); + + ALLOC_HASHTABLE(W32_G(libraries)); + zend_hash_init(W32_G(libraries), 1, NULL, php_w32api_dtor_library, 1); + + ALLOC_HASHTABLE(W32_G(types)); + zend_hash_init(W32_G(types), 5, NULL, NULL, 1); + +} +/* }}} */ + +/* {{{ */ +static void register_constants(int module_number) +{ + TSRMLS_FETCH(); + + W32_REG_CONST(DC_MICROSOFT) + W32_REG_CONST(DC_BORLAND) + W32_REG_CONST(DC_CALL_CDECL) + W32_REG_CONST(DC_CALL_STD) + W32_REG_CONST(DC_RETVAL_MATH4) + W32_REG_CONST(DC_RETVAL_MATH8) + W32_REG_CONST(DC_CALL_STD_BO) + W32_REG_CONST(DC_CALL_STD_MS) + W32_REG_CONST(DC_CALL_STD_M8) + W32_REG_CONST(DC_FLAG_ARGPTR) + +} +/* }}} */ + +/* {{{ proto void w32api_set_call_method(int method) + Sets the calling method used */ +PHP_FUNCTION(w32api_set_call_method) +{ + zval **method; + + if(zend_get_parameters_ex(1, &method) == FAILURE) + { + WRONG_PARAM_COUNT + } + + switch((*method)->value.lval) + { + case DC_CALL_CDECL: + W32_G(call_type) = DC_CALL_CDECL; + break; + default: + W32_G(call_type) = DC_CALL_STD; + break; + } + + RETURN_TRUE + +} +/* }}} */ + +/* {{{ proto bool w32api_register_function(string libary, string function_name) + Registers function function_name from library with PHP */ +PHP_FUNCTION(w32api_register_function) +{ + HINSTANCE hinstLib; + FARPROC ProcAdd; + W32APIFE *fe; + BOOL fRunTimeLinkSuccess = FALSE; + zval **libname, **funcname, **retval_type; + void *tmp; + runtime_struct *rst; + + if(zend_get_parameters_ex(3, &libname, &funcname, &retval_type) == FAILURE) + { + WRONG_PARAM_COUNT + } + + convert_to_string_ex(libname); + convert_to_string_ex(funcname); + convert_to_string_ex(retval_type); + + fe = (W32APIFE *)emalloc(sizeof(W32APIFE)); + fe->retvaltype = 0; + //TODO: Check library isnt alreay loaded + + hinstLib = LoadLibrary((*libname)->value.str.val); + + if(hinstLib == NULL) + { + php_error(E_WARNING, "Could not load dynamic link library %s", (*libname)->value.str.val); + RETURN_FALSE + } + + zend_hash_add(W32_G(libraries), + (*libname)->value.str.val, + strlen((*libname)->value.str.val), + &hinstLib, + sizeof(HINSTANCE), + NULL); + + //TODO: Check function handle isnt already loaded + + ProcAdd = (FARPROC) GetProcAddress(hinstLib, (*funcname)->value.str.val); + + if(ProcAdd == NULL) + { + php_error(E_WARNING, "Could not get handle for function %s", (*funcname)->value.str.val); + RETURN_FALSE + } + + fe->fp = ProcAdd; + + if(!strcmp((*retval_type)->value.str.val, "long")) + { + fe->rettype = malloc(5*sizeof(char)); + fe->rettype = strdup("long\0"); + } + else if (!strcmp((*retval_type)->value.str.val, "int")) + { + fe->rettype = malloc(4*sizeof(char)); + fe->rettype = strdup("long\0"); + } + else if (!strcmp((*retval_type)->value.str.val, "string")) + { + fe->rettype = malloc(7*sizeof(char)); + fe->rettype = strdup("string\0"); + } + else if (!strcmp((*retval_type)->value.str.val, "byte")) + { + fe->rettype = malloc(5*sizeof(char)); + fe->rettype = strdup("byte\0"); + } + else if (!strcmp((*retval_type)->value.str.val, "double")) + { + fe->rettype = malloc(7*sizeof(char)); + fe->rettype = strdup("double\0"); + } + else if (!strcmp((*retval_type)->value.str.val, "bool")) + { + fe->rettype = malloc(5*sizeof(char)); + fe->rettype = strdup("bool\0"); + } + else + { + /** + * this could be a userdef'd type so lets + * search the ht for that. + */ + if(zend_hash_find(W32_G(types), (*retval_type)->value.str.val, (*retval_type)->value.str.len, (void **) &tmp) == FAILURE) + { + php_error(E_WARNING, "Unknown type %s", (*retval_type)->value.str.val); + RETURN_FALSE; + } + rst = tmp; + fe->rettype = malloc(sizeof(char) * strlen(rst->name) + 1); + memcpy(fe->rettype, rst->name, strlen(rst->name) + 1); + fe->retvaltype = 1; + } + + if(zend_hash_add(W32_G(regfuncs), php_strtolower((*funcname)->value.str.val, (*funcname)->value.str.len), (*funcname)->value.str.len, fe, sizeof(W32APIFE), NULL) == FAILURE) + { + php_error(E_WARNING, "Could not register function %s into hash"); + RETURN_FALSE; + } + + /** + * We now need to add the function into the global namespace, the best way to do this is + * to register it as a new module then it will definatly be removed on shutdown + */ + { + zend_module_entry *temp_module_entry; + char *fname; + function_entry *tmp_functions; + + tmp_functions = malloc(sizeof(function_entry) * 2); + fname = malloc((*funcname)->value.str.len + 1); + memcpy(fname, (*funcname)->value.str.val, (*funcname)->value.str.len + 1); + + tmp_functions[0].fname = php_strtolower(fname, (*funcname)->value.str.len); + tmp_functions[0].handler = zif_w32api_invoke_function; + tmp_functions[0].func_arg_types = NULL; + tmp_functions[1].fname = NULL; + tmp_functions[1].handler = NULL; + tmp_functions[1].func_arg_types = NULL; + + + temp_module_entry = malloc(sizeof(zend_module_entry)); + temp_module_entry->size = sizeof(zend_module_entry); + temp_module_entry->zend_api = ZEND_MODULE_API_NO; + temp_module_entry->zend_debug = ZEND_DEBUG; + temp_module_entry->zts = USING_ZTS; + temp_module_entry->name = fname; + temp_module_entry->functions = tmp_functions; + temp_module_entry->module_startup_func = temp_module_entry->module_shutdown_func = + temp_module_entry->request_startup_func = temp_module_entry->request_shutdown_func = NULL; + temp_module_entry->info_func = NULL; + temp_module_entry->version = NULL; + temp_module_entry->global_startup_func = temp_module_entry->global_shutdown_func = NULL; + temp_module_entry->globals_id = 0; + temp_module_entry->module_started = 0; + temp_module_entry->type = 0; + temp_module_entry->handle = NULL; + temp_module_entry->module_number = 0; + + if(zend_register_module(temp_module_entry) != SUCCESS) + { + php_error(E_WARNING, "could not register function %s into the function table", (*funcname)->value.str.val); + RETURN_FALSE + } + + + } + + + + RETURN_TRUE +}; +/* }}} */ + +/* {{{ proto mixed w32api_invoke_function(string funcname, ....) + Invokes function funcname with the arguments passed after the function name */ +PHP_FUNCTION(w32api_invoke_function) +{ + zval ***args = (zval ***)NULL; + void *tmp; + W32APIFE *fe; + char *funcname; + int argc = ZEND_NUM_ARGS(); + runtime_struct *rst; + RESULT retval; + DYNAPARM *Param, *drval; + LPVOID pVParam; + int VParamsz; + int i; + + args = emalloc(argc * sizeof(zval **)); + Param = (DYNAPARM *)emalloc((argc) * sizeof(DYNAPARM)); + + if(zend_get_parameters_array_ex(argc, args) == FAILURE) + { + WRONG_PARAM_COUNT + } + + funcname = get_active_function_name(TSRMLS_C); + + if(zend_hash_find(W32_G(regfuncs), funcname, strlen(funcname), (void **) &tmp) == FAILURE) + { + php_error(E_WARNING, "Could not find function handle for function %s", funcname); + RETURN_FALSE; + } + + fe = (W32APIFE *)tmp; + + // Build the DYNPARAM array. + for(i = 0; i < (argc); i++) + { + Param[i] = w32api_convert_zval_to_dynparam(args[(i)] TSRMLS_CC); + } + + + /** + * We need to check the return type, if its a complex return type then we need to sort out pVParam and + * VParamsz and pass them as the last two parameters of the call to the invoke of the function. + */ + if(fe->retvaltype) // Complex return type + { + tmp = NULL; + if(zend_hash_find(W32_G(types), fe->rettype, strlen(fe->rettype), (void **) &tmp) == FAILURE) + { + php_error(E_WARNING, "Unknown type %s", fe->rettype); + RETURN_FALSE; + } + rst = tmp; + VParamsz = rst->size; + pVParam = malloc(rst->size); + } + else + { + pVParam = NULL; + VParamsz = 0; + } + + retval = php_w32api_dynamic_dll_call(W32_G(call_type), (ulong)(fe->fp), (argc), Param, pVParam, VParamsz); + + if(!strcmp(fe->rettype, "long")) + { + RETURN_LONG(retval.Long); + } + else if (!strcmp(fe->rettype, "int")) + { + RETURN_LONG(retval.Int); + } + else if (!strcmp(fe->rettype, "string")) + { + RETURN_STRING(retval.Pointer, 1); + } + else if (!strcmp(fe->rettype, "byte")) + { + php_error(E_WARNING, "byte return values are not supported right now"); + RETURN_FALSE; + } + else if (!strcmp(fe->rettype, "double")) + { + RETURN_DOUBLE(retval.Double); + } + else if (!strcmp(fe->rettype, "bool")) + { + if(retval.Int) + { + RETURN_TRUE; + } + else + { + RETURN_FALSE; + } + } + else + { + /** + * This is returned in pRet, we need to get type and build a DYNAPARM for + * the return value and return the RESOURCE. + */ + + drval = malloc(sizeof(DYNAPARM)); + drval->pArg = pVParam; + drval->nWidth = VParamsz; + drval->dwFlags = 0; + ZEND_REGISTER_RESOURCE(return_value, drval, W32_G(le_dynaparm)); + } + +} +/* }}} */ + +/* {{{ Dynamic calling of dll functions by pushing onto the stack manually. */ +PHP_W32API_API RESULT php_w32api_dynamic_dll_call( int Flags, DWORD lpFunction, + int nArgs, DYNAPARM Param[], + LPVOID pRet, int nRetSize) +{ + /** + * Here we dont know the function we are calling or the arguments + * it expects so we must do quite a lot of work, normally done by + * the compiler ourselves, this is far easier to do it Assembly than + * in C.. here goes (jmoore - 05/11/2001). + * + * Based on the code by Ton Plooy + * See Also MSFT KB Article ID: Q171729 for more background. + * + * We will support two calling mechanisms, __stdcall and __cdecl(WINAPIV). + */ + RESULT Res = { 0 }; + int i, nInd, nSize; + DWORD dwEAX, dwEDX, dwVal, *pStack, dwStSize = 0; + BYTE *pArg; + + _asm { + mov pStack, esp + sub esp, 0x100 + } + + for (i = nArgs; i > 0; i--) { + nInd = i - 1; + nSize = (Param[nInd].nWidth + 3) / 4 * 4; + pArg = (BYTE *)Param[nInd].pArg + nSize - 4; + dwStSize += (DWORD)nSize; + while (nSize > 0) { + if (Param[nInd].dwFlags & DC_FLAG_ARGPTR) { + dwVal = *(DWORD *)pArg; + pArg -= 4; + } + else { + + dwVal = Param[nInd].dwArg; + } + + pStack--; + *pStack = dwVal; + nSize -= 4; + } + } + + if((pRet != NULL) && ((Flags & DC_BORLAND) || (nRetSize > 8))) + { + dwStSize += 4; + pStack--; + *pStack = (DWORD)pRet; + } + + _asm { + add esp, 0x100 + sub esp, dwStSize + call [lpFunction] + mov dwEAX, eax + mov dwEDX, edx + } + + if (Flags & DC_CALL_CDECL) { + _asm add esp, dwStSize + } + + if (Flags & DC_RETVAL_MATH4) { + _asm fstp dword ptr [Res] + } + else if (Flags & DC_RETVAL_MATH8) { + _asm fstp qword ptr [Res] + } + else if (pRet == NULL) { + _asm{ + mov eax, [dwEAX] + mov DWORD PTR [Res], eax + mov edx, [dwEDX] + mov DWORD PTR [Res + 4], edx + } + } + else if (((Flags & DC_BORLAND) == 0) && (nRetSize <= 8)) { + // Microsoft optimized less than 8-bytes structure passing + _asm { + mov ecx, DWORD PTR [pRet] + mov eax, [dwEAX] + mov DWORD PTR [ecx], eax + mov edx, [dwEDX] + mov DWORD PTR [ecx + 4], edx + } + } + return Res; +} +/* }}} */ + +/* {{{ Conversion function for zvals to dynparams */ +DYNAPARM w32api_convert_zval_to_dynparam(zval ** carg TSRMLS_DC) +{ + DYNAPARM dparam, *tparam; + dparam.dwFlags = 0; + + switch((*carg)->type) + { + case IS_RESOURCE: + tparam = (DYNAPARM *) zend_fetch_resource(carg TSRMLS_CC, -1, "dynaparm", NULL, 1, W32_G(le_dynaparm)); + if(!tparam) + { + php_error(E_ERROR, "Error when fetching argument"); + } + dparam = *tparam; + break; + case IS_LONG: + dparam.nWidth = sizeof(long); + dparam.dwArg = (*carg)->value.lval; + break; + case IS_DOUBLE: + dparam.nWidth = sizeof(float); + dparam.pArg = &(*carg)->value.dval; + dparam.dwFlags = DC_FLAG_ARGPTR; + break; + case IS_STRING: + dparam.nWidth = sizeof(char *); + dparam.pArg = (*carg)->value.str.val; + break; + case IS_BOOL: + dparam.nWidth = sizeof(BOOL); + dparam.dwArg = ((*carg)->value.lval == 0)?FALSE:TRUE; + break; + case IS_NULL: + dparam.nWidth = sizeof(void *); + dparam.pArg = NULL; + break; + default: + php_error(E_ERROR, "Cant convert variable to type dynparam"); + } + + return dparam; +} +/* }}} */ + +/** + * Typedef functions, We need to be flexible about what types we are going + * to pass and retrive from functions in the win32 api. this means we need + * to be able to create structs of any different type at runtime. We can do + * this in asm. For example: + * + * typedef struct james { + * char firstname[81]; + * char lastname[81]; + * } + * + * An instance of the above struct (lets call this instance iJames. iJames + * is a pointer to the first letter of firstname (the base address), firstname + * then fills the following 81 bytes (some of these may be empty), lastname is + * at the offset iJames+81, + * + * |- 81 Bytes -|- 81 Bytes -| + * +------//------+------//------+ + * | James\0 | Moore\0 | + * +------//------+------//------+ + * ^ ^ + * iJames iJames[81] + * + * We could store a value in ax in this field by + * the assembly command: + * + * move ac iJames[81] + * + * Unions are easy in asm as the length of memory they use is equal to the size + * of their largest member. For example: + * + * typedef union foo { + * int i; + * char j; + * } + * + * The length of an int might be 4 bytes, the length of a char might be 1 byte. + * So if we create an instance of foo called bar then it would have the following + * layout in memory: + * + * +---+------------+ + * | ¦ | + * +---+------------+ + * ^^^^^ + * Memory area for char + * ^^^^^^^^^^^^^^^^^^ + * Memory area for int + * + * Therefore even if there was only a char held in this section and the union was within + * a struct the next offset would still be base address + 4 not +1 so we need to deal + * with this too. + * + * When defining types the user can call the w32api_deftype() function, this takes 2n+1 args where + * n is the number of members the type has. The first argument is the name of the struct struct + * after that is the type of the member followed by the members name (in pairs). + * + * + * James Moore 6/11/2001 + * + */ + +/* {{{ proto int w32api_deftype(string typename, string member1_type, string member1_name, ...) + Defines a type for use with other w32api_functions. */ +PHP_FUNCTION(w32api_deftype) +{ + zval ***args; + int argc = ZEND_NUM_ARGS(); + int i; + runtime_struct *rst, *orst; + void *tmp; + field *fields, *ptr; + + args = (zval ***)emalloc(sizeof(zval **) * argc); + rst = malloc(sizeof(runtime_struct)); + + ptr = (field *)emalloc(sizeof(field) *((argc-1)/2)); + + fields = ptr; + + if((zend_get_parameters_array_ex(argc, args) == FAILURE) || ((argc % 2) != 1)) + { + WRONG_PARAM_COUNT + } + + for(i=2; iname = (*args[0])->value.str.val; + rst->size = 0; + + /** + * We now take each parameter pair and fill out the field struct + * for each parameter pair. + */ + for(i=1; itype = malloc((*args[i])->value.str.len + 1); + memcpy(ptr->type, (*args[i])->value.str.val, (*args[i])->value.str.len + 1); + + ptr->fname = malloc((*args[i+1])->value.str.len + 1); + memcpy(ptr->fname, (*args[i+1])->value.str.val, (*args[i+1])->value.str.len + 1); + + ptr->fsize = 0; + + if(!strcmp(ptr->type, "long")) + { + ptr->fsize = sizeof(long); + } + else if (!strcmp(ptr->type, "int")) + { + ptr->fsize = sizeof(int); + } + else if (!strcmp(ptr->type, "string")) + { + ptr->fsize = sizeof(char *); + } + else if (!strcmp(ptr->type, "byte")) + { + ptr->fsize = 1; + } + else if (!strcmp(ptr->type, "double")) + { + ptr->fsize = sizeof(double); + } + else if (!strcmp(ptr->type, "bool")) + { + ptr->fsize = sizeof(BOOL); + } + else + { + /** + * this could be a userdef'd type so lets + * search the ht for that. + */ + if(zend_hash_find(W32_G(types), ptr->type, strlen(ptr->type), (void **) &tmp) == FAILURE) + { + php_error(E_WARNING, "Unknown type %s", ptr->type); + RETURN_FALSE; + } + orst = tmp; + ptr->fsize = orst->size; + } + + rst->size += ptr->fsize; + ptr++; + } + + rst->fields = fields; + + if(zend_hash_add(W32_G(types), rst->name, strlen(rst->name), rst, sizeof(runtime_struct), NULL) == FAILURE) + { + php_error(E_WARNING, "Error registering type %s", rst->name); + RETURN_FALSE; + } + + RETURN_TRUE; + +} +/* }}} */ + +/* {{{ proto resource w32api_init_dtype(string typename, mixed val1, mixed val2); + Creates an instance to the data type typename and fills it with the values val1, val2, the function + then returns a DYNAPARM which can be passed when invoking a function as a parameter.*/ +PHP_FUNCTION(w32api_init_dtype) +{ + DYNAPARM *dparam, *tparam; + void *rtstruct, *tmp; + runtime_struct *rst; + field *ptr; + char *m; + zval ***args; + zval **curarg; + int i, j,argc = ZEND_NUM_ARGS(); + + args = emalloc(sizeof(zval **) * argc); + dparam = emalloc(sizeof(DYNAPARM)); + + if(zend_get_parameters_array_ex(argc, args) != SUCCESS) + { + WRONG_PARAM_COUNT + } + + convert_to_string_ex(args[0]); + + if(zend_hash_find(W32_G(types), (*args[0])->value.str.val, (*args[0])->value.str.len, (void **)&tmp) == FAILURE) + { + php_error(E_WARNING, "Unknown type %s",(*args[0])->value.str.val); + RETURN_FALSE + } + + rst = (runtime_struct *)tmp; + + rtstruct = emalloc(rst->size); + rtstruct = memset(rtstruct, 0, rst->size); + tmp = rtstruct; + curarg = args[1]; + ptr = rst->fields; + + i = 0; + j = (argc-1); + + while(itype, "long")) + { + convert_to_long_ex(curarg); + memcpy(tmp, &(*curarg)->value.lval, ptr->fsize); + } + else if (!strcmp(ptr->type, "int")) + { + convert_to_long_ex(curarg); + memcpy(tmp, &(*curarg)->value.lval, ptr->fsize); + } + else if (!strcmp(ptr->type, "string")) + { + convert_to_string_ex(curarg); + m = emalloc(sizeof(char) * (*curarg)->value.str.len + 1); + memcpy(m, (*curarg)->value.str.val, (*curarg)->value.str.len + 1); + memcpy(tmp, &m, ptr->fsize); + } + else if (!strcmp(ptr->type, "byte")) + { + /* use Lower order bytes */ + convert_to_long_ex(curarg); + memcpy(tmp, &(*curarg)->value.lval, ptr->fsize); + } + else if (!strcmp(ptr->type, "double")) + { + convert_to_double_ex(curarg); + memcpy(tmp, &(*curarg)->value.dval, ptr->fsize); + } + else if (!strcmp(ptr->type, "bool")) + { + convert_to_boolean_ex(curarg); + memcpy(tmp, &(*curarg)->value.lval, ptr->fsize); + } + else + { + /** + * OK we have a user type here, we need to treat the param + * as a resource and fetch the DYNAPARM its contained in + * then copy the contents of its LPVOID pointer into our + * memory space. + */ + ZEND_FETCH_RESOURCE(tparam, DYNAPARM *, curarg, -1, "dynaparm", W32_G(le_dynaparm)); + memcpy(tmp, tparam->pArg, ptr->fsize); + } + + /** + * We need somthing that is 1 byte + */ + (char)tmp += ptr->fsize; + (void *)tmp; + + curarg++; + ptr++; + i++; + } + + dparam->dwFlags = 0; + dparam->nWidth = rst->size; + dparam->pArg = rtstruct; + + ZEND_REGISTER_RESOURCE(return_value, dparam, W32_G(le_dynaparm)); + +} +/* }}} */ + + +#endif /* HAVE_W32API */ \ No newline at end of file diff --git a/ext/w32api/w32api.dsp b/ext/w32api/w32api.dsp new file mode 100644 index 0000000000..8910cfb929 --- /dev/null +++ b/ext/w32api/w32api.dsp @@ -0,0 +1,114 @@ +# Microsoft Developer Studio Project File - Name="w32api" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=w32api - Win32 Release_TS +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "w32api.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "w32api.mak" CFG="w32api - Win32 Release_TS" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "w32api - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "w32api - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "w32api - Win32 Release_TS" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_TS" +# PROP BASE Intermediate_Dir "Release_TS" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_TS" +# PROP Intermediate_Dir "Release_TS" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_W32API" /D ZTS=1 /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /ZI /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D ZEND_DEBUG=0 /D HAVE_W32API=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "W32API_EXPORTS" /D "COMPILE_DL_W32API" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x406 /d "NDEBUG" +# ADD RSC /l 0x406 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_w32api.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" + +!ELSEIF "$(CFG)" == "w32api - Win32 Debug_TS" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Debug_TS" +# PROP BASE Intermediate_Dir "Debug_TS" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Debug_TS" +# PROP Intermediate_Dir "Debug_TS" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_W32API" /D ZTS=1 /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "_DEBUG" /D "_LIB" /D "__WIN32__" /D "USE_TLS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=1 /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "W32API_EXPORTS" /D "COMPILE_DL_W32API" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_W32API=1 /FAcs /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# SUBTRACT MTL /Oicf +# ADD BASE RSC /l 0x406 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/php_w32api.dll" /libpath:"..\..\Debug_TS" + +!ENDIF + +# Begin Target + +# Name "w32api - Win32 Release_TS" +# Name "w32api - Win32 Debug_TS" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\w32api.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\php_w32api.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project -- 2.40.0