четверг, 25 октября 2007 г.

XML в ядре

Существует замечательная мультиплатформеная библиотека для работы с XML именуемая The Expat XML Parser.Так вот оказалось что малой кровью её можно заставить работать и в ядре. Ниже я приведу шаги которые были применены для сборки отладочной версии статической библиотеки с драйвером.

Изменение кода Expat проекта в Visual Studio:
Нам нужно переопределить используемые CRTшные функции отсутсвующие в ядре. Это:
free
malloc
realloc
assert
memcmp

Для примера это можно сделать включив в проект файл со следующим содержанием:
#define _X86_
#include

void __cdecl free(void * _Memory)
{
if( _Memory )
ExFreePoolWithTag(_Memory, 'test');
}

void * __cdecl malloc( size_t _Size)
{
return (void*)ExAllocatePoolWithTag(NonPagedPool, _Size, 'test' );
}

void * __cdecl realloc( void * _Memory, size_t _NewSize)
{
if( _Memory )
ExFreePoolWithTag(_Memory, 'myma');
return (void*)ExAllocatePoolWithTag(NonPagedPool, _NewSize, 'test' );
}

int __cdecl memcmp(const void * _Buf1, const void * _Buf2, size_t _Size)
{
return (int)RtlCompareMemory( _Buf1, _Buf2, _Size );
}

void __cdecl assert( unsigned char something )
{

}

Кстати, для вышеприведенного кода нужно установить соглашение о вызове __stdcall. Это связано с тем что в прототипе
ExFreePoolWithTag это не указано явно.


Изменение настроек Expat проекта в Visual Studio:
1. C/C++ --> General --> Debug Information Format = Program Database (/Zi)
2. C/C++ --> CodeGeneration --> Basic Runtime Checks = Default
3. Подключить ntoskrnl.lib
4. Установить __stdcall для файла с переопределенными функциями (если используется ExFreePoolWithTag);

Код драйвера:
Если предполагается копмилировать статическую библиотеку (а это предполагается :) ), то нужно продефайнить:
#define XML_BUILDING_EXPAT 1

Ниже приведены заглушки которые можно реализовать (а можно пользоваться теми, что были переопределены выше):
..............
void * __cdecl MyMalloc(size_t size)
{
return ExAllocatePoolWithTag( NonPagedPool, size, '
test' );
}

void * __cdecl MyRealloc(void *ptr, size_t size)
{
if( ptr )
ExFreePoolWithTag(ptr, 'myma');
return ExAllocatePoolWithTag( NonPagedPool, size, '
test' );
}

void __cdecl MyFree(void *ptr)
{
if( ptr )
ExFreePoolWithTag(ptr, '
test');
}

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pusRegistryPath
)
{
XML_Memory_Handling_Suite memsuite;
...................

myMemSuite.malloc_fcn = (void *(__stdcall *)(size_t))&MyMalloc;
myMemSuite.realloc_fcn = (void *(__stdcall *)(void *,size_t))&MyRealloc;
myMemSuite.free_fcn = (void (__stdcall *)(void *))&MyFree;

parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
..........................
}

sources драйвера:
TARGETLIBS=XmlParser.lib

Пример библиотеки и вызывающего драйвера постараюсь выложить в ближайшее время.

Вот и всё. Вся эта морока с соглашениями о вызове нужна была что бы свести к минимуму вносимые изменения в код библиотеки.

Свежую версию Expat всегда можно найти на http://expat.sourceforge.net/

Комментариев нет: