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.

busTRACE 6.0 This WEB page comes from the busTRACE 6.0 User's Manual. (Table of Contents)

Previous Topic Next Topic
 

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:

  • Initiating media mount process
  • New media detected
  • Media mount complete
  • etc.

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 #1

We 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 #2

Our 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:

  1. We start by using IoGetDeviceObjectPointer to get a pointer to the busTRACE driver device object. If this call fails, then the busTRACE driver is not resident on this system.
  2. We then use IoBuildDeviceIoControlRequest to allocate and setup an IRP for the device control request we want to send. You use an IOCTL value of 0x80002024 to submit the request. Notice how we also submit a pointer to the text message we want to inject as well as its buffer length.
  3. Once the IRP is initialized, we submit the request to the busTRACE kernel driver by using the IoCallDriver API.

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 Application

If 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:

  1. We start by using CreateFile to get a handle to the busTRACE driver. If this call returns INVALID_HANDLE_VALUE, then the busTRACE driver is not resident on this system.
  2. We then use DeviceIoControl to submit the IOCTL request to the driver. You use an IOCTL value of 0x80002024 to submit the request. Notice how we also submit a pointer to the text message we want to inject as well as its buffer length.

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: