From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mmap_SA/database.c | 224 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 plugins/Dbx_mmap_SA/database.c (limited to 'plugins/Dbx_mmap_SA/database.c') diff --git a/plugins/Dbx_mmap_SA/database.c b/plugins/Dbx_mmap_SA/database.c new file mode 100644 index 0000000000..b9c1b9871f --- /dev/null +++ b/plugins/Dbx_mmap_SA/database.c @@ -0,0 +1,224 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "commonheaders.h" + +int ProfileManager(char *szDbDest,int cbDbDest); +int ShouldAutoCreate(void); +int CreateDbHeaders(HANDLE hFile); +int InitialiseDbHeaders(void); +int InitSettings(void); +void UninitSettings(void); +int InitContacts(void); +void UninitContacts(void); +int InitEvents(void); +void UninitEvents(void); +int InitCrypt(void); +int InitModuleNames(void); +void UninitModuleNames(void); +int InitCache(void); +void UninitCache(void); +int InitIni(void); +void UninitIni(void); +int InitPreset(void); +void UninitPreset(void); +int InitDialogs(void); +void InitSecurity(void); +void UnloadSecurity(void); + +HANDLE hDbFile=INVALID_HANDLE_VALUE; +CRITICAL_SECTION csDbAccess; +struct DBHeader dbHeader; +char szDbPath[MAX_PATH]; + +static void UnloadDatabase(void) +{ + // update profile last modified time + DWORD bytesWritten; + SetFilePointer(hDbFile,0,NULL,FILE_BEGIN); + WriteFile(hDbFile,dbHeader.signature,sizeof(1),&bytesWritten,NULL); + + CloseHandle(hDbFile); +} + +DWORD CreateNewSpace(int bytes) +{ + DWORD ofsNew; + ofsNew=dbHeader.ofsFileEnd; + dbHeader.ofsFileEnd+=bytes; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + log2("newspace %d@%08x",bytes,ofsNew); + return ofsNew; +} + +void DeleteSpace(DWORD ofs,int bytes) +{ + if (ofs+bytes == dbHeader.ofsFileEnd) { + log2("freespace %d@%08x",bytes,ofs); + dbHeader.ofsFileEnd=ofs; + } else { + log2("deletespace %d@%08x",bytes,ofs); + dbHeader.slackSpace+=bytes; + } + DBWrite(0,&dbHeader,sizeof(dbHeader)); + DBFill(ofs,bytes); +} + +DWORD ReallocSpace(DWORD ofs,int oldSize,int newSize) +{ + DWORD ofsNew; + + if (oldSize >= newSize) return ofs; + + if (ofs+oldSize == dbHeader.ofsFileEnd) { + ofsNew = ofs; + dbHeader.ofsFileEnd+=newSize-oldSize; + DBWrite(0,&dbHeader,sizeof(dbHeader)); + log3("adding newspace %d@%08x+%d",newSize,ofsNew,oldSize); + } else { + ofsNew=CreateNewSpace(newSize); + DBMoveChunk(ofsNew,ofs,oldSize); + DeleteSpace(ofs,oldSize); + } + return ofsNew; +} + +void UnloadDatabaseModule(void) +{ + //UninitIni(); + UninitPreset(); + UninitEvents(); + UninitSettings(); + UninitContacts(); + UninitModuleNames(); + UninitCache(); + UnloadDatabase(); + UnloadSecurity(); + DeleteCriticalSection(&csDbAccess); +} + +INT_PTR GetProfileName(WPARAM wParam, LPARAM lParam) +{ + char * p = 0; + p = strrchr(szDbPath, '\\'); + if ( p == 0 ) return 1; + p++; + strncpy((char*)lParam, p, (size_t) wParam); + return 0; +} + +int LoadDatabaseModule(void) +{ + char szDBName[255]; + InitializeCriticalSection(&csDbAccess); + log0("DB logging running"); + { + DWORD dummy=0; + hDbFile=CreateFileA(szDbPath,GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + if ( hDbFile == INVALID_HANDLE_VALUE ) { + return 1; + } + if ( !ReadFile(hDbFile,&dbHeader,sizeof(dbHeader),&dummy,NULL) ) { + CloseHandle(hDbFile); + return 1; + } + } + InitSecurity(); + CheckDbHeaders(&dbHeader); + GetProfileName((WPARAM)50, (LPARAM)szDBName); + if(bEncoding && !CheckPassword(dbHeader.checkWord, szDBName)) return 1; + //if(ParseCommandLine()) return 1; + if(InitCache()) return 1; + if(InitModuleNames()) return 1; + if(InitContacts()) return 1; + if(InitSettings()) return 1; + if(InitEvents()) return 1; + if(InitCrypt()) return 1; + if(InitPreset()) return 1; + if(InitDialogs()) return 1; + //EncryptDB(); + return 0; +} + +static DWORD DatabaseCorrupted=0; +static TCHAR *msg = NULL; +static DWORD dwErr = 0; + +void __cdecl dbpanic(void *arg) +{ + if (msg) + { + TCHAR err[256]; + + if (dwErr==ERROR_DISK_FULL) + msg = TranslateT("Disk is full. Miranda will now shutdown."); + + mir_sntprintf(err, SIZEOF(err), msg, TranslateT("Database failure. Miranda will now shutdown."), dwErr); + + MessageBox(0,err,TranslateT("Database Error"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); + } + else + MessageBox(0,TranslateT("Miranda has detected corruption in your database. This corruption maybe fixed by DBTool. Please download it from http://www.miranda-im.org. Miranda will now shutdown."), + TranslateT("Database Panic"),MB_SETFOREGROUND|MB_TOPMOST|MB_APPLMODAL|MB_ICONWARNING|MB_OK); + + TerminateProcess(GetCurrentProcess(),255); +} + +void DatabaseCorruption(TCHAR *text) +{ + int kill=0; + + EnterCriticalSection(&csDbAccess); + if (DatabaseCorrupted==0) { + DatabaseCorrupted++; + kill++; + msg = text; + dwErr = GetLastError(); + } else { + /* db is already corrupted, someone else is dealing with it, wait here + so that we don't do any more damage */ + LeaveCriticalSection(&csDbAccess); + Sleep(INFINITE); + return; + } + LeaveCriticalSection(&csDbAccess); + if (kill) { + _beginthread(dbpanic,0,NULL); + Sleep(INFINITE); + } +} + +#ifdef DBLOGGING +void DBLog(const char *file,int line,const char *fmt,...) +{ + FILE *fp; + va_list vararg; + char str[1024]; + + va_start(vararg,fmt); + mir_vsnprintf(str,sizeof(str),fmt,vararg); + va_end(vararg); + fp=fopen("c:\\mirandadatabase.log.txt","at"); + fprintf(fp,"%u: %s %d: %s\n",GetTickCount(),file,line,str); + fclose(fp); +} +#endif -- cgit v1.2.3