<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/extras/importer/etw/eventtrace_parser.html">
<link rel="import" href="/extras/importer/etw/process_parser.html">
<link rel="import" href="/extras/importer/etw/thread_parser.html">
<link rel="import" href="/importer/importer.html">
<link rel="import" href="/base/base64.html">
<link rel="import" href="/model/model.html">

<script>
/**
 * @fileoverview Imports JSON file with the raw payloads from a Windows event
 * trace into the Model. This format is outputted by Chrome running
 * on a Windows system.
 *
 * This importer assumes the events arrived as a JSON file and the payloads are
 * undecoded sequence of bytes in hex format string. The unit tests provide
 * examples of the trace format.
 *
 * The format of the system trace is
 *     {
 *       name: 'ETW',
 *       content: [ <events> ]
 *     }
  *
 * where the <events> are dictionary values with fields.
 *
 *     {
 *       guid: "1234-...",    // The unique GUID for the event.
 *       op: 12,              // The opcode of the event.
 *       ver: 1,              // The encoding version of the event.
 *       cpu: 0,              // The cpu id on which the event was captured.
 *       ts: 1092,            // The thread id on which the event was captured.
 *       payload: "aaaa"      // A base64 encoded string of the raw payload.
 *     }
 *
 * The payload is an undecoded version of the raw event sent by ETW.
 * This importer uses specific parsers to decode recognized events.
 * A parser need to register the recognized event by calling
 * registerEventHandler(guid, opcode, handler). The parser is responsible to
 * decode the payload and update the Model.
 *
 * The payload formats are described there:
 *   http://msdn.microsoft.com/en-us/library/windows/desktop/aa364085(v=vs.85).aspx
 *
 */
'use strict';

