From: Jan Dubois Date: Wed, 11 May 2005 22:30:37 +0000 (-0700) Subject: Add Win32::GetFileVersion() function X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e364e11cbe4a80d9acc3833bfaa4404dc494d83f;p=p5sagit%2Fp5-mst-13.2.git Add Win32::GetFileVersion() function From: "Jan Dubois" Message-Id: <200505120530.j4C5UhpX031152@smtp3.ActiveState.com> p4raw-id: //depot/perl@24453 --- diff --git a/win32/ext/Win32/Win32.pm b/win32/ext/Win32/Win32.pm index 02e72bc..f3517b1 100644 --- a/win32/ext/Win32/Win32.pm +++ b/win32/ext/Win32/Win32.pm @@ -368,6 +368,13 @@ $ENV{PROCESSOR_ARCHITECTURE}. This might not work on Win9X. does not return a UNC path, since the functionality required for such a feature is not available under Windows 95. +=item Win32::GetFileVersion(FILENAME) + +[EXT] Returns the file version number from the VERSIONINFO resource of +the executable file or DLL. This is a tuple of four 16 bit numbers. +In list context these four numbers will be returned. In scalar context +they are concatenated into a string, separated by dots. + =item Win32::GetFolderPath(FOLDER [, CREATE]) [EXT] Returns the full pathname of one of the Windows special folders. @@ -555,6 +562,19 @@ function. system boot. Resolution is limited to system timer ticks (about 10ms on WinNT and 55ms on Win9X). +=item Win32::GuidGen() + +[EXT] Creates a globally unique 128 bit integer that can be used as a +persistent identifier in a distributed setting. To a very high degree +of certainty this function returns a unique value. No other +invocation, on the same or any other system (networked or not), should +return the same value. + +The return value is formatted according to OLE conventions, as groups +of hex digits with surrounding braces. For example: + + {09531CF1-D0C7-4860-840C-1C8C8735E2AD} + =item Win32::InitiateSystemShutdown (MACHINE, MESSAGE, TIMEOUT, FORCECLOSE, REBOOT) diff --git a/win32/ext/Win32/Win32.xs b/win32/ext/Win32/Win32.xs index e15fc81..5342dca 100644 --- a/win32/ext/Win32/Win32.xs +++ b/win32/ext/Win32/Win32.xs @@ -572,14 +572,14 @@ XS(w32_GuidGen) if (SUCCEEDED(hr)) { LPOLESTR pStr = NULL; - StringFromCLSID(&guid, &pStr); - WideCharToMultiByte(CP_ACP, 0, pStr, wcslen(pStr), szGUID, - sizeof(szGUID), NULL, NULL); - - XSRETURN_PV(szGUID); + if (SUCCEEDED(StringFromCLSID(&guid, &pStr))) { + WideCharToMultiByte(CP_ACP, 0, pStr, wcslen(pStr), szGUID, + sizeof(szGUID), NULL, NULL); + CoTaskMemFree(pStr); + XSRETURN_PV(szGUID); + } } - else - XSRETURN_UNDEF; + XSRETURN_UNDEF; } XS(w32_GetFolderPath) @@ -626,6 +626,57 @@ XS(w32_GetFolderPath) XSRETURN_UNDEF; } +XS(w32_GetFileVersion) +{ + dXSARGS; + DWORD size; + DWORD handle; + char *filename; + char *data; + + if (items != 1) + croak("usage: Win32::GetFileVersion($filename)\n"); + + filename = SvPV_nolen(ST(0)); + size = GetFileVersionInfoSize(filename, &handle); + if (!size) + XSRETURN_UNDEF; + + New(0, data, size, char); + if (!data) + XSRETURN_UNDEF; + + if (GetFileVersionInfo(filename, handle, size, data)) { + VS_FIXEDFILEINFO *info; + UINT len; + if (VerQueryValue(data, "\\", (void**)&info, &len)) { + int dwValueMS1 = (info->dwFileVersionMS>>16); + int dwValueMS2 = (info->dwFileVersionMS&0xffff); + int dwValueLS1 = (info->dwFileVersionLS>>16); + int dwValueLS2 = (info->dwFileVersionLS&0xffff); + + if (GIMME_V == G_ARRAY) { + EXTEND(SP, 4); + XST_mIV(0, dwValueMS1); + XST_mIV(1, dwValueMS2); + XST_mIV(2, dwValueLS1); + XST_mIV(3, dwValueLS2); + items = 4; + } + else { + char version[50]; + sprintf(version, "%d.%d.%d.%d", dwValueMS1, dwValueMS2, dwValueLS1, dwValueLS2); + XST_mPV(0, version); + } + } + } + else + items = 0; + + Safefree(data); + XSRETURN(items); +} + XS(boot_Win32) { dXSARGS; @@ -647,6 +698,7 @@ XS(boot_Win32) newXS("Win32::GuidGen", w32_GuidGen, file); newXS("Win32::GetFolderPath", w32_GetFolderPath, file); newXS("Win32::IsAdminUser", w32_IsAdminUser, file); + newXS("Win32::GetFileVersion", w32_GetFileVersion, file); XSRETURN_YES; }