]> granicus.if.org Git - php/commitdiff
Get rid of these slow calls to LoadLibrary()/GetProcAddress() calls on Windows, we...
authorKalle Sommer Nielsen <kalle@php.net>
Thu, 11 Aug 2016 00:09:50 +0000 (02:09 +0200)
committerKalle Sommer Nielsen <kalle@php.net>
Thu, 11 Aug 2016 00:09:50 +0000 (02:09 +0200)
GD:
 - PrintWindow() is available as of Windows XP, it requires linking to User32.lib, which config.w32 for ext/gd already.

CLI:
 - The borrowed functions from PostgreSQL to set the titles of the console window uses SetConsoleTitle() and GetConsoleTitle(), both are available as of Windows 2000 from Kernel32.lib which we already are linking against.

Standard:
 - The disk space utility functions uses GetDiskFreeSpaceExA() which is available as of Windows XP, again links to Kernel32.lib.
 - The symlink() PHP function uses CreateSymbolicLinkA() which is available from Windows Vista, again from Kernel32.lib.
 - php_get_windows_name() in info.c uses GetNativeSystemInfo() which is available as of Windows XP and GetProductInfo() which is available as of Windows Vista, both are again from Kernel32.lib.

Notes:
 - ext/interbase & ext/pdo_firebird uses GetProcAddress(), I'm not entirely sure how to handle this one.
 - ext/sqlite3, this is apart of the bundled libsqlite3, I don't really wanna play around with our bundled libs and make it a bigger issue for those who maintain and upgrade them.
 - ext/readline, the call to GetProcAddress() here does not do any system calls, so it is left as is.
 - win32/ioutil.c uses GetProcAddress(), but the function it attempts to load (PathCchCanonicalizeEx()) is only available from Windows 8 and greater (Pathcch.lib linkage).
 - win32/time.c uses GetSystemTimePreciseAsFileTime() which is available from Windows 8 and greater to get the current system date and time which the highest possible precision and falls back to GetSystemTimeAsFileTime() (available as of Windows 2000), again Kernel32.lib, the GetSystemTimePreciseAsFileTime() is left in a GetProcAddress().

ext/gd/gd.c
ext/standard/filestat.c
ext/standard/info.c
ext/standard/link_win32.c
sapi/cli/ps_title.c
win32/time.c

index d0eea0bd0b2e99319dd97ad120a670ea1d042f7c..a056a49d47055cb30c9f5d03b32b6bb836b5684e 100644 (file)
@@ -1891,10 +1891,7 @@ PHP_FUNCTION(imagegrabwindow)
        HDC memDC;
        HBITMAP memBM;
        HBITMAP hOld;
-       HINSTANCE handle;
        zend_long lwindow_handle;
-       typedef BOOL (WINAPI *tPrintWindow)(HWND, HDC,UINT);
-       tPrintWindow pPrintWindow = 0;
        gdImagePtr im = NULL;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &lwindow_handle, &client_area) == FAILURE) {
@@ -1926,21 +1923,7 @@ PHP_FUNCTION(imagegrabwindow)
        memBM   = CreateCompatibleBitmap(hdc, Width, Height);
        hOld    = (HBITMAP) SelectObject (memDC, memBM);
 
-
-       handle = LoadLibrary("User32.dll");
-       if ( handle == 0 ) {
-               goto clean;
-       }
-       pPrintWindow = (tPrintWindow) GetProcAddress(handle, "PrintWindow");
-
-       if ( pPrintWindow )  {
-               pPrintWindow(window, memDC, (UINT) client_area);
-       } else {
-               php_error_docref(NULL, E_WARNING, "Windows API too old");
-               goto clean;
-       }
-
-       FreeLibrary(handle);
+       PrintWindow(window, memDC, (UINT) client_area);
 
        im = gdImageCreateTrueColor(Width, Height);
        if (im) {
@@ -1953,7 +1936,6 @@ PHP_FUNCTION(imagegrabwindow)
                }
        }
 
-clean:
        SelectObject(memDC,hOld);
        DeleteObject(memBM);
        DeleteDC(memDC);
