Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/md/windows/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  w32shm.c   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <private/primpl.h>
#include <string.h>
#include <prshm.h>
#include <prerr.h>
#include <prmem.h>

#if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)

extern PRLogModuleInfo* _pr_shm_lm;

/*
 * NSPR-to-NT access right mapping table for file-mapping objects.
 *
 * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS.
 * This is because if a file-mapping object with the specified name
 * exists, CreateFileMapping requests full access to the existing
 * object.
 */

static DWORD filemapAccessTable[] = {
    FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */
    FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ,  /* write */
    0                                      /* execute */
};

extern PRSharedMemory* _MD_OpenSharedMemory(const char* name, PRSize size,
                                            PRIntn flags, PRIntn mode) {
  char ipcname[PR_IPC_NAME_SIZE];
  PRStatus rc = PR_SUCCESS;
  DWORD dwHi, dwLo;
  PRSharedMemory* shm;
  DWORD flProtect = (PAGE_READWRITE);
  SECURITY_ATTRIBUTES sa;
  LPSECURITY_ATTRIBUTES lpSA = NULL;
  PSECURITY_DESCRIPTOR pSD = NULL;
  PACL pACL = NULL;

  rc = _PR_MakeNativeIPCName(name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm);
  if (PR_FAILURE == rc) {
    PR_SetError(PR_UNKNOWN_ERROR, 0);
    PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ("PR_OpenSharedMemory: name is invalid"));
    return (NULL);
  }

  shm = PR_NEWZAP(PRSharedMemory);
  if (NULL == shm) {
    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
           ("PR_OpenSharedMemory: New PRSharedMemory out of memory"));
    return (NULL);
  }

  shm->ipcname = PR_MALLOC((PRUint32)(strlen(ipcname) + 1));
  if (NULL == shm->ipcname) {
    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
    PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
           ("PR_OpenSharedMemory: New shm->ipcname out of memory"));
    PR_DELETE(shm);
    return (NULL);
  }

  /* copy args to struct */
  strcpy(shm->ipcname, ipcname);
  shm->size = size;
  shm->mode = mode;
  shm->flags = flags;
  shm->ident = _PR_SHM_IDENT;

  if (flags & PR_SHM_CREATE) {
    dwHi = (DWORD)(((PRUint64)shm->size >> 32) & 0xffffffff);
    dwLo = (DWORD)(shm->size & 0xffffffff);

    if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable, &pSD,
                                         &pACL) == PR_SUCCESS) {
      sa.nLength = sizeof(sa);
      sa.lpSecurityDescriptor = pSD;
      sa.bInheritHandle = FALSE;
      lpSA = &sa;
    }
#  ifdef WINCE
    {
      /*
       * This is assuming that the name will never be larger than
       * MAX_PATH.  Should we dynamically allocate?
       */

      PRUnichar wideIpcName[MAX_PATH];
      MultiByteToWideChar(CP_ACP, 0, shm->ipcname, -1, wideIpcName, MAX_PATH);
      shm->handle = CreateFileMappingW((HANDLE)-1, lpSA, flProtect, dwHi, dwLo,
                                       wideIpcName);
    }
#  else
    shm->handle = CreateFileMappingA((HANDLE)-1, lpSA, flProtect, dwHi, dwLo,
                                     shm->ipcname);
#  endif
    if (lpSA != NULL) {
      _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
    }

    if (NULL == shm->handle) {
      PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
             ("PR_OpenSharedMemory: CreateFileMapping() failed: %s",
              shm->ipcname));
      _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
      PR_FREEIF(shm->ipcname)
      PR_DELETE(shm);
      return (NULL);
    } else {
      if ((flags & PR_SHM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
               ("PR_OpenSharedMemory: Request exclusive & already exists",
                shm->ipcname));
        PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
        CloseHandle(shm->handle);
        PR_FREEIF(shm->ipcname)
        PR_DELETE(shm);
        return (NULL);
      } else {
        PR_LOG(
            _pr_shm_lm, PR_LOG_DEBUG,
            ("PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
             shm->ipcname, shm->handle));
        return (shm);
      }
    }
  } else {
#  ifdef WINCE
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    shm->handle = NULL; /* OpenFileMapping not supported */
#  else
    shm->handle = OpenFileMapping(FILE_MAP_WRITE, TRUE, shm->ipcname);
#  endif
    if (NULL == shm->handle) {
      _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
      PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
             ("PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d",
              shm->ipcname, PR_GetOSError()));
      PR_FREEIF(shm->ipcname);
      PR_DELETE(shm);
      return (NULL);
    } else {
      PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
             ("PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d",
              shm->ipcname, shm->handle));
      return (shm);
    }
  }
  /* returns from separate paths */
}

