diff --git a/third_party/krabsetw/LICENSE b/third_party/krabsetw/LICENSE
new file mode 100644
index 0000000..a369f2b
--- /dev/null
+++ b/third_party/krabsetw/LICENSE
@@ -0,0 +1,25 @@
+krabsetw
+
+Copyright (c) Microsoft Corporation
+
+All rights reserved.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ""Software""), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/third_party/krabsetw/krabs/krabs/client.hpp b/third_party/krabsetw/krabs/krabs/client.hpp
new file mode 100644
index 0000000..010d9d3
--- /dev/null
+++ b/third_party/krabsetw/krabs/krabs/client.hpp
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#pragma once
+
+#include "compiler_check.hpp"
+#include "ut.hpp"
+#include "kt.hpp"
+#include "trace.hpp"
+
+namespace krabs {
+
+ /**
+ *
+ * Specialization of the base trace class for user traces.
+ *
+ */
+ typedef krabs::trace user_trace;
+
+ /**
+ *
+ * Specialization of the base trace class for kernel traces.
+ *
+ */
+ typedef krabs::trace kernel_trace;
+}
diff --git a/third_party/krabsetw/krabs/krabs/collection_view.hpp b/third_party/krabsetw/krabs/krabs/collection_view.hpp
new file mode 100644
index 0000000..be301a9
--- /dev/null
+++ b/third_party/krabsetw/krabs/krabs/collection_view.hpp
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#pragma once
+
+#include
+
+#include "compiler_check.hpp"
+
+namespace krabs {
+
+ /**
+ * Wraps a range of a collection starting at the location
+ * specified by the begin iterator and ending a the location
+ * specified by the end iterator. The underlying items are
+ * left in-place and should be considered const
+ */
+ template
+ struct collection_view
+ {
+ private:
+ const T beg_;
+ const T end_;
+
+ public:
+ /**
+ * Construct a new view for the range specified by the
+ * iterators 'begin' and 'end'
+ */
+ collection_view(const T begin, const T end)
+ : beg_(begin)
+ , end_(end)
+ { }
+
+ /**
+ * Get the iterator for the beginning of the view range
+ */
+ const T begin() const
+ {
+ return beg_;
+ }
+
+ /**
+ * Get the iterator for the end of the view range
+ */
+ const T end() const
+ {
+ return end_;
+ }
+ };
+
+ /**
+ * Create a view over the range specified by iterators 'begin' and 'end'
+ */
+ template
+ inline collection_view view(const T& begin, const T& end)
+ {
+ return{ begin, end };
+ }
+
+ /**
+ * Create a const_iterator view over the specified string
+ */
+ template
+ inline collection_view::const_iterator> view(const std::basic_string& string)
+ {
+ return{ string.cbegin(), string.cend() };
+ }
+
+ /**
+ * Create a const view over the range starting at 'begin' extending 'length' items
+ */
+ template
+ inline collection_view view(const T* begin, size_t length)
+ {
+ return{ begin, begin + length };
+ }
+
+ /**
+ * Create a const view over the specified array
+ */
+ template
+ inline collection_view view(const T(&arr)[n])
+ {
+ return{ arr, arr + n };
+ }
+
+} /* namespace krabs */
\ No newline at end of file
diff --git a/third_party/krabsetw/krabs/krabs/compiler_check.hpp b/third_party/krabsetw/krabs/krabs/compiler_check.hpp
new file mode 100644
index 0000000..85227a7
--- /dev/null
+++ b/third_party/krabsetw/krabs/krabs/compiler_check.hpp
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#pragma once
+
+#if (_MSC_VER < 1900)
+#error "krabsetw is only supported with Visual Studio 2015 and above (MSVC++ 14.0)"
+#endif
diff --git a/third_party/krabsetw/krabs/krabs/errors.hpp b/third_party/krabsetw/krabs/krabs/errors.hpp
new file mode 100644
index 0000000..046fbb1
--- /dev/null
+++ b/third_party/krabsetw/krabs/krabs/errors.hpp
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#pragma once
+
+#include
+
+#include "compiler_check.hpp"
+
+namespace krabs {
+
+ class trace_already_registered : public std::runtime_error {
+ public:
+ trace_already_registered()
+ : std::runtime_error("The trace session has already been registered")
+ {}
+ };
+
+ class invalid_parameter : public std::logic_error {
+ public:
+ invalid_parameter()
+ : std::logic_error("Invalid parameter given")
+ {}
+ };
+
+ class open_trace_failure : public std::runtime_error {
+ public:
+ open_trace_failure()
+ : std::runtime_error("Failure to open trace")
+ {}
+ };
+
+ class need_to_be_admin_failure : public std::runtime_error {
+ public:
+ need_to_be_admin_failure()
+ : std::runtime_error("Need to be an admin")
+ {}
+ };
+
+ class could_not_find_schema : public std::runtime_error {
+ public:
+ could_not_find_schema()
+ : std::runtime_error("Could not find the schema")
+ {}
+
+ could_not_find_schema(const std::string& context)
+ : std::runtime_error(std::string("Could not find the schema: ") + context)
+ {}
+ };
+
+ class type_mismatch_assert : public std::runtime_error {
+ public:
+ type_mismatch_assert(
+ const char* property,
+ const char* actual,
+ const char* requested)
+ : std::runtime_error(std::string("Attempt to read property '") +
+ property + "' type " + actual + " as " + requested)
+ {}
+ };
+
+ class no_trace_sessions_remaining : public std::runtime_error {
+ public:
+ no_trace_sessions_remaining()
+ : std::runtime_error("No more trace sessions available.")
+ {}
+ };
+
+ class function_not_supported : public std::runtime_error {
+ public:
+ function_not_supported()
+ : std::runtime_error("This function is not supported on this system.")
+ {}
+ };
+
+ class unexpected_error : public std::runtime_error {
+ public:
+ unexpected_error(ULONG status)
+ : std::runtime_error(std::string("An unexpected error occurred: status_code=") +
+ std::to_string(status))
+ {}
+
+ unexpected_error(const std::string &context)
+ : std::runtime_error(std::string("An unexpected error occurred: ") + context)
+ {}
+ };
+
+ inline std::string get_status_and_record_context(ULONG status, const EVENT_RECORD& record)
+ {
+ std::stringstream message;
+ message << "status_code="
+ << status
+ << " provider_id="
+ << std::to_string(record.EventHeader.ProviderId)
+ << " event_id="
+ << record.EventHeader.EventDescriptor.Id;
+
+ return message.str();
+ }
+
+ /**
+ * Checks for common ETW API error codes.
+ */
+ inline void error_check_common_conditions(ULONG status)
+ {
+ if (status == ERROR_SUCCESS) {
+ return;
+ }
+
+ switch (status) {
+ case ERROR_ALREADY_EXISTS:
+ throw krabs::trace_already_registered();
+ case ERROR_INVALID_PARAMETER:
+ throw krabs::invalid_parameter();
+ case ERROR_ACCESS_DENIED:
+ throw krabs::need_to_be_admin_failure();
+ case ERROR_NOT_FOUND:
+ throw krabs::could_not_find_schema();
+ case ERROR_NO_SYSTEM_RESOURCES:
+ throw krabs::no_trace_sessions_remaining();
+ case ERROR_NOT_SUPPORTED:
+ throw krabs::function_not_supported();
+ default:
+ throw krabs::unexpected_error(status);
+ }
+ }
+
+ /**
+ * Checks for common ETW API error codes and includes properties from the event record.
+ */
+ inline void error_check_common_conditions(ULONG status, const EVENT_RECORD &record)
+ {
+ if (status == ERROR_SUCCESS) {
+ return;
+ }
+
+ auto context = get_status_and_record_context(status, record);
+
+ switch (status) {
+ case ERROR_ALREADY_EXISTS:
+ throw krabs::trace_already_registered();
+ case ERROR_INVALID_PARAMETER:
+ throw krabs::invalid_parameter();
+ case ERROR_ACCESS_DENIED:
+ throw krabs::need_to_be_admin_failure();
+ case ERROR_NOT_FOUND:
+ throw krabs::could_not_find_schema(context);
+ case ERROR_NO_SYSTEM_RESOURCES:
+ throw krabs::no_trace_sessions_remaining();
+ case ERROR_NOT_SUPPORTED:
+ throw krabs::function_not_supported();
+ default:
+ throw krabs::unexpected_error(context);
+ }
+ }
+}
diff --git a/third_party/krabsetw/krabs/krabs/etw.hpp b/third_party/krabsetw/krabs/krabs/etw.hpp
new file mode 100644
index 0000000..0bc2265
--- /dev/null
+++ b/third_party/krabsetw/krabs/krabs/etw.hpp
@@ -0,0 +1,403 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+// Interface for ETW.
+
+#pragma once
+
+#define INITGUID
+
+#include "compiler_check.hpp"
+#include "trace.hpp"
+#include "errors.hpp"
+
+#include
+#include