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
15 #include "nsAutoRef.h"
16 #include "mozilla/Assertions.h"
17 #include "mozilla/UniquePtr.h"
19 // ----------------------------------------------------------------------------
20 // Critical Section helper class
21 // ----------------------------------------------------------------------------
23 class AutoCriticalSection
{
25 explicit AutoCriticalSection(LPCRITICAL_SECTION aSection
)
26 : mSection(aSection
) {
27 ::EnterCriticalSection(mSection
);
29 ~AutoCriticalSection() { ::LeaveCriticalSection(mSection
); }
32 LPCRITICAL_SECTION mSection
;
36 class nsAutoRefTraits
<HKEY
> {
39 static HKEY
Void() { return nullptr; }
41 static void Release(RawRef aFD
) {
49 class nsAutoRefTraits
<HDC
> {
52 static HDC
Void() { return nullptr; }
54 static void Release(RawRef aFD
) {
62 class nsAutoRefTraits
<HFONT
> {
65 static HFONT
Void() { return nullptr; }
67 static void Release(RawRef aFD
) {
75 class nsAutoRefTraits
<HBRUSH
> {
77 typedef HBRUSH RawRef
;
78 static HBRUSH
Void() { return nullptr; }
80 static void Release(RawRef aFD
) {
88 class nsAutoRefTraits
<HRGN
> {
91 static HRGN
Void() { return nullptr; }
93 static void Release(RawRef aFD
) {
101 class nsAutoRefTraits
<HBITMAP
> {
103 typedef HBITMAP RawRef
;
104 static HBITMAP
Void() { return nullptr; }
106 static void Release(RawRef aFD
) {
114 class nsAutoRefTraits
<SC_HANDLE
> {
116 typedef SC_HANDLE RawRef
;
117 static SC_HANDLE
Void() { return nullptr; }
119 static void Release(RawRef aFD
) {
121 CloseServiceHandle(aFD
);
127 class nsSimpleRef
<HANDLE
> {
129 typedef HANDLE RawRef
;
131 nsSimpleRef() : mRawRef(nullptr) {}
133 explicit nsSimpleRef(RawRef aRawRef
) : mRawRef(aRawRef
) {}
135 bool HaveResource() const {
136 return mRawRef
&& mRawRef
!= INVALID_HANDLE_VALUE
;
140 RawRef
get() const { return mRawRef
; }
142 static void Release(RawRef aRawRef
) {
143 if (aRawRef
&& aRawRef
!= INVALID_HANDLE_VALUE
) {
144 CloseHandle(aRawRef
);
151 class nsAutoRefTraits
<HMODULE
> {
153 typedef HMODULE RawRef
;
154 static RawRef
Void() { return nullptr; }
156 static void Release(RawRef aFD
) {
164 class nsAutoRefTraits
<DEVMODEW
*> {
166 typedef DEVMODEW
* RawRef
;
167 static RawRef
Void() { return nullptr; }
169 static void Release(RawRef aDevMode
) {
170 if (aDevMode
!= Void()) {
171 ::HeapFree(::GetProcessHeap(), 0, aDevMode
);
177 class nsAutoRefTraits
<MSIHANDLE
> {
179 typedef MSIHANDLE RawRef
;
180 static RawRef
Void() { return 0; }
182 static void Release(RawRef aHandle
) {
183 if (aHandle
!= Void()) {
184 ::MsiCloseHandle(aHandle
);
189 // HGLOBAL is just a typedef of HANDLE which nsSimpleRef has a specialization
190 // of, that means having a nsAutoRefTraits specialization for HGLOBAL is
191 // useless. Therefore we create a wrapper class for HGLOBAL to make
192 // nsAutoRefTraits and nsAutoRef work as intention.
195 MOZ_IMPLICIT
nsHGLOBAL(HGLOBAL hGlobal
) : m_hGlobal(hGlobal
) {}
197 operator HGLOBAL() const { return m_hGlobal
; }
204 class nsAutoRefTraits
<nsHGLOBAL
> {
206 typedef nsHGLOBAL RawRef
;
207 static RawRef
Void() { return nullptr; }
209 static void Release(RawRef hGlobal
) { ::GlobalFree(hGlobal
); }
212 // Because Printer's HANDLE uses ClosePrinter and we already have
213 // nsAutoRef<HANDLE> which uses CloseHandle so we need to create a wrapper class
214 // for HANDLE to have another specialization for nsAutoRefTraits.
217 MOZ_IMPLICIT
nsHPRINTER(HANDLE hPrinter
) : m_hPrinter(hPrinter
) {}
219 operator HANDLE() const { return m_hPrinter
; }
221 HANDLE
* operator&() { return &m_hPrinter
; }
227 // winspool.h header has AddMonitor macro, it conflicts with AddMonitor member
228 // function in TaskbarPreview.cpp and TaskbarTabPreview.cpp. Beside, we only
229 // need ClosePrinter here for Release function, so having its prototype is
231 extern "C" BOOL WINAPI
ClosePrinter(HANDLE hPrinter
);
234 class nsAutoRefTraits
<nsHPRINTER
> {
236 typedef nsHPRINTER RawRef
;
237 static RawRef
Void() { return nullptr; }
239 static void Release(RawRef hPrinter
) { ::ClosePrinter(hPrinter
); }
242 typedef nsAutoRef
<HKEY
> nsAutoRegKey
;
243 typedef nsAutoRef
<HDC
> nsAutoHDC
;
244 typedef nsAutoRef
<HFONT
> nsAutoFont
;
245 typedef nsAutoRef
<HBRUSH
> nsAutoBrush
;
246 typedef nsAutoRef
<HRGN
> nsAutoRegion
;
247 typedef nsAutoRef
<HBITMAP
> nsAutoBitmap
;
248 typedef nsAutoRef
<SC_HANDLE
> nsAutoServiceHandle
;
249 typedef nsAutoRef
<HANDLE
> nsAutoHandle
;
250 typedef nsAutoRef
<HMODULE
> nsModuleHandle
;
251 typedef nsAutoRef
<DEVMODEW
*> nsAutoDevMode
;
252 typedef nsAutoRef
<nsHGLOBAL
> nsAutoGlobalMem
;
253 typedef nsAutoRef
<nsHPRINTER
> nsAutoPrinter
;
254 typedef nsAutoRef
<MSIHANDLE
> nsAutoMsiHandle
;
256 // Construct a path "<system32>\<aModule>". return false if the output buffer
258 // Note: If the system path cannot be found, or doesn't fit in the output buffer
259 // with the module name, we will just ignore the system path and output the
260 // module name alone;
261 // this may mean using a normal search path wherever the output is used.
262 bool inline ConstructSystem32Path(LPCWSTR aModule
, WCHAR
* aSystemPath
,
264 MOZ_ASSERT(aSystemPath
);
266 size_t fileLen
= wcslen(aModule
);
267 if (fileLen
>= aSize
) {
268 // The module name alone cannot even fit!
272 size_t systemDirLen
= GetSystemDirectoryW(aSystemPath
, aSize
);
275 if (systemDirLen
< aSize
- fileLen
) {
276 // Make the system directory path terminate with a slash.
277 if (aSystemPath
[systemDirLen
- 1] != L
'\\') {
278 if (systemDirLen
+ 1 < aSize
- fileLen
) {
279 aSystemPath
[systemDirLen
] = L
'\\';
281 // No need to re-nullptr terminate.
283 // Couldn't fit the system path with added slash.
288 // Couldn't fit the system path.
293 MOZ_ASSERT(systemDirLen
+ fileLen
< aSize
);
295 wcsncpy(aSystemPath
+ systemDirLen
, aModule
, fileLen
);
296 aSystemPath
[systemDirLen
+ fileLen
] = L
'\0';
300 HMODULE
inline LoadLibrarySystem32(LPCWSTR aModule
) {
301 return LoadLibraryExW(aModule
, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32
);
305 struct LocalFreeDeleter
{
306 void operator()(void* aPtr
) { ::LocalFree(aPtr
); }
309 struct VirtualFreeDeleter
{
310 void operator()(void* aPtr
) { ::VirtualFree(aPtr
, 0, MEM_RELEASE
); }
313 // for UniquePtr to store a PSID
314 struct FreeSidDeleter
{
315 void operator()(void* aPtr
) { ::FreeSid(aPtr
); }
317 // Unfortunately, although SID is a struct, PSID is a void*
318 // This typedef will work for storing a PSID in a UniquePtr and should make
319 // things a bit more readable.
320 typedef mozilla::UniquePtr
<void, FreeSidDeleter
> UniqueSidPtr
;
322 struct CloseHandleDeleter
{
323 typedef HANDLE pointer
;
324 void operator()(pointer aHandle
) {
325 if (aHandle
!= INVALID_HANDLE_VALUE
) {
326 ::CloseHandle(aHandle
);
331 // One caller of this function is early in startup and several others are not,
332 // so they have different ways of determining the two parameters. This function
333 // exists just so any future code that needs to determine whether the dynamic
334 // blocklist is disabled remembers to check whether safe mode is active.
335 inline bool IsDynamicBlocklistDisabled(bool isSafeMode
,
336 bool hasCommandLineDisableArgument
) {
337 return isSafeMode
|| hasCommandLineDisableArgument
;