1
0
mirror of https://github.com/MinimaJack/JVM-plugin.git synced 2024-11-21 13:15:56 +02:00
This commit is contained in:
Evgeniy 2019-11-29 14:29:46 +03:00
commit 18d78d42f4
22 changed files with 2717 additions and 0 deletions

61
.gitignore vendored Normal file
View File

@ -0,0 +1,61 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Tt]arget/
[Tt]argets/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

858
JVMLauncher.cpp Normal file
View File

@ -0,0 +1,858 @@
#include "stdafx.h"
#ifdef __linux__
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#endif
#include <stdio.h>
#include <include/jni.h>
#include <wchar.h>
#include "JVMLauncher.h"
#define BASE_ERRNO 7
static jobject s_threadLock;
static IAddInDefBase *gAsyncEvent = NULL;
static wchar_t *g_PropNames[] = { L"IsEnabled", L"javaHome", L"libraryDir" };
static wchar_t *g_MethodNames[] = { L"LaunchInJVM",L"LaunchInJVMP",L"LaunchInJVMPP", L"CallFInJVMB", L"CallFInJVMBP", L"CallFInJVMBPP", L"CallFInJVM", L"CallFInJVMP", L"CallFInJVMPP", L"Disable", L"AddJar" };
static wchar_t *g_PropNamesRu[] = { L"Включен", L"javaHome", L"libraryDir" };
static wchar_t *g_MethodNamesRu[] = { L"LaunchInJVM",L"LaunchInJVMP",L"LaunchInJVMPP", L"CallFInJVMB", L"CallFInJVMBP", L"CallFInJVMBPP", L"CallFInJVM", L"CallFInJVMP", L"CallFInJVMPP", L"Выключить", L"AddJar" };
static void JNICALL Java_Runner_log(JNIEnv *env, jobject thisObj, jstring info) {
wchar_t *who = L"ComponentNative", *what = L"Java";
auto wstring = JStringToWString(env, info);
WCHAR_T *err = 0;
::convToShortWchar(&err, wstring.c_str());
gAsyncEvent->ExternalEvent(who, what, err);
delete[]err;
}
bool JVMLauncher::endCall(JNIEnv* env)
{
m_JVMEnv = env;
jobject exh = m_JVMEnv->ExceptionOccurred();
if (exh) {
jclass classClass = this->m_JVMEnv->GetObjectClass(exh);
auto getClassLoaderMethod = this->m_JVMEnv->GetMethodID(classClass, "getLocalizedMessage", "()Ljava/lang/String;");
auto info = (jstring)this->m_JVMEnv->CallObjectMethod(exh, getClassLoaderMethod);
if (m_JVMEnv->IsSameObject(info, NULL)) {
jmethodID mid = env->GetMethodID(classClass, "getClass", "()Ljava/lang/Class;");
jobject clsObj = env->CallObjectMethod(exh, mid);
jclass classClass = env->GetObjectClass(clsObj);
auto getNameMethod = this->m_JVMEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
info = (jstring)this->m_JVMEnv->CallObjectMethod(clsObj, getNameMethod);
}
auto wstring = JStringToWString(env, info);
WCHAR_T *err = 0;
::convToShortWchar(&err, wstring.c_str());
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", err, 10);
delete[]err;
m_JVMEnv->ExceptionClear();
return false;
}
return true;
}
jobjectArray JVMLauncher::JNI_newObjectArray(jsize length, jclass elementClass, jobject initialElement, bool& hasError)
{
jobjectArray result;
BEGIN_JAVA
result = env->NewObjectArray(length, elementClass, initialElement);
END_JAVA
return result;
}
jclass JVMLauncher::JNI_findClass(const char* className)
{
jclass result;
BEGIN_JAVA
result = env->FindClass(className);
END_JAVA
return result;
}
void JVMLauncher::JNI_callStaticVoidMethod(jclass clazz, jmethodID methodID, bool& hasError, ...)
{
va_list args;
va_start(args, methodID);
JVMLauncher::JNI_callStaticVoidMethodV(clazz, methodID, args, hasError);
va_end(args);
}
jobject JVMLauncher::JNI_callStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
jobject result;
BEGIN_CALL
result = (*env).CallStaticObjectMethodA(clazz, methodID, args);
END_CALL
return result;
}
jboolean JVMLauncher::JNI_callStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
jboolean result;
BEGIN_CALL
result = (*env).CallStaticBooleanMethodA(clazz, methodID, args);
END_CALL
return result;
}
jint JVMLauncher::JNI_callStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
jint result;
BEGIN_CALL
result = (*env).CallStaticIntMethodA(clazz, methodID, args);
END_CALL
return result;
}
jfloat JVMLauncher::JNI_callStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
jfloat result;
BEGIN_CALL
result = (*env).CallStaticFloatMethodA(clazz, methodID, args);
END_CALL
return result;
}
jdouble JVMLauncher::JNI_callStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
jdouble result;
BEGIN_CALL
result = (*env).CallStaticDoubleMethodA(clazz, methodID, args);
END_CALL
return result;
}
void JVMLauncher::JNI_callStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError)
{
BEGIN_CALL
(*env).CallStaticVoidMethodA(clazz, methodID, args);
END_CALL
}
void JVMLauncher::JNI_callStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args, bool& hasError)
{
BEGIN_CALL
(*env).CallStaticVoidMethodV(clazz, methodID, args);
END_CALL
}
jmethodID JVMLauncher::JNI_getStaticMethodID(jclass clazz, const char* name, const char* sig, bool& hasError)
{
jmethodID result;
BEGIN_CALL
result = (*env).GetStaticMethodID(clazz, name, sig);
END_CALL
return result;
}
void JVMLauncher::addJar(const char* jarname)
{
if (m_boolEnabled) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"JVM already launched", 6);
return;
}
m_listOfJars.push_back(jarname);
}
bool JVMLauncher::verify() {
if (!m_boolEnabled) {
return true;
};
return true;
}
JVMLauncher::JVMLauncher() {
// Check for JAVA_HOME
char *pValue = getenv("JAVA_HOME");
if (pValue != NULL) {
m_JavaHome = pValue;
}
m_ProductLibDir = "d:/";
}
void JVMLauncher::LaunchJVM() {
if (m_hDllInstance == nullptr) {
if (m_JavaHome.empty()) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Set JAVA_HOME environment", 1);
return;
}
m_JvmDllLocation = m_JavaHome + "/jre/bin/server/jvm.dll";
m_hDllInstance = LoadLibraryA(m_JvmDllLocation.c_str());
}
if (m_hDllInstance == nullptr) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Cannot find JDK", 1);
return;
}
else {
if (m_GetCreatedJavaVMs == nullptr) {
m_GetCreatedJavaVMs = (GetCreatedJavaVMs)GetProcAddress(m_hDllInstance, "JNI_GetCreatedJavaVMs");
}
int n;
jint retval = m_GetCreatedJavaVMs(&m_RunningJVMInstance, 1, (jsize*)&n);
if (retval == JNI_OK)
{
if (n == 0)
{
if (m_JVMInstance == nullptr) {
m_JVMInstance = (CreateJavaVM)GetProcAddress(m_hDllInstance, "JNI_CreateJavaVM");
}
std::string strJavaClassPath;
std::string strJavaLibraryPath;
strJavaClassPath = "-Djava.class.path=";
for (std::size_t idx = 0; idx < m_listOfJars.size(); idx++) {
strJavaClassPath += m_ProductLibDir + "/" + m_listOfJars[idx] + ";";
}
strJavaLibraryPath = "-Djava.library.path=";
strJavaLibraryPath += m_JavaHome + "/lib" + "," + m_JavaHome + "/jre/lib";
JavaVMOption options[6];
options[0].optionString = const_cast<char*>(strJavaClassPath.c_str());
options[1].optionString = const_cast<char*>(strJavaLibraryPath.c_str());
options[2].optionString = "-Xms128m";
options[3].optionString = "-Xmx1024m";
options[4].optionString = "-Xcheck:jni:nonfatal";
options[5].optionString = "-XX:+DisableAttachMechanism";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_8;
vm_args.options = options;
vm_args.nOptions = 5;
vm_args.ignoreUnrecognized = JNI_TRUE;
jint res = m_JVMInstance(&m_RunningJVMInstance, (void **)&m_JVMEnv, &vm_args);
if (res != JNI_OK) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Could not launch the JVM", 3);
}
else {
m_boolEnabled = true;
if (!verify()) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Cannot verify jar", 8);
this->JNI_destroyVM();
}
}
}
else
{
m_boolEnabled = true;
}
}
}
}
jint JVMLauncher::JNI_destroyVM() {
jint result = m_RunningJVMInstance->DestroyJavaVM();
m_JVMEnv = nullptr;
s_threadLock = nullptr;
return result;
}
bool JVMLauncher::validateCall() {
LaunchJVM();
if (!m_boolEnabled) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"JVM not running", 5);
return false;
}
if (!valid) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Load not valid packages", 5);
return false;
}
return true;
}
jclass JVMLauncher::findClassForCall(std::string className) {
jclass findedClass = nullptr;
auto val = m_cachedClasses.find(className);
if (val == m_cachedClasses.end()) {
jclass neededclass = this->m_JVMEnv->FindClass(className.c_str());
if (!this->m_JVMEnv->ExceptionCheck()) {
findedClass = (jclass)this->m_JVMEnv->NewGlobalRef(neededclass);
m_cachedClasses.insert(std::pair<std::string, jclass>(className, findedClass));
this->m_JVMEnv->DeleteLocalRef(neededclass);
JNINativeMethod methods[]{ { "log", "(Ljava/lang/String;)V", (void *)&Java_Runner_log } }; // mapping table
if (m_JVMEnv->RegisterNatives(findedClass, methods, 1) < 0) {
if (m_JVMEnv->ExceptionOccurred()) // verify if it's ok
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L" OOOOOPS: exception when registreing natives handlers", 6);
}
}
else {
this->m_JVMEnv->ExceptionClear();
}
}
else {
findedClass = val->second;
}
return findedClass;
}
jmethodID JVMLauncher::findMethodForCall(jclass findedclass, bool& hasError) {
jmethodID findedMethod = nullptr;
auto val = m_cachedMethod.find(findedclass);
if (val == m_cachedMethod.end()) {
hasError = true;
}
else {
findedMethod = val->second;
}
return findedMethod;
}
jmethodID JVMLauncher::HasMethodInCache(jclass findedclass) {
jmethodID findedMethod = nullptr;
auto val = m_cachedMethod.find(findedclass);
if (val != m_cachedMethod.end()) {
findedMethod = val->second;
}
return findedMethod;
}
/////////////////////////////////////////////////////////////////////////////
// ILanguageExtenderBase
//---------------------------------------------------------------------------//
bool JVMLauncher::RegisterExtensionAs(WCHAR_T** wsExtensionName)
{
wchar_t *wsExtension = L"JVMLauncher";
size_t iActualSize = ::wcslen(wsExtension) + 1;
if (m_iMemory && m_iMemory->AllocMemory((void**)wsExtensionName, iActualSize * sizeof(wchar_t))) {
::convToShortWchar(wsExtensionName, wsExtension, iActualSize);
return true;
}
return false;
}
//---------------------------------------------------------------------------//
long JVMLauncher::GetNProps()
{
return ePropLast;
}
//---------------------------------------------------------------------------//
long JVMLauncher::FindProp(const WCHAR_T* wsPropName)
{
long plPropNum = -1;
wchar_t* propName = 0;
::convFromShortWchar(&propName, wsPropName);
plPropNum = findName(g_PropNames, propName, ePropLast);
if (plPropNum == -1)
plPropNum = findName(g_PropNamesRu, propName, ePropLast);
delete[] propName;
return plPropNum;
}
//---------------------------------------------------------------------------//
const WCHAR_T* JVMLauncher::GetPropName(long lPropNum, long lPropAlias)
{
if (lPropNum >= ePropLast)
return NULL;
wchar_t *wsCurrentName = NULL;
WCHAR_T *wsPropName = NULL;
int iActualSize = 0;
switch (lPropAlias)
{
case 0: // First language
wsCurrentName = g_PropNames[lPropNum];
break;
case 1: // Second language
wsCurrentName = g_PropNamesRu[lPropNum];
break;
default:
return 0;
}
iActualSize = wcslen(wsCurrentName) + 1;
if (m_iMemory && wsCurrentName)
{
if (m_iMemory->AllocMemory((void**)&wsPropName, iActualSize * sizeof(WCHAR_T)))
::convToShortWchar(&wsPropName, wsCurrentName, iActualSize);
}
return wsPropName;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::GetPropVal(const long lPropNum, tVariant* pvarPropVal)
{
char *name = 0;
size_t size = 0;
wchar_t* wsMsgBuf;
switch (lPropNum)
{
case ePropIsEnabled:
TV_VT(pvarPropVal) = VTYPE_BOOL;
TV_BOOL(pvarPropVal) = m_boolEnabled;
break;
case ePropJavaHome:
TV_VT(pvarPropVal) = VTYPE_PWSTR;
name = const_cast<char*>(this->m_JavaHome.c_str());
size = mbstowcs(0, name, 0) + 1;
wsMsgBuf = new wchar_t[size];
memset(wsMsgBuf, 0, size * sizeof(wchar_t));
size = mbstowcs(wsMsgBuf, name, size);
pvarPropVal->wstrLen = size;
m_iMemory->AllocMemory((void**)&pvarPropVal->pwstrVal, size * sizeof(WCHAR_T));
::convToShortWchar(&pvarPropVal->pwstrVal, wsMsgBuf, size);
break;
case ePropLibraryDir:
TV_VT(pvarPropVal) = VTYPE_PWSTR;
name = const_cast<char*>(this->m_ProductLibDir.c_str());
size = mbstowcs(0, name, 0) + 1;
wsMsgBuf = new wchar_t[size];
memset(wsMsgBuf, 0, size * sizeof(wchar_t));
size = mbstowcs(wsMsgBuf, name, size);
pvarPropVal->wstrLen = size;
m_iMemory->AllocMemory((void**)&pvarPropVal->pwstrVal, size * sizeof(WCHAR_T));
::convToShortWchar(&pvarPropVal->pwstrVal, wsMsgBuf, size);
break;
default:
return false;
}
return true;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::SetPropVal(const long lPropNum, tVariant *varPropVal)
{
switch (lPropNum)
{
case ePropIsEnabled:
if (TV_VT(varPropVal) != VTYPE_BOOL)
return false;
m_boolEnabled = TV_BOOL(varPropVal);
break;
case ePropJavaHome:
if (m_boolEnabled) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"JVM already running", 7);
return false;
}
m_JavaHome = getStdStringFrom1C(varPropVal);
break;
case ePropLibraryDir:
if (m_boolEnabled) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"JVM already running", 7);
return false;
}
m_ProductLibDir = getStdStringFrom1C(varPropVal);
break;
default:
return false;
}
return true;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::IsPropReadable(const long lPropNum)
{
switch (lPropNum)
{
case ePropIsEnabled:
case ePropJavaHome:
case ePropLibraryDir:
return true;
default:
return false;
}
return false;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::IsPropWritable(const long lPropNum)
{
switch (lPropNum)
{
case ePropJavaHome:
case ePropLibraryDir:
return true;
case ePropIsEnabled:
return false;
default:
return false;
}
return false;
}
//---------------------------------------------------------------------------//
long JVMLauncher::GetNMethods()
{
return eMethLast;
}
//---------------------------------------------------------------------------//
long JVMLauncher::FindMethod(const WCHAR_T* wsMethodName)
{
long plMethodNum = -1;
wchar_t* name = 0;
::convFromShortWchar(&name, wsMethodName);
plMethodNum = findName(g_MethodNames, name, eMethLast);
if (plMethodNum == -1)
plMethodNum = findName(g_MethodNamesRu, name, eMethLast);
delete[] name;
return plMethodNum;
}
//---------------------------------------------------------------------------//
const WCHAR_T* JVMLauncher::GetMethodName(const long lMethodNum, const long lMethodAlias)
{
if (lMethodNum >= eMethLast)
return NULL;
wchar_t *wsCurrentName = NULL;
WCHAR_T *wsMethodName = NULL;
size_t iActualSize = 0;
switch (lMethodAlias)
{
case 0: // First language
wsCurrentName = g_MethodNames[lMethodNum];
break;
case 1: // Second language
wsCurrentName = g_MethodNamesRu[lMethodNum];
break;
default:
return 0;
}
iActualSize = wcslen(wsCurrentName) + 1;
if (m_iMemory && wsCurrentName)
{
if (m_iMemory->AllocMemory((void**)&wsMethodName, iActualSize * sizeof(WCHAR_T)))
::convToShortWchar(&wsMethodName, wsCurrentName, iActualSize);
}
return wsMethodName;
}
//---------------------------------------------------------------------------//
long JVMLauncher::GetNParams(const long lMethodNum)
{
switch (lMethodNum)
{
case eMethAddJar:
case eCallAsFuncB:
case eCallAsProcedure:
return 1;
case eCallAsProcedureP:
case eCallAsFuncBP:
case eCallAsFunc:
return 2;
case eCallAsProcedurePP:
case eCallAsFuncBPP:
case eCallAsFuncP:
return 3;
case eCallAsFuncPP:
return 4;
default:
return 0;
}
return 0;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::HasRetVal(const long lMethodNum)
{
switch (lMethodNum)
{
case eCallAsFuncB:
case eCallAsFuncBP:
case eCallAsFuncBPP:
case eCallAsFunc:
case eCallAsFuncP:
case eCallAsFuncPP:
return true;
default:
return false;
}
return false;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::CallAsProc(const long lMethodNum,
tVariant* paParams, const long lSizeArray)
{
switch (lMethodNum)
{
case eCallAsProcedure:
case eCallAsProcedureP:
case eCallAsProcedurePP:
return CallAsFunc(lMethodNum, paParams, paParams, lSizeArray);
case eMethDisable:
m_boolEnabled = false;
break;
case eMethAddJar:
{
if (!lSizeArray)
return false;
this->addJar(getStdStringFrom1C(paParams).c_str());
}
break;
default:
return false;
}
return true;
}
//---------------------------------------------------------------------------//
bool JVMLauncher::CallAsFunc(const long lMethodNum,
tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray)
{
if (!lSizeArray || !paParams)
return false;
bool resultOk = true;
std::string className = getStdStringFrom1C(paParams);
if (className.empty()) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Send empty class name", 10);
return false;
}
if (!validateCall()) {
return false;
}
int lastIndexOfParam = lSizeArray;
TYPEVAR rt;
switch (lMethodNum)
{
case eCallAsProcedure:
case eCallAsProcedureP:
case eCallAsProcedurePP:
rt = VTYPE_EMPTY;
break;
case eCallAsFuncB:
case eCallAsFuncBP:
case eCallAsFuncBPP:
rt = VTYPE_BLOB;
break;
case eCallAsFunc:
case eCallAsFuncP:
case eCallAsFuncPP:
{
lastIndexOfParam = lSizeArray - 1;
rt = TV_VT(&paParams[lastIndexOfParam]);
}
break;
}
jint res = m_RunningJVMInstance->GetEnv((void**)&m_JVMEnv, NULL);
res = m_RunningJVMInstance->AttachCurrentThread((void**)&m_JVMEnv, NULL);
if (res != JNI_OK) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Could not attach to the JVM", 4);
return false;
}
jclass findedClass = findClassForCall(className);
if (findedClass == nullptr) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Cannot find class", 10);
resultOk = false;
goto detach;
}
jmethodID methodID;
if (!(methodID = HasMethodInCache(findedClass))) {
std::string signature = getSignature(this->m_JVMEnv, paParams, 1, lastIndexOfParam);
switch (rt) {
case VTYPE_PSTR: signature.append("Ljava/lang/String;"); break;
case VTYPE_PWSTR: signature.append("Ljava/lang/String;"); break;
case VTYPE_BLOB: signature.append("[B"); break;
case VTYPE_I4: signature.append("I"); break;
case VTYPE_BOOL: signature.append("Z"); break;
case VTYPE_R4: signature.append("F"); break;
case VTYPE_R8: signature.append("D"); break;
case VTYPE_EMPTY: signature.append("V"); break;
}
methodID = JNI_getStaticMethodID(findedClass, "mainInt", signature.c_str(), resultOk);
if (!resultOk) {
goto detach;
}
m_cachedMethod.insert(std::pair<jclass, jmethodID>(findedClass, methodID));
}
else {
methodID = findMethodForCall(findedClass, resultOk);
}
if (!resultOk) {
pAsyncEvent->AddError(ADDIN_E_FAIL, L"JVMLauncher", L"Cannot find method", 10);
goto detach;
}
jvalue *values = getParams(this->m_JVMEnv, paParams, 1, lastIndexOfParam);
jboolean resultBoolean = false;
jstring resultString = nullptr;
jint resultInt = 0;
jfloat resultFloat = 0.0f;
jdouble resultDouble = 0.0;
jobject resultByteArray = nullptr;
switch (rt)
{
case VTYPE_BOOL:
resultBoolean = JNI_callStaticBooleanMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_PWSTR:
case VTYPE_PSTR:
resultString = (jstring)JNI_callStaticObjectMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_I4:
resultInt = JNI_callStaticIntMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_R4:
resultFloat = JNI_callStaticFloatMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_R8:
resultDouble = JNI_callStaticDoubleMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_BLOB:
resultByteArray = JNI_callStaticObjectMethodA(findedClass, methodID, values, resultOk);
break;
case VTYPE_EMPTY:
this->JNI_callStaticVoidMethodA(findedClass, methodID, values, resultOk);
break;
}
delete[] values;
if (!resultOk) {
goto detach;
}
if (rt != VTYPE_EMPTY) {
TV_VT(pvarRetValue) = rt;
}
switch (rt)
{
case VTYPE_BOOL:
TV_BOOL(pvarRetValue) = resultBoolean;
break;
case VTYPE_PWSTR:
case VTYPE_PSTR:
{
auto wstring = JStringToWString(m_JVMEnv, resultString);
auto length = wstring.length();
if (length && m_iMemory->AllocMemory((void**)&pvarRetValue->pwstrVal, length * sizeof(WCHAR_T)))
{
memcpy(pvarRetValue->pwstrVal, wstring.c_str(), length * sizeof(WCHAR_T));
pvarRetValue->strLen = length;
}
m_JVMEnv->DeleteLocalRef(resultString);
TV_VT(pvarRetValue) = VTYPE_PWSTR;
}
break;
case VTYPE_I4:
TV_INT(pvarRetValue) = resultInt;
break;
case VTYPE_R4:
TV_R4(pvarRetValue) = resultFloat;
break;
case VTYPE_R8:
TV_R8(pvarRetValue) = resultDouble;
break;
case VTYPE_BLOB:
{
jbyteArray arr = reinterpret_cast<jbyteArray>(resultByteArray);
auto length = m_JVMEnv->GetArrayLength(arr);
void *elements = m_JVMEnv->GetPrimitiveArrayCritical(arr, NULL);
if (length && m_iMemory->AllocMemory((void**)&pvarRetValue->pstrVal, length))
{
memcpy(pvarRetValue->pstrVal, elements, length);
pvarRetValue->strLen = length;
}
m_JVMEnv->ReleasePrimitiveArrayCritical(arr, elements, 0);
m_JVMEnv->DeleteLocalRef(resultByteArray);
}
break;
}
detach:
m_RunningJVMInstance->DetachCurrentThread();
return resultOk;
}
/////////////////////////////////////////////////////////////////////////////
// LocaleBase
//---------------------------------------------------------------------------//
bool JVMLauncher::setMemManager(void* memoryManager)
{
m_iMemory = static_cast<IMemoryManager *>(memoryManager);
return m_iMemory != nullptr;
}
//---------------------------------------------------------------------------//
void JVMLauncher::addError(uint32_t wcode, const wchar_t* source,
const wchar_t* descriptor, long code)
{
if (pAsyncEvent)
{
WCHAR_T *err = 0;
WCHAR_T *descr = 0;
::convToShortWchar(&err, source);
::convToShortWchar(&descr, descriptor);
pAsyncEvent->AddError(wcode, err, descr, code);
delete[] err;
delete[] descr;
}
}
//---------------------------------------------------------------------------//
long JVMLauncher::findName(wchar_t* names[], const wchar_t* name,
const uint32_t size) const
{
long ret = -1;
for (uint32_t i = 0; i < size; i++)
{
if (!wcscmp(names[i], name))
{
ret = i;
break;
}
}
return ret;
}
bool JVMLauncher::Init(void* connection)
{
gAsyncEvent = static_cast<IAddInDefBase *>(connection);
pAsyncEvent = static_cast<IAddInDefBase *>(connection);
pAsyncEvent->SetEventBufferDepth(1000);
return pAsyncEvent != nullptr;
}

