ESENT всегда выдает EsentPageSizeMismatchException при попытке открыть IE 10/11 WebCache.dat

Я пытаюсь создать сценарий powershell для чтения интернет-истории IE 10/11, которая хранится в AppData\Local\Microsoft\Windows\WebCache\WebCache.dat.

Я использую Managed Esent+ - для взаимодействия с Win32 Jet API в.NET.

Моя проблема в том, что я никогда не смогу открыть базу данных, так как EsentPageSizeMismatchException выбрасывается, когда я вызываю JetAttachDatabase. Проведя некоторые исследования этой ошибки, я обнаружил, что IE WebCache имеет размер страницы 32K. Когда я попытался исправить это, установив системный параметр DatabasePageSize в 0x8000, JetInit начал выдавать то же исключение.

Вот код, который у меня есть

#stop the things locking the database
stop-process -name taskhost
stop-process -name dllhost
#give powershell access to the interop dlls
add-type -path "$PSScriptRoot\ManagedEsent 1.6\Esent.Interop.dll"
$instance = [Microsoft.Isam.Esent.Interop.JET_INSTANCE]::Nil
#set page size
[Microsoft.Isam.Esent.Interop.api]::JetSetSystemParameter(
    $instance,
    [Microsoft.Isam.Esent.Interop.JET_SESID]::Nil,
    [Microsoft.Isam.Esent.Interop.JET_param]::DatabasePageSize,
    0x8000,
    $null
)
[Microsoft.Isam.Esent.Interop.Api]::JetCreateInstance([ref]$instance,"testing")
# init the instance, throws EsentPageSizeMismatchException if the page size is not default
[Microsoft.Isam.Esent.Interop.Api]::JetInit([ref]$instance) 
$sesid = [Microsoft.Isam.Esent.Interop.JET_SESID]::Nil
[Microsoft.Isam.Esent.Interop.Api]::JetBeginSession($instance,[ref]$sesid,$null,$null)
# throws EsentPageSizeMismatchException if page size is default
[Microsoft.Isam.Esent.Interop.api]::JetAttachDatabase(
   $sesid,
   "C:\Users\Administrator\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat",
   [Microsoft.Isam.Esent.Interop.AttachDatabaseGrbit]::ReadOnly
)
...

Похоже, что движку ESENT не нравится иметь размер страницы не по умолчанию, но я искал в Интернете, и, похоже, нет способа изменить размер страницы движка. Что вызывает эту ошибку?

3 ответа

Решение

Если вы заметили, в одном случае это JetAttachDatabase что терпит неудачу с исключением, и JetInit в другом.

Вы действительно правы, что вам нужно установить DatabasePageSize.JetInit на самом деле плохое имя. Это надо называть как то JetInitAndReplayLogFiles, Он будет просматривать файлы журнала транзакций (имя по умолчанию edb*.log) в каталоге журналов (по умолчанию: ".") И воспроизводит операции в файлах журнала транзакций.

Вы, вероятно, теперь выбираете другие файлы журнала транзакций, созданные с другим размером страницы. Теория: вы подбираете edb*.log файлы, которые вы случайно создали при первой попытке.

Некоторые потенциальные решения:

-cd в каталог, который сначала содержит файлы журнала.

-Измените LogFileDirectory (вы можете использовать JetSetSystemParameter с JET_param.LogFilePathили класс оболочки InstanceParameters.LogFileDirectory). О, вам также нужно установить InstanceParameters.BaseName на "v01", поскольку именно это, похоже, использует файл webcache01.dat (влияет на имена "edb.log" против "v01.log").

-Использование esentutl.exe -r v01 чтобы привести базу данных в состояние "чистого отключения", а затем установить InstanceParameters.Recovery в false чтобы случайно не создавать новые файлы журнала транзакций. И я вижу, что вы уже привязаны к AttacheDatabaseGrbit.ReadOnly,

Наконец, я надеюсь, что это просто для любопытства. Люди, которые работали с inetcache, могут изменить детали реализации в любое время. Если это для судебных целей, Microsoft действительно помогает судебным усилиям правоохранительных органов.

-Мартин

Вы должны использовать JetGetDatabaseFileInfo(), чтобы получить требуемый размер страницы для использования с SetSetSystemParameter()

Вот пример в C# (эй... это достаточно близко, верно?)

        int pageSize;
        JET_INSTANCE instance;
        JET_SESID sesId;

        // match the Page size
        Api.JetGetDatabaseFileInfo(databasePath, out pageSize, JET_DbInfo.PageSize);
        Api.JetSetSystemParameter(JET_INSTANCE.Nil, JET_SESID.Nil, JET_param.DatabasePageSize, pageSize, null);

В моем случае мне пришлось вручную зайти в папку bin/Debug и вручную удалять содержимое каждый раз, когда я переключал базы данных, прежде чем снова отлаживать его. Я надеюсь, что это помогает кому-то, кто сталкивается с этой проблемой.

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