static KVMemoryStream g_MemoryAllocator = { NULL, myMalloc, myFree, myRealloc, myCalloc }; /******************************************************************************* * * function: AutoDetectFile() * * summary: Print out the format informaton for a file. * ******************************************************************************/ KVErrorCode AutoDetectFile(void *pContext, char *szFile) { ADDOCINFO DocInfo; KVErrorCode eErr = KVERR_Success; BOOL bVal; string filename(szFile); bVal = FilterFunc.fpGetDocInfoFile(pContext, szFile, &DocInfo); if (!bVal || (DocInfo.eClass == AutoDetFail) || (DocInfo.eClass == AutoDetNoFormat)) { if (DocInfo.eClass == AutoDetFail) { eErr = KVERR_AutoDetFail; } else { eErr = KVERR_AutoDetNoFormat; } goto slammer; } const size_t last_slash_idx = filename.find_last_of("\\/"); if (std::string::npos != last_slash_idx) { filename.erase(0, last_slash_idx + 1); } char metaVal[512] = { 0 }; sprintf(metaVal, "C:\\Program Files\\Tocsg\\eCrmHome\\conf\\ECRMHOMEDB\\tmp\\%s.meta", filename.c_str()); FILE *logfile = NULL; char ctemp[MAX_PATH]; fopen_s(&logfile, metaVal, "a+"); if (NULL != logfile) { char buff[2 * 1024] = { 0 }; sprintf(buff, "%d_tocLine_%d_tocLine_\n", DocInfo.eClass, DocInfo.eFormat); fwrite(buff, sizeof(char), strlen(buff), logfile); fclose(logfile); } /* printf("The file %s \n", szFile); printf("Class ID: %d\n", DocInfo.eClass); printf("Format ID: %d\n", DocInfo.eFormat); printf("Major Version: %ld\n", DocInfo.lVersion); printf("Attributes: %u\n", DocInfo.ulAttributes); printf("\n"); */ slammer: return(eErr); } KVErrorCode AutoDetectStream(void *pContext, char *szFile) { ADDOCINFO DocInfo; KVErrorCode eErr = KVERR_Success; KVInputStream inputStream = { 0 }; MyOpenInfo o = { 0 }; BOOL bVal = TRUE; o.pszName = szFile; inputStream.pInputStreamPrivateData = (void*)&o; inputStream.fpOpen = myOpen; inputStream.fpRead = myRead; inputStream.fpSeek = mySeek; inputStream.fpTell = myTell; inputStream.fpClose = myClose; bVal = FilterFunc.fpGetDocInfoStream(pContext, &inputStream, &DocInfo); if (!bVal || (DocInfo.eClass == AutoDetFail) || (DocInfo.eClass == AutoDetNoFormat)) { if (DocInfo.eClass == AutoDetFail) { eErr = KVERR_AutoDetFail; } else { eErr = KVERR_AutoDetNoFormat; } goto slammer; } /* printf("The stream %s \n", szFile); printf("Class ID: %d\n", DocInfo.eClass); printf("Format ID: %d\n", DocInfo.eFormat); printf("Major Version: %ld\n", DocInfo.lVersion); printf("Attributes: %u\n", DocInfo.ulAttributes); printf("\n"); */ slammer: return(eErr); } /******************************************************************************* * * function: DoSummaryInfo() * * ******************************************************************************/ static void pascal DoSummaryInfo(void *pKVFilter, KVFltInterfaceEx *pInterface, char *pszFileIn, char *pszFileOut) { KVSummaryInfoEx si; FILE *fo = NULL; fo = fopen(pszFileOut, "wb"); if (!fo) { fprintf(fo, "Error opening target file for summary information\n"); return; /* error */ } memset(&si, 0, sizeof(si)); if (KVERR_Success != (*pInterface->fpGetOLESummaryInfoFile)(pKVFilter, pszFileIn, &si)) { fprintf(fo, "Error obtaining summary information\n"); goto slammer; } if (si.nElem == 0) { fprintf(fo, "No summary information\n"); } else { PrintSummaryInfo(&si, fo); } (*pInterface->fpFreeOLESummaryInfo)(pKVFilter, &si); slammer: if (fo) fclose(fo); } /******************************************************************************* * * function: DoSummaryInfoStream() * * ******************************************************************************/ static void pascal DoSummaryInfoStream(void *pKVFilter, KVFltInterfaceEx *pInterface, KVInputStream *pInput, FILE *fpOut) { KVSummaryInfoEx si; memset(&si, 0, sizeof(si)); if (KVERR_Success != (*pInterface->fpGetOLESummaryInfo)(pKVFilter, pInput, &si)) { fprintf(fpOut, "Error obtaining summary information\n"); return; } if (si.nElem == 0) { fprintf(fpOut, "No summary information\n"); goto theend; } PrintSummaryInfo(&si, fpOut); theend: (*pInterface->fpFreeOLESummaryInfo)(pKVFilter, &si); } /******************************************************************************* * * function: PrintXmpnfo() * * ******************************************************************************/ void printXmpInfo(KVXmpInfo xi, FILE *fo, DWORD dwXmpOptions) { int i = 0, j = 0; if (dwXmpOptions & 2) { // print raw xmp only // print UPacket Data if exists // but what is a good way to print UTF16 and UTF32 string into a file? if (xi.usXpacketData.cbSize > 0 && xi.usXpacketData.pcString != 0) { for (i = 0; i < xi.usXpacketData.cbSize; i++) { fputc((int)xi.usXpacketData.pcString[i], fo); } } fputc('\n', fo); } else { fprintf(fo, "*** Keyview XMP Information ***\n"); // print encoding fprintf(fo, "\nEncoding = %d\n", xi.encoding); // print byteOrder fprintf(fo, "\nByte Order = %d\n\n", xi.bIsLittleEndian); // print UPacket Data if exists // but what is a good way to print UTF16 and UTF32 string into a file? if (xi.usXpacketData.cbSize > 0 && xi.usXpacketData.pcString != 0) { for (i = 0; i < xi.usXpacketData.cbSize; i++) { fputc((int)xi.usXpacketData.pcString[i], fo); } } fprintf(fo, "\n\n"); // print nNoOfElements fprintf(fo, "No of XMP elements = %d\n\n", xi.nNoOfElements); // print XmpInfoElements if (xi.nNoOfElements > 0 && xi.pXmpInfoElems) { for (i = 0; i < (int)xi.nNoOfElements; i++) { fprintf(fo, "KVXmpInfoElem number %d:\n", i); // printf xpath fprintf(fo, "xpath = \""); if (xi.pXmpInfoElems[i].usXPathToElement.cbSize) { for (j = 0; j < xi.pXmpInfoElems[i].usXPathToElement.cbSize; j++) fputc(xi.pXmpInfoElems[i].usXPathToElement.pcString[j], fo); } fprintf(fo, "\"\n"); // printf value fprintf(fo, "value = \""); if (xi.pXmpInfoElems[i].usValue.cbSize > 0 && xi.pXmpInfoElems[i].usValue.pcString) { for (j = 0; j < xi.pXmpInfoElems[i].usValue.cbSize; j++) fputc(xi.pXmpInfoElems[i].usValue.pcString[j], fo); } fprintf(fo, "\"\n\n"); } } } } //#define enumFileMode 0x1 //#define enumStreamMode 0x2 // ****************************************************************************** // Function: DoXmpInfoStream() // Description: // Process the stream or file mode request by using the getXmpInfo API // in kvfilter.dll // // ****************************************************************************** static void pascal DoXmpInfo(void * pKVFilter, KVFltInterfaceEx * pInterface, char * pszFileIn, char * pszFileOut, KVInputStream * pInput, FILE * fpOut, DWORD dwXmpOptions, UINT uiMode // to determine if we are using file mode or stream mode ) { int ret = KVERR_General; KVXmpInfo xi; if (uiMode == enumFileMode) { fpOut = fopen(pszFileOut, "wb"); if (!fpOut) { fprintf(fpOut, "Error opening target file for Xmp information\n"); goto CATCH; } } memset(&xi, 0, sizeof(xi)); if (uiMode == enumFileMode) { if (*pInterface->fpGetXmpInfoFile != NULL) { ret = (*pInterface->fpGetXmpInfoFile)(pKVFilter, pszFileIn, &xi, dwXmpOptions); } } else if (uiMode == enumStreamMode) { if (*pInterface->fpGetXmpInfoFile != NULL) { ret = (*pInterface->fpGetXmpInfo)(pKVFilter, pInput, &xi, dwXmpOptions); } } else { goto CATCH; } if (KVERR_Success != ret) { fprintf(fpOut, "Error obtaining Xmp information\n"); goto CATCH; } if (xi.nNoOfElements == 0 && xi.usXpacketData.cbSize == 0) { // fprintf( fpOut, "No Xmp information\n" ); // output empty file } else { printXmpInfo(xi, fpOut, dwXmpOptions); } CATCH: (*pInterface->fpFreeXmpInfo)(pKVFilter, &xi); if (uiMode == enumFileMode) { if (fpOut) fclose(fpOut); } } // ****************************************************************************** // Function: DoXmpInfoFile() // Description: // A proxy to forward the file mode request to the function DoXmpInfo() // // ****************************************************************************** static void pascal DoXmpInfoFile(void * pKVFilter, KVFltInterfaceEx * pInterface, char * pszFileIn, char * pszFileOut, DWORD dwXmpOptions) { DoXmpInfo(pKVFilter, pInterface, pszFileIn, pszFileOut, NULL, NULL, dwXmpOptions, enumFileMode); } // ****************************************************************************** // Function: DoXmpInfoStream() // Description: // A proxy to forward the stream mode request to the function DoXmpInfo() // // ****************************************************************************** static void pascal DoXmpInfoStream(void * pKVFilter, KVFltInterfaceEx * pInterface, KVInputStream * pInput, FILE * fpOut, DWORD dwXmpOptions) { DoXmpInfo(pKVFilter, pInterface, NULL, NULL, pInput, fpOut, dwXmpOptions, enumStreamMode); } /******************************************************************************* * * function: PrintSummaryInfo() * * ******************************************************************************/ void pascal PrintSummaryInfo(KVSummaryInfoEx *pSI, FILE *fpOut) { int n; for (n = 0; n < pSI->nElem; ++n) { fprintf(fpOut, "%d %d ", pSI->pElem[n].isValid, pSI->pElem[n].type); switch (pSI->pElem[n].type) { case KV_String: { fprintf(fpOut, "\"%s\"", pSI->pElem[n].data); } break; case KV_Int4: { fprintf(fpOut, "%d", pSI->pElem[n].data); } break; case KV_DateTime: { LONGLONG rtnValue = 0; memcpy(&rtnValue, pSI->pElem[n].data, 8); if (n == 9) { #if defined (KV_BIG_ENDIAN) /* if it is big endian, swap bytes */ LONGLONG NN = 0; unsigned char *a, *b, *c; a = (unsigned char *)&rtnValue; b = a + sizeof(LONGLONG)-1; c = (unsigned char *)&NN; while (a <= b) { *c = *b; b--; c++; } rtnValue = NN; #endif fprintf(fpOut, "%ld Minutes", (long)(rtnValue / 600000000)); } else { time_t timer; char * timeStr = NULL; char * linefeed = NULL; char buffer[40] = { 0 }; FileTimeToUnixTime(rtnValue, &timer); #if defined (_WINDOWS) timeStr = ctime(&timer); if (timeStr) { strncpy(buffer, timeStr, 40); } #elif defined (KV_CTIME_R_40) timeStr = ctime_r(&timer, buffer, 40); #else timeStr = ctime_r(&timer, buffer); #endif if (buffer[0] != 0) { linefeed = strchr(buffer, '\012'); if (linefeed != NULL) { *linefeed = '\0'; } fprintf(fpOut, "%s", timeStr); } } } break; case KV_ClipBoard: { fprintf(fpOut, "Clipboard data"); } break; case KV_Bool: { fprintf(fpOut, "%s", pSI->pElem[n].data ? "true" : "false"); } break; case KV_Unicode: { int len = 0; BYTE *p = (BYTE *)pSI->pElem[n].data; if (p) { for (; *p != 0 || *(p + 1) != 0; p += 2, len += 2); } fprintf(fpOut, "\""); if (p) { fwrite(pSI->pElem[n].data, 1, len + 2, fpOut); } fprintf(fpOut, "\""); } break; case KV_IEEE8: { fprintf(fpOut, "%lf", *((double *)pSI->pElem[n].data)); } break; case KV_Other: { fprintf(fpOut, "other"); } break; default: { if (pSI->pElem[n].isValid) { fprintf(fpOut, "Bad element type!"); } } break; } fprintf(fpOut, " %s\n", pSI->pElem[n].isValid ? pSI->pElem[n].pcType : "(null)"); } } /******************************************************************************* * * function: FilterFile() * * summary: Takes an input file specification and filters the output to an output file * using the KeyView filtering API. * ******************************************************************************/ static int pascal FilterFile(void *pFilter, char *pszFileIn, char *pszFileOut, FilterLsv *lsv) { ADDOCINFO DocInfo; BOOL bAutoRec = FALSE; KVErrorCode kvstatus = KVERR_Success; KVErrorCode nRet = KVERR_Success; /**************************************************************************/ /* Call the KeyView auto-recognition on this file. */ bAutoRec = FilterFunc.fpGetDocInfoFile(pFilter, pszFileIn, &DocInfo); if (!bAutoRec || (DocInfo.eClass == AutoDetFail) || (DocInfo.eClass == AutoDetNoFormat)) { fprintf(stderr, "Error: fpGetDocInfoFile returned %d in %s\n", DocInfo.eClass, pszFileIn); if (DocInfo.eClass == AutoDetFail) nRet = KVERR_AutoDetFail; else nRet = KVERR_AutoDetNoFormat; return (nRet); } /* Check if KeyView can filter this file. */ kvstatus = (*FilterFunc.fpCanFilterFile)(pFilter, pszFileIn); nRet = kvstatus; if (KVERR_Success == kvstatus) { if (lsv->gbSummary) { DoSummaryInfo(pFilter, &FilterFunc, pszFileIn, pszFileOut); } else if (lsv->gbXmp) { DoXmpInfoFile(pFilter, &FilterFunc, pszFileIn, pszFileOut, lsv->gbXmp); } else { kvstatus = (*FilterFunc.fpFilterFile)(pFilter, pszFileIn, pszFileOut, NULL); nRet = kvstatus; if (kvstatus != KVERR_Success) { fprintf(stderr, "Filter error, value returned is %d\n", kvstatus); } } } else { lsv->pszSrcFile = pszFileIn; lsv->pszTrgFile = pszFileOut; } return (nRet); } /******************************************************************************* * * function: FilterStream() * * summary: Takes an input file specification and filters the output to an output file * using the KeyView filtering API. * Uses stream-based filtering instead of file-based. * ******************************************************************************/ static int pascal FilterStream(void *pFilter, char *pszFileIn, char *pszFileOut, FilterLsv *lsv) { adDocDesc DocDesc = { 0 }; KVErrorCode nRet = KVERR_Success; KVInputStream IO = { 0 }; MyOpenInfo o = { 0 }; FILE *fo = NULL; void *pStream = NULL; KVFilterOutput filterOut = { 0 }; BOOL bStreamOpen = FALSE; /**************************************************************************/ lsv->pszSrcFile = pszFileIn; lsv->pszTrgFile = pszFileOut; fo = fopen(pszFileOut, "wb"); if (!fo) { printf("Error opening target file for filtering\n"); nRet = KVERR_CreateOutputFileFailed; return(nRet); } /* Initialize the input stream */ o.pszName = pszFileIn; IO.pInputStreamPrivateData = (void *)&o; IO.fpOpen = myOpen; IO.fpRead = myRead; IO.fpSeek = mySeek; IO.fpTell = myTell; IO.fpClose = myClose; /* Open this stream for filtering. */ /* if you need to change the BITWISE flags on the fly then call the Ex2 function * This is just a test as the flags are set in the fpInit */ if (lsv->AddInputFileName) { if (lsv->fpKV_FilterConfig) lsv->fpKV_FilterConfig(pFilter, 0, 0, pszFileIn); } pStream = (*FilterFunc.fpOpenStream)(pFilter, &IO); if (!pStream) { fprintf(stderr, "Error opening input stream on -> %s\n", pszFileIn); nRet = KVERR_badInputStream; goto slammer; } bStreamOpen = TRUE; /* Check if KeyView can filter this stream. */ nRet = (*FilterFunc.fpCanFilterStream)(pFilter, pStream); if (nRet != KVERR_Success) { if (bStreamOpen) { if (!(*FilterFunc.fpCloseStream)(pFilter, pStream)) { fprintf(stderr, "Error: Unable to filter %s (fpCanFilterStream returns %d)\n", pszFileIn, nRet); fprintf(stderr, "Error in KVCloseStream(): %s\n", pszFileIn); nRet = KVERR_General; } } if (fo) { fclose(fo); } if (nRet == KVERR_General) { /* stop, get out! */ _unlink(pszFileOut); return(nRet); } if (nRet != KVERR_Success) { _unlink(pszFileOut); } return(nRet); } if (lsv->gbSummary) { /* * Do summary extraction. */ DoSummaryInfoStream(pFilter, &FilterFunc, &IO, fo); } else if (lsv->gbXmp) { /* * Do XMP Info extraction. */ DoXmpInfoStream(pFilter, &FilterFunc, &IO, fo, lsv->gbXmp); } else { while (1) { nRet = (*FilterFunc.fpFilterStream)(pFilter, pStream, &filterOut, NULL); if (nRet != KVERR_Success) { fprintf(stderr, "Error filtering stream: %s\n", pszFileIn); goto slammer; } /* ** Check if we're done filtering... */ if (filterOut.cbText == 0) { break; } /* ** Write this buffer out to stdout... */ fwrite(filterOut.pcText, 1, filterOut.cbText, fo); /* The caller is responsible for free'ing the memory allocated * by the KVFilterStream() function. The KeyView filtering API used * our g_MemoryAllocator to allocate the memory... */ (*g_MemoryAllocator.fpFree)(&g_MemoryAllocator, filterOut.pcText); } } slammer: /* ** Load KVCloseStream */ if (pStream) { if (!(*FilterFunc.fpCloseStream)(pFilter, pStream)) { fprintf(stderr, "Error closing stream: %s\n", pszFileIn); nRet = KVERR_General; } } if (fo) { fclose(fo); } return (nRet); } /******************************************************************************* * * Installable file system layer: the next 5 functions provide basic file * manipulation. * ******************************************************************************/ BOOL pascal myOpen(struct tag_InputStream *p) { MyOpenInfo *po = (MyOpenInfo *)p->pInputStreamPrivateData; po->fp = fopen(po->pszName, "rb"); return (po->fp != NULL); } UINT pascal myRead(struct tag_InputStream *p, BYTE *pc, UINT cb) { MyOpenInfo *po = (MyOpenInfo *)p->pInputStreamPrivateData; return (fread(pc, 1, cb, po->fp)); } BOOL pascal mySeek(struct tag_InputStream *p, long l, int w) { MyOpenInfo *po = (MyOpenInfo *)p->pInputStreamPrivateData; if (!po->fp) return(1); return(!fseek(po->fp, l, w)); } long pascal myTell(struct tag_InputStream *p) { MyOpenInfo *po = (MyOpenInfo *)p->pInputStreamPrivateData; if (!po->fp) return(-1); return (ftell(po->fp)); } BOOL pascal myClose(struct tag_InputStream *p) { MyOpenInfo *po = (MyOpenInfo *)p->pInputStreamPrivateData; if (po->fp) { fclose(po->fp); po->fp = NULL; } return (TRUE); } /******************************************************************************* * * Memory abstraction: the variable g_MemoryAllocator is passed into all KeyView * filtering API entry points requiring it. * ******************************************************************************/ void * pascal myMalloc(struct tag_MemoryStream *pX, size_t cb) { return (malloc(cb)); } void pascal myFree(struct tag_MemoryStream *pX, void *ptr) { free(ptr); } void * pascal myRealloc(struct tag_MemoryStream *pX, void *ptr, size_t cb) { return (realloc(ptr, cb)); } void * pascal myCalloc(struct tag_MemoryStream *pX, size_t ne, size_t s) { return (calloc(ne, s)); } /* szDir is the directory where the filter dlls are */ int filterText(char *szDir, char *szSrc, char *szTarget, FilterLsv *lsv) { void *pFilter = NULL; char szDllName[1024]; //void *pKVFILTER; HINSTANCE pKVFILTER; KVErrorCode nRet = KVERR_Success; KVErrorCode(pascal *fpGetFilterInterfaceEx)(KVFltInterfaceEx*, int); strcpy(szDllName, szDir); strcat(szDllName, "kvfilter"); pKVFILTER = myLoadLibrary(szDllName); if (!pKVFILTER) { WriteLog("filterlocation err"); fprintf(stderr, "Can't load kvfilter!\n"); fprintf(stderr, "This executable must be in the same directory as the Filter binaries.\n"); nRet = KVERR_DLLNotFound; goto jail; } fpGetFilterInterfaceEx = (KVErrorCode(pascal *)(KVFltInterfaceEx *, int)) myGetProcAddress(pKVFILTER, (char*)"KV_GetFilterInterfaceEx"); if (fpGetFilterInterfaceEx == NULL) { WriteLog("Can't get interface function!"); fprintf(stderr, "Can't get interface function!\n"); nRet = KVERR_General; goto jail; } nRet = (*fpGetFilterInterfaceEx)(&FilterFunc, KVFLTINTERFACE_REVISION); if (KVERR_Success != nRet) { WriteLog("interface"); fprintf(stderr, "Can't get Filter interface functions!\n"); goto jail; } /* * if the BITWISE flags don't need to be see on the fly, set the gdwFlags here. * pFilter = (*FilterFunc.fpInit)( &g_MemoryAllocator, NULL , szDir, KVCS_UTF8, gdwFLAGS ); */ lsv->fpKV_GetKvErrorCodeEx = (KVErrorCodeEx(pascal *)(void *))myGetProcAddress(pKVFILTER, (char*)"KV_GetKvErrorCodeEx"); lsv->fpKV_FilterConfig = (BOOL(pascal *)(void *, int, int, void *))myGetProcAddress(pKVFILTER, (char*)"KV_FilterConfig"); pFilter = (*FilterFunc.fpInit)(&g_MemoryAllocator, NULL, szDir, KVCS_UTF8, lsv->dwFlags); if (pFilter == NULL) { WriteLog("Error Init"); fprintf(stderr, "Error initializing filter!\n"); nRet = KVERR_General; goto jail; } if (lsv->fpKV_FilterConfig) { if (lsv->bInclRMark) { lsv->fpKV_FilterConfig(pFilter, KVFLT_INCLREVISIONMARK, TRUE, NULL); } if (lsv->bNoComments) { lsv->fpKV_FilterConfig(pFilter, KVFLT_NOCOMMENTS, TRUE, NULL); } if (lsv->bShowHiddenText) { lsv->fpKV_FilterConfig(pFilter, KVFLT_SHOWHIDDENTEXT, TRUE, NULL); } if (lsv->szXMLConfigFile[0]) { KVXConfigInfo xinfo; BOOL bDone = FALSE; int n = 0; /* get config info for Verity-recognized formats */ while (!bDone) { memset(&xinfo, 0, sizeof(KVXConfigInfo)); if (GetKVXConfigInfo(lsv, &xinfo, n)) { lsv->fpKV_FilterConfig(pFilter, KVFLT_SETXMLCONFIGINFO, 0, &xinfo); FreeKVXConfigInfo(&xinfo); n++; } else { bDone = TRUE; } } /* get customized config info for other formats */ bDone = FALSE; n = 100; while (!bDone) { memset(&xinfo, 0, sizeof(KVXConfigInfo)); if (GetKVXConfigInfo(lsv, &xinfo, n)) { lsv->fpKV_FilterConfig(pFilter, KVFLT_SETXMLCONFIGINFO, 0, &xinfo); FreeKVXConfigInfo(&xinfo); n++; } else { bDone = TRUE; } } } if (lsv->szTempDir[0]) { lsv->fpKV_FilterConfig(pFilter, KVFLT_SETTEMPDIRECTORY, 0, lsv->szTempDir); } if (lsv->szSrcPassword[0]) { lsv->fpKV_FilterConfig(pFilter, KVFLT_SETSRCPASSWORD, strlen(lsv->szSrcPassword), lsv->szSrcPassword); } if (lsv->lpdfDirection >= LPDF_RAW) { lsv->fpKV_FilterConfig(pFilter, KVFLT_LOGICALPDF, lsv->lpdfDirection, NULL); } } #if 0 if (_access(szSrc, 0)) { fprintf(stderr, "Cannot locate input file.\n"); nRet = KVERR_badInputStream; goto jail; } #endif //TODO JKim AutoDetectFile(pFilter, szSrc); if (lsv->gbKWAD) { if (lsv->gbStreamBased) { nRet = AutoDetectStream(pFilter, szSrc); } else { nRet = AutoDetectFile(pFilter, szSrc); } } else if (lsv->gbStreamBased) { FilterStream(pFilter, szSrc, szTarget, lsv); } else { FilterFile(pFilter, szSrc, szTarget, lsv); } nRet = KVERR_Success; jail: if (nRet == KVERR_General) { int kvErrorEx; if (lsv->fpKV_GetKvErrorCodeEx) { kvErrorEx = (*lsv->fpKV_GetKvErrorCodeEx)(pFilter); if (kvErrorEx != KVError_Last) printf("KvErrorCodeEx = %d \n ", kvErrorEx); else printf("No more KvErrorCodeEx \n"); } } if (pFilter) (*FilterFunc.fpShutdown)(pFilter); FreeLibrary((HINSTANCE)pKVFILTER); return (nRet); } /****************************************************************** * * Porting Load library function to different platforms * *******************************************************************/ HINSTANCE myLoadLibrary(char *filename) { char szFileNameWithExtension[_MAX_PATH]; strcpy(szFileNameWithExtension, filename); #if defined(_WINDOWS) strcat(szFileNameWithExtension, ".dll"); return LoadLibraryA(szFileNameWithExtension); #elif defined(_HPUX11) strcat(szFileNameWithExtension, ".sl"); return shl_load(szFileNameWithExtension, BIND_DEFERRED, 0L); #elif defined (HPUX_R64) strcat(szFileNameWithExtension, ".sl"); return dlopen(szFileNameWithExtension, RTLD_LAZY); #elif defined (_RS6K43) || defined (AIX_P64) strcat(szFileNameWithExtension, ".a"); return dlopen(szFileNameWithExtension, RTLD_LAZY); #else strcat(szFileNameWithExtension, ".so"); return dlopen(szFileNameWithExtension, RTLD_LAZY); #endif } /****************************************************************** * * Porting Free library function to different platforms * ******************************************************************* void myFreeLibrary(void * hKVFILTER) { #if defined(_WINDOWS) FreeLibrary((HINSTANCE)hKVFILTER); #elif defined(_HPUX11) shl_unload((shl_t)hKVFILTER); #else dlclose(hKVFILTER); #endif } */ void PrintFilterErrMsg(char *szTitle, KVErrorCode error) { char szError[40]; *szError = '\0'; switch (error) { case KVERR_Success: //wsprintfA(szError, "KVERR_Success"); return; case KVERR_DLLNotFound: wsprintfA(szError, "KVERR_DLLNotFound"); break; case KVERR_processCancelled: wsprintfA(szError, "KVERR_processCancelled"); break; case KVERR_OutOfCore: wsprintfA(szError, "KVERR_OutOfCore"); break; case KVERR_badInputStream: wsprintfA(szError, "KVERR_badInputStream"); break; case KVERR_badOutputType: wsprintfA(szError, "KVERR_badOutputType"); break; case KVERR_General: wsprintfA(szError, "KVERR_General"); return; case KVERR_FormatNotSupported: wsprintfA(szError, "KVERR_FormatNotSupported"); break; case KVERR_PasswordProtected: wsprintfA(szError, "KVERR_PasswordProtected"); break; case KVERR_ADSNotFound: wsprintfA(szError, "KVERR_ADSNotFound"); break; case KVERR_AutoDetFail: wsprintfA(szError, "KVERR_AutoDetFail"); break; case KVERR_AutoDetNoFormat: wsprintfA(szError, "KVERR_AutoDetNoFormat"); break; case KVERR_ReaderInitError: wsprintfA(szError, "KVERR_ReaderInitError"); break; case KVERR_NoReader: wsprintfA(szError, "KVERR_NoReader"); break; case KVERR_CreateOutputFileFailed: wsprintfA(szError, "KVERR_CreateOutputFileFailed"); break; case KVERR_CreateTempFileFailed: wsprintfA(szError, "KVERR_CreateTempFileFailed"); break; case KVERR_ErrorWritingToOutputFile: wsprintfA(szError, "KVERR_ErrorWritingToOutputFile"); break; case KVERR_CreateProcessFailed: wsprintfA(szError, "KVERR_CreateProcessFailed"); break; case KVERR_WaitForChildFailed: wsprintfA(szError, "KVERR_WaitForChildFailed"); break; case KVERR_ChildTimeOut: wsprintfA(szError, "KVERR_ChildTimeOut"); break; case KVERR_ArchiveFileNotFound: wsprintfA(szError, "KVERR_ArchiveFileNotFound"); break; case KVERR_ArchiveFatalError: wsprintfA(szError, "KVERR_ArchiveFatalError"); break; default: wsprintfA(szError, "%d", error); } WriteLog("%s: error code returned is %s\n", szTitle, szError); } /****************************************************************** * * Porting GetProcAddress for different platforms * * * *****************************************************************/ void * myGetProcAddress(HINSTANCE hInst, char *funcName) { #if defined(_WINDOWS) return GetProcAddress(hInst, funcName); #elif defined (_HPUX11) int result = 0; void *fp = NULL; shl_findsym((shl_t*)&hInst, funcName, TYPE_UNDEFINED, &fp); if (result) fp = NULL; return fp; #else return dlsym(hInst, funcName); #endif } /******************************************************************************* * * function: filterArchive() * * summary: Takes an input file specification and extract archive file to a * directory. * ******************************************************************************/ int filterArchive(void *pFilter, char *pszFileIn, char *pszFileOut) { void *pArchiveContext = NULL; int nFilesInArch; int nIndex; char acExtractFile[250]; char acPathFile[250]; int rcMkdir; void *vpKVUtilLib = NULL; int error = 0; KVErrorCode nRet = KVERR_Success; /* Open Archive File */ if ((pArchiveContext = (void *)(*FilterFunc.fpOpenArchiveFile) (pFilter, pszFileIn)) == NULL) { fprintf(stderr, "Error: can't openning archive file %s.\n", pszFileIn); nRet = KVERR_badInputStream; /* Shut Down Archive */ /* Don't need to shut down again, because it is already shut down when * fpOpenArchiveFile fails */ /*if( !(*FilterFunc.fpCloseArchiveFile)( pArchiveContext ) ) { fprintf(stderr, "Error: shutting down archive file %s.\n", pszFileIn ); nRet = KVERR_General; }*/ return (nRet); } /* Get Number of Files In Archive */ if ((nFilesInArch = (*FilterFunc.fpGetNumFilesInArchiveFile) (pArchiveContext)) < 0) { fprintf(stderr, "Error: getting number of files in archive failed.\n"); nRet = KVERR_ArchiveFatalError; /* Shut Down Archive */ if (!(*FilterFunc.fpCloseArchiveFile)(pArchiveContext)) { fprintf(stderr, "Error: shutting down archive file.\n"); nRet = KVERR_General; } return (nRet); } /* create directory if not exist */ if (_access(pszFileOut, 0) == -1) { #ifdef _WINDOWS rcMkdir = _mkdir(pszFileOut); #else rcMkdir = _mkdir(pszFileOut, 511); #endif if (rcMkdir) { fprintf(stderr, "Error: creating output directories %s\n", pszFileOut); nRet = KVERR_CreateOutputFileFailed; /* Shut Down Archive */ if (!(*FilterFunc.fpCloseArchiveFile)(pArchiveContext)) { fprintf(stderr, "Error: shutting down archive file\n"); nRet = KVERR_General; } return (nRet); } } for (nIndex = 0; nIndex < nFilesInArch; nIndex++) { TPArchiveFileInfo archiveInfo; /* Get Archive File Info */ if ((nRet = (*FilterFunc.fpGetArchiveFileInfo) (pArchiveContext, nIndex, &archiveInfo)) != KVERR_Success) { continue; } if (archiveInfo.bIsDir || archiveInfo.bNeedPwd) { nRet = KVERR_PasswordProtected; continue; } /* assume no problem in creating directory... */ sprintf(acExtractFile, "%s/%s", pszFileOut, archiveInfo.szFilename); /* create directory */ { char *pBeginDir, *pEndDir, *pDir; int length; length = strlen(pszFileOut); pBeginDir = acExtractFile + length + 1; pEndDir = strrchr(acExtractFile, '/') + 1; pDir = pBeginDir; for (; pDir != pEndDir; pDir++) { switch ((char)*pDir) { case '/': { memcpy(acPathFile, acExtractFile, pDir - acExtractFile); acPathFile[pDir - acExtractFile] = '\0'; #ifdef _WINDOWS rcMkdir = _mkdir(acPathFile); #else rcMkdir = _mkdir(acPathFile, 511); #endif break; } default: break; } } } /* Extract Files In Archive */ nRet = (*FilterFunc.fpExtractArchiveFile)(pArchiveContext, nIndex, acExtractFile); if (nRet != KVERR_Success) { fprintf(stderr, "Error: extracting files in archive...\n"); } } /* Shut Down Archive */ if (!(*FilterFunc.fpCloseArchiveFile)(pArchiveContext)) { fprintf(stderr, "Error: shutting down archive file\n"); nRet = KVERR_General; return (nRet); } /* return ok */ return(nRet); } /* ---------------------------------------------------------------------- * This function checks to see if the INI file exists by making a call * to GetPrivateProfileString(). If the file is found, no further * action is required. If the entry returns a blank, the path of the * INI file is adjusted to match the current working directory and * another attempt is made to read the first entry in the file. If this * also fails, a warning message is output, indicating the INI file was * not found but that the input file will be converted using the internal * defaults. * ---------------------------------------------------------------------*/ void LocateINIFile(char *szExecutable, char *szINIFile) { char szINIPath[_MAX_PATH]; char szINIFileName[_MAX_PATH]; char *pszINI = NULL; char *pszPath = NULL; char szReturnedString[GPPSTRINGMAXSIZE]; /* Attempt to find the first entry in the ini file */ GetPrivateProfileStringA("config0", "eKVFormat", "Not found", szReturnedString, GPPSTRINGMAXSIZE, szINIFile); if (strcmp(szReturnedString, "Not found") == 0) { /* entry not found, try further */ char *pcTmp; for (pcTmp = szExecutable; *pcTmp != '\0'; pcTmp++) { *pcTmp = (char)tolower((int)((char)(*pcTmp))); } /* Determine the directory of the executable, if we can */ strcpy(szINIPath, szExecutable); pszPath = strstr(szExecutable, "filter"); szINIPath[pszPath - szExecutable] = '\0'; strcpy(szINIFileName, szINIFile); pszINI = strrchr(szINIFileName, '/'); if (pszINI == NULL) { pszINI = strrchr(szINIFileName, '\\'); } if (pszINI) { strcpy(szINIFileName, &pszINI[1]); if (szINIFileName != NULL) { pszINI = szINIFileName; } } strcat(szINIPath, szINIFileName); #ifdef _WINDOWS GetCurrentDirectoryA(_MAX_PATH, szINIPath); strcat(szINIPath, "\\"); #else strcpy(szINIPath, "./"); #endif strcat(szINIPath, szINIFileName); /* Attempt to find the first entry in the ini file */ GetPrivateProfileStringA("config0", "eKVFormat", "Not found", szReturnedString, GPPSTRINGMAXSIZE, szINIPath); if (strcmp(szReturnedString, "Not found") != 0) { strcpy(szINIFile, szINIPath); } else { #if !defined (__mac_os) printf("File <%s> not found or is not formatted as expected!\n", szINIPath); printf("Conversion will proceed with internal defaults.\n"); #endif } } } /*---------------------------------------------------------------------- * * SaveINIFileString * *---------------------------------------------------------------------*/ char* SaveINIFileString(char *szINIString) { char *psz = NULL; int nLength = strlen(szINIString); if (nLength == 0) { return NULL; } psz = (char *)malloc(nLength + 1); #ifdef _WINDOWS assert(psz != 0); #endif strcpy(psz, szINIString); return psz; } /*---------------------------------------------------------------------- * *---------------------------------------------------------------------*/ ENdocFmt FindFormatID(char *szInputString) { if (strcmp(szInputString, "MS_Word_XML_Fmt") == 0) return MS_Word_XML_Fmt; if (strcmp(szInputString, "MS_Excel_XML_Fmt") == 0) return MS_Excel_XML_Fmt; if (strcmp(szInputString, "MS_Visio_XML_Fmt") == 0) return MS_Visio_XML_Fmt; if (strcmp(szInputString, "SO_Text_XML_Fmt") == 0) return SO_Text_XML_Fmt; if (strcmp(szInputString, "SO_Spreadsheet_XML_Fmt") == 0) return SO_Spreadsheet_XML_Fmt; if (strcmp(szInputString, "SO_Presentation_XML_Fmt") == 0) return SO_Presentation_XML_Fmt; return Unknown_Fmt; } /*---------------------------------------------------------------------- * *---------------------------------------------------------------------*/ BOOL GetKVXConfigInfo(FilterLsv *lsv, KVXConfigInfo *pXInfo, int n) { BOOL bRet = TRUE; char szSection[16]; char szReturnedString[GPPSTRINGMAXSIZE]; sprintf(szSection, "config%d", n); GetPrivateProfileStringA(szSection, "eKVFormat", "Not found", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); if (strcmp(szReturnedString, "Not found") == 0) { bRet = FALSE; } else { pXInfo->eKVFormat = FindFormatID(szReturnedString); GetPrivateProfileStringA(szSection, "szRoot", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszRoot = SaveINIFileString(szReturnedString); GetPrivateProfileStringA(szSection, "szInMetaElement", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszInMeta = SaveINIFileString(szReturnedString); GetPrivateProfileStringA(szSection, "szExMetaElement", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszExMeta = SaveINIFileString(szReturnedString); GetPrivateProfileStringA(szSection, "szInContentElement", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszInContent = SaveINIFileString(szReturnedString); GetPrivateProfileStringA(szSection, "szExContentElement", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszExContent = SaveINIFileString(szReturnedString); GetPrivateProfileStringA(szSection, "szInAttribute", "", szReturnedString, GPPSTRINGMAXSIZE, lsv->szXMLConfigFile); pXInfo->pszInAttribute = SaveINIFileString(szReturnedString); } return bRet; } /*---------------------------------------------------------------------- * *---------------------------------------------------------------------*/ BOOL FreeKVXConfigInfo(KVXConfigInfo *pXInfo) { BOOL bRet = TRUE; if (!pXInfo) return bRet; if (pXInfo->pszRoot) free(pXInfo->pszRoot); if (pXInfo->pszInMeta) free(pXInfo->pszInMeta); if (pXInfo->pszExMeta) free(pXInfo->pszExMeta); if (pXInfo->pszInContent) free(pXInfo->pszInContent); if (pXInfo->pszExContent) free(pXInfo->pszExContent); if (pXInfo->pszInAttribute) free(pXInfo->pszInAttribute); return bRet; } /****************************************************************************** ******************************************************************************/ void FileTimeToUnixTime(LONGLONG pft, time_t* t) { LONGLONG ll = 0; #if defined (KV_BIG_ENDIAN) { int i; for (i = 0; i < 64; i += 8) { ll |= (LONGLONG)((BYTE)(pft >> i)) << (56 - i); } } #else ll = pft; #endif #if defined (_WINDOWS) if (ll >= 116444736000000000) { ll = ll - 116444736000000000; } #else if (ll >= 116444736000000000LL) { ll = ll - 116444736000000000LL; } #endif else { ll = 0; } #if defined (KV_SIZEOF_LONG_IS_64_BITS) *t = (unsigned int)(ll / 10000000L); #else *t = (unsigned long)(ll / 10000000L); #endif } int encodeutf8(unsigned long u, unsigned char *buf, size_t maxbytes) { static const struct { int nbytes; unsigned long max; } tab[] = { { 1, 0x0000007F }, { 2, 0x000007FF }, { 3, 0x0000FFFF }, { 4, 0x001FFFFF }, { 5, 0x03FFFFFF }, { 6, 0x7FFFFFFF }, }; static const int ntab = sizeof(tab) / sizeof(tab[0]); int i, j; if (u > tab[ntab - 1].max) return -1; for (i = 0; i < ntab; ++i) { if (u <= tab[i].max) break; } assert(i < ntab); if (tab[i].nbytes > maxbytes) return -1; if (tab[i].nbytes == 1) { /* Special case */ buf[0] = u; } else { for (j = tab[i].nbytes - 1; j > 0; --j) { buf[j] = 0x80 | (u & 0x3f); u >>= 6; } unsigned char mask = ~(0xFF >> tab[i].nbytes); buf[0] = mask | u; } return tab[i].nbytes; } int high_ones(int c) { int n; for (n = 0; (c & 0x80) == 0x80; c <<= 1) ++n; return n; } unsigned long decodeutf8(unsigned char *buf, int nbytes) { unsigned long u; int i, j; if (nbytes <= 0) return INVALID_CHAR; if (nbytes == 1) { if (buf[0] >= 0x80) return INVALID_CHAR; return buf[0]; } i = high_ones(buf[0]); if (i != nbytes) return INVALID_CHAR; u = buf[0] & (0xff >> i); for (j = 1; j < nbytes; ++j) { if ((buf[j] & 0xC0) != 0x80) return INVALID_CHAR; u = (u << 6) | (buf[j] & 0x3f); } /* Conforming UTF-8 cannot contain codes 0xd800쭯0xdfff (UTF-16 surrogates) as well as 0xfffe and 0xffff. */ if (u >= 0xD800 && u <= 0xDFFF) return INVALID_CHAR; if (u == 0xFFFE || u == 0xFFFF) return INVALID_CHAR; return u; } int is_utf8_byte_stream(FILE *file, int quiet) { enum { MAX_UTF8_BYTES = 6 }; unsigned char buf[MAX_UTF8_BYTES]; unsigned char buf2[MAX_UTF8_BYTES]; int nbytes, nbytes2; int c; unsigned long code; unsigned long line, col, byteoff; nbytes = 0; line = 1; col = 1; byteoff = 0; for (;;) { c = getc(file); if (c == EOF || c < 0x80 || (c & 0xC0) != 0x80) { /* New char starts, deal with previous one. */ if (nbytes > 0) { code = decodeutf8(buf, nbytes); if (code == INVALID_CHAR) goto error; nbytes2 = encodeutf8(code, buf2, MAX_UTF8_BYTES); if (nbytes != nbytes2 || memcmp(buf, buf2, nbytes) != 0) goto error; ++col; } nbytes = 0; /* If it's UTF8, start collecting again. */ if (c != EOF && c >= 0x80) buf[nbytes++] = c; } else { /* This is a continuation byte, append to buffer. */ if (nbytes == MAX_UTF8_BYTES) goto error; buf[nbytes++] = c; } if (c == EOF) break; else if (c == '\n') { ++line; byteoff = 0; col = 1; } else ++byteoff; } if (nbytes != 0) goto error; return 1; error: if (!quiet) { printf("line %lu, char %lu, byte offset %lu: " "invalid UTF-8 code\n", line, col, byteoff); } return 0; } int JudgeUtf8File(TCHAR * FileName) { int ok = 1; FILE *file = NULL; file = _tfopen(FileName, _T("r")); if (file == NULL) { // should never occur ok = -1; } else { if (!is_utf8_byte_stream(file)) ok = 0; fclose(file); } return ok; } int ConvertAnsi2Utf8(TCHAR *szSrcAnsi, TCHAR *szDesUtf8) { HANDLE hFile = CreateFile(szSrcAnsi, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hFile) { return -1; } DWORD dwFileSize = GetFileSize(hFile, NULL); if (INVALID_FILE_SIZE == dwFileSize) { CloseHandle(hFile); hFile = NULL; return -2; } char * szAnsiBuf = new char[dwFileSize + 1]; if (NULL == szAnsiBuf) { CloseHandle(hFile); hFile = NULL; return -3; } memset(szAnsiBuf, 0, dwFileSize + 1); DWORD dwBytesRead = 0; if (!ReadFile(hFile, szAnsiBuf, dwFileSize, &dwBytesRead, NULL)) { if (NULL != szAnsiBuf) { delete[] szAnsiBuf; szAnsiBuf = NULL; } CloseHandle(hFile); hFile = NULL; return -4; } CloseHandle(hFile); hFile = NULL; wchar_t *szUnicodeBuf = new wchar_t[dwFileSize + 1]; memset(szUnicodeBuf, 0, sizeof(wchar_t)*(dwFileSize + 1)); int nWCHAR = MultiByteToWideChar(CP_ACP, 0, szAnsiBuf, dwFileSize, szUnicodeBuf, dwFileSize); int nUTF8 = WideCharToMultiByte(CP_UTF8, 0, szUnicodeBuf, nWCHAR, NULL, 0, NULL, NULL); char *szUTF8Buf = new char[nUTF8 + 1]; memset(szUTF8Buf, 0, nUTF8 + 1); WideCharToMultiByte(CP_UTF8, 0, szUnicodeBuf, nWCHAR, szUTF8Buf, nUTF8, NULL, NULL); int iRet = 0; FILE * fo = _tfopen(szDesUtf8, _T("wb")); if (!fo) { iRet = -5; } else { if (nUTF8 != fwrite(szUTF8Buf, 1, nUTF8, fo)) { iRet = -6; } } if (fo) { fclose(fo); } delete[]szAnsiBuf; delete[]szUnicodeBuf; delete[]szUTF8Buf; return iRet; }