]> granicus.if.org Git - php/commitdiff
@ - Add generic Win 32 API extension (jmoore)
authorJames Moore <jmoore@php.net>
Wed, 7 Nov 2001 14:31:03 +0000 (14:31 +0000)
committerJames Moore <jmoore@php.net>
Wed, 7 Nov 2001 14:31:03 +0000 (14:31 +0000)
14 files changed:
ext/w32api/CREDITS [new file with mode: 0644]
ext/w32api/EXPERIMENTAL [new file with mode: 0644]
ext/w32api/README [new file with mode: 0644]
ext/w32api/TODO [new file with mode: 0644]
ext/w32api/examples/uptime.php [new file with mode: 0644]
ext/w32api/php_w32api.h [new file with mode: 0644]
ext/w32api/test_dll/dll_test.h [new file with mode: 0644]
ext/w32api/test_dll/test.php [new file with mode: 0644]
ext/w32api/test_dll/test_dll.c [new file with mode: 0644]
ext/w32api/test_dll/test_dll.def [new file with mode: 0644]
ext/w32api/test_dll/test_dll.dsp [new file with mode: 0644]
ext/w32api/test_dll/test_dll.dsw [new file with mode: 0644]
ext/w32api/w32api.c [new file with mode: 0644]
ext/w32api/w32api.dsp [new file with mode: 0644]

diff --git a/ext/w32api/CREDITS b/ext/w32api/CREDITS
new file mode 100644 (file)
index 0000000..e046aad
--- /dev/null
@@ -0,0 +1,2 @@
+W32API
+James Moore <jmoore@php.net>
diff --git a/ext/w32api/EXPERIMENTAL b/ext/w32api/EXPERIMENTAL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ext/w32api/README b/ext/w32api/README
new file mode 100644 (file)
index 0000000..0e77cfe
--- /dev/null
@@ -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 =====================================
+<?php
+
+        dl("php_w32api.dll");
+        
+        w32api_register_function("kernel32.dll", 
+                                 "GetTickCount",
+                                 W32_LONG);
+                                 
+        w32api_register_function("User32.dll",
+                                 "MessageBoxA",
+                                 W32_LONG);
+
+        $ticks = w32api_invoke_function("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));
+
+        w32api_invoke_function("MessageBoxA", 
+                                NULL, 
+                                $str, 
+                                "Uptime Information", 
+                                MB_OK);
+?>
+============================================================================
+
+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 <jmoore@php.net>
diff --git a/ext/w32api/TODO b/ext/w32api/TODO
new file mode 100644 (file)
index 0000000..76b2562
--- /dev/null
@@ -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 (file)
index 0000000..24ef0e5
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/*
+   +----------------------------------------------------------------------+
+   | 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$ */
+
+/**
+ * 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 (file)
index 0000000..3eb7de4
--- /dev/null
@@ -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 <jmoore@php.net>                                |
+   +----------------------------------------------------------------------+
+ */
+
+ /* $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 (file)
index 0000000..e443c17
--- /dev/null
@@ -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 <jmoore@php.net>                                       |
+   +----------------------------------------------------------------------+
+*/
+
+#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 (file)
index 0000000..9f85aca
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+
+        dl("php_w32api.dll");
+        
+        w32api_register_function("test_dll.dll", "print_names", "long");
+        w32api_deftype("name", "string", "fname", "string", "lname");
+        $rsrc = w32api_init_dtype("name", "James", "Moore");
+        print_names($rsrc);
+
+?>
diff --git a/ext/w32api/test_dll/test_dll.c b/ext/w32api/test_dll/test_dll.c
new file mode 100644 (file)
index 0000000..39b29c4
--- /dev/null
@@ -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 <jmoore@php.net>                                       |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include <stdio.h>
+#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 (file)
index 0000000..7ffba76
--- /dev/null
@@ -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 (file)
index 0000000..945dc7e
--- /dev/null
@@ -0,0 +1,110 @@
+# Microsoft Developer Studio Project File - Name="test_dll" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=test_dll - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "test_dll.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "test_dll.mak" CFG="test_dll - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "test_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "test_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "test_dll - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+# 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\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_DLL_EXPORTS" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x809 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# 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\r
+# 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\r
+\r
+!ELSEIF  "$(CFG)" == "test_dll - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# 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\r
+# 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\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x809 /d "_DEBUG"\r
+# ADD RSC /l 0x809 /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# 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\r
+# 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\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "test_dll - Win32 Release"\r
+# Name "test_dll - Win32 Debug"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\test_dll.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\dll_test.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r
diff --git a/ext/w32api/test_dll/test_dll.dsw b/ext/w32api/test_dll/test_dll.dsw
new file mode 100644 (file)
index 0000000..e22c7b4
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "test_dll"=.\test_dll.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/ext/w32api/w32api.c b/ext/w32api/w32api.c
new file mode 100644 (file)
index 0000000..068ae31
--- /dev/null
@@ -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 <jmoore@php.net>                                |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_W32API
+#include <stdio.h>
+#include <stdlib.h>
+#define  WIN32_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"
+
+/* {{{ 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 <tonp@xs4all.nl>
+        * 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 <jmoore@php.net> 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; i<argc; i++)
+       {
+               convert_to_string_ex(args[i]);
+       }
+
+       convert_to_string_ex(args[0]);
+
+       rst->name = (*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; i<argc; i += 2)
+       {
+               ptr->type = 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(i<j)
+       {
+               if(!strcmp(ptr->type, "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 (file)
index 0000000..8910cfb
--- /dev/null
@@ -0,0 +1,114 @@
+# Microsoft Developer Studio Project File - Name="w32api" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=w32api - Win32 Release_TS\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "w32api.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "w32api.mak" CFG="w32api - Win32 Release_TS"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "w32api - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "w32api - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "w32api - Win32 Release_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release_TS"\r
+# PROP BASE Intermediate_Dir "Release_TS"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release_TS"\r
+# PROP Intermediate_Dir "Release_TS"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# 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\r
+# 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\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x406 /d "NDEBUG"\r
+# ADD RSC /l 0x406 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# 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\r
+# 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"\r
+\r
+!ELSEIF  "$(CFG)" == "w32api - Win32 Debug_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Debug_TS"\r
+# PROP BASE Intermediate_Dir "Debug_TS"\r
+# PROP BASE Ignore_Export_Lib 0\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Debug_TS"\r
+# PROP Intermediate_Dir "Debug_TS"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# 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\r
+# 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\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# SUBTRACT MTL /Oicf\r
+# ADD BASE RSC /l 0x406 /d "NDEBUG"\r
+# ADD RSC /l 0x809 /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# 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\r
+# 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"\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "w32api - Win32 Release_TS"\r
+# Name "w32api - Win32 Debug_TS"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\w32api.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\php_w32api.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# End Target\r
+# End Project\r