Bug 1700051: part 32) Move `InvalidateWords` to `SoftText`. r=smaug
[gecko.git] / xpcom / base / nsWindowsHelpers.h
blob6f4e7db7616b423beb92c04f2f3134aa49ad076b
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 // NB: This code may be used from non-XPCOM code, in particular, the
8 // Windows Default Browser Agent.
10 #ifndef nsWindowsHelpers_h
11 #define nsWindowsHelpers_h
13 #include <windows.h>
14 #include "nsAutoRef.h"
15 #include "mozilla/Assertions.h"
16 #include "mozilla/UniquePtr.h"
18 // ----------------------------------------------------------------------------
19 // Critical Section helper class
20 // ----------------------------------------------------------------------------
22 class AutoCriticalSection {
23 public:
24 explicit AutoCriticalSection(LPCRITICAL_SECTION aSection)
25 : mSection(aSection) {
26 ::EnterCriticalSection(mSection);
28 ~AutoCriticalSection() { ::LeaveCriticalSection(mSection); }
30 private:
31 LPCRITICAL_SECTION mSection;
34 template <>
35 class nsAutoRefTraits<HKEY> {
36 public:
37 typedef HKEY RawRef;
38 static HKEY Void() { return nullptr; }
40 static void Release(RawRef aFD) {
41 if (aFD != Void()) {
42 RegCloseKey(aFD);
47 template <>
48 class nsAutoRefTraits<HDC> {
49 public:
50 typedef HDC RawRef;
51 static HDC Void() { return nullptr; }
53 static void Release(RawRef aFD) {
54 if (aFD != Void()) {
55 ::DeleteDC(aFD);
60 template <>
61 class nsAutoRefTraits<HFONT> {
62 public:
63 typedef HFONT RawRef;
64 static HFONT Void() { return nullptr; }
66 static void Release(RawRef aFD) {
67 if (aFD != Void()) {
68 ::DeleteObject(aFD);
73 template <>
74 class nsAutoRefTraits<HBRUSH> {
75 public:
76 typedef HBRUSH RawRef;
77 static HBRUSH Void() { return nullptr; }
79 static void Release(RawRef aFD) {
80 if (aFD != Void()) {
81 ::DeleteObject(aFD);
86 template <>
87 class nsAutoRefTraits<HRGN> {
88 public:
89 typedef HRGN RawRef;
90 static HRGN Void() { return nullptr; }
92 static void Release(RawRef aFD) {
93 if (aFD != Void()) {
94 ::DeleteObject(aFD);
99 template <>
100 class nsAutoRefTraits<HBITMAP> {
101 public:
102 typedef HBITMAP RawRef;
103 static HBITMAP Void() { return nullptr; }
105 static void Release(RawRef aFD) {
106 if (aFD != Void()) {
107 ::DeleteObject(aFD);
112 template <>
113 class nsAutoRefTraits<SC_HANDLE> {
114 public:
115 typedef SC_HANDLE RawRef;
116 static SC_HANDLE Void() { return nullptr; }
118 static void Release(RawRef aFD) {
119 if (aFD != Void()) {
120 CloseServiceHandle(aFD);
125 template <>
126 class nsSimpleRef<HANDLE> {
127 protected:
128 typedef HANDLE RawRef;
130 nsSimpleRef() : mRawRef(nullptr) {}
132 explicit nsSimpleRef(RawRef aRawRef) : mRawRef(aRawRef) {}
134 bool HaveResource() const {
135 return mRawRef && mRawRef != INVALID_HANDLE_VALUE;
138 public:
139 RawRef get() const { return mRawRef; }
141 static void Release(RawRef aRawRef) {
142 if (aRawRef && aRawRef != INVALID_HANDLE_VALUE) {
143 CloseHandle(aRawRef);
146 RawRef mRawRef;
149 template <>
150 class nsAutoRefTraits<HMODULE> {
151 public:
152 typedef HMODULE RawRef;
153 static RawRef Void() { return nullptr; }
155 static void Release(RawRef aFD) {
156 if (aFD != Void()) {
157 FreeLibrary(aFD);
162 template <>
163 class nsAutoRefTraits<DEVMODEW*> {
164 public:
165 typedef DEVMODEW* RawRef;
166 static RawRef Void() { return nullptr; }
168 static void Release(RawRef aDevMode) {
169 if (aDevMode != Void()) {
170 ::HeapFree(::GetProcessHeap(), 0, aDevMode);
175 // HGLOBAL is just a typedef of HANDLE which nsSimpleRef has a specialization
176 // of, that means having a nsAutoRefTraits specialization for HGLOBAL is
177 // useless. Therefore we create a wrapper class for HGLOBAL to make
178 // nsAutoRefTraits and nsAutoRef work as intention.
179 class nsHGLOBAL {
180 public:
181 MOZ_IMPLICIT nsHGLOBAL(HGLOBAL hGlobal) : m_hGlobal(hGlobal) {}
183 operator HGLOBAL() const { return m_hGlobal; }
185 private:
186 HGLOBAL m_hGlobal;
189 template <>
190 class nsAutoRefTraits<nsHGLOBAL> {
191 public:
192 typedef nsHGLOBAL RawRef;
193 static RawRef Void() { return nullptr; }
195 static void Release(RawRef hGlobal) { ::GlobalFree(hGlobal); }
198 // Because Printer's HANDLE uses ClosePrinter and we already have
199 // nsAutoRef<HANDLE> which uses CloseHandle so we need to create a wrapper class
200 // for HANDLE to have another specialization for nsAutoRefTraits.
201 class nsHPRINTER {
202 public:
203 MOZ_IMPLICIT nsHPRINTER(HANDLE hPrinter) : m_hPrinter(hPrinter) {}
205 operator HANDLE() const { return m_hPrinter; }
207 HANDLE* operator&() { return &m_hPrinter; }
209 private:
210 HANDLE m_hPrinter;
213 // winspool.h header has AddMonitor macro, it conflicts with AddMonitor member
214 // function in TaskbarPreview.cpp and TaskbarTabPreview.cpp. Beside, we only
215 // need ClosePrinter here for Release function, so having its prototype is
216 // enough.
217 extern "C" BOOL WINAPI ClosePrinter(HANDLE hPrinter);
219 template <>
220 class nsAutoRefTraits<nsHPRINTER> {
221 public:
222 typedef nsHPRINTER RawRef;
223 static RawRef Void() { return nullptr; }
225 static void Release(RawRef hPrinter) { ::ClosePrinter(hPrinter); }
228 typedef nsAutoRef<HKEY> nsAutoRegKey;
229 typedef nsAutoRef<HDC> nsAutoHDC;
230 typedef nsAutoRef<HFONT> nsAutoFont;
231 typedef nsAutoRef<HBRUSH> nsAutoBrush;
232 typedef nsAutoRef<HRGN> nsAutoRegion;
233 typedef nsAutoRef<HBITMAP> nsAutoBitmap;
234 typedef nsAutoRef<SC_HANDLE> nsAutoServiceHandle;
235 typedef nsAutoRef<HANDLE> nsAutoHandle;
236 typedef nsAutoRef<HMODULE> nsModuleHandle;
237 typedef nsAutoRef<DEVMODEW*> nsAutoDevMode;
238 typedef nsAutoRef<nsHGLOBAL> nsAutoGlobalMem;
239 typedef nsAutoRef<nsHPRINTER> nsAutoPrinter;
241 namespace {
243 // Construct a path "<system32>\<aModule>". return false if the output buffer
244 // is too small.
245 // Note: If the system path cannot be found, or doesn't fit in the output buffer
246 // with the module name, we will just ignore the system path and output the
247 // module name alone;
248 // this may mean using a normal search path wherever the output is used.
249 bool inline ConstructSystem32Path(LPCWSTR aModule, WCHAR* aSystemPath,
250 UINT aSize) {
251 MOZ_ASSERT(aSystemPath);
253 size_t fileLen = wcslen(aModule);
254 if (fileLen >= aSize) {
255 // The module name alone cannot even fit!
256 return false;
259 size_t systemDirLen = GetSystemDirectoryW(aSystemPath, aSize);
261 if (systemDirLen) {
262 if (systemDirLen < aSize - fileLen) {
263 // Make the system directory path terminate with a slash.
264 if (aSystemPath[systemDirLen - 1] != L'\\') {
265 if (systemDirLen + 1 < aSize - fileLen) {
266 aSystemPath[systemDirLen] = L'\\';
267 ++systemDirLen;
268 // No need to re-nullptr terminate.
269 } else {
270 // Couldn't fit the system path with added slash.
271 systemDirLen = 0;
274 } else {
275 // Couldn't fit the system path.
276 systemDirLen = 0;
280 MOZ_ASSERT(systemDirLen + fileLen < aSize);
282 wcsncpy(aSystemPath + systemDirLen, aModule, fileLen);
283 aSystemPath[systemDirLen + fileLen] = L'\0';
284 return true;
287 HMODULE inline LoadLibrarySystem32(LPCWSTR aModule) {
288 WCHAR systemPath[MAX_PATH + 1];
289 if (!ConstructSystem32Path(aModule, systemPath, MAX_PATH + 1)) {
290 return NULL;
292 return LoadLibraryW(systemPath);
295 } // namespace
297 // for UniquePtr
298 struct LocalFreeDeleter {
299 void operator()(void* aPtr) { ::LocalFree(aPtr); }
302 // for UniquePtr to store a PSID
303 struct FreeSidDeleter {
304 void operator()(void* aPtr) { ::FreeSid(aPtr); }
306 // Unfortunately, although SID is a struct, PSID is a void*
307 // This typedef will work for storing a PSID in a UniquePtr and should make
308 // things a bit more readable.
309 typedef mozilla::UniquePtr<void, FreeSidDeleter> UniqueSidPtr;
310 #endif