Я тут немного подумал и склоняюсь к мысли, что динамические блоки (тут сложно найти тонкую грань между динамическими и статическими  блоками - свойство/метод isDynamicBlock не показатель) не могут быть анонимными.
чего это? именно на анонимных блоках и построена вся работа с динамическими блоками, если верить логике автодеска. когда динамический блок вставляется, ему дается имя как и у родительской BTR. Дальше, любое изменение динамики приводит к рождению анонимного блока, который описывает текущее положение динамики, но ссылается на родительский. В итоге, если блок подергать 10 раз, мы получаем 10 анонимных блоков, каждый из которых описывает какое-то изменение динамики (это то и позволяет делать откат Ctrl+Z). После переоткрытия чертежа все анонимные блоки, которые не используются просто вычищаются. Странно, не удобно, но реализовано именно так. В свете всего этого становится понятно, зачем придумали функцию acdbSetReferenced (вот только работает она странноватенько).
Если хочешь защитить свои блоки, разбей все блоки. Т.к. насколько помню, анонимные блоки легко переделать в обычные и использовать.
Да я ж и не спорю, поэтому и написал в первом посте слово защита в кавычках. Задача скорей не защитить, а сделать не удобным использование БЕЗ arx-ины, за которую нужно платить деньги 

. 
По поводу защиты блоков и чертежей в автодеске придерживаются мнения, что все мы живем в каммунзме и всё, что нарисовано - общественная собственность (если не ошибаюсь, в начале существования автокада была возможность ставить пароль на блоки. также была возможность закрывать паролем весь чертеж. парольной защиты блоков уже нет в 2005 автокаде, парольный вход не поддерживается в 2020. зато везде пихают цифровые подписи, которые служат чисто для поддержания на плаву организаций, их выдающих и не обладают никакими защитными свойствами). было б здорово написать свой кастомный объект на основе блока (а лучше BTR), увы - нельзя, ибо сами автодесковцы говорят, что работает криво, да и пару лет назад я честно пытался. статические блоки - работают, динамика - не поддерживается.
Конечно ты накосячил. Но чтоб понять в чем именно нужно детально смотреть чертеж и код.
С этим никаких проблем нет, вот код функции
void lockcur()
{       
        acutPrintf(_T("\n*Начало..."));
        int count1 = 0;
        //-> для начала пробежимся по BTR, сделаем все наши блоки анонимными
        AcDbBlockTable* pBlockTable;
        if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
        {
                AcDbBlockTableIterator *pBlockTableIterator = NULL;
                if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
                {
                        for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
                        {
                                AcDbObjectId eId;
                                ACHAR * szBuffer;
                                pBlockTableIterator->getRecordId(eId);
                                AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
                                if (Acad::eOk != pRec.openStatus()) continue;
 
                                pRec->getName(szBuffer);
                                CString realName = szBuffer;
                                acutDelString(szBuffer);
                                if (realName.Find(_T('*')) == -1 && realName.Find(_T('$')) == -1)
                                {
                                        count1++;
                                        if (Acad::eOk != pRec->upgradeOpen()) continue;
                                        pRec->setName(_T("*U"));
                                        pRec->downgradeOpen();
                                        if (Acad::eOk != acdbSetReferenced(eId))
                                                acutPrintf(_T("\nError acdbSetReferenced"));
                                        AcDbObjectIdArray blkInserts; blkInserts.removeAll();
                                        pRec->getBlockReferenceIds(blkInserts);
                                        pRec->getName(szBuffer);
                                        CString anonymouseName = szBuffer;
                                        acutDelString(szBuffer);
                                        acutPrintf(_T("\n%s : %s"), realName.GetString(), anonymouseName.GetString());
                                }
                        }
                }
                if (pBlockTableIterator != NULL) delete pBlockTableIterator;
                pBlockTable->close();
        }       
        acutPrintf(_T("\n*Обработано %d блоков"), count1);
 
        count1 = 0;
 
        acutPrintf(_T("\n*Проверка количества блоков в БД чертежа после анонимизации :) ..."));
        if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
        {
                AcDbBlockTableIterator *pBlockTableIterator = NULL;
                if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
                {
                        for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
                        {
                                AcDbObjectId eId;
                                ACHAR * szBuffer;
                                pBlockTableIterator->getRecordId(eId);
                                AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
                                if (Acad::eOk != pRec.openStatus()) continue;
 
                                pRec->getName(szBuffer);
                                CString realName = szBuffer;
                                acutDelString(szBuffer);
                                if (realName.Find(_T("*U")) != -1)
                                {
                                        count1++;
                                        acutPrintf(_T("\n%d. %s"), count1, realName.GetString());
                                }
                        }
                }
                if (pBlockTableIterator != NULL) delete pBlockTableIterator;
                pBlockTable->close();
        }
 
        CString filePath = curDoc()->fileName();
        acutPrintf(_T("\nЗапись в файл: %s"), filePath.GetString());
        if (Acad::eOk != acdbCurDwg()->saveAs(filePath.GetString(), true, AcDb::kDHL_1024))
        {
                acutPrintf(_T("\n*** Не смогла я записать файл, увы"));
        }
        //<-
 
        count1 = 0;
        acutPrintf(_T("\n*Проверка количества блоков в БД чертежа после сохранения..."));
        if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
        {
                AcDbBlockTableIterator *pBlockTableIterator = NULL;
                if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
                {
                        for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
                        {
                                AcDbObjectId eId;
                                ACHAR * szBuffer;
                                pBlockTableIterator->getRecordId(eId);
                                AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
                                if (Acad::eOk != pRec.openStatus()) continue;
 
                                pRec->getName(szBuffer);
                                CString realName = szBuffer;
                                acutDelString(szBuffer);
                                if (realName.Find(_T("*U")) != -1)
                                {
                                        count1++;
                                        acutPrintf(_T("\n%d. %s"), count1, realName.GetString());
                                }
                        }
                }
                if (pBlockTableIterator != NULL) delete pBlockTableIterator;
                pBlockTable->close();
        }
}
Чертеж будет во вложениях. В чертеже 58 блоков с нормальными именами. Открываем чертеж, делаем его текущим. Запускаем команду, выполняющую функцию, написанную выше. В логе командной строки будет выведена информация о текущем состянии дел. Сразу идет сопоставление реального имени и анонимного. Потом еще один пробег по БД, с отображением всех анонимных BTR, потом сохранение чертежа и снова отображение всего, что осталось в БД после сохранения. 
После этого чертеж нужно закрыть и открыть заново. И попытаться объяснить, почему вместо 58 блоков осталось 4 (вставок нет, использования в других блоках нет, а они остались). Функция acdbSetReferenced использовалась 58 раз, а видим 4 (если ей НЕ пользоваться, мы тожеж увидим те же 4 блока через ArxDbg или утилиты очистки чертежа, если что 

 )
А теперь взрыв мозга... Если всё это проделать БЕЗ физического открытия чертежа (пользуемся readDwgFile), то видно все 58 анонимных блоков. В этом случае не вызывается реактор dwgFileOpened, который судя по справке и удаляет не используемые блоки (которые призвана защитить функция acdbSetReferenced!!!). Вот правда если "анонимизировать" блоки БЕЗ функции acdbSetReferenced, то в процессе открытия через readDwgFile их тоже всего 4. Вот такой закрученный сюжет 

, в котором вроде бы бесполезная функция с одной стороны оказывается очень даже нужной с другой )))))))))))
Понапрягать можно. Но (!!!) ты дожен всё для них подготовить
сейчас слегка занят, да и главное понять, во что тыкать носом. в общем обязательно все подготовлю, но не на этой неделе.