Skip to content

Commit

Permalink
* filter/BusDogCommon.h:
Browse files Browse the repository at this point in the history
 * filter/BusDogTraceList.c:  
 * filter/BusDogMain.c: Added a manual queue for user mode trace buffer
   requests (with luck this will be a better design so that the requests
   would be pending to the user code and they do not have to poll for data)

 * gui/busdog/MainForm.cs:
 * gui/busdog/MainForm.Designer.cs:
 * gui/busdog/MainForm.resx:
 * gui/busdog/Native.cs: Added a thread to handle the blocking trace buffer ioctl
  • Loading branch information
djpnewton committed Nov 8, 2009
1 parent 0e81e66 commit 0a843f9
Show file tree
Hide file tree
Showing 8 changed files with 496 additions and 109 deletions.
22 changes: 18 additions & 4 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
2009-11-08 Daniel Newton <djpnewton@gmail.com>

* filter/BusDogCommon.h:
* filter/BusDogTraceList.c:
* filter/BusDogMain.c: Added a manual queue for user mode trace buffer
requests (with luck this will be a better design so that the requests
would be pending to the user code and they do not have to poll for data)

* gui/busdog/MainForm.cs:
* gui/busdog/MainForm.Designer.cs:
* gui/busdog/MainForm.resx:
* gui/busdog/Native.cs: Added a thread to handle the blocking trace buffer ioctl

2009-10-30 Daniel Newton <djpnewton@gmail.com>

* filter/BusDogMain.c:
Expand All @@ -12,17 +25,18 @@
* gui/busdog/VistaSecurity.cs: Added UAC elevation to driver
install/uninstall functions

2009-10-28 Daniel Newton <djpnewton@gmail.com>

* filter/busdog.inx:
* gui/busdog/Properties/AssemblyInfo.cs: Updated version to 0.2

2009-10-28 Daniel Newton <djpnewton@gmail.com>

* make_package.bat, gui/driverRes/build.xml: add debug symbols to release
packages

* filter/BusDogMain.c: removed obsolete WDM preprocess code

* filter/busdog.inx:
* gui/busdog/Properties/AssemblyInfo.cs:
Updated version to 0.2

2009-10-27 Daniel Newton <djpnewton@gmail.com>

* filter/busdog.inx: fix wdf section in inf
Expand Down
8 changes: 4 additions & 4 deletions filter/BusDogCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ BusDogAddTraceToFifo(
ULONG BufferLength
);

size_t
BusDogFillBufferWithTraces(
PVOID Buffer,
size_t BufferSize
NTSTATUS
BusDogFufillRequestWithTraces(
IN WDFREQUEST Request,
OUT size_t* bytesWritten
);

//
Expand Down
95 changes: 69 additions & 26 deletions filter/BusDogMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
//
WDFDEVICE ControlDevice = NULL;

//
// BufferRequestQueue is a manual queue to store trace buffer requests
// when an IOCTL_BUSDOG_GET_BUFFER request can not be fulfilled
// straight away
//
WDFQUEUE BufferRequestQueue;

#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, BusDogIoDeviceControl)
#pragma alloc_text (PAGE, BusDogCreateControlDevice)
Expand Down Expand Up @@ -504,6 +511,25 @@ Return Value:
goto Error;
}

//
// Create manual I/O queue to take care of user trace buffer requests
//
WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig, WdfIoQueueDispatchManual);

ioQueueConfig.PowerManaged = WdfFalse;

status = WdfIoQueueCreate(controlDevice,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&BufferRequestQueue);

if (!NT_SUCCESS(status))
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfIoQueueCreate failed 0x%x\n", status);

goto Error;
}