7
JVMLauncher.def Normal file
View File

@ -0,0 +1,7 @@
LIBRARY "JVMLauncher"
EXPORTS
GetClassObject
DestroyObject
GetClassNames
SetPlatformCapabilities

137
JVMLauncher.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef __JVMLAUNCHER_H__
#define __JVMLAUNCHER_H__
#include "ComponentBase.h"
#include "AddInDefBase.h"
#include "IMemoryManager.h"
#include <string>
#include <vector>
#include <map>
#include <include/jni.h>
#include "Utils.h"
#define BEGIN_JAVA { JNIEnv* env = this->m_JVMEnv; this->m_JVMEnv = nullptr;
#define END_JAVA this->m_JVMEnv = env; }
#define BEGIN_CALL \
BEGIN_JAVA
#define END_CALL \
hasError = this->endCall(env); }
typedef jint(JNICALL *CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
typedef jint(JNICALL * GetCreatedJavaVMs)(JavaVM**, jsize, jsize*);
class JVMLauncher : public IComponentBase {
public:
enum Props
{
ePropIsEnabled = 0,
ePropJavaHome,
ePropLibraryDir,
ePropLast // Always last
};
enum Methods
{
eCallAsProcedure = 0,
eCallAsProcedureP,
eCallAsProcedurePP,
eCallAsFuncB,
eCallAsFuncBP,
eCallAsFuncBPP,
eCallAsFunc,
eCallAsFuncP,
eCallAsFuncPP,
eMethDisable,
eMethAddJar,
eMethLast // Always last
};
JVMLauncher(void);
~JVMLauncher() override {};
// IInitDoneBase
bool ADDIN_API Init(void*) override;
bool ADDIN_API setMemManager(void* mem) override;
long ADDIN_API GetInfo() override { return 2000; }
void ADDIN_API Done() override {};
// ILanguageExtenderBase
bool ADDIN_API RegisterExtensionAs(WCHAR_T**) override;
long ADDIN_API GetNProps() override;
long ADDIN_API FindProp(const WCHAR_T* wsPropName) override;
const WCHAR_T* ADDIN_API GetPropName(long lPropNum, long lPropAlias) override;
bool ADDIN_API GetPropVal(const long lPropNum, tVariant* pvarPropVal) override;
bool ADDIN_API SetPropVal(const long lPropNum, tVariant* varPropVal) override;
bool ADDIN_API IsPropReadable(const long lPropNum) override;
bool ADDIN_API IsPropWritable(const long lPropNum) override;
long ADDIN_API GetNMethods() override;
long ADDIN_API FindMethod(const WCHAR_T* wsMethodName) override;
const WCHAR_T* ADDIN_API GetMethodName(const long lMethodNum,
const long lMethodAlias) override;
long ADDIN_API GetNParams(const long lMethodNum) override;
bool ADDIN_API GetParamDefValue(const long lMethodNum, const long lParamNum,
tVariant *pvarParamDefValue) override {
return false;
};
bool ADDIN_API HasRetVal(const long lMethodNum) override;
bool ADDIN_API CallAsProc(const long lMethodNum,
tVariant* paParams, const long lSizeArray) override;
bool ADDIN_API CallAsFunc(const long lMethodNum,
tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) override;
// LocaleBase
void ADDIN_API SetLocale(const WCHAR_T* loc) override {};
private:
// Attributes
IAddInDefBase *pAsyncEvent = nullptr;
IMemoryManager *m_iMemory;
bool m_boolEnabled = false;
bool valid = true;
HINSTANCE m_hDllInstance = nullptr;
std::string m_JavaHome;
std::string m_ProductLibDir;
std::string m_JvmDllLocation;
CreateJavaVM m_JVMInstance = nullptr;
GetCreatedJavaVMs m_GetCreatedJavaVMs = nullptr;
JNIEnv *m_JVMEnv;
JavaVM *m_RunningJVMInstance;
std::vector<std::string> m_listOfJars;
std::vector<std::string> m_listOfClasses;
std::map<std::string, jclass> m_cachedClasses;
std::map<jclass, jmethodID> m_cachedMethod;
void LaunchJVM();
bool verify();
jint JNI_destroyVM();
bool validateCall();
jclass findClassForCall(std::string className);
jmethodID findMethodForCall(jclass findedclass, bool& hasError);
jmethodID HasMethodInCache(jclass findedclass);
long findName(wchar_t* names[], const wchar_t* name, const uint32_t size) const;
void addError(uint32_t wcode, const wchar_t* source,
const wchar_t* descriptor, long code);
void addJar(const char* jarname);
jclass JNI_findClass(const char* className);
void JNI_callStaticVoidMethod(jclass clazz, jmethodID methodID, bool& hasError, ...);
jobjectArray JNI_newObjectArray(jsize length, jclass elementClass, jobject initialElement, bool& hasError);
void JNI_callStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
jobject JNI_callStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
jboolean JNI_callStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
jint JNI_callStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
jfloat JNI_callStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
jdouble JNI_callStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue* args, bool& hasError);
void JNI_callStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args, bool& hasError);
jmethodID JNI_getStaticMethodID(jclass clazz, const char* name, const char* sig, bool& hasError);
bool endCall(JNIEnv* env);
protected:
};
#endif //__JVMLAUNCHER_H__

