diff --git a/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin.sln b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin.sln
new file mode 100644
index 0000000000..696b697898
--- /dev/null
+++ b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34330.188
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvLoggerDumpWin", "AdvLoggerDumpWin\AdvLoggerDumpWin.vcxproj", "{F983380B-B6C4-44EE-8835-0137E0876321}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|ARM64.Build.0 = Debug|ARM64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|x64.ActiveCfg = Debug|x64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|x64.Build.0 = Debug|x64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|x86.ActiveCfg = Debug|Win32
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Debug|x86.Build.0 = Debug|Win32
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|ARM64.Build.0 = Release|ARM64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|x64.ActiveCfg = Release|x64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|x64.Build.0 = Release|x64
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|x86.ActiveCfg = Release|Win32
+ {F983380B-B6C4-44EE-8835-0137E0876321}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {514003CD-1327-488E-9C4E-8761C728A1E3}
+ EndGlobalSection
+EndGlobal
diff --git a/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/AdvLoggerDumpWin.vcxproj b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/AdvLoggerDumpWin.vcxproj
new file mode 100644
index 0000000000..6faf8b2766
--- /dev/null
+++ b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/AdvLoggerDumpWin.vcxproj
@@ -0,0 +1,160 @@
+
+
+
+
+ true
+ true
+ true
+ true
+ 15.0
+ {f983380b-b6c4-44ee-8835-0137e0876321}
+ Win32Proj
+ AdvLoggerDumpWin
+ 10.0
+ 10.0.17134.0
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ Application
+ v143
+ v142
+ v141
+ v140
+ Unicode
+
+
+ true
+ true
+
+
+ false
+ true
+ true
+
+
+ Static
+
+
+ Static
+
+
+ Static
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NotUsing
+
+
+
+
+ _CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)
+ Level4
+ %(AdditionalOptions) /permissive- /bigobj
+
+
+
+
+ Disabled
+ _DEBUG;%(PreprocessorDefinitions)
+ ProgramDatabase
+ MultiThreadedDebugDLL
+ false
+ ProgramDatabase
+ false
+
+
+ Console
+ false
+ RequireAdministrator
+ RequireAdministrator
+ true
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+ MultiThreaded
+ MultiThreaded
+ Default
+ false
+
+
+ Console
+ false
+
+
+ false
+
+
+ RequireAdministrator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/ReadMe.md b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/ReadMe.md
new file mode 100644
index 0000000000..ab916944ab
--- /dev/null
+++ b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/ReadMe.md
@@ -0,0 +1,32 @@
+# AdvLoggerPkg - AdvLoggerDumpWin
+AdvLoggerDumpWin is used to retrieve the advanced UEFI debug log stored in system memory.
+
+## About
+If the Advanced Logger is enabled, the debug log is stored in memory and is available through the UEFI
+Variable store.
+This tool creates a Windows executable that writes the UEFI variable data to a binary log file. As the
+log in memory has additional metadata and alignment structure, DecodeUefiLog.py (in AdvLoggerPkg)
+parses the in-memory UefiLog to a text stream and writes the decoded log to a local file. The Python
+script can be used to both retrieve the log and decode it.
+AdvLoggerDumpWin is able to be used in systems without Python.
+
+## Usage:
+With administrator privileges, run the executable.
+In an administrator command prompt:
+```
+AdvLoggerDumpWin.exe
+```
+The program creates a new log file `new_logfile.bin` in the current directory.
+
+
+## Building
+To build the project, open the solution file in Visual Studio.
+Ensure you have the necessary dependencies.
+ * Microsoft.Windows.CppWinRT package
+ * Windows SDK
+ * VS build tools
+
+
+## Copyright
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
\ No newline at end of file
diff --git a/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.cpp b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.cpp
new file mode 100644
index 0000000000..d743400a03
--- /dev/null
+++ b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.cpp
@@ -0,0 +1,161 @@
+#include "main.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace winrt;
+using namespace Windows::Foundation;
+using namespace std;
+
+//
+// Elevate current process system environment privileges to access UEFI variables
+//
+static int ElevateCurrentPrivileges()
+{
+ HANDLE ProcessHandle = GetCurrentProcess();
+ DWORD DesiredAccess = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY;;
+ HANDLE hProcessToken;
+ TOKEN_PRIVILEGES tp;
+ LUID luid;
+ int Status = 0;
+
+ if (!LookupPrivilegeValue(NULL, L"SeSystemEnvironmentPrivilege", &luid)) {
+ Status = GetLastError();
+ cout << "Failed to lookup privilege value. Errno " << Status << endl;
+ return Status;
+ }
+
+ if (!OpenProcessToken(ProcessHandle, DesiredAccess, &hProcessToken)) {
+ Status = GetLastError();
+ cout << "Failed to open process token. Errno " << Status << endl;
+ return Status;
+ }
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if (!AdjustTokenPrivileges(hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
+ Status = GetLastError();
+ cout << "Failed to adjust token privileges. Errno " << Status << endl;
+ return Status;
+ }
+
+ if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
+ Status = (int)ERROR_NOT_ALL_ASSIGNED;
+ cout << "The token does not have the specified privilege. Errno " << Status << endl;
+ return Status;
+ }
+
+ CloseHandle(ProcessHandle);
+ return SUCCESS;
+}
+
+//
+// Create log file by retrieving AdvancedLogger variables from UEFI interface
+//
+int ReadLogFromUefiInterface(fstream& lfile)
+{
+ int Status = 0;
+ int i = 0;
+ DWORD length = 0;
+ DWORD err = 0;
+
+ stringstream varName;
+ char* varBuffer = (char *) malloc(MAX_VAR_LENGTH + 1);
+
+ // string to LPCWSTR conversion
+ string tmpGuid = "{a021bf2b-34ed-4a98-859c-420ef94f3e94}";
+ wstring tmpGuidW = wstring(tmpGuid.begin(), tmpGuid.end());
+ LPCWSTR guid = tmpGuidW.c_str();
+
+ //
+ // Parse variables by index until reached end of log
+ //
+ while (Status == 0) {
+ string tmpVarName = "V" + to_string(i);
+ wstring tmpVarNameW = wstring(tmpVarName.begin(), tmpVarName.end());
+ LPCWSTR varNameConst = tmpVarNameW.c_str();
+
+ // Retrieve one advanced logger indexed variable via kernel32 API
+ length = GetFirmwareEnvironmentVariableW(varNameConst, guid, varBuffer, MAX_VAR_LENGTH);
+
+ if (length == 0) {
+ err = GetLastError();
+
+ // If error is ERROR_NOT_FOUND (203), reached end of variables
+ if (err != 203) {
+ Status = EFI_ERROR;
+ cout << "Error reading variable " << tmpVarName << " errno: " << err << endl;
+ return Status;
+ }
+ else {
+ Status = (int)err;
+ }
+ }
+
+ if (Status == 0) {
+ i += 1;
+ streamsize varSize = (streamsize)length;
+ lfile.write(varBuffer, varSize);
+ if (lfile.fail()) {
+ cout << "Failed to write to file\n";
+ Status = CONS_ERROR;
+ return Status;
+ }
+ }
+ else if (i == 0) {
+ cout << "No variables found.\n";
+ return Status;
+ }
+ else {
+ cout << i << " variables read. " << lfile.tellg() << " chars written.\n";
+ }
+
+ if (varBuffer) {
+ ZeroMemory(varBuffer, MAX_VAR_LENGTH);
+ }
+ }
+
+ free(varBuffer);
+ return SUCCESS;
+}
+
+int main()
+{
+ fstream logfile;
+ const char* newRawFilename = ".\\new_logfile.bin";
+ int Status = 0;
+
+ Status = ElevateCurrentPrivileges();
+ if (Status !=0) {
+ cout << "Failed to elevate privileges, errno:" << Status << endl;
+ return Status;
+ }
+
+ // Create new binary logfile
+ logfile.open(newRawFilename, ios::out | ios::binary);
+ if (!logfile) {
+ cout << "Error opening file.\n";
+ Status = FILE_ERROR;
+ return Status;
+ }
+
+ Status = ReadLogFromUefiInterface(logfile);
+ if (Status != SUCCESS) {
+ cerr << "Error reading log, exiting.\n";
+ return LOG_ERROR;
+ }
+
+ logfile.close();
+ if (logfile.fail()) {
+ cout << "Error closing file.\n";
+ return FILE_ERROR;
+ }
+
+ return SUCCESS;
+}
+
\ No newline at end of file
diff --git a/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.h b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.h
new file mode 100644
index 0000000000..7d3ad496d5
--- /dev/null
+++ b/AdvLoggerPkg/Application/Windows/AdvLoggerDumpWin/main.h
@@ -0,0 +1,10 @@
+#pragma once
+#include
+#include
+
+#define EFI_ERROR 1
+#define CONS_ERROR 2
+#define FILE_ERROR 3
+#define LOG_ERROR 4
+#define SUCCESS 0
+#define MAX_VAR_LENGTH 1024*1024
\ No newline at end of file