Exemple #1
0
UInt16 OpenPrefsDatabase(void) {
  JMPalmPrefs = DmOpenDatabaseByTypeCreator(JMPalmPrefsType, JMPalmAppID,
					    dmModeReadWrite);

  // the database doesn't exist
  if (!JMPalmPrefs) {
    MemHandle foo;
    UInt16 position = 1;

    if (DmCreateDatabase(0, JMPalmPrefsName,
			 JMPalmAppID, JMPalmPrefsType, false))
      return true;
    
    JMPalmPrefs = DmOpenDatabaseByTypeCreator(JMPalmPrefsType, JMPalmAppID,
					      dmModeReadWrite);
		 		 
    ResetHeader();
    
    // create dummy record
    foo = DmNewRecord(JMPalmPrefs, &position, sizeof(headerdata));
    DmReleaseRecord(JMPalmPrefs, position, true);
    WriteHeader();

    // Do some special handling for the first run of the application
    HandleFirstRun();
  }

  return false;
}
Exemple #2
0
/*
** Handle Security command
*/
static void ThumbnailDoCmdSecurity(void) {
  FormType* frm = FrmGetActiveForm();
  Boolean wasHiding = d.privateRecordStatus == hidePrivateRecords;
  UInt16 mode;

  d.privateRecordStatus = SecSelectViewStatus();

  if (wasHiding ^ (d.privateRecordStatus == hidePrivateRecords)) {
    /* We have to close the database first */
    if (DmCloseDatabase(d.dbR) != errNone) abort();

    mode = dmModeReadWrite;
    if (d.privateRecordStatus != hidePrivateRecords)
      mode |= dmModeShowSecret;

    /* Re-open the database */
    if ((d.dbR = DmOpenDatabaseByTypeCreator(DBType, AppType, mode)) == NULL)
      abort();

    /* Update cached values */
    d.records_in_cat = DmNumRecordsInCategory(d.dbR, p.category);
    if (d.privateRecordStatus == hidePrivateRecords)
      SetTopVisibleRecord(0);

    ThumbnailViewLoadRecords (frm);
  }
}
Exemple #3
0
/*
 * OpenIconSet - returns a DmOpenRef to an icon set
 *
 * Arguments:
 *  name            = Optional name of icon set to open (can be NULL).
 *  canUseDefault   = Indicates if it's ok to open a default icon set if
 *                    the named icon set isn't available.
 *
 * Returns:
 *  NULL            = Unable to open an icon set.
 *  non-NULL        = DmOpenRef to the icon set database.
 *
 * Remarks:         If OpenIconSet() returns a valid DmOpenRef, the caller
 *                  is required to call DmCloseDatabase() to close it when
 *                  the caller is finished with it.
 */
DmOpenRef OpenIconSet(const Char *name, Boolean canUseDefault)
{
    DmOpenRef pdb = 0;

    // If 'name' was specified, try to open it.

    if (name && *name)
    {
        const UInt16 card = 0;
        const LocalID lid = DmFindDatabase(card, name);

        if (lid)
        {
            UInt32 type;
            UInt32 creator;

            // Double check the type and creator.

            DmDatabaseInfo(card, lid, 0, 0, 0, 0, 0, 0, 0, 0, 0, &type, &creator);

            if ('Rsrc' == type && 'Actn' == creator)
                pdb = DmOpenDatabase(card, lid, dmModeReadOnly);
        }
    }

    // Fall back to the default icon set if we need to.

    if (!pdb && canUseDefault)
        pdb = DmOpenDatabaseByTypeCreator('Rsrc', 'Actn', dmModeReadOnly);

    // At this point we may or may not have been able to open an icon set.
    // The return value may be NULL or it may point to an icon set.

    return pdb;
}
Exemple #4
0
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);
}
Exemple #5
0
/* DESCRIPTION:  Get the application's database.  Open the database if it
 * exists, create it if neccessary.
 *
 * PARAMETERS:   *dbPP - pointer to a database ref (DmOpenRef) to be set
 *					  mode - how to open the database (dmModeReadWrite)
 *
 * RETURNED:     Err - zero if no error, else the error
 */