31
JVMLauncher.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JVMLauncher", "JVMLauncher.vcxproj", "{55890DF2-D13E-4C89-A01D-79CAD6726246}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Debug|Win32.ActiveCfg = Debug|Win32
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Debug|Win32.Build.0 = Debug|Win32
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Debug|x64.ActiveCfg = Debug|x64
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Debug|x64.Build.0 = Debug|x64
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Release|Win32.ActiveCfg = Release|Win32
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Release|Win32.Build.0 = Release|Win32
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Release|x64.ActiveCfg = Release|x64
{55890DF2-D13E-4C89-A01D-79CAD6726246}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B2584843-D338-494E-BE3E-1685D14B0174}
EndGlobalSection
EndGlobal

231
JVMLauncher.vcxproj Normal file
View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{55890DF2-D13E-4C89-A01D-79CAD6726246}</ProjectGuid>
<RootNamespace>testCPP</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<ProjectName>JVMLauncher</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.26730.3</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<OutDir>$(SolutionDir)\bind\</OutDir>
<IntDir>$(SolutionDir)\build\$(Configuration)\$(ProjectName)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>Target\$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>Target\$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>Target\$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ADDINCPP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)64.dll</OutputFile>
<ModuleDefinitionFile>JVMLauncher.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl />
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;ADDINCPP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)64.dll</OutputFile>
<ModuleDefinitionFile>JVMLauncher.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>c:\Program Files\Java\jdk1.8.0_171\include\win32\;c:\Program Files\Java\jdk1.8.0_171\;D:\vanzhula\cpp\NativeAPI\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ADDINCPP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)64.dll</OutputFile>
<ModuleDefinitionFile>JVMLauncher.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl />
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>c:\Program Files\Java\jdk1.8.0_171\include\win32\;c:\Program Files\Java\jdk1.8.0_171\;D:\vanzhula\cpp\NativeAPI\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;ADDINCPP_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName)86.dll</OutputFile>
<ModuleDefinitionFile>JVMLauncher.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Utils.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="exports.cpp" />
<ClCompile Include="JVMLauncher.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="JVMLauncher.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Utils.h" />
<ClInclude Include="include\AddInDefBase.h" />
<ClInclude Include="include\addinlib.h" />
<ClInclude Include="include\com.h" />
<ClInclude Include="include\ComponentBase.h" />
<ClInclude Include="include\IMemoryManager.h" />
<ClInclude Include="include\NPAPILib.h" />
<ClInclude Include="include\types.h" />
<ClInclude Include="JVMLauncher.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JVMLauncher.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="exports.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="JVMLauncher.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\AddInDefBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\addinlib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\com.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\ComponentBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\IMemoryManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\NPAPILib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JVMLauncher.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

