changing data type to ascii so diffs will work
This commit is contained in:
@@ -1,57 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize
|
||||
(JNIEnv *env, jclass cls, jint mode)
|
||||
{
|
||||
int threadModel = mode;
|
||||
CoInitializeEx(NULL, threadModel);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize
|
||||
(JNIEnv *env, jclass cls)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize
|
||||
(JNIEnv *env, jclass cls, jint mode)
|
||||
{
|
||||
int threadModel = mode;
|
||||
CoInitializeEx(NULL, threadModel);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize
|
||||
(JNIEnv *env, jclass cls)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_jacob_com_ComThread */
|
||||
|
||||
#ifndef _Included_com_jacob_com_ComThread
|
||||
#define _Included_com_jacob_com_ComThread
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_ComThread
|
||||
* Method: doCoInitialize
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_ComThread
|
||||
* Method: doCoUninitialize
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_jacob_com_ComThread */
|
||||
|
||||
#ifndef _Included_com_jacob_com_ComThread
|
||||
#define _Included_com_jacob_com_ComThread
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_ComThread
|
||||
* Method: doCoInitialize
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoInitialize
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_ComThread
|
||||
* Method: doCoUninitialize
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_ComThread_doCoUninitialize
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
880
jni/Dispatch.cpp
880
jni/Dispatch.cpp
@@ -1,440 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#define DISP_FLD "m_pDispatch"
|
||||
|
||||
// extract a IDispatch from a jobject
|
||||
IDispatch *extractDispatch(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, DISP_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
IDispatch *v = (IDispatch *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
||||
(JNIEnv *env, jobject _this, jstring _iid)
|
||||
{
|
||||
// get the current IDispatch
|
||||
IDispatch *pIDispatch = extractDispatch(env, _this);
|
||||
if (!pIDispatch) return NULL;
|
||||
const char *siid = env->GetStringUTFChars(_iid, NULL);
|
||||
USES_CONVERSION;
|
||||
LPOLESTR bsIID = A2W(siid);
|
||||
env->ReleaseStringUTFChars(_iid, siid);
|
||||
IID iid;
|
||||
HRESULT hr = IIDFromString(bsIID, &iid);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't get IID from String", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// try to call QI on the passed IID
|
||||
IDispatch *disp;
|
||||
hr = pIDispatch->QueryInterface(iid, (void **)&disp);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "QI on IID from String Failed", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jclass autoClass = env->FindClass("com/jacob/com/Dispatch");
|
||||
jmethodID autoCons =
|
||||
env->GetMethodID(autoClass, "<init>", "(I)V");
|
||||
// construct a Dispatch object to return
|
||||
// I am copying the pointer to java
|
||||
// jacob-msg 1817 - SF 1053871 : QueryInterface already called AddRef!!
|
||||
//if (disp) disp->AddRef();
|
||||
jobject newAuto = env->NewObject(autoClass, autoCons, disp);
|
||||
return newAuto;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||
(JNIEnv *env, jobject _this, jstring _progid)
|
||||
{
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||
|
||||
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||
CLSID clsid;
|
||||
HRESULT hr;
|
||||
IUnknown *punk = NULL;
|
||||
IDispatch *pIDispatch;
|
||||
USES_CONVERSION;
|
||||
LPOLESTR bsProgId = A2W(progid);
|
||||
if (strchr(progid,':'))
|
||||
{
|
||||
env->ReleaseStringUTFChars(_progid, progid);
|
||||
// it's a moniker
|
||||
hr = CoGetObject(bsProgId, NULL, IID_IUnknown, (LPVOID *)&punk);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't find moniker", hr);
|
||||
return;
|
||||
}
|
||||
IClassFactory *pIClass;
|
||||
// if it was a clsid moniker, I may have a class factory
|
||||
hr = punk->QueryInterface(IID_IClassFactory, (void **)&pIClass);
|
||||
if (!SUCCEEDED(hr)) goto doDisp;
|
||||
punk->Release();
|
||||
// try to create an instance
|
||||
hr = pIClass->CreateInstance(NULL, IID_IUnknown, (void **)&punk);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't create moniker class instance", hr);
|
||||
return;
|
||||
}
|
||||
pIClass->Release();
|
||||
goto doDisp;
|
||||
}
|
||||
env->ReleaseStringUTFChars(_progid, progid);
|
||||
// Now, try to find an IDispatch interface for progid
|
||||
hr = CLSIDFromProgID(bsProgId, &clsid);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't get object clsid from progid", hr);
|
||||
return;
|
||||
}
|
||||
// standard creation
|
||||
hr = CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER,IID_IUnknown, (void **)&punk);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ThrowComFail(env, "Can't co-create object", hr);
|
||||
return;
|
||||
}
|
||||
doDisp:
|
||||
|
||||
// now get an IDispatch pointer from the IUnknown
|
||||
hr = punk->QueryInterface(IID_IDispatch, (void **)&pIDispatch);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ThrowComFail(env, "Can't QI object for IDispatch", hr);
|
||||
return;
|
||||
}
|
||||
// CoCreateInstance called AddRef
|
||||
punk->Release();
|
||||
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||
jint num = env->GetIntField(_this, jf);
|
||||
|
||||
IDispatch *disp = (IDispatch *)num;
|
||||
if (disp) {
|
||||
disp->Release();
|
||||
env->SetIntField(_this, jf, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
name2ID(IDispatch *pIDispatch, const char *prop, DISPID *dispid, long lcid)
|
||||
{
|
||||
HRESULT hresult;
|
||||
USES_CONVERSION;
|
||||
LPOLESTR propOle = A2W(prop);
|
||||
hresult = pIDispatch->GetIDsOfNames(IID_NULL,(LPOLESTR*)&propOle,1,lcid,dispid);
|
||||
return hresult;
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
|
||||
(JNIEnv *env, jclass clazz, jobject disp, jint lcid, jobjectArray names)
|
||||
{
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return NULL;
|
||||
|
||||
int l = env->GetArrayLength(names);
|
||||
int i;
|
||||
LPOLESTR *lps = (LPOLESTR *)CoTaskMemAlloc(l * sizeof(LPOLESTR));
|
||||
DISPID *dispid = (DISPID *)CoTaskMemAlloc(l * sizeof(DISPID));
|
||||
for(i=0;i<l;i++)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
jstring s = (jstring)env->GetObjectArrayElement(names, i);
|
||||
const char *nm = env->GetStringUTFChars(s, NULL);
|
||||
LPOLESTR nmos = A2W(nm);
|
||||
env->ReleaseStringUTFChars(s, nm);
|
||||
lps[i] = nmos;
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
HRESULT hr = pIDispatch->GetIDsOfNames(IID_NULL,lps,l,lcid,dispid);
|
||||
if (FAILED(hr)) {
|
||||
CoTaskMemFree(lps);
|
||||
CoTaskMemFree(dispid);
|
||||
char buf[1024];
|
||||
strcpy(buf, "Can't map names to dispid:");
|
||||
for(i=0;i<l;i++)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
jstring s = (jstring)env->GetObjectArrayElement(names, i);
|
||||
const char *nm = env->GetStringUTFChars(s, NULL);
|
||||
strcat(buf, nm);
|
||||
env->ReleaseStringUTFChars(s, nm);
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
ThrowComFail(env, buf, hr);
|
||||
return NULL;
|
||||
}
|
||||
jintArray iarr = env->NewIntArray(l);
|
||||
env->SetIntArrayRegion(iarr, i, l, dispid);
|
||||
CoTaskMemFree(lps);
|
||||
CoTaskMemFree(dispid);
|
||||
return iarr;
|
||||
}
|
||||
|
||||
static char* BasicToCharString(const BSTR inBasicString)
|
||||
{
|
||||
char* charString = NULL;
|
||||
const size_t charStrSize = ::SysStringLen(inBasicString) + 1;
|
||||
if (charStrSize > 1)
|
||||
{
|
||||
charString = new char[charStrSize];
|
||||
size_t len = ::wcstombs(charString, inBasicString, charStrSize);
|
||||
}
|
||||
else
|
||||
charString = ::strdup("");
|
||||
|
||||
return charString;
|
||||
}
|
||||
|
||||
static char* CreateErrorMsgFromResult(HRESULT inResult)
|
||||
{
|
||||
char* msg = NULL;
|
||||
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM, NULL, inResult,MAKELANGID(LANG_NEUTRAL,
|
||||
SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL);
|
||||
if (msg == NULL)
|
||||
msg = ::strdup("An unknown COM error has occured.");
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static char* CreateErrorMsgFromInfo(HRESULT inResult, EXCEPINFO* ioInfo,
|
||||
const char* methName)
|
||||
{
|
||||
char* msg = NULL;
|
||||
|
||||
// If this is a dispatch exception (triggered by an Invoke message),
|
||||
// then we have to take some additional steps to process the error
|
||||
// message.
|
||||
if (inResult == DISP_E_EXCEPTION)
|
||||
{
|
||||
// Check to see if the server deferred filling in the exception
|
||||
// information. If so, make the call to populate the structure.
|
||||
if (ioInfo->pfnDeferredFillIn != NULL)
|
||||
(*(ioInfo->pfnDeferredFillIn))(ioInfo);
|
||||
|
||||
// Build the error message from exception information content.
|
||||
char* source = ::BasicToCharString(ioInfo->bstrSource);
|
||||
char* desc = ::BasicToCharString(ioInfo->bstrDescription);
|
||||
const size_t MSG_LEN = ::strlen(methName) + ::strlen(source) + ::strlen(desc) + 128;
|
||||
msg = new char[MSG_LEN];
|
||||
::strncpy(msg, "Invoke of: ", MSG_LEN);
|
||||
::strncat(msg, methName, MSG_LEN);
|
||||
::strncat(msg, "\nSource: ", MSG_LEN);
|
||||
::strncat(msg, source, MSG_LEN);
|
||||
::strncat(msg, "\nDescription: ", MSG_LEN);
|
||||
::strncat(msg, desc, MSG_LEN);
|
||||
::strncat(msg, "\n", MSG_LEN);
|
||||
delete source;
|
||||
delete desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* msg2 = CreateErrorMsgFromResult(inResult);
|
||||
const size_t MSG_LEN = ::strlen(methName) + ::strlen(msg2) + 128;
|
||||
msg = new char[MSG_LEN];
|
||||
::strncpy(msg, "A COM exception has been encountered:\n"
|
||||
"At Invoke of: ", MSG_LEN);
|
||||
::strncat(msg, methName, MSG_LEN);
|
||||
::strncat(msg, "\nDescription: ", MSG_LEN);
|
||||
::strncat(msg, msg2, MSG_LEN);
|
||||
// jacob-msg 1075 - SF 1053872 : Documentation says "use LocalFree"!!
|
||||
//delete msg2;
|
||||
LocalFree(msg2);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
#define SETDISPPARAMS(dp, numArgs, pvArgs, numNamed, pNamed) \
|
||||
{\
|
||||
(dp).cArgs = numArgs; \
|
||||
(dp).rgvarg = pvArgs; \
|
||||
(dp).cNamedArgs = numNamed; \
|
||||
(dp).rgdispidNamedArgs = pNamed; \
|
||||
}
|
||||
|
||||
#define SETNOPARAMS(dp) SETDISPPARAMS(dp, 0, NULL, 0, NULL)
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
||||
(JNIEnv *env, jclass clazz,
|
||||
jobject disp, jstring name, jint dispid,
|
||||
jint lcid, jint wFlags, jobjectArray vArg, jintArray uArgErr)
|
||||
{
|
||||
DISPPARAMS dispparams;
|
||||
EXCEPINFO excepInfo;
|
||||
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return NULL;
|
||||
|
||||
int dispID = dispid;
|
||||
if (name != NULL)
|
||||
{
|
||||
const char *nm = env->GetStringUTFChars(name, NULL);
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = name2ID(pIDispatch, nm, (long *)&dispID, lcid))) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "Can't map name to dispid: %s", nm);
|
||||
ThrowComFail(env, buf, -1);
|
||||
return NULL;
|
||||
}
|
||||
env->ReleaseStringUTFChars(name, nm);
|
||||
}
|
||||
|
||||
int num_args = env->GetArrayLength(vArg);
|
||||
int i, j;
|
||||
VARIANT *varr = NULL;
|
||||
if (num_args)
|
||||
{
|
||||
varr = (VARIANT *)CoTaskMemAlloc(num_args*sizeof(VARIANT));
|
||||
/* reverse args for dispatch */
|
||||
for(i=num_args-1,j=0;0<=i;i--,j++)
|
||||
{
|
||||
VariantInit(&varr[j]);
|
||||
jobject arg = env->GetObjectArrayElement(vArg, i);
|
||||
VARIANT *v = extractVariant(env, arg);
|
||||
// no escape from copy?
|
||||
VariantCopy(&varr[j], v);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
}
|
||||
// prepare a new return value
|
||||
jclass variantClass = env->FindClass("com/jacob/com/Variant");
|
||||
jmethodID variantCons =
|
||||
env->GetMethodID(variantClass, "<init>", "()V");
|
||||
// construct a variant to return
|
||||
jobject newVariant = env->NewObject(variantClass, variantCons);
|
||||
// get the VARIANT from the newVariant
|
||||
VARIANT *v = extractVariant(env, newVariant);
|
||||
DISPID dispidPropertyPut = DISPID_PROPERTYPUT;
|
||||
|
||||
// determine how to dispatch
|
||||
switch (wFlags)
|
||||
{
|
||||
case DISPATCH_PROPERTYGET: // GET
|
||||
case DISPATCH_METHOD: // METHOD
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
{
|
||||
SETDISPPARAMS(dispparams, num_args, varr, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
case DISPATCH_PROPERTYPUTREF: // jacob-msg 1075 - SF 1053872
|
||||
{
|
||||
SETDISPPARAMS(dispparams, num_args, varr, 1, &dispidPropertyPut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = 0;
|
||||
jint count = env->GetArrayLength(uArgErr);
|
||||
if ( count != 0 )
|
||||
{
|
||||
jint *uAE = env->GetIntArrayElements(uArgErr, NULL);
|
||||
hr = pIDispatch->Invoke(dispID,IID_NULL,
|
||||
lcid,wFlags,&dispparams,v,&excepInfo,(unsigned int *)uAE);
|
||||
env->ReleaseIntArrayElements(uArgErr, uAE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = pIDispatch->Invoke(dispID,IID_NULL,
|
||||
lcid,wFlags,&dispparams,v,&excepInfo, NULL);
|
||||
}
|
||||
if (num_args)
|
||||
{
|
||||
// to account for inouts, I need to copy the inputs back to
|
||||
// the java array after the method returns
|
||||
// this occurs, for example, in the ADO wrappers
|
||||
for(i=num_args-1,j=0;0<=i;i--,j++)
|
||||
{
|
||||
jobject arg = env->GetObjectArrayElement(vArg, i);
|
||||
VARIANT *v = extractVariant(env, arg);
|
||||
// reverse copy
|
||||
VariantCopy(v, &varr[j]);
|
||||
// clear out the temporary variant
|
||||
VariantClear(&varr[j]);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (varr) CoTaskMemFree(varr);
|
||||
|
||||
// check for error and display a somewhat verbose error message
|
||||
if (!SUCCEEDED(hr)) {
|
||||
const char *nm = env->GetStringUTFChars(name, NULL);
|
||||
char *buf = CreateErrorMsgFromInfo(hr, &excepInfo, nm);
|
||||
env->ReleaseStringUTFChars(name, nm);
|
||||
|
||||
// jacob-msg 3696 - SF 1053866
|
||||
if(hr == DISP_E_EXCEPTION)
|
||||
{
|
||||
if(excepInfo.scode != 0)
|
||||
{
|
||||
hr = excepInfo.scode;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = _com_error::WCodeToHRESULT(excepInfo.wCode);
|
||||
}
|
||||
}
|
||||
|
||||
ThrowComFail(env, buf, hr);
|
||||
if (buf) delete buf;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newVariant;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#define DISP_FLD "m_pDispatch"
|
||||
|
||||
// extract a IDispatch from a jobject
|
||||
IDispatch *extractDispatch(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, DISP_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
IDispatch *v = (IDispatch *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
||||
(JNIEnv *env, jobject _this, jstring _iid)
|
||||
{
|
||||
// get the current IDispatch
|
||||
IDispatch *pIDispatch = extractDispatch(env, _this);
|
||||
if (!pIDispatch) return NULL;
|
||||
const char *siid = env->GetStringUTFChars(_iid, NULL);
|
||||
USES_CONVERSION;
|
||||
LPOLESTR bsIID = A2W(siid);
|
||||
env->ReleaseStringUTFChars(_iid, siid);
|
||||
IID iid;
|
||||
HRESULT hr = IIDFromString(bsIID, &iid);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't get IID from String", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// try to call QI on the passed IID
|
||||
IDispatch *disp;
|
||||
hr = pIDispatch->QueryInterface(iid, (void **)&disp);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "QI on IID from String Failed", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jclass autoClass = env->FindClass("com/jacob/com/Dispatch");
|
||||
jmethodID autoCons =
|
||||
env->GetMethodID(autoClass, "<init>", "(I)V");
|
||||
// construct a Dispatch object to return
|
||||
// I am copying the pointer to java
|
||||
// jacob-msg 1817 - SF 1053871 : QueryInterface already called AddRef!!
|
||||
//if (disp) disp->AddRef();
|
||||
jobject newAuto = env->NewObject(autoClass, autoCons, disp);
|
||||
return newAuto;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||
(JNIEnv *env, jobject _this, jstring _progid)
|
||||
{
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||
|
||||
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||
CLSID clsid;
|
||||
HRESULT hr;
|
||||
IUnknown *punk = NULL;
|
||||
IDispatch *pIDispatch;
|
||||
USES_CONVERSION;
|
||||
LPOLESTR bsProgId = A2W(progid);
|
||||
if (strchr(progid,':'))
|
||||
{
|
||||
env->ReleaseStringUTFChars(_progid, progid);
|
||||
// it's a moniker
|
||||
hr = CoGetObject(bsProgId, NULL, IID_IUnknown, (LPVOID *)&punk);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't find moniker", hr);
|
||||
return;
|
||||
}
|
||||
IClassFactory *pIClass;
|
||||
// if it was a clsid moniker, I may have a class factory
|
||||
hr = punk->QueryInterface(IID_IClassFactory, (void **)&pIClass);
|
||||
if (!SUCCEEDED(hr)) goto doDisp;
|
||||
punk->Release();
|
||||
// try to create an instance
|
||||
hr = pIClass->CreateInstance(NULL, IID_IUnknown, (void **)&punk);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't create moniker class instance", hr);
|
||||
return;
|
||||
}
|
||||
pIClass->Release();
|
||||
goto doDisp;
|
||||
}
|
||||
env->ReleaseStringUTFChars(_progid, progid);
|
||||
// Now, try to find an IDispatch interface for progid
|
||||
hr = CLSIDFromProgID(bsProgId, &clsid);
|
||||
if (FAILED(hr)) {
|
||||
ThrowComFail(env, "Can't get object clsid from progid", hr);
|
||||
return;
|
||||
}
|
||||
// standard creation
|
||||
hr = CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER,IID_IUnknown, (void **)&punk);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ThrowComFail(env, "Can't co-create object", hr);
|
||||
return;
|
||||
}
|
||||
doDisp:
|
||||
|
||||
// now get an IDispatch pointer from the IUnknown
|
||||
hr = punk->QueryInterface(IID_IDispatch, (void **)&pIDispatch);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
ThrowComFail(env, "Can't QI object for IDispatch", hr);
|
||||
return;
|
||||
}
|
||||
// CoCreateInstance called AddRef
|
||||
punk->Release();
|
||||
env->SetIntField(_this, jf, (unsigned int)pIDispatch);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
jfieldID jf = env->GetFieldID( clazz, DISP_FLD, "I");
|
||||
jint num = env->GetIntField(_this, jf);
|
||||
|
||||
IDispatch *disp = (IDispatch *)num;
|
||||
if (disp) {
|
||||
disp->Release();
|
||||
env->SetIntField(_this, jf, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
name2ID(IDispatch *pIDispatch, const char *prop, DISPID *dispid, long lcid)
|
||||
{
|
||||
HRESULT hresult;
|
||||
USES_CONVERSION;
|
||||
LPOLESTR propOle = A2W(prop);
|
||||
hresult = pIDispatch->GetIDsOfNames(IID_NULL,(LPOLESTR*)&propOle,1,lcid,dispid);
|
||||
return hresult;
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
|
||||
(JNIEnv *env, jclass clazz, jobject disp, jint lcid, jobjectArray names)
|
||||
{
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return NULL;
|
||||
|
||||
int l = env->GetArrayLength(names);
|
||||
int i;
|
||||
LPOLESTR *lps = (LPOLESTR *)CoTaskMemAlloc(l * sizeof(LPOLESTR));
|
||||
DISPID *dispid = (DISPID *)CoTaskMemAlloc(l * sizeof(DISPID));
|
||||
for(i=0;i<l;i++)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
jstring s = (jstring)env->GetObjectArrayElement(names, i);
|
||||
const char *nm = env->GetStringUTFChars(s, NULL);
|
||||
LPOLESTR nmos = A2W(nm);
|
||||
env->ReleaseStringUTFChars(s, nm);
|
||||
lps[i] = nmos;
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
HRESULT hr = pIDispatch->GetIDsOfNames(IID_NULL,lps,l,lcid,dispid);
|
||||
if (FAILED(hr)) {
|
||||
CoTaskMemFree(lps);
|
||||
CoTaskMemFree(dispid);
|
||||
char buf[1024];
|
||||
strcpy(buf, "Can't map names to dispid:");
|
||||
for(i=0;i<l;i++)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
jstring s = (jstring)env->GetObjectArrayElement(names, i);
|
||||
const char *nm = env->GetStringUTFChars(s, NULL);
|
||||
strcat(buf, nm);
|
||||
env->ReleaseStringUTFChars(s, nm);
|
||||
env->DeleteLocalRef(s);
|
||||
}
|
||||
ThrowComFail(env, buf, hr);
|
||||
return NULL;
|
||||
}
|
||||
jintArray iarr = env->NewIntArray(l);
|
||||
env->SetIntArrayRegion(iarr, i, l, dispid);
|
||||
CoTaskMemFree(lps);
|
||||
CoTaskMemFree(dispid);
|
||||
return iarr;
|
||||
}
|
||||
|
||||
static char* BasicToCharString(const BSTR inBasicString)
|
||||
{
|
||||
char* charString = NULL;
|
||||
const size_t charStrSize = ::SysStringLen(inBasicString) + 1;
|
||||
if (charStrSize > 1)
|
||||
{
|
||||
charString = new char[charStrSize];
|
||||
size_t len = ::wcstombs(charString, inBasicString, charStrSize);
|
||||
}
|
||||
else
|
||||
charString = ::strdup("");
|
||||
|
||||
return charString;
|
||||
}
|
||||
|
||||
static char* CreateErrorMsgFromResult(HRESULT inResult)
|
||||
{
|
||||
char* msg = NULL;
|
||||
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM, NULL, inResult,MAKELANGID(LANG_NEUTRAL,
|
||||
SUBLANG_DEFAULT), (LPTSTR) &msg, 0, NULL);
|
||||
if (msg == NULL)
|
||||
msg = ::strdup("An unknown COM error has occured.");
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static char* CreateErrorMsgFromInfo(HRESULT inResult, EXCEPINFO* ioInfo,
|
||||
const char* methName)
|
||||
{
|
||||
char* msg = NULL;
|
||||
|
||||
// If this is a dispatch exception (triggered by an Invoke message),
|
||||
// then we have to take some additional steps to process the error
|
||||
// message.
|
||||
if (inResult == DISP_E_EXCEPTION)
|
||||
{
|
||||
// Check to see if the server deferred filling in the exception
|
||||
// information. If so, make the call to populate the structure.
|
||||
if (ioInfo->pfnDeferredFillIn != NULL)
|
||||
(*(ioInfo->pfnDeferredFillIn))(ioInfo);
|
||||
|
||||
// Build the error message from exception information content.
|
||||
char* source = ::BasicToCharString(ioInfo->bstrSource);
|
||||
char* desc = ::BasicToCharString(ioInfo->bstrDescription);
|
||||
const size_t MSG_LEN = ::strlen(methName) + ::strlen(source) + ::strlen(desc) + 128;
|
||||
msg = new char[MSG_LEN];
|
||||
::strncpy(msg, "Invoke of: ", MSG_LEN);
|
||||
::strncat(msg, methName, MSG_LEN);
|
||||
::strncat(msg, "\nSource: ", MSG_LEN);
|
||||
::strncat(msg, source, MSG_LEN);
|
||||
::strncat(msg, "\nDescription: ", MSG_LEN);
|
||||
::strncat(msg, desc, MSG_LEN);
|
||||
::strncat(msg, "\n", MSG_LEN);
|
||||
delete source;
|
||||
delete desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* msg2 = CreateErrorMsgFromResult(inResult);
|
||||
const size_t MSG_LEN = ::strlen(methName) + ::strlen(msg2) + 128;
|
||||
msg = new char[MSG_LEN];
|
||||
::strncpy(msg, "A COM exception has been encountered:\n"
|
||||
"At Invoke of: ", MSG_LEN);
|
||||
::strncat(msg, methName, MSG_LEN);
|
||||
::strncat(msg, "\nDescription: ", MSG_LEN);
|
||||
::strncat(msg, msg2, MSG_LEN);
|
||||
// jacob-msg 1075 - SF 1053872 : Documentation says "use LocalFree"!!
|
||||
//delete msg2;
|
||||
LocalFree(msg2);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
#define SETDISPPARAMS(dp, numArgs, pvArgs, numNamed, pNamed) \
|
||||
{\
|
||||
(dp).cArgs = numArgs; \
|
||||
(dp).rgvarg = pvArgs; \
|
||||
(dp).cNamedArgs = numNamed; \
|
||||
(dp).rgdispidNamedArgs = pNamed; \
|
||||
}
|
||||
|
||||
#define SETNOPARAMS(dp) SETDISPPARAMS(dp, 0, NULL, 0, NULL)
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
||||
(JNIEnv *env, jclass clazz,
|
||||
jobject disp, jstring name, jint dispid,
|
||||
jint lcid, jint wFlags, jobjectArray vArg, jintArray uArgErr)
|
||||
{
|
||||
DISPPARAMS dispparams;
|
||||
EXCEPINFO excepInfo;
|
||||
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return NULL;
|
||||
|
||||
int dispID = dispid;
|
||||
if (name != NULL)
|
||||
{
|
||||
const char *nm = env->GetStringUTFChars(name, NULL);
|
||||
HRESULT hr;
|
||||
if (FAILED(hr = name2ID(pIDispatch, nm, (long *)&dispID, lcid))) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "Can't map name to dispid: %s", nm);
|
||||
ThrowComFail(env, buf, -1);
|
||||
return NULL;
|
||||
}
|
||||
env->ReleaseStringUTFChars(name, nm);
|
||||
}
|
||||
|
||||
int num_args = env->GetArrayLength(vArg);
|
||||
int i, j;
|
||||
VARIANT *varr = NULL;
|
||||
if (num_args)
|
||||
{
|
||||
varr = (VARIANT *)CoTaskMemAlloc(num_args*sizeof(VARIANT));
|
||||
/* reverse args for dispatch */
|
||||
for(i=num_args-1,j=0;0<=i;i--,j++)
|
||||
{
|
||||
VariantInit(&varr[j]);
|
||||
jobject arg = env->GetObjectArrayElement(vArg, i);
|
||||
VARIANT *v = extractVariant(env, arg);
|
||||
// no escape from copy?
|
||||
VariantCopy(&varr[j], v);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
}
|
||||
// prepare a new return value
|
||||
jclass variantClass = env->FindClass("com/jacob/com/Variant");
|
||||
jmethodID variantCons =
|
||||
env->GetMethodID(variantClass, "<init>", "()V");
|
||||
// construct a variant to return
|
||||
jobject newVariant = env->NewObject(variantClass, variantCons);
|
||||
// get the VARIANT from the newVariant
|
||||
VARIANT *v = extractVariant(env, newVariant);
|
||||
DISPID dispidPropertyPut = DISPID_PROPERTYPUT;
|
||||
|
||||
// determine how to dispatch
|
||||
switch (wFlags)
|
||||
{
|
||||
case DISPATCH_PROPERTYGET: // GET
|
||||
case DISPATCH_METHOD: // METHOD
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
{
|
||||
SETDISPPARAMS(dispparams, num_args, varr, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
case DISPATCH_PROPERTYPUTREF: // jacob-msg 1075 - SF 1053872
|
||||
{
|
||||
SETDISPPARAMS(dispparams, num_args, varr, 1, &dispidPropertyPut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = 0;
|
||||
jint count = env->GetArrayLength(uArgErr);
|
||||
if ( count != 0 )
|
||||
{
|
||||
jint *uAE = env->GetIntArrayElements(uArgErr, NULL);
|
||||
hr = pIDispatch->Invoke(dispID,IID_NULL,
|
||||
lcid,wFlags,&dispparams,v,&excepInfo,(unsigned int *)uAE);
|
||||
env->ReleaseIntArrayElements(uArgErr, uAE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = pIDispatch->Invoke(dispID,IID_NULL,
|
||||
lcid,wFlags,&dispparams,v,&excepInfo, NULL);
|
||||
}
|
||||
if (num_args)
|
||||
{
|
||||
// to account for inouts, I need to copy the inputs back to
|
||||
// the java array after the method returns
|
||||
// this occurs, for example, in the ADO wrappers
|
||||
for(i=num_args-1,j=0;0<=i;i--,j++)
|
||||
{
|
||||
jobject arg = env->GetObjectArrayElement(vArg, i);
|
||||
VARIANT *v = extractVariant(env, arg);
|
||||
// reverse copy
|
||||
VariantCopy(v, &varr[j]);
|
||||
// clear out the temporary variant
|
||||
VariantClear(&varr[j]);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (varr) CoTaskMemFree(varr);
|
||||
|
||||
// check for error and display a somewhat verbose error message
|
||||
if (!SUCCEEDED(hr)) {
|
||||
const char *nm = env->GetStringUTFChars(name, NULL);
|
||||
char *buf = CreateErrorMsgFromInfo(hr, &excepInfo, nm);
|
||||
env->ReleaseStringUTFChars(name, nm);
|
||||
|
||||
// jacob-msg 3696 - SF 1053866
|
||||
if(hr == DISP_E_EXCEPTION)
|
||||
{
|
||||
if(excepInfo.scode != 0)
|
||||
{
|
||||
hr = excepInfo.scode;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = _com_error::WCodeToHRESULT(excepInfo.wCode);
|
||||
}
|
||||
}
|
||||
|
||||
ThrowComFail(env, buf, hr);
|
||||
if (buf) delete buf;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newVariant;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
106
jni/Dispatch.h
106
jni/Dispatch.h
@@ -1,53 +1,53 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class Dispatch */
|
||||
|
||||
#ifndef _Included_Dispatch
|
||||
#define _Included_Dispatch
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_Dispatch
|
||||
* Method: QueryInterface
|
||||
* Signature: (Ljava/lang/String;)Lcom/jacob/com/Dispatch;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: createInstance
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: getIDsOfNames
|
||||
* Signature: (Ljava/lang/Object;I[Ljava/lang/String;)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
|
||||
(JNIEnv *, jclass, jobject, jint, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: invokev
|
||||
* Signature: (Ljava/lang/Object;Ljava/lang/String;III[LVariant;[I)LVariant;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
||||
(JNIEnv *, jclass, jobject, jstring, jint, jint, jint, jobjectArray, jintArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class Dispatch */
|
||||
|
||||
#ifndef _Included_Dispatch
|
||||
#define _Included_Dispatch
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_Dispatch
|
||||
* Method: QueryInterface
|
||||
* Signature: (Ljava/lang/String;)Lcom/jacob/com/Dispatch;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_QueryInterface
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: createInstance
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_createInstance
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_Dispatch_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: getIDsOfNames
|
||||
* Signature: (Ljava/lang/Object;I[Ljava/lang/String;)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_com_jacob_com_Dispatch_getIDsOfNames
|
||||
(JNIEnv *, jclass, jobject, jint, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: Dispatch
|
||||
* Method: invokev
|
||||
* Signature: (Ljava/lang/Object;Ljava/lang/String;III[LVariant;[I)LVariant;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_Dispatch_invokev
|
||||
(JNIEnv *, jclass, jobject, jstring, jint, jint, jint, jobjectArray, jintArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,311 +1,311 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "DispatchEvents.h"
|
||||
#include "EventProxy.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#define PROXY_FLD "m_pConnPtProxy"
|
||||
|
||||
// defined below
|
||||
BOOL GetEventIID(IUnknown*, IID*, CComBSTR **, DISPID **, int *,LPOLESTR);
|
||||
BOOL getClassInfoFromProgId(LPOLESTR bsProgId,LPTYPEINFO *pClassInfo);
|
||||
|
||||
// extract a EventProxy* from a jobject
|
||||
EventProxy *extractProxy(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, PROXY_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
EventProxy *v = (EventProxy *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
void putProxy(JNIEnv *env, jobject arg, EventProxy *ep)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, PROXY_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
env->SetIntField(arg, ajf, (jint)ep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init2
|
||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||
(JNIEnv *env, jobject _this, jobject src, jobject sink, jstring _progid)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
// find progid if any
|
||||
LPOLESTR bsProgId = NULL;
|
||||
if (_progid!=NULL) {
|
||||
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||
bsProgId = A2W(progid);
|
||||
}
|
||||
|
||||
// get the IDispatch for the source object
|
||||
IDispatch *pDisp = extractDispatch(env, src);
|
||||
CComQIPtr<IUnknown, &IID_IUnknown> pUnk(pDisp);
|
||||
// see if it implements connection points
|
||||
CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
|
||||
if (!pCPC)
|
||||
{
|
||||
// no events, throw something
|
||||
ThrowComFail(env, "Can't find IConnectionPointContainer", -1);
|
||||
return;
|
||||
}
|
||||
// hook up to the default source iid
|
||||
CComPtr<IConnectionPoint> pCP;
|
||||
IID eventIID;
|
||||
CComBSTR *mNames;
|
||||
DISPID *mIDs;
|
||||
int n_EventMethods;
|
||||
if (!GetEventIID(pUnk, &eventIID, &mNames, &mIDs, &n_EventMethods,bsProgId)) {
|
||||
ThrowComFail(env, "Can't find event iid", -1);
|
||||
return;
|
||||
}
|
||||
HRESULT hr = pCPC->FindConnectionPoint(eventIID, &pCP);
|
||||
DWORD dwEventCookie;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
EventProxy *ep = new EventProxy(env, sink, pCP, eventIID, mNames, mIDs, n_EventMethods);
|
||||
// need to store ep on _this, in case it gets collected
|
||||
putProxy(env, _this, ep);
|
||||
} else {
|
||||
ThrowComFail(env, "Can't FindConnectionPoint", hr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init
|
||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||
(JNIEnv *env, jobject _this, jobject src, jobject sink)
|
||||
{
|
||||
Java_com_jacob_com_DispatchEvents_init2(env,_this,src,sink,NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
EventProxy *ep = extractProxy(env, _this);
|
||||
if (ep) {
|
||||
ep->Release();
|
||||
putProxy(env, _this, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* I need a reverse map from the event interface's dispids to
|
||||
* function names so that we can reflect them to java
|
||||
*/
|
||||
void
|
||||
LoadNameCache(LPTYPEINFO pTypeInfo, LPTYPEATTR pta,
|
||||
CComBSTR **mNames, DISPID **mIDs, int *nmeth)
|
||||
{
|
||||
CComBSTR *names = NULL;
|
||||
DISPID *ids = NULL;
|
||||
int m_nCount;
|
||||
|
||||
m_nCount = pta->cFuncs;
|
||||
*nmeth = m_nCount;
|
||||
names = m_nCount == 0 ? NULL : new CComBSTR[m_nCount];
|
||||
ids = m_nCount == 0 ? NULL : new DISPID[m_nCount];
|
||||
for (int i=0; i<m_nCount; i++)
|
||||
{
|
||||
FUNCDESC* pfd;
|
||||
if (SUCCEEDED(pTypeInfo->GetFuncDesc(i, &pfd)))
|
||||
{
|
||||
CComBSTR bstrName;
|
||||
if (SUCCEEDED(pTypeInfo->GetDocumentation(pfd->memid, &bstrName, NULL, NULL, NULL)))
|
||||
{
|
||||
names[i].Attach(bstrName.Detach());
|
||||
ids[i] = pfd->memid;
|
||||
/*
|
||||
USES_CONVERSION;
|
||||
printf("map:%d -> %s\n", ids[i], W2A((OLECHAR *)names[i]));
|
||||
*/
|
||||
}
|
||||
pTypeInfo->ReleaseFuncDesc(pfd);
|
||||
}
|
||||
}
|
||||
*mNames = names;
|
||||
*mIDs = ids;
|
||||
}
|
||||
|
||||
#define IMPLTYPE_MASK \
|
||||
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FRESTRICTED)
|
||||
|
||||
#define IMPLTYPE_DEFAULTSOURCE \
|
||||
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)
|
||||
|
||||
|
||||
BOOL GetEventIID(IUnknown *m_pObject, IID* piid,
|
||||
CComBSTR **mNames, DISPID **mIDs, int *nmeth,LPOLESTR bsProgId)
|
||||
{
|
||||
*piid = GUID_NULL;
|
||||
ATLASSERT(m_pObject != NULL);
|
||||
// I Always use IProvideClassInfo rather than IProvideClassInfo2
|
||||
// since I also need to create a mapping from dispid to name
|
||||
LPPROVIDECLASSINFO pPCI = NULL;
|
||||
LPTYPEINFO pClassInfo = NULL;
|
||||
if (SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo, (LPVOID*)&pPCI)))
|
||||
{
|
||||
//printf("got IProvideClassInfo\n");
|
||||
ATLASSERT(pPCI != NULL);
|
||||
HRESULT hr = pPCI->GetClassInfo(&pClassInfo);
|
||||
pPCI->Release();
|
||||
if (!SUCCEEDED(hr)) return false;
|
||||
}
|
||||
else if (getClassInfoFromProgId(bsProgId,&pClassInfo)) {
|
||||
}
|
||||
else {
|
||||
printf("couldn't get IProvideClassInfo\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//printf("got ClassInfo\n");
|
||||
ATLASSERT(pClassInfo != NULL);
|
||||
LPTYPEATTR pClassAttr;
|
||||
if (SUCCEEDED(pClassInfo->GetTypeAttr(&pClassAttr)))
|
||||
{
|
||||
//printf("got TypeAttr\n");
|
||||
ATLASSERT(pClassAttr != NULL);
|
||||
ATLASSERT(pClassAttr->typekind == TKIND_COCLASS);
|
||||
|
||||
// Search for typeinfo of the default events interface.
|
||||
int nFlags;
|
||||
HREFTYPE hRefType;
|
||||
|
||||
for (unsigned int i = 0; i < pClassAttr->cImplTypes; i++)
|
||||
{
|
||||
if (SUCCEEDED(pClassInfo->GetImplTypeFlags(i, &nFlags)) &&
|
||||
((nFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
|
||||
{
|
||||
// Found it. Now look at its attributes to get IID.
|
||||
LPTYPEINFO pEventInfo = NULL;
|
||||
if (SUCCEEDED(pClassInfo->GetRefTypeOfImplType(i,
|
||||
&hRefType)) &&
|
||||
SUCCEEDED(pClassInfo->GetRefTypeInfo(hRefType,
|
||||
&pEventInfo)))
|
||||
{
|
||||
ATLASSERT(pEventInfo != NULL);
|
||||
LPTYPEATTR pEventAttr;
|
||||
if (SUCCEEDED(pEventInfo->GetTypeAttr(&pEventAttr)))
|
||||
{
|
||||
ATLASSERT(pEventAttr != NULL);
|
||||
|
||||
// create a mapping from dispid to string
|
||||
LoadNameCache(pEventInfo, pEventAttr,
|
||||
mNames, mIDs, nmeth);
|
||||
|
||||
*piid = pEventAttr->guid;
|
||||
pEventInfo->ReleaseTypeAttr(pEventAttr);
|
||||
}
|
||||
pEventInfo->Release();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pClassInfo->ReleaseTypeAttr(pClassAttr);
|
||||
}
|
||||
pClassInfo->Release();
|
||||
|
||||
return (!IsEqualIID(*piid, GUID_NULL));
|
||||
}
|
||||
|
||||
BOOL getClassInfoFromProgId(LPOLESTR bsProgId,LPTYPEINFO *pClassInfo)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
CLSID clsid;
|
||||
GUID libid;
|
||||
if (FAILED(CLSIDFromProgID(bsProgId, &clsid))) return false;
|
||||
if (FAILED(StringFromCLSID(clsid,&bsProgId))) return false;
|
||||
HKEY keySoftware, keyClasses, keyCLSID, keyXXXX, keyTypeLib;
|
||||
DWORD dwType, dwCountData=50;
|
||||
BYTE abData[50];
|
||||
LONG lVal;
|
||||
lVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE"),0,KEY_READ,&keySoftware);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keySoftware,_T("Classes"),0,KEY_READ,&keyClasses);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keyClasses,_T("CLSID"),0,KEY_READ,&keyCLSID);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
_TCHAR *tsProgId = W2T(bsProgId);
|
||||
lVal = RegOpenKeyEx(keyCLSID,tsProgId,0,KEY_READ,&keyXXXX);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keyXXXX,_T("TypeLib"),0,KEY_READ,&keyTypeLib);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegQueryValueEx(keyTypeLib,NULL,NULL,&dwType,abData,&dwCountData);
|
||||
RegCloseKey(keyTypeLib);
|
||||
}
|
||||
RegCloseKey(keyXXXX);
|
||||
}
|
||||
RegCloseKey(keyCLSID);
|
||||
}
|
||||
RegCloseKey(keyClasses);
|
||||
}
|
||||
RegCloseKey(keySoftware);
|
||||
}
|
||||
if (lVal!=ERROR_SUCCESS) return false;
|
||||
BSTR bsLibId = A2BSTR((char*)abData);
|
||||
if (FAILED(CLSIDFromString(bsLibId,&libid))) return false;
|
||||
//Try loading from registry information.
|
||||
ITypeLib* pITypeLib;
|
||||
if (FAILED(LoadRegTypeLib(libid,1,0, LANG_NEUTRAL, &pITypeLib))) return false;
|
||||
//Find ITypeInfo for coclass.
|
||||
pITypeLib->GetTypeInfoOfGuid(clsid, pClassInfo);
|
||||
pITypeLib->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "DispatchEvents.h"
|
||||
#include "EventProxy.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#define PROXY_FLD "m_pConnPtProxy"
|
||||
|
||||
// defined below
|
||||
BOOL GetEventIID(IUnknown*, IID*, CComBSTR **, DISPID **, int *,LPOLESTR);
|
||||
BOOL getClassInfoFromProgId(LPOLESTR bsProgId,LPTYPEINFO *pClassInfo);
|
||||
|
||||
// extract a EventProxy* from a jobject
|
||||
EventProxy *extractProxy(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, PROXY_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
EventProxy *v = (EventProxy *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
void putProxy(JNIEnv *env, jobject arg, EventProxy *ep)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, PROXY_FLD, "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
env->SetIntField(arg, ajf, (jint)ep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init2
|
||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||
(JNIEnv *env, jobject _this, jobject src, jobject sink, jstring _progid)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
// find progid if any
|
||||
LPOLESTR bsProgId = NULL;
|
||||
if (_progid!=NULL) {
|
||||
const char *progid = env->GetStringUTFChars(_progid, NULL);
|
||||
bsProgId = A2W(progid);
|
||||
}
|
||||
|
||||
// get the IDispatch for the source object
|
||||
IDispatch *pDisp = extractDispatch(env, src);
|
||||
CComQIPtr<IUnknown, &IID_IUnknown> pUnk(pDisp);
|
||||
// see if it implements connection points
|
||||
CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pCPC(pUnk);
|
||||
if (!pCPC)
|
||||
{
|
||||
// no events, throw something
|
||||
ThrowComFail(env, "Can't find IConnectionPointContainer", -1);
|
||||
return;
|
||||
}
|
||||
// hook up to the default source iid
|
||||
CComPtr<IConnectionPoint> pCP;
|
||||
IID eventIID;
|
||||
CComBSTR *mNames;
|
||||
DISPID *mIDs;
|
||||
int n_EventMethods;
|
||||
if (!GetEventIID(pUnk, &eventIID, &mNames, &mIDs, &n_EventMethods,bsProgId)) {
|
||||
ThrowComFail(env, "Can't find event iid", -1);
|
||||
return;
|
||||
}
|
||||
HRESULT hr = pCPC->FindConnectionPoint(eventIID, &pCP);
|
||||
DWORD dwEventCookie;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
EventProxy *ep = new EventProxy(env, sink, pCP, eventIID, mNames, mIDs, n_EventMethods);
|
||||
// need to store ep on _this, in case it gets collected
|
||||
putProxy(env, _this, ep);
|
||||
} else {
|
||||
ThrowComFail(env, "Can't FindConnectionPoint", hr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init
|
||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||
(JNIEnv *env, jobject _this, jobject src, jobject sink)
|
||||
{
|
||||
Java_com_jacob_com_DispatchEvents_init2(env,_this,src,sink,NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
EventProxy *ep = extractProxy(env, _this);
|
||||
if (ep) {
|
||||
ep->Release();
|
||||
putProxy(env, _this, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* I need a reverse map from the event interface's dispids to
|
||||
* function names so that we can reflect them to java
|
||||
*/
|
||||
void
|
||||
LoadNameCache(LPTYPEINFO pTypeInfo, LPTYPEATTR pta,
|
||||
CComBSTR **mNames, DISPID **mIDs, int *nmeth)
|
||||
{
|
||||
CComBSTR *names = NULL;
|
||||
DISPID *ids = NULL;
|
||||
int m_nCount;
|
||||
|
||||
m_nCount = pta->cFuncs;
|
||||
*nmeth = m_nCount;
|
||||
names = m_nCount == 0 ? NULL : new CComBSTR[m_nCount];
|
||||
ids = m_nCount == 0 ? NULL : new DISPID[m_nCount];
|
||||
for (int i=0; i<m_nCount; i++)
|
||||
{
|
||||
FUNCDESC* pfd;
|
||||
if (SUCCEEDED(pTypeInfo->GetFuncDesc(i, &pfd)))
|
||||
{
|
||||
CComBSTR bstrName;
|
||||
if (SUCCEEDED(pTypeInfo->GetDocumentation(pfd->memid, &bstrName, NULL, NULL, NULL)))
|
||||
{
|
||||
names[i].Attach(bstrName.Detach());
|
||||
ids[i] = pfd->memid;
|
||||
/*
|
||||
USES_CONVERSION;
|
||||
printf("map:%d -> %s\n", ids[i], W2A((OLECHAR *)names[i]));
|
||||
*/
|
||||
}
|
||||
pTypeInfo->ReleaseFuncDesc(pfd);
|
||||
}
|
||||
}
|
||||
*mNames = names;
|
||||
*mIDs = ids;
|
||||
}
|
||||
|
||||
#define IMPLTYPE_MASK \
|
||||
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FRESTRICTED)
|
||||
|
||||
#define IMPLTYPE_DEFAULTSOURCE \
|
||||
(IMPLTYPEFLAG_FDEFAULT | IMPLTYPEFLAG_FSOURCE)
|
||||
|
||||
|
||||
BOOL GetEventIID(IUnknown *m_pObject, IID* piid,
|
||||
CComBSTR **mNames, DISPID **mIDs, int *nmeth,LPOLESTR bsProgId)
|
||||
{
|
||||
*piid = GUID_NULL;
|
||||
ATLASSERT(m_pObject != NULL);
|
||||
// I Always use IProvideClassInfo rather than IProvideClassInfo2
|
||||
// since I also need to create a mapping from dispid to name
|
||||
LPPROVIDECLASSINFO pPCI = NULL;
|
||||
LPTYPEINFO pClassInfo = NULL;
|
||||
if (SUCCEEDED(m_pObject->QueryInterface(IID_IProvideClassInfo, (LPVOID*)&pPCI)))
|
||||
{
|
||||
//printf("got IProvideClassInfo\n");
|
||||
ATLASSERT(pPCI != NULL);
|
||||
HRESULT hr = pPCI->GetClassInfo(&pClassInfo);
|
||||
pPCI->Release();
|
||||
if (!SUCCEEDED(hr)) return false;
|
||||
}
|
||||
else if (getClassInfoFromProgId(bsProgId,&pClassInfo)) {
|
||||
}
|
||||
else {
|
||||
printf("couldn't get IProvideClassInfo\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//printf("got ClassInfo\n");
|
||||
ATLASSERT(pClassInfo != NULL);
|
||||
LPTYPEATTR pClassAttr;
|
||||
if (SUCCEEDED(pClassInfo->GetTypeAttr(&pClassAttr)))
|
||||
{
|
||||
//printf("got TypeAttr\n");
|
||||
ATLASSERT(pClassAttr != NULL);
|
||||
ATLASSERT(pClassAttr->typekind == TKIND_COCLASS);
|
||||
|
||||
// Search for typeinfo of the default events interface.
|
||||
int nFlags;
|
||||
HREFTYPE hRefType;
|
||||
|
||||
for (unsigned int i = 0; i < pClassAttr->cImplTypes; i++)
|
||||
{
|
||||
if (SUCCEEDED(pClassInfo->GetImplTypeFlags(i, &nFlags)) &&
|
||||
((nFlags & IMPLTYPE_MASK) == IMPLTYPE_DEFAULTSOURCE))
|
||||
{
|
||||
// Found it. Now look at its attributes to get IID.
|
||||
LPTYPEINFO pEventInfo = NULL;
|
||||
if (SUCCEEDED(pClassInfo->GetRefTypeOfImplType(i,
|
||||
&hRefType)) &&
|
||||
SUCCEEDED(pClassInfo->GetRefTypeInfo(hRefType,
|
||||
&pEventInfo)))
|
||||
{
|
||||
ATLASSERT(pEventInfo != NULL);
|
||||
LPTYPEATTR pEventAttr;
|
||||
if (SUCCEEDED(pEventInfo->GetTypeAttr(&pEventAttr)))
|
||||
{
|
||||
ATLASSERT(pEventAttr != NULL);
|
||||
|
||||
// create a mapping from dispid to string
|
||||
LoadNameCache(pEventInfo, pEventAttr,
|
||||
mNames, mIDs, nmeth);
|
||||
|
||||
*piid = pEventAttr->guid;
|
||||
pEventInfo->ReleaseTypeAttr(pEventAttr);
|
||||
}
|
||||
pEventInfo->Release();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pClassInfo->ReleaseTypeAttr(pClassAttr);
|
||||
}
|
||||
pClassInfo->Release();
|
||||
|
||||
return (!IsEqualIID(*piid, GUID_NULL));
|
||||
}
|
||||
|
||||
BOOL getClassInfoFromProgId(LPOLESTR bsProgId,LPTYPEINFO *pClassInfo)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
CLSID clsid;
|
||||
GUID libid;
|
||||
if (FAILED(CLSIDFromProgID(bsProgId, &clsid))) return false;
|
||||
if (FAILED(StringFromCLSID(clsid,&bsProgId))) return false;
|
||||
HKEY keySoftware, keyClasses, keyCLSID, keyXXXX, keyTypeLib;
|
||||
DWORD dwType, dwCountData=50;
|
||||
BYTE abData[50];
|
||||
LONG lVal;
|
||||
lVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE"),0,KEY_READ,&keySoftware);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keySoftware,_T("Classes"),0,KEY_READ,&keyClasses);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keyClasses,_T("CLSID"),0,KEY_READ,&keyCLSID);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
_TCHAR *tsProgId = W2T(bsProgId);
|
||||
lVal = RegOpenKeyEx(keyCLSID,tsProgId,0,KEY_READ,&keyXXXX);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegOpenKeyEx(keyXXXX,_T("TypeLib"),0,KEY_READ,&keyTypeLib);
|
||||
if (lVal==ERROR_SUCCESS) {
|
||||
lVal = RegQueryValueEx(keyTypeLib,NULL,NULL,&dwType,abData,&dwCountData);
|
||||
RegCloseKey(keyTypeLib);
|
||||
}
|
||||
RegCloseKey(keyXXXX);
|
||||
}
|
||||
RegCloseKey(keyCLSID);
|
||||
}
|
||||
RegCloseKey(keyClasses);
|
||||
}
|
||||
RegCloseKey(keySoftware);
|
||||
}
|
||||
if (lVal!=ERROR_SUCCESS) return false;
|
||||
BSTR bsLibId = A2BSTR((char*)abData);
|
||||
if (FAILED(CLSIDFromString(bsLibId,&libid))) return false;
|
||||
//Try loading from registry information.
|
||||
ITypeLib* pITypeLib;
|
||||
if (FAILED(LoadRegTypeLib(libid,1,0, LANG_NEUTRAL, &pITypeLib))) return false;
|
||||
//Find ITypeInfo for coclass.
|
||||
pITypeLib->GetTypeInfoOfGuid(clsid, pClassInfo);
|
||||
pITypeLib->Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class DispatchEvents */
|
||||
|
||||
#ifndef _Included_DispatchEvents
|
||||
#define _Included_DispatchEvents
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init
|
||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||
(JNIEnv *, jobject, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init2
|
||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||
(JNIEnv *, jobject, jobject, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class DispatchEvents */
|
||||
|
||||
#ifndef _Included_DispatchEvents
|
||||
#define _Included_DispatchEvents
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init
|
||||
* Signature: (LDispatch;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init
|
||||
(JNIEnv *, jobject, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: init2
|
||||
* Signature: (LDispatch;Ljava/lang/Object;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_init2
|
||||
(JNIEnv *, jobject, jobject, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: DispatchEvents
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchEvents_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,116 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// extract a IStream from a jobject
|
||||
IStream *extractStream(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
IStream *v = (IStream *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream
|
||||
(JNIEnv *env, jobject _this, jobject disp)
|
||||
{
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return;
|
||||
IStream *ps; // this is the stream we will marshall into
|
||||
HRESULT hr = CoMarshalInterThreadInterfaceInStream(
|
||||
IID_IDispatch, pIDispatch, &ps);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ThrowComFail(env, "Could not Marshal Dispatch into IStream", hr);
|
||||
return;
|
||||
}
|
||||
// store the stream pointer on the object
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (jint)ps);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
IStream *ps = extractStream(env, _this);
|
||||
if (!ps)
|
||||
{
|
||||
ThrowComFail(env, "Could not get IStream from DispatchProxy", -1);
|
||||
return NULL;
|
||||
}
|
||||
IDispatch *pD;
|
||||
HRESULT hr = CoGetInterfaceAndReleaseStream(ps, IID_IDispatch, (void **)&pD);
|
||||
// zero out the stream pointer on the object
|
||||
// since the stream can only be read once
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (unsigned int)0);
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ThrowComFail(env, "Could not Marshal Dispatch from IStream", hr);
|
||||
return NULL;
|
||||
}
|
||||
jclass autoClass = env->FindClass("com/jacob/com/Dispatch");
|
||||
jmethodID autoCons = env->GetMethodID(autoClass, "<init>", "(I)V");
|
||||
// construct a Dispatch object to return
|
||||
// I am copying the pointer to java
|
||||
if (pD) pD->AddRef();
|
||||
jobject newAuto = env->NewObject(autoClass, autoCons, pD);
|
||||
return newAuto;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
IStream *ps = extractStream(env, _this);
|
||||
if (ps) {
|
||||
ps->Release();
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// extract a IStream from a jobject
|
||||
IStream *extractStream(JNIEnv *env, jobject arg)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(arg);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
jint anum = env->GetIntField(arg, ajf);
|
||||
IStream *v = (IStream *)anum;
|
||||
return v;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream
|
||||
(JNIEnv *env, jobject _this, jobject disp)
|
||||
{
|
||||
IDispatch *pIDispatch = extractDispatch(env, disp);
|
||||
if (!pIDispatch) return;
|
||||
IStream *ps; // this is the stream we will marshall into
|
||||
HRESULT hr = CoMarshalInterThreadInterfaceInStream(
|
||||
IID_IDispatch, pIDispatch, &ps);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ThrowComFail(env, "Could not Marshal Dispatch into IStream", hr);
|
||||
return;
|
||||
}
|
||||
// store the stream pointer on the object
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (jint)ps);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
IStream *ps = extractStream(env, _this);
|
||||
if (!ps)
|
||||
{
|
||||
ThrowComFail(env, "Could not get IStream from DispatchProxy", -1);
|
||||
return NULL;
|
||||
}
|
||||
IDispatch *pD;
|
||||
HRESULT hr = CoGetInterfaceAndReleaseStream(ps, IID_IDispatch, (void **)&pD);
|
||||
// zero out the stream pointer on the object
|
||||
// since the stream can only be read once
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (unsigned int)0);
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
ThrowComFail(env, "Could not Marshal Dispatch from IStream", hr);
|
||||
return NULL;
|
||||
}
|
||||
jclass autoClass = env->FindClass("com/jacob/com/Dispatch");
|
||||
jmethodID autoCons = env->GetMethodID(autoClass, "<init>", "(I)V");
|
||||
// construct a Dispatch object to return
|
||||
// I am copying the pointer to java
|
||||
if (pD) pD->AddRef();
|
||||
jobject newAuto = env->NewObject(autoClass, autoCons, pD);
|
||||
return newAuto;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release
|
||||
(JNIEnv *env, jobject _this)
|
||||
{
|
||||
IStream *ps = extractStream(env, _this);
|
||||
if (ps) {
|
||||
ps->Release();
|
||||
jclass argClass = env->GetObjectClass(_this);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "m_pStream", "I");
|
||||
env->SetIntField(_this, ajf, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_jacob_com_DispatchProxy */
|
||||
|
||||
#ifndef _Included_com_jacob_com_DispatchProxy
|
||||
#define _Included_com_jacob_com_DispatchProxy
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: MarshalIntoStream
|
||||
* Signature: (Lcom/jacob/com/Dispatch;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: MarshalFromStream
|
||||
* Signature: ()Lcom/jacob/com/Dispatch;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_jacob_com_DispatchProxy */
|
||||
|
||||
#ifndef _Included_com_jacob_com_DispatchProxy
|
||||
#define _Included_com_jacob_com_DispatchProxy
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: MarshalIntoStream
|
||||
* Signature: (Lcom/jacob/com/Dispatch;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_MarshalIntoStream
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: MarshalFromStream
|
||||
* Signature: ()Lcom/jacob/com/Dispatch;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_com_jacob_com_DispatchProxy_MarshalFromStream
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_DispatchProxy
|
||||
* Method: release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_DispatchProxy_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,137 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* An implementation of IEnumVariant based on code submitted by
|
||||
* Thomas Hallgren (mailto:Thomas.Hallgren@eoncompany.com)
|
||||
*/
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// extract a IDispatch from a jobject
|
||||
IEnumVARIANT* extractEnumVariant(JNIEnv* env, jobject arg)
|
||||
{
|
||||
jfieldID FID_pIEnumVARIANT = 0;
|
||||
jclass clazz = env->GetObjectClass(arg);
|
||||
FID_pIEnumVARIANT = env->GetFieldID(clazz, "m_pIEnumVARIANT", "I");
|
||||
return (IEnumVARIANT*)env->GetIntField(arg, FID_pIEnumVARIANT);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Next(JNIEnv* env, jobject _this, jobjectArray vars)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
printf("self=%x\n", self);
|
||||
if(self == NULL)
|
||||
return 0;
|
||||
|
||||
ULONG count = (ULONG)env->GetArrayLength(vars);
|
||||
if(count == 0)
|
||||
return 0;
|
||||
|
||||
VARIANT* sink = (VARIANT*)CoTaskMemAlloc(count * sizeof(VARIANT));
|
||||
ULONG fetchCount = 0;
|
||||
|
||||
HRESULT hr = self->Next(count, sink, &fetchCount);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
CoTaskMemFree(sink);
|
||||
ThrowComFail(env, "IEnumVARIANT::Next", hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// prepare a new return value array
|
||||
//
|
||||
jclass clazz = env->FindClass("com/jacob/com/Variant");
|
||||
jmethodID ctor = env->GetMethodID(clazz, "<init>", "()V");
|
||||
|
||||
for(ULONG idx = 0; idx < fetchCount; ++idx)
|
||||
{
|
||||
// construct a variant to return
|
||||
//
|
||||
jobject newVariant = env->NewObject(clazz, ctor);
|
||||
VARIANT* v = extractVariant(env, newVariant);
|
||||
VariantCopy(v, sink + idx);
|
||||
env->SetObjectArrayElement(vars, idx, newVariant);
|
||||
env->DeleteLocalRef(newVariant);
|
||||
}
|
||||
CoTaskMemFree(sink);
|
||||
return (jint)fetchCount;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_release(JNIEnv* env, jobject _this)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self != NULL)
|
||||
{
|
||||
self->Release();
|
||||
jfieldID FID_pIEnumVARIANT = 0;
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
FID_pIEnumVARIANT = env->GetFieldID(clazz, "m_pIEnumVARIANT", "I");
|
||||
env->SetIntField(_this, FID_pIEnumVARIANT, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Reset(JNIEnv* env, jobject _this)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self == NULL)
|
||||
return;
|
||||
|
||||
HRESULT hr = self->Reset();
|
||||
if(FAILED(hr))
|
||||
ThrowComFail(env, "IEnumVARIANT::Reset", hr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Skip(JNIEnv* env, jobject _this, jint count)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self == NULL)
|
||||
return;
|
||||
|
||||
HRESULT hr = self->Skip((ULONG)count);
|
||||
if(FAILED(hr))
|
||||
ThrowComFail(env, "IEnumVARIANT::Skip", hr);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* An implementation of IEnumVariant based on code submitted by
|
||||
* Thomas Hallgren (mailto:Thomas.Hallgren@eoncompany.com)
|
||||
*/
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// extract a IDispatch from a jobject
|
||||
IEnumVARIANT* extractEnumVariant(JNIEnv* env, jobject arg)
|
||||
{
|
||||
jfieldID FID_pIEnumVARIANT = 0;
|
||||
jclass clazz = env->GetObjectClass(arg);
|
||||
FID_pIEnumVARIANT = env->GetFieldID(clazz, "m_pIEnumVARIANT", "I");
|
||||
return (IEnumVARIANT*)env->GetIntField(arg, FID_pIEnumVARIANT);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Next(JNIEnv* env, jobject _this, jobjectArray vars)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
printf("self=%x\n", self);
|
||||
if(self == NULL)
|
||||
return 0;
|
||||
|
||||
ULONG count = (ULONG)env->GetArrayLength(vars);
|
||||
if(count == 0)
|
||||
return 0;
|
||||
|
||||
VARIANT* sink = (VARIANT*)CoTaskMemAlloc(count * sizeof(VARIANT));
|
||||
ULONG fetchCount = 0;
|
||||
|
||||
HRESULT hr = self->Next(count, sink, &fetchCount);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
CoTaskMemFree(sink);
|
||||
ThrowComFail(env, "IEnumVARIANT::Next", hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// prepare a new return value array
|
||||
//
|
||||
jclass clazz = env->FindClass("com/jacob/com/Variant");
|
||||
jmethodID ctor = env->GetMethodID(clazz, "<init>", "()V");
|
||||
|
||||
for(ULONG idx = 0; idx < fetchCount; ++idx)
|
||||
{
|
||||
// construct a variant to return
|
||||
//
|
||||
jobject newVariant = env->NewObject(clazz, ctor);
|
||||
VARIANT* v = extractVariant(env, newVariant);
|
||||
VariantCopy(v, sink + idx);
|
||||
env->SetObjectArrayElement(vars, idx, newVariant);
|
||||
env->DeleteLocalRef(newVariant);
|
||||
}
|
||||
CoTaskMemFree(sink);
|
||||
return (jint)fetchCount;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_release(JNIEnv* env, jobject _this)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self != NULL)
|
||||
{
|
||||
self->Release();
|
||||
jfieldID FID_pIEnumVARIANT = 0;
|
||||
jclass clazz = env->GetObjectClass(_this);
|
||||
FID_pIEnumVARIANT = env->GetFieldID(clazz, "m_pIEnumVARIANT", "I");
|
||||
env->SetIntField(_this, FID_pIEnumVARIANT, (unsigned int)0);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Reset(JNIEnv* env, jobject _this)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self == NULL)
|
||||
return;
|
||||
|
||||
HRESULT hr = self->Reset();
|
||||
if(FAILED(hr))
|
||||
ThrowComFail(env, "IEnumVARIANT::Reset", hr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_jacob_com_EnumVariant_Skip(JNIEnv* env, jobject _this, jint count)
|
||||
{
|
||||
IEnumVARIANT* self = extractEnumVariant(env, _this);
|
||||
if(self == NULL)
|
||||
return;
|
||||
|
||||
HRESULT hr = self->Skip((ULONG)count);
|
||||
if(FAILED(hr))
|
||||
ThrowComFail(env, "IEnumVARIANT::Skip", hr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
/* Header for class EnumVariant
|
||||
*/
|
||||
#ifndef _Included_EnumVariant
|
||||
#define _Included_EnumVariant
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Next
|
||||
* Signature: ([Lcom/jacob/com/Variant;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_jacob_com_EnumVariant_Next
|
||||
(JNIEnv *, jobject, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Reset
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Reset
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Skip
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Skip
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* Header for class EnumVariant
|
||||
*/
|
||||
#ifndef _Included_EnumVariant
|
||||
#define _Included_EnumVariant
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Next
|
||||
* Signature: ([Lcom/jacob/com/Variant;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_jacob_com_EnumVariant_Next
|
||||
(JNIEnv *, jobject, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Release
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_release
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Reset
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Reset
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_EnumVariant
|
||||
* Method: Skip
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_EnumVariant_Skip
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "EventProxy.h"
|
||||
|
||||
// hook myself up as a listener for delegate
|
||||
EventProxy::EventProxy(JNIEnv *env, jobject aSinkObj,
|
||||
CComPtr<IConnectionPoint> pConn,
|
||||
IID eid, CComBSTR mName[], DISPID mID[], int mNum) :
|
||||
m_cRef(0), pCP(pConn),
|
||||
eventIID(eid), MethNum(mNum), MethName(mName),
|
||||
MethID(mID), JMethID(NULL), javaSinkClass(NULL)
|
||||
{
|
||||
javaSinkObj = env->NewGlobalRef(aSinkObj);
|
||||
// we need this to attach to the event invocation thread
|
||||
env->GetJavaVM(&jvm);
|
||||
AddRef();
|
||||
HRESULT hr = pCP->Advise(this, &dwEventCookie);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// create a mapping from the DISPID's to jmethodID's by using
|
||||
// the method names I extracted from the classinfo
|
||||
JMethID = new jmethodID[MethNum];
|
||||
javaSinkClass = env->GetObjectClass(javaSinkObj);
|
||||
const char *method;
|
||||
for(int i=0;i<MethNum;i++)
|
||||
{
|
||||
// look for a method with the specified name, that takes an
|
||||
// array of variants and return void
|
||||
USES_CONVERSION;
|
||||
method = W2A((OLECHAR *)MethName[i]);
|
||||
JMethID[i] = env->GetMethodID(javaSinkClass, method, "([Lcom/jacob/com/Variant;)V");
|
||||
// need to clear exceptions because GetMethodID above may fail
|
||||
// if the user didn't implement all the methods
|
||||
env->ExceptionClear();
|
||||
}
|
||||
} else {
|
||||
ThrowComFail(env, "Advise failed", hr);
|
||||
}
|
||||
}
|
||||
|
||||
// unhook myself up as a listener and get rid of delegate
|
||||
EventProxy::~EventProxy()
|
||||
{
|
||||
pCP->Unadvise(dwEventCookie);
|
||||
JNIEnv *env;
|
||||
// attach to the current running thread
|
||||
jvm->AttachCurrentThread((void **)&env, jvm);
|
||||
|
||||
env->DeleteGlobalRef(javaSinkObj);
|
||||
if (MethNum) {
|
||||
delete [] MethName;
|
||||
delete [] MethID;
|
||||
if (JMethID) delete [] JMethID;
|
||||
}
|
||||
// detach from thread
|
||||
jvm->DetachCurrentThread();
|
||||
}
|
||||
|
||||
// I only support the eventIID interface which was passed in
|
||||
// by the DispatchEvent wrapper who looked it up as the
|
||||
// source object's default source interface
|
||||
STDMETHODIMP EventProxy::QueryInterface(REFIID rid, void **ppv)
|
||||
{
|
||||
if (rid == IID_IUnknown || rid == eventIID || rid == IID_IDispatch)
|
||||
{
|
||||
*ppv = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// This should never get called - the event source fires events
|
||||
// by dispid's, not by name
|
||||
STDMETHODIMP EventProxy::GetIDsOfNames(REFIID riid,
|
||||
OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
// The actual callback from the connection point arrives here
|
||||
STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
||||
LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
||||
{
|
||||
HRESULT hr;
|
||||
jmethodID meth = 0;
|
||||
JNIEnv *env = NULL;
|
||||
|
||||
|
||||
// map dispID to jmethodID
|
||||
for(int i=0;i<MethNum;i++)
|
||||
{
|
||||
if (MethID[i] == dispID) { meth = JMethID[i]; break; }
|
||||
}
|
||||
|
||||
if (!meth)
|
||||
{
|
||||
// user did not implement this method
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (DISPATCH_METHOD & wFlags)
|
||||
{
|
||||
// attach to the current running thread
|
||||
jvm->AttachCurrentThread((void**)&env, jvm);
|
||||
|
||||
// how many params
|
||||
int num = pDispParams->cArgs;
|
||||
// get variant class
|
||||
jclass vClass = env->FindClass("com/jacob/com/Variant");
|
||||
// and the constructor
|
||||
jmethodID vCons = env->GetMethodID(vClass, "<init>", "()V");
|
||||
// make an array of them
|
||||
jobjectArray varr = env->NewObjectArray(num, vClass, 0);
|
||||
int i,j;
|
||||
for(i=num-1,j=0;i>=0;i--,j++)
|
||||
{
|
||||
// construct a java variant holder
|
||||
jobject arg = env->NewObject(vClass, vCons);
|
||||
// get the empty variant from it
|
||||
VARIANT *va = extractVariant(env, arg);
|
||||
// copy the value
|
||||
VariantCopy(va, &pDispParams->rgvarg[i]);
|
||||
// put it in the array
|
||||
env->SetObjectArrayElement(varr, j, arg);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
// call the method
|
||||
env->CallVoidMethod(javaSinkObj, meth, varr);
|
||||
|
||||
// detach from thread
|
||||
jvm->DetachCurrentThread();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "EventProxy.h"
|
||||
|
||||
// hook myself up as a listener for delegate
|
||||
EventProxy::EventProxy(JNIEnv *env, jobject aSinkObj,
|
||||
CComPtr<IConnectionPoint> pConn,
|
||||
IID eid, CComBSTR mName[], DISPID mID[], int mNum) :
|
||||
m_cRef(0), pCP(pConn),
|
||||
eventIID(eid), MethNum(mNum), MethName(mName),
|
||||
MethID(mID), JMethID(NULL), javaSinkClass(NULL)
|
||||
{
|
||||
javaSinkObj = env->NewGlobalRef(aSinkObj);
|
||||
// we need this to attach to the event invocation thread
|
||||
env->GetJavaVM(&jvm);
|
||||
AddRef();
|
||||
HRESULT hr = pCP->Advise(this, &dwEventCookie);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// create a mapping from the DISPID's to jmethodID's by using
|
||||
// the method names I extracted from the classinfo
|
||||
JMethID = new jmethodID[MethNum];
|
||||
javaSinkClass = env->GetObjectClass(javaSinkObj);
|
||||
const char *method;
|
||||
for(int i=0;i<MethNum;i++)
|
||||
{
|
||||
// look for a method with the specified name, that takes an
|
||||
// array of variants and return void
|
||||
USES_CONVERSION;
|
||||
method = W2A((OLECHAR *)MethName[i]);
|
||||
JMethID[i] = env->GetMethodID(javaSinkClass, method, "([Lcom/jacob/com/Variant;)V");
|
||||
// need to clear exceptions because GetMethodID above may fail
|
||||
// if the user didn't implement all the methods
|
||||
env->ExceptionClear();
|
||||
}
|
||||
} else {
|
||||
ThrowComFail(env, "Advise failed", hr);
|
||||
}
|
||||
}
|
||||
|
||||
// unhook myself up as a listener and get rid of delegate
|
||||
EventProxy::~EventProxy()
|
||||
{
|
||||
pCP->Unadvise(dwEventCookie);
|
||||
JNIEnv *env;
|
||||
// attach to the current running thread
|
||||
jvm->AttachCurrentThread((void **)&env, jvm);
|
||||
|
||||
env->DeleteGlobalRef(javaSinkObj);
|
||||
if (MethNum) {
|
||||
delete [] MethName;
|
||||
delete [] MethID;
|
||||
if (JMethID) delete [] JMethID;
|
||||
}
|
||||
// detach from thread
|
||||
jvm->DetachCurrentThread();
|
||||
}
|
||||
|
||||
// I only support the eventIID interface which was passed in
|
||||
// by the DispatchEvent wrapper who looked it up as the
|
||||
// source object's default source interface
|
||||
STDMETHODIMP EventProxy::QueryInterface(REFIID rid, void **ppv)
|
||||
{
|
||||
if (rid == IID_IUnknown || rid == eventIID || rid == IID_IDispatch)
|
||||
{
|
||||
*ppv = this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// This should never get called - the event source fires events
|
||||
// by dispid's, not by name
|
||||
STDMETHODIMP EventProxy::GetIDsOfNames(REFIID riid,
|
||||
OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
// The actual callback from the connection point arrives here
|
||||
STDMETHODIMP EventProxy::Invoke(DISPID dispID, REFIID riid,
|
||||
LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams,
|
||||
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
||||
{
|
||||
HRESULT hr;
|
||||
jmethodID meth = 0;
|
||||
JNIEnv *env = NULL;
|
||||
|
||||
|
||||
// map dispID to jmethodID
|
||||
for(int i=0;i<MethNum;i++)
|
||||
{
|
||||
if (MethID[i] == dispID) { meth = JMethID[i]; break; }
|
||||
}
|
||||
|
||||
if (!meth)
|
||||
{
|
||||
// user did not implement this method
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (DISPATCH_METHOD & wFlags)
|
||||
{
|
||||
// attach to the current running thread
|
||||
jvm->AttachCurrentThread((void**)&env, jvm);
|
||||
|
||||
// how many params
|
||||
int num = pDispParams->cArgs;
|
||||
// get variant class
|
||||
jclass vClass = env->FindClass("com/jacob/com/Variant");
|
||||
// and the constructor
|
||||
jmethodID vCons = env->GetMethodID(vClass, "<init>", "()V");
|
||||
// make an array of them
|
||||
jobjectArray varr = env->NewObjectArray(num, vClass, 0);
|
||||
int i,j;
|
||||
for(i=num-1,j=0;i>=0;i--,j++)
|
||||
{
|
||||
// construct a java variant holder
|
||||
jobject arg = env->NewObject(vClass, vCons);
|
||||
// get the empty variant from it
|
||||
VARIANT *va = extractVariant(env, arg);
|
||||
// copy the value
|
||||
VariantCopy(va, &pDispParams->rgvarg[i]);
|
||||
// put it in the array
|
||||
env->SetObjectArrayElement(varr, j, arg);
|
||||
env->DeleteLocalRef(arg);
|
||||
}
|
||||
// call the method
|
||||
env->CallVoidMethod(javaSinkObj, meth, varr);
|
||||
|
||||
// detach from thread
|
||||
jvm->DetachCurrentThread();
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
214
jni/EventProxy.h
214
jni/EventProxy.h
@@ -1,107 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Dan Adler, 315 E72 St. NY, NY, 10021, USA.
|
||||
* mailto:danadler@rcn.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* Redistribution of the JACOB software is not permitted as part of any
|
||||
* commercial product that is targeted primarily at Java developers.
|
||||
* Such products include, but are not limited to: Java virtual machines,
|
||||
* integrated development environments, code libraries, and application
|
||||
* server products. Licensing terms for such distribution may be
|
||||
* obtained from the copyright holder.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <jni.h>
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "stdafx.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* An instance of this class stands between a connection point
|
||||
* and a java object. When it gets invoked from the cp, it reflects
|
||||
* the call into the java object dynamically. The eventIID is passed
|
||||
* in as are the valid dispids and the corresponding names. A map
|
||||
* is created between the dispids and the java object's method in
|
||||
* the constructor. For now, all the java event methods have to have
|
||||
* the same signature: <name>(Variant[])
|
||||
*/
|
||||
class EventProxy : public IDispatch
|
||||
{
|
||||
private:
|
||||
LONG m_cRef;
|
||||
CComPtr<IConnectionPoint> pCP; // the connection point
|
||||
DWORD dwEventCookie; // connection point cookie
|
||||
jobject javaSinkObj; // the java object to delegate calls
|
||||
jclass javaSinkClass; // the java class of the object
|
||||
IID eventIID; // the interface iid passed in
|
||||
int MethNum;
|
||||
CComBSTR *MethName; // Array of method names
|
||||
DISPID *MethID; // Array of method ids
|
||||
jmethodID *JMethID; // Array of java method ids
|
||||
JavaVM *jvm; // The java vm we are running
|
||||
public:
|
||||
// constuct with a global JNI ref to a sink object
|
||||
// to which we will delegate event callbacks
|
||||
EventProxy(JNIEnv *jenv, jobject aSinkObj,
|
||||
CComPtr<IConnectionPoint> pConn,
|
||||
IID eventIID, CComBSTR *mName, DISPID *mID, int mNum);
|
||||
~EventProxy();
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHODIMP_(ULONG) AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) Release(void)
|
||||
{
|
||||
LONG res = InterlockedDecrement(&m_cRef);
|
||||
if (res == 0) delete this;
|
||||
return res;
|
||||
}
|
||||
|
||||
STDMETHODIMP QueryInterface(REFIID rid, void **ppv);
|
||||
|
||||
// IDispatch methods
|
||||
STDMETHODIMP GetTypeInfoCount(UINT *num)
|
||||
{
|
||||
*num = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetTypeInfo(UINT, LCID, ITypeInfo **pptInfo)
|
||||
{
|
||||
*pptInfo=NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// These are the actual supported methods
|
||||
STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR **, UINT, LCID , DISPID *);
|
||||
STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD , DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *);
|
||||
};
|
||||
/*
|
||||
* Copyright (c) 1999 Dan Adler, 315 E72 St. NY, NY, 10021, USA.
|
||||
* mailto:danadler@rcn.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* Redistribution of the JACOB software is not permitted as part of any
|
||||
* commercial product that is targeted primarily at Java developers.
|
||||
* Such products include, but are not limited to: Java virtual machines,
|
||||
* integrated development environments, code libraries, and application
|
||||
* server products. Licensing terms for such distribution may be
|
||||
* obtained from the copyright holder.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <jni.h>
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "stdafx.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* An instance of this class stands between a connection point
|
||||
* and a java object. When it gets invoked from the cp, it reflects
|
||||
* the call into the java object dynamically. The eventIID is passed
|
||||
* in as are the valid dispids and the corresponding names. A map
|
||||
* is created between the dispids and the java object's method in
|
||||
* the constructor. For now, all the java event methods have to have
|
||||
* the same signature: <name>(Variant[])
|
||||
*/
|
||||
class EventProxy : public IDispatch
|
||||
{
|
||||
private:
|
||||
LONG m_cRef;
|
||||
CComPtr<IConnectionPoint> pCP; // the connection point
|
||||
DWORD dwEventCookie; // connection point cookie
|
||||
jobject javaSinkObj; // the java object to delegate calls
|
||||
jclass javaSinkClass; // the java class of the object
|
||||
IID eventIID; // the interface iid passed in
|
||||
int MethNum;
|
||||
CComBSTR *MethName; // Array of method names
|
||||
DISPID *MethID; // Array of method ids
|
||||
jmethodID *JMethID; // Array of java method ids
|
||||
JavaVM *jvm; // The java vm we are running
|
||||
public:
|
||||
// constuct with a global JNI ref to a sink object
|
||||
// to which we will delegate event callbacks
|
||||
EventProxy(JNIEnv *jenv, jobject aSinkObj,
|
||||
CComPtr<IConnectionPoint> pConn,
|
||||
IID eventIID, CComBSTR *mName, DISPID *mID, int mNum);
|
||||
~EventProxy();
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHODIMP_(ULONG) AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) Release(void)
|
||||
{
|
||||
LONG res = InterlockedDecrement(&m_cRef);
|
||||
if (res == 0) delete this;
|
||||
return res;
|
||||
}
|
||||
|
||||
STDMETHODIMP QueryInterface(REFIID rid, void **ppv);
|
||||
|
||||
// IDispatch methods
|
||||
STDMETHODIMP GetTypeInfoCount(UINT *num)
|
||||
{
|
||||
*num = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP GetTypeInfo(UINT, LCID, ITypeInfo **pptInfo)
|
||||
{
|
||||
*pptInfo=NULL;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// These are the actual supported methods
|
||||
STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR **, UINT, LCID , DISPID *);
|
||||
STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD , DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *);
|
||||
};
|
||||
|
||||
146
jni/STA.cpp
146
jni/STA.cpp
@@ -1,73 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
// store the current thread id so we can kill it
|
||||
jclass argClass = env->GetObjectClass(obj);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "threadID", "I");
|
||||
jint threadID = (jint)GetCurrentThreadId();
|
||||
env->SetIntField(obj, ajf, threadID);
|
||||
|
||||
MSG msg;
|
||||
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
msg.wParam = S_OK;
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(obj);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "threadID", "I");
|
||||
jint threadID = env->GetIntField(obj, ajf);
|
||||
PostThreadMessage((DWORD)threadID, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include <objbase.h>
|
||||
#include "ComThread.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
// store the current thread id so we can kill it
|
||||
jclass argClass = env->GetObjectClass(obj);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "threadID", "I");
|
||||
jint threadID = (jint)GetCurrentThreadId();
|
||||
env->SetIntField(obj, ajf, threadID);
|
||||
|
||||
MSG msg;
|
||||
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
msg.wParam = S_OK;
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
jclass argClass = env->GetObjectClass(obj);
|
||||
jfieldID ajf = env->GetFieldID( argClass, "threadID", "I");
|
||||
jint threadID = env->GetIntField(obj, ajf);
|
||||
PostThreadMessage((DWORD)threadID, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
58
jni/STA.h
58
jni/STA.h
@@ -1,29 +1,29 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class STA */
|
||||
|
||||
#ifndef _Included_com_jacob_com_STA
|
||||
#define _Included_com_jacob_com_STA
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_STA
|
||||
* Method: doMessagePump
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_STA
|
||||
* Method: quitMessagePump
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class STA */
|
||||
|
||||
#ifndef _Included_com_jacob_com_STA
|
||||
#define _Included_com_jacob_com_STA
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: com_jacob_com_STA
|
||||
* Method: doMessagePump
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_doMessagePump
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: com_jacob_com_STA
|
||||
* Method: quitMessagePump
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_jacob_com_STA_quitMessagePump
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
4876
jni/SafeArray.cpp
4876
jni/SafeArray.cpp
File diff suppressed because it is too large
Load Diff
1386
jni/SafeArray.h
1386
jni/SafeArray.h
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// stdafx.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _ATL_STATIC_REGISTRY
|
||||
#include <statreg.h>
|
||||
#include <statreg.cpp>
|
||||
#endif
|
||||
|
||||
#include <atlimpl.cpp>
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// stdafx.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _ATL_STATIC_REGISTRY
|
||||
#include <statreg.h>
|
||||
#include <statreg.cpp>
|
||||
#endif
|
||||
|
||||
#include <atlimpl.cpp>
|
||||
|
||||
64
jni/StdAfx.h
64
jni/StdAfx.h
@@ -1,32 +1,32 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_)
|
||||
#define AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
//#define _ATL_APARTMENT_THREADED
|
||||
#include <windows.h>
|
||||
#include <comdef.h>
|
||||
#include <comutil.h>
|
||||
#include <atlbase.h>
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED)
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_)
|
||||
#define AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
//#define _ATL_APARTMENT_THREADED
|
||||
#include <windows.h>
|
||||
#include <comdef.h>
|
||||
#include <comutil.h>
|
||||
#include <atlbase.h>
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__9988E984_6789_11D3_A646_000000000000__INCLUDED)
|
||||
|
||||
2290
jni/Variant.cpp
2290
jni/Variant.cpp
File diff suppressed because it is too large
Load Diff
1226
jni/Variant.h
1226
jni/Variant.h
File diff suppressed because it is too large
Load Diff
138
jni/util.cpp
138
jni/util.cpp
@@ -1,69 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void ThrowComFail(JNIEnv *env, const char* desc, jint hr)
|
||||
{
|
||||
jclass failClass = env->FindClass("com/jacob/com/ComFailException");
|
||||
// call the constructor that takes hr and message
|
||||
jmethodID failCons =
|
||||
env->GetMethodID(failClass, "<init>", "(ILjava/lang/String;)V");
|
||||
if (!desc) desc = "Java/COM Error";
|
||||
jstring js = env->NewStringUTF(desc);
|
||||
jthrowable fail = (jthrowable)env->NewObject(failClass, failCons, hr, js);
|
||||
env->Throw(fail);
|
||||
}
|
||||
|
||||
// if env's are different throw on the 1st env
|
||||
int CheckEnv(JNIEnv *env1, JNIEnv *env2)
|
||||
{
|
||||
if (env1 != env2) {
|
||||
jclass failClass = env1->FindClass("com/jacob/com/WrongThreadException");
|
||||
// call the constructor that takes hr and message
|
||||
jmethodID failCons =
|
||||
env1->GetMethodID(failClass, "<init>", "()V");
|
||||
env1->ThrowNew(failClass, "Wrong Thread");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 1999-2004 Sourceforge JACOB Project.
|
||||
* All rights reserved. Originator: Dan Adler (http://danadler.com).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Redistributions in any form must be accompanied by information on
|
||||
* how to obtain complete source code for the JACOB software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "Dispatch.h"
|
||||
// Win32 support for Ole Automation
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <atlbase.h>
|
||||
#include <objbase.h>
|
||||
#include <oleauto.h>
|
||||
#include <olectl.h>
|
||||
#include "util.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void ThrowComFail(JNIEnv *env, const char* desc, jint hr)
|
||||
{
|
||||
jclass failClass = env->FindClass("com/jacob/com/ComFailException");
|
||||
// call the constructor that takes hr and message
|
||||
jmethodID failCons =
|
||||
env->GetMethodID(failClass, "<init>", "(ILjava/lang/String;)V");
|
||||
if (!desc) desc = "Java/COM Error";
|
||||
jstring js = env->NewStringUTF(desc);
|
||||
jthrowable fail = (jthrowable)env->NewObject(failClass, failCons, hr, js);
|
||||
env->Throw(fail);
|
||||
}
|
||||
|
||||
// if env's are different throw on the 1st env
|
||||
int CheckEnv(JNIEnv *env1, JNIEnv *env2)
|
||||
{
|
||||
if (env1 != env2) {
|
||||
jclass failClass = env1->FindClass("com/jacob/com/WrongThreadException");
|
||||
// call the constructor that takes hr and message
|
||||
jmethodID failCons =
|
||||
env1->GetMethodID(failClass, "<init>", "()V");
|
||||
env1->ThrowNew(failClass, "Wrong Thread");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
16
jni/util.h
16
jni/util.h
@@ -1,8 +1,8 @@
|
||||
#include <objbase.h>
|
||||
extern "C" {
|
||||
VARIANT *extractVariant(JNIEnv *env, jobject arg);
|
||||
void ThrowComFail(JNIEnv *env, const char* desc, jint hr);
|
||||
IDispatch *extractDispatch(JNIEnv *env, jobject arg);
|
||||
SAFEARRAY *extractSA(JNIEnv *env, jobject arg);
|
||||
void setSA(JNIEnv *env, jobject arg, SAFEARRAY *sa, int copy);
|
||||
}
|
||||
#include <objbase.h>
|
||||
extern "C" {
|
||||
VARIANT *extractVariant(JNIEnv *env, jobject arg);
|
||||
void ThrowComFail(JNIEnv *env, const char* desc, jint hr);
|
||||
IDispatch *extractDispatch(JNIEnv *env, jobject arg);
|
||||
SAFEARRAY *extractSA(JNIEnv *env, jobject arg);
|
||||
void setSA(JNIEnv *env, jobject arg, SAFEARRAY *sa, int copy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user