Passing string varaible to native method - java

I'm trying to pass two strings to a native method, the method doesn't execute while passing strings like this
String pathDir=request.getParameter("path");
String user=request.getParameter("user");
obj.modifyACL(pathDir, user, 'a', 1);
The same method executes well when passing strings as this
obj.modifyACL("C:/Users/margie/Desktop/tb.h", "SYSTEM", 'r', 2);
The value of pathDir and users are not empty while getting the HTML element value. I used
pw.println(user+pathDir);
and it shows like this
SYSTEM C:\Users\margie\Desktop\tb.h
This is native method
PACL SetPerm(LPCTSTR file, string user, char val, int perm, PACL pOldDACL)
{
EXPLICIT_ACCESS eas[1];
PACL pacl = 0;
DWORD rc;
long long int access_val;
LPSTR use = const_cast<char *>(user.c_str());
if(val=='R'||val=='r')
access_val=0x80000000; //GENERIC_READ
if(val=='W'||val=='w')
access_val=0x40000000; //GENERIC_WRITE
if(val=='A'||val=='a')
access_val=0x10000000; //GENERIC_ALL
if(perm==1)
{
eas[0].grfAccessPermissions = access_val;
eas[0].grfAccessMode = GRANT_ACCESS;
eas[0].grfInheritance = NO_INHERITANCE;
eas[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eas[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eas[0].Trustee.ptstrName = use;
}
else if(perm==2)
{
eas[0].grfAccessPermissions = access_val;
eas[0].grfAccessMode = DENY_ACCESS;
eas[0].grfInheritance = NO_INHERITANCE;
eas[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eas[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eas[0].Trustee.ptstrName = use;
}
rc = SetEntriesInAcl(1, eas, pOldDACL, &pacl);
if (rc != ERROR_SUCCESS)
{
printf("ERROR---------SetEntriesInAcl: %u\n", rc);
return NULL;
}
rc = SetNamedSecurityInfo((LPSTR)file, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL, NULL, pacl, NULL);
if (rc != ERROR_SUCCESS)
{
printf("ERROR---------SetNamedSecurityInfo: %u\n", rc);
return NULL;
}
cout << "----------------PERMISSION GRANTED----------------\n";
return pacl;
}
JNIEXPORT void JNICALL Java_total_modifyACL(JNIEnv *env, jobject thisObj, jstring inJNIStr, jstring inStr, jchar chr, jint num)
{
cout<<"Inside modifyACL()\n";
PSID pSidOwner = NULL;
DWORD dwRtnCode = 0, dwAcctName = 1, dwDomainName = 1;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pOldDACL = NULL;
char ch;
char tp=(char)chr;
int val,i,aceNum;
int perm=(int)num;
const char *input = env->GetStringUTFChars(inJNIStr, NULL);
const char *user = env->GetStringUTFChars(inStr, NULL);
// Get the handle of the file object.
hFile = CreateFile(
input,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
cout << "CreateFile error = " << dwErrorCode<<". Possibly NO file exist in the given path or READ Access denied.";
exit;
}
// Get the SID of the file.
dwRtnCode = GetSecurityInfo(
hFile,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
&pSidOwner,
NULL,
&pOldDACL,
NULL,
&pSD);
// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
cout << "GetSecurityInfo error = " << dwErrorCode;
}
pOldDACL = SetPerm(input,user,tp,perm,pOldDACL); //passing pOldDACL to add the ACE in exixting ACE.
}
What should I do to make modifyACL() work on passing user input string?

Related

Libspeexjni JNI integration

Those are Java functions in question:
targetFunctionPtr1 is public static native long nInitSpxEncoder();
targetFunctionPtr is public static native long nEncodeBuffer(long j12, short[] sArr, byte[] bArr, long j13);
Sample pseudo Java code
long nInitSpxEncoder = LibSpeex.nInitSpxEncoder();
long nEncodeBuffer = LibSpeex.nEncodeBuffer(nInitSpxEncoder, sArr, bArr, 65536);
called below via JNI
char b[16]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x00};
jinput = env->NewStringUTF(b);
jclass stringClass = env->FindClass("java/lang/String");
jmethodID getBytesMId = env->GetMethodID(stringClass, "getBytes", "()[B");
in1 = (jbyteArray)env->CallObjectMethod( jinput, getBytesMId);
jlong init;
init = targetFunctionPtr1(env, CallerObj1);
jshort outCArray[] = {100};
jshortArray retval = env->NewShortArray(10000); // allocate
env->SetShortArrayRegion(retval, 0 , 1, outCArray);
nenc = targetFunctionPtr(env, CallerObj, init, retval, in1, 10);
Don't get why above segfaults. It calls init, that works, but in second call nEncodeBuffer it segfaults. I see in debugger it loads byte array and shorts array, but cannot figure out why it does not return, just loops until segfault.
I mean I call it via JNI but I would expect targetFunctionPtr to return. It seems it loops somehow, until segmentation occurs.
This is sample implementation of the JNI in Java
long nInitSpxEncoder = LibSpeex.nInitSpxEncoder();
if (nInitSpxEncoder != 0) {
int nGetEncoderFrameSize = (int) LibSpeex.nGetEncoderFrameSize(nInitSpxEncoder);
System.err.println(String.format("Frame size = %d", Integer.valueOf(nGetEncoderFrameSize)));
short[] sArr = new short[nGetEncoderFrameSize];
AudioRecord audioRecord2 = null;
byte[] bArr3 = bArr2;
long j12 = 0;
while (j12 < this.f13733d) {
try {
synchronized (this) {
if (audioRecord2 != this.f13731b) {
Log.i("AudioPttRecorder", "source changed");
}
audioRecord = this.f13731b;
}
if (audioRecord == null || audioRecord.read(sArr, 0, nGetEncoderFrameSize) != nGetEncoderFrameSize) {
break;
}
if (this.f13730a != null) {
this.f13730a.a(j12, a(nGetEncoderFrameSize, sArr));
}
long j13 = j12;
int i12 = nGetEncoderFrameSize;
short[] sArr2 = sArr;
long nEncodeBuffer = LibSpeex.nEncodeBuffer(nInitSpxEncoder, sArr, bArr, 65536);
if (nEncodeBuffer >= 0) {
Log.d("AudioPttRecorder", String.format("Write packet len=%d", Long.valueOf(nEncodeBuffer)));
bArr3[0] = (byte) (255 & nEncodeBuffer);
bArr3[1] = (byte) (nEncodeBuffer >> 8);
byte[] bArr4 = bArr3;
bufferedOutputStream.write(bArr4, 0, 2);
bufferedOutputStream.write(bArr, 0, (int) nEncodeBuffer);
bArr3 = bArr4;
nGetEncoderFrameSize = i12;
sArr = sArr2;
j12 = j13 + 1;
audioRecord2 = audioRecord;
} else {
throw new RuntimeException("Something wrong with encoding Speex");
}
} finally {
LibSpeex.nDestroySpxEncoder(nInitSpxEncoder);
Log.i("AudioPttRecorder", "exited");
}
}
bufferedOutputStream.flush();
Log.d("AudioPttRecorder", "finished");
return;
}
My code using JNI directly does similar.
Any ideas what is wrong with the native code?
How should I call Libspx to encode a byte array in native code?

Signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr

I'm trying to do stitching on android. I used Surf algorithm to serve as finder and I got an error like "try enable OPENCV_ENABLED_NONFREE". I use C++ native code on Android Studio and do stitching in background. I solved the surf error but now, when I test this application on real device, I get this error:
I did some research in another forum, and they say that the problem may be caused by a function that doesn't return the value it's supposed to return. Is there anyone who can help me please. This is the code:
private Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message message) {
switch (message.what) {
case HANDLER_START_STITCHING :
{
new Thread()
{
public void run()
{
AsyncTask.execute(new Runnable() {
#Override
public void run() {
String[] source=getDirectoryFilelist("null");
final File resultDir = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + File.separator + "viewwer");
// if (!resultDir.exists())
// resultDir.mkdir();
final String stitchingResultImagePath = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath()) +"/result.jpg"; // + (ANGLE-90) + ".jpg";
if( NativePanorama.jniStitching(source, stitchingResultImagePath, STITCH_IMAGE_SCALE) == 0 )
{
handler.sendMessage(handler.obtainMessage(HANDLER_SET_STITCHING_BUTTON_TEXT,"Stitching success"));
File image = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath());
File result_90 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result90.jpg");
File result_180 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result180.jpg");
File result_270 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result270.jpg");
File result_360 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result360.jpg");
Log.d("GESTION_STITCHING", result_180.toString());
/*if (ANGLE == 450) {
handler.sendMessage(handler.obtainMessage(HANDLER_FINISH_STITCHING,"Stitching success"));
}*/
if (image.exists()) {
File[] files = image.listFiles();
for (int i=0;i<files.length; i++) {
if (files[i].compareTo(result_90) == 0 || files[i].compareTo(result_180) == 0 || files[i].compareTo(result_270) == 0 || files[i].compareTo(result_360) == 0) {
} else {
files[i].delete();
}
}
}
}
else
{
handler.sendMessage(handler.obtainMessage(HANDLER_SET_STITCHING_BUTTON_TEXT,"Stitching error"));
}
}
});
}
}.start();
break;
}
and the following is the native C++ code:
JNIEXPORT jint JNICALL Java_com_priscilla_viewwer_utils_NativePanorama_jniStitching(JNIEnv *env, jclass clazz, jobjectArray source, jstring result, jdouble scale) {
clock_t beginTime, endTime;
double timeSpent;
beginTime = clock();
//init jni call java method
int i = 0;
bool try_use_gpu = true;
vector<Mat> imgs;
Mat img;
Mat img_scaled;
Mat pano;
Mat pano_tocut;
Mat gray;
const char* result_name = env->GetStringUTFChars(result, JNI_FALSE); //convert result
LOGE("result_name=%s",result_name);
LOGE("scale=%f",scale);
int imgCount = env->GetArrayLength(source); //img count
LOGE("source imgCount=%d",imgCount);
for(i=0;i<imgCount;i++)
{
jstring jsource = (jstring)(env->GetObjectArrayElement(source, i));
const char* source_name = env->GetStringUTFChars(jsource, JNI_FALSE); //convert jsource
LOGE("Add index %d source_name=:%s", i, source_name);
img=imread(source_name);
Size dsize = Size((int)(img.cols*scale),(int)(img.rows*scale));
img_scaled = Mat(dsize,CV_32S);
resize(img,img_scaled,dsize);
imgs.push_back(img_scaled);
env->ReleaseStringUTFChars(jsource, source_name); //release convert jsource
}
img.release();
pano = stitchingImages(imgs);
for(i=0;i<imgs.size();i++)
{
imgs[i].release();
}
//cut black edges
//LOGE("stitching success,cutting black....");
pano_tocut = pano;
cvtColor(pano_tocut, gray, CV_BGR2GRAY);
Rect startROI(0,0,gray.cols,gray.rows); // start as the source image - ROI is the complete SRC-Image
cropLargestPossibleROI(gray,pano_tocut,startROI);
gray.release();
imwrite(result_name, pano_tocut);
pano.release();
pano_tocut.release();
env->ReleaseStringUTFChars(result, result_name); //release convert result
endTime = clock();
timeSpent = (double)(endTime - beginTime) / CLOCKS_PER_SEC;
LOGE("success,total cost time %f seconds",timeSpent);
// env->CallVoidMethod(clazz, javaMethodRef, timeSpent);
return 0;
}
I came cross this issues either, and I found it was violating strict aliasing.
cause by casting~
problem:
uint32_t i32 = *((uint32_t*)m_data);
solution:
uint32_t i32 = 0;
char* p = (char*)&i32;
for(int i =0;i < 4;i++)
{
p[i] = m_data[i];
}