//
// Control devices must notify WDF when they are done initializing. I/O is
// rejected until this call is made.
Expand Down Expand Up @@ -601,7 +627,7 @@ Return Value:
NTSTATUS status = STATUS_SUCCESS;
ULONG i;
ULONG noItems;
WDFDEVICE hFilterDevice;
WDFDEVICE device;
PBUSDOG_CONTEXT context;
PVOID outputBuffer = NULL;
PBUSDOG_FILTER_ENABLED filterEnabledBuffer;
Expand Down Expand Up @@ -638,36 +664,53 @@ Return Value:
BusDogPrint(BUSDOG_DEBUG_INFO, "Get buffer\n");

//
// Get the output buffer...
// Try to fulfill the request with whats currently in the request buffer
//
status = WdfRequestRetrieveOutputBuffer(Request,
sizeof(BUSDOG_FILTER_TRACE),
&outputBuffer,
&realLength);

if (!NT_SUCCESS(status))
status = BusDogFufillRequestWithTraces(Request,
&bytesWritten);

if (!NT_SUCCESS(status))
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfRequestRetrieveOutputBuffer failed - 0x%x\n",
status);
if (status == STATUS_NO_DATA_DETECTED)
{
//
// Forward this read request to our manual queue
// (in other words, we are going to defer this request
// until we have some traces to match it with)
//

WdfRequestComplete(Request, status);
status = WdfRequestForwardToIoQueue(Request, BufferRequestQueue);

return;
if (NT_SUCCESS(status))
{
return;
}
else
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfRequestForwardToIoQueue failed Status 0x%x\n", status);
}
}
else
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "BusDogFufillRequestWithTraces failed Status 0x%x\n", status);
}
}

//
// Fill buffer with traces
//

bytesWritten = BusDogFillBufferWithTraces(outputBuffer, realLength);

//
// Yes! Return to the user, telling them how many bytes
// we copied....
//
WdfRequestCompleteWithInformation(Request,
STATUS_SUCCESS,
bytesWritten);
if (NT_SUCCESS(status))
{
//
// Yes! Return to the user, telling them how many bytes
// we copied....
//
WdfRequestCompleteWithInformation(Request,
STATUS_SUCCESS,
bytesWritten);
}
else
{
WdfRequestComplete(Request, status);
}

return;

Expand Down Expand Up @@ -753,9 +796,9 @@ Return Value:
// Get our device and context
//

hFilterDevice = WdfCollectionGetItem(BusDogDeviceCollection, i);
device = WdfCollectionGetItem(BusDogDeviceCollection, i);

context = BusDogGetDeviceContext(hFilterDevice);
context = BusDogGetDeviceContext(device);


if (filterEnabledBuffer->DeviceId == context->DeviceId)
Expand Down
139 changes: 127 additions & 12 deletions filter/BusDogTraceList.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
BUSDOG_FILTER_TRACE_FIFO BusDogTraceFifo;
WDFSPINLOCK BusDogTraceFifoLock;

//
// Import the queue that has all the pending requests for trace buffers
//
extern WDFQUEUE BufferRequestQueue;

NTSTATUS
__BusDogFufillRequestWithTraces(
IN WDFREQUEST Request,
OUT size_t* bytesWritten
);

NTSTATUS
BusDogTraceFifoInit(
WDFDRIVER Driver
Expand Down Expand Up @@ -154,9 +165,15 @@ BusDogAddTraceToFifo(
)
{
PBUSDOG_FILTER_TRACE_FIFO_ITEM pTraceItem = NULL;
WDFREQUEST request;
NTSTATUS status;

WdfSpinLockAcquire(BusDogTraceFifoLock);

//
// First add trace to the fifo
//

pTraceItem = BusDogTraceFifo.TraceItems[BusDogTraceFifo.WriteIndex];

pTraceItem =
Expand All @@ -181,6 +198,35 @@ BusDogAddTraceToFifo(
BusDogPrint(BUSDOG_DEBUG_ERROR, "On noes! We have overflow\n");
}

//
// Now see if we can complete a request from the manual queue
//

status = WdfIoQueueRetrieveNextRequest(
BufferRequestQueue,
&request);

if (NT_SUCCESS(status))
{
size_t bytesWritten;

status = __BusDogFufillRequestWithTraces(request, &bytesWritten);

//
// Ok for better or worse we finally completed this request
//

WdfRequestCompleteWithInformation(request, status, bytesWritten);
}
else
{
if (status != STATUS_NO_MORE_ENTRIES)
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfIoQueueRetrieveNextRequest failed - 0x%x\n",
status);
}
}

