Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


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.0 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge