ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> php-dev
php-dev
[PHP-DEV] Extention_Dir
by Hector Santos other posts by this author
May 9 2008 3:05AM messages near this date
#44954 [Opn->Fbk]: file_get_contents crashes Apache | [PHP-DEV] Extension_Dir: Proposal to offer multi-directory DLL loading
I'm relatively new to PHP development. I hope this is the appropriate 
area for this question since I was thinking maybe I could use the 
opportunity to get involved with the internals by making a patch 
regarding how DLLs are loaded.

Specifically, the extension_dir="path" directive which only allows a 
single path for finding dlls.

I'm nearly done with a new Windows-based PHP extension (php_wildcat.dll) 
and one of the issues was DLL dependencies.

The PHP extension offers direct SDK/API support for our application 
server and all our DLLs are in a specific server folder.

The installation of the Extension is preferred to be placed in our 
server folder so ideally,  something like so would be ideal:

    extension_dir="./ext;c:/wildcat"

But of course, this isn't supported and it will not work, in fact, it 
fails the loading of other PHP extensions.

The official method of placing extensions in the PHP "./Ext" requires 
that we alter our long (12 years) recommended policy of a) not copying 
our DLLS to other folders (for auto update/version control reasons) or 
not requiring of adding the server folder in the Windows PATH.

I came up with an somewhat "kludgy" solution but I somewhat feel this 
has to be a common PHP extension issues with extension authors, thus 
maybe I must of a missed something where I don't have to do any of this.

The solution I came up with is to use DELAY LOADING where the extension 
is compiled and linked with delayed loading of implicit dlls.

For example: the extension is compiled/linked using pragma directives 
like so:

#define USE_DELAY_LOADING
...
#ifdef USE_DELAY_LOADING
#  pragma comment(lib, "delayimp.lib")
#  pragma comment(linker, "/delayload:wcsrv2.dll")
#  pragma comment(linker, "/delayload:door32.dll")
#endif

delayimp.lib is part of the VC6.0 C/C++ runtime library and it handles 
the delayed implicit loading of dlls.  The DLLs above are part of our 
RPC server API interface.

Now, our RPC server folder is recorded in the registry so using the dll 
entry point DllMain(),  the registry location is read and this is used 
to add to the process environment path.  So I have this at the end of my 
PHP_WILDCAT.CPP code:

#ifdef USE_DELAY_LOADING

#define GETENV GetEnvironmentVariable
#define SETENV SetEnvironmentVariable

BOOL GetRegistry(const TCHAR *key,
                  const TCHAR *name,
                  DWORD type,
                  void *data,
                  DWORD datasize)
{
   BOOL ok = FALSE;
   HKEY k;
   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
             key, 0, KEY_READ, &k) == ERROR_SUCCESS) {
     DWORD t;
     if (RegQueryValueEx(k, (TCHAR *)name,  NULL,
             &t, (BYTE *)data, &datasize) == ERROR_SUCCESS) {
       ok = t == type;
     }
     RegCloseKey(k);
   }
   return ok;
}

BOOL GetRegistryString(const TCHAR *name,
                        TCHAR *data,
                        DWORD datasize,
                        const TCHAR *key = "SOFTWARE\\SSI\\Wildcat")
{
   return GetRegistry(key, name, REG_SZ, data, datasize);
}

BOOL PrepareWildcatPath()
{
    char srvPath[MAX_PATH]={0};
    if (GetRegistryString("ServerDirectory",srvPath,MAX_PATH-1)) {
       char ePath[1024*4] = {0};
       strcpy(ePath,srvPath);
       strcat(ePath,";");
       DWORD dw = strlen(ePath);
       return (GETENV("PATH",&ePath[dw],sizeof(ePath)-dw) &&
               SETENV("PATH",ePath));
    }
    return FALSE;
}

////////////////////////////////////////////////////////////////////
// DllMain
////////////////////////////////////////////////////////////////////

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID)
{
   switch (dwReason) {
     case DLL_PROCESS_ATTACH:
       PrepareWildcatPath();
       break;
   }
   return TRUE;
}

#endif

This works really well. We can install PHP*.DLLs in the PHP "./EXT" 
folder and when the extension is loaded by PHP,  all of its dependencies 
  are now resolved during the temporary PHP runtime residence time.

I could of gone deeper (and more elegant without having to alter the 
process PATH) by using the delayimp.lib helper hooks available which 
will issue a callback for the delayed implicit dlls.  But seems overly 
complexed and before I begin on that I wanted so see if a) there was 
already a method to address this and/or b) I could patch PHP to offer an 
multi-path extension_dir method.

Ideally we would love to keep our specific PHP*.DLL files in our server 
folder and have extension_dir defined to look at multiple paths.

Comments?

TIA

-- 
Hector Santos


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Thread:
Hector Santos
Hector Santos
Stanislav Malyshev
Hector Santos
Stanislav Malyshev
Hector Santos
Stanislav Malyshev
Sean Finney
Hector Santos
Lars Strojny
Hector Santos
Hector Santos
Elizabeth M Smith
Hector Santos

Privacy Policy | Email Opt-out | Feedback | Syndication
© 2004 ActiveState, a division of Sophos All rights reserved