Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
p6api.cpp
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
# define DLLHANDLE HMODULE
# define LOADERLIB "p6loader.dll"
# define LOADLIB(fn) LoadLibraryA((fn))
# define LOADSYMBOL(h,s) GetProcAddress((HMODULE)(h),(s))
# define FREELIB(h) FreeLibrary((HMODULE)(h))
#else
# include <string.h> // memcpy()
# include <dlfcn.h> // dlopen() etc.
# include <unistd.h> // readlink()
# define DLLHANDLE void*
# define LOADERLIB "libp6loader.so"
# define LOADLIB(fn) dlopen((fn),RTLD_NOW)
# define LOADSYMBOL(h,s) dlsym((h),(s))
# define FREELIB(h) !dlclose((h))
#endif
#include <stdio.h>
#include <stdlib.h> // getexecname() on solaris
#include "p6err.h" // Error and type definitions
#include "p6comdef.h" // [p6]COM definitions
#include "p6errorinfo.h" // Definition only, not supported by p6Loader
#include "p6runtimeapi.h" // Platform runtime API definitions
#include "p6comhlpr.h" // [p6]COM helper macros
#undef P6ASSERT
#define P6ASSERT(x)
#include "p6comptr.h" // Smart COM pointer, ASSERTs disabled
#include "p6runtimeif.h" // P6Platform's runtime COM API interface definitions
#include "p6datastream.h" // p6IDataStream interface definition
#include "p6loader.h" // Standalone Component Loader definitions
using namespace P6R;
DLLHANDLE ghDll = NULL;
P6INITIALIZELOADER gp6InitializeLoader = NULL;
P6CLEANUPLOADER gp6CleanupLoader = NULL;
P6DLLAPI gAPI;
static P6ERR strlcpy(P6CHAR *dest,P6SIZE cDest,const P6CHAR *source,P6SIZE *pcCopied)
{
P6ERR err = eOk;
P6SIZE i = 0;
if(!dest || !cDest || !source) return eInvalidArg;
if(pcCopied) *pcCopied = 0;
for(i=0;0 != source[i] && i < cDest-1;i++) dest[i] = source[i];
dest[i] = '\0';
if(pcCopied) *pcCopied = i;
if(0 != source[i])
return eTooBig;
return err;
}
#if defined(__linux__)
static P6CHAR gszModuleDir[P6MAXPATH] = {0};
__attribute__((constructor)) void on_load(void)
{
Dl_info dl_info;
dladdr((void *)on_load,&dl_info);
strlcpy(&gszModuleDir[0],P6CNTOF(gszModuleDir),dl_info.dli_fname,NULL);
// fprintf(stderr, "module %s loaded\n", dl_info.dli_fname);
}
#endif
static P6ERR strlcat(char *dest,P6SIZE cDest,char const *source,P6SIZE *pcCopied)
{
P6ERR err = eOk;
P6SIZE len1 = 0;
P6SIZE len2 = 0;
P6SIZE i = 0;
P6SIZE j = 0;
if(!dest || !cDest || !source) return eInvalidArg;
if(pcCopied) *pcCopied = 0;
if(len2 > (cDest - len1 - 1)) {
return eTooBig;
}
for(i=len1;j<len2 && i<cDest-1;i++,j++)
dest[i] = source[j];
dest[i] = '\0';
if(pcCopied) *pcCopied = j;
return err;
}
static P6R::P6ERR readInstallConf(const P6CHAR *pszPath,P6CHAR *pBuffer,P6SIZE cBuffer)
{
P6ERR err = eNoMemory;
P6CHAR *pszConfFile = NULL;
P6CHAR *pszOrignalPath= NULL;
if(NULL != (pszConfFile = new(std::nothrow) P6CHAR[P6MAXPATH])) {
if(NULL != (pszOrignalPath = new(std::nothrow) P6CHAR[P6MAXPATH])) {
FILE *pFile = NULL;
err = eOk;
strlcpy(pszOrignalPath,P6MAXPATH,pszPath,NULL);
strlcpy(pszConfFile,P6MAXPATH,pszPath,NULL);
strlcat(pszConfFile,P6MAXPATH,"/install.conf",NULL);
if(NULL != (pFile = fopen(pszConfFile,"r"))) {
if(NULL == fgets(pBuffer,cBuffer,pFile)) {
strlcpy(pBuffer,cBuffer,pszOrignalPath,NULL);
}
else {
}
fclose(pFile);
}
else {
strlcpy(pBuffer,cBuffer,pszOrignalPath,NULL);
err = eOk;
}
delete [] pszOrignalPath;
}
delete [] pszConfFile;
}
return err;
}
static P6R::P6ERR getModuleDir(P6CHAR *pBuffer,P6SIZE cBuffer)
{
P6ERR err = eOk;
if(!pBuffer || !cBuffer)
return eInvalidArg;
pBuffer[0] = '\0';
#if defined(_WIN32)
HMODULE hm = NULL;
if (0 != GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | \
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCSTR) &getModuleDir,
&hm)) {
if(0 != GetModuleFileNameA(hm,pBuffer,cBuffer)) {
P6CHAR *pTmp = pBuffer;
P6CHAR *pszEnd = NULL;
while(*pTmp) {
if('\\' == *pTmp) *pTmp = '/';
pTmp++;
}
pszEnd = strrchr(pBuffer,'/');
if(NULL != pszEnd) *pszEnd = '\0';
err = readInstallConf(pBuffer,pBuffer,cBuffer);
}
}
else {
err = eFail;
}
#elif defined(__linux__)
P6CHAR *pszEnd = NULL;
if(gszModuleDir[0]) {
strlcpy(pBuffer,cBuffer,&gszModuleDir[0],NULL);
pszEnd = strrchr(pBuffer,'/');
if(NULL != pszEnd) *pszEnd = '\0';
err = readInstallConf(pBuffer,pBuffer,cBuffer);
}
else {
err = P6R::eFail;
}
#else
#pragma error("Unsupported Operating System. Code must be added to handle this OS")
#endif
return err;
}
static void setMem(P6R::P6VOID *pMemory,P6R::P6INT nValue,P6R::P6SIZE nBytes)
{
P6CHAR *pTmp = (P6CHAR*) pMemory;
if(!pMemory || !nBytes)
return;
while(nBytes) {
*pTmp = (P6CHAR) nValue & 0xff;
pTmp++;
nBytes--;
}
}
static P6R::P6ERR loadSymbols()
{
P6ERR err = eDllNotFound;
P6CHAR szLib[P6MAXPATH] = {0};
setMem(&gAPI,0,sizeof(gAPI));
if(P6SUCCEEDED(getModuleDir(&szLib[0],P6CHARCNT(szLib)))) {
strcat(&szLib[0],"/");
strcat(&szLib[0],LOADERLIB);
if(NULL != (ghDll = LOADLIB(&szLib[0]))) {
gp6InitializeLoader = (P6INITIALIZELOADER) LOADSYMBOL(ghDll,"p6InitializeLoader");
gp6CleanupLoader = (P6CLEANUPLOADER) LOADSYMBOL(ghDll,"p6CleanupLoader");
gAPI.p6CreateInstance = (P6CREATEINSTANCE) LOADSYMBOL(ghDll,"p6CreateInstance");
gAPI.p6CreateCryptoInstance = (P6CREATECRYPTOINSTANCE) LOADSYMBOL(ghDll,"p6CreateCryptoInstance");
gAPI.p6GetCryptoProviderVersion = (P6GETCRYPTOPROVIDERVERSION) LOADSYMBOL(ghDll,"p6GetCryptoProviderVersion");
gAPI.p6GetRuntimeIface = (P6GETRUNTIMEIFACE) LOADSYMBOL(ghDll,"p6GetRuntimeIface");
gAPI.p6GetThreadLogger = (P6GETTHREADLOGGER) LOADSYMBOL(ghDll,"p6GetThreadLogger");
// Note that these functions can be called prior to p6InitializeLoader() and/or if it fails
gAPI.p6GetRuntimeVersion = (P6GETRUNTIMEVERSION) LOADSYMBOL(ghDll,"p6GetRuntimeVersion");
gAPI.p6UUIDToString = (P6UUIDTOSTRING) LOADSYMBOL(ghDll,"p6UUIDToString");
gAPI.p6StringToUUID = (P6STRINGTOUUID) LOADSYMBOL(ghDll,"p6StringToUUID");
gAPI.p6UUIDToWString = (P6UUIDTOWSTRING) LOADSYMBOL(ghDll,"p6UUIDToWString");
gAPI.p6WStringToUUID = (P6WSTRINGTOUUID) LOADSYMBOL(ghDll,"p6WStringToUUID");
gAPI.p6GetDirectory = (P6GETDIRECTORY) LOADSYMBOL(ghDll,"p6GetDirectory");
gAPI.p6ErrToStr = (P6ERRTOSTR) LOADSYMBOL(ghDll,"p6ErrToStr");
gAPI.p6ErrToWStr = (P6ERRTOWSTR) LOADSYMBOL(ghDll,"p6ErrToWStr");
gAPI.p6AtomicInc32 = (P6ATOMICINC32) LOADSYMBOL(ghDll,"p6AtomicInc32");
gAPI.p6AtomicDec32 = (P6ATOMICDEC32) LOADSYMBOL(ghDll,"p6AtomicDec32");
gAPI.p6AtomicAdd32 = (P6ATOMICADD32) LOADSYMBOL(ghDll,"p6AtomicAdd32");
gAPI.p6AtomicSet32 = (P6ATOMICSET32) LOADSYMBOL(ghDll,"p6AtomicSet32");
gAPI.p6AtomicSet64 = (P6ATOMICSET64) LOADSYMBOL(ghDll,"p6AtomicSet64");
gAPI.p6AtomicSetPtr = (P6ATOMICSETPTR) LOADSYMBOL(ghDll,"p6AtomicSetPtr");
gAPI.p6HashData = (P6HASHDATA) LOADSYMBOL(ghDll,"p6HashData");
gAPI.p6HashString = (P6HASHSTRING) LOADSYMBOL(ghDll,"p6HashString");
gAPI.p6HashStringW = (P6HASHSTRINGW) LOADSYMBOL(ghDll,"p6HashStringW");
gAPI.p6HashBCSTR = (P6HASHBCSTR) LOADSYMBOL(ghDll,"p6HashBCSTR");
gAPI.p6HashBWCSTR = (P6HASHBWCSTR) LOADSYMBOL(ghDll,"p6HashBWCSTR");
gAPI.p6HashUINT32 = (P6HASHUINT32) LOADSYMBOL(ghDll,"p6HashUINT32");
gAPI.p6HashUINT64 = (P6HASHUINT64) LOADSYMBOL(ghDll,"p6HashUINT64");
gAPI.p6HashUINT64to32 = (P6HASHUINT64TO32) LOADSYMBOL(ghDll,"p6HashUINT64to32");
gAPI.p6TraceAddref = (P6TRACEADDREF) LOADSYMBOL(ghDll,"p6TraceAddref");
gAPI.p6TraceRelease = (P6TRACERELEASE) LOADSYMBOL(ghDll,"p6TraceRelease");
if(gp6InitializeLoader && \
gp6CleanupLoader && \
gAPI.p6CreateInstance && \
gAPI.p6CreateCryptoInstance && \
gAPI.p6GetCryptoProviderVersion && \
gAPI.p6GetRuntimeIface && \
gAPI.p6GetThreadLogger && \
gAPI.p6UUIDToString && \
gAPI.p6StringToUUID && \
gAPI.p6UUIDToWString && \
gAPI.p6WStringToUUID && \
gAPI.p6ErrToStr && \
gAPI.p6ErrToWStr && \
gAPI.p6AtomicInc32 && \
gAPI.p6AtomicDec32 && \
gAPI.p6AtomicAdd32 && \
gAPI.p6AtomicSet32 &&\
gAPI.p6AtomicSet64 &&\
gAPI.p6AtomicSetPtr &&\
gAPI.p6HashData &&\
gAPI.p6HashString &&\
gAPI.p6HashStringW &&\
gAPI.p6HashBCSTR &&\
gAPI.p6HashBWCSTR &&\
gAPI.p6HashUINT32 &&\
gAPI.p6HashUINT64 &&\
gAPI.p6HashUINT64to32 &&\
gAPI.p6TraceAddref && \
gAPI.p6TraceRelease) {
err = eOk;
}
else {
if(!gp6InitializeLoader) fprintf(stderr,"ERROR: Symbol Not Found [ p6InitializeLoader ]\n");
if(!gp6CleanupLoader) fprintf(stderr,"ERROR: Symbol Not Found [ p6CleanupLoader ]\n");
if(!gAPI.p6CreateInstance) fprintf(stderr,"ERROR: Symbol Not Found [ p6CreateInstance ]\n");
if(!gAPI.p6CreateCryptoInstance) fprintf(stderr,"ERROR: Symbol Not Found [ p6CreateCryptoInstance ]\n");
if(!gAPI.p6GetCryptoProviderVersion) fprintf(stderr,"ERROR: Symbol Not Found [ p6GetCryptoProviderVersion ]\n");
if(!gAPI.p6GetRuntimeVersion) fprintf(stderr,"ERROR: Symbol Not Found [ p6GetRuntimeVersion ]\n");
if(!gAPI.p6GetThreadLogger) fprintf(stderr,"ERROR: Symbol Not Found [ p6GetThreadLogger ]\n");
if(!gAPI.p6UUIDToString) fprintf(stderr,"ERROR: Symbol Not Found [ p6UUIDToString ]\n");
if(!gAPI.p6StringToUUID) fprintf(stderr,"ERROR: Symbol Not Found [ p6StringToUUID ]\n");
if(!gAPI.p6UUIDToWString) fprintf(stderr,"ERROR: Symbol Not Found [ p6UUIDToWString ]\n");
if(!gAPI.p6WStringToUUID) fprintf(stderr,"ERROR: Symbol Not Found [ p6WStringToUUID ]\n");
if(!gAPI.p6GetRuntimeIface) fprintf(stderr,"ERROR: Symbol Not Found [ p6GetRuntimeIface ]\n");
if(!gAPI.p6GetDirectory) fprintf(stderr,"ERROR: Symbol Not Found [ gp6GetDirectory ]\n");
if(!gAPI.p6ErrToStr) fprintf(stderr,"ERROR: Symbol Not Found [ p6ErrToStr ]\n");
if(!gAPI.p6ErrToWStr) fprintf(stderr,"ERROR: Symbol Not Found [ p6ErrToWStr ]\n");
if(!gAPI.p6AtomicInc32) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicInc32 ]\n");
if(!gAPI.p6AtomicDec32) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicDec32 ]\n");
if(!gAPI.p6AtomicAdd32) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicAdd32 ]\n");
if(!gAPI.p6AtomicSet32) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicSet32 ]\n");
if(!gAPI.p6AtomicSet64) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicSet64 ]\n");
if(!gAPI.p6AtomicSetPtr) fprintf(stderr,"ERROR: Symbol Not Found [ p6AtomicSetptr ]\n");
if(!gAPI.p6HashData) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashData ]\n");
if(!gAPI.p6HashString) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashString ]\n");
if(!gAPI.p6HashStringW) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashStringW ]\n");
if(!gAPI.p6HashBCSTR) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashBCSTR ]\n");
if(!gAPI.p6HashBWCSTR) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashBWCSTR ]\n");
if(!gAPI.p6HashUINT32) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashUINT32 ]\n");
if(!gAPI.p6HashUINT64) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashUINT64 ]\n");
if(!gAPI.p6HashUINT64to32) fprintf(stderr,"ERROR: Symbol Not Found [ p6HashUINT64to32 ]\n");
if(!gAPI.p6TraceAddref) fprintf(stderr,"ERROR: Symbol Not Found [ p6TraceAddref ]\n");
if(!gAPI.p6TraceRelease) fprintf(stderr,"ERROR: Symbol Not Found [ p6TraceRelease ]\n");
err = eNotFound;
}
}
else {
#if defined(_WIN32)
fprintf(stderr,"ERROR: Failed to dynamially load '%s' [ %x ]\nERROR: OS Error: %x\n",&szLib[0],err,::GetLastError());
#else
fprintf(stderr,"ERROR: Failed to dynamially load '%s' [ %x ]\nERROR: OS Error: %s\n",&szLib[0],err,dlerror());
#endif
}
}
return err;
}
static void unloadSymbols()
{
if(NULL != ghDll) {
(void) FREELIB(ghDll);
}
}
extern "C" P6R::P6ERR p6InitializeLoader(P6R::p6IDataStream *pLogSink,P6R::P6INT32 nVerbosity,P6SCLF fFlags)
{
P6ERR err;
if(P6SUCCEEDED(err = loadSymbols())) {
if(P6FAILED(err = gp6InitializeLoader(pLogSink,nVerbosity,fFlags))) {
P6CHAR szErr[256] = {0};
fprintf(stderr,"ERROR: p6InitializeLoader() Failed [ %s ]\n",gAPI.p6ErrToStr(err,&szErr[0],P6CHARCNT(szErr)));
}
}
return err;
}
{
P6ERR err = gp6CleanupLoader();
unloadSymbols();
return err;
}
extern "C" P6R::P6ERR p6GetRuntimeVersion(P6R::P6VERINFO *pVerInfo)
{
if(!gAPI.p6GetRuntimeVersion) return eNotInitialized;
return gAPI.p6GetRuntimeVersion(pVerInfo);
}
extern "C" P6R::P6ERR p6UUIDToString(const P6R::P6UUID &uuid,P6R::P6CHAR *pBuffer,P6R::P6SIZE cBuffer)
{
if(!pBuffer || !cBuffer)
return eInvalidArg;
return gAPI.p6UUIDToString(uuid,pBuffer,cBuffer);
}
extern "C" P6R::P6ERR p6StringToUUID(const P6R::P6CHAR *pszUUID,P6R::P6UUID &uuid)
{
if(!gAPI.p6StringToUUID) return eNotInitialized;
return gAPI.p6StringToUUID(pszUUID, uuid);
}
extern "C" P6R::P6ERR p6UUIDToWString(const P6R::P6UUID &uuid,P6R::P6WCHAR *pBuffer,P6R::P6SIZE cBuffer)
{
if(!pBuffer || !cBuffer)
return eInvalidArg;
return gAPI.p6UUIDToWString(uuid,pBuffer,cBuffer);
}
extern "C" P6R::P6ERR p6WStringToUUID(const P6R::P6WCHAR *pszUUID,P6R::P6UUID &uuid)
{
if(!gAPI.p6WStringToUUID) return eNotInitialized;
return gAPI.p6WStringToUUID(pszUUID,uuid);
}
extern "C" P6R::P6ERR p6GetRuntimeIface(const P6REFIID iid,P6R::P6VOID **ppIface)
{
if(!gAPI.p6GetRuntimeIface) return eNotInitialized;
return gAPI.p6GetRuntimeIface(iid, ppIface);
}
extern "C" P6R::P6ERR p6CreateInstance(P6R::p6ICom *pOuter,const P6REFCID cid,const P6REFIID iid,P6R::P6VOID **ppIface)
{
if(!gAPI.p6CreateInstance) return eNotInitialized;
return gAPI.p6CreateInstance(pOuter,cid,iid,ppIface);
}
extern "C" P6R::P6ERR p6CreateCryptoInstance(const P6REFCID cid,const P6REFIID iid,P6R::P6VOID** ppIface)
{
if(!gAPI.p6CreateCryptoInstance) return eNotInitialized;
return gAPI.p6CreateCryptoInstance(cid,iid,ppIface);
}
extern "C" P6R::P6ERR p6GetCryptoProviderVersion(P6R::P6CHAR *pBuffer,P6R::P6SIZE cBuffer,P6R::P6SIZE *pcWritten,P6R::P6BOOL bVerbose)
{
if(!gAPI.p6GetCryptoProviderVersion) return eNotInitialized;
return gAPI.p6GetCryptoProviderVersion(pBuffer,cBuffer,pcWritten,bVerbose);
}
extern "C" P6R::P6ERR p6GetDirectory(P6DIRS nDir,P6R::P6WCHAR* pBuffer,P6R::P6SIZE cBuffer,P6R::P6SIZE* pcWritten)
{
if(!gAPI.p6GetDirectory) return eNotInitialized;
return gAPI.p6GetDirectory(nDir,pBuffer,cBuffer,pcWritten);
}
extern "C" P6R::P6CHAR* p6ErrToStr(P6R::P6ERR err,P6R::P6CHAR *pszBuffer,P6R::P6SIZE cBuffer)
{
if(!gAPI.p6ErrToStr) return NULL;
return gAPI.p6ErrToStr(err,pszBuffer,cBuffer);
}
extern "C" P6R::P6WCHAR* p6ErrToWStr(P6R::P6ERR err,P6R::P6WCHAR *pszBuffer,P6R::P6SIZE cBuffer)
{
if(!gAPI.p6ErrToWStr) return NULL;
return gAPI.p6ErrToWStr(err,pszBuffer,cBuffer);
}
extern "C" P6R::P6INT32 p6AtomicInc32(P6R::P6INT32 volatile *pVar)
{
if(!gAPI.p6AtomicInc32) return 0;
return gAPI.p6AtomicInc32(pVar);
}
extern "C" P6R::P6INT32 p6AtomicDec32(P6R::P6INT32 volatile *pVar)
{
if(!gAPI.p6AtomicDec32) return 0;
return gAPI.p6AtomicDec32(pVar);
}
{
if(!gAPI.p6AtomicAdd32) return 0;
return gAPI.p6AtomicAdd32(pVar,value);
}
extern "C" P6R::P6INT32 p6AtomicSet32(P6R::P6INT32 volatile *pVar,P6R::P6INT32 value)
{
if(!gAPI.p6AtomicSet32) return 0;
return gAPI.p6AtomicSet32(pVar,value);
}
extern "C" P6R::P6INT64 p6AtomicSet64(P6R::P6INT64 volatile *pVar,P6R::P6INT64 value)
{
if(!gAPI.p6AtomicSet64) return 0;
return gAPI.p6AtomicSet64(pVar,value);
}
{
if(!gAPI.p6HashData) return 0;
return gAPI.p6HashData(pData,cData,hash);
}
extern "C" P6API P6R::P6UINT32 p6HashString(const P6R::P6CHAR *pszString)
{
if(!gAPI.p6HashString) return 0;
return gAPI.p6HashString(pszString);
}
extern "C" P6API P6R::P6UINT32 p6HashStringW(const P6R::P6WCHAR *pszString)
{
if(!gAPI.p6HashStringW) return 0;
return gAPI.p6HashStringW(pszString);
}
{
if(!gAPI.p6HashBCSTR) return 0;
return gAPI.p6HashBCSTR(pbcsString);
}
{
if(!gAPI.p6HashBWCSTR) return 0;
return gAPI.p6HashBWCSTR(pbwcsString);
}
{
if(!gAPI.p6HashUINT32) return 0;
return gAPI.p6HashUINT32(nInteger);
}
{
if(!gAPI.p6HashUINT64) return 0;
return gAPI.p6HashUINT64(nInteger);
}
{
if(!gAPI.p6HashUINT64to32) return 0;
return gAPI.p6HashUINT64to32(nInteger);
}
extern "C" P6R::P6ERR p6TraceAddref(const P6R::P6CHAR *pszClassname,P6R::P6UINT32 cClassSize,P6R::P6VOID *classAddr,P6R::P6INT32 refCount,P6R::P6UINT32 *pSerialNumber)
{
if(!gAPI.p6TraceAddref) return eNotInitialized;
return gAPI.p6TraceAddref(pszClassname,cClassSize,classAddr,refCount,pSerialNumber);
}
extern "C" P6R::P6ERR p6TraceRelease(const P6R::P6CHAR *pszClassname,P6R::P6VOID *classAddr,P6R::P6INT32 refCount,P6R::P6UINT32 *pSerialNumber)
{
if(!gAPI.p6TraceRelease) return eNotInitialized;
return gAPI.p6TraceRelease(pszClassname,classAddr,refCount,pSerialNumber);
}
extern "C" P6API P6R::P6ERR p6Assert(const P6R::P6WCHAR *pszExpr,const P6R::P6CHAR *pszFile,P6R::P6UINT32 nLine)
{
return eOk;
}
extern "C" P6API P6ERR p6Backtrace(P6R::P6CHAR *pBuffer,P6R::P6SIZE cBuffer,P6R::P6UINT32 cFramesToSkip,P6BTFLAGS fFlags)
{
return eNotImplemented;
}