176
Utils.cpp Normal file
View File

@ -0,0 +1,176 @@
#include "stdafx.h"
#ifdef __linux__
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#endif
#include <stdio.h>
#include <include/jni.h>
#include <wchar.h>
#include "Utils.h"
#include <string>
jvalue* getParams(JNIEnv* env, tVariant* paParams, int start, int end) {
if (end < start) {
return new jvalue[0];
}
jvalue *values = new jvalue[end - start];
for (auto i = start; i < end; i++)
{
if (TV_VT(&paParams[i]) == VTYPE_PSTR || TV_VT(&paParams[i]) == VTYPE_PWSTR) {
values[i - start].l = (jobject)getjstringFrom1C(env, &paParams[i]);
}
else if (TV_VT(&paParams[i]) == VTYPE_I4) {
values[i - start].i = TV_INT(&paParams[i]);
}
else if (TV_VT(&paParams[i]) == VTYPE_BOOL) {
values[i - start].z = TV_BOOL(&paParams[i]);
}
else if (TV_VT(&paParams[i]) == VTYPE_R4) {
values[i - start].f = (jfloat)TV_R4(&paParams[i]);
}
}
return values;
}
std::string getSignature(JNIEnv* env, tVariant* paParams, int start, int end) {
std::string signature = "(";
for (auto i = start; i < end; i++)
{
if (TV_VT(&paParams[i]) == VTYPE_PSTR || TV_VT(&paParams[i]) == VTYPE_PWSTR) {
signature.append("Ljava/lang/String;");
}
else if (TV_VT(&paParams[i]) == VTYPE_I4) {
signature.append("I");
}
else if (TV_VT(&paParams[i]) == VTYPE_BOOL) {
signature.append("Z");
}
else if (TV_VT(&paParams[i]) == VTYPE_R4) {
signature.append("F");
}
}
return signature.append(")");
}
std::wstring JStringToWString(JNIEnv* env, jstring string)
{
std::wstring value;
const jchar *raw = env->GetStringChars(string, 0);
jsize len = env->GetStringLength(string);
value.assign(raw, raw + len);
env->ReleaseStringChars(string, raw);
return value;
}
jstring getjstringFrom1C(JNIEnv* env, tVariant* paParams) {
jstring jstr;
switch (TV_VT(paParams))
{
case VTYPE_PSTR:
jstr = env->NewStringUTF(paParams->pstrVal);
break;
case VTYPE_PWSTR:
wchar_t* name = TV_WSTR(paParams);
jstr = env->NewString(reinterpret_cast<jchar*>(name), wcslen(name));
}
return jstr;
}
std::string getStdStringFrom1C(tVariant* paParams) {
std::string resultString;
char *name = 0;
size_t size = 0;
char *mbstr = 0;
wchar_t* wsTmp = 0;
switch (TV_VT(paParams))
{
case VTYPE_PSTR:
name = paParams->pstrVal;
resultString = std::string(name);
break;
case VTYPE_PWSTR:
::convFromShortWchar(&wsTmp, TV_WSTR(paParams));
size = wcstombs(0, wsTmp, 0) + 1;
mbstr = new char[size];
memset(mbstr, 0, size);
size = wcstombs(mbstr, wsTmp, getLenShortWcharStr(TV_WSTR(paParams)));
name = mbstr;
delete[] wsTmp;
resultString = std::string(name);
if (mbstr)
delete[] mbstr;
break;
}
return resultString;
}
//---------------------------------------------------------------------------//
uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, uint32_t len)
{
if (!len)
len = ::wcslen(Source)+1;
if (!*Dest)
*Dest = new WCHAR_T[len];
WCHAR_T* tmpShort = *Dest;
wchar_t* tmpWChar = (wchar_t*) Source;
uint32_t res = 0;
::memset(*Dest, 0, len*sizeof(WCHAR_T));
do
{
*tmpShort++ = (WCHAR_T)*tmpWChar++;
++res;
}
while (len-- && *tmpWChar);
return res;
}
//---------------------------------------------------------------------------//
uint32_t getLenShortWcharStr(const WCHAR_T* Source)
{
uint32_t res = 0;
WCHAR_T *tmpShort = (WCHAR_T*)Source;
while (*tmpShort++)
++res;
return res;
}
//---------------------------------------------------------------------------//
uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len)
{
if (!len)
len = getLenShortWcharStr(Source)+1;
if (!*Dest)
*Dest = new wchar_t[len];
wchar_t* tmpWChar = *Dest;
WCHAR_T* tmpShort = (WCHAR_T*)Source;
uint32_t res = 0;
::memset(*Dest, 0, len*sizeof(wchar_t));
do
{
*tmpWChar++ = (wchar_t)*tmpShort++;
++res;
}
while (len-- && *tmpShort);
return res;
}