WdfSpinLockRelease(BusDogTraceFifoLock);
}

Expand Down Expand Up @@ -244,28 +290,35 @@ __BusDogRetrieveTraceSize(
return sizeof(BUSDOG_FILTER_TRACE) + pTrace->BufferSize;
}

size_t
BusDogFillBufferWithTraces(
//
// Assumes trace fifo already locked
//
NTSTATUS
__BusDogFillBufferWithTraces(
PVOID Buffer,
size_t BufferSize
size_t BufferSize,
OUT size_t* BytesWritten
)
{
PBUSDOG_FILTER_TRACE pTrace = NULL;

NTSTATUS status = STATUS_SUCCESS;
size_t TraceSize;

size_t BytesWritten = 0;

WdfSpinLockAcquire(BusDogTraceFifoLock);
*BytesWritten = 0;

while (TRUE)
{
TraceSize = __BusDogRetrieveTraceSize();

if (TraceSize > BufferSize - BytesWritten)
if (TraceSize > BufferSize - *BytesWritten)
{
BusDogPrint(BUSDOG_DEBUG_WARN, "No room for next trace\n");

if (*BytesWritten == 0)
{
status = STATUS_BUFFER_TOO_SMALL;
}

break;
}

Expand All @@ -275,23 +328,85 @@ BusDogFillBufferWithTraces(
{
BusDogPrint(BUSDOG_DEBUG_INFO, "No more traces\n");

if (*BytesWritten == 0)
{
status = STATUS_NO_DATA_DETECTED;
}

break;
}

BusDogPrint(BUSDOG_DEBUG_INFO, "Got trace %d\n", pTrace);

RtlCopyMemory((PCHAR)Buffer + BytesWritten,
RtlCopyMemory((PCHAR)Buffer + *BytesWritten,
pTrace,
TraceSize);

BytesWritten += TraceSize;
*BytesWritten += TraceSize;

BusDogPrint(BUSDOG_DEBUG_INFO, " Bytes written %d\n", BytesWritten);
BusDogPrint(BUSDOG_DEBUG_INFO, " Bytes written %d\n", *BytesWritten);
}

return status;
}

//
// Assumes trace fifo already locked
//
NTSTATUS
__BusDogFufillRequestWithTraces(
IN WDFREQUEST Request,
OUT size_t* bytesWritten
)
{
PVOID outputBuffer = NULL;
size_t realLength;
NTSTATUS status = STATUS_SUCCESS;

*bytesWritten = 0;

//
// Get the output buffer...
//
status = WdfRequestRetrieveOutputBuffer(Request,
sizeof(BUSDOG_FILTER_TRACE),
&outputBuffer,
&realLength);

if (NT_SUCCESS(status))
{
//
// Fill buffer with traces
//

status = __BusDogFillBufferWithTraces(outputBuffer,
realLength,
bytesWritten);
}
else
{
BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfRequestRetrieveOutputBuffer failed - 0x%x\n",
status);
}

return status;
}

NTSTATUS
BusDogFufillRequestWithTraces(
IN WDFREQUEST Request,
OUT size_t* bytesWritten
)
{
NTSTATUS status;

WdfSpinLockAcquire(BusDogTraceFifoLock);

status = __BusDogFufillRequestWithTraces(Request, bytesWritten);

WdfSpinLockRelease(BusDogTraceFifoLock);

return BytesWritten;
return status;
}


Loading

0 comments on commit 0a843f9

Please sign in to comment.