This web page refers to our older busTRACE 6.0 which is no longer shipping. Click here for details on our latest generation busTRACE software.
This WEB page comes from the busTRACE 6.0 User's Manual. (Table of Contents)
While you are capturing I/O activity with busTRACE, you can also type in and insert your own message into the capture buffer. In addition, if you are a Windows software developer, you can also have your software communicate with busTRACE and have it insert any text into the capture buffer. This can help you document what is going on during the capture sequence. For example, let's say you have written a file system driver for a removable media device. You start a busTRACE capture and insert the media. In your file system driver, you may want to inject messages into the capture buffer such as:
By injecting these text messages, you can see the I/O activity that occurs before and after key events that you insert into the capture buffer. There are two methods you can use to inject a text message into the busTRACE capture buffer. One is from a device driver; the other from a Windows application. Both methods are only valid if busTRACE is active capturing I/O activity. Injecting Text Messages from a Device Driver - Method #1We provide two different methods, from a kernel driver, to inject a text message into the busTRACE capture buffer. When text messages are inserted into the buffer, they appear in the I/O Capture List window along with the time the message was sent. This first method, method #1, is the most flexible way to inject messages into the capture buffer. It is, however, only supported with busTRACE 6.0.035 (and above). Here is sample code for kernel method #1: typedef NTSTATUS (*PBT_ADD_STRING_DISPATCH) (IN LPCTSTR strMsg); PBT_ADD_STRING_DISPATCH pMsgInjectFunc=NULL;
PFILE_OBJECT pFileObject = NULL; PDEVICE_OBJECT pDeviceObject = NULL; UNICODE_STRING NtDeviceName; RtlInitUnicodeString ( &NtDeviceName, L"\\Device\\BUSTRCE6" ); NTSTATUS nStatus = IoGetDeviceObjectPointer ( &NtDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject ); if ( NT_SUCCESS(nStatus) ) { PIRP Irp; KEVENT event; IO_STATUS_BLOCK ioStatus; NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest ( 0x80002034, pDeviceObject, NULL, 0 , &pMsgInjectFunc, sizeof(pMsgInjectFunc), FALSE, &event, &ioStatus ); if ( Irp ) { status = IoCallDriver(pDeviceObject, Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); status = ioStatus.Status; } if ( NT_SUCCESS(status) && pMsgInjectFunc) { // At this point, you have our message inject API that you can call directly. // You can call this function at IRQL <= DISPATCH_LEVEL. In this example, // we'll go ahead and insert a "test" message here.
status = pMsgInjectFunc("This is a test");
// If a value of 0xE0008007 is returned, then a busTRACE capture // is not active. } } }
Injecting Text Messages from a Device Driver - Method #2Our second method to inject message into the kernel driver is supported in all versions of busTRACE 6.0. It is less optimal than Method #1 above since it requires an IOCTL to be sent each time you want to inject a message into the capture buffer. If you have written a Windows device driver (i.e. kernel driver), you can inject a text message into the busTRACE capture buffer by submitting an IOCTL to our driver. Here is sample code for kernel method #2: PFILE_OBJECT pFileObject = NULL; PDEVICE_OBJECT pDeviceObject = NULL; UNICODE_STRING NtDeviceName; RtlInitUnicodeString ( &NtDeviceName, L"\\Device\\BUSTRCE6" ); NTSTATUS nStatus = IoGetDeviceObjectPointer ( &NtDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject ); if ( NT_SUCCESS(nStatus) ) { PIRP Irp; KEVENT event; IO_STATUS_BLOCK ioStatus; NTSTATUS status; char* strMsg = "Submitting this text message to busTRACE!";
KeInitializeEvent(&event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest ( 0x80002024, pDeviceObject, strMsg, strlen(strMsg)+1, NULL, NULL, FALSE, &event, &ioStatus ); if ( Irp ) { status = IoCallDriver(pDeviceObject, Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); status = ioStatus.Status; } if ( NT_SUCCESS(status) ) { // Message added to busTRACE capture buffer!!! } } } The sample code is relatively straight-forward. The sequence of events are as follows:
The call to IoCallDriver will fail with an error code of 0xE0008007 if the busTRACE capture is not active. If a successful status is returned, then the text message has been "injected" into the busTRACE capture buffer. Injecting Text Messages from a Windows ApplicationIf you have written a Windows application (i.e. ring 3 application), you can inject a text message into the busTRACE capture buffer by submitting an IOCTL to our driver. The best way to describe this is by way of sample source code. HANDLE hBustrace = ::CreateFile ( "\\\\.\\bustrce6", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL ); if ( hBustrace != INVALID_HANDLE_VALUE ) { char* strMessage = "Submitting this text message to busTRACE!";
// You *MUST* include the NULL terminator in the byte count as we do below DWORD nBytesReturned = 0; BOOL bStatus = ::DeviceIoControl ( hBustrace, 0x80002024, strMessage, (ULONG)(strlen(strMessage)+1), NULL, NULL, &nBytesReturned, NULL ); if ( bStatus ) { // If here, messages was injected successfully } else { HRESULT hr = ::GetLastError(); // If a value of 0xE0008007 is returned, then a busTRACE capture // is not active. }
::CloseHandle(hBustrace); } The sample code is relatively straight-forward. The sequence of events are as follows:
The call to DeviceIoControl will fail with an error code of 0xE0008007 if the busTRACE capture is not active. If a successful status is returned, then the text message has been "injected" into the busTRACE capture buffer. See Also: |
|