Java 构建HashMap<;字符串,字符串[]>;通过JNI
我有一个Java类调用本机方法ACLInfo(stringpath),这个本机方法应该返回HashMap以在Java中使用。下面是java代码Java 构建HashMap<;字符串,字符串[]>;通过JNI,java,c++,hashmap,java-native-interface,Java,C++,Hashmap,Java Native Interface,我有一个Java类调用本机方法ACLInfo(stringpath),这个本机方法应该返回HashMap以在Java中使用。下面是java代码 import java.util.*; public class test { native Map<String, String[]> ACLInfo(String s); static { System.loadLibrary("test"); } static p
import java.util.*;
public class test
{
native Map<String, String[]> ACLInfo(String s);
static
{
System.loadLibrary("test");
}
static public void main(String args[])
{
test obj = new test();
Map<String, String[]> map = obj.ACLInfo("C:/Windows/Boot/Resources/bootres.dll");
for (Map.Entry<String, String[]> entry : map.entrySet())
{
String name = entry.getKey();
System.out.println("Name:"+name);
System.out.println("Properties are:");
for(String text : entry.getValue())
{
if(text.equals("Full Control")){
System.out.println(text);
continue;
}
if(text.equals("Read"))
System.out.println(text);
if(text.equals("Write"))
System.out.println(text);
if(text.equals("Execute"))
System.out.println(text);
}
}
}
}
import java.util.*;
公开课考试
{
本机映射ACLInfo(字符串s);
静止的
{
系统加载库(“测试”);
}
静态公共void main(字符串参数[])
{
测试对象=新测试();
Map Map=obj.ACLInfo(“C:/Windows/Boot/Resources/bootres.dll”);
对于(Map.Entry:Map.entrySet())
{
字符串名称=entry.getKey();
System.out.println(“名称:”+Name);
System.out.println(“属性为:”);
for(字符串文本:entry.getValue())
{
if(text.equals(“完全控制”)){
System.out.println(文本);
继续;
}
if(text.equals(“Read”))
System.out.println(文本);
if(text.equals(“Write”))
System.out.println(文本);
if(text.equals(“执行”))
System.out.println(文本);
}
}
}
}
本机代码是
#include <iostream>
#include <jni.h>
#include <string.h>
#include <windows.h>
#include <tchar.h>
#include <Lmcons.h>
#include "test.h"
#include "accctrl.h"
#include "aclapi.h"
using namespace std;
JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv *env, jobject jobj, jstring s)
{
jobjectArray ret;
jstring jstr;
PSID pSidOwner = NULL;
BOOL bRtnBool = TRUE;
DWORD dwRtnCode = 0;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pOldDACL = NULL;
int i,aceNum;
const char* test;
std::string name,reslt;
const char* nativeString = env->GetStringUTFChars(s, 0);
LPCSTR file = nativeString;
// Get the handle of the file object.
hFile = CreateFile(
file,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Get the SID of the file.
dwRtnCode = GetSecurityInfo(
hFile,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
&pSidOwner,
NULL,
&pOldDACL,
NULL,
&pSD);
PACL pAcl = pOldDACL;
aceNum = pOldDACL->AceCount;
ret = (jobjectArray)env->NewObjectArray(3, env->FindClass("java/lang/String"), env->NewStringUTF(""));
jclass mapClass = env->FindClass("java/util/HashMap"); //HashMap class in java library
if(mapClass == NULL)
{
return NULL;
}
jsize map_len = aceNum;
jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); //constructor of HashMap class
jobject hashMap = env->NewObject(mapClass, init, map_len); //creating a new object for that class
jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;");
for (i = 0; i < aceNum; i++)
{
PACCESS_ALLOWED_ACE AceItem;
ACE_HEADER *aceAddr = NULL;
if (GetAce(pOldDACL, i, (LPVOID*)&AceItem) && GetAce(pOldDACL, i, (LPVOID*)&aceAddr))
{
LPTSTR AccountBuff = NULL, DomainBuff = NULL;
DWORD AccountBufflength = 1, DomainBufflength = 1;
PSID_NAME_USE peUse = new SID_NAME_USE;
PSID Sid = &AceItem->SidStart;
LookupAccountSid(NULL, Sid, AccountBuff, (LPDWORD)&AccountBufflength, DomainBuff, (LPDWORD)&DomainBufflength, peUse);
AccountBuff = (LPSTR)malloc(AccountBufflength * sizeof(LPSTR));
DomainBuff = (LPSTR)malloc(DomainBufflength * sizeof(LPSTR));
LookupAccountSid(NULL, Sid, AccountBuff, &AccountBufflength, DomainBuff, &DomainBufflength, peUse);
std::string acc=AccountBuff;
std::string dom=DomainBuff;
name = acc+"\\"+dom;
ACCESS_MASK Mask = AceItem->Mask;
if (((Mask & GENERIC_ALL) == GENERIC_ALL) || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS)){
reslt="Full Control";
test = reslt.c_str();
env->SetObjectArrayElement(ret,i,env->NewStringUTF(test));
env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret);
continue;
}
int j=0;
if (((Mask & GENERIC_READ) == GENERIC_READ) || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ))
{
reslt="Read";
test = reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if (((Mask & GENERIC_WRITE) == GENERIC_WRITE) || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE))
{
reslt="Write";
test = reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE) || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE))
{
reslt="Execute";
test = reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret);
}
}
return hashMap;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括“test.h”
#包括“accctrl.h”
#包括“aclapi.h”
使用名称空间std;
JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv*env、jobject jobj、jstring s)
{
jobject数组ret;
jstring-jstr;
PSID pSidOwner=NULL;
BOOL bRtnBool=TRUE;
DWORD dwRtnCode=0;
SID_NAME_USE eUse=SidTypeUnknown;
处理文件;
PSECURITY_描述符pSD=NULL;
PACL pOldDACL=NULL;
inti,aceNum;
常量字符*测试;
std::字符串名称,reslt;
const char*nativeString=env->GetStringUTFChars(s,0);
LPCSTR文件=nativeString;
//获取文件对象的句柄。
hFile=CreateFile(
文件
泛读,
文件共享读取,
无效的
开放式,
文件\u属性\u正常,
无效);
//获取文件的SID。
dwRtnCode=GetSecurityInfo(
hFile,
SE_文件_对象,
DACL_安全信息,
&普西唐纳,
无效的
&波尔达克尔,
无效的
&pSD);
PACL-PACL=pOldDACL;
aceNum=pOldDACL->acecont;
ret=(jobjectArray)env->NewObjectArray(3,env->FindClass(“java/lang/String”),env->NewStringUTF(“”);
jclass mapClass=env->FindClass(“java/util/HashMap”);//java库中的HashMap类
if(mapClass==NULL)
{
返回NULL;
}
jsize map_len=aceNum;
jmethodID init=env->GetMethodID(mapClass,”,“(I)V”);//HashMap类的构造函数
jobject hashMap=env->NewObject(mapClass、init、map_len);//为该类创建新对象
jmethodID put=env->GetMethodID(mapClass,“put”,“(Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;”;
对于(i=0;iSidStart;
LookupAccountSid(NULL,Sid,AccountBuff,(LPDWORD)和AccountBufflength,DomainBuff,(LPDWORD)和DomainBufflength,peUse);
AccountBuff=(LPSTR)malloc(AccountBufflength*sizeof(LPSTR));
DomainBuff=(LPSTR)malloc(DomainBufflength*sizeof(LPSTR));
LookupAccountSid(NULL、Sid、AccountBuff和AccountBufflength、DomainBuff和DomainBufflength、peUse);
std::string acc=AccountBuff;
std::string dom=DomainBuff;
名称=acc+“\\”+dom;
访问\u MASK MASK=AceItem->MASK;
if((屏蔽和通用访问)=通用访问)((屏蔽和文件访问)=文件访问)){
reslt=“完全控制”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,i,env->NewStringUTF(test));
env->CallObjectMethod(hashMap,put,env->NewStringUTF(name.c_str()),ret);
继续;
}
int j=0;
如果((屏蔽和通用读取)=通用读取);(屏蔽和文件通用读取)=文件通用读取))
{
reslt=“读取”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if(((掩码和通用写入)=通用写入)((掩码和文件通用写入)=文件通用写入))
{
reslt=“写入”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
if(((掩码和泛型执行)=泛型执行)| |((掩码和文件泛型执行)=文件泛型执行))
{
reslt=“执行”;
test=reslt.c_str();
env->SetObjectArrayElement(ret,j++,env->NewStringUTF(test));
}
env->CallObjectMethod(hashMap,put,env->NewStringUTF(name.c_str()),ret);
}
}
返回hashMap;
}
在运行这个java类时,它显示:java运行时环境检测到一个致命错误:pc=0x000000006d6cd4ed、pid=19504、tid=0x0000000000003da0处的异常访问违反(0xc0000005)
有什么问题吗?
我利用这篇stackoverflow帖子创建hashmap我重写了您的代码,以消除最严重的bug:
- 您对
的签名错误HashMap\put
- 您必须为放入hashmap中的每个元素创建一个
。如果重用同一对象,您将获得相同string[]
的N个副本string[]
- 无法创建数组o
JNIEXPORT jobject JNICALL Java_test_ACLInfo(JNIEnv *env, jobject jobj, jstring s) { // removed stuff jclass mapClass = env->FindClass("java/util/HashMap"); //HashMap class in java library jclass stringClass = env->FindClass("java/lang/String"); if(mapClass == NULL) { return NULL; } jsize map_len = aceNum; jmethodID init = env->GetMethodID(mapClass, "<init>", "(I)V"); //constructor of HashMap class jobject hashMap = env->NewObject(mapClass, init, map_len); //creating a new object for that class jmethodID put = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); for (i = 0; i < aceNum; i++) { // removed stuff PACCESS_ALLOWED_ACE AceItem; ACE_HEADER *aceAddr = NULL; if (GetAce(pOldDACL, i, (LPVOID*)&AceItem) && GetAce(pOldDACL, i, (LPVOID*)&aceAddr)) { // removed more stuff std::string name = std::string(AccountBuff)+"\\"+std::string(DomainBuff); std::vector<std::string> perms; ACCESS_MASK Mask = AceItem->Mask; if (((Mask & GENERIC_ALL) == GENERIC_ALL) || ((Mask & FILE_ALL_ACCESS) == FILE_ALL_ACCESS)) { perms.emplace_back("Full Control"); } else { if (((Mask & GENERIC_READ) == GENERIC_READ) || ((Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ)) { perms.emplace_back("Read"); } if (((Mask & GENERIC_WRITE) == GENERIC_WRITE) || ((Mask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE)) { perms.emplace_back("Write"); } if (((Mask & GENERIC_EXECUTE) == GENERIC_EXECUTE) || ((Mask & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE)) { perms.emplace_back("Execute"); } } env->PushLocalFrame(10); jobject ret = env->NewObjectArray(perms.size(), stringClass, nullptr); for (int i = 0; i < perms.size(); i++) { env->SetObjectArrayElement(ret, i, env->NewStringUTF(perms[i].c_str())); } env->CallObjectMethod(hashMap, put, env->NewStringUTF(name.c_str()), ret); env->PopLocalFrame(nullptr); } } return hashMap; }