19
Utils.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#include "ComponentBase.h"
#include "AddInDefBase.h"
#include "IMemoryManager.h"
#include <string>
#include <include/jni.h>
uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, uint32_t len = 0);
uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len = 0);
uint32_t getLenShortWcharStr(const WCHAR_T* Source);
std::wstring JStringToWString(JNIEnv* env, jstring string);
std::string getStdStringFrom1C(tVariant* paParams);
jstring getjstringFrom1C(JNIEnv* env, tVariant* paParams);
std::string getSignature(JNIEnv* env, tVariant* paParams, int start, int end);
jvalue* getParams(JNIEnv* env, tVariant* paParams, int start, int end);
#endif //__UTILS_H__

19
dllmain.cpp Normal file
View File

@ -0,0 +1,19 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#ifndef __linux__
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;
}
#endif //__linux__

36
exports.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "JVMLauncher.h"
static const wchar_t g_kClassNames[] = L"JVMLauncher";
//---------------------------------------------------------------------------//
const WCHAR_T* GetClassNames()
{
static WCHAR_T* names = 0;
if (!names)
::convToShortWchar(&names, g_kClassNames);
return names;
}
//---------------------------------------------------------------------------//
long GetClassObject(const WCHAR_T* wsName, IComponentBase** pInterface)
{
if (!*pInterface) {
*pInterface = new JVMLauncher;
return (long)*pInterface;
}
return 0;
}
long DestroyObject(IComponentBase** pInterface)
{
if (!*pInterface)
return -1;
delete *pInterface;
*pInterface = nullptr;
return 0;
}
AppCapabilities SetPlatformCapabilities(const AppCapabilities capabilities) {
return eAppCapabilitiesLast;
}

146
include/AddInDefBase.h Normal file
View File

@ -0,0 +1,146 @@
/*
* Warning!!!
* DO NOT ALTER THIS FILE!
*/
#ifndef __ADAPTER_DEF_H__
#define __ADAPTER_DEF_H__
#include "types.h"
struct IInterface
{
};
enum Interfaces
{
eIMsgBox = 0,
eIPlatformInfo,
};
////////////////////////////////////////////////////////////////////////////////
/**
* This class serves as representation of a platform for external
* components External components use it to communicate with a platform.
*
*/
/// Base interface for object components.
class IAddInDefBase
{
public:
virtual ~IAddInDefBase() {}
/// Adds the error message
/**
* @param wcode - error code
* @param source - source of error
* @param descr - description of error
* @param scode - error code (HRESULT)
* @return the result of
*/
virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source,
const WCHAR_T* descr, long scode) = 0;
/// Reads a property value
/**
* @param wszPropName -property name
* @param pVal - value being returned
* @param pErrCode - error code (if any error occured)
* @param errDescriptor - error description (if any error occured)
* @return the result of read.
*/
virtual bool ADDIN_API Read(WCHAR_T* wszPropName,
tVariant* pVal,
long *pErrCode,
WCHAR_T** errDescriptor) = 0;
/// Writes a property value
/**
* @param wszPropName - property name
* @param pVar - new property value
* @return the result of write.
*/
virtual bool ADDIN_API Write(WCHAR_T* wszPropName,
tVariant *pVar) = 0;
///Registers profile components
/**
* @param wszProfileName - profile name
* @return the result of
*/
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName) = 0;
/// Changes the depth of event buffer
/**
* @param lDepth - new depth of event buffer
* @return the result of
*/
virtual bool ADDIN_API SetEventBufferDepth(long lDepth) = 0;
/// Returns the depth of event buffer
/**
* @return the depth of event buffer
*/
virtual long ADDIN_API GetEventBufferDepth() = 0;
/// Registers external event
/**
* @param wszSource - source of event
* @param wszMessage - event message
* @param wszData - message parameters
* @return the result of
*/
virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource,
WCHAR_T* wszMessage,
WCHAR_T* wszData) = 0;
/// Clears event buffer
/**
*/
virtual void ADDIN_API CleanEventBuffer() = 0;
/// Sets status line contents
/**
* @param wszStatusLine - new status line contents
* @return the result of
*/
virtual bool ADDIN_API SetStatusLine(WCHAR_T* wszStatusLine) = 0;
/// Resets the status line contents
/**
* @return the result of
*/
virtual void ADDIN_API ResetStatusLine() = 0;
};
class IAddInDefBaseEx :
public IAddInDefBase
{
public:
virtual ~IAddInDefBaseEx() {}
virtual IInterface* ADDIN_API GetInterface(Interfaces iface) = 0;
};
struct IMsgBox :
public IInterface
{
virtual bool ADDIN_API Confirm(const WCHAR_T* queryText, tVariant* retVal) = 0;
virtual bool ADDIN_API Alert(const WCHAR_T* text) = 0;
};
struct IPlatformInfo :
public IInterface
{
enum AppType
{
eAppUnknown = -1,
eAppThinClient = 0,
eAppThickClient,
eAppWebClient,
eAppServer,
eAppExtConn,
};
struct AppInfo
{
const WCHAR_T* AppVersion;
const WCHAR_T* UserAgentInformation;
AppType Application;
};
virtual const AppInfo* ADDIN_API GetPlatformInfo() = 0;
};
#endif //__ADAPTER_DEF_H__

247
include/ComponentBase.h Normal file
View File