index f6bd99c474108afd544eff5ebed522dc946afedd..6f3a43ee701197aefbce637870e5a4cd62e96355 100644 (file)
@@ -110,59 +110,19 @@ PHP_RSHUTDOWN_FUNCTION(filestat) /* {{{ */
 static int php_disk_total_space(char *path, double *space) /* {{{ */
 #if defined(WINDOWS) /* {{{ */
 {
-       double bytestotal = 0;
-       HINSTANCE kernel32;
-       FARPROC gdfse;
-       typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
-       gdfse_func func;
-
-       /* These are used by GetDiskFreeSpaceEx, if available. */
        ULARGE_INTEGER FreeBytesAvailableToCaller;
        ULARGE_INTEGER TotalNumberOfBytes;
        ULARGE_INTEGER TotalNumberOfFreeBytes;
 
-       /* These are used by GetDiskFreeSpace otherwise. */
-       DWORD SectorsPerCluster;
-       DWORD BytesPerSector;
-       DWORD NumberOfFreeClusters;
-       DWORD TotalNumberOfClusters;
-
-       /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
-          so we have to jump through some hoops to see if the function
-          exists. */
-       kernel32 = LoadLibrary("kernel32.dll");
-       if (kernel32) {
-               gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
-               /* It's available, so we can call it. */
-               if (gdfse) {
-                       func = (gdfse_func)gdfse;
-                       if (func(path,
-                                               &FreeBytesAvailableToCaller,
-                                               &TotalNumberOfBytes,
-                                               &TotalNumberOfFreeBytes) == 0) {
-                               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
-                               return FAILURE;
-                       }
+       if (GetDiskFreeSpaceExA(path, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == 0) {
+               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
 
-                       /* i know - this is ugly, but i works <thies@thieso.net> */
-                       bytestotal  = TotalNumberOfBytes.HighPart *
-                               (double) (((zend_ulong)1) << 31) * 2.0 +
-                               TotalNumberOfBytes.LowPart;
-               } else { /* If it's not available, we just use GetDiskFreeSpace */
-                       if (GetDiskFreeSpace(path,
-                                               &SectorsPerCluster, &BytesPerSector,
-                                               &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
-                               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
-                               return FAILURE;
-                       }
-                       bytestotal = (double)TotalNumberOfClusters * (double)SectorsPerCluster * (double)BytesPerSector;
-               }
-       } else {
-               php_error_docref(NULL, E_WARNING, "Unable to load kernel32.dll");
                return FAILURE;
        }
 
-       *space = bytestotal;
+       /* i know - this is ugly, but i works <thies@thieso.net> */
+       *space = TotalNumberOfBytes.HighPart * (double) (((zend_ulong)1) << 31) * 2.0 + TotalNumberOfBytes.LowPart;
+
        return SUCCESS;
 }
 /* }}} */
@@ -241,60 +201,19 @@ PHP_FUNCTION(disk_total_space)
 static int php_disk_free_space(char *path, double *space) /* {{{ */
 #if defined(WINDOWS) /* {{{ */
 {
-       double bytesfree = 0;
-
-       HINSTANCE kernel32;
-       FARPROC gdfse;
-       typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
-       gdfse_func func;
-
-       /* These are used by GetDiskFreeSpaceEx, if available. */
        ULARGE_INTEGER FreeBytesAvailableToCaller;
        ULARGE_INTEGER TotalNumberOfBytes;
        ULARGE_INTEGER TotalNumberOfFreeBytes;
 
-       /* These are used by GetDiskFreeSpace otherwise. */
-       DWORD SectorsPerCluster;
-       DWORD BytesPerSector;
-       DWORD NumberOfFreeClusters;
-       DWORD TotalNumberOfClusters;
-
-       /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
-          so we have to jump through some hoops to see if the function
-          exists. */
-       kernel32 = LoadLibrary("kernel32.dll");
-       if (kernel32) {
-               gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
-               /* It's available, so we can call it. */
-               if (gdfse) {
-                       func = (gdfse_func)gdfse;
-                       if (func(path,
-                                               &FreeBytesAvailableToCaller,
-                                               &TotalNumberOfBytes,
-                                               &TotalNumberOfFreeBytes) == 0) {
-                               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
-                               return FAILURE;
-                       }
+       if (GetDiskFreeSpaceExA(path, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == 0) {
+               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
 
-                       /* i know - this is ugly, but i works <thies@thieso.net> */
-                       bytesfree  = FreeBytesAvailableToCaller.HighPart *
-                               (double) (((zend_ulong)1) << 31) * 2.0 +
-                               FreeBytesAvailableToCaller.LowPart;
-               } else { /* If it's not available, we just use GetDiskFreeSpace */
-                       if (GetDiskFreeSpace(path,
-                                               &SectorsPerCluster, &BytesPerSector,
-                                               &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
-                               php_error_docref(NULL, E_WARNING, "%s", php_win_err());
-                               return FAILURE;
-                       }
-                       bytesfree = (double)NumberOfFreeClusters * (double)SectorsPerCluster * (double)BytesPerSector;
-               }
-       } else {
-               php_error_docref(NULL, E_WARNING, "Unable to load kernel32.dll");
                return FAILURE;
        }
 
-       *space = bytesfree;
+       /* i know - this is ugly, but i works <thies@thieso.net> */
+       *space = FreeBytesAvailableToCaller.HighPart * (double) (((zend_ulong)1) << 31) * 2.0 + FreeBytesAvailableToCaller.LowPart;
+
        return SUCCESS;
 }
 /* }}} */
index 982d4e461b75b7add9731a38d3c7f6f6e1e9defc..b62679528c39cecda20402b5e477dc5310adb7fb 100644 (file)
 #include "php_string.h"
 
 #ifdef PHP_WIN32
-typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
-typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
 # include "winver.h"
-
 #endif
 
 #define SECTION(name)  if (!sapi_module.phpinfo_as_text) { \
@@ -295,19 +292,12 @@ char* php_get_windows_name()
 {
        OSVERSIONINFOEX osvi = EG(windows_version_info);
        SYSTEM_INFO si;
-       PGNSI pGNSI;
-       PGPI pGPI;
        DWORD dwType;
        char *major = NULL, *sub = NULL, *retval;
 
        ZeroMemory(&si, sizeof(SYSTEM_INFO));
 
-       pGNSI = (PGNSI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
-       if(NULL != pGNSI) {
-               pGNSI(&si);
-       } else {
-               GetSystemInfo(&si);
-       }
+       GetNativeSystemInfo(&si);
 
        if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) {
                if (osvi.dwMajorVersion == 10) {
@@ -380,8 +370,8 @@ char* php_get_windows_name()
                                major = "Unknown Windows version";
                        }
 
-                       pGPI = (PGPI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");
-                       pGPI(6, 0, 0, 0, &dwType);
+                       /* No return value check, as it can only fail if the input parameters are broken (which we manually supply) */
+                       GetProductInfo(6, 0, 0, 0, &dwType);
 
                        switch (dwType) {
                                case PRODUCT_ULTIMATE:
index 56ab4500c404c9b031e6bc5d70060c846f1518b6..a6ad0c34f2693332b395371bfe81922fca017883 100644 (file)
@@ -117,22 +117,6 @@ PHP_FUNCTION(symlink)
        char dirname[MAXPATHLEN];
        size_t len;
        DWORD attr;
-       HINSTANCE kernel32;
-       typedef BOOLEAN (WINAPI *csla_func)(LPCSTR, LPCSTR, DWORD);
-       csla_func pCreateSymbolicLinkA;
-
-       kernel32 = LoadLibrary("kernel32.dll");
-
-       if (kernel32) {
-               pCreateSymbolicLinkA = (csla_func)GetProcAddress(kernel32, "CreateSymbolicLinkA");
-               if (pCreateSymbolicLinkA == NULL) {
-                       php_error_docref(NULL, E_WARNING, "Can't call CreateSymbolicLinkA");
-                       RETURN_FALSE;
-               }
-       } else {
-               php_error_docref(NULL, E_WARNING, "Can't call get a handle on kernel32.dll");
-               RETURN_FALSE;
-       }
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
                return;
@@ -174,7 +158,7 @@ PHP_FUNCTION(symlink)
        /* For the source, an expanded path must be used (in ZTS an other thread could have changed the CWD).
         * For the target the exact string given by the user must be used, relative or not, existing or not.
         * The target is relative to the link itself, not to the CWD. */
-       ret = pCreateSymbolicLinkA(source_p, topath, (attr & FILE_ATTRIBUTE_DIRECTORY ? 1 : 0));
+       ret = CreateSymbolicLinkA(source_p, topath, (attr & FILE_ATTRIBUTE_DIRECTORY ? 1 : 0));
 
        if (!ret) {
                php_error_docref(NULL, E_WARNING, "Cannot create symlink, error code(%d)", GetLastError());
index 8f5ce2480088e59e606db774da7298bea7db0cd3..514a2ebc7b7ba1d6db8aecc6aa61dd2a94b275e0 100644 (file)
@@ -109,8 +109,6 @@ extern char** environ;
 static char windows_error_details[64];
 static char ps_buffer[MAX_PATH];
 static const size_t ps_buffer_size = MAX_PATH;
-typedef BOOL (WINAPI *MySetConsoleTitle)(LPCTSTR);
-typedef DWORD (WINAPI *MyGetConsoleTitle)(LPTSTR, DWORD);
 #elif defined(PS_USE_CLOBBER_ARGV)
 static char *ps_buffer;         /* will point to argv area */
 static size_t ps_buffer_size;   /* space determined at run time */
@@ -371,22 +369,10 @@ int set_ps_title(const char* title)
 
 #ifdef PS_USE_WIN32
     {
-       MySetConsoleTitle set_title = NULL;
-       HMODULE hMod = LoadLibrary("kernel32.dll");
-
-       if (!hMod) {
-            return PS_TITLE_WINDOWS_ERROR;
-       }
-
-       /* NOTE we don't use _UNICODE*/
-       set_title = (MySetConsoleTitle)GetProcAddress(hMod, "SetConsoleTitleA");
-       if (!set_title) {
-            return PS_TITLE_WINDOWS_ERROR;
-       }
-
-        if (!set_title(ps_buffer)) {
+               /* NOTE we don't use _UNICODE*/
+        if (!SetConsoleTitleA(ps_buffer)) {
             return PS_TITLE_WINDOWS_ERROR;
-       }
+               }
     }
 #endif /* PS_USE_WIN32 */
 
@@ -407,22 +393,10 @@ int get_ps_title(int *displen, const char** string)
 
 #ifdef PS_USE_WIN32
     {
-       MyGetConsoleTitle get_title = NULL;
-       HMODULE hMod = LoadLibrary("kernel32.dll");
-
-       if (!hMod) {
-            return PS_TITLE_WINDOWS_ERROR;
-       }
-
-       /* NOTE we don't use _UNICODE*/
-       get_title = (MyGetConsoleTitle)GetProcAddress(hMod, "GetConsoleTitleA");
-       if (!get_title) {
-            return PS_TITLE_WINDOWS_ERROR;
-       }
-
-        if (!(ps_buffer_cur_len = get_title(ps_buffer, (DWORD)ps_buffer_size))) {
+               /* NOTE we don't use _UNICODE*/
+        if (!(ps_buffer_cur_len = GetConsoleTitleA(ps_buffer, (DWORD)ps_buffer_size))) {
             return PS_TITLE_WINDOWS_ERROR;
-       }
+               }
     }
 #endif
     *displen = (int)ps_buffer_cur_len;
index dfcc46a59b6e26f29c54df00b8776ab7e23e3d9d..9063ebf62900e7332a54eb5a6180fd386afee691 100644 (file)
@@ -38,11 +38,14 @@ static zend_always_inline MyGetSystemTimeAsFileTime get_time_func(void)
        if (hMod) {
                /* Max possible resolution <1us, win8/server2012 */
                timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
+       }
+
+       /* Lower the refcount */
+       FreeLibrary(hMod);
 
-               if(!timefunc) {
-                       /* 100ns blocks since 01-Jan-1641 */
-                       timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
-               }
+       if(!timefunc) {
+               /* 100ns blocks since 01-Jan-1641 */
+               timefunc = (MyGetSystemTimeAsFileTime) GetSystemTimeAsFileTime;
        }
 
        return timefunc;