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
14 #include "nsAutoRef.h"
15 #include "mozilla/Assertions.h"
16 #include "mozilla/UniquePtr.h"
18 // ----------------------------------------------------------------------------
19 // Critical Section helper class
20 // ----------------------------------------------------------------------------
22 class AutoCriticalSection
{
24 explicit AutoCriticalSection(LPCRITICAL_SECTION aSection
)
25 : mSection(aSection
) {
26 ::EnterCriticalSection(mSection
);
28 ~AutoCriticalSection() { ::LeaveCriticalSection(mSection
); }
31 LPCRITICAL_SECTION mSection
;
35 class nsAutoRefTraits
<HKEY
> {
38 static HKEY
Void() { return nullptr; }
40 static void Release(RawRef aFD
) {
48 class nsAutoRefTraits
<HDC
> {
51 static HDC
Void() { return nullptr; }
53 static void Release(RawRef aFD
) {
61 class nsAutoRefTraits
<HFONT
> {
64 static HFONT
Void() { return nullptr; }
66 static void Release(RawRef aFD
) {
74 class nsAutoRefTraits
<HBRUSH
> {
76 typedef HBRUSH RawRef
;
77 static HBRUSH
Void() { return nullptr; }
79 static void Release(RawRef aFD
) {
87 class nsAutoRefTraits
<HRGN
> {
90 static HRGN
Void() { return nullptr; }
92 static void Release(RawRef aFD
) {
100 class nsAutoRefTraits
<HBITMAP
> {
102 typedef HBITMAP RawRef
;
103 static HBITMAP
Void() { return nullptr; }
105 static void Release(RawRef aFD
) {
113 class nsAutoRefTraits
<SC_HANDLE
> {
115 typedef SC_HANDLE RawRef
;
116 static SC_HANDLE
Void() { return nullptr; }
118 static void Release(RawRef aFD
) {
120 CloseServiceHandle(aFD
);
126 class nsSimpleRef
<HANDLE
> {
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
;
139 RawRef
get() const { return mRawRef
; }
141 static void Release(RawRef aRawRef
) {
142 if (aRawRef
&& aRawRef
!= INVALID_HANDLE_VALUE
) {
143 CloseHandle(aRawRef
);
150 class nsAutoRefTraits
<HMODULE
> {
152 typedef HMODULE RawRef
;
153 static RawRef
Void() { return nullptr; }
155 static void Release(RawRef aFD
) {
163 class nsAutoRefTraits
<DEVMODEW
*> {
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.
181 MOZ_IMPLICIT
nsHGLOBAL(HGLOBAL hGlobal
) : m_hGlobal(hGlobal
) {}
183 operator HGLOBAL() const { return m_hGlobal
; }
190 class nsAutoRefTraits
<nsHGLOBAL
> {
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.
203 MOZ_IMPLICIT
nsHPRINTER(HANDLE hPrinter
) : m_hPrinter(hPrinter
) {}
205 operator HANDLE() const { return m_hPrinter
; }
207 HANDLE
* operator&() { return &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
217 extern "C" BOOL WINAPI
ClosePrinter(HANDLE hPrinter
);
220 class nsAutoRefTraits
<nsHPRINTER
> {
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
;
243 // Construct a path "<system32>\<aModule>". return false if the output buffer
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
,
251 MOZ_ASSERT(aSystemPath
);
253 size_t fileLen
= wcslen(aModule
);
254 if (fileLen
>= aSize
) {
255 // The module name alone cannot even fit!
259 size_t systemDirLen
= GetSystemDirectoryW(aSystemPath
, aSize
);
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
'\\';
268 // No need to re-nullptr terminate.
270 // Couldn't fit the system path with added slash.
275 // Couldn't fit the system path.
280 MOZ_ASSERT(systemDirLen
+ fileLen
< aSize
);
282 wcsncpy(aSystemPath
+ systemDirLen
, aModule
, fileLen
);
283 aSystemPath
[systemDirLen
+ fileLen
] = L
'\0';
287 HMODULE
inline LoadLibrarySystem32(LPCWSTR aModule
) {
288 WCHAR systemPath
[MAX_PATH
+ 1];
289 if (!ConstructSystem32Path(aModule
, systemPath
, MAX_PATH
+ 1)) {
292 return LoadLibraryW(systemPath
);
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
;