@ -0,0 +1,247 @@
/*
* Warning!!!
* DO NOT ALTER THIS FILE!
*/
#ifndef __COMPONENT_BASE_H__
#define __COMPONENT_BASE_H__
#include "types.h"
////////////////////////////////////////////////////////////////////////////////
/**
* The given interface is intended for initialization and
* uninitialization of component and its adjustments
*/
/// Interface of component initialization.
class IInitDoneBase
{
public:
virtual ~IInitDoneBase() {}
/// Initializes component
/**
* @param disp - 1C:Enterpise interface
* @return the result of
*/
virtual bool ADDIN_API Init(void* disp) = 0;
/// Sets the memory manager
/*
* @param mem - pointer to memory manager interface.
* @return the result of
*/
virtual bool ADDIN_API setMemManager(void* mem) = 0;
/// Returns component version
/**
* @return - component version (2000 - version 2)
*/
virtual long ADDIN_API GetInfo() = 0;
/// Uninitializes component
/**
* Component here should release all consumed resources.
*/
virtual void ADDIN_API Done() = 0;
};
///////////////////////////////////////////////////////////////////////////
/**
* The given interface defines methods that are intented to be used by the Platform
*/
/// Interface describing extension of language.
class ILanguageExtenderBase
{
public:
virtual ~ILanguageExtenderBase(){}
/// Registers language extension
/**
* @param wsExtensionName - extension name
* @return the result of
*/
virtual bool ADDIN_API RegisterExtensionAs(WCHAR_T** wsExtensionName) = 0;
/// Returns number of component properties
/**
* @return number of properties
*/
virtual long ADDIN_API GetNProps() = 0;
/// Finds property by name
/**
* @param wsPropName - property name
* @return property index or -1, if it is not found
*/
virtual long ADDIN_API FindProp(const WCHAR_T* wsPropName) = 0;
/// Returns property name
/**
* @param lPropNum - property index (starting with 0)
* @param lPropAlias - 0 - international alias,
* 1 - russian alias. (International alias is required)
* @return proeprty name or 0 if it is not found
*/
virtual const WCHAR_T* ADDIN_API GetPropName(long lPropNum,
long lPropAlias) = 0;
/// Returns property value
/**
* @param lPropNum - property index (starting with 0)
* @param pvarPropVal - the pointer to a variable for property value
* @return the result of
*/
virtual bool ADDIN_API GetPropVal(const long lPropNum,
tVariant* pvarPropVal) = 0;
/// Sets the property value
/**
* @param lPropNum - property index (starting with 0)
* @param varPropVal - the pointer to a variable for property value
* @return the result of
*/
virtual bool ADDIN_API SetPropVal(const long lPropNum,
tVariant* varPropVal) = 0;
/// Is property readable?
/**
* @param lPropNum - property index (starting with 0)
* @return true if property is readable
*/
virtual bool ADDIN_API IsPropReadable(const long lPropNum) = 0;
/// Is property writable?
/**
* @param lPropNum - property index (starting with 0)
* @return true if property is writable
*/
virtual bool ADDIN_API IsPropWritable(const long lPropNum) = 0;
/// Returns number of component methods
/**
* @return number of component methods
*/
virtual long ADDIN_API GetNMethods() = 0;
/// Finds a method by name
/**
* @param wsMethodName - method name
* @return - method index
*/
virtual long ADDIN_API FindMethod(const WCHAR_T* wsMethodName) = 0;
/// Returns method name
/**
* @param lMethodNum - method index(starting with 0)
* @param lMethodAlias - 0 - international alias,
* 1 - russian alias. (International alias is required)
* @return method name or 0 if method is not found
*/
virtual const WCHAR_T* ADDIN_API GetMethodName(const long lMethodNum,
const long lMethodAlias) = 0;
/// Returns number of method parameters
/**
* @param lMethodNum - method index (starting with 0)
* @return number of parameters
*/
virtual long ADDIN_API GetNParams(const long lMethodNum) = 0;
/// Returns default value of method parameter
/**
* @param lMethodNum - method index(starting with 0)
* @param lParamNum - parameter index (starting with 0)
* @param pvarParamDefValue - the pointer to a variable for default value
* @return the result of
*/
virtual bool ADDIN_API GetParamDefValue(const long lMethodNum,
const long lParamNum,
tVariant *pvarParamDefValue) = 0;
/// Does the method have a return value?
/**
* @param lMethodNum - method index (starting with 0)
* @return true if the method has a return value
*/
virtual bool ADDIN_API HasRetVal(const long lMethodNum) = 0;
/// Calls the method as a procedure
/**
* @param lMethodNum - method index (starting with 0)
* @param paParams - the pointer to array of method parameters
* @param lSizeArray - the size of array
* @return the result of
*/
virtual bool ADDIN_API CallAsProc(const long lMethodNum,
tVariant* paParams,
const long lSizeArray) = 0;
/// Calls the method as a function
/**
* @param lMethodNum - method index (starting with 0)
* @param pvarRetValue - the pointer to returned value
* @param paParams - the pointer to array of method parameters
* @param lSizeArray - the size of array
* @return the result of
*/
virtual bool ADDIN_API CallAsFunc(const long lMethodNum,
tVariant* pvarRetValue,
tVariant* paParams,
const long lSizeArray) = 0;
};
///////////////////////////////////////////////////////////////////////////
/**
* This interface is used to change component locale
*/
/// Base interface for component localization.
class LocaleBase
{
public:
virtual ~LocaleBase(){}
/// Changes component locale
/**
* @param loc - new locale (for Windows - rus_RUS,
* for Linux - ru_RU, etc...)
*/
virtual void ADDIN_API SetLocale(const WCHAR_T* loc) = 0;
};
///////////////////////////////////////////////////////////////////////////
/**
* The given interface is generalized, for its obligatory inheritance
* in implementing components.
*/
/// Base interface describing object as a set of properties and methods.
class IComponentBase :
public IInitDoneBase,
public ILanguageExtenderBase,
public LocaleBase
{
public:
virtual ~IComponentBase(){}
};
enum AppCapabilities
{
eAppCapabilitiesInvalid = -1,
eAppCapabilities1 = 1,
eAppCapabilitiesLast = eAppCapabilities1,
};
/// Announcements of exported functions
/**
* These functions should be implemented that component can be loaded and created.
*/
extern "C" long GetClassObject(const WCHAR_T*, IComponentBase** pIntf);
extern "C" long DestroyObject(IComponentBase** pIntf);
extern "C" const WCHAR_T* GetClassNames();
extern "C" AppCapabilities SetPlatformCapabilities(const AppCapabilities capabilities);
typedef long (*GetClassObjectPtr)(const WCHAR_T* wsName, IComponentBase** pIntf);
typedef long (*DestroyObjectPtr)(IComponentBase** pIntf);
typedef const WCHAR_T* (*GetClassNamesPtr)();
typedef AppCapabilities (*SetPlatformCapabilitiesPtr)(const AppCapabilities capabilities);
#endif //__COMPONENT_BASE_H__

34
include/IMemoryManager.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Warning!!!
* DO NOT ALTER THIS FILE!
*/
#ifndef __IMEMORY_MANAGER_H__
#define __IMEMORY_MANAGER_H__
///////////////////////////////////////////////////////////////////////////////
/**
* The given class allocates and releases memory for a component
*/
/// Interface representing memory manager.
class IMemoryManager
{
public:
virtual ~IMemoryManager() {}
/// Allocates memory of specified size
/**
* @param pMemory - the double pointer to variable, that will hold newly
* allocated block of memory of NULL if allocation fails.
* @param ulCountByte - memory size
* @return the result of
*/
virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
/// Releases memory
/**
* @param pMemory - The double pointer to the memory block being released
*/
virtual void ADDIN_API FreeMemory (void** pMemory) = 0;
};
#endif //__IMEMORY_MANAGER_H__

68
include/MANIFEST.xsd Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://v8.1c.ru/8.2/addin/bundle" targetNamespace="http://v8.1c.ru/8.2/addin/bundle" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="Bundle">
<xs:annotation>
<xs:documentation>Bundle description<xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="component" type="Component" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Component">
<xs:attribute name="os" type="OSType" use="required">
<xs:annotation>
<xs:documentation>Platform type<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="path" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>File name<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="ComponentType" use="required">
<xs:annotation>
<xs:documentation>Component type<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="object" type="xs:string" >
<xs:annotation>
<xs:documentation>Object name<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="arch" type="ArchType" use="required">
<xs:annotation>
<xs:documentation>Architecture<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="client" type="ClientType" >
<xs:annotation>
<xs:documentation>Client type<xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="clientVersion" type="xs:string" >
<xs:annotation>
<xs:documentation>Client version<xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:simpleType name="OSType">
<xs:enumeration value="Windows"/>
<xs:enumeration value="Linux"/>
</xs:simpleType>
<xs:simpleType name="ComponentType">
<xs:enumeration value="native"/>
<xs:enumeration value="com"/>
<xs:enumeration value="plugin"/>
</xs:simpleType>
<xs:simpleType name="ArchType">
<xs:enumeration value="i386"/>
<xs:enumeration value="x86_64"/>
</xs:simpleType>
<xs:simpleType name="ClientType">
<xs:enumeration value="1C:Enterprise"/>
<xs:enumeration value="Firefox"/>
<xs:enumeration value="MSIE"/>
<xs:enumeration value="Safari"/>
<xs:enumeration value="Chrome"/>
</xs:simpleType>
</xs:schema>

9
include/NPAPILib.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
enum AddInComponentType
{
eAddInCom = 1,
eAddInNative,
eAddInJava,
eAddInvalid = -1
};

180
include/addin.idl Normal file
View File

