Как прочитать строковое значение из файла базы данных ESE, используя API ESE CPP?

Я анализирую файл базы данных ESE, т.е. WebCacheV01.dat. Это файл, в котором IE 10 начал хранить всю историю просмотров и другую информацию. Я использую JET Blue CPP API для анализа этого файла.

Я могу прочитать любое значение столбца типа integer или long, но не могу прочитать значение столбца типа string.

Например, я открыл таблицу "MSysObjects" и хочу получить значение столбца "Имя".

Вот пример кода

 for( err = ::JetMove( sessionID, tableId, JET_MoveFirst, 0 );
        JET_errSuccess == err;
        err = ::JetMove( sessionID, tableId, JET_MoveNext, 0 ) )
    {
        JET_COLUMNID columnid = 12/*columnid of the Name column*/;
        char *pszBuff = new char[2048];
        if( pszBuff )
        {
            long lReadBytes;
             memset(pszBuff, 0, 2048);
             err = ::JetRetrieveColumn( sessionID,
               tableId,
                columnid,
                pszBuff,
                2047,
               &lReadBytes,
               0,
               NULL);
            delete[] pszBuff;
        }
    }

Возвращаемое значение JetRetrieveColumn равно -1507, которое является ничем иным, как JET_errColumnNotFound. С помощью инструмента ESEDatabaseViewer я убедился, что таблица MSysObjects содержит 25 столбцов. Это означает, что столбец 18 не является недействительным.

Пожалуйста, дайте мне знать, если кто-нибудь знает, как получить строковые значения из базы данных ESE.

Заранее спасибо.

1 ответ

Потратив почти два дня, я наконец понял, как правильно читать значения из таблицы базы данных ESE. Я думал, что columnid находится в последовательности, и, следовательно, я определял columnid путем подсчета определенного местоположения столбца в инструменте "ESEDatabaseView".

Но это не так. Правильный способ получения columnid - вызвать метод JetGetTableColumnInfo, указав имя столбца. После получения значения columnid используйте его в методах JetRetrieveColumn для получения значения столбца.

Вот исправленный код

for( err = ::JetMove( jetSessionId, jetContainersTableId, JET_MoveFirst, 0 );
    JET_errSuccess == err;
    err = ::JetMove( jetSessionId, jetContainersTableId, JET_MoveNext, 0 ) )
{
    unsigned long nReadBytes = 0;

    JET_COLUMNDEF colName;
    err = ::JetGetTableColumnInfoW(jetSessionId, jetContainersTableId, L"Name", (void *)&colName, sizeof(JET_COLUMNDEF), JET_ColInfo);

    wchar_t szName[MAX_PATH] = {0};
    if( JET_errSuccess == err )
    {
        err = ::JetRetrieveColumn(jetSessionId, jetContainersTableId, colName.columnid, szName, sizeof(szName) , &nReadBytes, 0, NULL);
    }
}

Это может помочь кому-то, кто работает с базой данных ESE.

Другие вопросы по тегам