1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FileUtilsWin.h"
12 #include "base/process_util.h"
13 #include "mozilla/ProfilerLabels.h"
14 #include "mozilla/ScopeExit.h"
15 #include "mozilla/Unused.h"
16 #include "nsWindowsHelpers.h"
20 bool HandleToFilename(HANDLE aHandle
, const LARGE_INTEGER
& aOffset
,
21 nsAString
& aFilename
) {
22 AUTO_PROFILER_LABEL("HandletoFilename", OTHER
);
25 // This implementation is nice because it uses fully documented APIs that
26 // are available on all Windows versions that we support.
27 nsAutoHandle
fileMapping(
28 CreateFileMapping(aHandle
, nullptr, PAGE_READONLY
, 0, 1, nullptr));
32 const auto view
= MapViewOfFile(fileMapping
, FILE_MAP_READ
, aOffset
.HighPart
,
38 MakeScopeExit([&]() { mozilla::Unused
<< UnmapViewOfFile(view
); });
40 nsAutoString mappedFilename
;
42 SetLastError(ERROR_SUCCESS
);
44 mappedFilename
.SetLength(mappedFilename
.Length() + MAX_PATH
);
45 len
= GetMappedFileNameW(GetCurrentProcess(), view
, mappedFilename
.get(),
46 mappedFilename
.Length());
47 } while (!len
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
51 mappedFilename
.Truncate(len
);
52 return NtPathToDosPath(mappedFilename
, aFilename
);
57 RVAMap(HANDLE map
, DWORD offset
) {
62 (offset
/ info
.dwAllocationGranularity
) * info
.dwAllocationGranularity
;
64 MOZ_ASSERT(offset
- alignedOffset
< info
.dwAllocationGranularity
, "Wtf");
66 mRealView
= ::MapViewOfFile(map
, FILE_MAP_READ
, 0, alignedOffset
,
67 sizeof(T
) + (offset
- alignedOffset
));
71 ? reinterpret_cast<T
*>((char*)mRealView
+ (offset
- alignedOffset
))
76 ::UnmapViewOfFile(mRealView
);
79 operator const T
*() const { return mMappedView
; }
80 const T
* operator->() const { return mMappedView
; }
87 uint32_t GetExecutableArchitecture(const wchar_t* aPath
) {
88 nsAutoHandle
file(::CreateFileW(aPath
, GENERIC_READ
, FILE_SHARE_READ
, nullptr,
89 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
,
92 return base::PROCESS_ARCH_INVALID
;
96 ::CreateFileMappingW(file
, nullptr, PAGE_READONLY
, 0, 0, nullptr));
98 return base::PROCESS_ARCH_INVALID
;
101 RVAMap
<IMAGE_DOS_HEADER
> peHeader(map
, 0);
103 return base::PROCESS_ARCH_INVALID
;
106 RVAMap
<IMAGE_NT_HEADERS
> ntHeader(map
, peHeader
->e_lfanew
);
108 return base::PROCESS_ARCH_INVALID
;
111 switch (ntHeader
->FileHeader
.Machine
) {
112 case IMAGE_FILE_MACHINE_I386
:
113 return base::PROCESS_ARCH_I386
;
114 case IMAGE_FILE_MACHINE_AMD64
:
115 return base::PROCESS_ARCH_X86_64
;
116 case IMAGE_FILE_MACHINE_ARM64
:
117 return base::PROCESS_ARCH_ARM_64
;
118 case IMAGE_FILE_MACHINE_ARM
:
119 case IMAGE_FILE_MACHINE_ARMNT
:
120 case IMAGE_FILE_MACHINE_THUMB
:
121 return base::PROCESS_ARCH_ARM
;
123 return base::PROCESS_ARCH_INVALID
;
127 } // namespace mozilla