Почему моя структура Fiddle заполнена мусором? - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь преобразовать очень простой C32-вызов Win32 API в Ruby с использованием Fiddle, и я не добиваюсь большого успеха.

Первые два вызова метода работают безупречно, хотя, когда я добираюсь до вызова, который заполняет структуру, у меня возникают некоторые трудности, так как кажется, что структура заполняется мусорными данными:

Вот соответствующий код C:

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));
        }
    }
}

А вот моя попытка конвертировать C в 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}"

К сожалению, pFileInfo.dwSignature, похоже, меняется каждый раз, указывая на то, что он заполняется мусорными данными (как ни странно, он равен нулю перед вызовом VerQueryValue). Значение pFileInfo.dwSignature всегда должно быть 0xFEEF04BD или в десятичном виде 4277077181.

Есть мысли о том, что здесь происходит?

Спасибо!

...