You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@xml.apache.org by sn...@apache.org on 2002/09/11 23:21:24 UTC
cvs commit: xml-soap/java/src/org/apache/soap/providers/com COMProvider.dll RPCProvider.cpp RPCProvider.h
snichol 2002/09/11 14:21:24
Modified: java/src/org/apache/soap/providers/com COMProvider.dll
RPCProvider.cpp RPCProvider.h
Log:
Avoid use of ws2mbs macro when handling strings. That macro makes a copy
of the string on the stack, which is a problem for long strings.
Revision Changes Path
1.5 +18 -9 xml-soap/java/src/org/apache/soap/providers/com/COMProvider.dll
<<Binary file>>
1.4 +129 -30 xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.cpp
Index: RPCProvider.cpp
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- RPCProvider.cpp 16 Aug 2002 19:17:38 -0000 1.3
+++ RPCProvider.cpp 11 Sep 2002 21:21:23 -0000 1.4
@@ -74,12 +74,11 @@
using namespace std;
-
-
HRESULT variant2object (JNIEnv *jenv, const VARIANT &var, jobject &ret, bool *localRefCreated= NULL);
wchar_t ModuleName[MAX_PATH *2 ]={0};
HANDLE thisModule;
+
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID fImpLoad)
{
if(fdwReason == DLL_PROCESS_ATTACH)
@@ -133,6 +132,9 @@
const short LOG_ERROR = 1;
short eventLevel= LOG_ERROR;
+/*
+ * Undoes an action when exiting scope.
+ */
struct Undoit
{
void (__stdcall*coinit )(void);
@@ -147,14 +149,23 @@
}
};
+/*
+ * The actual provider.
+ */
class COMProvider
{
jobject jPP; //the java pluggable provider
JNIEnv *env;
static const char* javaClass;
public:
+ /*
+ * Constructor that initializes member variables.
+ */
COMProvider(JNIEnv *e, jobject jthis):jPP(jthis),env(e){};
-
+ /*
+ * Gets the dispatch type to handle property get/set as
+ * well as straight method calls.
+ */
WORD getMethodDispatchType( const wchar_t *mname)
{
WORD ret = DISPATCH_METHOD;
@@ -162,13 +173,21 @@
else if(0 == wcsncmp(L"set_", mname, 4)) ret= DISPATCH_PROPERTYPUT;
return ret;
}
-
+ /*
+ * Invokes a method on a COM object, translating parameters and results
+ * between Java types and COM types.
+ */
jobject invoke (jstring jthreadingModel, jstring jprogid, jstring jmethodName, jbyteArray parms_in)
{
eventlog(LOG_SUCCESS, msgCalledDLL, ModuleName );
wchar_t progid[256];
Undoit undoit;
ZeroIt(undoit);
+ //
+ // Get a local copy of parameters. The Java code for the
+ // provider has already munged the Java parameters into the
+ // byte array (which is really a VARIANT array) we use here.
+ //
jsize noParmsBytes= NULL == parms_in ? 0 : env->GetArrayLength( parms_in);
unsigned noParms= noParmsBytes/ sizeof VARIANT;
eventlog(LOG_SUCCESS, msgNoParms, noParms );
@@ -195,6 +214,9 @@
dumpVariant(vp[i]);
}
*/
+ //
+ // Initialize COM
+ //
DWORD coInit= COINIT_MULTITHREADED; //The default.
bool oleInit= false;
jboolean isCopy;
@@ -236,7 +258,9 @@
}
undoit.coinit= CoUninitialize; //Ensure we uninitialize.
}
-
+ //
+ // Get the method name
+ //
cstr= (wchar_t *)env->GetStringChars(jmethodName, &isCopy);
wchar_t *methodName= _wcsdup(cstr);
if(isCopy == JNI_TRUE) env->ReleaseStringChars(jmethodName, cstr);
@@ -246,7 +270,9 @@
throwSoapException( msgFailedMemory);
return NULL;
}
-
+ //
+ // Get the CLSID
+ //
CLSID clsid;
cstr= (wchar_t*) env->GetStringChars(jprogid, &isCopy);
if( L'{' == cstr[0]) //clsid is specified as a string
@@ -278,8 +304,9 @@
wcsncpy(progid, cstr, (sizeof(progid)/(sizeof progid[0]))-1);
if(isCopy == JNI_TRUE) env->ReleaseStringChars(jprogid, cstr);
- //Start doing COM stuff
-
+ //
+ // Create an instance of the COM object
+ //
hr= CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IDispatch, (void **)&undoit.idisp );
if (ASSERT_FAILED(hr))
@@ -289,8 +316,9 @@
if(methodName) free(methodName);
return NULL;
}
-
-
+ //
+ // Get the dispatch id of the method
+ //
DISPID dispid;
ZeroIt(dispid);
bool isSet= false;
@@ -308,7 +336,9 @@
if(methodName) free(methodName);
return NULL;
}
-
+ //
+ // Initialize the parameter info
+ //
DISPPARAMS dispparams;
ZeroIt( dispparams);
dispparams.rgvarg= undoit.vp;
@@ -319,15 +349,19 @@
dispparams.cNamedArgs= 1 ;
dispparams.rgdispidNamedArgs= &didpp;
}
+ //
+ // Invoke the COM method
+ //
VARIANT result;
ZeroIt(result);
EXCEPINFO expInfo;
ZeroIt( expInfo);
unsigned parg;
ZeroIt( parg);
-
hr= undoit.idisp->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), getMethodDispatchType(methodName), &dispparams, &result, &expInfo, &parg);
-
+ //
+ // Translate COM errors or exceptions to Java
+ //
if(hr == DISP_E_EXCEPTION )
{
unsigned long err= (unsigned long) expInfo.wCode;
@@ -352,6 +386,9 @@
if(methodName) free(methodName);
return NULL;
}
+ //
+ // Convert the result to a variant
+ //
jobject jresult= NULL;
hr= variant2object (env, result, jresult);
@@ -369,30 +406,47 @@
::VariantClear(&result);
return jresult;
}
- //Throw a Java SOAP Exception.
+ /*
+ * Throws a SOAP exception for a UNICODE string.
+ */
BOOL throwSoapException( const wchar_t *msg)
{
if(NULL== msg) msg= L"Exception thrown by COMProvider";
- jstring jmsg= env->NewStringUTF(ws2mbs(msg));
+// jstring jmsg= env->NewStringUTF(ws2mbs(msg));
+ jstring jmsg= env->NewString(msg, wcslen(msg));
jclass jcASE= env->FindClass(javaClass);
jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
jthrowable jt= (jthrowable) env->CallStaticObjectMethod(jcASE,mid, jmsg);
env->Throw(jt);
return true;
}
-
+ /*
+ * Throws a SOAP exception for a string.
+ */
+ BOOL throwSoapException( const char *msg)
+ {
+ if(NULL== msg) msg= "Exception thrown by COMProvider";
+ jstring jmsg= env->NewStringUTF(msg);
+ jclass jcASE= env->FindClass(javaClass);
+ jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
+ jthrowable jt= (jthrowable) env->CallStaticObjectMethod(jcASE,mid, jmsg);
+ env->Throw(jt);
+ return true;
+ }
+ /*
+ * Throws a SOAP exception for a Win32 message id.
+ */
BOOL throwSoapException( int id, ...)
{
-
va_list a;
va_start( a, id);
wchar_t *msgbuf= NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_STRING ,
(wchar_t *)id, 0, 3, (wchar_t *) &msgbuf, 10000, &a);
-
if(NULL== msgbuf || *msgbuf == L'\0') msgbuf= L"Exception thrown by COMProvider";
- jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
+// jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
+ jstring jmsg= env->NewString(msgbuf, wcslen(msgbuf));
LocalFree( msgbuf );
jclass jcASE= env->FindClass(javaClass);
jmethodID mid= env->GetStaticMethodID(jcASE,"getSOAPException","(Ljava/lang/String;)Lorg/apache/soap/SOAPException;");
@@ -400,12 +454,13 @@
env->Throw(jt);
env->DeleteLocalRef(jmsg);
- return true;
+ return true;
}
-
+ /*
+ * Logs an event
+ */
BOOL eventlog(short eventtype, int id, ...)
{
-
if( (eventtype & eventLevel) == 0 ) return false;
va_list a;
va_start( a, id);
@@ -415,7 +470,8 @@
// fwprintf( stderr, L"%s\n", msgbuf);
jclass spClass= env->GetObjectClass(jPP);
- jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
+// jstring jmsg= env->NewStringUTF(ws2mbs(msgbuf));
+ jstring jmsg= env->NewString(msgbuf, wcslen(msgbuf));
jmethodID mid= env->GetMethodID(spClass, "logit", "(ILjava/lang/String;)V");
env->CallVoidMethod(jPP, mid, (jint)eventtype, jmsg);
env->DeleteLocalRef(jmsg);
@@ -424,11 +480,21 @@
return true;
}
};//class COMProvider
- const char* COMProvider::javaClass= "org/apache/soap/providers/com/RPCProvider";
+/*
+ * Native methods
+ */
+const char* COMProvider::javaClass= "org/apache/soap/providers/com/RPCProvider";
+
+/*
+ * org.apache.soap.providers.com.RPCProvider#invoke
+ *
+ * Invokes the COM method as the SOAP service.
+ */
extern "C" JNIEXPORT jobject JNICALL Java_org_apache_soap_providers_com_RPCProvider_invoke
(JNIEnv *env, jobject jo, jstring threadingModel, jstring jprogid, jstring jmethodName, jbyteArray parms_in)
{
+ // Instantiate a COMProvider (see above) and call its invoke member function.
CRTDBGBRK
COMProvider cp(env, jo);
#ifdef NDEBUG //This also will to debug on demand so if we are debugging don't do the catch.
@@ -439,6 +505,25 @@
return cp.invoke(threadingModel, jprogid, jmethodName, parms_in);
#ifdef NDEBUG
}
+ catch(wchar_t *wstr)
+ {
+ env->ExceptionClear(); //Ignore all previous errors.
+ cp.throwSoapException(wstr);
+ return NULL;
+ }
+ catch(char *str)
+ {
+ env->ExceptionClear(); //Ignore all previous errors.
+ cp.throwSoapException(str);
+ return NULL;
+ }
+ catch(unsigned int ui)
+ {
+ env->ExceptionClear(); //Ignore all previous errors.
+ wchar_t numbuf[16];
+ cp.throwSoapException(_ultow(ui, numbuf, 10));
+ return NULL;
+ }
catch( ... )
{ //Main point here is not to trap the JVM!
env->ExceptionClear(); //Ignore all previous errors.
@@ -447,10 +532,20 @@
}
#endif
}
+/*
+ * org.apache.soap.providers.com.RPCProvider#initlog
+ *
+ * Sets the logging level.
+ */
extern "C" JNIEXPORT void JNICALL Java_org_apache_soap_providers_com_RPCProvider_initlog(JNIEnv *env, jclass jc, jshort jlvl)
{
eventLevel= jlvl;
}
+/*
+ * org.apache.soap.providers.com.RPCProvider#nativeConvertToBString
+ *
+ * Converts a Java string to a BSTR.
+ */
extern "C" JNIEXPORT jbyteArray JNICALL Java_org_apache_soap_providers_com_RPCProvider_nativeConvertToBString(JNIEnv *env, jclass jc, jstring s)
{
env->ExceptionClear(); //Let a calling thread to invoke a call record the error.
@@ -466,8 +561,9 @@
return jByteArray;
}
-/* make objects from primitives */
-
+/*
+ * Functions to create a Java Object from primitive types.
+ */
jobject bsf_makeBoolean (JNIEnv *jenv, int val) {
jclass classobj = jenv->FindClass ( "java/lang/Boolean");
jmethodID constructor =
@@ -486,8 +582,7 @@
jclass classobj = jenv->FindClass ( "java/lang/Short");
jmethodID constructor =
jenv->GetMethodID ( classobj, "<init>", "(S)V");
- return jenv->NewObject ( classobj, constructor, (jshort) val);
-}
+ return jenv->NewObject ( classobj, constructor, (jshort) val);
}
jobject bsf_makeInteger (JNIEnv *jenv, int val) {
jclass classobj = jenv->FindClass ( "java/lang/Integer");
@@ -517,6 +612,9 @@
return jenv->NewObject ( classobj, constructor, (jdouble) val);
}
+/*
+ * Create a Java Object from VARIANT types.
+ */
HRESULT variant2object (JNIEnv *jenv, const VARIANT &var, jobject &jresult, bool *localRefCreated)
{
HRESULT result = S_OK;
@@ -550,8 +648,9 @@
break;
case VT_BSTR:
/* if its a string with the right stuff, retract the object */
- buf= ws2mbs(var.bstrVal);
- jresult = jenv->NewStringUTF (buf);
+// buf= ws2mbs(var.bstrVal);
+// jresult = jenv->NewStringUTF (buf);
+ jresult = jenv->NewString(var.bstrVal, wcslen(var.bstrVal));
break;
case VT_BOOL:
jresult = bsf_makeBoolean (jenv, (int) V_BOOL (&var));
1.2 +2 -0 xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.h
Index: RPCProvider.h
===================================================================
RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/providers/com/RPCProvider.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RPCProvider.h 14 Mar 2001 19:39:56 -0000 1.1
+++ RPCProvider.h 11 Sep 2002 21:21:23 -0000 1.2
@@ -127,6 +127,8 @@
return (char *) d;
}
+// TODO: this requires sufficient stack for a copy of the string,
+// which may simply not be available.
#define ws2mbs(s) (ws2mbsConvert((s), _alloca( ((2+(wcslen((const wchar_t *)(s))<<1))))))
template<class T> inline void ZeroIt(T &t){ memset(&t, 0, sizeof t);};
--
To unsubscribe, e-mail: <ma...@xml.apache.org>
For additional commands, e-mail: <ma...@xml.apache.org>