static void LoadPreferencesNoahPro(AppContext* appContext) { DmOpenRef db; UInt recNo; void * recData; MemHandle recHandle; UInt recsCount; Boolean fRecFound = false; appContext->fFirstRun = true; db = DmOpenDatabaseByTypeCreator(NOAH_PREF_TYPE, NOAH_PRO_CREATOR, dmModeReadWrite); if (!db) return; recsCount = DmNumRecords(db); for (recNo = 0; (recNo < recsCount) && !fRecFound; recNo++) { recHandle = DmQueryRecord(db, recNo); recData = MemHandleLock(recHandle); if ( (MemHandleSize(recHandle)>=PREF_REC_MIN_SIZE) && IsValidPrefRecord( recData ) ) { LogG( "LoadPreferencesNoahPro(), found prefs record" ); fRecFound = true; appContext->fFirstRun = false; DeserializePreferencesNoahPro(appContext, (unsigned char*)recData, MemHandleSize(recHandle) ); } MemPtrUnlock(recData); } DmCloseDatabase(db); }
/*********************************************************************** * * FUNCTION: SubstituteStr * * DESCRIPTION: This routine substitutes the occurrence a token, within * a string, with another string. * * PARAMETERS: str - string containing token string * token - the string to be replaced * sub - the string to substitute for the token * subLen - length of the substitute string. * * RETURNED: pointer to the string * ***********************************************************************/ static Char* SubstituteStr(Char* str, const Char* token, const Char* sub, UInt16 subLen) { const UInt16 tokenLen = StrLen(token); const UInt16 charsToMove = subLen - tokenLen; const UInt16 strLen = StrLen(str); MemHandle strH = MemPtrRecoverHandle(str); const UInt16 blockSize = MemHandleSize(strH); Char* ptr = StrStr(str, token); ASSERT(str); ASSERT(token); ASSERT(sub); /* Find the start of the token string, if it doesn't exist, exit. */ if (ptr == NULL) return str; /* Resize the string if necessary. */ if (strLen + charsToMove + 1 >= blockSize) { MemHandleUnlock(strH); MemHandleResize(strH, strLen + charsToMove + 1); str = MemHandleLock(strH); ASSERT(str); ptr = StrStr(str, token); ASSERT(ptr); } /* Make room for the substitute string. */ if (charsToMove) MemMove(ptr + subLen, ptr + tokenLen, StrLen (ptr + tokenLen)+1); /* Replace the token with the substitute string. */ MemMove(ptr, sub, subLen); return str; }
void String_Init() { MemHandle Resource; DmResID Id; context* p = Context(); StringAlloc(); for (Id=1000;Id<1000+32;++Id) { Resource = DmGetResource('lang',Id); if (Resource) { int Size = MemHandleSize(Resource); void* Data = MemHandleLock(Resource); if (Size && Data && StringAddBinary(Data,Size)) ArrayAppend(&p->StrModule,&Resource,sizeof(Resource),16); else { if (Data) MemHandleUnlock(Resource); DmReleaseResource(Resource); } } } }
/*----------------------------------------CIRexxApp::copyScriptFromFindResult-+ | | +----------------------------------------------------------------------------*/ void CIRexxApp::copyScriptFromFindResult(GoToParamsPtr pGoToParams) { Err err; LocalID dbID; UInt16 cardNo = 0; DmOpenRef dbP; DmSearchStateType searchState; MemHandle hRecord; if ((err = DmGetNextDatabaseByTypeCreator( true, &searchState, 'data', CREATORID, true, &cardNo, &dbID)) != errNone) { return; } if ((dbP = DmOpenDatabase(cardNo, dbID, dmModeReadOnly)) == 0) { return; } if (!(hRecord = DmQueryRecord(dbP, pGoToParams->recordNum))) { DmCloseDatabase(dbP); return; } Char * p = (char *)MemHandleLock(hRecord); UInt32 size = MemHandleSize(hRecord); if (p[size - 1] == '\0') { --size; } emptyScript(); appendScript(p, size); MemHandleUnlock(hRecord); DmCloseDatabase(dbP); return; }
/** * FUNCTION: smGetSize * * Get size of memory block memH. * * PRE-Condition: memH is a valid handle * * POST-Condition: actSize = memory block size * * IN: memH * Handle to memory block * * OUT: actSize * Actual size of memory block * * RETURN: SML_ERR_OK, if O.K. * SML_ERR_WRONG_PARAM, if memH is unknown * * @see smSetSize */ Ret_t smGetSize (MemHandle_t memH, MemSize_t *actSize) { if ( memH != smMemH ) { return SML_ERR_WRONG_PARAM; } *actSize = MemHandleSize((VoidHand)smPalmH); return SML_ERR_OK; }
// Open preferences database and find a record that contains preferences. // Return errNone if opened succesfully, otherwise an error: // psErrNoPrefDatabase - pref database couldn't be found // devnote: it scans through all records even though we only store preferences // in one record because I want to be able to use preferences database used // in earlier versions of Noah Pro/Thes. Err PrefsStoreReader::ErrOpenPrefsDatabase() { if (_db) { Assert(_recHandle); Assert(_recData); return errNone; } // we already tried to open the database but couldn't, so don't try again if (_fDbNotFound) return psErrNoPrefDatabase; LocalID dbId; Err err = ErrFindDatabaseByNameTypeCreator(_dbName, _dbType, _dbCreator, &dbId); if (dmErrCantFind==err) { err = psErrNoPrefDatabase; goto ExitAndMarkNotFound; } if (err) goto ExitAndMarkNotFound; Assert(0!=dbId); _db = DmOpenDatabase(0, dbId, dmModeReadWrite); if (!_db) { err = DmGetLastErr(); Assert(err); goto ExitAndMarkNotFound; } UInt16 recsCount = DmNumRecords(_db); for (UInt16 recNo = 0; recNo < recsCount; recNo++) { _recHandle = DmQueryRecord(_db, recNo); _recData = (unsigned char*)MemHandleLock(_recHandle); if ( (MemHandleSize(_recHandle)>=4) && FValidPrefsStoreRecord(_recData) ) { // we found the record with prefernces so remember _recData and _recHandle // those must be freed in destructor return errNone; } MemHandleUnlock(_recHandle); _recHandle = NULL; } DmCloseDatabase(_db); _db = 0; err = psErrNoPrefDatabase; ExitAndMarkNotFound: _fDbNotFound = true; return err; }
/************************************************************************** * Function: getSystemFromIndex * Description: based upon a system database index, this will locate the * system for that index, unpack and decrypt it and initialize s * ************************************************************************/ void getSystemFromIndex (DmOpenRef SystemDB, md_hash * SysPass, UInt16 index, MemHandle tmp, System * s) { MemHandle rec = DmQueryRecord (SystemDB, index); if (rec) { MemPtr scratch, buff = MemHandleLock (rec); /* resize the buffer */ if (MemHandleResize (tmp, MemPtrSize (buff)) == 0) { scratch = MemHandleLock (tmp); /* unpack and decrypt the account */ UnpackSystem (s, buff, scratch, SysPass, MemHandleSize (rec), true); } MemHandleUnlock (rec); } }
// Function loads a resource with specified name resource_p resourceLoad(const char* name) { resource_p resource = NULL; MemHandle handle = NULL; ASSERT(NULL != name, "resourceLoad"); resource = resourceFind(name); if (NULL == resource) { handle = resourceOpen(name); if (NULL == handle) { THROW("resourceLoad", appErrResourceNotFound); } TRY { resource = (resource_p)objectCreate( sizeof(*resource), (destructor_f)resourceDestroy); resource->handle = handle; resource->memory = (const void*)MemHandleLock( handle); resource->size = MemHandleSize(handle); if (NULL != resourcesList) { resource->prev = NULL; resource->next = resourcesList; resourcesList->prev = resource; } resourcesList = resource; resource = resourceRetain(resource); } CATCH { MemHandleUnlock(handle); RETHROW(); } END; resource = resourceAutorelease(resource); }
/************************************************************************** * Function: getAccountFromIndex * Description: based upon an account index, this will locate the * account for that index, unpack and decrypt it and initialize acc * ************************************************************************/ void getAccountFromIndex (DmOpenRef AccountDB, md_hash * SysPass, UInt16 index, MemHandle tmp, Account * acc) { /* query the record from the database */ MemHandle rec = DmQueryRecord (AccountDB, index); if (rec){ MemPtr scratch, buff = MemHandleLock (rec); /* resize buffer */ if (MemHandleResize (tmp, MemPtrSize (buff)) == 0) { scratch = MemHandleLock (tmp); /* unpack the account */ UnpackAccount (acc, buff, scratch, SysPass, MemHandleSize (rec), true, true); } MemHandleUnlock (rec); } }
/*-------------------------------------CIRexxApp::copyScriptFromIndexDatabase-+ | | +----------------------------------------------------------------------------*/ void CIRexxApp::copyScriptFromIndexDatabase(Int16 index) { Int16 count; UInt32 dbptr; ScriptRecord sr; CDBStream dbs(m_scriptIndexDB->QueryRecord(index)); dbs >> sr.m_title; dbs >> sr.m_dbi; dbs >> dbptr; sr.m_db = (CDatabase *)dbptr; dbs >> count; sr.m_indexes.EnsureSize(count); sr.m_segments.EnsureSize(count); for (int i = 0; i < count; ++i) { Int16 value1, value2; dbs >> value1 >> value2; sr.m_indexes.Insert(i, value1); sr.m_segments.Insert(i, value2); } emptyScript(); bool isSegmented = count > 1; for (Int16 i = 0; i < count; ++i) { MemHandle hMem = sr.m_db->QueryRecord(sr.m_indexes[i]); char * script = (char *)MemHandleLock(hMem); UInt32 size = MemHandleSize(hMem); if (isSegmented) { char * realScript = strstr( script, "!DO NOT TOUCH THIS LINE OR ABOVE!" ); if (realScript) { realScript += 34; size -= (realScript - script); script = realScript; } } if (script[size - 1] == '\0') { --size; } appendScript(script, size); MemHandleUnlock(hMem); } return; }
static Int16 LoadSMF(SndMidiListItemType midi, NoteListPtr list) { Err err = false; DmOpenRef dbP; UInt16 recIndex; MemHandle midiH; debugPrintf("LoadSMF: open db cardNo=%d dbID=%d for readOnly\n", midi.cardNo, midi.dbID); dbP = DmOpenDatabase (midi.cardNo, midi.dbID, dmModeReadOnly); if (!dbP) err = true; if (!err) err = DmFindRecordByID(dbP, midi.uniqueRecID, &recIndex); debugPrintf("LoadSMF: find record with uniqueRecID=%ld\n", midi.uniqueRecID); if (!err) { midiH = DmQueryRecord (dbP, recIndex); if (!midiH) err = true; } debugPrintf("LoadSMF: midiH=%lx size=%ld\n", midiH, MemHandleSize(midiH)); if (!err) smfutils_load(midiH, list); if (dbP) DmCloseDatabase (dbP); if (err) ErrDisplay ("LoadSMF(): error occure in function."); return true; }
/************************************************************************* * Function: replaceAccountHash * Description: regernate the hash on a single account based on account * index * ***********************************************************************/ void replaceAccountHash(UInt16 index, DmOpenRef db, md_hash * SysPass) { Account ac; MemHandle rH; MemPtr pac = NULL, scratch = NULL, scratch2=NULL; if ((rH = DmGetRecord (db, index))) { pac = MemHandleLock (rH); if ((scratch = MemPtrNew (MemPtrSize (pac)))) { UnpackAccount (&ac, pac, scratch, SysPass, MemHandleSize (rH), true, true); if ((scratch2 = MemPtrNew (MemPtrSize (pac)))) { MemMove(ac.hash, generateAccountHash(&ac), sizeof(md_hash)); PackAccount (scratch2, ac, SysPass, true); writeRecord(scratch2, rH); } } MemPtrFree(scratch); MemPtrFree(scratch2); MemHandleUnlock (rH); DmReleaseRecord (db, index, true); } }
int AppendField( FieldPtr fld, CharPtr str, UInt len ) { Err err=0; CharPtr s; VoidHand h; UInt prevlen; h=(VoidHand)FldGetTextHandle(fld); if(h==NULL) { h=MemHandleNew(len+1); if(h==NULL) return(-1); s=MemHandleLock(h); StrNCopy(s, str, len); s[len]=0; MemHandleUnlock(h); } else { prevlen=FldGetTextLength(fld); FldSetTextHandle(fld, NULL); if( MemHandleSize(h)<=(prevlen+len)) { err=MemHandleResize( h, prevlen+len+1 ); } if( err!=0 ) return(-1); s=MemHandleLock(h); StrNCopy(s+prevlen, str, len); s[len+prevlen]=0; MemHandleUnlock(h); } FldSetTextHandle(fld, (Handle)h); /* FldDrawField(fld); */ return( 0 ); }
/* ** Initiates transfer mode. */ void StartXferMode(void) { FormType* frm = FrmGetActiveForm(); FieldType* fld = GetObjectPointer(frm, XferField); const UInt32 len = MemHandleSize(d.record_name); MemHandle textH = MemHandleNew(len); ASSERT(textH); FlushToBuffer(); FrmSetMenu(frm, XferMenu); d.is_xfer_mode = true; ToggleButtonBar(frm, false); ResetDrawingAreaRectangle(p.formID == DiddleTForm, true); FrmUpdateForm(p.formID, 0); InitXferList(); ToggleXferBar(frm, true); FrmSetFocus(frm, FrmGetObjectIndex(frm, XferField)); /* Init field with record title */ MemMove(MemHandleLock(textH), MemHandleLock(d.record_name), len); MemHandleUnlock(textH); MemHandleUnlock(d.record_name); FldSetTextHandle(fld, textH); }
/*-----------------------------------------------CIRexxApp::addRecordsToIndex-+ | | +----------------------------------------------------------------------------*/ void CIRexxApp::addRecordsToIndex(CArray<ScriptRecord *> & records, CDatabase * db, UInt16 cat, char * dbi) { UInt16 index = 0; UInt32 rowId; MemHandle hMem; Int16 recordPosition = 0; CHash<unsigned int, Int16> recordPositionBySegmentId; ScriptRecord * scriptRecord; if (db == 0) { return; } while ((hMem = db->QueryNextInCategory(index, cat))) { db->GetRecordUniqueID(index, rowId); UInt32 size = MemHandleSize(hMem); const char * pMem = (char *)MemHandleLock(hMem); /* | FORMAT: | %6s #segment.<no>#\ndate() time() <id>\nTitle: <tit>\nCategory: <cat> */ char * scanner; if ( // if it's segmented, combine the segments (scanner = StrStr(pMem, "#segment.")) && (scanner = StrChr(scanner + 1, '#')) ) { char segmentNoAsString[5]; memcpy(segmentNoAsString, scanner - 4, 4); segmentNoAsString[4] = '\0'; int segmentNo = StrAToI(segmentNoAsString); ++scanner; int peditHeaderSize = size - (scanner - pMem); if (peditHeaderSize > ScriptRecord::MAX_PEDITHEADERLEN) { peditHeaderSize = ScriptRecord::MAX_PEDITHEADERLEN; } RexxString header(scanner, peditHeaderSize); RexxString segmentIdAsString; segmentIdAsString.wordAt(header, 3); unsigned int segmentId = hex2uint( (char const *)segmentIdAsString, segmentIdAsString.length() ); int titWordNo = RexxString("Title:").wordpos(header, 1); int catWordNo = RexxString("Category:").wordpos(header, 1); RexxString title; title.subword(header, titWordNo + 1, catWordNo - (titWordNo + 1)); // create the script record Int16 * psegmentedRecordPosition = (Int16 *)recordPositionBySegmentId.Lookup(segmentId); // if this segment has already been encountered, then create a chain of segments if (psegmentedRecordPosition) { ScriptRecord * sr = records[*psegmentedRecordPosition]; sr->m_indexes.Insert(sr->m_indexes.GetCount(), index); sr->m_segments.Insert(sr->m_segments.GetCount(), segmentNo); // otherwise just add it }else { scriptRecord = new ScriptRecord(db, dbi, title, index, segmentNo); recordPositionBySegmentId.SetAt(segmentId, recordPosition); records.Insert(recordPosition++, scriptRecord); } }else { // otherwise just add it unsigned int i; for (i=0; pMem[i] && pMem[i] != linefeedChr && i < ScriptRecord::MAX_TITLELEN; ++i) { ; } char * t = new char[i + 1]; memcpy(t, pMem, i); t[i] = '\0'; RexxString title(t); scriptRecord = new ScriptRecord(db, dbi, title, index); delete [] t; records.Insert(recordPosition++, scriptRecord); } MemHandleUnlock(hMem); ++index; } }
/* Delete bookmark, return true if list is empty */ void DeleteBookmark ( UInt16 index /* index in bookmarks list */ ) { BookmarkData bookmarkData; MemHandle handle; UInt16 entries; UInt16 offset; UInt16 tempOffset; UInt16 newSize; UInt16 nameLength; UInt16 i; UInt8* bookmarkPtr; UInt8* readPtr; handle = ReturnMetaHandle( INTERNAL_BOOKMARKS_ID, NO_PARAGRAPHS ); if ( handle == NULL ) return; bookmarkPtr = MemHandleLock( handle ); entries = GET_ENTRIES( bookmarkPtr ); if ( entries <= 1 ) { MemHandleUnlock( handle ); ReleaseBookmarkList(); RemoveBookmarkRecord(); return; } /* Find name string for bookmark */ readPtr = bookmarkPtr + BOOKMARK_HEADER_LEN; for ( i = 0; i < index; i++ ) readPtr += StrLen( readPtr ) + 1; tempOffset = readPtr - bookmarkPtr; nameLength = StrLen( readPtr ) + 1; readPtr += nameLength; for ( i = 0; i < entries - index - 1; i++ ) { UInt16 length; Char tempString[ MAX_BOOKMARK_LEN + 1 ]; MemMove( tempString, readPtr, StrLen( readPtr ) + 1 ); length = StrLen( tempString ) + 1; DmWrite( bookmarkPtr, tempOffset, tempString, length ); tempOffset += length; readPtr += length; } /* Reshuffle blocks with bookmark data */ offset = GET_OFFSET( bookmarkPtr ); readPtr = bookmarkPtr + offset; for ( i = 0; i < index; i++ ) { MemMove( &bookmarkData, readPtr, sizeof( BookmarkData ) ); DmWrite( bookmarkPtr, tempOffset, &bookmarkData, sizeof( BookmarkData ) ); tempOffset += sizeof( BookmarkData ); readPtr += sizeof( BookmarkData ); } readPtr += sizeof( BookmarkData ); for ( i = index + 1; i < entries; i++ ) { MemMove( &bookmarkData, readPtr, sizeof( BookmarkData ) ); DmWrite( bookmarkPtr, tempOffset, &bookmarkData, sizeof( BookmarkData ) ); tempOffset += sizeof( BookmarkData ); readPtr += sizeof( BookmarkData ); } entries--; DmWrite( bookmarkPtr, sizeof( UInt16 ), &entries, sizeof( UInt16 ) ); offset -= nameLength; DmWrite( bookmarkPtr, 2 * sizeof( UInt16 ), &offset, sizeof( UInt16 ) ); newSize = MemHandleSize( handle ) - sizeof( BookmarkData ) - nameLength; MemHandleUnlock( handle ); ResizeMetaRecord( INTERNAL_BOOKMARKS_ID, newSize, &handle ); }
/* Add data for bookmark */ void AddBookmark ( Char* name /* name of bookmark */ ) /* THROWS */ { MetaRecord* meta; BookmarkData bookmarkData; UInt8* bookmarkPtr; MemHandle handle; UInt32 endOfRecord; UInt16 entries; UInt16 offset; UInt16 newSize; UInt16 nameLength; UInt16 i; THROW_IF( name == NULL || *name == '\0', errNoBookmarkName ); handle = ReturnMetaHandle( INTERNAL_BOOKMARKS_ID, NO_PARAGRAPHS ); if ( handle == NULL ) AddBookmarkRecord( &handle ); endOfRecord = MemHandleSize( handle ); TrimText( name, BOOKMARKLISTWIDTH ); nameLength = StrLen( name ) + 1; newSize = endOfRecord + sizeof( BookmarkData ) + nameLength; ResizeMetaRecord( INTERNAL_BOOKMARKS_ID, newSize, &handle ); bookmarkPtr = MemHandleLock( handle ); entries = GET_ENTRIES( bookmarkPtr ) + 1; offset = GET_OFFSET( bookmarkPtr ) + nameLength; DmWrite( bookmarkPtr, sizeof( UInt16 ), &entries, sizeof( UInt16 ) ); DmWrite( bookmarkPtr, 2 * sizeof( UInt16 ), &offset, sizeof( UInt16 ) ); meta = MemHandleLock( GetMetaRecord() ); bookmarkData.verticalOffset = meta->verticalOffset; bookmarkData.characterPosition = meta->characterPosition; bookmarkData.firstVisibleParagraph = meta->firstVisibleParagraph; bookmarkData.firstParagraphY = meta->firstParagraphY; #ifdef STORE_LAST_VISIBLE bookmarkData.lastVisibleParagraph = meta->lastVisibleParagraph; bookmarkData.lastParagraphY = meta->lastParagraphY; #endif bookmarkData.recordId = GetHistoryCurrent(); /* Write new block of bookmark data */ DmWrite( bookmarkPtr, endOfRecord + nameLength, &bookmarkData, sizeof( BookmarkData ) ); endOfRecord -= sizeof( BookmarkData ); /* Reshuffle old blocks with bookmark data */ for ( i = 1; i < entries; i++ ) { MemMove( &bookmarkData, bookmarkPtr + endOfRecord, sizeof( BookmarkData ) ); DmWrite( bookmarkPtr, endOfRecord + nameLength, &bookmarkData, sizeof( BookmarkData ) ); endOfRecord -= sizeof( BookmarkData ); } /* Write new bookmark name */ DmStrCopy( bookmarkPtr, offset - nameLength, name ); MemHandleUnlock( GetMetaRecord() ); MemHandleUnlock( handle ); }
// Save preferences previously set via ErrSet*() calls to a database. // If something goes wrong, returns an error // Possible errors: // memErrNotEnoughSpace - not enough memory to allocate needed structures // errors from Dm*() calls Err PrefsStoreWriter::ErrSavePreferences() { Err err = errNone; long blobSize; void * prefsBlob = SerializeItems(_items, _itemsCount, &blobSize); if ( NULL == prefsBlob ) return memErrNotEnoughSpace; DmOpenRef db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) { err = DmCreateDatabase(0, _dbName, _dbCreator, _dbType, false); if ( err) return err; db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) return DmGetLastErr(); } // set backup bit on the database. code adapted from DataStore.cpp // DataStore::open() if (errNone == err) { LocalID localId; UInt16 cardNo; UInt16 attribs; err = DmOpenDatabaseInfo(db, &localId, NULL, NULL, &cardNo, NULL); if (errNone != err) goto Continue; err = DmDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (errNone != err) goto Continue; if (0 != attribs & dmHdrAttrBackup) goto Continue; attribs |= dmHdrAttrBackup; err = DmSetDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); Continue: err = errNone; } UInt16 recNo = 0; UInt16 recsCount = DmNumRecords(db); MemHandle recHandle; Boolean fRecordBusy = false; Boolean fRecFound = false; void * recData; long recSize; while (recNo < recsCount) { recHandle = DmGetRecord(db, recNo); fRecordBusy = true; recData = MemHandleLock(recHandle); recSize = MemHandleSize(recHandle); if (IsValidPrefRecord(recData)) { fRecFound = true; break; } MemPtrUnlock(recData); DmReleaseRecord(db, recNo, true); fRecordBusy = false; ++recNo; } if (fRecFound && blobSize>recSize) { /* need to resize the record */ MemPtrUnlock(recData); DmReleaseRecord(db,recNo,true); fRecordBusy = false; recHandle = DmResizeRecord(db, recNo, blobSize); if ( NULL == recHandle ) return DmGetLastErr(); recData = MemHandleLock(recHandle); Assert( MemHandleSize(recHandle) == blobSize ); } if (!fRecFound) { recNo = 0; recHandle = DmNewRecord(db, &recNo, blobSize); if (!recHandle) { err = DmGetLastErr(); goto CloseDbExit; } recData = MemHandleLock(recHandle); fRecordBusy = true; } err = DmWrite(recData, 0, prefsBlob, blobSize); MemPtrUnlock(recData); if (fRecordBusy) DmReleaseRecord(db, recNo, true); CloseDbExit: // if had error before - preserve that error // otherwise return error code from DmCloseDatabase() if (err) DmCloseDatabase(db); else err = DmCloseDatabase(db); new_free( prefsBlob ); return err; }
// devnote: not very optimal implementation, we reparse the blob every // time. We could deserialize things once and store in a buffer or optimize for // a common pattern: reading in the same sequence as the data was written in which // case we could remember the current place in the blob and start from there when // we're called again (and re-start from the beginning if we don't find data) Err PrefsStoreReader::ErrGetPrefItemWithId(int uniqueId, PrefItem *prefItem) { Assert(uniqueId>=0); Assert(prefItem); Err err = ErrOpenPrefsDatabase(); if (err) return err; Assert(_db); Assert(_recHandle); Assert(_recData); // usually when we Assert() we don't error out on the same condition // but in this case, while highly improbably, it's conceivable that some // other app created a database with the same name, creator, type and a // record that has the same magic header and we don't want to crash // in this case long recSizeLeft = (long)MemHandleSize(_recHandle); Assert(recSizeLeft>=4); if (recSizeLeft<4) return psErrDatabaseCorrupted; const unsigned char *currData = _recData; Assert(FValidPrefsStoreRecord(currData)); // skip the header currData += 4; recSizeLeft-=4; while(recSizeLeft!=0) { // get unique id and type Assert(recSizeLeft>=2); if (recSizeLeft<2) return psErrDatabaseCorrupted; int id = deserInt(&currData,&recSizeLeft); Assert(id>=0); Assert(recSizeLeft>=2); if (recSizeLeft<2) return psErrDatabaseCorrupted; PrefItemType type = (PrefItemType)deserInt(&currData,&recSizeLeft); switch (type) { case pitBool: Assert(recSizeLeft>=1); if (recSizeLeft<1) return psErrDatabaseCorrupted; prefItem->value.boolVal = deserBool(&currData,&recSizeLeft); break; case pitInt: Assert(recSizeLeft>=sizeof(int)); if (recSizeLeft<sizeof(int)) return psErrDatabaseCorrupted; prefItem->value.intVal = deserInt(&currData, &recSizeLeft); break; case pitLong: Assert(recSizeLeft>=sizeof(long)); if (recSizeLeft<sizeof(long)) return psErrDatabaseCorrupted; prefItem->value.longVal = deserLong(&currData, &recSizeLeft); break; case pitUInt16: Assert(recSizeLeft>=sizeof(UInt16)); if (recSizeLeft<sizeof(UInt16)) return psErrDatabaseCorrupted; prefItem->value.uint16Val = deserUInt16(&currData, &recSizeLeft); break; case pitUInt32: Assert(recSizeLeft>=sizeof(UInt32)); if (recSizeLeft<sizeof(UInt32)) return psErrDatabaseCorrupted; prefItem->value.uint32Val = deserUInt32(&currData, &recSizeLeft); break; case pitStr: prefItem->value.strVal = deserStringInPlace(&currData, &recSizeLeft); if(NULL==prefItem->value.strVal) return psErrDatabaseCorrupted; break; default: Assert(0); return psErrDatabaseCorrupted; } if (id==uniqueId) { prefItem->uniqueId=id; prefItem->type=type; return errNone; } } return psErrItemNotFound; }
/*************************************************************************** * Function: cryptSwitch * Description: handles changing the system password based upon the * password change screen. Basically checks that current password is correct, * checks that the new password was entered correctly, then re-encrypts the * databases based upon the new password. * ************************************************************************/ static void cryptSwitch (int v) { // total number of records to re-write UInt16 totalAItems = DmNumRecordsInCategory (AccountDB, dmAllCategories); UInt16 totalSItems = DmNumRecordsInCategory (SystemDB, dmAllCategories); MemPtr pac = NULL, scratch = NULL, scratch2 = NULL; UInt16 i = 0, senc = 0, aenc = 0; MemHandle rH; char s[5], a[5]; StripPrefType prefs; UInt16 prefsSize, prefsVersion; FormType *preF = FrmGetActiveForm (); FormType *f = FrmInitForm (pleaseWait); FrmDrawForm (f); // re-encrypt the password if ((rH = DmGetRecord (PasswordDB, 0))) { if ((scratch = MemPtrNew (getSCSize(sizeof(md_hash))))) { PackPassword (scratch, &NewSysPass); writeRecord (scratch, rH); MemPtrFree (scratch); } DmReleaseRecord (PasswordDB, 0, true); } // loop through the systems and re-encrypt for (i = 0; i < totalSItems; i++) { System_old sys; if ((rH = DmGetRecord (SystemDB, i))) { pac = MemHandleLock (rH); if ((scratch = MemPtrNew (MemPtrSize (pac)))) { // decrypt the system with old password switch (v) { case 0: UnpackSystem_old (&sys, pac, scratch, SysPass, MemHandleSize (rH), true, 1); scratch2 = MemPtrNew (getSystemSize((System *)&sys, true)); break; case 1: UnpackSystem_old (&sys, pac, scratch, SysPass, MemHandleSize (rH), true, 2); scratch2 = MemPtrNew (getSystemSize ((System *)&sys,true) ); break; case 2: UnpackSystem_old (&sys, pac, scratch, SysPass, MemHandleSize (rH), true, 0); scratch2 = MemPtrNew (getSystemSize ((System *)&sys, true )); break; } if (scratch2) { PackSystem(scratch2, *((System *) &sys), &NewSysPass, true); MemHandleUnlock (rH); writeRecord (scratch2, rH); senc++; MemPtrFree (scratch2); } MemPtrFree (scratch); } DmReleaseRecord (SystemDB, i, true); } } // loop through the accounts and re-encrypt for (i = 0; i < totalAItems; i++) { Account_old ac; Account ac_new; if ((rH = DmGetRecord (AccountDB, i))) { pac = MemHandleLock (rH); if ((scratch = MemPtrNew (MemPtrSize (pac)))) { // decrypt the system with old password switch (v) { case 0: UnpackAccount_old(&ac, pac, scratch, SysPass, MemHandleSize (rH), true, true, 1); ChangeAccountFormat(i, &ac, &ac_new); scratch2 = MemPtrNew (getAccountSize(&ac_new, true)); break; case 1: UnpackAccount_old (&ac, pac, scratch, SysPass, MemHandleSize (rH), true, true, 2); ChangeAccountFormat(i, &ac, &ac_new); scratch2 = MemPtrNew (getAccountSize(&ac_new, true)); break; case 2: UnpackAccount_old(&ac, pac, scratch, SysPass, MemHandleSize (rH), true, true, 0); ChangeAccountFormat(i, &ac, &ac_new); scratch2 = MemPtrNew (getAccountSize(&ac_new,true)); break; } if (scratch2) { PackAccount(scratch2, ac_new, &NewSysPass, true); MemHandleUnlock (rH); writeRecord (scratch2, rH); aenc++; MemPtrFree (scratch2); } MemPtrFree (scratch); } DmReleaseRecord (AccountDB, i, true); } } FrmEraseForm (f); FrmDeleteForm (f); FrmSetActiveForm (preF); // close databases. DmCloseDatabase (SystemDB); DmCloseDatabase (AccountDB); DmCloseDatabase (PasswordDB); { UInt16 cardNo; UInt32 type; LocalID dbID; DmSearchStateType search; type = systemDBType; DmGetNextDatabaseByTypeCreator(true, &search, systemDBTypeOld, StripCreator, true, &cardNo, &dbID); DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &type, NULL); type = accountDBType; DmGetNextDatabaseByTypeCreator(true, &search, accountDBTypeOld, StripCreator, true, &cardNo, &dbID); DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &type, NULL); type = passwordDBType; DmGetNextDatabaseByTypeCreator(true, &search, passwordDBTypeOld, StripCreator, true, &cardNo, &dbID); DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &type, NULL); } prefsSize = sizeof (StripPrefType); prefsVersion = PrefGetAppPreferences (StripCreator, StripPrefID, &prefs, &prefsSize, true); if (prefsVersion != StripVersionNumber) { prefs.smart_beaming = false; PrefSetAppPreferences (StripCreator, StripPrefID, StripVersionNumber, &prefs, sizeof (StripPrefType), true); prefsVersion = PrefGetAppPreferences (StripCreator, StripPrefID, &prefs, &prefsSize, true); } StrIToA (s, senc); StrIToA (a, aenc); FrmCustomAlert (infoDialog, s, a, NULL); StopApplication (); SysReset (); }