Still new to android and java but learning more each day :)
This question refers to
Ok, the error refers to
expression failed to parse:
error: <user expression 27>:1:1: 'bl' has unknown type; cast it to its declared type to use it
bl
^~
and
expression failed to parse:
error: <user expression 28>:1:1: 'uxtb' has unknown type; cast it to its declared type to use it
uxtb.w
^~~~
I call (will want a short ) result = getCheckSum(A, B); from my java code.
The method in my C++ code is
//---------------------------------------------------------------------------
unsigned short ekmCheckCRC16(const unsigned char *dat, unsigned short len)
{
unsigned short crc = 0xffff;
while (len--)
{
crc = (crc >> 8 ) ^ ekmCrcLut[(crc ^ *dat++) & 0xff];
}
crc = (crc << 8 ) | (crc >> 8);
crc &= 0x7f7f;
return crc;
}
//---------------------------------------------------------------------------
// Implementation of the native method getCheckSum()
extern "C"
JNIEXPORT unsigned short JNICALL
Java_com_(...)_getCheckSum(JNIEnv *env, jobject thiz, jstring a) {
const char * aCStr = env->GetStringUTFChars(a, NULL);
if(NULL == aCStr)
return NULL;
unsigned short crc = ekmCheckCRC16(reinterpret_cast<const unsigned char *>(aCStr), strlen(aCStr));
return crc;
}
This code is experimental showing the actual code I want to run ekmCheckCRC16( ... ), its purpose is to learn how to return a value back to the java module.
The error message seems to be clear 'unknown' type cast, so question is, how should I be returning the value of aCStr?
Thanks in advance.
Solved my problem, was simple error of not changing one important detail before executing call i was looking for a return type of short but had String in native declaration.
I had
private native String getCheckSum(String a);
it should have been
`private native short getCheckSum(String a);`
My call was / is
short result = getCheckSum(A);
Worked fine after correcting my mistake.
for those interested my c++ code
#include <jni.h> // JNI header provided by JDK
#include "ekmCheckSum.h"
#include <iostream> // C++ standard IO header
using namespace std;
//---------------------------------------------------------------------------
void ekmCheckSum() {
}
static const unsigned short ekmCrcLut[256] = {
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
};
//---------------------------------------------------------------------------
unsigned short ekmCheckCRC16(const unsigned char *dat, unsigned short len)
{
unsigned short crc = 0xffff;
while (len--)
{
crc = (crc >> 8 ) ^ ekmCrcLut[(crc ^ *dat++) & 0xff];
}
crc = (crc << 8 ) | (crc >> 8);
crc &= 0x7f7f;
return crc;
}
//---------------------------------------------------------------------------
// Implementation of the native method getCheckSum()
extern "C"
JNIEXPORT unsigned short JNICALL
Java_com_[project name]_ekmV4Fields_getCheckSum(JNIEnv *env, jobject thiz, jstring a) {
const char * aCStr = env->GetStringUTFChars(a, NULL);
if(NULL == aCStr)
return NULL;
unsigned short crc = ekmCheckCRC16(reinterpret_cast<const unsigned char *>(aCStr), strlen(aCStr));
return crc;
}
my .h file contains
#ifndef PROJECT_NAME_EKMCHECKSUM_H
#define PROJECT_NAME_EKMCHECKSUM_H
class ekmCheckSum
{
private:
public:
ekmCheckSum();
unsigned short ekmCheckCRC16(const unsigned char *dat, unsigned short len);
};
#endif //PROJECT_NAME_EKMCHECKSUM_H
my java file includes
static {System.loadLibrary("ekmCheckSum");}
private native short getCheckSum(String a);
public void SetEkmFieldValueStrings(String A, String B)
{
/* if length of A is less than 250 chars, read is no good, discard
* NOTE: both Strings A and B will need to be validated for checksum
* TODO check A & B if checksum is correct
* */
boolean _aOk = false, _bOk=false;
short result = getCheckSum(A);
...
...
I am deploying a program and encountered error of
Caused by: java.lang.Exception: java.lang.UnsatisfiedLinkError:
com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
I managed to load the dll but I feel like something has caused the string to not be converted correctly and caused the error. The following is the JNI code I am currently testing to deploy on Karaf :
JNI Codes>>>JAVA and c++
JniGeoDbReader.class
package com.package.JniClass;
public final class JniGeoDbReader {
private JniGeoDbReader() { }
public static native String openGeoDb(); }
ServiceClass.class <--- This class is the simplified version
import com.package.JniClass.JniGeoDbReader;
public class ServiceClass{
public void fetchResponse(){
System.load("D:\\DLL_PATH\\com_package_jniGeoDbReader.dll");
LOGGER.info(">>>>>>>>>>>>>>>>> {}", JniGeoDbReader.openGeoDb());
}
}
com_package_JniClass_JniGeoDbReader.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_package_JniClass_JniGeoDbReader */
#ifndef _Included_com_package_JniClass_JniGeoDbReader
#define
_Included_com_package_JniClass_JniGeoDbReader_JniClass_JniGeoDbReader
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_package_JniClass_JniGeoDbReader
* Method: openGeoDb
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_package_JniClass_JniGeoDbReader_openGeoDb
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
dllmain.cpp <--I got this code from somewhere else
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "com_package_JniClass_JniGeoDbReader.h"
#include <string>
using namespace std;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
JNIEXPORT jstring JNICALL
Java_com_package_JniClass_JniGeoDbReader_openGeoDb
(JNIEnv *env , jobject obj) {
string message = "Welcome to JNI";
int byteCount = message.length();
const jbyte* pNativeMessage = reinterpret_cast<const jbyte*>
(message.c_str());
jbyteArray bytes = env->NewByteArray(byteCount);
env->SetByteArrayRegion(bytes, 0, byteCount, pNativeMessage);
// find the Charset.forName method:
// javap -s java.nio.charset.Charset | egrep -A2 "forName"
jclass charsetClass = env->FindClass("java/nio/charset/Charset");
jmethodID forName = env->GetStaticMethodID(
charsetClass, "forName", "
(Ljava/lang/String;)Ljava/nio/charset/Charset;");
jstring utf8 = env->NewStringUTF("UTF-8");
jobject charset = env->CallStaticObjectMethod(charsetClass,
forName, utf8);
// find a String constructor that takes a Charset:
// javap -s java.lang.String | egrep -A2 "String\(.*charset"
jclass stringClass = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(
stringClass, "<init>", "([BLjava/nio/charset/Charset;)V");
jstring jMessage = reinterpret_cast<jstring>(
env->NewObject(stringClass, ctor, bytes, charset));
return jMessage; }
I got the code in the cpp from here: Send C++ string to Java via JNI. I would like to do something similar, that is to return a string without accepting any parameters. But for some reason, it is throwing error. Please guide me in what causes this error and which part of this code I should change. Thank you.
UPDATE
Here is the full stacktrace:
at com.sun.proxy.$Proxy116.fetchCatalogue(Unknown Source)
at com.package.ArcGisDiscoveryJob$CatalogueTask.call(ArcGisDiscoveryJob.java:485)
at com.package.ArcGisDiscoveryJob$CatalogueTask.call(ArcGisDiscoveryJob.java:450)
at com.package.BaseTaskExecutor.invoke(BaseTaskExecutor.java:84)
at com.package.ArcGisDiscoveryJob.traverse(ArcGisDiscoveryJob.java:131)
at com.package.ArcGisDiscoveryJob.run(ArcGisDiscoveryJob.java:224)
at com.package.BaseScheduler$1.run(BaseScheduler.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.Exception: java.lang.UnsatisfiedLinkError: com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
at com.package.service.rest.impl.ArcGisClientProxy$1.call(ArcGisClientProxy.java:161)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
... 3 more
Caused by: java.lang.UnsatisfiedLinkError: com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
at com.package.JniClass.JniGeoDbReader.openGeoDb(Native Method)
at com.package.service.rest.impl.ServiceClass.fetchResponse(ServiceClass.java:364)
at com.package.service.rest.impl.ServiceClass.fetchCatalogue(ServiceClass.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.package.service.rest.impl.ArcGisClientProxy.callEndPoint(ArcGisClientProxy.java:241)
at com.package.service.rest.impl.ArcGisClientProxy.access$000(ArcGisClientProxy.java:32)
at com.package.service.rest.impl.ArcGisClientProxy$1.call(ArcGisClientProxy.java:155)
... 4 more
Your header file and your CPP code don't match. The header declares jclass for the second function parameter, but the implementation has jobject. JNI itself would not care because jclass is the same as jobject, but your compiler will not recognize the function, because of the different parameter declaration. Therefore it will not see the extern "C" for the function and export it with CPP name mangling, and Java will not find it.
Edit: hadn't seen #user207421's comment, and while it is important that you always regenerate the header file if something changes in your native method, it won't help in your case because your header already matches the Java code. You also have to change your implementation to match the header.
I've tried creating a simple jni test app from "Beginning Android Games 3rd Ed" book. I copy-pasted the code, but when I try to link with ndk-build, I get the following error messages:
D:\apps\android\projects\NDK\app\src\main\java>ndk-build
[armeabi-v7a] Compile++ arm : jniutils <= jniutils.cpp
jni/jniutils.cpp:8:52: error: format string is not a string literal (potentially insecure)
[-Werror,-Wformat-security]
__android_log_print(ANDROID_LOG_VERBOSE, cTag, cMessage);
^~~~~~~~
jni/jniutils.cpp:8:52: note: treat the string as an argument to avoid this
__android_log_print(ANDROID_LOG_VERBOSE, cTag, cMessage);
^
"%s",
1 error generated.
make: *** [obj/local/armeabi-v7a/objs/jniutils/jniutils.o] Error 1
If I try to treat these errors as warnings and suppress these with the following lines in android.mk / application.mk:
APP_CFLAGS += -Wno-error=format-security
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
Then I get this error:
D:\apps\android\projects\NDK\app\src\main\java>ndk-build
[armeabi-v7a] SharedLibrary : libjniutils.so
clang++.exe: error: no such file or directory: '遶上・llog'
make: *** [obj/local/armeabi-v7a/libjniutils.so] Error 1
Which I guess is just some garbage from memory, like a string /variable hasn't been addressed correctly.
I'm very new to jni, so I'm at a bit of a loss of how to troubleshoot this.
Code follows:
JniUtils.java
package com.badlogic.androidgames.ndk;
import java.nio.ByteBuffer;
public class JniUtils {
static {
System.loadLibrary("jniutils");
}
public static native void log(String tag, String message);
public static native void copy(ByteBuffer dst, float[] src, int offset, int len);
}
jniutils.cpp
#include <android/log.h>
#include <string.h>
#include "jniutils.h"
JNIEXPORT void JNICALL Java_com_badlogic_androidgames_ndk_JniUtils_log
(JNIEnv *env, jclass clazz, jstring tag, jstring message) {
const char *cTag = env-> GetStringUTFChars(tag, 0);
const char *cMessage = env-> GetStringUTFChars(message, 0);
__android_log_print(ANDROID_LOG_VERBOSE, cTag, cMessage);
env-> ReleaseStringUTFChars(tag, cTag);
env-> ReleaseStringUTFChars(message, cMessage);
}
JNIEXPORT void JNICALL Java_com_badlogic_androidgames_ndk_JniUtils_copy
(JNIEnv *env, jclass clazz, jobject dst, jfloatArray src, jint offset, jint len) {
unsigned char* pDst = (unsigned char*)env-> GetDirectBufferAddress(dst);
float* pSrc = (float*)env-> GetPrimitiveArrayCritical(src, 0); memcpy(pDst,
pSrc + offset, len * 4);
env-> ReleasePrimitiveArrayCritical(src, pSrc, 0);
}
application.mk
APP_ABI := armeabi-v7a x86
APP_PLATFORM := android-19
android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jniutils
LOCAL_LDLIBS := − llog
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := jniutils.cpp
include $(BUILD_SHARED_LIBRARY)
I have a java Web application to collect some data from local and remote windows machine. I am using wmi connection to connect to machine.
I use tomcat as Web server. For wmi connection i wrote c++ code and connect java and c++ using JNI. When i start the server and enter login details, tomcat crashes.
In log file error is..
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd1e6e2931, pid=3940, tid=0x0000000000000a6c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [Verify_.dll+0x2931]
#
I am using tomcat 8.5.28 and jdk1.8.0_162
Here is my java code: Verify_.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Verify_ extends HttpServlet{
public native int connect();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.loadLibrary("Verify_");
Verify_ verify = new Verify_();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String ServerName = request.getParameter("servername");
String UserName = request.getParameter("username");
String Password = request.getParameter("password");
int status = verify.connect();
if(status == 0)
out.println("Connected to " + ServerName);
else if(status == 1)
out.println("failed to initialize CoInitializeEx");
else if(status == 2)
out.println("failed to initialize CoInitializeSecurity");
else if(status == 3)
out.println("failed to initialize CoCreateInstance");
else if(status == 4)
out.println("failed to connect to Server");
else
out.println(status);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request,response);
}}
Here is JNI interface code: Verify_.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Verify_ */
#ifndef _Included_Verify_
#define _Included_Verify_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Verify_
* Method: connect
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Verify_1_connect
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Here is C++ code: Verify_.cpp
#include <iostream>
#include <wbemidl.h>
#include <conio.h>
#include <windows.h>
#include <comdef.h>
#include <wincred.h>
#include <string.h>
#include "Verify_.h"
#pragma comment(lib, "credui.lib")
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ole32.lib")
#define _WIN32_DCOM
JNIEXPORT jint JNICALL Java_Verify_1_connect (JNIEnv *, jobject){
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2"));
wcscpy(pszUserName, BSTR(L"Administrator"));
wcscpy(pszPassword, BSTR(L"qwerty1233"));
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) {
return 1;
}
hr = CoInitializeSecurity(
NULL, // Security descriptor
-1, // COM negotiates authentication service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
NULL, // Authentication info
EOAC_NONE, // Additional capabilities of the client or server
NULL); // Reserved
if (FAILED(hr)) {
CoUninitialize();
return 2;
}
IWbemLocator *pLoc = 0;
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hr)){
CoUninitialize();
return 3;
}
IWbemServices *pSvc = NULL;
// Connect to the root\default namespace with the current user.
hr = pLoc->ConnectServer(
pszRoot, //namespace
pszUserName, // User name
pszPassword, // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc); // IWbemServices proxy
if (FAILED(hr)){
pLoc->Release();
CoUninitialize();
return 4;
}
// pSvc->Release();
// pLoc->Release();
CoUninitialize();
return 0;
}
i am trying for past 5 days. Pls help me. If there is any other way tell me..
Thanks in advance
0xc0000005
-> Access violation, mostly because using a NULL pointer.
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2"));
You have to allocate memory when using wcscpy. So, the wcscopy is called with an invalid (random) address (in Debugmode: With NULL).
I'm not sure you are handling BSTR correct (I did not know BSTR). See definition of BSTR:
typedef OLECHAR *BSTR;
Why not assign directly?
pszRoot = BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2");
thanks Ralph Erdt
i changed this part
BSTR pszRoot,pszUserName,pszPassword;
pszRoot = ::SysAllocString(L"\\\\172.21.111.250\\ROOT\\cimv2");
pszUserName = ::SysAllocString(L"Administrator");
pszPassword = ::SysAllocString(L"qwerty1233");
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.