JNA получить модуль из процесса по имени - PullRequest
0 голосов
/ 28 октября 2018

Я ищу способ переписать функцию из C ++ в Java, где я получаю запись модуля из процесса по его имени.Я не очень разбираюсь в JNA, и мне трудно понять, как указатели реализованы в Java.Вот мой код на C ++.

ULONG GetModule(DWORD th32ProcessID, MODULEENTRY32* Entry, PCWSTR szModule) 
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, th32ProcessID);

    if (hSnapshot != INVALID_HANDLE_VALUE) 
{
    ULONG dwError = ERROR_NOT_FOUND;

    Entry->dwSize = sizeof(MODULEENTRY32);

    if (Module32FirstW(hSnapshot, Entry))
    {
        do 
        {
            if (!_wcsicmp(Entry->szModule, szModule))
            {
                dwError = NOERROR;
                break;
            }
        } while (Module32NextW(hSnapshot, Entry));
    }

    CloseHandle(hSnapshot);

    return dwError;
   }
   return GetLastError();
}

А вот моя попытка реализовать это в Java:

    private Tlhelp32.MODULEENTRY32W findModule(String module) {
    Tlhelp32.MODULEENTRY32W moduleEntry = new Tlhelp32.MODULEENTRY32W.ByReference();

    WinNT.HANDLE snapshot =
            Kernel32.INSTANCE.CreateToolhelp32Snapshot(
                    TH32CS_SNAPMODULE,
                    new WinDef.DWORD(pid)
            );

    if(snapshot != INVALID_HANDLE_VALUE) {
        if(Kernel32.INSTANCE.Module32FirstW(snapshot, moduleEntry)) {
            do {
                if(Arrays.toString(moduleEntry.szModule).equals(module)) {
                    return moduleEntry;
                }
            } while (Kernel32.INSTANCE.Module32NextW(snapshot, moduleEntry));
        }
    }
    return null;
}

Всегда возвращает ноль.

1 Ответ

0 голосов
/ 28 октября 2018

Я не думаю, что вы ищете Arrays.toString здесь.Взгляните на его документацию :

Возвращает строковое представление содержимого указанного массива.Строковое представление состоит из списка элементов массива, заключенного в квадратные скобки ("[]").Соседние элементы разделены символами «,» (запятая, за которой следует пробел).Элементы преобразуются в строки как String.valueOf (char).Возвращает «ноль», если a равно нулю.

Так, например, массив char[] из { 'h', 'e', 'l', 'l', 'o' } будет преобразован в "[h, e, l, l, o]".

Поскольку вы просто хотитепревратить этот массив символов в строку как есть, попробуйте использовать конструктор String class ', который именно это и делает.

if (module.equals(new String(moduleEntry.szModule))) {
    // ...
}

Если вы не ищете точное совпадение, вы можете попробовать .contains().

Также, не забудьте закрыть дескриптор для снимка с CloseHandle, как в версии C ++!Если вы не закроете дескриптор, ваш метод будет терять память при каждом вызове.

private Tlhelp32.MODULEENTRY32W findModule(String module) {
    Tlhelp32.MODULEENTRY32W moduleEntry = new Tlhelp32.MODULEENTRY32W.ByReference();

    WinNT.HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot(
        TH32CS_SNAPMODULE,
        new WinDef.DWORD(pid)
    );

    if (snapshot == INVALID_HANDLE_VALUE) {
        return null;
    }

    Tlhelp32.MODULEENTRY32W match = null;
    if (Kernel32.INSTANCE.Module32FirstW(snapshot, moduleEntry)) {
        do {
            if (module.equals(new String(moduleEntry.szModule))) {
                match = moduleEntry;
                break;
            }
        } while (Kernel32.INSTANCE.Module32NextW(snapshot, moduleEntry));
    }

    Kernel32.INSTANCE.CloseHandle(snapshot);
    return match;
}
...