// static already_AddRefed<Shmem::SharedMemory> Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, const IPC::Message& aDescriptor, id_t* aId, bool aProtect) { size_t size; size_t pageSize = SharedMemory::SystemPageSize(); // |2*pageSize| is for the front and back sentinels RefPtr<SharedMemory> segment = ReadSegment(aDescriptor, aId, &size, 2*pageSize); if (!segment) { return nullptr; } Header* header = GetHeader(segment); if (size != header->mSize) { // Deallocation should zero out the header, so check for that. if (header->mSize || header->mUnsafe || header->mMagic[0] || memcmp(header->mMagic, &header->mMagic[1], sizeof(header->mMagic)-1)) { NS_ERROR("Wrong size for this Shmem!"); } else { NS_WARNING("Shmem was deallocated"); } return nullptr; } // The caller of this function may not know whether the segment is // unsafe or not if (!header->mUnsafe && aProtect) Protect(segment); return segment.forget(); }
NS_IMETHODIMP sbSeekableChannel::OnDataAvailable( nsIRequest *pRequest, nsISupports *pCtx, nsIInputStream *pStream, PRUint32 offset, PRUint32 numBytes) { nsresult result = NS_OK; /* Do nothing if channel is restarting. */ if (mRestarting) return (NS_ERROR_SONGBIRD_SEEKABLE_CHANNEL_RESTART); /* Read the base channel data into a data segment. */ if (numBytes > 0) { mDataReceivedSinceStart = PR_TRUE; ReadSegment(pStream, numBytes); } /* Call the OnChannelDataAvailable handler. */ /*zzz should read minimum block size before calling handler. */ if (mpListener) mpListener->OnChannelDataAvailable(this); return (result); }
int WorkInitialChecks(int firstTime) { DWORD bytesRead; sourceFileSize=GetFileSize(opts.hFile,NULL); if(sourceFileSize==0) { AddToStatus(STATUS_WARNING,TranslateT("Database is newly created and has no data to process")); AddToStatus(STATUS_SUCCESS,TranslateT("Processing completed successfully")); return ERROR_INVALID_DATA; } ReadFile(opts.hFile,&dbhdr,sizeof(dbhdr),&bytesRead,NULL); if(bytesRead<sizeof(dbhdr)) { AddToStatus(STATUS_FATAL,TranslateT("Database is corrupted and too small to contain any recoverable data")); return ERROR_BAD_FORMAT; } if(memcmp(dbhdr.signature,&dbSignature,sizeof(dbhdr.signature))) { AddToStatus(STATUS_FATAL,TranslateT("Database signature is corrupted, automatic repair is impossible")); return ERROR_BAD_FORMAT; } if(dbhdr.version!=0x00000700) { AddToStatus(STATUS_FATAL,TranslateT("Database is marked as belonging to an unknown version of Miranda")); return ERROR_BAD_FORMAT; } _tcscpy(opts.workingFilename,opts.filename); if(opts.bCheckOnly) { _tcscpy( opts.outputFilename, TranslateT("<check only>")); opts.hOutFile=INVALID_HANDLE_VALUE; } else { _tcscpy(opts.outputFilename,opts.filename); *_tcsrchr(opts.outputFilename,'.')=0; _tcscat(opts.outputFilename,TranslateT(" (Output).dat")); opts.hOutFile = CreateFile(opts.outputFilename,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_SEQUENTIAL_SCAN,NULL); if ( opts.hOutFile == INVALID_HANDLE_VALUE ) { AddToStatus(STATUS_FATAL,TranslateT("Can't create output file (%u)"),GetLastError()); return ERROR_ACCESS_DENIED; } } opts.hMap = CreateFileMapping(opts.hFile, NULL, opts.bAggressive?PAGE_WRITECOPY:PAGE_READONLY, 0, 0, NULL); if (opts.hMap) opts.pFile = (BYTE*)MapViewOfFile(opts.hMap, opts.bAggressive?FILE_MAP_COPY:FILE_MAP_READ, 0, 0 ,0); else { AddToStatus(STATUS_FATAL,TranslateT("Can't create file mapping (%u)"),GetLastError()); return ERROR_ACCESS_DENIED; } if (!opts.pFile) { AddToStatus(STATUS_FATAL,TranslateT("Can't create map view of file (%u)"),GetLastError()); return ERROR_ACCESS_DENIED; } if(ReadSegment(0,&dbhdr,sizeof(dbhdr))!=ERROR_SUCCESS) return ERROR_READ_FAULT; if(WriteSegment(0,&dbhdr,sizeof(dbhdr))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; spaceUsed=dbhdr.ofsFileEnd-dbhdr.slackSpace; dbhdr.ofsFileEnd=sizeof(dbhdr); return ERROR_NO_MORE_ITEMS; }
int WorkSettingsChain(DWORD ofsContact,DBContact *dbc,int firstTime) { DBContactSettings *dbcsNew,dbcsOld; DWORD ofsDestThis; int ret; if(firstTime) { ofsDestPrevSettings=0; ofsThisSettings=dbc->ofsFirstSettings; dbc->ofsFirstSettings=0; } if(ofsThisSettings==0) return ERROR_NO_MORE_ITEMS; if(!SignatureValid(ofsThisSettings,DBCONTACTSETTINGS_SIGNATURE)) { AddToStatus(STATUS_ERROR,TranslateT("Settings chain corrupted, further entries ignored")); return ERROR_NO_MORE_ITEMS; } if(PeekSegment(ofsThisSettings,&dbcsOld,sizeof(dbcsOld))!=ERROR_SUCCESS) return ERROR_NO_MORE_ITEMS; if(dbcsOld.cbBlob>256*1024 || dbcsOld.cbBlob==0) { AddToStatus(STATUS_ERROR,TranslateT("Infeasibly large settings blob: skipping")); ofsThisSettings=dbcsOld.ofsNext; return ERROR_SUCCESS; } dbcsNew=(DBContactSettings*)_malloca(offsetof(DBContactSettings,blob)+dbcsOld.cbBlob); if((ret=ReadSegment(ofsThisSettings,dbcsNew,offsetof(DBContactSettings,blob)+dbcsOld.cbBlob))!=ERROR_SUCCESS) { if(ret!=ERROR_HANDLE_EOF) { //eof is OK because blank space at the end doesn't matter return ERROR_NO_MORE_ITEMS; } } if((dbcsNew->ofsModuleName=ConvertModuleNameOfs(dbcsOld.ofsModuleName))==0) { ofsThisSettings=dbcsOld.ofsNext; return ERROR_SUCCESS; } if(dbcsNew->blob[0]==0) { AddToStatus(STATUS_MESSAGE,TranslateT("Empty settings group at %08X: deleting"),ofsThisSettings); ofsThisSettings=dbcsOld.ofsNext; return ERROR_SUCCESS; } dbcsNew->ofsNext=0; //TODO? validate all settings in blob/compact if necessary if((ofsDestThis=WriteSegment(WSOFS_END,dbcsNew,offsetof(DBContactSettings,blob)+dbcsNew->cbBlob))==WS_ERROR) { return ERROR_HANDLE_DISK_FULL; } if(ofsDestPrevSettings) WriteSegment(ofsDestPrevSettings+offsetof(DBContactSettings,ofsNext),&ofsDestThis,sizeof(DWORD)); else dbc->ofsFirstSettings=ofsDestThis; ofsDestPrevSettings=ofsDestThis; ofsThisSettings=dbcsOld.ofsNext; return ERROR_SUCCESS; }
int WorkUser(int firstTime) { int first=0; if(firstTime) { AddToStatus(STATUS_MESSAGE,TranslateT("Processing user data")); if(!SignatureValid(dbhdr.ofsUser,DBCONTACT_SIGNATURE)) { AddToStatus(STATUS_ERROR,TranslateT("User corrupted, this could cause major problems")); return ERROR_NO_MORE_ITEMS; } if(ReadSegment(dbhdr.ofsUser,&user,sizeof(DBContact))!=ERROR_SUCCESS) return ERROR_NO_MORE_ITEMS; if(user.ofsNext) { AddToStatus(STATUS_WARNING,TranslateT("More than one user contact: keeping only first")); user.ofsNext=0; } if((ofsUser=WriteSegment(WSOFS_END,&user,sizeof(DBContact)))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; dbhdr.ofsUser=ofsUser; phase=0; first=1; } switch(phase) { int ret; case 0: ret=WorkSettingsChain(ofsUser,&user,first); if(ret==ERROR_NO_MORE_ITEMS) { phase++; first=1; } else if(ret) return ret; else break; case 1: ret=WorkEventChain(ofsUser,&user,first); if(ret==ERROR_NO_MORE_ITEMS) { if(WriteSegment(ofsUser,&user,sizeof(DBContact))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; return ERROR_NO_MORE_ITEMS; } else if(ret) return ret; break; } return ERROR_SUCCESS; }
// static already_AddRefed<Shmem::SharedMemory> Shmem::OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead, const IPC::Message& aDescriptor, id_t* aId, bool /*unused*/) { size_t size; RefPtr<SharedMemory> segment = ReadSegment(aDescriptor, aId, &size, sizeof(uint32_t)); if (!segment) { return nullptr; } // this is the only validity check done in non-DEBUG builds if (size != static_cast<size_t>(*PtrToSize(segment))) { return nullptr; } return segment.forget(); }
/* Read in prep class instructions */ prepClass *Read_prepClass ( prepClass *t, InputStream *in ) { tt_uint32 numInstructions=t->numInstructions; tt_uint8 *instructionPtr=t->instructions; #if 0 for ( i = 0; i < numInstructions; i++ ) { *instructionPtr++ = ReadUnsignedByteMacro( in ); } #else ReadSegment( in, instructionPtr, numInstructions ); #endif return t; /*****/ }
int WorkModuleChain(int firstTime) { DBModuleName moduleName,*newModName; if(firstTime) { AddToStatus(STATUS_MESSAGE,TranslateT("Processing module name chain")); modChainCount=0; last_mod = 0; if(modChain!=NULL) free(modChain); modChain = (ModChainEntry*)malloc(sizeof(ModChainEntry)); phase=0; ofsCurrent=dbhdr.ofsFirstModuleName; } switch(phase) { case 0: if(ofsCurrent==0) { phase++; return ERROR_SUCCESS; } if(!SignatureValid(ofsCurrent,DBMODULENAME_SIGNATURE)) { AddToStatus(STATUS_ERROR,TranslateT("Module chain corrupted, further entries ignored")); phase++; return ERROR_SUCCESS; } if(PeekSegment(ofsCurrent,&moduleName,offsetof(DBModuleName,name))!=ERROR_SUCCESS) { phase++; return ERROR_SUCCESS; } if(moduleName.cbName>256) AddToStatus(STATUS_WARNING,TranslateT("Unreasonably long module name, skipping")); else { modChain=(ModChainEntry*)realloc(modChain,sizeof(ModChainEntry)*++modChainCount); modChain[modChainCount-1].ofsOld=ofsCurrent; modChain[modChainCount-1].size=offsetof(DBModuleName,name)+moduleName.cbName; modChain[modChainCount-1].ofsNew=0; if (moduleName.cbName) PeekSegment(ofsCurrent+offsetof(DBModuleName,name),&modChain[modChainCount-1].name,moduleName.cbName); modChain[modChainCount-1].name[moduleName.cbName]=0; } ofsCurrent=moduleName.ofsNext; break; case 1: ofsLast = 0; iCurrentModName=0; dbhdr.ofsFirstModuleName=0; phase++; case 2: if(iCurrentModName>=modChainCount) { DWORD dw = 0; if(ofsLast) WriteSegment(ofsLast+offsetof(DBModuleName,ofsNext),&dw,sizeof(DWORD)); return ERROR_NO_MORE_ITEMS; } if(modChain[iCurrentModName].ofsNew==0) { newModName=(DBModuleName*)_malloca(modChain[iCurrentModName].size); if(ReadSegment(modChain[iCurrentModName].ofsOld,newModName,modChain[iCurrentModName].size)!=ERROR_SUCCESS) return ERROR_NO_MORE_ITEMS; if((modChain[iCurrentModName].ofsNew=WriteSegment(WSOFS_END,newModName,modChain[iCurrentModName].size))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; { // check duplicated modulenames int i, n=0; for(i=iCurrentModName+1;i<modChainCount;i++) if(!strcmp(modChain[i].name, modChain[iCurrentModName].name)) { modChain[i].ofsNew = modChain[iCurrentModName].ofsNew; n++; } if (n) AddToStatus(STATUS_WARNING,TranslateT("Module name '%s' is not unique: %d duplicates found)"), modChain[iCurrentModName].name,n); } if(iCurrentModName==0) dbhdr.ofsFirstModuleName=modChain[iCurrentModName].ofsNew; else if(WriteSegment(ofsLast+offsetof(DBModuleName,ofsNext),&modChain[iCurrentModName].ofsNew,sizeof(DWORD))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; ofsLast = modChain[iCurrentModName].ofsNew; } iCurrentModName++; break; } return ERROR_SUCCESS; }
int CDb3Mmap::WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime) { int isUnread = 0; if (firstTime) { dbePrevEvent = NULL; ofsPrevEvent = 0; ofsDestPrevEvent = 0; ofsThisEvent = dbc->ofsFirstEvent; eventCount = 0; backLookup = 0; lastTimestamp = 0; ofsFirstUnread = tsFirstUnread = 0; if (cb->bEraseHistory) { dbc->eventCount = 0; dbc->ofsFirstEvent = 0; dbc->ofsLastEvent = 0; dbc->ofsFirstUnread = 0; dbc->tsFirstUnread = 0; return ERROR_NO_MORE_ITEMS; } } if (ofsThisEvent == 0) { FinishUp(ofsDestPrevEvent, dbc); return ERROR_NO_MORE_ITEMS; } DBEvent dbeOld; if (!SignatureValid(ofsThisEvent, DBEVENT_SIGNATURE)) { DWORD ofsNew = 0; DWORD ofsTmp = dbc->ofsLastEvent; if (!backLookup && ofsTmp) { backLookup = 1; while (SignatureValid(ofsTmp, DBEVENT_SIGNATURE)) { if (PeekEvent(ofsTmp, dbc->dwContactID, dbeOld) != ERROR_SUCCESS) break; ofsNew = ofsTmp; ofsTmp = dbeOld.ofsPrev; } } if (ofsNew) { cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event chain corrupted, trying to recover...")); ofsThisEvent = ofsNew; } else { cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Event chain corrupted, further entries ignored")); FinishUp(ofsDestPrevEvent, dbc); return ERROR_NO_MORE_ITEMS; } } if (PeekEvent(ofsThisEvent, dbc->dwContactID, dbeOld) != ERROR_SUCCESS) { FinishUp(ofsDestPrevEvent, dbc); return ERROR_NO_MORE_ITEMS; } if (firstTime) { if (dbeOld.ofsPrev != 0) cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("First event not marked as such: correcting")); dbeOld.ofsPrev = 0; lastTimestamp = dbeOld.timestamp; } if (dbeOld.flags & 1) dbeOld.flags &= ~1; if (dbeOld.flags & ~DBEF_ALL) { cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Extra flags found in event: removing")); dbeOld.flags &= DBEF_ALL; } if (!(dbeOld.flags & (DBEF_READ | DBEF_SENT))) { if (cb->bMarkRead) dbeOld.flags |= DBEF_READ; else if (ofsFirstUnread == 0) { if (dbc->ofsFirstUnread != ofsThisEvent || dbc->tsFirstUnread != dbeOld.timestamp) cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("First unread event marked wrong: fixing")); isUnread = 1; } } if (dbeOld.cbBlob > 1024 * 1024 || dbeOld.cbBlob == 0) { cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Infeasibly large event blob: skipping")); ofsThisEvent = dbeOld.ofsNext; return ERROR_SUCCESS; } DBEvent *dbePrev = NULL; if (dbePrevEvent && dbeOld.timestamp == lastTimestamp) { int len = offsetof(DBEvent, blob) + dbePrevEvent->cbBlob; dbePrev = (DBEvent*)malloc(len); memcpy(dbePrev, dbePrevEvent, len); } if (offsetof(DBEvent, blob) + dbeOld.cbBlob > memsize) { memsize = offsetof(DBEvent, blob) + dbeOld.cbBlob; memblock = (DBEvent*)realloc(memblock, memsize); } DBEvent *dbeNew = memblock; DWORD ret; if (m_dbHeader.version < DB_095_1_VERSION) { DBEvent_094 oldEvent; ret = ReadSegment(ofsThisEvent, &oldEvent, offsetof(DBEvent_094, blob)); if (ret == ERROR_SUCCESS) { dbeNew->signature = oldEvent.signature; dbeNew->contactID = dbc->dwContactID; memcpy(&dbeNew->ofsPrev, &oldEvent.ofsPrev, offsetof(DBEvent_094, blob) - sizeof(DWORD)); ret = ReadSegment(ofsThisEvent + offsetof(DBEvent_094, blob), &dbeNew->blob, dbeOld.cbBlob); } } else ret = ReadSegment(ofsThisEvent, dbeNew, offsetof(DBEvent, blob) + dbeOld.cbBlob); if (ret != ERROR_SUCCESS) { FinishUp(ofsDestPrevEvent, dbc); return ERROR_NO_MORE_ITEMS; } if ((dbeNew->ofsModuleName = ConvertModuleNameOfs(dbeOld.ofsModuleName)) == 0) { ofsThisEvent = dbeOld.ofsNext; return ERROR_SUCCESS; } if (!firstTime && dbeOld.ofsPrev != ofsPrevEvent) cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event not backlinked correctly: fixing")); dbeNew->flags = dbeOld.flags; dbeNew->ofsPrev = ofsDestPrevEvent; dbeNew->ofsNext = 0; if (dbeNew->contactID == 0) dbeNew->contactID = dbc->dwContactID; if (dbeOld.wEventType == EVENTTYPE_MESSAGE && cb->bConvertUtf && !(dbeOld.flags & DBEF_ENCRYPTED)) ConvertOldEvent(dbeNew); if (dbePrev) { if (dbePrev->cbBlob == dbeNew->cbBlob && dbePrev->ofsModuleName == dbeNew->ofsModuleName && dbePrev->wEventType == dbeNew->wEventType && (dbePrev->flags & DBEF_SENT) == (dbeNew->flags & DBEF_SENT) && !memcmp(dbePrev->blob, dbeNew->blob, dbeNew->cbBlob)) { cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Duplicate event was found: skipping")); if (dbc->eventCount) dbc->eventCount--; free(dbePrev); // ofsDestPrevEvent is still the same! ofsPrevEvent = ofsThisEvent; ofsThisEvent = dbeOld.ofsNext; return ERROR_SUCCESS; } free(dbePrev); } else if (!firstTime && dbeNew->timestamp < lastTimestamp) { DWORD found = 0; DBEvent dbeTmp = { 0 }; DWORD ofsTmp = 0; if (cb->bCheckOnly) { if (!cb->bAggressive) { ofsTmp = dbeOld.ofsPrev; while (PeekEvent(ofsTmp, dbc->dwContactID, dbeTmp) == ERROR_SUCCESS) { if (dbeTmp.ofsPrev == ofsContact) { found = 1; break; } if (dbeTmp.timestamp < dbeNew->timestamp) { found = 2; break; } ofsTmp = dbeTmp.ofsPrev; } } cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct")); } else { ofsTmp = ofsDestPrevEvent; while (ReadWrittenSegment(ofsTmp, &dbeTmp, sizeof(dbeTmp)) == ERROR_SUCCESS) { if (dbeTmp.ofsPrev == ofsContact) { found = 1; break; } if (dbeTmp.timestamp < dbeNew->timestamp) { found = 2; break; } ofsTmp = dbeTmp.ofsPrev; } if (found) cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct: fixing")); else cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Event position in chain is not correct: unable to fix")); } // insert before FIRST if (found == 1 && !cb->bCheckOnly) { dbeNew->ofsPrev = 0; dbeNew->ofsNext = dbc->ofsFirstEvent; DWORD ofsDestThis = WriteEvent(dbeNew); if (!ofsDestThis) return ERROR_HANDLE_DISK_FULL; if (isUnread && tsFirstUnread >= dbeNew->timestamp) { ofsFirstUnread = ofsDestThis; tsFirstUnread = dbeNew->timestamp; } // fix first event WriteOfsNextToPrevious(0, dbc, ofsDestThis); // fix next event WriteSegment(dbeNew->ofsNext + offsetof(DBEvent, ofsPrev), &ofsDestThis, sizeof(DWORD)); } else if (found == 2 && !cb->bCheckOnly) { dbeNew->ofsPrev = ofsTmp; dbeNew->ofsNext = dbeTmp.ofsNext; DWORD ofsDestThis = WriteEvent(dbeNew); if (!ofsDestThis) return ERROR_HANDLE_DISK_FULL; if (isUnread && tsFirstUnread >= dbeNew->timestamp) { ofsFirstUnread = ofsDestThis; tsFirstUnread = dbeNew->timestamp; } // fix previous event WriteOfsNextToPrevious(dbeNew->ofsPrev, dbc, ofsDestThis); // fix next event WriteSegment(dbeNew->ofsNext + offsetof(DBEvent, ofsPrev), &ofsDestThis, sizeof(DWORD)); } if (found) { eventCount++; // ofsDestPrevEvent is still the same! ofsPrevEvent = ofsThisEvent; ofsThisEvent = dbeOld.ofsNext; return ERROR_SUCCESS; } } lastTimestamp = dbeNew->timestamp; dbePrevEvent = dbeNew; DWORD ofsDestThis = WriteEvent(dbeNew); if (!ofsDestThis) return ERROR_HANDLE_DISK_FULL; if (isUnread) { ofsFirstUnread = ofsDestThis; tsFirstUnread = dbeOld.timestamp; } eventCount++; WriteOfsNextToPrevious(ofsDestPrevEvent, dbc, ofsDestThis); ofsDestPrevEvent = ofsDestThis; ofsPrevEvent = ofsThisEvent; ofsThisEvent = dbeOld.ofsNext; return ERROR_SUCCESS; }
int CDb3Mmap::WorkContactChain(int firstTime) { int first = 0; int ret; if (firstTime) { cb->pfnAddLogMessage(STATUS_MESSAGE, TranslateT("Processing contact chain")); ofsDestPrevContact = 0; ofsThisContact = m_dbHeader.ofsFirstContact; contactCount = 0; m_dbHeader.ofsFirstContact = 0; phase = 0; } switch (phase) { case 0: if (ofsThisContact == 0) { LBL_FinishUp: if (contactCount != m_dbHeader.contactCount) cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Contact count marked wrongly: correcting")); m_dbHeader.contactCount = contactCount; return ERROR_NO_MORE_ITEMS; } if (!SignatureValid(ofsThisContact, DBCONTACT_SIGNATURE)) { cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Contact chain corrupted, further entries ignored")); goto LBL_FinishUp; } if (ReadSegment(ofsThisContact, &dbc, sizeof(dbc)) != ERROR_SUCCESS) goto LBL_FinishUp; ofsNextContact = dbc.ofsNext; dbc.ofsNext = 0; if (!cb->bCheckOnly) { if ((ofsDestThis = WriteSegment(WSOFS_END, &dbc, sizeof(dbc))) == WS_ERROR) return ERROR_HANDLE_DISK_FULL; if (ofsDestPrevContact) WriteSegment(ofsDestPrevContact + offsetof(DBContact, ofsNext), &ofsDestThis, sizeof(DWORD)); else m_dbHeader.ofsFirstContact = ofsDestThis; } else ofsDestThis = ofsThisContact; // needed in event chain worker contactCount++; phase++; first = 1; // fall thru case 1: ret = WorkSettingsChain(ofsDestThis, &dbc, first); if (ret == ERROR_NO_MORE_ITEMS) { phase++; first = 1; } else if (ret) return ret; else break; // fall thru case 2: ret = WorkEventChain(ofsDestThis, &dbc, first); if (ret == ERROR_NO_MORE_ITEMS) { phase++; first = 1; } else if (ret) return ret; else break; // fall thru case 3: if (WriteSegment(ofsDestThis, &dbc, sizeof(DBContact)) == WS_ERROR) return ERROR_HANDLE_DISK_FULL; ofsDestPrevContact = ofsDestThis; ofsThisContact = ofsNextContact; phase = 0; break; } return ERROR_SUCCESS; }
int WorkContactChain(int firstTime) { int first=0; if(firstTime) { AddToStatus(STATUS_MESSAGE,TranslateT("Processing contact chain")); ofsDestPrevContact=0; ofsThisContact=dbhdr.ofsFirstContact; contactCount=0; dbhdr.ofsFirstContact=0; phase=0; } switch(phase) { int ret; case 0: if(ofsThisContact==0) { FinishUp(); return ERROR_NO_MORE_ITEMS; } if(!SignatureValid(ofsThisContact,DBCONTACT_SIGNATURE)) { AddToStatus(STATUS_ERROR,TranslateT("Contact chain corrupted, further entries ignored")); FinishUp(); return ERROR_NO_MORE_ITEMS; } if(ReadSegment(ofsThisContact,&dbc,sizeof(dbc))!=ERROR_SUCCESS) { FinishUp(); return ERROR_NO_MORE_ITEMS; } ofsNextContact=dbc.ofsNext; dbc.ofsNext=0; if (!opts.bCheckOnly) { if((ofsDestThis=WriteSegment(WSOFS_END,&dbc,sizeof(dbc)))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; if(ofsDestPrevContact) WriteSegment(ofsDestPrevContact+offsetof(DBContact,ofsNext),&ofsDestThis,sizeof(DWORD)); else dbhdr.ofsFirstContact=ofsDestThis; } else ofsDestThis = ofsThisContact; // needed in event chain worker contactCount++; phase++; first=1; //fall thru case 1: ret=WorkSettingsChain(ofsDestThis,&dbc,first); if(ret==ERROR_NO_MORE_ITEMS) { phase++; first=1; } else if(ret) return ret; else break; //fall thru case 2: ret=WorkEventChain(ofsDestThis,&dbc,first); if(ret==ERROR_NO_MORE_ITEMS) { phase++; first=1; } else if(ret) return ret; else break; //fall thru case 3: if(WriteSegment(ofsDestThis,&dbc,sizeof(DBContact))==WS_ERROR) return ERROR_HANDLE_DISK_FULL; ofsDestPrevContact=ofsDestThis; ofsThisContact=ofsNextContact; phase=0; break; } return ERROR_SUCCESS; }
int CDb3Mmap::WorkModuleChain(int firstTime) { DBModuleName moduleName, *newModName; if (firstTime) { cb->pfnAddLogMessage(STATUS_MESSAGE, TranslateT("Processing module name chain")); modChainCount = 0; last_mod = 0; free(modChain); modChain = (ModChainEntry*)malloc(sizeof(ModChainEntry)); phase = 0; ofsCurrent = m_dbHeader.ofsModuleNames; } switch (phase) { case 0: if (ofsCurrent == 0) { phase++; return ERROR_SUCCESS; } if (!SignatureValid(ofsCurrent, DBMODULENAME_SIGNATURE)) { cb->pfnAddLogMessage(STATUS_ERROR, TranslateT("Module chain corrupted, further entries ignored")); phase++; return ERROR_SUCCESS; } if (PeekSegment(ofsCurrent, &moduleName, offsetof(DBModuleName, name)) != ERROR_SUCCESS) { phase++; return ERROR_SUCCESS; } modChain = (ModChainEntry*)realloc(modChain, sizeof(ModChainEntry)*++modChainCount); modChain[modChainCount - 1].ofsOld = ofsCurrent; modChain[modChainCount - 1].size = offsetof(DBModuleName, name) + moduleName.cbName; modChain[modChainCount - 1].ofsNew = 0; if (moduleName.cbName) PeekSegment(ofsCurrent + offsetof(DBModuleName, name), &modChain[modChainCount - 1].name, moduleName.cbName); modChain[modChainCount - 1].name[moduleName.cbName] = 0; ofsCurrent = moduleName.ofsNext; break; case 1: ofsLast = 0; iCurrentModName = 0; m_dbHeader.ofsModuleNames = 0; phase++; case 2: if (iCurrentModName >= modChainCount) { DWORD dw = 0; if (ofsLast) WriteSegment(ofsLast + offsetof(DBModuleName, ofsNext), &dw, sizeof(DWORD)); return ERROR_NO_MORE_ITEMS; } if (modChain[iCurrentModName].ofsNew == 0) { newModName = (DBModuleName*)_alloca(modChain[iCurrentModName].size); if (ReadSegment(modChain[iCurrentModName].ofsOld, newModName, modChain[iCurrentModName].size) != ERROR_SUCCESS) return ERROR_NO_MORE_ITEMS; if ((modChain[iCurrentModName].ofsNew = WriteSegment(WSOFS_END, newModName, modChain[iCurrentModName].size)) == WS_ERROR) return ERROR_HANDLE_DISK_FULL; // check duplicated modulenames int i, n = 0; for (i = iCurrentModName + 1; i < modChainCount; i++) if (!mir_strcmp(modChain[i].name, modChain[iCurrentModName].name)) { modChain[i].ofsNew = modChain[iCurrentModName].ofsNew; n++; } if (n) { TCHAR szModuleName[257]; MultiByteToWideChar(CP_ACP, 0, modChain[iCurrentModName].name, -1, szModuleName, _countof(szModuleName)); TCHAR *pszModuleName = szModuleName; cb->pfnAddLogMessage(STATUS_WARNING, TranslateT("Module name '%s' is not unique: %d duplicates found"), pszModuleName, n); } if (iCurrentModName == 0) m_dbHeader.ofsModuleNames = modChain[iCurrentModName].ofsNew; else if (WriteSegment(ofsLast + offsetof(DBModuleName, ofsNext), &modChain[iCurrentModName].ofsNew, sizeof(DWORD)) == WS_ERROR) return ERROR_HANDLE_DISK_FULL; ofsLast = modChain[iCurrentModName].ofsNew; } iCurrentModName++; break; } return ERROR_SUCCESS; }