code: package org.gridkit.jvmtool.win32;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.lang.management.ManagementFactory;
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.util.Arrays;
  import java.util.Properties;
  
  public class SjkWinHelper {
      static {
          try {
              loadNative();
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
  //        System.load("C:/WarZone/spaces/_rust_jni/rust-jni-test/target/release/hello.dll");
  //        System.load("C:/WarZone/spaces/_rust_jni/rust-jni-test/src/lib.dll");
  //        System.load("C:/WarZone/spaces/_rust_jni/rust-jni-test/src/sjkwinh.dll");
      }
  
      private static void loadNative() throws IOException {
          File tmp = File.createTempFile("java", "").getAbsoluteFile().getParentFile();
          if (tmp.getPath().startsWith("/")) {
              // this is not a windows
              throw new RuntimeException("Cannot load on non Windows OS");
          }
          if ("x86".equals(ManagementFactory.getOperatingSystemMXBean().getArch())) {
              load(tmp, "32");
          }
          else {
              load(tmp, "64");
          }
      }
  
      private static void load(File tmp, String arch) throws IOException {
          InputStream is = SjkWinHelper.class.getClassLoader().getResourceAsStream("sjkwinh.prop");
          Properties prop = new Properties();
          prop.load(is);
  
          String dllName = "sjkwinh" + arch + "." + prop.getProperty("dll" + arch + ".hash") + ".dll";
          int len = Integer.valueOf(prop.getProperty("dll" + arch + ".len"));
  
          File tgt = new File(tmp, dllName);
          if (tgt.isFile() && tgt.length() == len) {
              // dll is present
          }
          else {
              tgt.delete();
              InputStream dllis = SjkWinHelper.class.getClassLoader().getResourceAsStream("sjkwinh" + arch + ".dll");
              byte[] buf = new byte[len];
              int n = dllis.read(buf);
              if (n != buf.length) {
                  throw new RuntimeException("Failed extract dll, size mismatch");
              }
              FileOutputStream fos = new FileOutputStream(tgt);
              fos.write(buf);
              fos.close();
          }
  
          System.load(tgt.getPath());
      }
  
      private native int GetProcessTimes(int pid, int[] buf);
      private native int GetThreadTimes(int pid, int[] buf);
      private native long QueryProcessCycleTime(int pid);
      private native long QueryThreadCycleTime(int pid);
      private native int EnumThreads(int pid, int[] buf);
  
      int[] callBuf = new int[8];
  
      /**
       * Call kernel32::GetProcessTimes.
       * If successful kernel and user times are set to
       * first two slots in array.
       * <p>
       * Time units are microseconds.
       *
       * @param pid
       * @return <code>false</code> is not successful
       */
      public synchronized boolean getProcessCpuTimes(int pid, long[] result) {
          int rc = GetProcessTimes(pid, callBuf);
          if (rc == 0) {
              long ktime = (0xFFFFFFFFl & callBuf[4]) | ((long)callBuf[5]) << 32;
              long utime = (0xFFFFFFFFl & callBuf[6]) | ((long)callBuf[7]) << 32;
  
              result[0] = ktime / 10;
              result[1] = utime / 10;
              return true;
          }
          else {
              System.out.println("Error code: " + rc);
              return false;
          }
      }
  
      /**
       * Call kernel32::GetThreadTimes.
       * If successful kernel and user times are set to
       * first two slots in array.
       * <p>
       * Time units are microseconds.
       *
       * @param pid
       * @return <code>false</code> is not successful
       */
      public synchronized boolean getThreadCpuTimes(int pid, long[] result) {
          int rc = GetThreadTimes(pid, callBuf);
          if (rc == 0) {
              long ktime = (0xFFFFFFFFl & callBuf[4]) | ((long)callBuf[5]) << 32;
              long utime = (0xFFFFFFFFl & callBuf[6]) | ((long)callBuf[7]) << 32;
  
              result[0] = ktime / 10;
              result[1] = utime / 10;
              return true;
          }
          else {
              System.out.println("Error code: " + rc);
              return false;
          }
      }
  
      public synchronized long getProcessCpuCycles(int pid) {
          return QueryProcessCycleTime(pid);
      }
  
      public synchronized long getThreadCpuCycles(int pid) {
          return QueryThreadCycleTime(pid);
      }
  
      public synchronized int[] enumThreads(int pid) {
          int[] buf = new int[128];
          int n = EnumThreads(pid, buf);
          if (n < 0) {
              throw new RuntimeException("Cannot enum threads. WinError: " + (-n));
          }
          while (n > buf.length) {
              buf = new int[n + 16];
              n = EnumThreads(pid, buf);
              if (n < 0) {
                  throw new RuntimeException("Cannot enum threads. WinError: " + (-n));
              }
          }
          return buf.length == n ? buf : Arrays.copyOf(buf, n);
      }
  }
  