static Err getPalmanoDatabase (DmOpenRef *dbPP, UInt16 mode)
{
  Err error = 0;
  DmOpenRef dbP;

  *dbPP = NULL;
  
  // Find the application's data file.  If it doesn't exist create it.
  dbP = DmOpenDatabaseByTypeCreator (sysFileTMidi, pmnoCreatorDB, mode);

  if (!dbP) {
    debugPrintf("getPalmanoDatabase(): Can't open database, code %d\n",
		DmGetLastErr());
    error = DmCreateDatabase (0, "palmano", pmnoCreatorDB, sysFileTMidi, false);

    if (error) {
      debugPrintf("getPalmanoDatabase(): DmCreateDatabase exit code %d\n", error);
      ErrAlert(error);
      return error;
    }
    else
      debugPrintf("getPalmanoDatabase(): create DB ok\n");

    dbP = DmOpenDatabaseByTypeCreator(sysFileTMidi, pmnoCreatorDB, mode);
    if (!dbP) {
      debugPrintf("getPalmanoDatabase(): Can't open database after create, code %d\n",
		  DmGetLastErr());
      ErrAlert(DmGetLastErr());      
      return DmGetLastErr();
    } else
      debugPrintf("getPalmanoDatabase(): second open DB ok\n");


    // Set the backup bit.  This is to aid syncs with non Palm software.
    //    ToDoSetDBBackupBit(dbP);
		
  } else
    debugPrintf("getPalmanoDatabase(): open DB ok\n");


  *dbPP = dbP;
  return 0;
}
/* Return info for last openned document */
DocumentInfo* GetLastDocInfo( void )
{
    DocumentInfo* docInfo;

    docInfo = NULL;

    if ( plkrDocList == NULL ) {
        plkrDocList = DmOpenDatabaseByTypeCreator( PlkrDocListType, ViewerAppID,
                        dmModeReadWrite );
    }
    if ( plkrDocList != NULL ) {
        DocumentData*   recordPtr;
        MemHandle       handle;

        ErrTry {
            /* assign doc info values for document */
            handle = FindDocData( Prefs()->docName, ALL_ELEMENTS, NULL );
            if ( handle != NULL ) {
                recordPtr = MemHandleLock( handle );

                StrNCopy( lastDocInfo.name, recordPtr->name, dmDBNameLength );
                lastDocInfo.cardNo      = recordPtr->cardNo;
                lastDocInfo.created     = recordPtr->created;
                lastDocInfo.attributes  = recordPtr->attributes;
                lastDocInfo.size        = recordPtr->size;
                lastDocInfo.categories  = recordPtr->categories;
                lastDocInfo.location    = recordPtr->location;
                lastDocInfo.timestamp   = recordPtr->timestamp;
                if ( lastDocInfo.location != RAM ) {
                    UInt16 fileLength;

                    ReleaseLastDocInfo();

                    fileLength              = StrLen( recordPtr->data ) + 1;
                    lastDocInfo.filename    = SafeMemPtrNew( fileLength );
                    StrNCopy( lastDocInfo.filename, recordPtr->data,
                        fileLength );
                    lastDocInfo.volumeRef   = FindVolRefNum( recordPtr->data +
                                                             fileLength );
                }
                MemHandleUnlock( handle );
                CloseRecord( handle, false );

                CloseDocList();

                docInfo = &lastDocInfo;
            }
        }
        ErrCatch( UNUSED_PARAM( err ) ) {
        } ErrEndCatch

        CloseDocList();
    }
Exemple #7
0
void Memo_WriteOpen(void) {
	if (s_pMemoDb)
		return;
	s_pMemoDb = DmOpenDatabaseByTypeCreator('DATA', sysFileCMemo,
											dmModeReadWrite);
	if(!s_pMemoDb)
		return;
	s_iRecNum = DmNumRecords(s_pMemoDb);
	s_RecHandle = DmNewRecord(s_pMemoDb, &s_iRecNum, diAllocSize);
	s_iOffset = 0;
	s_iAllocSize = diAllocSize;
}
Exemple #8
0
/*
 * initCNLBGlobeParameter
 * 初始化调用CLibGetMatchContactByRecordId()时需提供的预初始化参数。需要由调用者提供
 * 该参数的原因,是CLibGetMatchContactByRecordId()可能被用于循环检索多条记录(比如,
 * 由于查找库未提供获取特定分类下符合拼音关键字要求的通讯录集这种功能,调用者可能自行
 * 通过循环调用CLibGetMatchContactByRecordId()来实现该功能),提供该参数可以节省每次
 * 调用CLibGetMatchContactByRecordId()时,由库函数进行初始化所造成的时间开销和内存碎片
 *
 * 参数:
 *	globe			<->	给予的UInt16指针,用于返回查找库的引用
 *	addressType		->	通讯录的类型,ADDRESS_VERSION_OLD或ADDRESS_VERSION_NEW
 *
 * 返回:
 *	当成功初始化时,返回errNone;否则返回对应的错误代码
 */
Err initCNLBGlobeParameter(CNLBGlobeType **globe, UInt8 addressType)
{	
	//Allocate globe variable
	(*globe) = (CNLBGlobeType *)MemPtrNew(sizeof(CNLBGlobeType));
	if ((*globe) != NULL)
	{
		MemSet((*globe), sizeof(CNLBGlobeType), 0x00);
		
		//Get the PY table
		if (FtrGet(CLibCreatorID, PY_TABLE_FTR_NUMBER, (UInt32 *)&((*globe)->pyTableP)) == errNone)
		{
			//Open Contact database
			if (addressType == ADDRESS_VERSION_NEW)
			{
				(*globe)->addressDbRef = DmOpenDatabaseByTypeCreator('DATA', 'PAdd', dmModeReadOnly);
			}
			else
			{
				(*globe)->addressDbRef = DmOpenDatabaseByTypeCreator('DATA', 'addr', dmModeReadOnly);
			}
			if (DmGetLastErr())
			{
				MemPtrFree((*globe));
				return CNLB_DB_NOT_FOUND_ERROR;
			}
		}
		else
		{
			MemPtrFree((*globe));
			return CNLB_RUNTIME_ERROR;
		}
	}
	else
	{
		return CNLB_RUNTIME_ERROR;
	}
	
	return errNone;
}
Exemple #9
0
/***********************************************************************
 *
 * FUNCTION: ZDicFontInit
 *
 * DESCRIPTION: Initial all font resource
 *
 * PARAMETERS:	nothing
 *
 * RETURN:		errNone if success else fail.
 *
 * REVISION HISTORY:
 *		Name			Date		Description
 *		----			----		-----------
 *		ZhongYuanHuan	14/Aug/04	Initial Revision 
 *				
 ***********************************************************************/
Err ZDicFontInit ( UInt16 refNum, ZDicFontType* fontP, Boolean bUseSysFont )
{
	#pragma unused(refNum)
	
	UInt32  version;	
	Err     err;
	
	MemSet ( fontP, sizeof ( ZDicFontType ), 0 );
	fontP->smallFontID = stdFont;
	fontP->largeFontID = largeFont;
	
	if ( bUseSysFont ) return errNone;
	
	fontP->fontLibP = DmOpenDatabaseByTypeCreator ( ZDicFontTypeID, ZDicFontCreatorID, dmModeReadOnly );
	
	if ( fontP->fontLibP == 0 )
	{
	    err = DmGetLastErr ();
	    return err;
	}
	
	// Load the phonic font resource and assign it a font ID.
	err = FtrGet(sysFtrCreator, sysFtrNumWinVersion, &version);
	if (!err && version >= 4 )
	{
		// the screen is double density so use double density of phonetic font.
		fontP->phonicSmallFontH = DmGetResource('nfnt', PhonicSmallFontHight);
		fontP->phonicLargeFontH = DmGetResource('nfnt', PhonicLargeFontHight);		
	}
		
	if (fontP->phonicSmallFontH == NULL || fontP->phonicLargeFontH == NULL)
	{
		if (fontP->phonicSmallFontH != NULL) DmReleaseResource(fontP->phonicSmallFontH);
		if (fontP->phonicLargeFontH != NULL) DmReleaseResource(fontP->phonicLargeFontH);
		
		// the screen is low desity so use low density of phonetic font.
		fontP->phonicSmallFontH = DmGetResource(fontRscType, PhonicSmallFontLow);
		fontP->phonicLargeFontH = DmGetResource(fontRscType, PhonicLargeFontLow);		
	}
		
	fontP->phonicSmallFontP = (FontType *)MemHandleLock(fontP->phonicSmallFontH);
	fontP->phonicLargeFontP = (FontType *)MemHandleLock(fontP->phonicLargeFontH);
	err = FntDefineFont(kPHONIC_SMALL_FONT_ID, fontP->phonicSmallFontP);
	err = FntDefineFont(kPHONIC_LARGE_FONT_ID, fontP->phonicLargeFontP);
	fontP->smallFontID = kPHONIC_SMALL_FONT_ID;
	fontP->largeFontID = kPHONIC_LARGE_FONT_ID;		

	return errNone;
}
Exemple #10
0
/* 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
}
Exemple #11
0
/***********************************************************************
 * main function
 ***********************************************************************/
UInt32
PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
  UInt16 error = RomVersionCompatible (MINVERSION, launchFlags);
  if (error) return (error);

  /***
  * NORMAL STARTUP
  ****/
  if ( cmd == sysAppLaunchCmdNormalLaunch ) {
    error = StartApplication ();
    if (error) {
      // PalmOS before 3.5 will continuously relaunch this app unless we switch to
      // another safe one.
      if (error != dmErrCorruptDatabase) {
        FrmCustomAlert(ALERT_debug, "Please reports this bug! Give your Palm device and PalmOS version, this BadBug(TM) should not happen.", "", "");
      }
      StopApplication();
      AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
      return error;
    }

    FrmGotoForm(FORM_main);

    AppEventLoop ();
    StopApplication ();

    /***
     * FIND
     ****/
    /*
      } else if (cmd == sysAppLaunchCmdSaveData) {
      FrmSaveAllForms();
      } else if (cmd == sysAppLaunchCmdFind) {
      PalmGlobalFind((FindParamsPtr)cmdPBP);
    */

    /***
     * GoTo
     ****/
    /*
      } else if (cmd == sysAppLaunchCmdGoTo) {
      Boolean launched = launchFlags & sysAppLaunchFlagNewGlobals;
	
      if (launched) {
      error = StartApplication();
      if (! error) {
      GoToItem((GoToParamsPtr)cmdPBP, launched);
      AppEventLoop();
      StopApplication();
      }
      } else {
      GoToItem((GoToParamsPtr)cmdPBP, launched);
      }
    */

    /***
     * BEAMING
     ****/
  } else if (cmd == sysAppLaunchCmdSyncNotify) {
    // Register with the Exchange Manager
    ExgRegisterData(APP_CREATOR, exgRegExtensionID, "umx");
  } else if (cmd == sysAppLaunchCmdExgAskUser) {
    // Always assume "Yes" as answer to the accept dialog since we display our
    // own on which the user can cancel the data
    ExgAskParamType *exgAskParam = (ExgAskParamType *)cmdPBP;
    exgAskParam->result=exgAskOk;
  } else if (cmd == sysAppLaunchCmdExgReceiveData) {
    DmOpenRef cats=NULL, dogs=NULL;
    // Is app active?
    if (launchFlags & sysAppLaunchFlagSubCall) {
      // Quit Forms
      FrmSaveAllForms();

      cats = DatabaseGetRefN(DB_MAIN);
      dogs = DatabaseGetRefN(DB_DATA);
      error = BeamReceive(cats, dogs, (ExgSocketPtr) cmdPBP);
      CacheReset();
      FrmGotoForm(FORM_main);

    } else {
      // Another app was running when we were called
      cats = DmOpenDatabaseByTypeCreator(DATABASE_TYPE, APP_CREATOR, dmModeReadWrite);
      dogs = DmOpenDatabaseByTypeCreator(DATABASE_DATA_TYPE, APP_CREATOR, dmModeReadWrite);
      if (! (cats && dogs)) {
        FrmAlert(ALERT_beamdbfail);
      } else {
        error=BeamReceive(cats, dogs, (ExgSocketPtr)cmdPBP);
      }
      if (cats)  DmCloseDatabase(cats);
      if (dogs)  DmCloseDatabase(dogs);
    }

    /***
     * ALARM
     ****/
  } else if (cmd == sysAppLaunchCmdAlarmTriggered) {
    // Is app active?
    if (launchFlags & sysAppLaunchFlagSubCall) {
      AlarmTriggered(DatabaseGetRefN(DB_MAIN), (SysAlarmTriggeredParamType *)cmdPBP);
    } else {
      DmOpenRef cats = DmOpenDatabaseByTypeCreator(DATABASE_TYPE, APP_CREATOR, dmModeReadWrite);
      AlarmTriggered(cats, (SysAlarmTriggeredParamType *)cmdPBP);
      DmCloseDatabase(cats);
    }

    /***
     * ATTENTION
     ****/
  } else if (cmd == sysAppLaunchCmdAttention) {
    // Is app active?
    if (launchFlags & sysAppLaunchFlagSubCall) {
      AttentionBottleNeckProc(DatabaseGetRefN(DB_MAIN), (AttnLaunchCodeArgsType *)cmdPBP);
    } else {
      // Another app was running when we were called
      DmOpenRef cats = DmOpenDatabaseByTypeCreator(DATABASE_TYPE, APP_CREATOR, dmModeReadWrite);
      AttentionBottleNeckProc(cats, (AttnLaunchCodeArgsType *)cmdPBP);
      DmCloseDatabase(cats);
    }

    /***
     * ATTENTION GOTO
     ****/
  } else if (cmd == appLaunchCmdAlarmEventGoto) {
    error = StartApplication ();
    if (error) {
      // PalmOS before 3.5 will continuously relaunch this app unless we switch to
      // another safe one.
      if (error != dmErrCorruptDatabase) {
        FrmCustomAlert(ALERT_debug, "Please reports this bug! Give your Palm device and PalmOS version, this BadBug(TM) should not happen.", "", "");
      }
      StopApplication();
      AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
      return error;
    }

    ExamSetGoto(*(UInt32 *)cmdPBP);
    FrmGotoForm(FORM_exams);

    AppEventLoop ();
    StopApplication ();


  /***
  * TIME CHANGE
  ****/
  // Launch code sent when the system time is changed.
  } else if (cmd == sysAppLaunchCmdTimeChange) {
    // reset the trigger for the next alarm to fire
    if (launchFlags & sysAppLaunchFlagSubCall) {
      AlarmReset(DatabaseGetRefN(DB_MAIN));
      // Remove any "future" alarms from the attention manager queue
      // (ie alarms that will trigger after the new time setting)
      //AlarmUpdatePosted(DeviceTimeChanged);
    } else {
      // Another app was running when we were called
      DmOpenRef cats = DmOpenDatabaseByTypeCreator(DATABASE_TYPE, APP_CREATOR, dmModeReadWrite);
      if (cats != 0) {
        AlarmReset(cats);
        //AlarmUpdatePosted(DeviceTimeChanged);
        DmCloseDatabase(cats);
      }
    }
    
  
  /***
  * RESET
  ****/
  // This action code is sent after the system is reset.
  } else if (cmd == sysAppLaunchCmdSystemReset) {
    if (! ((SysAppLaunchCmdSystemResetType*)cmdPBP)->hardReset) {
      if (launchFlags & sysAppLaunchFlagSubCall) {
        AlarmReset(DatabaseGetRefN(DB_MAIN));
      } else {
        // Another app was running when we were called
        DmOpenRef cats = DmOpenDatabaseByTypeCreator(DATABASE_TYPE, APP_CREATOR, dmModeReadWrite);
        if (cats != 0) {
          AlarmReset(cats);
          DmCloseDatabase(cats);
        }
      }
    }

  }

  return 0;
}
Exemple #12
0
// 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;
}