Как определить разрядность процесса Windows в Java с помощью JNA? - PullRequest
0 голосов
/ 18 января 2019

Я пишу метод Java для определения разрядности указанного процесса Windows, идентифицируемого PID. Код вызывает функции Win32 API через JNA. Моя попытка ниже, но она всегда возвращает 32, даже если задан PID 64-битного процесса. Путь к коду всегда один и тот же (см. Комментарии в фрагменте кода).

Я не уверен, является ли данный подход концептуальным или в реализации есть ошибка.

Код работает на 64-битной Windows 7 с 32-битной JRE. Что я делаю не так?

import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.IntByReference;

public class Test
{

  public static void main(String[] args)
  {
    int pid;

    pid = 10340;
    System.out.println(pid + " bitness = " + getProcessBitness(pid));
    pid = 15116;
    System.out.println(pid + " bitness = " + getProcessBitness(pid));
  }

  /**
   * Given a process ID, determine the bitness of the process.
   * 
   * @param pid
   * @return 32 or 64
   */
  public static int getProcessBitness(int pid)
  {
    Kernel32 kernel32 = Kernel32.INSTANCE;
    IntByReference ref = new IntByReference();

    WinNT.HANDLE hProcess = kernel32.OpenProcess(WinNT.PROCESS_TERMINATE, false, pid);

    // See https://docs.microsoft.com/en-us/windows/desktop/api/wow64apiset/nf-wow64apiset-iswow64process
    kernel32.IsWow64Process(hProcess, ref);
    boolean isWow64 = (ref.getValue() == 1);

    if (isWow64)
      // WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows
      return 32;  // This never happens
    else
    {
      // The process bitness matches the OS bitness
      int osBitness;

      // See https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
      SYSTEM_INFO systemInfo = new SYSTEM_INFO();
      kernel32.GetNativeSystemInfo(systemInfo);
      if (systemInfo.processorArchitecture.pi.wProcessorArchitecture.intValue() == 0)
        osBitness = 32;  // This code path is always taken for both 32 and 64 bit processes
      else
        osBitness = 64;  // This never happens
      return osBitness;
    }
  }

}

1 Ответ

0 голосов
/ 18 января 2019

Благодаря Реми Лебо, это исправленный код:

  /**
   * Given a process ID, determine the bitness of the process.
   * 
   * @param pid
   * @return 32 or 64
   */
  public static int getProcessBitness(int pid)
  {
    Kernel32 kernel32 = Kernel32.INSTANCE;
    IntByReference ref = new IntByReference();

    WinNT.HANDLE hProcess = kernel32.OpenProcess(WinNT.PROCESS_QUERY_LIMITED_INFORMATION, false, pid);

    // See https://docs.microsoft.com/en-us/windows/desktop/api/wow64apiset/nf-wow64apiset-iswow64process
    kernel32.IsWow64Process(hProcess, ref);
    boolean isWow64 = (ref.getValue() == 1);

    if (isWow64)
      // WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows
      return 32;
    else
    {
      // The process bitness matches the OS bitness
      int osBitness;

      // See https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
      SYSTEM_INFO systemInfo = new SYSTEM_INFO();
      kernel32.GetNativeSystemInfo(systemInfo);

      int processorArchitecture = systemInfo.processorArchitecture.dwOemID.intValue() & 0xFFFF;
      if (processorArchitecture == 0) // PROCESSOR_ARCHITECTURE_INTEL = x86
        osBitness = 32;
      else
        osBitness = 64;
      return osBitness;
    }
  }
...