@ -0,0 +1,180 @@
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(AB634001-F13D-11d0-A459-004095E1DAEA),
helpstring("IInitDone Interface"),
pointer_default(unique)
]
interface IInitDone : IUnknown
{
[helpstring("method Init")] HRESULT Init([in] IDispatch *pConnection);
[helpstring("method Done")] HRESULT Done();
[helpstring("method GetInfo")] HRESULT GetInfo([in,out] SAFEARRAY (VARIANT) *pInfo);
};
[
object,
uuid(AB634002-F13D-11d0-A459-004095E1DAEA),
helpstring("IPropertyProfile Interface"),
pointer_default(unique)
]
interface IPropertyProfile : IPropertyBag
{
[helpstring("method RegisterProfileAs")] HRESULT RegisterProfileAs(BSTR bstrProfileName);
};
[
object,
uuid(ab634004-f13d-11d0-a459-004095e1daea),
helpstring("IAsyncEvent Interface"),
pointer_default(unique)
]
interface IAsyncEvent : IUnknown
{
[helpstring("method SetEventBufferDepth")] HRESULT SetEventBufferDepth(long lDepth);
[helpstring("method GetEventBufferDepth")] HRESULT GetEventBufferDepth(long *plDepth);
[helpstring("method ExternalEvent")] HRESULT ExternalEvent(BSTR bstrSource, BSTR bstrMessage, BSTR bstrData);
[helpstring("method CleanBuffer")] HRESULT CleanBuffer();
};
[
object,
uuid(E88A191E-8F52-4261-9FAE-FF7AA84F5D7E),
helpstring("ILocale Interface"),
pointer_default(unique)
]
interface ILocale : IUnknown
{
[helpstring("method SetLocale")] HRESULT SetLocale(BSTR bstrLocale);
};
[
object,
uuid(AB634003-F13D-11d0-A459-004095E1DAEA),
helpstring("ILanguageExtender Interface"),
pointer_default(unique)
]
interface ILanguageExtender : IUnknown
{
[helpstring("method RegisterExtensionAs")] HRESULT RegisterExtensionAs([in,out]BSTR *bstrExtensionName);
[helpstring("method GetNProps")] HRESULT GetNProps([in,out]long *plProps);
[helpstring("method FindProp")] HRESULT FindProp([in]BSTR bstrPropName,[in,out]long *plPropNum);
[helpstring("method GetPropName")] HRESULT GetPropName([in]long lPropNum,[in]long lPropAlias,[in,out]BSTR *pbstrPropName);
[helpstring("method GetPropVal")] HRESULT GetPropVal([in]long lPropNum,[in,out]VARIANT *pvarPropVal);
[helpstring("method SetPropVal")] HRESULT SetPropVal([in]long lPropNum,[in]VARIANT *varPropVal);
[helpstring("method IsPropReadable")] HRESULT IsPropReadable([in]long lPropNum,[in,out]BOOL *pboolPropRead);
[helpstring("method IsPropWritable")] HRESULT IsPropWritable([in]long lPropNum,[in,out]BOOL *pboolPropWrite);
[helpstring("method GetNMethods")] HRESULT GetNMethods([in,out]long *plMethods);
[helpstring("method FindMethod")] HRESULT FindMethod(BSTR bstrMethodName,[in,out]long *plMethodNum);
[helpstring("method GetMethodName")] HRESULT GetMethodName([in]long lMethodNum,[in]long lMethodAlias,[in,out]BSTR *pbstrMethodName);
[helpstring("method GetNParams")] HRESULT GetNParams([in]long lMethodNum,[in,out]long *plParams);
[helpstring("method GetParamDefValue")] HRESULT GetParamDefValue([in]long lMethodNum,[in]long lParamNum,[in,out]VARIANT *pvarParamDefValue);
[helpstring("method HasRetVal")] HRESULT HasRetVal([in]long lMethodNum,[in,out]BOOL *pboolRetValue);
[helpstring("method CallAsProc")] HRESULT CallAsProc([in]long lMethodNum,[in,out] SAFEARRAY (VARIANT) *paParams);
[helpstring("method CallAsFunc")] HRESULT CallAsFunc([in]long lMethodNum,[in,out] VARIANT *pvarRetValue,[in,out] SAFEARRAY (VARIANT) *paParams);
};
[
object,
uuid(ab634005-f13d-11d0-a459-004095e1daea),
helpstring("IStatusLine Interface"),
pointer_default(unique)
]
interface IStatusLine : IUnknown
{
[helpstring("method SetStatusLine")] HRESULT SetStatusLine(BSTR bstrStatusLine);
[helpstring("method ResetStatusLine")] HRESULT ResetStatusLine();
};
[
object,
uuid(efe19ea0-09e4-11d2-a601-008048da00de),
helpstring("IExtWndsSupport Interface"),
pointer_default(unique)
]
interface IExtWndsSupport : IUnknown
{
[helpstring("method GetAppMainFrame")] HRESULT GetAppMainFrame([in,out]HWND *hwnd);
[helpstring("method GetAppMDIFrame")] HRESULT GetAppMDIFrame([in,out]HWND *hwnd);
[helpstring("method CreateAddInWindow")] HRESULT CreateAddInWindow([in]BSTR bstrProgID, [in]BSTR bstrWindowName, [in]long dwStyles, [in]long dwExStyles, [in]RECT *rctl, [in]long Flags, [in,out]HWND *pHwnd, [in,out]IDispatch **pDisp);
};
cpp_quote("typedef enum")
cpp_quote("{")
cpp_quote(" eAQDModeOK,")
cpp_quote(" eAQDModeOKCancel,")
cpp_quote(" eAQDModeAbortRetryIgnore,")
cpp_quote(" eAQDModeYesNoCancel,")
cpp_quote(" eAQDModeYesNo,")
cpp_quote(" eAQDModeRetryCancel,")
cpp_quote("} AddInQuestionDialogModeEnum;")
// êîäû âîçâðàòà äèàëîãîâ
cpp_quote("typedef enum ")
cpp_quote("{")
cpp_quote(" eADlgRetCodeTimeout = -1,")
cpp_quote(" eADlgRetCodeOK = 1,")
cpp_quote(" eADlgRetCodeCancel,")
cpp_quote(" eADlgRetCodeAbort,")
cpp_quote(" eADlgRetCodeRetry,")
cpp_quote(" eADlgRetCodeIgnore,")
cpp_quote(" eADlgRetCodeYes,")
cpp_quote(" eADlgRetCodeNo,")
cpp_quote("} AddInDlgRetCodesEnum;")
typedef struct _Button{
VARIANT value;
BSTR presentation;
} Button;
[
object,
uuid(3C2136B5-B35A-4FAC-9AC3-F77F361E9467),
helpstring("IMsgBox Interface"),
pointer_default(unique)
]
interface IMsgBox : IUnknown
{
[helpstring("method QueryBox")] HRESULT QueryBox([in]BSTR queryText, [in]Button* buttons, [in]int sizeButtons, [in,out]VARIANT *retVal,
[in, defaultvalue(0)]long timeout, [in, defaultvalue(0)]int defButton, [in, defaultvalue("")]BSTR caption, [in, defaultvalue(0)]int timeoutButton);
[helpstring("method MessageBox")] HRESULT MessageBox([in] BSTR text, [in,out] VARIANT* retVal,
[in, defaultvalue(0)] long timeout, [in, defaultvalue(0)] BSTR caption);
};
typedef [v1_enum] enum _AppType {
eAppUnknown = -1,
eAppThinClient = 0,
eAppThickClient,
eAppWebClient,
eAppServer,
eAppExtConn,
} AppType;
typedef struct _AppInfo {
BSTR AppVersion;
BSTR UserAgentInformation;
const AppType Application;
} AppInfo;
[
object,
uuid(AAABE126-2230-4a7d-9DDA-8987FD2A62BA),
helpstring("IPlatformInfo Interface"),
pointer_default(unique)
]
interface IPlatformInfo : IUnknown
{
[helpstring("method GetPlatformInfo")] HRESULT GetPlatformInfo([out]AppInfo** info);
};
[
object,
uuid(3F3BC8D5-C0AC-4544-8A76-632EC0989318),
dual,
nonextensible,
helpstring("IButtonIE Interface"),
pointer_default(unique)
]
interface IButtonIE : IDispatch{
[local] void init([in] VARIANT first, [in] VARIANT second);
[propget] HRESULT text([out, retval] VARIANT* data);
[propget] HRESULT value([out, retval] VARIANT* data);
};

9
include/addinlib.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
enum AddInComponentType
{
eAddInCom = 1,
eAddInNative,
eAddInJava,
eAddInvalid = -1
};

115
include/com.h Normal file
View File

@ -0,0 +1,115 @@
#ifndef __COM_H__
#define __COM_H__
#if defined(__linux__) || defined(__APPLE__)
#include <uuid/uuid.h>
#include <dlfcn.h>
#pragma GCC system_header
typedef long HRESULT;
#ifdef __GNUC__
#define STDMETHODCALLTYPE __attribute__ ((__stdcall__))
#define DECLSPEC_NOTHROW __attribute__ ((nothrow))
#define STDMETHOD(method) virtual DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE method
#else
#define STDMETHODCALLTYPE
#endif
#define __stdcall STDMETHODCALLTYPE
#define near
#define far
#define CONST const
#define FAR far
typedef unsigned long DWORD;
typedef int BOOL;
typedef short SHORT;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef BOOL near *PBOOL;
typedef BOOL far *LPBOOL;
typedef BYTE near *PBYTE;
typedef BYTE far *LPBYTE;
typedef int near *PINT;
typedef int far *LPINT;
typedef WORD near *PWORD;
typedef WORD far *LPWORD;
typedef long far *LPLONG;
typedef DWORD near *PDWORD;
typedef DWORD far *LPDWORD;
typedef void far *LPVOID;
typedef CONST void far *LPCVOID;
typedef wchar_t *BSTR;
typedef long SCODE;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned int *PUINT;
typedef wchar_t WCHAR;
typedef wchar_t OLECHAR;
typedef wchar_t *LPOLESTR;
typedef const wchar_t *LPCOLESTR;
typedef DWORD LCID;
typedef PDWORD PLCID;
typedef long LONG;
typedef unsigned long ULONG;
typedef long long LONGLONG;
typedef unsigned long long ULONGLONG;
typedef LONG DISPID;
typedef double DOUBLE;
typedef double DATE;
typedef short VARIANT_BOOL;
typedef void *PVOID;
typedef char CHAR;
typedef unsigned short USHORT;
typedef void *HMODULE;
#define OLESTR(str) L##str
typedef uuid_t GUID;
typedef uuid_t IID;
typedef uuid_t UUID;
#define REFIID const IID &
#define MAX_PATH 260
#define IsEqualIID(x,y) uuid_compare((x),(y))
#ifdef __GNUC__
#define LoadLibraryA(x) dlopen((x), RTLD_LAZY)
#define FreeLibrary(x) dlclose((x))
#define GetProcAddress(x, y) dlsym((x), (y))
#endif //__GNUC__
#define E_FAIL 0x80004005L
#define S_OK 0L
#define S_FALSE 1L
#define E_NOINTERFACE 0x80004002L
#define E_NOTIMPL 0x80004001L
#define E_INVALIDARG 0x80070057L
#define E_UNEXPECTED 0x8000FFFFL
#define E_OUTOFMEMORY 0x8007000EL
#define DISP_E_UNKNOWNNAME 0x80020006L
#define DISPID_UNKNOWN ( -1 )
#define TRUE 1
#define FALSE 0
typedef long ITypeInfo;
#if defined (__GNUC__) && !defined (NONAMELESSUNION)
__extension__ /* no named members */
#endif
union tCY {
__extension__ struct
{
unsigned long Lo;
long Hi;
};
long long int64;
};
typedef union tagCY CY;
#define CLSIDFromString(x,y) uuid_parse((x),(unsigned char*)(y))
#endif //defined(__linux__) || defined(__APPLE__)
#endif //__COM_H__

