I'm attempting to convert a very simple C Win32 API call over to Ruby utilizing Fiddle and I'm not having much success.
The first two method calls work flawlessly, though when I get to the call which populates a struct I'm having a bit of difficulty, as it appears the struct is being populated with garbage data:
Here's the relevant C code:
DWORD dwHandle, dwLen;
LPVOID lpData;
UINT BufLen;
VS_FIXEDFILEINFO *pFileInfo;
LPTSTR LibName = L"C:\\windows\\notepad.exe";
dwLen = GetFileVersionInfoSize(LibName, &dwHandle);
if(dwLen != 0)
{
lpData = malloc(dwLen);
if (GetFileVersionInfo(LibName, NULL, &dwLen, lpData))
{
if (VerQueryValue(lpData, L"\\", (LPVOID)&pFileInfo, (PUINT)&BufLen))
{
printf("ProductVersion: %d.%d.%d.%d\n", HIWORD(pFileInfo->dwProductVersionMS), LOWORD(pFileInfo->dwProductVersionLS), HIWORD(pFileInfo->dwFileVersionLS), LOWORD(pFileInfo->dwFileVersionLS));
printf("FileVersion: %d.%d.%d.%d\n", HIWORD(pFileInfo->dwFileVersionMS), LOWORD(pFileInfo->dwFileVersionMS), HIWORD(pFileInfo->dwFileVersionLS), LOWORD(pFileInfo->dwFileVersionLS));
}
}
}
And here's my attempt at converting the C to Ruby:
require 'fiddle/import'
module Version
extend Fiddle::Importer
dlload 'version'
typealias 'HANDLE', 'void*'
typealias 'LPVOID', 'void*'
typealias 'LPCVOID', 'const void*'
typealias 'LPDWORD', 'int*'
typealias 'HWND', 'HANDLE'
typealias 'LPCSTR', 'const char*'
typealias 'LPCWSTR', 'const wchar_t*'
typealias 'UINT', 'unsigned int'
typealias 'PUINT', 'unsigned int*'
typealias 'DWORD', 'unsigned long'
typealias 'BOOL', 'int'
extern 'DWORD GetFileVersionInfoSize(LPCSTR, LPDWORD)'
extern 'BOOL GetFileVersionInfo(LPCSTR, DWORD, DWORD, LPVOID)'
extern 'BOOL VerQueryValue(LPCVOID, LPCSTR, LPVOID, PUINT)'
VS_FIXEDFILEINFO = struct [
'DWORD dwSignature',
'DWORD dwStrucVersion',
'DWORD dwFileVersionMS',
'DWORD dwFileVersionLS',
'DWORD dwProductVersionMS',
'DWORD dwProductVersionLS',
'DWORD dwFileFlagsMask',
'DWORD dwFileFlags',
'DWORD dwFileOS',
'DWORD dwFileType',
'DWORD dwFileSubtype',
'DWORD dwFileDateMS',
'DWORD dwFileDateLS'
]
end
dwHandle = Fiddle::NULL
dwLen = Version::GetFileVersionInfoSize "C:\\windows\\system32\\notepad.exe", dwHandle
lpData = Fiddle::Pointer.malloc(dwLen)
Version::GetFileVersionInfo "C:\\windows\\notepad.exe", 0, dwLen, lpData
BufLen = Fiddle::NULL
pFileInfo = Version::VS_FIXEDFILEINFO.malloc()
success = Version::VerQueryValue lpData, "\\", pFileInfo, BufLen.ref
puts "pFileInfo: #{pFileInfo.dwSignature}"
Unfortunately, pFileInfo.dwSignature appears to change every time around indicating it's being filled with garbage data (strangely enough it IS zero before the VerQueryValue call). The pFileInfo.dwSignature value should always be 0xFEEF04BD, or in decimal 4277077181.
Any thoughts on what's going on here?
Thanks!