Index: init.c =================================================================== --- init.c (revision 4057) +++ init.c (working copy) @@ -111,6 +111,7 @@ #endif // don't need thread notifications strncpy(szDbPath, profile, sizeof(szDbPath)); + szDbPath[sizeof(szDbPath)-1]=0; // this is like Load()'s pluginLink pluginLink=link; // set the memory manager @@ -123,6 +124,18 @@ return 1; } + { + char *p; + strncpy(szDbDir,szDbPath,sizeof(szDbDir)); + p = strrchr(szDbDir, '\\'); + if ( p != NULL ) + *(p+1)=0; + uiDbDirLen = strlen(szDbDir); + + szDbDirUtf8 = Utf8Encode(szDbDir); + uiDbDirLenUtf8 = strlen(szDbDirUtf8); + } + // inject all APIs and hooks into the core return LoadDatabaseModule(); } @@ -130,6 +143,7 @@ static int UnloadDatabase(int wasLoaded) { if ( !wasLoaded) return 0; + mir_free(szDbDirUtf8); UnloadDatabaseModule(); return 0; } Index: database.c =================================================================== --- database.c (revision 4057) +++ database.c (working copy) @@ -46,6 +46,14 @@ CRITICAL_SECTION csDbAccess; struct DBHeader dbHeader; char szDbPath[MAX_PATH]; +char szDbDir[MAX_PATH]; +size_t uiDbDirLen; +char szMirandaDir[MAX_PATH]; +size_t uiMirandaDirLen; +char *szMirandaDirUtf8; +size_t uiMirandaDirLenUtf8; +char *szDbDirUtf8; +size_t uiDbDirLenUtf8; static void UnloadDatabase(void) { @@ -85,6 +93,7 @@ UninitCache(); UnloadDatabase(); DeleteCriticalSection(&csDbAccess); + mir_free(szMirandaDirUtf8); } static int GetProfileName(WPARAM wParam, LPARAM lParam) @@ -123,6 +132,19 @@ return 1; } } + + { + char *p; + GetModuleFileName(GetModuleHandle(NULL),szMirandaDir,sizeof(szMirandaDir)); + p = strrchr(szMirandaDir,'\\'); + if( p != NULL ) + *(p+1)=0; + uiMirandaDirLen = strlen(szMirandaDir); + + szMirandaDirUtf8 = Utf8Encode(szMirandaDir); + uiMirandaDirLenUtf8 = strlen(szMirandaDirUtf8); + } + //if(ParseCommandLine()) return 1; if(InitCache()) return 1; if(InitModuleNames()) return 1; @@ -170,6 +192,14 @@ } #ifdef DBLOGGING +__inline static int mir_vsnprintf(char *buffer, size_t count, const char* fmt, va_list va) { + int len; + + len = _vsnprintf(buffer, count-1, fmt, va); + buffer[count-1] = 0; + return len; +} + void DBLog(const char *file,int line,const char *fmt,...) { FILE *fp; Index: dbsettings.c =================================================================== --- dbsettings.c (revision 4057) +++ dbsettings.c (working copy) @@ -45,6 +45,10 @@ static struct SettingsGroupOfsCacheEntry settingsGroupOfsCache[SETTINGSGROUPOFSCOUNT]; static int nextSGOCacheEntry; +#define TYPE_IS_STRING(_type_) ( _type_ == DBVT_ASCIIZ || _type_ == DBVT_UTF8 \ + || _type_ == DBVT_ASCIIZ_PATH || _type_ == DBVT_UTF8_PATH \ + || _type_ == DBVT_ASCIIZ_DB_PATH || _type_ == DBVT_UTF8_DB_PATH ) + //this function caches results static DWORD GetSettingsGroupOfsByModuleNameOfs(struct DBContact *dbc,DWORD ofsContact,DWORD ofsModuleName) { @@ -84,7 +88,7 @@ break; } } } -static DWORD __inline GetSettingValueLength(PBYTE pSetting) +__inline static DWORD GetSettingValueLength(PBYTE pSetting) { if(pSetting[0]&DBVTF_VARIABLELENGTH) return 2+*(PWORD)(pSetting+1); return pSetting[0]; @@ -128,11 +132,12 @@ } switch( d->type ) { + case DBVT_DELETED: log0( "set cached type deleted" ); break; case DBVT_BYTE: log1( "set cached byte: %d", d->bVal ); break; case DBVT_WORD: log1( "set cached word: %d", d->wVal ); break; case DBVT_DWORD: log1( "set cached dword: %d", d->dVal ); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break; + case DBVT_UTF8: log1( "set cached string(UTF8): '%s'", d->pszVal ); break; + case DBVT_ASCIIZ: log1( "set cached string(ASCII): '%s'", d->pszVal ); break; default: log1( "set cached crap: %d", d->type ); break; } } @@ -216,7 +221,7 @@ #define NeedBytes(n) if(bytesRemaining<(n)) pBlob=(PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining) #define MoveAlong(n) {int x=n; pBlob+=(x); ofsBlobPtr+=(x); bytesRemaining-=(x);} -#define VLT(n) ((n==DBVT_UTF8)?DBVT_ASCIIZ:n) +#define VLT(n) (TYPE_IS_STRING(n)?DBVT_ASCIIZ:n) static __inline int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic) { struct DBContact dbc; @@ -264,12 +269,13 @@ memcpy( dbcgs->pValue, pCachedValue, sizeof( DBVARIANT )); switch( dbcgs->pValue->type ) { + case DBVT_DELETED: log0( "set cached type deleted" ); break; case DBVT_BYTE: log1( "get cached byte: %d", dbcgs->pValue->bVal ); break; case DBVT_WORD: log1( "get cached word: %d", dbcgs->pValue->wVal ); break; case DBVT_DWORD: log1( "get cached dword: %d", dbcgs->pValue->dVal ); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: log1( "get cached string: '%s'", dbcgs->pValue->pszVal); break; - default: log1( "get cached crap: %d", dbcgs->pValue->type ); break; + case DBVT_ASCIIZ: log1( "get cached string(ASCII): '%s'", dbcgs->pValue->pszVal ); break; + case DBVT_UTF8: log1( "get cached string(UTF8): '%s'", dbcgs->pValue->pszVal ); break; + default: log1( "get cached crap: %d", dbcgs->pValue->type ); } LeaveCriticalSection(&csDbAccess); @@ -308,6 +314,67 @@ case DBVT_BYTE: dbcgs->pValue->bVal=pBlob[1]; break; case DBVT_WORD: dbcgs->pValue->wVal=*(PWORD)(pBlob+1); break; case DBVT_DWORD: dbcgs->pValue->dVal=*(PDWORD)(pBlob+1); break; + case DBVT_UTF8_DB_PATH: + case DBVT_ASCIIZ_DB_PATH: + case DBVT_UTF8_PATH: + case DBVT_ASCIIZ_PATH: + { + // For cache / outter world, this is a asciiz or utf8 + char *dir; + size_t dirLen; + + switch(pBlob[0]) { + case DBVT_UTF8_DB_PATH: + dir = szDbDirUtf8; + dirLen = uiDbDirLenUtf8; + dbcgs->pValue->type = DBVT_UTF8; + break; + case DBVT_ASCIIZ_DB_PATH: + dir = szDbDir; + dirLen = uiDbDirLen; + dbcgs->pValue->type = DBVT_ASCIIZ; + break; + case DBVT_UTF8_PATH: + dir = szMirandaDirUtf8; + dirLen = uiMirandaDirLenUtf8; + dbcgs->pValue->type = DBVT_UTF8; + break; + case DBVT_ASCIIZ_PATH: + dir = szMirandaDir; + dirLen = uiMirandaDirLen; + dbcgs->pValue->type = DBVT_ASCIIZ; + break; + } + + NeedBytes(3+*(PWORD)(pBlob+1)); + if(isStatic) { + dbcgs->pValue->cchVal--; + + if(*(PWORD)(pBlob+1) + uiDbDirLen < dbcgs->pValue->cchVal) + dbcgs->pValue->cchVal = *(PWORD)(pBlob+1) + dirLen; + + if (dbcgs->pValue->cchVal <= dirLen) + { + CopyMemory(dbcgs->pValue->pszVal, dir, dbcgs->pValue->cchVal); + } + else + { + CopyMemory(dbcgs->pValue->pszVal, dir, dirLen); + CopyMemory(dbcgs->pValue->pszVal + dirLen, pBlob+3, + dbcgs->pValue->cchVal - dirLen); + } + + dbcgs->pValue->pszVal[dbcgs->pValue->cchVal]=0; + } + else + { + dbcgs->pValue->pszVal=(char*)mir_alloc(1+*(PWORD)(pBlob+1)+dirLen); + CopyMemory(dbcgs->pValue->pszVal,dir,dirLen); + CopyMemory(dbcgs->pValue->pszVal+dirLen,pBlob+3,*(PWORD)(pBlob+1)); + dbcgs->pValue->pszVal[*(PWORD)(pBlob+1)+dirLen]=0; + } + break; + } case DBVT_UTF8: case DBVT_ASCIIZ: NeedBytes(3+*(PWORD)(pBlob+1)); @@ -396,7 +463,7 @@ if ( iSaveType == 0 || iSaveType == dgs->pValue->type ) return 0; - if ( dgs->pValue->type != DBVT_ASCIIZ && dgs->pValue->type != DBVT_UTF8 ) + if ( ! TYPE_IS_STRING( dgs->pValue->type )) return 0; if ( iSaveType == DBVT_WCHAR ) { @@ -500,8 +567,9 @@ int settingNameLen=0; int moduleNameLen=0; int settingDataLen=0; + char szTmpPath[MAX_PATH]; - int bytesRequired,bytesRemaining; + int bytesRequired=0,bytesRemaining; DWORD ofsContact,ofsSettingsGroup,ofsBlobPtr; if (dbcws == NULL) @@ -568,8 +636,8 @@ case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcws->value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcws->value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcws->value.dVal; break; - case DBVT_UTF8: - case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, dbcws->value.pszVal ) == 0; break; + default: if (TYPE_IS_STRING( dbcws->value.type )) + bIsIdentical = strcmp( pCachedValue->pszVal, dbcws->value.pszVal ) == 0; } if ( bIsIdentical ) { LeaveCriticalSection(&csDbAccess); @@ -597,11 +665,33 @@ return 1; } log0("write setting"); + if ( ( dbcws->value.type == DBVT_ASCIIZ || dbcws->value.type == DBVT_UTF8 ) && strlen(dbcws->value.pszVal) < MAX_PATH ) { + if ( dbcws->value.type == DBVT_ASCIIZ && strnicmp(szDbDir, dbcws->value.pszVal, uiDbDirLen) == 0 ) { + strcpy(szTmpPath, &dbcws->value.pszVal[uiDbDirLen]); + dbcws->value.pszVal = szTmpPath; + dbcws->value.type = DBVT_ASCIIZ_DB_PATH; + } + else if ( dbcws->value.type == DBVT_ASCIIZ && strnicmp(szMirandaDir, dbcws->value.pszVal, uiMirandaDirLen) == 0 ) { + strcpy(szTmpPath, &dbcws->value.pszVal[uiMirandaDirLen]); + dbcws->value.pszVal = szTmpPath; + dbcws->value.type = DBVT_ASCIIZ_PATH; + } + else if ( dbcws->value.type == DBVT_UTF8 && strnicmp(szDbDirUtf8, dbcws->value.pszVal, uiDbDirLenUtf8) == 0 ) { + strcpy(szTmpPath, &dbcws->value.pszVal[uiDbDirLenUtf8]); + dbcws->value.pszVal = szTmpPath; + dbcws->value.type = DBVT_UTF8_DB_PATH; + } + else if ( dbcws->value.type == DBVT_UTF8 && strnicmp(szMirandaDirUtf8, dbcws->value.pszVal, uiMirandaDirLenUtf8) == 0 ) { + strcpy(szTmpPath, &dbcws->value.pszVal[uiMirandaDirLenUtf8]); + dbcws->value.pszVal = szTmpPath; + dbcws->value.type = DBVT_UTF8_PATH; + } + } //make sure the module group exists ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsContact,ofsModuleName); if(ofsSettingsGroup==0) { //module group didn't exist - make it if(dbcws->value.type&DBVTF_VARIABLELENGTH) { - if(dbcws->value.type==DBVT_ASCIIZ || dbcws->value.type==DBVT_UTF8) bytesRequired=strlen(dbcws->value.pszVal)+2; + if(TYPE_IS_STRING(dbcws->value.type)) bytesRequired=strlen(dbcws->value.pszVal)+2; else if(dbcws->value.type==DBVT_BLOB) bytesRequired=dbcws->value.cpbVal+2; } else bytesRequired=dbcws->value.type; @@ -638,7 +728,7 @@ MoveAlong(1+settingNameLen); //if different type or variable length and length is different NeedBytes(3); - if(pBlob[0]!=dbcws->value.type || ((pBlob[0]==DBVT_ASCIIZ || pBlob[0]==DBVT_UTF8) && *(PWORD)(pBlob+1)!=strlen(dbcws->value.pszVal)) || (pBlob[0]==DBVT_BLOB && *(PWORD)(pBlob+1)!=dbcws->value.cpbVal)) { + if(pBlob[0]!=dbcws->value.type || (TYPE_IS_STRING(pBlob[0]) && *(PWORD)(pBlob+1)!=strlen(dbcws->value.pszVal)) || (pBlob[0]==DBVT_BLOB && *(PWORD)(pBlob+1)!=dbcws->value.cpbVal)) { //bin it int nameLen,valLen; DWORD ofsSettingToCut; @@ -665,8 +755,8 @@ case DBVT_BYTE: DBWrite(ofsBlobPtr,&dbcws->value.bVal,1); break; case DBVT_WORD: DBWrite(ofsBlobPtr,&dbcws->value.wVal,2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr,&dbcws->value.dVal,4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: DBWrite(ofsBlobPtr+2,dbcws->value.pszVal,strlen(dbcws->value.pszVal)); break; + default: if (TYPE_IS_STRING( dbcws->value.type )) + DBWrite(ofsBlobPtr+2,dbcws->value.pszVal,strlen(dbcws->value.pszVal)); break; case DBVT_BLOB: DBWrite(ofsBlobPtr+2,dbcws->value.pbVal,dbcws->value.cpbVal); break; } //quit @@ -682,7 +772,7 @@ //pBlob already points to end of list //see if it fits if(dbcws->value.type&DBVTF_VARIABLELENGTH) { - if(dbcws->value.type==DBVT_ASCIIZ || dbcws->value.type==DBVT_UTF8) bytesRequired=strlen(dbcws->value.pszVal)+2; + if(TYPE_IS_STRING(dbcws->value.type)) bytesRequired=strlen(dbcws->value.pszVal)+2; else if(dbcws->value.type==DBVT_BLOB) bytesRequired=dbcws->value.cpbVal+2; } else bytesRequired=dbcws->value.type; @@ -737,13 +827,13 @@ case DBVT_BYTE: DBWrite(ofsBlobPtr,&dbcws->value.bVal,1); MoveAlong(1); break; case DBVT_WORD: DBWrite(ofsBlobPtr,&dbcws->value.wVal,2); MoveAlong(2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr,&dbcws->value.dVal,4); MoveAlong(4); break; - case DBVT_UTF8: - case DBVT_ASCIIZ: - { int len=strlen(dbcws->value.pszVal); + default: + if (TYPE_IS_STRING( dbcws->value.type )) { + int len=strlen(dbcws->value.pszVal); DBWrite(ofsBlobPtr,&len,2); DBWrite(ofsBlobPtr+2,dbcws->value.pszVal,len); MoveAlong(2+len); - } + } break; case DBVT_BLOB: DBWrite(ofsBlobPtr,&dbcws->value.cpbVal,2); Index: commonheaders.h =================================================================== --- commonheaders.h (revision 4057) +++ commonheaders.h (working copy) @@ -51,6 +51,14 @@ #include extern PLUGINLINK *pluginLink; +extern char szMirandaDir[MAX_PATH]; +extern size_t uiMirandaDirLen; +extern char szDbDir[MAX_PATH]; +extern size_t uiDbDirLen; +extern char *szMirandaDirUtf8; +extern size_t uiMirandaDirLenUtf8; +extern char *szDbDirUtf8; +extern size_t uiDbDirLenUtf8; extern struct MM_INTERFACE memoryManagerInterface; extern struct LIST_INTERFACE li; @@ -64,3 +72,9 @@ #else #define mir_i64(x) (x##i64) #endif + + +#define DBVT_ASCIIZ_PATH 250 //pszVal is valid +#define DBVT_UTF8_PATH 249 //pszVal is valid +#define DBVT_ASCIIZ_DB_PATH 248 //pszVal is valid +#define DBVT_UTF8_DB_PATH 247 //pszVal is valid