Bug 1946184 - Fix computing the CSD margin right after calling HideWindowChrome(...
[gecko.git] / nsprpub / pr / src / md / windows / w32shm.c
blob127a55a1cd1a8c6d8f9edccaa0d347900dfefdbf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <private/primpl.h>
7 #include <string.h>
8 #include <prshm.h>
9 #include <prerr.h>
10 #include <prmem.h>
12 #if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
14 extern PRLogModuleInfo* _pr_shm_lm;
17 * NSPR-to-NT access right mapping table for file-mapping objects.
19 * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS.
20 * This is because if a file-mapping object with the specified name
21 * exists, CreateFileMapping requests full access to the existing
22 * object.
24 static DWORD filemapAccessTable[] = {
25 FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */
26 FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */
27 0 /* execute */
30 extern PRSharedMemory* _MD_OpenSharedMemory(const char* name, PRSize size,
31 PRIntn flags, PRIntn mode) {
32 char ipcname[PR_IPC_NAME_SIZE];
33 PRStatus rc = PR_SUCCESS;
34 DWORD dwHi, dwLo;
35 PRSharedMemory* shm;
36 DWORD flProtect = (PAGE_READWRITE);
37 SECURITY_ATTRIBUTES sa;
38 LPSECURITY_ATTRIBUTES lpSA = NULL;
39 PSECURITY_DESCRIPTOR pSD = NULL;
40 PACL pACL = NULL;
42 rc = _PR_MakeNativeIPCName(name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm);
43 if (PR_FAILURE == rc) {
44 PR_SetError(PR_UNKNOWN_ERROR, 0);
45 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ("PR_OpenSharedMemory: name is invalid"));
46 return (NULL);
49 shm = PR_NEWZAP(PRSharedMemory);
50 if (NULL == shm) {
51 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
52 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
53 ("PR_OpenSharedMemory: New PRSharedMemory out of memory"));
54 return (NULL);
57 shm->ipcname = PR_MALLOC((PRUint32)(strlen(ipcname) + 1));
58 if (NULL == shm->ipcname) {
59 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
60 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
61 ("PR_OpenSharedMemory: New shm->ipcname out of memory"));
62 PR_DELETE(shm);
63 return (NULL);
66 /* copy args to struct */
67 strcpy(shm->ipcname, ipcname);
68 shm->size = size;
69 shm->mode = mode;
70 shm->flags = flags;
71 shm->ident = _PR_SHM_IDENT;
73 if (flags & PR_SHM_CREATE) {
74 dwHi = (DWORD)(((PRUint64)shm->size >> 32) & 0xffffffff);
75 dwLo = (DWORD)(shm->size & 0xffffffff);
77 if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable, &pSD,
78 &pACL) == PR_SUCCESS) {
79 sa.nLength = sizeof(sa);
80 sa.lpSecurityDescriptor = pSD;
81 sa.bInheritHandle = FALSE;
82 lpSA = &sa;
84 # ifdef WINCE
87 * This is assuming that the name will never be larger than
88 * MAX_PATH. Should we dynamically allocate?
90 PRUnichar wideIpcName[MAX_PATH];
91 MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1, wideIpcName, MAX_PATH);
92 shm->handle = CreateFileMappingW((HANDLE)-1, lpSA, flProtect, dwHi, dwLo,
93 wideIpcName);
95 # else
96 shm->handle = CreateFileMappingA((HANDLE)-1, lpSA, flProtect, dwHi, dwLo,
97 shm->ipcname);
98 # endif
99 if (lpSA != NULL) {
100 _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
103 if (NULL == shm->handle) {
104 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
105 ("PR_OpenSharedMemory: CreateFileMapping() failed: %s",
106 shm->ipcname));
107 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
108 PR_FREEIF(shm->ipcname)
109 PR_DELETE(shm);
110 return (NULL);
111 } else {
112 if ((flags & PR_SHM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
113 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
114 ("PR_OpenSharedMemory: Request exclusive & already exists",
115 shm->ipcname));
116 PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
117 CloseHandle(shm->handle);
118 PR_FREEIF(shm->ipcname)
119 PR_DELETE(shm);
120 return (NULL);
121 } else {
122 PR_LOG(
123 _pr_shm_lm, PR_LOG_DEBUG,
124 ("PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
125 shm->ipcname, shm->handle));
126 return (shm);
129 } else {
130 # ifdef WINCE
131 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
132 shm->handle = NULL; /* OpenFileMapping not supported */
133 # else
134 shm->handle = OpenFileMapping(FILE_MAP_WRITE, TRUE, shm->ipcname);
135 # endif
136 if (NULL == shm->handle) {
137 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
138 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
139 ("PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d",
140 shm->ipcname, PR_GetOSError()));
141 PR_FREEIF(shm->ipcname);
142 PR_DELETE(shm);
143 return (NULL);
144 } else {
145 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
146 ("PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d",
147 shm->ipcname, shm->handle));
148 return (shm);
151 /* returns from separate paths */
154 extern void* _MD_AttachSharedMemory(PRSharedMemory* shm, PRIntn flags) {
155 PRUint32 access = FILE_MAP_WRITE;
156 void* addr;
158 PR_ASSERT(shm->ident == _PR_SHM_IDENT);
160 if (PR_SHM_READONLY & flags) {
161 access = FILE_MAP_READ;
164 addr = MapViewOfFile(shm->handle, access, 0, 0, shm->size);
166 if (NULL == addr) {
167 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
168 PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
169 ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d",
170 PR_GetOSError()));
173 return (addr);
174 } /* end _MD_ATTACH_SHARED_MEMORY() */
176 extern PRStatus _MD_DetachSharedMemory(PRSharedMemory* shm, void* addr) {
177 PRStatus rc = PR_SUCCESS;
178 BOOL wrc;
180 PR_ASSERT(shm->ident == _PR_SHM_IDENT);
182 wrc = UnmapViewOfFile(addr);
183 if (FALSE == wrc) {
184 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
185 PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
186 ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d",
187 PR_GetOSError()));
188 rc = PR_FAILURE;
191 return (rc);
194 extern PRStatus _MD_CloseSharedMemory(PRSharedMemory* shm) {
195 PRStatus rc = PR_SUCCESS;
196 BOOL wrc;
198 PR_ASSERT(shm->ident == _PR_SHM_IDENT);
200 wrc = CloseHandle(shm->handle);
201 if (FALSE == wrc) {
202 _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
203 PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
204 ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d",
205 PR_GetOSError()));
206 rc = PR_FAILURE;
208 PR_FREEIF(shm->ipcname);
209 PR_DELETE(shm);
211 return (rc);
212 } /* end _MD_CLOSE_SHARED_MEMORY() */
214 extern PRStatus _MD_DeleteSharedMemory(const char* name) {
215 return (PR_SUCCESS);
219 ** Windows implementation of anonymous memory (file) map
221 extern PRLogModuleInfo* _pr_shma_lm;
223 extern PRFileMap* _md_OpenAnonFileMap(const char* dirName, PRSize size,
224 PRFileMapProtect prot) {
225 PRFileMap* fm;
226 HANDLE hFileMap;
228 fm = PR_CreateFileMap((PRFileDesc*)-1, size, prot);
229 if (NULL == fm) {
230 PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
231 ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed"));
232 goto Finished;
236 ** Make fm->md.hFileMap inheritable. We can't use
237 ** GetHandleInformation and SetHandleInformation
238 ** because these two functions fail with
239 ** ERROR_CALL_NOT_IMPLEMENTED on Win95.
241 if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap, GetCurrentProcess(),
242 &hFileMap, 0, TRUE /* inheritable */,
243 DUPLICATE_SAME_ACCESS) == FALSE) {
244 PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
245 PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
246 ("_md_OpenAnonFileMap(): DuplicateHandle(): failed"));
247 PR_CloseFileMap(fm);
248 fm = NULL;
249 goto Finished;
251 CloseHandle(fm->md.hFileMap);
252 fm->md.hFileMap = hFileMap;
254 Finished:
255 return (fm);
256 } /* end md_OpenAnonFileMap() */
259 ** _md_ExportFileMapAsString()
262 extern PRStatus _md_ExportFileMapAsString(PRFileMap* fm, PRSize bufSize,
263 char* buf) {
264 PRIntn written;
266 written = PR_snprintf(buf, (PRUint32)bufSize, "%d:%" PR_PRIdOSFD ":%ld",
267 (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap,
268 (PRInt32)fm->md.dwAccess);
270 PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
271 ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x",
272 fm->prot, fm->md.hFileMap, fm->md.dwAccess));
274 return ((written == -1) ? PR_FAILURE : PR_SUCCESS);
275 } /* end _md_ExportFileMapAsString() */
278 ** _md_ImportFileMapFromString()
281 extern PRFileMap* _md_ImportFileMapFromString(const char* fmstring) {
282 PRIntn prot;
283 PROsfd hFileMap;
284 PRInt32 dwAccess;
285 PRFileMap* fm = NULL;
287 PR_sscanf(fmstring, "%d:%" PR_SCNdOSFD ":%ld", &prot, &hFileMap, &dwAccess);
289 fm = PR_NEWZAP(PRFileMap);
290 if (NULL == fm) {
291 PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
292 ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed"));
293 return (fm);
296 fm->prot = (PRFileMapProtect)prot;
297 fm->md.hFileMap = (HANDLE)hFileMap;
298 fm->md.dwAccess = (DWORD)dwAccess;
299 fm->fd = (PRFileDesc*)-1;
301 PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
302 ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, "
303 "dwAccess: %8.8x, fd: %x",
304 fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd));
305 return (fm);
306 } /* end _md_ImportFileMapFromString() */
308 #else
309 Error !Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined
311 #endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */
312 /* --- end w32shm.c --- */