extern void* _MD_AttachSharedMemory(PRSharedMemory* shm, PRIntn flags) {
  PRUint32 access = FILE_MAP_WRITE;
  void* addr;

  PR_ASSERT(shm->ident == _PR_SHM_IDENT);

  if (PR_SHM_READONLY & flags) {
    access = FILE_MAP_READ;
  }

  addr = MapViewOfFile(shm->handle, access, 0, 0, shm->size);

  if (NULL == addr) {
    _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
    PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
           ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d",
            PR_GetOSError()));
  }

  return (addr);
/* end _MD_ATTACH_SHARED_MEMORY() */

extern PRStatus _MD_DetachSharedMemory(PRSharedMemory* shm, void* addr) {
  PRStatus rc = PR_SUCCESS;
  BOOL wrc;

  PR_ASSERT(shm->ident == _PR_SHM_IDENT);

  wrc = UnmapViewOfFile(addr);
  if (FALSE == wrc) {
    _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
    PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
           ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d",
            PR_GetOSError()));
    rc = PR_FAILURE;
  }

  return (rc);
}

extern PRStatus _MD_CloseSharedMemory(PRSharedMemory* shm) {
  PRStatus rc = PR_SUCCESS;
  BOOL wrc;

  PR_ASSERT(shm->ident == _PR_SHM_IDENT);

  wrc = CloseHandle(shm->handle);
  if (FALSE == wrc) {
    _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
    PR_LOG(_pr_shm_lm, PR_LOG_ERROR,
           ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d",
            PR_GetOSError()));
    rc = PR_FAILURE;
  }
  PR_FREEIF(shm->ipcname);
  PR_DELETE(shm);

  return (rc);
/* end _MD_CLOSE_SHARED_MEMORY() */

extern PRStatus _MD_DeleteSharedMemory(const char* name) {
  return (PR_SUCCESS);
}

/*
** Windows implementation of anonymous memory (file) map
*/

extern PRLogModuleInfo* _pr_shma_lm;

extern PRFileMap* _md_OpenAnonFileMap(const char* dirName, PRSize size,
                                      PRFileMapProtect prot) {
  PRFileMap* fm;
  HANDLE hFileMap;

  fm = PR_CreateFileMap((PRFileDesc*)-1, size, prot);
  if (NULL == fm) {
    PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
           ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed"));
    goto Finished;
  }

  /*
  ** Make fm->md.hFileMap inheritable. We can't use
  ** GetHandleInformation and SetHandleInformation
  ** because these two functions fail with
  ** ERROR_CALL_NOT_IMPLEMENTED on Win95.
  */

  if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap, GetCurrentProcess(),
                      &hFileMap, 0, TRUE /* inheritable */,
                      DUPLICATE_SAME_ACCESS) == FALSE) {
    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
    PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
           ("_md_OpenAnonFileMap(): DuplicateHandle(): failed"));
    PR_CloseFileMap(fm);
    fm = NULL;
    goto Finished;
  }
  CloseHandle(fm->md.hFileMap);
  fm->md.hFileMap = hFileMap;

Finished:
  return (fm);
/* end md_OpenAnonFileMap() */

/*
** _md_ExportFileMapAsString()
**
*/

extern PRStatus _md_ExportFileMapAsString(PRFileMap* fm, PRSize bufSize,
                                          char* buf) {
  PRIntn written;

  written = PR_snprintf(buf, (PRUint32)bufSize, "%d:%" PR_PRIdOSFD ":%ld",
                        (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap,
                        (PRInt32)fm->md.dwAccess);

  PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
         ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x",
          fm->prot, fm->md.hFileMap, fm->md.dwAccess));

  return ((written == -1) ? PR_FAILURE : PR_SUCCESS);
/* end _md_ExportFileMapAsString() */

/*
** _md_ImportFileMapFromString()
**
*/

extern PRFileMap* _md_ImportFileMapFromString(const char* fmstring) {
  PRIntn prot;
  PROsfd hFileMap;
  PRInt32 dwAccess;
  PRFileMap* fm = NULL;

  PR_sscanf(fmstring, "%d:%" PR_SCNdOSFD ":%ld", &prot, &hFileMap, &dwAccess);

  fm = PR_NEWZAP(PRFileMap);
  if (NULL == fm) {
    PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
           ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed"));
    return (fm);
  }

  fm->prot = (PRFileMapProtect)prot;
  fm->md.hFileMap = (HANDLE)hFileMap;
  fm->md.dwAccess = (DWORD)dwAccess;
  fm->fd = (PRFileDesc*)-1;

  PR_LOG(_pr_shma_lm, PR_LOG_DEBUG,
         ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, "
          "dwAccess: %8.8x, fd: %x",
          fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd));
  return (fm);
/* end _md_ImportFileMapFromString() */

#else
Error !Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined
    ?
#endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */
/* --- end w32shm.c --- */

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.