if(!sync)
if(!sync || !sync->m_dbHH)
DWORD WINAPI DoFastSync(LPVOID lpParameter){    long retval=0;    BOOL success = FALSE;    CMozABConduitSync * sync = (CMozABConduitSync * ) lpParameter;    if(!sync)        return retval;    if(sync->m_dbHH) {        DWORD mozABCount=0;        DWORD * mozCatIDList = NULL; // freed by MSCOM/Mozilla        CPString ** mozABNameList = NULL; // freed by MSCOM/Mozilla        BOOL * mozIsFirstSyncList = NULL; // freed by MSCOM/Mozilla        retval = sync->m_dbHH->OpenDB(FALSE);        if (!retval)            retval = sync->m_dbHH->LoadCategories();        if(!retval)            retval = sync->m_dbPC->GetPCABList(&mozABCount, &mozCatIDList, &mozABNameList, &mozIsFirstSyncList);        // for each category synchronize        if (!retval) {            CPCategory * pCategory = sync->m_dbHH->GetFirstCategory();            while (pCategory) {                CPalmRecord ** recordListHH = NULL;                DWORD recordCountHH=0;                DWORD catID = pCategory->GetID();                DWORD catIndex = pCategory->GetIndex();                CPString catName(pCategory->GetName());                                DWORD mozABIndex=0;                BOOL foundInABList=FALSE;                for(mozABIndex=0; mozABIndex<mozABCount; mozABIndex++) {                    // if this category has been synchronized before                    if(catID == mozCatIDList[mozABIndex]) {                        retval = sync->m_dbHH->LoadUpdatedRecordsInCategory(catIndex, &recordListHH, &recordCountHH);                        foundInABList = TRUE;                        break;                    }                    // if corresponding category exists but not synchronized before                    if(!catName.CompareNoCase(mozABNameList[mozABIndex]->GetBuffer(0))) {                        retval = sync->m_dbHH->LoadAllRecordsInCategory(catIndex, &recordListHH, &recordCountHH);                        foundInABList = TRUE;                        break;                    }                    // if it is PAB, called 'Personal' on Palm and 'Personal Address Book' in Mozilla/Netscape                    CPString personal(PERSONAL);                    if( (catName.Find(personal) != -1) &&                        (mozABNameList[mozABIndex]->Find(personal) != -1) ) {                        retval = sync->m_dbHH->LoadAllRecordsInCategory(catIndex, &recordListHH, &recordCountHH);                        foundInABList = TRUE;                        break;                    }                } // end of for                if(!retval && foundInABList) {                    CPalmRecord ** recordListPC=NULL;                    DWORD recordCountPC=0;                    DWORD newRecAddedCount = 0;                    DWORD * newRecIDList=NULL;                    retval = sync->m_dbPC->SynchronizePCAB(catID, catName,						                              recordCountHH, recordListHH,						                              &recordCountPC, &recordListPC);                    if (!retval) {                        newRecIDList = (DWORD *) calloc(recordCountPC, sizeof(DWORD));                        for (unsigned long i=0; i < recordCountPC; i++) {                            if(!recordListPC[i])                                continue;                            CPalmRecord palmRec = *recordListPC[i];                            palmRec.SetCategory(catIndex);                            if(palmRec.GetAttribs() == ATTR_DELETED)							    retval = sync->m_dbHH->DeleteARecord(palmRec);                            else if(palmRec.GetAttribs() == ATTR_MODIFIED)							    retval = sync->m_dbHH->UpdateARecord(palmRec);                            else if(palmRec.GetAttribs() == ATTR_NEW) { 							    retval = sync->m_dbHH->AddARecord(palmRec); // should we check existing recs?                                if(!retval && (newRecAddedCount < recordCountPC)) {                                    newRecIDList[newRecAddedCount] = palmRec.GetID();                                    newRecAddedCount++;                                }                            }                            delete recordListPC[i]; // once done with PC record, delete					    }                    }                    // the MozAB is now synchronized                    if(!retval)                        mozIsFirstSyncList[mozABIndex] = FALSE;                    // delete the PC recordList now that palm is updated                    if(recordListPC)                        free(recordListPC);                      // notify Mozilla that sync is done so that memory can be freed                     if(!retval)                        success = TRUE;                    if(newRecAddedCount) {                        if(newRecAddedCount != recordCountPC)                            newRecIDList = (DWORD *) realloc(newRecIDList, newRecAddedCount);                        retval = sync->m_dbPC->NotifySyncDone(success, catID, newRecAddedCount, newRecIDList);                    }                    else                         retval = sync->m_dbPC->NotifySyncDone(success);                    if(newRecIDList)                        free(newRecIDList);                }                                if(!retval && !foundInABList) {                    retval = sync->m_dbHH->LoadAllRecordsInCategory(catIndex, &recordListHH, &recordCountHH);                    if(!retval && recordCountHH)                        retval = sync->m_dbPC->AddRecords(catID, catName, recordCountHH, recordListHH);                }                // delete and free HH records and recordList once synced                if(recordListHH) {                    CPalmRecord ** tempRecordListHH = recordListHH;                    for(DWORD i=0; i < recordCountHH; i++) {                        if(*tempRecordListHH)                            delete *tempRecordListHH;                        tempRecordListHH++;                    }                    free(recordListHH);                }                pCategory = sync->m_dbHH->GetNextCategory();            } // end of while            // deal with any Moz AB not existing in Palm, ones not sync'ed above            for(DWORD mozABIndex=0; mozABIndex<mozABCount; mozABIndex++) {                if(mozIsFirstSyncList[mozABIndex]) {                    CPalmRecord ** recordListPC=NULL;                    DWORD recordCountPC=0;                    DWORD * newRecIDList=NULL;                    CPCategory cat;                    retval = sync->m_dbPC->LoadAllRecords(*mozABNameList[mozABIndex],						                              &recordCountPC, &recordListPC);                    if(!retval && recordCountPC) {                        cat.SetName(mozABNameList[mozABIndex]->GetBuffer(0));                        retval = sync->m_dbHH->AddCategory(cat);                    }                    if(!retval) {                        newRecIDList = (DWORD *) calloc(recordCountPC, sizeof(DWORD));                        for (unsigned long i=0; i < recordCountPC; i++) {                            if(!recordListPC[i])                                continue;                            CPalmRecord palmRec = *recordListPC[i];                            palmRec.SetCategory(cat.GetIndex()); 						    retval = sync->m_dbHH->AddARecord(palmRec); // should we check existing recs?                            newRecIDList[i] = palmRec.GetID();                            delete recordListPC[i]; // delete the record now that it is used                        }                    }                    // the MozAB is now synchronized                    if(!retval)                        mozIsFirstSyncList[mozABIndex] = FALSE;                    // delete the recordList now that palm is updated                    if(recordListPC)                        free(recordListPC);                      // notify Mozilla that sync is done so that memory can be freed                     if(!retval)                        success = TRUE;                    else                        recordCountPC=0;                    retval = sync->m_dbPC->NotifySyncDone(success, cat.GetID(), recordCountPC, newRecIDList);                    if(newRecIDList)                        free(newRecIDList);                }            } // end of mozAB for loop        }        // update category info in HH        sync->m_dbHH->CompactCategoriesToHH();        // close the HH DB once synced        retval = sync->m_dbHH->CloseDB(FALSE);    }    return retval;}