mirror of
https://github.com/reactos/reactos.git
synced 2024-07-12 07:35:10 +00:00
[KMTESTS]
- use a shared memory buffer for storing test results to provide seamless communication between all test parts - Now user mode code can easily add messages to the buffer svn path=/branches/GSoC_2011/KMTestSuite/; revision=52216
This commit is contained in:
parent
1de7bf0885
commit
a6b4eba335
|
@ -23,6 +23,7 @@ add_library(kmtest_drv SHARED ${KMTEST_DRV_SOURCE})
|
|||
set_module_type(kmtest_drv kernelmodedriver)
|
||||
target_link_libraries(kmtest_drv ${PSEH_LIB})
|
||||
add_importlibs(kmtest_drv ntoskrnl hal)
|
||||
set_property(TARGET kmtest_drv PROPERTY COMPILE_DEFINITIONS KMT_KERNEL_MODE)
|
||||
|
||||
add_cd_file(TARGET kmtest_drv DESTINATION reactos/system32/drivers FOR all)
|
||||
|
||||
|
@ -39,5 +40,6 @@ list(APPEND KMTEST_SOURCE
|
|||
add_executable(kmtest ${KMTEST_SOURCE})
|
||||
set_module_type(kmtest win32cui)
|
||||
add_importlibs(kmtest advapi32 msvcrt kernel32)
|
||||
set_property(TARGET kmtest PROPERTY COMPILE_DEFINITIONS KMT_USER_MODE)
|
||||
|
||||
add_cd_file(TARGET kmtest DESTINATION reactos/bin FOR all)
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#define IOCTL_KMTEST_RUN_TEST \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
|
||||
#define IOCTL_KMTEST_SET_RESULTBUFFER \
|
||||
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
|
||||
|
||||
#define KMTEST_DEVICE_NAME L"Kmtest"
|
||||
#define KMTEST_DEVICE_PATH (L"\\\\.\\Global\\GLOBALROOT\\Device\\" KMTEST_DEVICE_NAME)
|
||||
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#ifndef _KMTEST_TEST_H_
|
||||
#define _KMTEST_TEST_H_
|
||||
|
||||
#include <kmt_log.h>
|
||||
|
||||
typedef void KMT_TESTFUNC(void);
|
||||
|
||||
typedef struct
|
||||
|
@ -22,4 +20,60 @@ typedef const KMT_TEST CKMT_TEST, *PCKMT_TEST;
|
|||
|
||||
extern const KMT_TEST TestList[];
|
||||
|
||||
typedef struct {
|
||||
volatile LONG Successes;
|
||||
volatile LONG Failures;
|
||||
volatile LONG LogBufferLength;
|
||||
LONG LogBufferMaxLength;
|
||||
CHAR LogBuffer[ANYSIZE_ARRAY];
|
||||
} KMT_RESULTBUFFER, *PKMT_RESULTBUFFER;
|
||||
|
||||
extern PKMT_RESULTBUFFER ResultBuffer;
|
||||
|
||||
#if defined KMT_DEFINE_TEST_FUNCTIONS
|
||||
PKMT_RESULTBUFFER ResultBuffer = NULL;
|
||||
|
||||
#if defined KMT_USER_MODE
|
||||
static PKMT_RESULTBUFFER KmtAllocateResultBuffer(SIZE_T LogBufferMaxLength)
|
||||
{
|
||||
PKMT_RESULTBUFFER Buffer = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer[LogBufferMaxLength]));
|
||||
|
||||
Buffer->Successes = 0;
|
||||
Buffer->Failures = 0;
|
||||
Buffer->LogBufferLength = 0;
|
||||
Buffer->LogBufferMaxLength = LogBufferMaxLength;
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
static VOID KmtFreeResultBuffer(PKMT_RESULTBUFFER Buffer)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||
}
|
||||
#endif /* defined KMT_USER_MODE */
|
||||
|
||||
#define KmtMemCpy memcpy
|
||||
|
||||
static VOID KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer, PCSTR String, SIZE_T Length)
|
||||
{
|
||||
LONG OldLength;
|
||||
LONG NewLength;
|
||||
|
||||
do
|
||||
{
|
||||
OldLength = Buffer->LogBufferLength;
|
||||
NewLength = OldLength + Length;
|
||||
if (NewLength > Buffer->LogBufferMaxLength)
|
||||
{
|
||||
/* TODO: indicate failure somehow */
|
||||
__debugbreak();
|
||||
return;
|
||||
}
|
||||
} while (InterlockedCompareExchange(&Buffer->LogBufferLength, NewLength, OldLength) != OldLength);
|
||||
|
||||
KmtMemCpy(&Buffer->LogBuffer[OldLength], String, Length);
|
||||
}
|
||||
|
||||
#endif /* defined KMT_DEFINE_TEST_FUNCTIONS */
|
||||
|
||||
#endif /* !defined _KMTEST_TEST_H_ */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<module name="kmtest" type="win32cui" installbase="system32" installname="kmtest.exe">
|
||||
<include base="kmtest">include</include>
|
||||
<library>advapi32</library>
|
||||
<define name="KMT_USER_MODE" />
|
||||
<directory name="kmtest">
|
||||
<file>kmtest.c</file>
|
||||
<file>service.c</file>
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#include "kmtest.h"
|
||||
#include <winioctl.h>
|
||||
#include <kmt_public.h>
|
||||
#define KMT_DEFINE_TEST_FUNCTIONS
|
||||
#include <kmt_test.h>
|
||||
|
||||
#define LOGBUFFER_SIZE 65000
|
||||
|
||||
static void OutputError(FILE *fp, DWORD error);
|
||||
static DWORD RunTest(char *testName);
|
||||
|
@ -40,9 +44,14 @@ static DWORD RunTest(char *testName)
|
|||
{
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
HANDLE hDevice = INVALID_HANDLE_VALUE;
|
||||
DWORD bytesRead;
|
||||
char buffer[1024];
|
||||
BOOL ret;
|
||||
DWORD bytesRead, bytesWritten;
|
||||
|
||||
ResultBuffer = KmtAllocateResultBuffer(LOGBUFFER_SIZE);
|
||||
if (!ResultBuffer)
|
||||
{
|
||||
error = GetLastError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hDevice = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
@ -53,23 +62,19 @@ static DWORD RunTest(char *testName)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!DeviceIoControl(hDevice, IOCTL_KMTEST_SET_RESULTBUFFER, ResultBuffer, FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer[LOGBUFFER_SIZE]), NULL, 0, &bytesRead, NULL))
|
||||
{
|
||||
error = GetLastError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!DeviceIoControl(hDevice, IOCTL_KMTEST_RUN_TEST, testName, strlen(testName), NULL, 0, &bytesRead, NULL))
|
||||
{
|
||||
error = GetLastError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while ((ret = ReadFile(hDevice, buffer, sizeof buffer - 1, &bytesRead, NULL)) != 0)
|
||||
{
|
||||
if (!bytesRead)
|
||||
break;
|
||||
|
||||
assert(bytesRead < sizeof buffer);
|
||||
buffer[bytesRead] = '\0';
|
||||
|
||||
fputs(buffer, stdout);
|
||||
}
|
||||
if (!ret)
|
||||
if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), ResultBuffer->LogBuffer, ResultBuffer->LogBufferLength, &bytesWritten, NULL))
|
||||
{
|
||||
error = GetLastError();
|
||||
goto cleanup;
|
||||
|
@ -79,6 +84,9 @@ cleanup:
|
|||
if (hDevice != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hDevice);
|
||||
|
||||
if (ResultBuffer)
|
||||
KmtFreeResultBuffer(ResultBuffer);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<library>ntdll</library>
|
||||
<library>hal</library>
|
||||
<library>pseh</library>
|
||||
<define name="KMT_KERNEL_MODE" />
|
||||
<directory name="kmtest_drv">
|
||||
<file>kmtest_drv.c</file>
|
||||
<file>log.c</file>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <ntddk.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <limits.h>
|
||||
#include <pseh/pseh2.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -19,9 +20,16 @@
|
|||
/* Prototypes */
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
static DRIVER_UNLOAD DriverUnload;
|
||||
static DRIVER_DISPATCH DriverCreateClose;
|
||||
static DRIVER_DISPATCH DriverCreate;
|
||||
static DRIVER_DISPATCH DriverClose;
|
||||
static DRIVER_DISPATCH DriverIoControl;
|
||||
static DRIVER_DISPATCH DriverRead;
|
||||
|
||||
/* Device Extension layout */
|
||||
typedef struct
|
||||
{
|
||||
PKMT_RESULTBUFFER ResultBuffer;
|
||||
PMDL Mdl;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
/* Globals */
|
||||
static PDEVICE_OBJECT MainDeviceObject;
|
||||
|
@ -43,6 +51,8 @@ NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING Re
|
|||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
UNICODE_STRING DeviceName;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
@ -55,7 +65,8 @@ NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING Re
|
|||
goto cleanup;
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Kmtest");
|
||||
Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN,
|
||||
Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DeviceName,
|
||||
FILE_DEVICE_UNKNOWN,
|
||||
FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE,
|
||||
TRUE, &MainDeviceObject);
|
||||
|
||||
|
@ -64,13 +75,14 @@ NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING Re
|
|||
|
||||
DPRINT("DriverEntry. Created DeviceObject %p\n",
|
||||
MainDeviceObject);
|
||||
MainDeviceObject->Flags |= DO_DIRECT_IO;
|
||||
DeviceExtension = MainDeviceObject->DeviceExtension;
|
||||
DeviceExtension->ResultBuffer = NULL;
|
||||
DeviceExtension->Mdl = NULL;
|
||||
|
||||
DriverObject->DriverUnload = DriverUnload;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreateClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverCreateClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverIoControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = DriverRead;
|
||||
|
||||
cleanup:
|
||||
if (MainDeviceObject && !NT_SUCCESS(Status))
|
||||
|
@ -100,15 +112,21 @@ static VOID NTAPI DriverUnload(IN PDRIVER_OBJECT DriverObject)
|
|||
DPRINT("DriverUnload\n");
|
||||
|
||||
if (MainDeviceObject)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = MainDeviceObject->DeviceExtension;
|
||||
ASSERT(!DeviceExtension->Mdl);
|
||||
ASSERT(!DeviceExtension->ResultBuffer);
|
||||
ASSERT(!ResultBuffer);
|
||||
IoDeleteDevice(MainDeviceObject);
|
||||
}
|
||||
|
||||
LogFree();
|
||||
}
|
||||
|
||||
/**
|
||||
* @name DriverCreateClose
|
||||
* @name DriverCreate
|
||||
*
|
||||
* Driver Dispatch function for CreateFile/CloseHandle.
|
||||
* Driver Dispatch function for CreateFile
|
||||
*
|
||||
* @param DeviceObject
|
||||
* Device Object
|
||||
|
@ -117,19 +135,66 @@ static VOID NTAPI DriverUnload(IN PDRIVER_OBJECT DriverObject)
|
|||
*
|
||||
* @return Status
|
||||
*/
|
||||
static NTSTATUS NTAPI DriverCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
static NTSTATUS NTAPI DriverCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverCreateClose. Function=%s, DeviceObject=%p\n",
|
||||
IoStackLocation->MajorFunction == IRP_MJ_CREATE ? "Create" : "Close",
|
||||
DPRINT("DriverCreate. DeviceObject=%p\n",
|
||||
DeviceObject);
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
ASSERT(!DeviceExtension->Mdl);
|
||||
ASSERT(!DeviceExtension->ResultBuffer);
|
||||
ASSERT(!ResultBuffer);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name DriverClose
|
||||
*
|
||||
* Driver Dispatch function for CloseHandle.
|
||||
*
|
||||
* @param DeviceObject
|
||||
* Device Object
|
||||
* @param Irp
|
||||
* I/O request packet
|
||||
*
|
||||
* @return Status
|
||||
*/
|
||||
static NTSTATUS NTAPI DriverClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverClose. DeviceObject=%p\n",
|
||||
DeviceObject);
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
if (DeviceExtension->Mdl)
|
||||
{
|
||||
MmUnlockPages(DeviceExtension->Mdl);
|
||||
IoFreeMdl(DeviceExtension->Mdl);
|
||||
DeviceExtension->Mdl = NULL;
|
||||
ResultBuffer = DeviceExtension->ResultBuffer = NULL;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
|
@ -223,6 +288,48 @@ static NTSTATUS NTAPI DriverIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir
|
|||
|
||||
break;
|
||||
}
|
||||
case IOCTL_KMTEST_SET_RESULTBUFFER:
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT("DriverIoControl. IOCTL_KMTEST_SET_RESULTBUFFER, inlen=%lu, outlen=%lu\n",
|
||||
IoStackLocation->Parameters.DeviceIoControl.InputBufferLength,
|
||||
IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength);
|
||||
|
||||
if (DeviceExtension->Mdl)
|
||||
{
|
||||
MmUnlockPages(DeviceExtension->Mdl);
|
||||
IoFreeMdl(DeviceExtension->Mdl);
|
||||
}
|
||||
|
||||
DeviceExtension->Mdl = IoAllocateMdl(IoStackLocation->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||
IoStackLocation->Parameters.DeviceIoControl.InputBufferLength,
|
||||
FALSE, FALSE, NULL);
|
||||
if (!DeviceExtension->Mdl)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
MmProbeAndLockPages(DeviceExtension->Mdl, KernelMode, IoModifyAccess);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
IoFreeMdl(DeviceExtension->Mdl);
|
||||
DeviceExtension->Mdl = NULL;
|
||||
break;
|
||||
} _SEH2_END;
|
||||
|
||||
ResultBuffer = DeviceExtension->ResultBuffer = MmGetSystemAddressForMdlSafe(DeviceExtension->Mdl, NormalPagePriority);
|
||||
|
||||
DPRINT("DriverIoControl. ResultBuffer: %ld %ld %ld %ld\n",
|
||||
ResultBuffer->Successes, ResultBuffer->Failures,
|
||||
ResultBuffer->LogBufferLength, ResultBuffer->LogBufferMaxLength);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DPRINT1("DriverIoControl. Invalid IoCtl code 0x%08X\n",
|
||||
IoStackLocation->Parameters.DeviceIoControl.IoControlCode);
|
||||
|
@ -237,46 +344,3 @@ static NTSTATUS NTAPI DriverIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Ir
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name DriverRead
|
||||
*
|
||||
* Driver Dispatch function for ReadFile.
|
||||
*
|
||||
* @param DeviceObject
|
||||
* Device Object
|
||||
* @param Irp
|
||||
* I/O request packet
|
||||
*
|
||||
* @return Status
|
||||
*/
|
||||
static NTSTATUS NTAPI DriverRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PVOID ReadBuffer;
|
||||
SIZE_T Length;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverRead. Offset=%I64u, Length=%lu, DeviceObject=%p\n",
|
||||
IoStackLocation->Parameters.Read.ByteOffset.QuadPart,
|
||||
IoStackLocation->Parameters.Read.Length,
|
||||
DeviceObject);
|
||||
|
||||
ReadBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||
|
||||
Length = LogRead(ReadBuffer, IoStackLocation->Parameters.Read.Length);
|
||||
|
||||
DPRINT("DriverRead. Length of data read: %lu\n",
|
||||
Length);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -9,14 +9,8 @@
|
|||
#include <ntstrsafe.h>
|
||||
|
||||
#include <kmt_log.h>
|
||||
|
||||
#define LOGBUFFER_MAX (1024UL * 1024)
|
||||
static PCHAR LogBuffer;
|
||||
static SIZE_T LogOffset;
|
||||
|
||||
#define LOG_TAG 'LtmK'
|
||||
|
||||
/* TODO: allow concurrent log buffer access */
|
||||
#define KMT_DEFINE_TEST_FUNCTIONS
|
||||
#include <kmt_test.h>
|
||||
|
||||
/**
|
||||
* @name LogInit
|
||||
|
@ -30,11 +24,6 @@ NTSTATUS LogInit(VOID)
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PAGED_CODE();
|
||||
|
||||
LogBuffer = ExAllocatePoolWithTag(NonPagedPool, LOGBUFFER_MAX, LOG_TAG);
|
||||
|
||||
if (!LogBuffer)
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -48,8 +37,6 @@ NTSTATUS LogInit(VOID)
|
|||
VOID LogFree(VOID)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
ExFreePoolWithTag(LogBuffer, LOG_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,10 +51,10 @@ VOID LogFree(VOID)
|
|||
*/
|
||||
VOID LogPrint(IN PCSTR Message)
|
||||
{
|
||||
SIZE_T MessageLength = strlen(Message);
|
||||
ASSERT(LogOffset + MessageLength + 1 < LOGBUFFER_MAX);
|
||||
RtlCopyMemory(&LogBuffer[LogOffset], Message, MessageLength + 1);
|
||||
LogOffset += MessageLength;
|
||||
size_t MessageLength;
|
||||
ASSERT(NT_SUCCESS(RtlStringCbLengthA(Message, 512, &MessageLength)));
|
||||
|
||||
KmtAddToLogBuffer(ResultBuffer, Message, MessageLength);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,47 +92,11 @@ VOID LogPrintF(IN PCSTR Format, ...)
|
|||
*/
|
||||
VOID LogVPrintF(IN PCSTR Format, va_list Arguments)
|
||||
{
|
||||
CHAR Buffer[1024];
|
||||
SIZE_T BufferLength;
|
||||
CHAR Buffer[512];
|
||||
/* TODO: make this work from any IRQL */
|
||||
PAGED_CODE();
|
||||
|
||||
RtlStringCbVPrintfA(Buffer, sizeof Buffer, Format, Arguments);
|
||||
|
||||
BufferLength = strlen(Buffer);
|
||||
ASSERT(LogOffset + BufferLength + 1 < LOGBUFFER_MAX);
|
||||
RtlCopyMemory(&LogBuffer[LogOffset], Buffer, BufferLength + 1);
|
||||
LogOffset += BufferLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name LogRead
|
||||
*
|
||||
* Retrieve data from the log buffer.
|
||||
*
|
||||
* @param Buffer
|
||||
* Buffer to copy log data to
|
||||
* @param BufferSize
|
||||
* Maximum number of bytes to copy
|
||||
*
|
||||
* @return Number of bytes copied
|
||||
*/
|
||||
SIZE_T LogRead(OUT PVOID Buffer, IN SIZE_T BufferSize)
|
||||
{
|
||||
SIZE_T Size;
|
||||
PAGED_CODE();
|
||||
|
||||
Size = min(BufferSize, LogOffset);
|
||||
RtlCopyMemory(Buffer, LogBuffer, Size);
|
||||
|
||||
if (BufferSize < LogOffset)
|
||||
{
|
||||
SIZE_T SizeLeft = LogOffset - BufferSize;
|
||||
RtlMoveMemory(LogBuffer, &LogBuffer[LogOffset], SizeLeft);
|
||||
LogOffset = SizeLeft;
|
||||
}
|
||||
else
|
||||
LogOffset = 0;
|
||||
|
||||
return Size;
|
||||
LogPrint(Buffer);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ntddk.h>
|
||||
#include <kmt_test.h>
|
||||
|
||||
KMT_TESTFUNC Test_Example;
|
||||
|
|
Loading…
Reference in a new issue