summaryrefslogtreecommitdiff
path: root/src/ToolBox/superpmi/superpmi/filecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/superpmi/superpmi/filecache.cpp')
-rw-r--r--src/ToolBox/superpmi/superpmi/filecache.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/ToolBox/superpmi/superpmi/filecache.cpp b/src/ToolBox/superpmi/superpmi/filecache.cpp
new file mode 100644
index 0000000000..dcd783a09b
--- /dev/null
+++ b/src/ToolBox/superpmi/superpmi/filecache.cpp
@@ -0,0 +1,150 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+// TODO-Cleanup: this class is unused
+
+#include "standardpch.h"
+#include "filecache.h"
+
+#define FileCacheSize 0xFFFFFF //needs to be bigger than the biggest read request.
+
+HANDLE FileCache::cachedHandle;
+bool FileCache::openAsCache;
+BYTE *FileCache::rawBuff;
+unsigned int FileCache::offset;
+unsigned int FileCache::length;
+__int64 FileCache::fileoffset;
+
+HANDLE
+FileCache::CreateFileA(
+ _In_ LPCSTR lpFileName,
+ _In_ DWORD dwDesiredAccess,
+ _In_ DWORD dwShareMode,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ _In_ DWORD dwCreationDisposition,
+ _In_ DWORD dwFlagsAndAttributes,
+ _In_opt_ HANDLE hTemplateFile
+ )
+{
+ openAsCache = false;
+ rawBuff = nullptr;
+ offset = 0;
+ length = 0;
+
+ if((dwShareMode&CACHE_THIS_FILE)==CACHE_THIS_FILE)
+ {
+ dwShareMode ^= CACHE_THIS_FILE;
+ openAsCache = true;
+ }
+ HANDLE temp = ::CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+ if(openAsCache)
+ cachedHandle = temp; //yes yes.. this is unsafe.. but one accessor now is okay. bswhack
+ return temp;
+}
+
+HANDLE
+FileCache::CreateFileW(
+ _In_ LPCWSTR lpFileName,
+ _In_ DWORD dwDesiredAccess,
+ _In_ DWORD dwShareMode,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ _In_ DWORD dwCreationDisposition,
+ _In_ DWORD dwFlagsAndAttributes,
+ _In_opt_ HANDLE hTemplateFile
+ )
+{
+ openAsCache = false;
+ rawBuff = nullptr;
+ offset = 0;
+ length = 0;
+ return ::CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+}
+
+
+//Somewhat sloppy quick copy... we don't treat lpNumberOfBytesRead etc correctly
+BOOL
+FileCache::ReadFile(
+ _In_ HANDLE hFile,
+ _Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer,
+ _In_ DWORD nNumberOfBytesToRead,
+ _Out_opt_ LPDWORD lpNumberOfBytesRead,
+ _Inout_opt_ LPOVERLAPPED lpOverlapped
+ )
+{
+ if(!openAsCache)
+ return ::ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
+ else
+ {
+ if(rawBuff == nullptr)
+ {
+ rawBuff = new BYTE[FileCacheSize];
+ length = FileCacheSize;
+ offset = FileCacheSize;
+ }
+ if(nNumberOfBytesToRead > FileCacheSize)
+ {
+ printf("ERROR: nNumberOfBytesToRead exceeds FileCacheSize %u > %u\n", nNumberOfBytesToRead, FileCacheSize);
+ __debugbreak();
+ }
+ if((offset+nNumberOfBytesToRead) > length)
+ {
+ memmove(rawBuff, &rawBuff[offset], length-offset); //Use memmove since we have overlapping regions more than half the time
+ ::ReadFile(hFile, &rawBuff[length-offset], offset, lpNumberOfBytesRead, lpOverlapped);
+ if(*lpNumberOfBytesRead ==0)
+ __debugbreak();
+ length -= offset-(*lpNumberOfBytesRead);
+ LARGE_INTEGER DataTemp;
+ LARGE_INTEGER zero;
+ zero.QuadPart = 0;
+ ::SetFilePointerEx(hFile, zero, &DataTemp, FILE_CURRENT);
+ fileoffset = DataTemp.QuadPart;
+
+ offset = 0;
+ }
+ memcpy(lpBuffer, &rawBuff[offset], nNumberOfBytesToRead);
+ offset+=nNumberOfBytesToRead;
+ if(offset > FileCacheSize)
+ __debugbreak();
+ return true;
+ }
+}
+
+BOOL
+FileCache::WriteFile(
+ _In_ HANDLE hFile,
+ _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
+ _In_ DWORD nNumberOfBytesToWrite,
+ _Out_opt_ LPDWORD lpNumberOfBytesWritten,
+ _Inout_opt_ LPOVERLAPPED lpOverlapped
+ )
+{
+ if(!openAsCache)
+ return ::WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
+ else
+ {
+ printf("ERROR: We only support one file open via the cache.\n");
+ __debugbreak();
+ return false;
+ }
+}
+
+BOOL
+FileCache::CloseHandle(
+ _In_ HANDLE hObject
+ )
+{
+ if(!openAsCache)
+ return ::CloseHandle(hObject);
+ else
+ {
+ if(rawBuff!=nullptr)
+ delete []rawBuff;
+ return ::CloseHandle(hObject);
+ }
+}
+__int64 FileCache::GetFilePos(HANDLE hFile)
+{
+ return (fileoffset - (__int64)length) + (__int64)offset;
+}