MiniFilter buffer problem

Most definitely a very funny error on my part but I could not get
the minifilter to return data to my user mode app.
I did a very small filter very similar to MiniSpy (for the messaging
part) but while I get the ReturnedOutputBufferLength correctly, the
buffer is totally … incorrect.
Here’s the snippet of the code I am using for the app and the
snippet of the Message handler in the driver:

Driver Message Handler :

NTSTATUS Message(IN PVOID ConnectionCookie,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferSize,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferSize,
OUT PULONG ReturnOutputBufferLength)
{
PLog OldLog;
PDWORD lpCode = InputBuffer;

switch(*lpCode)
{
case GetBuffer:
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&LogMutex, TRUE);
if(!Used)
{
if(*ReturnOutputBufferLength = ActiveLog->Len)
{
DbgPrint(“Out = %p\t Len = %u\t DataLen = %u\n”,
OutputBuffer,
ActiveLog->Len,
ActiveLog->DataLen);
DbgPrint(“Log = %p\tDataLen = %p\tLen = %p\tData =
%p\n”,
ActiveLog,
&ActiveLog->DataLen,
&ActiveLog->Len,
ActiveLog->Data);
memcpy(OutputBuffer,
&ActiveLog->Data[0],
ActiveLog->Len);
ActiveLog->Len = 0;
ActiveLog->DataLen = 0;
}
ExReleaseResourceLite(&LogMutex);
KeLeaveCriticalRegion();
break;
}
*ReturnOutputBufferLength = Used->Len;
memcpy(OutputBuffer,
Used->Data,
Used->Len);
OldLog = Used->Next;
Used->Next = Free;
Free = Used;
Used = OldLog;
ExReleaseResourceLite(&LogMutex);
KeLeaveCriticalRegion();
break;
default:
DbgPrint(“Invalid code: %p\n”, *lpCode);
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}

Since the driver is only logging during CreatePreOp, the buffer has
at most 2 entries if any, so the part where DbgPrints are is what is
being called, and I see in Debug View that the Len is 180 bytes, as it
should be, DataLen is 1 or 2 (number of entries, i.e. number of creates
logged).

User mode part:

void __cdecl main()
{
HANDLE hPort;
HRESULT hRes;
PVOID AlignedBuffer[sizeof(TLog) / sizeof(PVOID) + 1];
PLog Log = (PLog) AlignedBuffer;
PLogEntry Entry;
DWORD dwMsg = GetBuffer, dwData;
DWORD Tick, Ticked, i;

hRes = FilterConnectCommunicationPort(L"\AlfaPort",
0,
NULL,
0,
NULL,
&hPort);
if(hRes != S_OK)
{
DisplayError( hRes );
return;
}
Tick = GetTickCount();
Ticked = 0;
while(Ticked < (DWORD)10000)
{
hRes = FilterSendMessage(hPort,
&dwMsg,
sizeof(dwMsg),
Log,
sizeof(TLog),
&dwData);
if(hRes != S_OK)
{
DisplayError( hRes );
return;
}
if(!dwData)
goto NoData;
printf(“DataSize = %u\n”, dwData);
Entry = (PLogEntry)(Log->Data);
printf(“Log->DataLen = %u, Log->Len = %u, Log->Next = %p\n”,
Log->DataLen, Log->Len, Log->Next);
for(i = 0; i < Log->DataLen; i++)
{
wprintf(L"FileName: %.*S\n",
Entry->FileNameLen / 2,
Entry->Data);
Entry = (PLogEntry)
((PCHAR)Entry + sizeof(TLogEntry) +
Entry->FileNameLen +
Entry->ProcessLen +
Entry->UserNameLen);
}
NoData:
Ticked = GetTickCount() - Tick;
}
CloseHandle(hPort);
}

The dwData is 1 or 2, however Log->DataLen and Log->Len are totally
incorrect values (DataLen is always 0 and Len is always 15).

typedef struct _Log
{
ULONG Len;
ULONG DataLen;
struct _Log *Next;
UCHAR Data[65524];
} TLog, *PLog;

Any insight is appreciated.

Dejan.