I am trying to create a servlet web application which creates active directory application, So am calling the native method using java native interface and it produces this error. The user is created when calling the c code but when calling the same c code with jni interface am getting A device attached to the system is not functioning error. C code.
#include "atlbase.h"
#include <atlstr.h>
void CreateUserFromADs(LPCWSTR pwszFirstName, LPCWSTR pwszLastName, LPCWSTR pwszSAMAccountName, LPCWSTR pwszInitialPassword);
LPCWSTR jstring2string(JNIEnv* env, jstring jStr) {
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t)env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char*)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
std::wstring converted = std::wstring(ret.begin(), ret.end());
return converted.c_str();
}
JNIEXPORT void JNICALL Java_Test_createUser
(JNIEnv* env, jobject obj, jstring pwszFirstName, jstring pwszLastName, jstring pwszSAMAccountName, jstring pwszInitialPassword) {
LPCWSTR convertedFirstname = jstring2string(env, pwszFirstName);
LPCWSTR convertLastName = jstring2string(env, pwszLastName);
LPCWSTR convertAccname = jstring2string(env, pwszSAMAccountName);
LPCWSTR convPassword = jstring2string(env, pwszInitialPassword);
CreateUserFromADs(convertedFirstname, convertLastName, convertAccname, convPassword);
}
void CreateUserFromADs(LPCWSTR pwszFirstName, LPCWSTR pwszLastName, LPCWSTR pwszSAMAccountName, LPCWSTR pwszInitialPassword)
{
HRESULT hr;
CoInitialize(NULL);
IADsContainer* pUsers = NULL;
std::cout << "Intially pUsers : " << pUsers << std::endl;
hr = ADsOpenObject(L"LDAP://WIN-F94H2MP3UJR.Test.local/CN=Users,DC=Test,DC=local", L"Administrator", L"pass@12",
ADS_SECURE_AUTHENTICATION, // For secure authentication
IID_IADsContainer,
(void**)&pUsers);
// Here pUser has some values now.
std::cout << "After :" << pUsers << std::endl;
if (SUCCEEDED(hr))
{
IDispatch* __stdcall pDisp = NULL;
std::cout << "Initially pdisp:" << pDisp << std::endl;
CComBSTR sbstrName = "CN=";
sbstrName = pwszFirstName;
// Create the new object in the User folder.
hr = pUsers->Create(CComBSTR("user"), sbstrName, &pDisp);
std::cout << "After pdisp:" << pDisp << std::endl;
if (SUCCEEDED(hr))
{
IADsUser* padsUser = NULL;
hr = pDisp->QueryInterface(IID_IADsUser, (void**)&padsUser);
std::cout << "After padsUser:" << padsUser << std::endl;
if (SUCCEEDED(hr))
{
CComBSTR sbstrProp;
CComVariant svar;
//Pre windows 2000
svar = pwszSAMAccountName;
sbstrProp = "sAMAccountName";
hr = padsUser->Put(sbstrProp, svar);
hr = padsUser->SetInfo();
// newer syntax
sbstrProp = "userPrincipalName";
hr = padsUser->Put(sbstrProp, svar);
hr = padsUser->SetInfo();
//This one sets the firstname.
hr = padsUser->Put(CComBSTR("givenName"), (CComVariant)pwszFirstName);
hr = padsUser->SetInfo();
hr = padsUser->Put(CComBSTR("displayName"), (CComVariant)pwszFirstName);
hr = padsUser->SetInfo();
// This one sets the last name here.
hr = padsUser->Put(CComBSTR("sn"), (CComVariant)pwszLastName);
hr = padsUser->SetInfo();
// Set Passoword here.
hr = padsUser->SetPassword(CComBSTR(pwszInitialPassword));
svar.Clear();
sbstrProp = "userAccountControl";
hr = padsUser->Get(sbstrProp, &svar);
if (SUCCEEDED(hr))
{
svar = svar.lVal & ~(ADS_UF_ACCOUNTDISABLE |
ADS_UF_PASSWD_NOTREQD |
ADS_UF_DONT_EXPIRE_PASSWD);
hr = padsUser->Put(sbstrProp, svar);
hr = padsUser->SetInfo();
}
hr = padsUser->put_AccountDisabled(VARIANT_FALSE);
hr = padsUser->SetInfo();
padsUser->Release();
}
pDisp->Release();
}
pUsers->Release();
}
CoUninitialize();
std::string message = std::system_category().message(hr);
std::cout << message << std::endl;
}
Java code which imports the dll file and call the native method and produces the error.
public class Test {
static{
System.loadLibrary("testNativeMethods");
}
public native void createUser(String firstName,String lastName,String accountName,String password );
public static void main(String[] args) {
Test t = new Test();
t.createUser("maggi","dsds","maggi01","User@12");
}
}
CodePudding user response:
Here there is error in converting the jstring to the LPWCSTR . Use this function to convert jstring to LPWCSTR
LPCWSTR jstring2LPWSTR(JNIEnv* env, jstring jStr) {
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t)env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char*)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
LPWSTR ws = new wchar_t[s.size() 1]; // 1 for zero at the end
copy(ret.begin(), ret.end(), ws);
ws[ret.size()] = 0; // zero at the end
return ws;
}