简体   繁体   中英

C++ code works fine but doesn't work when calling from Java (JNI)

I used to have some privilege issues when calling ExitWindowsEX Windows API function.

So I wrote the following code to get the privilege:

This works fine in C++

#include <cstdlib>
#include <windows.h>
#include <iostream>


using namespace std;

/*
 * 
 */

int MyExitWindows(int flag, int reason);

int main(int argc, char** argv) {
  MyExitWindows(EWX_SHUTDOWN, 0);
}

int MyExitWindows(int flag, int reason) {
  HANDLE hToken;
  TOKEN_PRIVILEGES tkp;

  //   Get   a   token   for   this   process.     

  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    return GetLastError();

  //   Get   the   LUID   for   the   shutdown   privilege.     

  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);

  tkp.PrivilegeCount = 1; //   one   privilege   to   set           
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  //   Get   the   shutdown   privilege   for   this   process.     

  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
          (PTOKEN_PRIVILEGES) NULL, 0);

  //   Cannot   test   the   return   value   of   AdjustTokenPrivileges.     

  ExitWindowsEx(flag, reason);
  if (GetLastError() != ERROR_SUCCESS) {
    return GetLastError();
  }

  return 0;
}

But this doesn't work when I call it from Java

#include <jni.h>
#include <cstdlib>
#include <windows.h>
#include "com_ehsunbehravesh_jshutdown_system_Shutdowner.h"

using namespace std;

int MyExitWindows(int flag, int reason);

JNIEXPORT jint JNICALL Java_com_ehsunbehravesh_jshutdown_system_Shutdowner_exitWindowsEx
(JNIEnv *env, jobject obj, jlong flag, jlong reason) {
  return MyExitWindows(flag, reason);
}

int MyExitWindows(int flag, int reason) {
  HANDLE hToken;
  TOKEN_PRIVILEGES tkp;

  //   Get   a   token   for   this   process.     

  int cpid = GetCurrentProcessId();
  printf("%d", cpid);
  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    return GetLastError();

  //   Get   the   LUID   for   the   shutdown   privilege.     

  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);

  tkp.PrivilegeCount = 1; //   one   privilege   to   set           
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  //   Get   the   shutdown   privilege   for   this   process.     

  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
          (PTOKEN_PRIVILEGES) NULL, 0);

  //   Cannot   test   the   return   value   of   AdjustTokenPrivileges.     

  ExitWindowsEx(flag, reason);
  if (GetLastError() != ERROR_SUCCESS) {
    return GetLastError();
  }

  return 0;
}

Is there any reason you are not using System.exit(int) ?

Java attempts to control the shutdown of an application, perhaps it tries to prevent you doing it other ways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM