| OLD | NEW |
| (Empty) |
| 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/. */ | |
| 5 | |
| 6 #include <private/primpl.h> | |
| 7 #include <string.h> | |
| 8 #include <prshm.h> | |
| 9 #include <prerr.h> | |
| 10 #include <prmem.h> | |
| 11 | |
| 12 #if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY) | |
| 13 | |
| 14 extern PRLogModuleInfo *_pr_shm_lm; | |
| 15 | |
| 16 /* | |
| 17 * NSPR-to-NT access right mapping table for file-mapping objects. | |
| 18 * | |
| 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. | |
| 23 */ | |
| 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 */ | |
| 28 }; | |
| 29 | |
| 30 extern PRSharedMemory * _MD_OpenSharedMemory( | |
| 31 const char *name, | |
| 32 PRSize size, | |
| 33 PRIntn flags, | |
| 34 PRIntn mode | |
| 35 ) | |
| 36 { | |
| 37 char ipcname[PR_IPC_NAME_SIZE]; | |
| 38 PRStatus rc = PR_SUCCESS; | |
| 39 DWORD dwHi, dwLo; | |
| 40 PRSharedMemory *shm; | |
| 41 DWORD flProtect = ( PAGE_READWRITE ); | |
| 42 SECURITY_ATTRIBUTES sa; | |
| 43 LPSECURITY_ATTRIBUTES lpSA = NULL; | |
| 44 PSECURITY_DESCRIPTOR pSD = NULL; | |
| 45 PACL pACL = NULL; | |
| 46 | |
| 47 rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); | |
| 48 if ( PR_FAILURE == rc ) | |
| 49 { | |
| 50 PR_SetError(PR_UNKNOWN_ERROR, 0 ); | |
| 51 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid
")); | |
| 52 return(NULL); | |
| 53 } | |
| 54 | |
| 55 shm = PR_NEWZAP( PRSharedMemory ); | |
| 56 if ( NULL == shm ) | |
| 57 { | |
| 58 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); | |
| 59 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMem
ory out of memory")); | |
| 60 return(NULL); | |
| 61 } | |
| 62 | |
| 63 shm->ipcname = PR_MALLOC( (PRUint32) (strlen( ipcname ) + 1) ); | |
| 64 if ( NULL == shm->ipcname ) | |
| 65 { | |
| 66 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); | |
| 67 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcnam
e out of memory")); | |
| 68 PR_DELETE(shm); | |
| 69 return(NULL); | |
| 70 } | |
| 71 | |
| 72 /* copy args to struct */ | |
| 73 strcpy( shm->ipcname, ipcname ); | |
| 74 shm->size = size; | |
| 75 shm->mode = mode; | |
| 76 shm->flags = flags; | |
| 77 shm->ident = _PR_SHM_IDENT; | |
| 78 | |
| 79 if (flags & PR_SHM_CREATE ) { | |
| 80 dwHi = (DWORD) (((PRUint64) shm->size >> 32) & 0xffffffff); | |
| 81 dwLo = (DWORD) (shm->size & 0xffffffff); | |
| 82 | |
| 83 if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable, | |
| 84 &pSD, &pACL) == PR_SUCCESS) { | |
| 85 sa.nLength = sizeof(sa); | |
| 86 sa.lpSecurityDescriptor = pSD; | |
| 87 sa.bInheritHandle = FALSE; | |
| 88 lpSA = &sa; | |
| 89 } | |
| 90 #ifdef WINCE | |
| 91 { | |
| 92 /* | |
| 93 * This is assuming that the name will never be larger than | |
| 94 * MAX_PATH. Should we dynamically allocate? | |
| 95 */ | |
| 96 PRUnichar wideIpcName[MAX_PATH]; | |
| 97 MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1, | |
| 98 wideIpcName, MAX_PATH); | |
| 99 shm->handle = CreateFileMappingW( | |
| 100 (HANDLE)-1 , | |
| 101 lpSA, | |
| 102 flProtect, | |
| 103 dwHi, | |
| 104 dwLo, | |
| 105 wideIpcName); | |
| 106 } | |
| 107 #else | |
| 108 shm->handle = CreateFileMappingA( | |
| 109 (HANDLE)-1 , | |
| 110 lpSA, | |
| 111 flProtect, | |
| 112 dwHi, | |
| 113 dwLo, | |
| 114 shm->ipcname); | |
| 115 #endif | |
| 116 if (lpSA != NULL) { | |
| 117 _PR_NT_FreeSecurityDescriptorACL(pSD, pACL); | |
| 118 } | |
| 119 | |
| 120 if ( NULL == shm->handle ) { | |
| 121 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, | |
| 122 ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s", | |
| 123 shm->ipcname )); | |
| 124 _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); | |
| 125 PR_FREEIF( shm->ipcname ) | |
| 126 PR_DELETE( shm ); | |
| 127 return(NULL); | |
| 128 } else { | |
| 129 if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXIS
TS )) { | |
| 130 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, | |
| 131 ( "PR_OpenSharedMemory: Request exclusive & already exists", | |
| 132 shm->ipcname )); | |
| 133 PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS ); | |
| 134 CloseHandle( shm->handle ); | |
| 135 PR_FREEIF( shm->ipcname ) | |
| 136 PR_DELETE( shm ); | |
| 137 return(NULL); | |
| 138 } else { | |
| 139 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, | |
| 140 ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, han
dle: %d", | |
| 141 shm->ipcname, shm->handle )); | |
| 142 return(shm); | |
| 143 } | |
| 144 } | |
| 145 } else { | |
| 146 #ifdef WINCE | |
| 147 PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 ); | |
| 148 shm->handle = NULL; /* OpenFileMapping not supported */ | |
| 149 #else | |
| 150 shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname ); | |
| 151 #endif | |
| 152 if ( NULL == shm->handle ) { | |
| 153 _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); | |
| 154 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, | |
| 155 ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d"
, | |
| 156 shm->ipcname, PR_GetOSError())); | |
| 157 PR_FREEIF( shm->ipcname ); | |
| 158 PR_DELETE( shm ); | |
| 159 return(NULL); | |
| 160 } else { | |
| 161 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, | |
| 162 ( "PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %
d", | |
| 163 shm->ipcname, shm->handle )); | |
| 164 return(shm); | |
| 165 } | |
| 166 } | |
| 167 /* returns from separate paths */ | |
| 168 } | |
| 169 | |
| 170 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) | |
| 171 { | |
| 172 PRUint32 access = FILE_MAP_WRITE; | |
| 173 void *addr; | |
| 174 | |
| 175 PR_ASSERT( shm->ident == _PR_SHM_IDENT ); | |
| 176 | |
| 177 if ( PR_SHM_READONLY & flags ) | |
| 178 access = FILE_MAP_READ; | |
| 179 | |
| 180 addr = MapViewOfFile( shm->handle, | |
| 181 access, | |
| 182 0, 0, | |
| 183 shm->size ); | |
| 184 | |
| 185 if ( NULL == addr ) { | |
| 186 _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); | |
| 187 PR_LOG( _pr_shm_lm, PR_LOG_ERROR, | |
| 188 ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d", PR_G
etOSError())); | |
| 189 } | |
| 190 | |
| 191 return( addr ); | |
| 192 } /* end _MD_ATTACH_SHARED_MEMORY() */ | |
| 193 | |
| 194 | |
| 195 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) | |
| 196 { | |
| 197 PRStatus rc = PR_SUCCESS; | |
| 198 BOOL wrc; | |
| 199 | |
| 200 PR_ASSERT( shm->ident == _PR_SHM_IDENT ); | |
| 201 | |
| 202 wrc = UnmapViewOfFile( addr ); | |
| 203 if ( FALSE == wrc ) | |
| 204 { | |
| 205 _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); | |
| 206 PR_LOG( _pr_shm_lm, PR_LOG_ERROR, | |
| 207 ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d", PR
_GetOSError())); | |
| 208 rc = PR_FAILURE; | |
| 209 } | |
| 210 | |
| 211 return( rc ); | |
| 212 } | |
| 213 | |
| 214 | |
| 215 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) | |
| 216 { | |
| 217 PRStatus rc = PR_SUCCESS; | |
| 218 BOOL wrc; | |
| 219 | |
| 220 PR_ASSERT( shm->ident == _PR_SHM_IDENT ); | |
| 221 | |
| 222 wrc = CloseHandle( shm->handle ); | |
| 223 if ( FALSE == wrc ) | |
| 224 { | |
| 225 _PR_MD_MAP_DEFAULT_ERROR( GetLastError()); | |
| 226 PR_LOG( _pr_shm_lm, PR_LOG_ERROR, | |
| 227 ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d", PR_GetO
SError())); | |
| 228 rc = PR_FAILURE; | |
| 229 } | |
| 230 PR_FREEIF( shm->ipcname ); | |
| 231 PR_DELETE( shm ); | |
| 232 | |
| 233 return( rc ); | |
| 234 } /* end _MD_CLOSE_SHARED_MEMORY() */ | |
| 235 | |
| 236 extern PRStatus _MD_DeleteSharedMemory( const char *name ) | |
| 237 { | |
| 238 return( PR_SUCCESS ); | |
| 239 } | |
| 240 | |
| 241 | |
| 242 /* | |
| 243 ** Windows implementation of anonymous memory (file) map | |
| 244 */ | |
| 245 extern PRLogModuleInfo *_pr_shma_lm; | |
| 246 | |
| 247 extern PRFileMap* _md_OpenAnonFileMap( | |
| 248 const char *dirName, | |
| 249 PRSize size, | |
| 250 PRFileMapProtect prot | |
| 251 ) | |
| 252 { | |
| 253 PRFileMap *fm; | |
| 254 HANDLE hFileMap; | |
| 255 | |
| 256 fm = PR_CreateFileMap( (PRFileDesc*)-1, size, prot ); | |
| 257 if ( NULL == fm ) { | |
| 258 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, | |
| 259 ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed")); | |
| 260 goto Finished; | |
| 261 } | |
| 262 | |
| 263 /* | |
| 264 ** Make fm->md.hFileMap inheritable. We can't use | |
| 265 ** GetHandleInformation and SetHandleInformation | |
| 266 ** because these two functions fail with | |
| 267 ** ERROR_CALL_NOT_IMPLEMENTED on Win95. | |
| 268 */ | |
| 269 if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap, | |
| 270 GetCurrentProcess(), &hFileMap, | |
| 271 0, TRUE /* inheritable */, | |
| 272 DUPLICATE_SAME_ACCESS) == FALSE) { | |
| 273 PR_SetError( PR_UNKNOWN_ERROR, GetLastError() ); | |
| 274 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, | |
| 275 ("_md_OpenAnonFileMap(): DuplicateHandle(): failed")); | |
| 276 PR_CloseFileMap( fm ); | |
| 277 fm = NULL; | |
| 278 goto Finished; | |
| 279 } | |
| 280 CloseHandle(fm->md.hFileMap); | |
| 281 fm->md.hFileMap = hFileMap; | |
| 282 | |
| 283 Finished: | |
| 284 return(fm); | |
| 285 } /* end md_OpenAnonFileMap() */ | |
| 286 | |
| 287 /* | |
| 288 ** _md_ExportFileMapAsString() | |
| 289 ** | |
| 290 */ | |
| 291 extern PRStatus _md_ExportFileMapAsString( | |
| 292 PRFileMap *fm, | |
| 293 PRSize bufSize, | |
| 294 char *buf | |
| 295 ) | |
| 296 { | |
| 297 PRIntn written; | |
| 298 | |
| 299 written = PR_snprintf( buf, (PRUint32) bufSize, "%d:%" PR_PRIdOSFD ":%ld", | |
| 300 (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap, (PRInt32)fm->md.dwAccess ); | |
| 301 | |
| 302 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, | |
| 303 ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x", | |
| 304 fm->prot, fm->md.hFileMap, fm->md.dwAccess )); | |
| 305 | |
| 306 return((written == -1)? PR_FAILURE : PR_SUCCESS); | |
| 307 } /* end _md_ExportFileMapAsString() */ | |
| 308 | |
| 309 | |
| 310 /* | |
| 311 ** _md_ImportFileMapFromString() | |
| 312 ** | |
| 313 */ | |
| 314 extern PRFileMap * _md_ImportFileMapFromString( | |
| 315 const char *fmstring | |
| 316 ) | |
| 317 { | |
| 318 PRIntn prot; | |
| 319 PROsfd hFileMap; | |
| 320 PRInt32 dwAccess; | |
| 321 PRFileMap *fm = NULL; | |
| 322 | |
| 323 PR_sscanf( fmstring, "%d:%" PR_SCNdOSFD ":%ld", | |
| 324 &prot, &hFileMap, &dwAccess ); | |
| 325 | |
| 326 fm = PR_NEWZAP(PRFileMap); | |
| 327 if ( NULL == fm ) { | |
| 328 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, | |
| 329 ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed")); | |
| 330 return(fm); | |
| 331 } | |
| 332 | |
| 333 fm->prot = (PRFileMapProtect)prot; | |
| 334 fm->md.hFileMap = (HANDLE)hFileMap; | |
| 335 fm->md.dwAccess = (DWORD)dwAccess; | |
| 336 fm->fd = (PRFileDesc*)-1; | |
| 337 | |
| 338 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, | |
| 339 ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, dwAc
cess: %8.8x, fd: %x", | |
| 340 fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd)); | |
| 341 return(fm); | |
| 342 } /* end _md_ImportFileMapFromString() */ | |
| 343 | |
| 344 #else | |
| 345 Error! Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined? | |
| 346 #endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */ | |
| 347 /* --- end w32shm.c --- */ | |
| OLD | NEW |