Example #1
0
static void
VMToolsLog(const gchar *domain,
           GLogLevelFlags level,
           const gchar *message,
           gpointer _data)
{
   LogHandler *data = _data;

   if (SHOULD_LOG(level, data)) {
      gchar *msg;

      data = data->inherited ? gDefaultData : data;
      msg = VMToolsLogFormat(message, domain, level, data);

      if (data->logger != NULL) {
         data->logger->logfn(domain, level, msg, data->logger);
      } else if (gErrorData->logger != NULL) {
         gErrorData->logger->logfn(domain, level, msg, gErrorData->logger);
      }
      g_free(msg);
   }
   if (IS_FATAL(level)) {
      VMToolsLogPanic();
   }
}
Example #2
0
static void
VMToolsLog(const gchar *domain,
           GLogLevelFlags level,
           const gchar *message,
           gpointer _data)
{
   LogHandler *data = _data;

   if (SHOULD_LOG(level, data)) {
      LogEntry *entry;

      data = data->inherited ? gDefaultData : data;

      entry = g_malloc0(sizeof(LogEntry));
      if (entry) {
         entry->domain = domain ? g_strdup(domain) : NULL;
         if (domain && !entry->domain) {
            VMToolsLogPanic();
         }
         entry->handler = data;
         entry->level = level;
      }

      if (gLogIOSuspended && data->needsFileIO) {
         if (gMaxCacheEntries == 0) {
            /* No way to log at this point, drop it */
            VMToolsFreeLogEntry(entry);
            gDroppedLogCount++;
            goto exit;
         }

         entry->msg = VMToolsLogFormat(message, domain, level, data, TRUE);

         /*
          * Cache the log message
          */
         if (!gCachedLogs) {

            /*
             * If gMaxCacheEntries > 1K, start with 1/4th size
             * to avoid frequent allocations
             */
            gCachedLogs = g_ptr_array_sized_new(gMaxCacheEntries < 1024 ?
                                                gMaxCacheEntries :
                                                gMaxCacheEntries/4);
            if (!gCachedLogs) {
               VMToolsLogPanic();
            }

            /*
             * Some builds use glib version 2.16.4 which does not
             * support g_ptr_array_set_free_func function
             */
         }

         /*
          * We don't expect logging to be suspended for a long time,
          * so we can avoid putting a cap on cache size. However, we
          * still have a default cap of 4K messages, just to be safe.
          */
         if (gCachedLogs->len < gMaxCacheEntries) {
            g_ptr_array_add(gCachedLogs, entry);
         } else {
            /*
             * Cache is full, drop the oldest log message. This is not
             * very efficient but we don't expect this to be a common
             * case anyway.
             */
            LogEntry *oldest = g_ptr_array_remove_index(gCachedLogs, 0);
            VMToolsFreeLogEntry(oldest);
            gDroppedLogCount++;

            g_ptr_array_add(gCachedLogs, entry);
         }

      } else {
         entry->msg = VMToolsLogFormat(message, domain, level, data, FALSE);
         VMToolsLogMsg(entry, NULL);
      }
   }

exit:
   if (IS_FATAL(level)) {
      VMToolsLogPanic();
   }
}
Example #3
0
VOID
SpyLogIrpCompletion (
    __in PIRP Irp,
    __inout PRECORD_LIST RecordList
)
/*++

Routine Description:

    Records the Irp necessary information according to LoggingFlags in
    RecordList.  For any activity on the Irp path of a device being
    logged, this function should get called twice: once on the IRPs
    originating path and once on the IRPs completion path.

Arguments:

    Irp - The Irp that contains the information we want to record.
    LoggingFlags - The flags that say what to log.
    RecordList - The PRECORD_LIST in which the Irp information is stored.

Return Value:

    None.

--*/
{
    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_OBJECT deviceObject = pIrpStack->DeviceObject;
    PRECORD_IRP pRecordIrp;

    //
    //  Process the log record
    //

    if (SHOULD_LOG( deviceObject )) {

        pRecordIrp = &RecordList->LogRecord.Record.RecordIrp;

        //
        // Record the information we use for a completion Irp.
        //

        pRecordIrp->ReturnStatus = Irp->IoStatus.Status;
        pRecordIrp->ReturnInformation = Irp->IoStatus.Information;
        KeQuerySystemTime(&pRecordIrp->CompletionTime);

        //
        //  Add RecordList to our gOutputBufferList so that it gets up to
        //  the user
        //

        SpyLog( RecordList );

    } else {

        if (RecordList) {

            //
            //  Context is set with a RECORD_LIST, but we are no longer
            //  logging so free this record.
            //

            SpyFreeRecord( RecordList );
        }
    }

    switch (pIrpStack->MajorFunction) {

    case IRP_MJ_CREATE:
        //
        //  If the operation failed remove the name from the cache because
        //  it is stale
        //

        if (!NT_SUCCESS(Irp->IoStatus.Status) &&
                (pIrpStack->FileObject != NULL)) {

            SpyNameDelete(pIrpStack->FileObject);
        }
        break;

    case IRP_MJ_CLOSE:

        //
        //  Always remove the name on close
        //

        SpyNameDelete(pIrpStack->FileObject);
        break;


    case IRP_MJ_SET_INFORMATION:
        //
        //  If the operation was successful and it was a rename, always
        //  remove the name.  They can re-get it next time.
        //

        if (NT_SUCCESS(Irp->IoStatus.Status) &&
                (FileRenameInformation ==
                 pIrpStack->Parameters.SetFile.FileInformationClass)) {

            SpyNameDelete(pIrpStack->FileObject);
        }
        break;
    }
}