/// <summary>
        /// Do intialization common to the contructors.  
        /// </summary>
        private void Init(string sessionName)
        {
            this.sessionHandle = TraceEventNativeMethods.INVALID_HANDLE_VALUE;
            if (sessionName.Length > MaxNameSize - 1)
                throw new ArgumentException("File name too long", "sessionName");

            this.sessionName = sessionName;
            properties = new TraceEventNativeMethods.EVENT_TRACE_PROPERTIES();
            properties.Wnode.Flags = TraceEventNativeMethods.WNODE_FLAG_TRACED_GUID;
            properties.LoggerNameOffset = (uint)Marshal.SizeOf(typeof(TraceEventNativeMethods.EVENT_TRACE_PROPERTIES));
            properties.LogFileNameOffset = properties.LoggerNameOffset + MaxNameSize * sizeof(char);
            extentionSpaceOffset = properties.LogFileNameOffset + MaxNameSize * sizeof(char);
            // #sizeCalculation
            properties.Wnode.BufferSize = extentionSpaceOffset + 8 + 8 * 4 + 4 + maxStackTraceProviders * 4;
            unmanagedPropertiesBuffer = TraceEventNativeMethods.AllocHGlobal((int) properties.Wnode.BufferSize);
            TraceEventNativeMethods.ZeroMemory(unmanagedPropertiesBuffer, properties.Wnode.BufferSize);
        }
        /// <summary>
        /// Open an existing Windows Event Tracing Session, with name 'sessionName'.
        /// 
        /// If you are opening a new session use TraceEventSession(string, string).
        ///  
        /// To support the illusion that you can have a session with both kernel and user events,
        /// TraceEventSession might start up both a kernel and a user session.   When you want to 'attach'
        /// to such a combined session, the constructor needs to know if you want to control the kernel
        /// session or not.  If attachKernelSession is true, then it opens both sessions (and thus 'Close'
        /// will operation on both sessions.
        /// </summary>
        public TraceEventSession(string sessionName, bool attachKernelSession)
        {
            Init(sessionName);
            int hr = TraceEventNativeMethods.ControlTrace(0UL, sessionName, ToUnmanagedBuffer(properties, null), TraceEventNativeMethods.EVENT_TRACE_CONTROL_QUERY);
            Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr));
            isActive = true;
            properties = (TraceEventNativeMethods.EVENT_TRACE_PROPERTIES)Marshal.PtrToStructure(unmanagedPropertiesBuffer, typeof(TraceEventNativeMethods.EVENT_TRACE_PROPERTIES));
            if (properties.LogFileNameOffset != 0)
                fileName = Marshal.PtrToStringUni((IntPtr)(unmanagedPropertiesBuffer.ToInt64() + properties.LogFileNameOffset));

            if (attachKernelSession)
            {
                bool success = false;
                try
                {
                    kernelSession = new TraceEventSession(KernelTraceEventParser.KernelSessionName);
                    success = true;
                }
                finally
                {
                    if (!success)
                        Stop();
                }
            }
        }