summaryrefslogtreecommitdiff
path: root/src/ToolBox/superpmi/superpmi-shared/tocfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/superpmi/superpmi-shared/tocfile.cpp')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/tocfile.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/tocfile.cpp b/src/ToolBox/superpmi/superpmi-shared/tocfile.cpp
new file mode 100644
index 0000000000..c91ca89c93
--- /dev/null
+++ b/src/ToolBox/superpmi/superpmi-shared/tocfile.cpp
@@ -0,0 +1,79 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//----------------------------------------------------------
+// TOCFile.cpp - Abstraction for reading a TOC file
+//----------------------------------------------------------
+
+#include "standardpch.h"
+#include "tocfile.h"
+#include "logging.h"
+
+// Tries to load a Table of Contents
+void TOCFile::LoadToc(const char *inputFileName, bool validate)
+{
+ HANDLE hIndex = CreateFileA(inputFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (hIndex == INVALID_HANDLE_VALUE)
+ {
+ LogError("Failed to open file '%s'. GetLastError()=%u", inputFileName, GetLastError());
+ return;
+ }
+
+ // Now read the index file
+ LARGE_INTEGER val; // I'm abusing LARGE_INTEGER here...
+ DWORD read;
+ if (!ReadFile(hIndex, &val, sizeof(val), &read, nullptr) ||
+ (val.u.LowPart != *(DWORD *)("INDX")))
+ {
+ CloseHandle(hIndex);
+ LogWarning("The index file %s is invalid: it seems to be missing the starting sentinel/length", inputFileName);
+ return;
+ }
+
+ this->m_tocCount = val.u.HighPart;
+ this->m_tocArray = new TOCElement[this->m_tocCount];
+
+ // Read the whole array
+ if (!ReadFile(hIndex, &this->m_tocArray[0], (DWORD)(this->m_tocCount * sizeof(TOCElement)), &read, nullptr) ||
+ (read != (DWORD)(this->m_tocCount * sizeof(TOCElement))))
+ {
+ CloseHandle(hIndex);
+ this->Clear();
+ LogWarning("The index file %s is invalid: it appears to be truncated.", inputFileName);
+ return;
+ }
+
+ // Get the last 4 byte token (more abuse of LARGE_INTEGER)
+ if (!ReadFile(hIndex, &val.u.HighPart, sizeof(DWORD), &read, nullptr) ||
+ (read != sizeof(DWORD)) ||
+ (val.u.LowPart != val.u.HighPart))
+ {
+ CloseHandle(hIndex);
+ this->Clear();
+ LogWarning("The index file %s is invalid: it appears to be missing the ending sentinel.", inputFileName);
+ return;
+ }
+
+ CloseHandle(hIndex);
+
+ if (validate)
+ {
+ int lastNum = -1;
+
+ // Quickly validate that the index is sorted
+ for (size_t i = 0; i < this->m_tocCount; i++)
+ {
+ int nextNum = this->m_tocArray[i].Number;
+ if (nextNum <= lastNum)
+ {
+ // It wasn't sorted: abort
+ this->Clear();
+ LogWarning("The index file %s is invalid: it is not sorted.", inputFileName);
+ return;
+ }
+ lastNum = nextNum;
+ }
+ }
+}