245
include/types.h Normal file
View File

@ -0,0 +1,245 @@
#ifndef __CON_TYPES_H__
#define __CON_TYPES_H__
#ifdef _WINDOWS
#include <windows.h>
#endif
#if __GNUC__ >=3
#pragma GCC system_header
#endif
#include "com.h"
#include <time.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#define EXTERN_C extern "C"
#ifdef __GNUC__
#define _ANONYMOUS_UNION __extension__
#define _ANONYMOUS_STRUCT __extension__
#else
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif //__GNUC__
#ifdef NONAMELESSUNION
#define __VARIANT_NAME_1 u
#define __VARIANT_NAME_2 iface
#define __VARIANT_NAME_3 str
#define __VARIANT_NAME_4 wstr
#else
#define __VARIANT_NAME_1
#define __VARIANT_NAME_2
#define __VARIANT_NAME_3
#define __VARIANT_NAME_4
#endif //NONAMELESSUNION
#define RESULT_FROM_ERRNO(x) ((long)(x) <= 0 ? ((long)(x)) \
: ((long) (((x) & 0x0000FFFF) | (BASE_ERRNO << 16) | 0x80000000)))
#define ADDIN_E_NONE 1000
#define ADDIN_E_ORDINARY 1001
#define ADDIN_E_ATTENTION 1002
#define ADDIN_E_IMPORTANT 1003
#define ADDIN_E_VERY_IMPORTANT 1004
#define ADDIN_E_INFO 1005
#define ADDIN_E_FAIL 1006
#define ADDIN_E_MSGBOX_ATTENTION 1007
#define ADDIN_E_MSGBOX_INFO 1008
#define ADDIN_E_MSGBOX_FAIL 1009
#ifndef ADDIN_API
#ifdef _WINDOWS
#define ADDIN_API __stdcall
#else
//#define ADDIN_API __attribute__ ((__stdcall__))
#define ADDIN_API
#endif //_WINDOWS
#endif //ADDIN_API
#ifndef _WINDOWS
////////////////////////////////////////////////////////////////////////////
// sized integer types
typedef __int8 int8_t ; ///< 8-bit integer
typedef unsigned __int8 uint8_t ; ///< 8-bit unsigned integer
typedef __int16 int16_t ; ///< 16-bit integer
typedef unsigned __int16 uint16_t ; ///< 16-bit unsigned integer
typedef __int32 int32_t ; ///< 32-bit integer
typedef unsigned __int32 uint32_t ; ///< 32-bit unsigned integer
typedef __int64 int64_t ; ///< 64-bit integer
typedef unsigned __int64 uint64_t ; ///< 64-bit unsigned integer
#else
#include <stdint.h>
#endif
#ifdef _WINDOWS
#define WCHAR_T wchar_t
#else
#define WCHAR_T uint16_t
#endif //_WINDOWS
typedef unsigned short TYPEVAR;
enum ENUMVAR
{
VTYPE_EMPTY = 0,
VTYPE_NULL,
VTYPE_I2, //int16_t
VTYPE_I4, //int32_t
VTYPE_R4, //float
VTYPE_R8, //double
VTYPE_DATE, //DATE (double)
VTYPE_TM, //struct tm
VTYPE_PSTR, //struct str string
VTYPE_INTERFACE, //struct iface
VTYPE_ERROR, //int32_t errCode
VTYPE_BOOL, //bool
VTYPE_VARIANT, //struct _tVariant *
VTYPE_I1, //int8_t
VTYPE_UI1, //uint8_t
VTYPE_UI2, //uint16_t
VTYPE_UI4, //uint32_t
VTYPE_I8, //int64_t
VTYPE_UI8, //uint64_t
VTYPE_INT, //int Depends on architecture
VTYPE_UINT, //unsigned int Depends on architecture
VTYPE_HRESULT, //long hRes
VTYPE_PWSTR, //struct wstr
VTYPE_BLOB, //means in struct str binary data contain
VTYPE_CLSID, //UUID
VTYPE_STR_BLOB = 0xfff,
VTYPE_VECTOR = 0x1000,
VTYPE_ARRAY = 0x2000,
VTYPE_BYREF = 0x4000, //Only with struct _tVariant *
VTYPE_RESERVED = 0x8000,
VTYPE_ILLEGAL = 0xffff,
VTYPE_ILLEGALMASKED = 0xfff,
VTYPE_TYPEMASK = 0xfff
} ;
#if defined (__GNUC__) && !defined (NONAMELESSUNION)
__extension__ /* no named members */
#endif
struct _tVariant
{
_ANONYMOUS_UNION union
{
int8_t i8Val;
int16_t shortVal;
int32_t lVal;
int intVal;
unsigned int uintVal;
int64_t llVal;
uint8_t ui8Val;
uint16_t ushortVal;
uint32_t ulVal;
uint64_t ullVal;
int32_t errCode;
long hRes;
float fltVal;
double dblVal;
bool bVal;
char chVal;
wchar_t wchVal;
DATE date;
IID IDVal;
struct _tVariant *pvarVal;
struct tm tmVal;
_ANONYMOUS_STRUCT struct
{
void* pInterfaceVal;
IID InterfaceID;
} __VARIANT_NAME_2/*iface*/;
_ANONYMOUS_STRUCT struct
{
char* pstrVal;
uint32_t strLen; //count of bytes
} __VARIANT_NAME_3/*str*/;
_ANONYMOUS_STRUCT struct
{
WCHAR_T* pwstrVal;
uint32_t wstrLen; //count of symbol
} __VARIANT_NAME_4/*wstr*/;
} __VARIANT_NAME_1;
uint32_t cbElements; //Dimension for an one-dimensional array in pvarVal
TYPEVAR vt;
};
typedef struct _tVariant tVariant;
typedef tVariant tVariantArg;
#if defined(NONAMELESSUNION)
#define TV_JOIN(X, Y) ((X)->u.Y)
#else
#define TV_JOIN(X, Y) ((X)->Y)
#endif
#define TV_VT(X) ((X)->vt)
#define TV_ISBYREF(X) (TV_VT(X)&VT_BYREF)
#define TV_ISARRAY(X) (TV_VT(X)&VT_ARRAY)
#define TV_ISVECTOR(X) (TV_VT(X)&VT_VECTOR)
#define TV_NONE(X) TV_I2(X)
#define TV_UI1(X) TV_JOIN(X, ui8Val)
#define TV_I2(X) TV_JOIN(X, shortVal)
#define TV_I4(X) TV_JOIN(X, lVal)
#define TV_I8(X) TV_JOIN(X, llVal)
#define TV_R4(X) TV_JOIN(X, fltVal)
#define TV_R8(X) TV_JOIN(X, dblVal)
#define TV_I1(X) TV_JOIN(X, i8Val)
#define TV_UI2(X) TV_JOIN(X, ushortVal)
#define TV_UI4(X) TV_JOIN(X, ulVal)
#define TV_UI8(X) TV_JOIN(X, ullVal)
#define TV_INT(X) TV_JOIN(X, intVal)
#define TV_UINT(X) TV_JOIN(X, uintVal)
#ifdef _WIN64
#define TV_INT_PTR(X) TV_JOIN(X, llVal)
#define TV_UINT_PTR(X) TV_JOIN(X, ullVal)
#else
#define TV_INT_PTR(X) TV_JOIN(X, lVal)
#define TV_UINT_PTR(X) TV_JOIN(X, ulVal)
#endif
#define TV_DATE(X) TV_JOIN(X, date)
#define TV_STR(X) TV_JOIN(X, pstrVal)
#define TV_WSTR(X) TV_JOIN(X, pwstrVal)
#define TV_BOOL(X) TV_JOIN(X, bVal)
#define TV_UNKNOWN(X) TV_JOIN(X, pInterfaceVal)
#define TV_VARIANTREF(X) TV_JOIN(X, pvarVal)
void tVarInit(tVariant* tvar);
inline
void tVarInit(tVariant* tvar)
{
assert(tvar != NULL);
memset(tvar, 0, sizeof(tVariant));
TV_VT(tvar) = VTYPE_EMPTY;
}
//----------------------------------------------------------------------------//
// static setter functions...
#define DATA_SET_BEGIN(data_) \
tVarInit(data_);
#define DATA_SET_END(data_, type_) \
TV_VT(data_) = type_;
#define DATA_SET(data_, type_, member_, value_) \
DATA_SET_BEGIN(data_) \
TV_JOIN(data_, member_) = value_; \
DATA_SET_END(data_, type_)
#define DATA_SET_WITH_CAST(data_, type_, member_, cast_, value_) \
DATA_SET_BEGIN(data_) \
TV_JOIN(data_, member_) = cast_ value_; \
DATA_SET_END(data_, type_)
#endif //__CON_TYPES_H__

8
stdafx.cpp Normal file
View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// AddInNative.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

10
stdafx.h Normal file
View File

@ -0,0 +1,10 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#ifndef __STDAFX_H__
#define __STDAFX_H__
#ifndef __linux__
#include <windows.h>
#endif //__linux__
#endif //__STDAFX_H__