BSOne.SFC/eCrmHE/example/keyview.c

1875 lines
42 KiB
C

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;
}