tr.exportTo('tr.e.importer.etw', function() {
  var Importer = tr.importer.Importer;

  // GUID and opcode of a Thread DCStart event, as defined at the link above.
  var kThreadGuid = '3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';
  var kThreadDCStartOpcode = 3;

  /**
   * Represents the raw bytes payload decoder.
   * @constructor
   */
  function Decoder() {
    this.payload_ = new DataView(new ArrayBuffer(256));
  };

  Decoder.prototype = {
    __proto__: Object.prototype,

    reset: function(base64_payload) {
      var decoded_size = tr.b.Base64.getDecodedBufferLength(base64_payload);
      if (decoded_size > this.payload_.byteLength)
        this.payload_ = new DataView(new ArrayBuffer(decoded_size));

      tr.b.Base64.DecodeToTypedArray(base64_payload, this.payload_);
      this.position_ = 0;
    },

    skip: function(length) {
      this.position_ += length;
    },

    decodeUInt8: function() {
      var result = this.payload_.getUint8(this.position_, true);
      this.position_ += 1;
      return result;
    },

    decodeUInt16: function() {
      var result = this.payload_.getUint16(this.position_, true);
      this.position_ += 2;
      return result;
    },

    decodeUInt32: function() {
      var result = this.payload_.getUint32(this.position_, true);
      this.position_ += 4;
      return result;
    },

    decodeUInt64ToString: function() {
      // Javascript isn't able to manage 64-bit numeric values.
      var low = this.decodeUInt32();
      var high = this.decodeUInt32();
      var low_str = ('0000000' + low.toString(16)).substr(-8);
      var high_str = ('0000000' + high.toString(16)).substr(-8);
      var result = high_str + low_str;
      return result;
    },

    decodeInt8: function() {
      var result = this.payload_.getInt8(this.position_, true);
      this.position_ += 1;
      return result;
    },

    decodeInt16: function() {
      var result = this.payload_.getInt16(this.position_, true);
      this.position_ += 2;
      return result;
    },

    decodeInt32: function() {
      var result = this.payload_.getInt32(this.position_, true);
      this.position_ += 4;
      return result;
    },

    decodeInt64ToString: function() {
      // Javascript isn't able to manage 64-bit numeric values.
      // Fallback to unsigned 64-bit hexa value.
      return this.decodeUInt64ToString();
    },

    decodeUInteger: function(is64) {
      if (is64)
        return this.decodeUInt64ToString();
      return this.decodeUInt32();
    },

    decodeString: function() {
      var str = '';
      while (true) {
        var c = this.decodeUInt8();
        if (!c)
          return str;
        str = str + String.fromCharCode(c);
      }
    },

    decodeW16String: function() {
      var str = '';
      while (true) {
        var c = this.decodeUInt16();
        if (!c)
          return str;
        str = str + String.fromCharCode(c);
      }
    },

    decodeFixedW16String: function(length) {
      var old_position = this.position_;
      var str = '';
      for (var i = 0; i < length; i++) {
        var c = this.decodeUInt16();
        if (!c)
          break;
        str = str + String.fromCharCode(c);
      }

      // Move the position after the fixed buffer (i.e. wchar[length]).
      this.position_ = old_position + 2 * length;
      return str;
    },

    decodeBytes: function(length) {
      var bytes = [];
      for (var i = 0; i < length; ++i) {
        var c = this.decodeUInt8();
        bytes.push(c);
      }
      return bytes;
    },

    decodeSID: function(is64) {
      // Decode the TOKEN_USER structure.
      var pSid = this.decodeUInteger(is64);
      var attributes = this.decodeUInt32();

      // Skip padding.
      if (is64)
        this.decodeUInt32();

      // Decode the SID structure.
      var revision = this.decodeUInt8();
      var subAuthorityCount = this.decodeUInt8();
      this.decodeUInt16();
      this.decodeUInt32();

      if (revision != 1)
        throw 'Invalid SID revision: could not decode the SID structure.';

      var sid = this.decodeBytes(4 * subAuthorityCount);

      return {
        pSid: pSid,
        attributes: attributes,
        sid: sid
      };
    },

    decodeSystemTime: function() {
      // Decode the SystemTime structure.
      var wYear = this.decodeInt16();
      var wMonth = this.decodeInt16();
      var wDayOfWeek = this.decodeInt16();
      var wDay = this.decodeInt16();
      var wHour = this.decodeInt16();
      var wMinute = this.decodeInt16();
      var wSecond = this.decodeInt16();
      var wMilliseconds = this.decodeInt16();
      return {
        wYear: wYear,
        wMonth: wMonth,
        wDayOfWeek: wDayOfWeek,
        wDay: wDay,
        wHour: wHour,
        wMinute: wMinute,
        wSecond: wSecond,
        wMilliseconds: wMilliseconds
      };
    },

    decodeTimeZoneInformation: function() {
      // Decode the TimeZoneInformation structure.
      var bias = this.decodeUInt32();
      var standardName = this.decodeFixedW16String(32);
      var standardDate = this.decodeSystemTime();
      var standardBias = this.decodeUInt32();
      var daylightName = this.decodeFixedW16String(32);
      var daylightDate = this.decodeSystemTime();
      var daylightBias = this.decodeUInt32();
      return {
        bias: bias,
        standardName: standardName,
        standardDate: standardDate,
        standardBias: standardBias,
        daylightName: daylightName,
        daylightDate: daylightDate,
        daylightBias: daylightBias
      };
    }

  };

  /**
   * Imports Windows ETW kernel events into a specified model.
   * @constructor
   */
  function EtwImporter(model, events) {
    this.importPriority = 3;
    this.model_ = model;
    this.events_ = events;
    this.handlers_ = {};
    this.decoder_ = new Decoder();
    this.walltime_ = undefined;
    this.ticks_ = undefined;
    this.is64bit_ = undefined;

    // A map of tids to their process pid. On Windows, the tid is global to
    // the system and doesn't need to belong to a process. As many events
    // only provide tid, this map allows to retrieve the parent process.
    this.tidsToPid_ = {};

    // Instantiate the parsers; this will register handlers for known events.
    var allTypeInfos = tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();
    this.parsers_ = allTypeInfos.map(
        function(typeInfo) {
          return new typeInfo.constructor(this);
        }, this);
  }

  /**
   * Guesses whether the provided events is from a Windows ETW trace.
   * The object must has a property named 'name' with the value 'ETW' and
   * a property 'content' with all the undecoded events.
   *
   * @return {boolean} True when events is a Windows ETW array.
   */
  EtwImporter.canImport = function(events) {
    if (!events.hasOwnProperty('name') ||
        !events.hasOwnProperty('content') ||
        events.name !== 'ETW') {
      return false;
    }

    return true;
  };

  EtwImporter.prototype = {
    __proto__: Importer.prototype,

    get model() {
      return this.model_;
    },

    createThreadIfNeeded: function(pid, tid) {
      this.tidsToPid_[tid] = pid;
    },

    removeThreadIfPresent: function(tid) {
      this.tidsToPid_[tid] = undefined;
    },

    getPidFromWindowsTid: function(tid) {
      if (tid == 0)
        return 0;
      var pid = this.tidsToPid_[tid];
      if (pid == undefined) {
        // Kernel threads are not defined.
        return 0;
      }
      return pid;
    },

    getThreadFromWindowsTid: function(tid) {
      var pid = this.getPidFromWindowsTid(tid);
      var process = this.model_.getProcess(pid);
      if (!process)
        return undefined;
      return process.getThread(tid);
    },

    /*
     * Retrieve the Cpu for a given cpuNumber.
     * @return {Cpu} A Cpu corresponding to the given cpuNumber.
     */
    getOrCreateCpu: function(cpuNumber) {
      var cpu = this.model_.kernel.getOrCreateCpu(cpuNumber);
      return cpu;
    },

    /**
     * Imports the data in this.events_ into this.model_.
     */
    importEvents: function(isSecondaryImport) {
      this.events_.content.forEach(this.parseInfo.bind(this));

      if (this.walltime_ == undefined || this.ticks_ == undefined)
        throw Error('Cannot find clock sync information in the system trace.');

      if (this.is64bit_ == undefined)
        throw Error('Cannot determine pointer size of the system trace.');

      this.events_.content.forEach(this.parseEvent.bind(this));
    },

    importTimestamp: function(timestamp) {
      var ts = parseInt(timestamp, 16);
      return (ts - this.walltime_ + this.ticks_) / 1000.;
    },

    parseInfo: function(event) {
      // Retrieve clock sync information.
      if (event.hasOwnProperty('guid') &&
          event.hasOwnProperty('walltime') &&
          event.hasOwnProperty('tick') &&
          event.guid === 'ClockSync') {
        this.walltime_ = parseInt(event.walltime, 16);
        this.ticks_ = parseInt(event.tick, 16);
      }

      // Retrieve pointer size information from a Thread.DCStart event.
      if (this.is64bit_ == undefined &&
          event.hasOwnProperty('guid') &&
          event.hasOwnProperty('op') &&
          event.hasOwnProperty('ver') &&
          event.hasOwnProperty('payload') &&
          event.guid === kThreadGuid &&
          event.op == kThreadDCStartOpcode) {
        var decoded_size = tr.b.Base64.getDecodedBufferLength(event.payload);

        if (event.ver == 1) {
          if (decoded_size >= 52)
            this.is64bit_ = true;
          else
            this.is64bit_ = false;
        } else if (event.ver == 2) {
          if (decoded_size >= 64)
            this.is64bit_ = true;
          else
            this.is64bit_ = false;
        } else if (event.ver == 3) {
          if (decoded_size >= 60)
            this.is64bit_ = true;
          else
            this.is64bit_ = false;
        }
      }

      return true;
    },

    parseEvent: function(event) {
      if (!event.hasOwnProperty('guid') ||
          !event.hasOwnProperty('op') ||
          !event.hasOwnProperty('ver') ||
          !event.hasOwnProperty('cpu') ||
          !event.hasOwnProperty('ts') ||
          !event.hasOwnProperty('payload')) {
        return false;
      }

      var timestamp = this.importTimestamp(event.ts);

      // Create the event header.
      var header = {
        guid: event.guid,
        opcode: event.op,
        version: event.ver,
        cpu: event.cpu,
        timestamp: timestamp,
        is64: this.is64bit_
      };

      // Set the payload to decode.
      var decoder = this.decoder_;
      decoder.reset(event.payload);

      // Retrieve the handler to decode the payload.
      var handler = this.getEventHandler(header.guid, header.opcode);
      if (!handler)
        return false;

      if (!handler(header, decoder)) {
        this.model_.importWarning({
          type: 'parse_error',
          message: 'Malformed ' + header.guid + ' event (' + text + ')'
        });
        return false;
      }

      return true;
    },

    /**
     * Registers a windows ETW event handler used by parseEvent().
     */
    registerEventHandler: function(guid, opcode, handler) {
      if (this.handlers_[guid] == undefined)
        this.handlers_[guid] = [];
      this.handlers_[guid][opcode] = handler;
    },

    /**
     * Retrieves a registered event handler.
     */
    getEventHandler: function(guid, opcode) {
      if (this.handlers_[guid] == undefined)
        return undefined;
      return this.handlers_[guid][opcode];
    }

  };

  // Register the EtwImporter to the Importer.
  tr.importer.Importer.register(EtwImporter);

  return {
    EtwImporter: EtwImporter
  };
});
</script>
