00001 /*---------------------------------------------------------------------------- 00002 Name: XmlBlasterUnmanagedCE.c 00003 Project: xmlBlaster.org 00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file 00005 Comment: See XmlBlasterUnmanagedCE.h 00006 Access C dll from C# on Windows CE with P/Invoke 00007 Todo: Callback function (update from Dll to C#) 00008 Author: "Marcel Ruff" <xmlBlaster@marcelruff.info> 00009 See: http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html 00010 -----------------------------------------------------------------------------*/ 00011 #include <string.h> /* memset */ 00012 #include <stdio.h> /* printf */ 00013 #include <XmlBlasterUnmanagedCE.h> 00014 #ifndef WINCE 00015 # include <stdarg.h> 00016 # include <locale.h> /* setlocal() */ 00017 #endif 00018 00019 #ifdef __cplusplus 00020 # define XBFORCE_EXTERNC extern "C" 00021 #else 00022 # define XBFORCE_EXTERNC 00023 #endif 00024 00025 static const bool freeIt = true; 00026 00027 /* 00028 We should avoid C++ code as the name mangling makes difficulties, 00029 so we force C code here. 00030 See: http://www.opennetcf.org/Forums/topic.asp?TOPIC_ID=255 00031 */ 00032 00033 static void myLogger(void *logUserP, 00034 XMLBLASTER_LOG_LEVEL currLevel, 00035 XMLBLASTER_LOG_LEVEL level, 00036 const char *location, const char *fmt, ...); 00037 00038 static void myLogger(void *logUserP, 00039 XMLBLASTER_LOG_LEVEL currLevel, 00040 XMLBLASTER_LOG_LEVEL level, 00041 const char *location, const char *fmt, ...) 00042 { 00043 /* Guess we need no more than 200 bytes. */ 00044 int n, size = 200; 00045 char *p = 0; 00046 va_list ap; 00047 int32_t lvl = (int32_t)level; 00048 XmlBlasterUnmanagedCELoggerFp managedLoggerFp = (XmlBlasterUnmanagedCELoggerFp)logUserP; 00049 00050 00051 if (managedLoggerFp == 0) 00052 return; 00053 00054 if (level > currLevel) { /* XMLBLASTER_LOG_ERROR, XMLBLASTER_LOG_WARN, XMLBLASTER_LOG_INFO, XMLBLASTER_LOG_TRACE */ 00055 return; 00056 } 00057 if ((p = (char *)malloc (size)) == NULL) 00058 return; 00059 00060 for (;;) { 00061 /* Try to print in the allocated space. */ 00062 va_start(ap, fmt); 00063 n = VSNPRINTF(p, size, fmt, ap); /* UNIX: vsnprintf(), WINDOWS: _vsnprintf() */ 00064 va_end(ap); 00065 /* If that worked, print the string to console. */ 00066 if (n > -1 && n < size) { 00067 /*printf("{%s-%s-%s} [%s] %s\n", 00068 __DATE__, __TIME__, getLogLevelStr(level), location, p);*/ 00069 /* Call now the C# logger XmlBlasterUnmanagedCELoggerFp */ 00070 00071 (*managedLoggerFp)(lvl, location, p); 00072 00073 /* The C# code does not free 'p' during its UNICODE marshalling 00074 with byteArrayFromIntPtr(false) -> no xmlBlasterUnmanagedCEFree() */ 00075 free(p); 00076 00077 return; 00078 } 00079 /* Else try again with more space. */ 00080 if (n > -1) /* glibc 2.1 */ 00081 size = n+1; /* precisely what is needed */ 00082 else /* glibc 2.0 */ 00083 size *= 2; /* twice the old size */ 00084 if ((p = (char *)realloc (p, size)) == NULL) { 00085 return; 00086 } 00087 } 00088 } 00089 00090 /* extern "C" __declspec (dllexport) */ 00091 XBFORCE_EXTERNC Dll_Export void xmlBlasterUnmanagedCERegisterLogger(struct XmlBlasterAccessUnparsed *xa, 00092 XmlBlasterUnmanagedCELoggerFp logger) { 00093 /*MessageBox(NULL, L"Entering xmlBlasterUnmanagedCERegisterLogger", _T("Unmanaged"), MB_OK);*/ 00094 /*printf("dll: Register logger\n");*/ 00095 if (logger != 0) { 00096 /* Register our own logging function */ 00097 xa->log = myLogger; 00098 /* Pass a pointer which we can use in myLogger() again */ 00099 xa->logUserP = (void*)logger; 00100 } 00101 else { /* unregister */ 00102 xa->log = 0; 00103 xa->logUserP = 0; 00104 } 00105 /*xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_ERROR, __FILE__, "Testing logging output only");*/ 00106 } 00107 00108 00109 static void callbackProgressListener(void *userP, const size_t currBytesRead, const size_t nbytes); 00115 static void callbackProgressListener(void *userP, const size_t currBytesRead, const size_t nbytes) { 00116 XmlBlasterUnmanagedCECallbackProgressListenerFp *fp = (XmlBlasterUnmanagedCECallbackProgressListenerFp *)userP; 00117 if (fp != 0) { 00118 int32_t curr = (int32_t)currBytesRead; 00119 int32_t n = (int32_t)nbytes; 00120 printf("C-DLL: entering callbackProgressListener(fp=%ld) %d/%d\n", (long)fp, curr, n); 00121 (*fp)(curr, n); 00122 printf("C-DLL: done callbackProgressListener(fp=%ld) %d/%d\n", (long)fp, curr, n); 00123 } 00124 } 00128 XBFORCE_EXTERNC Dll_Export void xmlBlasterUnmanagedCERegisterProgressListener( 00129 struct XmlBlasterAccessUnparsed *xa, 00130 XmlBlasterUnmanagedCECallbackProgressListenerFp csharpProgressListenerFp) { 00131 00132 if (xa && xa->callbackP != 0) { 00133 xa->callbackP->readFromSocket.numReadUserP = (void*)csharpProgressListenerFp; 00134 if (callbackProgressListener != 0) { 00135 printf("C-DLL: doing xmlBlasterUnmanagedCERegisterProgressListener(csharpProgressListenerFp=%ld)\n", (long)csharpProgressListenerFp); 00136 xa->callbackP->readFromSocket.numReadFuncP = callbackProgressListener; 00137 } 00138 else { 00139 xa->callbackP->readFromSocket.numReadFuncP = 0; /* Dangerous: not thread safe, TODO: Add a mutex */ 00140 } 00141 } 00142 } 00143 00149 XBFORCE_EXTERNC extern char *xmlBlasterUnmanagedCEMalloc(int32_t size) { 00150 /*printf("dll: xmlBlasterUnmanagedCEMalloc(size=%d)\n", size);*/ 00151 if (size > 0) 00152 return (char *)malloc(size*sizeof(char)); 00153 return (char *)0; 00154 } 00155 00160 XBFORCE_EXTERNC extern void xmlBlasterUnmanagedCEFree(char *p) { 00161 /*if (p!=0) 00162 printf("dll: xmlBlasterUnmanagedCEFree size=%d:\n%s\n", strlen(p), p);*/ /* dangeraous for none strings like IntPtr */ 00163 xmlBlasterFree(p); 00164 } 00165 00172 XBFORCE_EXTERNC extern void xmlBlasterUnmanagedCEFreePP(char **pp) { 00173 if (pp==0) 00174 return; 00175 else { 00176 char *p = *pp; 00177 /*printf("dll: xmlBlasterUnmanagedCEFreePP('%s')\n", ((p!=(char *)0)?p:""));*/ 00178 xmlBlasterFree(p); 00179 } 00180 } 00181 00186 XBFORCE_EXTERNC static void convert(XmlBlasterException *in, XmlBlasterUnmanagedCEException *out) { 00187 if (*in->errorCode != 0) { 00188 out->errorCode = strcpyAlloc(in->errorCode); 00189 out->message = strcpyAlloc(in->message); 00190 out->remote = in->remote; 00191 } 00192 else { 00193 out->errorCode = 0; 00194 } 00195 } 00196 00197 XBFORCE_EXTERNC extern void xmlBlasterUnmanagedCEExceptionFree(XmlBlasterUnmanagedCEException *ex) { 00198 if (ex == 0) return; 00199 xmlBlasterFree(ex->errorCode); 00200 ex->errorCode = 0; 00201 xmlBlasterFree(ex->message); 00202 ex->message = 0; 00203 ex->remote = 0; 00204 } 00205 00206 00211 XBFORCE_EXTERNC static XMLBLASTER_C_bool interceptUpdate(MsgUnitArr *msgUnitArr, void *userData, XmlBlasterException *exception) { 00212 size_t i; 00213 XmlBlasterUnmanagedCEException unmanagedException; 00214 XMLBLASTER_C_bool retVal = true; 00215 int32_t isOneway = 0; 00216 /*MessageBox(NULL, L"Entering interceptUpdate0", _T("Unmanaged"), MB_OK);*/ 00217 00218 XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData; 00219 XmlBlasterUnmanagedCEUpdateFp unmanagedUpdate = (XmlBlasterUnmanagedCEUpdateFp)(xa->userFp); 00220 00221 if (xa->logLevel>=XMLBLASTER_LOG_TRACE) 00222 xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_TRACE, __FILE__, "Got update message"); 00223 00224 if (userData != 0) ; /* Supress compiler warning */ 00225 if (unmanagedUpdate == 0) return false; 00226 00227 /*memset(&unmanagedException, 0, sizeof(struct XmlBlasterUnmanagedCEException));*/ 00228 unmanagedException.remote = false; 00229 unmanagedException.errorCode = (char)0; 00230 unmanagedException.message = (char)0; 00231 00232 isOneway = msgUnitArr->isOneway; 00233 for (i=0; i<msgUnitArr->len; i++) { 00234 const char *cbSessionId = strcpyAlloc(msgUnitArr->secretSessionId); 00235 /* 00236 char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]); 00237 printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n", 00238 xml); 00239 xmlBlasterFree(xml); 00240 00241 printf("XmlBlasterUnmanaged.c: before update() %d\n", (int)msgUnitArr->len); 00242 */ 00243 00244 if (xa->logLevel>=XMLBLASTER_LOG_TRACE) xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_TRACE, __FILE__, "Got update, calling C# ..."); 00245 00246 /* Call C# ..., it may allocate errorCode */ 00247 unmanagedUpdate(cbSessionId, &msgUnitArr->msgUnitArr[i], isOneway, &unmanagedException); 00248 00249 if (xa->logLevel>=XMLBLASTER_LOG_TRACE) xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_TRACE, __FILE__, "Got update, calling C# DONE"); 00250 00251 if (unmanagedException.errorCode != 0) { 00252 /* catch first exception set and return */ 00253 strncpy0(exception->errorCode, unmanagedException.errorCode, EXCEPTIONSTRUCT_ERRORCODE_LEN); 00254 if (unmanagedException.message != 0) 00255 strncpy0(exception->message, unmanagedException.message, EXCEPTIONSTRUCT_MESSAGE_LEN); 00256 exception->remote = unmanagedException.remote; 00257 xmlBlasterUnmanagedCEExceptionFree(&unmanagedException); 00258 msgUnitArr->msgUnitArr[i].responseQos = 0; 00259 xa->log(xa->logUserP, xa->logLevel, XMLBLASTER_LOG_WARN, __FILE__, "Rethrowing exception from C# '%s' '%s'", exception->errorCode, exception->message); 00260 retVal = false; 00261 } 00262 else { 00263 msgUnitArr->msgUnitArr[i].responseQos = strcpyAlloc("<qos><state id='OK'/></qos>"); 00264 /* Return QoS: Everything is OK */ 00265 } 00266 } 00267 00268 return retVal; 00269 } 00270 00271 /* 00272 * We take a clone of argv, and not free your argv (crashes for some reason if we free it here) 00273 * @paran argc 00274 * @param argv [0] contains the exe name, [1] the first argument, etc. 00275 * "Hello.exe" "-dispatch/connection/plugin/socket/hostname" "192.168.1.2" 00276 * @return the XmlBlasterAccessUnparsed handle 00277 */ 00278 XBFORCE_EXTERNC Dll_Export XmlBlasterAccessUnparsed *getXmlBlasterAccessUnparsedUnmanagedCE(int argc, char** argv){ 00279 int i=0; 00280 XmlBlasterAccessUnparsed *xa; 00281 const char ** ptr = (const char **)malloc(argc*sizeof(char *)); 00282 for (i=0; i<argc; ++i) { 00283 ptr[i] = strcpyAlloc(argv[i]); 00284 /*printf("dll: getAccess '%s'\n", argv[i]);*/ 00285 /*if (freeIt) { xmlBlasterFree(argv[i]); argv[i] = 0; }*/ 00286 } 00287 /*if (freeIt) { xmlBlasterFree((char *)argv); }*/ 00288 xa = getXmlBlasterAccessUnparsed(argc, ptr); 00289 /*xa->userObject = ...; // Transports something to the interceptUpdate() method*/ 00290 return xa; 00291 } 00292 00293 XBFORCE_EXTERNC Dll_Export void freeXmlBlasterAccessUnparsedUnmanagedCE(XmlBlasterAccessUnparsed *xmlBlasterAccess) { 00294 if (xmlBlasterAccess != 0) { 00295 int i; 00296 for (i=0; i<xmlBlasterAccess->argc; ++i) 00297 free((void*)xmlBlasterAccess->argv[i]); 00298 free((void*)xmlBlasterAccess->argv); 00299 freeXmlBlasterAccessUnparsed(xmlBlasterAccess); 00300 } 00301 } 00302 00303 XBFORCE_EXTERNC Dll_Export bool xmlBlasterUnmanagedCEInitialize(struct XmlBlasterAccessUnparsed *xa, 00304 XmlBlasterUnmanagedCEUpdateFp update, XmlBlasterUnmanagedCEException *exception) { 00305 XmlBlasterException e; 00306 bool ret = false; 00307 xa->userFp = (XmlBlasterAccessGenericFp)update; 00308 ret = xa->initialize(xa, interceptUpdate, &e); 00309 convert(&e, exception); 00310 return ret; 00311 } 00312 00316 XBFORCE_EXTERNC Dll_Export char *xmlBlasterUnmanagedCEConnect(struct XmlBlasterAccessUnparsed *xa, 00317 char *qos, XmlBlasterUnmanagedCEUpdateFp update, XmlBlasterUnmanagedCEException *exception) { 00318 XmlBlasterException e; 00319 char *ret = 0; 00320 /*MessageBox(NULL, L"Entering xmlBlasterUnmanagedCEConnect", _T("Unmanaged"), MB_OK);*/ 00321 if (update != 0) 00322 xa->userFp = (XmlBlasterAccessGenericFp)update; 00323 ret = xa->connect(xa, qos, interceptUpdate, &e); 00324 convert(&e, exception); 00325 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00326 return ret; 00327 } 00328 00332 XBFORCE_EXTERNC Dll_Export extern bool xmlBlasterUnmanagedCEDisconnect(struct XmlBlasterAccessUnparsed *xa, 00333 char * qos, XmlBlasterUnmanagedCEException *exception) { 00334 XmlBlasterException e; 00335 bool ret = xa->disconnect(xa, qos, &e); 00336 convert(&e, exception); 00337 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00338 return ret; 00339 } 00340 00341 XBFORCE_EXTERNC Dll_Export extern char *xmlBlasterUnmanagedCEPublish(struct XmlBlasterAccessUnparsed *xa, 00342 MsgUnitUnmanagedCEpublish *msgUnitUnmanaged, XmlBlasterUnmanagedCEException *exception) { 00343 XmlBlasterException e; 00344 char *ret = xa->publish(xa, msgUnitUnmanaged, &e); 00345 convert(&e, exception); 00346 if (freeIt) freeMsgUnitData(msgUnitUnmanaged); 00347 return ret; 00348 } 00349 00350 XBFORCE_EXTERNC Dll_Export extern QosArr *xmlBlasterUnmanagedCEPublishArr(struct XmlBlasterAccessUnparsed *xa, MsgUnitArr *msgUnitArr, XmlBlasterUnmanagedCEException *exception) { 00351 XmlBlasterException e; 00352 QosArr *ret = xa->publishArr(xa, msgUnitArr, &e); 00353 convert(&e, exception); 00354 return ret; 00355 } 00356 00357 XBFORCE_EXTERNC Dll_Export extern void xmlBlasterUnmanagedCEPublishOneway(struct XmlBlasterAccessUnparsed *xa, void *msgUnitArr, int length, XmlBlasterUnmanagedCEException *exception) { 00358 XmlBlasterException e; 00359 MsgUnitArr arr; 00360 /*printf("C: xmlBlasterUnmanagedCEPublishOneway %d\n", length);*/ 00361 arr.isOneway = true; 00362 arr.len = length; 00363 arr.msgUnitArr = (MsgUnit*)msgUnitArr; 00364 *arr.secretSessionId = 0; 00365 xa->publishOneway(xa, &arr, &e); 00366 convert(&e, exception); 00367 if (freeIt) { 00368 size_t i; 00369 for (i=0; i<arr.len; i++) { 00370 freeMsgUnitData(&arr.msgUnitArr[i]); 00371 } 00372 /*free(msgUnitArr.msgUnitArr); is memory from C# IntPtr*/ 00373 } 00374 } 00375 00379 XBFORCE_EXTERNC Dll_Export extern char *xmlBlasterUnmanagedCESubscribe(struct XmlBlasterAccessUnparsed *xa, char *key, char *qos, XmlBlasterUnmanagedCEException *exception) { 00380 XmlBlasterException e; 00381 char *ret = xa->subscribe(xa, key, qos, &e); 00382 convert(&e, exception); 00383 if (freeIt) { xmlBlasterFree(key); key=0; } 00384 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00385 return ret; 00386 } 00387 00388 XBFORCE_EXTERNC Dll_Export void xmlBlasterUnmanagedCEUnSubscribe(struct XmlBlasterAccessUnparsed *xa, 00389 char * key, char * qos, XmlBlasterUnmanagedCEException *exception, uint32_t* pSize, XmlBlasterUnmanagedCEStringArr** ppStruct) { 00390 XmlBlasterException e; 00391 QosArr *ret = 0; 00392 initializeXmlBlasterException(&e); 00393 ret = xa->unSubscribe(xa, key, qos, &e); 00394 convert(&e, exception); 00395 if (freeIt) { xmlBlasterFree(key); key=0; } 00396 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00397 if (*e.errorCode != 0) { 00398 /*printf("C: Caught exception in unSubscribe errorCode=%s, message=%s\n", e.errorCode, e.message);*/ 00399 if (ret) freeQosArr(ret); 00400 return; 00401 } 00402 if (ret) { 00403 size_t i; 00404 XmlBlasterUnmanagedCEStringArr* pCurStruct = 0; 00405 const uint32_t cArraySize = ret->len; 00406 *pSize = cArraySize; 00407 *ppStruct = (XmlBlasterUnmanagedCEStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedCEStringArr )); 00408 pCurStruct = *ppStruct; 00409 for (i=0; i<ret->len; i++, pCurStruct++) { 00410 /*printf("C: Unsubscribe success, returned status is '%s'\n", ret->qosArr[i]);*/ 00411 pCurStruct->str = strcpyAlloc(ret->qosArr[i]); 00412 } 00413 freeQosArr(ret); 00414 } 00415 } 00416 00417 XBFORCE_EXTERNC Dll_Export void xmlBlasterUnmanagedCEErase(struct XmlBlasterAccessUnparsed *xa, char * key, 00418 char * qos, XmlBlasterUnmanagedCEException *exception, uint32_t* pSize, XmlBlasterUnmanagedCEStringArr** ppStruct) { 00419 XmlBlasterException e; 00420 QosArr *ret = 0; 00421 initializeXmlBlasterException(&e); 00422 ret = xa->erase(xa, key, qos, &e); 00423 convert(&e, exception); 00424 if (freeIt) { xmlBlasterFree(key); key=0; } 00425 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00426 if (*e.errorCode != 0) { 00427 if (ret) freeQosArr(ret); 00428 return; 00429 } 00430 if (ret) { 00431 size_t i; 00432 XmlBlasterUnmanagedCEStringArr* pCurStruct = 0; 00433 const uint32_t cArraySize = ret->len; 00434 *pSize = cArraySize; 00435 if (cArraySize == 0) { 00436 *ppStruct = 0; 00437 } 00438 else { 00439 *ppStruct = (XmlBlasterUnmanagedCEStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedCEStringArr )); 00440 pCurStruct = *ppStruct; 00441 for (i=0; i<ret->len; i++, pCurStruct++) { 00442 /*printf("dll: erase success, returned status is '%s'\n", ret->qosArr[i]);*/ 00443 pCurStruct->str = strcpyAlloc(ret->qosArr[i]); 00444 } 00445 } 00446 freeQosArr(ret); 00447 } 00448 } 00449 00450 XBFORCE_EXTERNC Dll_Export void xmlBlasterUnmanagedCEGet(struct XmlBlasterAccessUnparsed *xa, 00451 char * key, char *qos, XmlBlasterUnmanagedCEException *exception, 00452 uint32_t* pSize, MsgUnitUnmanagedCEget** ppStruct) { 00453 XmlBlasterException e; 00454 uint32_t i; 00455 MsgUnitArr *msgUnitArr = xa->get(xa, key, qos, &e); 00456 convert(&e, exception); 00457 if (freeIt) { xmlBlasterFree(key); key=0; } 00458 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00459 if (*e.errorCode != 0) { 00460 return; 00461 } 00462 /*printf("dll: xmlBlasterUnmanagedCEGet building response\n");*/ 00463 if (msgUnitArr != (MsgUnitArr *)0) { 00464 const uint32_t cArraySize = msgUnitArr->len; 00465 MsgUnitUnmanagedCEget* msgUnitUnmanagedP = 0; 00466 if (cArraySize == 0) { 00467 *ppStruct = 0; 00468 freeMsgUnitArr(msgUnitArr); 00469 return; 00470 } 00471 00472 *pSize = cArraySize; 00473 *ppStruct = (MsgUnitUnmanagedCEget*)malloc( cArraySize * sizeof( MsgUnitUnmanagedCEget )); 00474 msgUnitUnmanagedP = *ppStruct; 00475 /*printf("dll: xmlBlasterUnmanagedCEGet %ud\n", cArraySize);*/ 00476 /* TODO: It should be possible to pass msgUnitArr->msgUnitArr* directly 00477 as it has the same memory layout as the IntPtr 00478 */ 00479 /* NOTE: 00480 The sizeof(MsgUnitUnmanagedCEget) returns 20 bytes 00481 The same bytes are reported on the C# side (otherwise this approach fails) 00482 */ 00483 for(i=0; i < cArraySize; i++, msgUnitUnmanagedP++) { 00484 MsgUnit *msgUnit = &msgUnitArr->msgUnitArr[i]; 00485 char *cnt = (char *)malloc(msgUnit->contentLen*sizeof(char)); 00486 /*printf("dll: xmlBlasterUnmanagedCEGet processing #%u\n", i);*/ 00487 msgUnitUnmanagedP->contentLen = (int32_t)msgUnit->contentLen; 00488 if (cnt != 0) { 00489 size_t j; 00490 for (j=0; j<msgUnit->contentLen; j++) cnt[j] = (char)msgUnit->content[j]; 00491 } 00492 msgUnitUnmanagedP->content = cnt; 00493 msgUnitUnmanagedP->key = strcpyAlloc(msgUnit->key); 00494 msgUnitUnmanagedP->qos = strcpyAlloc(msgUnit->qos); 00495 msgUnitUnmanagedP->responseQos = strcpyAlloc("<qos/>"); 00496 /*printf("dll: xmlBlasterUnmanagedCEGet processing #%u key=%s qos=%s\n", i, msgUnitUnmanagedP->key, msgUnitUnmanagedP->qos);*/ 00497 } 00498 freeMsgUnitArr(msgUnitArr); 00499 } 00500 /*printf("DONE in get\n");*/ 00501 } 00502 00503 XBFORCE_EXTERNC Dll_Export char *xmlBlasterUnmanagedCEPing(struct XmlBlasterAccessUnparsed *xa, char *qos, XmlBlasterUnmanagedCEException *exception) { 00504 XmlBlasterException e; 00505 char *ret = xa->ping(xa, qos, &e); 00506 convert(&e, exception); 00507 if (freeIt) { xmlBlasterFree(qos); qos=0; } 00508 return ret; 00509 } 00510 00511 XBFORCE_EXTERNC Dll_Export bool xmlBlasterUnmanagedCEIsConnected(struct XmlBlasterAccessUnparsed *xa) { 00512 return xa->isConnected(xa); 00513 } 00514 00515 XBFORCE_EXTERNC Dll_Export const char *xmlBlasterUnmanagedCEUsage() { 00516 char *usage = (char *)malloc(XMLBLASTER_MAX_USAGE_LEN*sizeof(char)); 00517 return xmlBlasterAccessUnparsedUsage(usage); 00518 } 00519 00520 XBFORCE_EXTERNC Dll_Export const char *xmlBlasterUnmanagedCEVersion() { 00521 char *version = strcpyAlloc(getXmlBlasterVersion()); 00522 return version; 00523 } 00524 00525 #ifdef WINCE_EMEI 00526 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/apisp/html/sp_extapi_linegetgeneralinfo.asp */ 00527 /* Tutorial: http://www.developer.com/ws/pc/print.php/10947_3503761_1 */ 00528 #include <commctrl.h> 00529 #include "tapi.h" 00530 #include "extapi.h" 00531 00532 #define TAPI_API_HIGH_VERSION 0x00020000 00533 #define EXT_API_LOW_VERSION 0x00010000 00534 #define EXT_API_HIGH_VERSION 0x00010000 00535 /* 00536 OS Versions: Windows CE 3.0 and later 00537 Header: extapi.h 00538 Library: cellcore.lib 00539 */ 00540 00541 #define DEVICE_ID_LENGTH 20 00542 #define APPLICATION_DATA "@^!MyAppName!^@" #define APPLICATION_DATA_LENGTH 15 static void GetTAPIErrorMsg(TCHAR *szMsg,int nSize, DWORD dwError) { LPTSTR lpBuffer = 0; DWORD dwRet = 0; dwRet = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,TAPIERROR_FORMATMESSAGE(dwError),MAKELANGID(LANG_NEUTRAL, LANG_NEUTRAL), (LPTSTR) &lpBuffer,0,NULL); memset(szMsg,0,nSize); if (lpBuffer && dwRet) { _tcscpy(szMsg,lpBuffer); LocalFree(lpBuffer); } else { _stprintf(szMsg,L"Unknown Error: 0x%X",dwError); 00543 } 00544 } 00545 #endif /* WINCE_EMEI */ 00546 00553 const char *getXmlBlasterEmei() { 00554 #ifdef WINCE_EMEI 00555 /*TCHAR imei[80]; // 40 should be OK */ 00556 LPBYTE pLineGeneralInfoBytes = NULL; 00557 LINEGENERALINFO lineGeneralInfo; 00558 HLINEAPP hLineApp = 0; 00559 HLINE hLine = 0; 00560 DWORD dwNumDevs; 00561 DWORD dwAPIVersion = TAPI_API_HIGH_VERSION; 00562 DWORD dwExtVersion = 0; 00563 DWORD dwDeviceID; 00564 DWORD dwMediaMode = LINEMEDIAMODE_DATAMODEM; /* | LINEMEDIAMODE_INTERACTIVEVOICE; */ 00565 LONG tapiresult; /* functions return 0 (SUCCESS) */ 00566 LINEINITIALIZEEXPARAMS lineInitializeExParams; 00567 00568 lineGeneralInfo.dwTotalSize = sizeof(lineGeneralInfo); 00569 00570 lineInitializeExParams.dwTotalSize = sizeof(lineInitializeExParams); 00571 lineInitializeExParams.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT; /*The application desires to use the Event Handle event notification mechanism*/ 00572 tapiresult = lineInitializeEx(&hLineApp, 0, 0, L"MyApp", &dwNumDevs, &dwAPIVersion, &lineInitializeExParams); 00573 if (tapiresult) { 00574 MessageBox(NULL, L"lineInitializeEx failed", _T("Unmanaged"), MB_OK); 00575 return 0; 00576 } 00577 00578 /*MessageBox(NULL, L"lineInitializeEx OK", _T("Unmanaged"), MB_OK);*/ 00579 for (dwDeviceID = 0; dwDeviceID < dwNumDevs; dwDeviceID++) { 00580 tapiresult = lineOpen(hLineApp, dwDeviceID, &hLine, dwAPIVersion, 0, 0, 00581 LINECALLPRIVILEGE_OWNER, dwMediaMode, 0); /*returns 0 (SUCCESS)*/ 00582 if (tapiresult) { 00583 MessageBox(NULL, L"lineOpen failed", _T("Unmanaged"), MB_OK); 00584 continue; 00585 } 00586 00587 tapiresult = lineNegotiateExtVersion(hLineApp, dwDeviceID, dwAPIVersion, 00588 EXT_API_LOW_VERSION, EXT_API_HIGH_VERSION, &dwExtVersion); /*returns 0 (SUCCESS)*/ 00589 if (tapiresult) { 00590 MessageBox(NULL, L"lineNegotiateExtVersion failed", _T("Unmanaged"), MB_OK); 00591 continue; 00592 } 00593 00594 tapiresult = lineGetGeneralInfo(hLine, &lineGeneralInfo); /*FAILs and gives error: -2147483595 (Invalid pointer)*/ 00595 if (tapiresult != 0 && tapiresult != LINEERR_STRUCTURETOOSMALL) { 00596 TCHAR szMsg[255]; 00597 GetTAPIErrorMsg(szMsg,sizeof(szMsg), tapiresult); 00598 MessageBox(NULL, szMsg, _T("Unmanaged"), MB_OK); 00599 continue; 00600 } 00601 00602 /*MessageBox(NULL, L"success!!!", _T("Unmanaged"), MB_OK);*/ 00603 00604 pLineGeneralInfoBytes = new BYTE[lineGeneralInfo.dwNeededSize]; 00605 LPLINEGENERALINFO plviGeneralInfo; 00606 plviGeneralInfo = (LPLINEGENERALINFO)pLineGeneralInfoBytes; 00607 00608 if(pLineGeneralInfoBytes != NULL) { 00609 plviGeneralInfo->dwTotalSize = lineGeneralInfo.dwNeededSize; 00610 if ((tapiresult = lineGetGeneralInfo(hLine, plviGeneralInfo)) != 0) { 00611 TCHAR szMsg[255]; 00612 GetTAPIErrorMsg(szMsg,sizeof(szMsg), tapiresult); 00613 MessageBox(NULL, szMsg, _T("Unmanaged"), MB_OK); 00614 } 00615 else { 00616 LPTSTR tsManufacturer, tsModel, tsRevision, tsSerialNumber, tsSubscriberNumber; 00617 TCHAR szUnavailable[] = L"Unavailable"; 00618 if(plviGeneralInfo->dwManufacturerSize) { 00619 tsManufacturer = (WCHAR*)(((BYTE*)plviGeneralInfo)+plviGeneralInfo->dwManufacturerOffset); 00620 } 00621 else { 00622 tsManufacturer = szUnavailable; 00623 } 00624 00625 if(plviGeneralInfo->dwModelSize) { 00626 tsModel = (WCHAR*)(((BYTE*)plviGeneralInfo)+plviGeneralInfo->dwModelOffset); 00627 } 00628 else { 00629 tsModel = szUnavailable; 00630 } 00631 00632 if(plviGeneralInfo->dwRevisionSize) { 00633 tsRevision = (WCHAR*)(((BYTE*)plviGeneralInfo)+plviGeneralInfo->dwRevisionOffset); 00634 } 00635 else { 00636 tsRevision = szUnavailable; 00637 } 00638 00639 if(plviGeneralInfo->dwSerialNumberSize) { 00640 tsSerialNumber = (WCHAR*)(((BYTE*)plviGeneralInfo)+plviGeneralInfo->dwSerialNumberOffset); 00641 } 00642 else { 00643 tsSerialNumber = szUnavailable; 00644 } 00645 00646 if(plviGeneralInfo->dwSubscriberNumberSize) 00647 { 00648 tsSubscriberNumber = (WCHAR*)(((BYTE*)plviGeneralInfo)+plviGeneralInfo->dwSubscriberNumberOffset); 00649 } 00650 else 00651 { 00652 tsSubscriberNumber = szUnavailable; 00653 } 00654 00655 /* AFXSTR.H*/ 00656 /*typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;*/ 00657 /* 00658 CString sInfo; 00659 sInfo.Format(L"Manufacturer: %s\nModel: %s\nRevision: %s\nSerial No: %s\nSubscriber No: %s\n", 00660 tsManufacturer, 00661 tsModel, 00662 tsRevision, 00663 tsSerialNumber, 00664 tsSubscriberNumber); 00665 */ 00666 char *imeiId = (char *)malloc(128); 00667 strcpy(imeiId, ( ( (char*)plviGeneralInfo) + lineGeneralInfo.dwSerialNumberOffset)); 00668 00669 /*MessageBox(NULL, (LPCWSTR)( ( (char*)plviGeneralInfo) + lineGeneralInfo.dwSerialNumberOffset), _T("Unmanaged"), MB_OK);*/ 00670 00671 delete plviGeneralInfo; 00672 return imeiId; 00673 } 00674 delete plviGeneralInfo; 00675 } 00676 } /* for */ 00677 return 0; 00678 #else 00679 return strcpyAlloc("NotImplemented"); 00680 #endif 00681 } 00682