/* Create an app info chunk if missing, return result from the database call */ static void InitPlkrAppInfo ( DmOpenRef docRef /* reference to document */ ) /* THROWS */ { UInt16 cardNo; MemHandle handle; LocalID dbID; LocalID appInfoID; PlkrAppInfoType* appInfoP; Err err; err = DmOpenDatabaseInfo( docRef, &dbID, NULL, NULL, &cardNo, NULL ); THROW_IF( err != errNone, err ); err = DmDatabaseInfo( cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL ); THROW_IF( err != errNone, err ); if ( appInfoID == 0 ) { handle = DmNewHandle( docRef, sizeof *appInfoP ); THROW_IF( handle == NULL, dmErrMemError ); appInfoID = MemHandleToLocalID( handle ); DmSetDatabaseInfo( cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL ); } appInfoP = MemLocalIDToLockedPtr( appInfoID, cardNo ); DmSet( appInfoP, 0, sizeof *appInfoP, 0 ); CategoryInitialize( ( AppInfoPtr ) appInfoP, strCatDefault ); MemPtrUnlock( appInfoP ); }
/********************************************************************** * Function: getDatabase * Description: pass the function the necessare database information, * and it will either open an existing database or create a new one if * neccessary. "created" will be true if a new database was created * *******************************************************************/ Err getDatabaseByTypeCreatorName (DmOpenRef * DBptr, UInt32 type, UInt32 creator, UInt32 mode, char *name) { Err errors; LocalID id; UInt16 cardNum, attr; DmSearchStateType srch; Char db_name[32]; errors = DmGetNextDatabaseByTypeCreator(true, &srch, type, creator, false, &cardNum, &id); while(!errors && id) { *DBptr = DmOpenDatabase (cardNum, id, mode); DmDatabaseInfo (cardNum, id, db_name, &attr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if(StrCompare(name, db_name) == 0) { attr |= dmHdrAttrBackup; DmSetDatabaseInfo (cardNum, id, NULL, &attr, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); return 0; } if(*DBptr) DmCloseDatabase(*DBptr); errors = DmGetNextDatabaseByTypeCreator(false, &srch, type, creator, false, &cardNum, &id); } return 1; }
/* Create database for list of documents */ static void CreateDocList( void ) /* THROWS */ { UInt16 cardNo; Err err; LocalID dbID; UInt16 version; /* list is always put on first card in RAM */ cardNo = 0; err = errNone; err = DmCreateDatabase( cardNo, PlkrDocListName, ViewerAppID, PlkrDocListType, false ); THROW_IF( err != errNone, memErrNotEnoughSpace ); dbID = DmFindDatabase( cardNo, PlkrDocListName ); version = PlkrDocListVersion; err = DmSetDatabaseInfo( cardNo, dbID, NULL, NULL, &version, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); plkrDocList = DmOpenDatabaseByTypeCreator( PlkrDocListType, ViewerAppID, dmModeReadWrite ); ErrTry { InitPlkrAppInfo( plkrDocList ); } ErrCatch( UNUSED_PARAM( err ) ) { LocalID dbID; DmOpenDatabaseInfo( plkrDocList, &dbID, NULL, NULL, &cardNo, NULL ); CloseDatabase( plkrDocList ); DmDeleteDatabase( cardNo, dbID ); MSG( "Couldn't initialize Plkr document list [ appInfo ]\n" ); ErrThrow( memErrNotEnoughSpace ); } ErrEndCatch }
/*********************************************************************** * * FUNCTION: ReceiveDatabase * * DESCRIPTION: Receives data in the input field using the Exg API * * RETURNED: error code or zero for no error. * ***************************************************************************/ static Err ReceiveDatabase (ExgSocketPtr exgSocketP) { Err err; LocalID dbID; UInt16 cardNo = 0; Boolean *needResetP = NULL; Boolean keepDates = false; char outName [32]; char appName [32]; int bytesSent = -1; LocalID app_dbID; // Create exgSocket structure MemSet(exgSocketP, sizeof(exgSocketP->length), 0); // Start and exchange put operation err = ExgAccept(exgSocketP); if (!err){ // Receive the DB name we fix it at 32 bytes bytesSent = ExgReceive(exgSocketP, outName, 32, &err); if(bytesSent != 32){ return err; } // Receive the DB name we fix it at 32 bytes bytesSent = ExgReceive(exgSocketP, appName, 32, &err); if(bytesSent != 32){ return err; } // Receive the database err = ExgDBRead(ReadDBData, DeleteExistingDB, exgSocketP, &dbID, cardNo, needResetP, keepDates); /* exgSocketP->goToCreator = 'CCPr'; exgSocketP->noGoTo = 0; */ // Disconnect Exg and pass error err = ExgDisconnect(exgSocketP, err); // Try to rename the database to the outName if(StrLen(outName) > 0){ /* UInt cardNo, LocalID dbID, CharPtr nameP, UIntPtr attributesP, UIntPtr versionP, ULongPtr crDateP, ULongPtr modDateP, ULongPtr bckUpDateP, ULongPtr modNumP, LocalID* appInfoIDP, LocalID* sortInfoIDP, ULongPtr typeP, ULongPtr creatorP); */ DmSetDatabaseInfo(cardNo, dbID, outName, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } if (!err && StrLen(appName) > 0) { // Find the database app_dbID = DmFindDatabase(0, appName); if(app_dbID != 0) { SysUIAppSwitch(0, app_dbID, sysAppLaunchCmdNormalLaunch, NULL); } } } /****************************************************************************/ return err; }
/*************************************************************************** * 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 (); }
// 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; }