why doesn't this java method work? it should eliminate empty spaces in Strings

here's the method :
public static String normalizza(String x) {
for (int i = x.length(); i > 0; i--) {
if (x.substring(i, x.length()).equalsIgnoreCase(" ")) {
x = x.substring(0, i);
}
}
return x;
}
i should read a String from a random access file and eliminate empty spaces to find the object position
these are the attributes of the class :
public class Iscritto {
private int id;
private String nome;
private String cognome;
private String dataNascita;
this is the search method for the attribute "nome" ( the method "normalizza" works with this one ) :
private static void cercaNome() {
Iscritto a = new Iscritto();
try {
File file = new File("C:\\temp\\iscritti.dat");
RandomAccessFile ra = new RandomAccessFile(file, "r");
String nome = JOptionPane.showInputDialog("Inserisci nome da cercare:");
ra.seek(0);
a.leggi(ra);
String nomeControllato = a.getNome();
nomeControllato = normalizza(nomeControllato);
int conta = 0;
if (nomeControllato.equalsIgnoreCase(nome)) {
int b = (int) ra.getFilePointer() - 2;
int position = b / 153;
ra.seek(position * 153);
a.leggi(ra);
System.out.println("iscritto: " + a);
} else {
while (!nomeControllato.equalsIgnoreCase(nome)) {
conta++;
ra.seek(conta * 153);
a.leggi(ra);
nomeControllato = a.getNome();
nomeControllato = normalizza(nomeControllato);
if (nomeControllato.equalsIgnoreCase(nome)) {
int b = (int) ra.getFilePointer() - 2;
int position = b / 153;
ra.seek(position * 153);
a.leggi(ra);
System.out.println("iscritto: " + a);
}
}
}
ra.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
this is the search method for the attribute "data" ( normalizza doesn't work for this one ) :
private static void cercaData() {
Iscritto a = new Iscritto();
try {
File file = new File("C:\\temp\\iscritti.dat");
RandomAccessFile ra = new RandomAccessFile(file, "r");
String data = JOptionPane.showInputDialog("Inserisci data da cercare (example : 12-MAG-2018):");
ra.seek(0);
a.leggi(ra);
String dataControllata = a.getDataNascita();
dataControllata = normalizza(dataControllata);
int conta = 0;
if (dataControllata.equalsIgnoreCase(data)) {
int b = (int) ra.getFilePointer() - 2;
int position = b / 153;
ra.seek(position * 153);
a.leggi(ra);
System.out.println("iscritto: " + a);
} else {
while (!dataControllata.equalsIgnoreCase(data)) {
conta++;
ra.seek(conta * 153);
a.leggi(ra);
dataControllata = a.getDataNascita();
dataControllata = normalizza(dataControllata);
if (dataControllata.equalsIgnoreCase(data)) {
int b = (int) ra.getFilePointer() - 2;
int position = b / 153;
ra.seek(position * 153);
a.leggi(ra);
System.out.println("iscritto: " + a);
}
}
}
ra.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if i search a "data" and it's not the last of the file it will give me an infinite "null" output
If you want to eliminate empty spaces at the end of your String, simply use the trim() method.
System.out.println(" my String ".trim()); // prints 'my String'
If you need to eliminate all whitespaces in your string, then use replace(String, String)
System.out.println(" my String ".replace(" ", "")); // prints 'myString'
Assuming you have a reason not to use String.trim(), you could do a much simpler implementation:
start i from the end of string, and look backward at each .charAt(i) until != ' '. Then substring just once, cutting after that non-space char.

Pentaho User defined Java Class - Datatype Conversion Error

I am currently trying to do nothing else, than getting all row values from a some columns and sum them together. That part works fine, it even worked out once :D. But when deleting the data and trying to run the job again I got a Casting error. For your information, my current attempt to this solution is:
Read in data from Excel (casting everything to Integer) => select all important fields (select values) => Add constants (append result field) => UDJC (sum up each row from the data set) => Update Database
I don't really understand why, since I am using all Integers. Maybe someone here can help me, I guess it is something dumb I am missing.
This is my Excel input
recasting them inside select values
My User defined Java Class code looks like this
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException {
if (first) {
first = false;
}
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
// It is always safest to call createOutputRow() to ensure that your output row's Object[] is large
// enough to handle any new fields you are creating in this step.
r = createOutputRow(r, data.outputRowMeta.size());
/* TODO: Your code here. (See Sample)
// Get the value from an input field
String foobar = get(Fields.In, "a_fieldname").getString(r);
foobar += "bar";
// Set a value in a new output field
get(Fields.Out, "output_fieldname").setValue(r, foobar);
*/
int result_value = 0;
int value10 = get(Fields.In, "int_10").getInteger(r).intValue();
int value20 = get(Fields.In, "int_20").getInteger(r).intValue();
int value30 = get(Fields.In, "int_30").getInteger(r).intValue();
int value40 = get(Fields.In, "int_40").getInteger(r).intValue();
int value50 = get(Fields.In, "int_50").getInteger(r).intValue();
int value60 = get(Fields.In, "int_60").getInteger(r).intValue();
int value70 = get(Fields.In, "int_70").getInteger(r).intValue();
int value80 = get(Fields.In, "int_80").getInteger(r).intValue();
int value90 = get(Fields.In, "int_90").getInteger(r).intValue();
int value100 = get(Fields.In, "int_100").getInteger(r).intValue();
int value110 = get(Fields.In, "int_110").getInteger(r).intValue();
int value120 = get(Fields.In, "int_120").getInteger(r).intValue();
int value130 = get(Fields.In, "int_130").getInteger(r).intValue();
int value140 = get(Fields.In, "int_140").getInteger(r).intValue();
int value150 = get(Fields.In, "int_150").getInteger(r).intValue();
int value160 = get(Fields.In, "int_160").getInteger(r).intValue();
int value170 = get(Fields.In, "int_170").getInteger(r).intValue();
int value180 = get(Fields.In, "int_180").getInteger(r).intValue();
int value190 = get(Fields.In, "int_190").getInteger(r).intValue();
int value200 = get(Fields.In, "int_200").getInteger(r).intValue();
int value210 = get(Fields.In, "int_210").getInteger(r).intValue();
int value220 = get(Fields.In, "int_220").getInteger(r).intValue();
result_value = (value10 + value20 + value30 + value40 + value50 + value60 +
value70 + value80 + value90 + value100 + value110 + value120 +
value130 + value140 + value150 + value160 + value170 + value180 +
value190 + value200 + value210 + value220);
get(Fields.Out, "neutral_or_personal").setValue(r, result_value);
// Send the row on to the next step.
putRow(data.outputRowMeta, r);
return true;
}

Retrieving sidHistory from LDAP with Java

I can retrieve objectSID and many other attributes without error, but not sidHistory (I need sidHistory to see which account in domain A corresponds to an account in domain B).
Here's the code that works for most attributes, including objectSID:
void dumpCSV(Attributes attrs, String[] displayList, Logger lg) {
// Assume we're only dealing with single valued attributes (for now)
StringBuilder sb = new StringBuilder();
for (String attName : displayList) {
String name = attName.trim().toLowerCase();
Attribute att = attrs.get(name);
if (sb.length() > 0)
sb.append(",");
if (att != null) {
String v = "?";
try {
if ((name.equals("objectsid")) || (name.equals("sidhistory")))
v = binString(att);
else {
v = (String) att.get();
if (name.equals("pwdlastset") || name.equals("lastlogontimestamp") || name.equals("lastlogon") || name.equals("accountexpires"))
v = TickConverter.tickDate(v);
}
sb.append(Logger.tidyString(v));
} catch (NamingException e) {
System.err.println("NamingException, " + e);
return;
}
}
}
lg.logln(sb.toString());
}
}
static String binString(Attribute att) {
try {
byte bin[] = (byte[]) att.get();
return decodeSID(bin);
} catch (NamingException e) {
System.err.println("NamingException, " + e);
return "?";
}
}
// taken from http://www.adamretter.org.uk/blog/entries/LDAPTest.java, in turn borrowed from Oracle docs
public static String decodeSID(byte[] sid) {
final StringBuilder strSid = new StringBuilder("S-");
// get version
final int revision = sid[0];
strSid.append(Integer.toString(revision));
//next byte is the count of sub-authorities
final int countSubAuths = sid[1] & 0xFF;
//get the authority
long authority = 0;
//String rid = "";
for(int i = 2; i <= 7; i++) {
authority |= ((long)sid[i]) << (8 * (5 - (i - 2)));
}
strSid.append("-");
strSid.append(Long.toHexString(authority));
//iterate all the sub-auths
int offset = 8;
int size = 4; //4 bytes for each sub auth
for(int j = 0; j < countSubAuths; j++) {
long subAuthority = 0;
for(int k = 0; k < size; k++) {
subAuthority |= (long)(sid[offset + k] & 0xFF) << (8 * k);
}
strSid.append("-");
strSid.append(subAuthority);
offset += size;
}
return strSid.toString();
}
If I try to retrieve sidHistory using this, tyhe value I get is "?".
Even if I use a namingEnumeration, as I think I probably should, I get "Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException: Vector Enumeration", probably because I am trying to save it to the wrong typoe (and I've tried a few different types).
snippet is :
String v;
NamingEnumeration nenum = att.getAll();
while (nenum.hasMore()) {
v = "";
if (name.equals("objectsid")) {
v = binString(att);
nenum.next();
} else if (name.equals("sidhistory")) {
nenum.next();
String[] vv = ((String[]) nenum.next());
v = vv[0];
} else
v = (String) nenum.next();
if (name.equals("pwdlastset") || name.equals("lastlogontimestamp") || name.equals("lastlogon") || name.equals("accountexpires"))
v = TickConverter.tickDate(v);
lg.logln(name + "=" + Logger.tidyString(v));
}
We used some code similar to:
We note we saw it at http://tomcatspnegoad.sourceforge.net/xref/net/sf/michaelo/tomcat/realm/ActiveDirectoryRealm.html#L566
...
Attribute sidHistory = roleAttributes.get("sIDHistory;binary");
List<String> sidHistoryStrings = new LinkedList<String>();
if (sidHistory != null)
{
NamingEnumeration<?> sidHistoryEnum = sidHistory.getAll();
while (sidHistoryEnum.hasMore())
{
byte[] sidHistoryBytes = (byte[]) sidHistoryEnum.next();
sidHistoryStrings.add(new Sid(sidHistoryBytes).toString());
}
...
}
sidHistory is multi-valued and binary (octetString) is what cause most people headaches.
Hope this helps.

Categories

Resources