Beispiel #1
0
Datei: bee2.c Projekt: fars/bee2
static err_t beeReadAndCalcStamp(octet stampRead[STAMP_SIZE], 
	octet stampCalc[STAMP_SIZE])
{
	err_t code = ERR_OK;
	char name[MAX_PATH];
	HANDLE hFile, hMapping;
	DWORD size, offset;
	octet* image;
	void* hash_state;
	// имя модуля
	if (!GetModuleFileNameA(GetModuleHandleA("bee2.dll"), name, sizeof(name)))
		return ERR_SYS_FUNCTION;
	// открыть файл
	hFile = CreateFileA(name, GENERIC_READ,	0, NULL, OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return ERR_OPEN_FAILED;
	// длина файла
	size = SetFilePointer(hFile, 0, NULL, FILE_END);
	if (size == INVALID_SET_FILE_POINTER)
	{
		CloseHandle(hFile);
		return ERR_SYS_FUNCTION;
	}
	// проецировать файл в память
	hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hMapping == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hFile);
		return ERR_SYS_FUNCTION;
	}
	// отобразить файл в память
	image = (octet*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
	if (image == NULL)
	{
		CloseHandle(hMapping), CloseHandle(hFile);
		return ERR_SYS_FUNCTION;
	}
	// найти смещение контрольной характеристики
	offset = stampFindOffset(image, size);
	if (offset == (DWORD)-1)
	{
		UnmapViewOfFile(image), CloseHandle(hMapping), CloseHandle(hFile);
		return ERR_BAD_FORMAT;
	}
	// сохранить характеристику
	memCopy(stampRead, image + offset, STAMP_SIZE);
	// вычислить характеристику
	ASSERT(STAMP_SIZE >= 32);
	memSetZero(stampCalc, STAMP_SIZE);
	hash_state = blobCreate(beltHash_keep());
	if (hash_state)
	{
		// хэшировать
		beltHashStart(hash_state);
		beltHashStepH(image, offset, hash_state);
		beltHashStepH(image + offset + STAMP_SIZE, 
			size - offset - STAMP_SIZE, hash_state);
		beltHashStepG(stampCalc, hash_state);
		blobClose(hash_state);
	}
	else
		code = ERR_OUTOFMEMORY;
	// очистка и выход
	UnmapViewOfFile(image);
	CloseHandle(hMapping);
	CloseHandle(hFile);
	return code;
}
/* map a file into system meory, return the file size */
size_t plat_mmap_create( plat_mmap *handle, const char *file, int fileAccessAttr )
{
	LARGE_INTEGER sizet;
	/* check error(s) */
	if ( ! handle )
		return 0;

	handle->fd_map = NULL;
	handle->address = NULL;

	if ( FLAG_ATTRIBUTE_READ & fileAccessAttr ) {
#ifdef _WIN32_WCE
		handle->fd_file = CreateFileForMappingA(
				file,
				GENERIC_READ,
				FILE_SHARE_READ,
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				NULL );
#else /* !_WIN32_WCE */
		handle->fd_file = CreateFileA(
				file,
				GENERIC_READ,
				FILE_SHARE_READ,
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS,
				0 );
#endif /* _WIN32_WCE */

		if ( INVALID_HANDLE_VALUE == handle->fd_file )
			return 0;

		sizet.LowPart = GetFileSize( handle->fd_file, (LPDWORD) &sizet.HighPart );
		handle->fd_map = CreateFileMappingA(
				handle->fd_file,
				NULL,
				PAGE_READONLY,
				sizet.HighPart,
				sizet.LowPart,
				0 );
	}
	else {
#ifdef _WIN32_WCE
		handle->fd_file = CreateFileForMappingA(
				file,
				GENERIC_WRITE | GENERIC_READ,
				FILE_SHARE_WRITE,
				NULL,
				CREATE_ALWAYS,
				FILE_ATTRIBUTE_NORMAL,
				NULL);
#else /* !_WIN32_WCE */
		handle->fd_file = CreateFileA(
				file,
				GENERIC_WRITE | GENERIC_READ,
				FILE_SHARE_WRITE,
				NULL,
				CREATE_ALWAYS,
				FILE_ATTRIBUTE_NORMAL,
				0);
#endif /* _WIN32_WCE */

		if ( INVALID_HANDLE_VALUE == handle->fd_file )
			return 0;

		sizet.LowPart  = 0;
		sizet.HighPart = 1;
		handle->fd_map = CreateFileMapping(
				handle->fd_file,
				NULL,
				PAGE_READWRITE,
				0,
				sizet.LowPart,
				0 );
		sizet.LowPart  = 1024 * 1024 * 1024;
		sizet.HighPart = 0;

		while ( ! handle->fd_map ) {
			DWORD error;
			handle->fd_map = CreateFileMapping(
					handle->fd_file,
					NULL,
					PAGE_READWRITE,
					0,
					sizet.LowPart,
					0 );
			error = GetLastError();

			if ( ERROR_NOT_ENOUGH_MEMORY == error || ERROR_DISK_FULL == error )
				sizet.LowPart /= 2;
			else
				break;
		}
	}

	handle->fAccessAttr = fileAccessAttr;

	if ( FLAG_ATTRIBUTE_READ & fileAccessAttr || 16 * 1024 * 1024 <= sizet.LowPart ) {
		if ( handle->fd_map )
			return (size_t) sizet.QuadPart;
	}

	plat_mmap_close( handle );

	return 0;
}
Beispiel #3
0
template<typename PointT> int
pcl::PCDWriter::appendBinary(const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud)
{
  if(cloud.empty())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Input point cloud has no data!");
    return -1;
  }

  if(!boost::filesystem::exists(file_name))
    return writeBinary(file_name, cloud);

  std::ifstream file_istream;
  file_istream.open(file_name.c_str(), std::ifstream::binary);
  if(!file_istream.good())
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Error opening file for reading");
    return -1;
  }
  file_istream.seekg(0, std::ios_base::end);
  size_t file_size = file_istream.tellg();
  file_istream.close();

  pcl::PCLPointCloud2 tmp_cloud;
  PCDReader reader;
  if(reader.readHeader(file_name, tmp_cloud) != 0)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] Failed reading header");
    return -1;
  }
  if(tmp_cloud.height != 1 || cloud.height != 1)
  {
    throw pcl::IOException("[pcl::PCDWriter::appendBinary] can't use appendBinary with a point cloud that "
      "has height different than 1!");
    return -1;
  }
  tmp_cloud.width += cloud.width;
  std::ostringstream oss;
  pcl::PointCloud<PointT> tmp_cloud2;
  // copy the header values:
  tmp_cloud2.header = tmp_cloud.header;
  tmp_cloud2.width = tmp_cloud.width;
  tmp_cloud2.height = tmp_cloud.height;
  tmp_cloud2.is_dense = tmp_cloud.is_dense;
  
  oss << PCDWriter::generateHeader(tmp_cloud2, tmp_cloud2.width) << "DATA binary\n";
  size_t data_idx = oss.tellp();
  
#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_APPEND, static_cast<mode_t> (0600));
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during open!");
    return (-1);
  }
#endif
  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;

    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);

  data_size = cloud.points.size () * fsize;

  data_idx += (tmp_cloud.width - cloud.width) * fsize;
  if (data_idx != file_size)
  {
    const char *msg = "[pcl::PCDWriter::appendBinary] The expected data size and the current data size are different!";
    PCL_WARN(msg);
    throw pcl::IOException (msg);
    return -1;
  }

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMappingA (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + data_size), NULL);
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);
#else
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);

  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::appendBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));

    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::appendBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  char* out = &map[0] + data_idx;
  // Copy the data
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[i]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // write the new header:
  std::string header(oss.str());
  memcpy(map, header.c_str(), header.size());


  // If the user set the synchronization flag on, call msync
#if !_WIN32
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
  UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle (h_native_file);
#else
  pcl_close (fd);
#endif

  resetLockingPermissions (file_name, file_lock);
  return 0;
}
Beispiel #4
0
int main (int argc, char *argv[])
{
  if (argc != 6) {
    fputs("Usage: lab1 [rc2|rc4|rc4e|des|3des112|3des|aes128|aes192|aes256] "
          "[enc|dec] <input file> <output file> <key>", stderr);
    return -1;
  }

  enum mode mod;
  if (strncmp(argv[2], "enc", 3) == 0) {
    mod = ENC;
  } else if (strncmp(argv[2], "dec", 3) == 0) {
    mod = DEC;
  } else {
    fprintf(stderr, "Wrong encryption mode: \"%s\".", argv[2]);
    return -1;
  }

  HANDLE inf = 0;
  HANDLE inmmf = 0;
  PBYTE indata = NULL;
  HANDLE outf = 0;
  HANDLE outmmf = 0;
  PBYTE outdata = NULL;
  LARGE_INTEGER insz = {.QuadPart = 0};
  LARGE_INTEGER outsz = {.QuadPart = 0};
  unsigned char err = 1;


  inf = CreateFileA(argv[3], GENERIC_READ, 0, NULL, OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL, NULL);
  inmmf = CreateFileMappingA(inf, NULL, PAGE_READONLY, 0, 0, NULL);
  if (inmmf == NULL) {
    fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n",
            GetLastError());
    goto err;
  }
  indata = (PBYTE)MapViewOfFile(inmmf, FILE_MAP_READ, 0, 0, 0);
  if (indata == NULL) {
    fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError());
    goto err;
  }

  GetFileSizeEx(inf, &insz);
  outsz.QuadPart = (insz.QuadPart / 8 + 2) * 8;

  outf = CreateFileA(argv[4], GENERIC_READ | GENERIC_WRITE, 0, NULL,
                     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  outmmf = CreateFileMappingA(outf, NULL, PAGE_READWRITE,
                              outsz.HighPart, outsz.LowPart, NULL);
  if (outmmf == NULL) {
    fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n",
            GetLastError());
    goto err;
  }

  outdata = (PBYTE)MapViewOfFile(outmmf, FILE_MAP_WRITE, 0, 0, 0);
  if (outdata == NULL) {
    fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError());
    goto err;
  }

  // Crypto stuff
  BOOL res;
  HCRYPTPROV prov;

  DWORD prov_type = PROV_RSA_AES;
  LPCTSTR prov_id = MS_ENH_RSA_AES_PROV; // MS_ENHANCED_PROV
  ALG_ID calg_id;
  if (strncmp(argv[1], "rc2", 3) == 0) {
    calg_id = CALG_RC2;
  } else if (strncmp(argv[1], "rc4e", 4) == 0) {
    calg_id = CALG_RC4;
  } else if (strncmp(argv[1], "rc4", 3) == 0) {
    prov_type = PROV_RSA_FULL;
    prov_id = MS_DEF_PROV;
    calg_id = CALG_RC4;
  } else if (strncmp(argv[1], "des", 3) == 0) {
    calg_id = CALG_DES;
  } else if (strncmp(argv[1], "3des112", 7) == 0) {
    calg_id = CALG_3DES_112;
  } else if (strncmp(argv[1], "3des", 4) == 0) {
    calg_id = CALG_3DES;
  } else if (strncmp(argv[1], "aes128", 6) == 0) {
    calg_id = CALG_AES_128;
  } else if (strncmp(argv[1], "aes192", 6) == 0) {
    calg_id = CALG_AES_192;
  } else if (strncmp(argv[1], "aes256", 6) == 0) {
    calg_id = CALG_AES_256;
  } else {
    fprintf(stderr, "Wrong cryptographic algorythm: \"%s\".", argv[1]);
    goto err;
  }

  if (!CryptAcquireContext(&prov, 0, prov_id, prov_type,
                           CRYPT_VERIFYCONTEXT)) {
    fputs("Cannot acquire crypt context.\n", stderr);
    goto err;
  }

  HCRYPTKEY key = generateKey(prov, calg_id, argv[5]);
  crash_if(key == 0, "Cannot make a key.");

  for (LARGE_INTEGER i = {.QuadPart = 0}; i.QuadPart < insz.QuadPart;
       (i.QuadPart) += buf_size) {

    unsigned char buf[buf_size + block_size];
    DWORD len = buf_size;
    void *inp = indata + i.QuadPart,
         *outp = outdata + i.QuadPart;
    BOOL final = insz.QuadPart - i.QuadPart <= buf_size;

    if (final) {
      len = insz.QuadPart - i.QuadPart;
    }

    memcpy(buf, inp, len);
    if (mod == ENC) {
      res = CryptEncrypt(key, 0, final, 0, buf, &len, buf_size + block_size);
    } else {
      res = CryptDecrypt(key, 0, final, 0, buf, &len);
    }

    if (res) {
      memcpy(outp, buf, len);
      if (final) {
        outsz.QuadPart = i.QuadPart + len;
      }
    } else {
      fprintf(stderr, "Can't crypt the block 0x%lx. Error code: %lu\n",
              i.QuadPart, GetLastError());
      goto err;
    }
  }

  CryptDestroyKey(key);
  CryptReleaseContext(prov,0);

  err = 0;

err:
  // Freeing resources.
  apply_not_null(indata, UnmapViewOfFile);
  apply_not_null(inmmf, CloseHandle);
  apply_not_null(inf, CloseHandle);

  apply_not_null(outdata, UnmapViewOfFile);
  apply_not_null(outmmf, CloseHandle);

  if (outf) {
    SetFilePointer(outf, outsz.LowPart, &(outsz.HighPart), FILE_BEGIN);
    SetEndOfFile(outf);
  }

  apply_not_null(outf, CloseHandle);

  if (err)
    return -1;
  else
    return 0;
}
Beispiel #5
0
status_t SharedMemory :: SetArea(const char * keyString, uint32 createSize, bool returnLocked)
{
   UnsetArea();  // make sure everything is deallocated to start with

#if defined(MUSCLE_FAKE_SHARED_MEMORY)
   if (createSize > 0)
   {
      _area = muscleAlloc(createSize);
      if (_area) 
      {
         memset(_area, 0, createSize);
         _areaName         = keyString;
         _areaSize         = createSize; 
         _isCreatedLocally = true;
         _isLocked         = returnLocked;
         _isLockedReadOnly = false;
         return B_NO_ERROR;
      }
      else WARN_OUT_OF_MEMORY;   
   }
#elif defined(WIN32)
   char buf[64];
   if (keyString == NULL)
   {
      muscleSprintf(buf, INT32_FORMAT_SPEC, GetTickCount());  // No user-supplied name?  We'll pick an arbitrary name then
      keyString = buf;
   }
   _areaName = keyString;

   // For windows we only use a Mutex, because even a Windows semaphore isn't enough to
   // do shared read locking.  When I figure out how to do interprocess shared read locking
   // under Windows I will implement that, but for now it's always exclusive-locking.  :^(
   _mutex = CreateMutexA(NULL, true, (_areaName+"__mutex")());
   if (_mutex != NULL)
   {
      bool ok = true;
      if (GetLastError() == ERROR_ALREADY_EXISTS) ok = (LockAreaReadWrite() == B_NO_ERROR);
      else
      {
         // We created it in our CreateMutex() call, and it's already locked for us
         _isLocked = true;
         _isLockedReadOnly = false;
      }
      if (ok)
      {
         char buf[MAX_PATH];
         if (GetTempPathA(sizeof(buf), buf) > 0)
         {
            _fileName = _areaName.Prepend(buf)+"__file";
            _file = CreateFileA(_fileName(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH|FILE_FLAG_RANDOM_ACCESS, NULL);
            if (_file != INVALID_HANDLE_VALUE)
            {
               _isCreatedLocally = (GetLastError() != ERROR_ALREADY_EXISTS);
               if (createSize == 0) createSize = GetFileSize(_file, NULL);
               _areaSize = createSize;  // assume the file will be resized automagically for us
               if (_areaSize > 0)
               {
                  _map = CreateFileMappingA(_file, NULL, PAGE_READWRITE, 0, createSize, (_areaName+"__map")());
                  if (_map)
                  {
                     _area = MapViewOfFile(_map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
                     if (_area)
                     {
                        if (returnLocked == false) UnlockArea();
                        return B_NO_ERROR;
                     }
                  }
               }
            }
         }
      }
   }
#else
   key_t requestedKey = IPC_PRIVATE;
   if (keyString)
   {
      requestedKey = (key_t) CalculateHashCode(keyString, (uint32)strlen(keyString));
      if (requestedKey == IPC_PRIVATE) requestedKey++;
      _areaName = keyString;
   }

   DECLARE_SEMCTL_ARG(semopts);
   const int permissionBits = 0777;

   // Try to create a new semaphore to control access to our area
   _semID = semget(requestedKey, 1, IPC_CREAT|IPC_EXCL|permissionBits);
   if (_semID >= 0)
   {
      // race condition here!?
      semopts.val = LARGEST_SEMAPHORE_DELTA;
      if (semctl(_semID, 0, SETVAL, semopts) < 0) _semID = -1; // oops!
   }
   else _semID = semget(requestedKey, 1, permissionBits);  // Couldn't create?  then get the existing one

   if (_semID >= 0)
   {
      _key = requestedKey;

      // If we requested a private key, we still need to know the actual key value
      if (_key == IPC_PRIVATE)
      {
         struct semid_ds semInfo = {};  // the braces zero-initialize the struct for us, to keep clang++SA happy
         semopts.buf = &semInfo;
         if (semctl(_semID, 0, IPC_STAT, semopts) == 0) 
         {
# ifdef __linux__
            _key = semInfo.sem_perm.__key;

// Mac os-x leopard uses '_key' by default. Both Tiger and Leopard may use _key if the following condition is true, otherwise they use 'key'.
# elif (defined(__APPLE__) && (defined(__POSIX_C_SOURCE) || defined(__LP64__))) || __DARWIN_UNIX03
            _key = semInfo.sem_perm._key;
# else
            _key = semInfo.sem_perm.key;
# endif
         }
         _areaName = "private";  // sorry, it's the best I can do short of figuring out how to invert the hash function!
      }

      if ((_key != IPC_PRIVATE)&&(LockAreaReadWrite() == B_NO_ERROR))
      {
         _areaID = shmget(_key, 0, permissionBits);
         if ((_areaID < 0)&&(createSize > 0)) 
         {
            _areaID = shmget(_key, createSize, IPC_CREAT|IPC_EXCL|permissionBits);
            _isCreatedLocally = true;
         }
         if (_areaID >= 0)
         {
            _area = shmat(_areaID, NULL, 0);
            if ((_area)&&(_area != ((void *)-1)))  // FogBugz #7294
            {
               // Now get the stats on our area
               struct shmid_ds buf;
               if (shmctl(_areaID, IPC_STAT, &buf) == 0)
               {
                  _areaSize = (uint32) buf.shm_segsz;
                  if (returnLocked == false) UnlockArea();
                  return B_NO_ERROR;
               }
            }
         }
      }
   }
#endif

   UnsetArea();  // oops, roll back everything!
   return B_ERROR;
}
Beispiel #6
0
template <typename PointT> int
pcl::PCDWriter::writeBinary (const std::string &file_name, 
                             const pcl::PointCloud<PointT> &cloud)
{
  if (cloud.empty ())
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Input point cloud has no data!");
    return (-1);
  }
  int data_idx = 0;
  std::ostringstream oss;
  oss << generateHeader<PointT> (cloud) << "DATA binary\n";
  oss.flush ();
  data_idx = static_cast<int> (oss.tellp ());

#if _WIN32
  HANDLE h_native_file = CreateFileA (file_name.c_str (), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h_native_file == INVALID_HANDLE_VALUE)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during CreateFile!");
    return (-1);
  }
#else
  int fd = pcl_open (file_name.c_str (), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  if (fd < 0)
  {
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during open!");
    return (-1);
  }
#endif
  // Mandatory lock file
  boost::interprocess::file_lock file_lock;
  setLockingPermissions (file_name, file_lock);

  std::vector<pcl::PCLPointField> fields;
  std::vector<int> fields_sizes;
  size_t fsize = 0;
  size_t data_size = 0;
  size_t nri = 0;
  pcl::getFields (cloud, fields);
  // Compute the total size of the fields
  for (size_t i = 0; i < fields.size (); ++i)
  {
    if (fields[i].name == "_")
      continue;
    
    int fs = fields[i].count * getFieldSize (fields[i].datatype);
    fsize += fs;
    fields_sizes.push_back (fs);
    fields[nri++] = fields[i];
  }
  fields.resize (nri);
  
  data_size = cloud.points.size () * fsize;

  // Prepare the map
#if _WIN32
  HANDLE fm = CreateFileMappingA (h_native_file, NULL, PAGE_READWRITE, 0, (DWORD) (data_idx + data_size), NULL);
  if (fm == NULL)
  {
      throw pcl::IOException("[pcl::PCDWriter::writeBinary] Error during memory map creation ()!");
      return (-1);
  }
  char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, data_idx + data_size));
  CloseHandle (fm);

#else
  // Stretch the file size to the size of the data
  off_t result = pcl_lseek (fd, getpagesize () + data_size - 1, SEEK_SET);

  if (result < 0)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    PCL_ERROR ("[pcl::PCDWriter::writeBinary] lseek errno: %d strerror: %s\n", errno, strerror (errno));

    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during lseek ()!");
    return (-1);
  }
  // Write a bogus entry so that the new file size comes in effect
  result = static_cast<int> (::write (fd, "", 1));
  if (result != 1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during write ()!");
    return (-1);
  }

  char *map = static_cast<char*> (mmap (0, data_idx + data_size, PROT_WRITE, MAP_SHARED, fd, 0));
  if (map == reinterpret_cast<char*> (-1)) //MAP_FAILED)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during mmap ()!");
    return (-1);
  }
#endif

  // Copy the header
  memcpy (&map[0], oss.str ().c_str (), data_idx);

  // Copy the data
  char *out = &map[0] + data_idx;
  for (size_t i = 0; i < cloud.points.size (); ++i)
  {
    int nrj = 0;
    for (size_t j = 0; j < fields.size (); ++j)
    {
      memcpy (out, reinterpret_cast<const char*> (&cloud.points[i]) + fields[j].offset, fields_sizes[nrj]);
      out += fields_sizes[nrj++];
    }
  }

  // If the user set the synchronization flag on, call msync
#if !_WIN32
  if (map_synchronization_)
    msync (map, data_idx + data_size, MS_SYNC);
#endif

  // Unmap the pages of memory
#if _WIN32
    UnmapViewOfFile (map);
#else
  if (munmap (map, (data_idx + data_size)) == -1)
  {
    pcl_close (fd);
    resetLockingPermissions (file_name, file_lock);
    throw pcl::IOException ("[pcl::PCDWriter::writeBinary] Error during munmap ()!");
    return (-1);
  }
#endif
  // Close file
#if _WIN32
  CloseHandle (h_native_file);
#else
  pcl_close (fd);
#endif
  resetLockingPermissions (file_name, file_lock);
  return (0);
}
Beispiel #7
0
void delegate_runner::create_process() {
    char path[MAX_PATH + 1];

    if (GetFullPathNameA(program_to_run.c_str(), MAX_PATH, path, NULL))
    {
        program_to_run = path;
    }

    options.push_argument_front(program_to_run);

    if (options.use_cmd)
    {
        options.push_argument_front("--cmd");
    }

    options.use_cmd = true;

    const std::map< restriction_kind_t, std::string > cmd_units = {
        { restriction_user_time_limit, "ms" },
        { restriction_memory_limit, "B" },
        { restriction_processor_time_limit, "us" },
        { restriction_security_limit, "" },
        { restriction_write_limit, "B" },
        { restriction_load_ratio, "" },
        { restriction_idle_time_limit, "us" },
        { restriction_processes_count_limit, "" }
    };

    const std::map< restriction_kind_t, std::string > cmd_arg = {
        { restriction_user_time_limit, "tl" },
        { restriction_memory_limit, "ml" },
        { restriction_processor_time_limit, "d" },
        { restriction_security_limit, "s" },
        { restriction_write_limit, "wl" },
        { restriction_load_ratio, "lr" },
        { restriction_idle_time_limit, "y" },
        { restriction_processes_count_limit, "only-process" }
    };

    for (int i = 0; i < restriction_max; ++i)
    {
        if (restrictions.restrictions[i] != restriction_no_limit)
        {
            std::string argument = "-" + cmd_arg.find((restriction_kind_t)i)->second;

            argument += " " + std::to_string(restrictions.restrictions[i]);
            argument += cmd_units.find((restriction_kind_t)i)->second;

            options.push_argument_front(argument);
        }
    }

    auto process_pipes = [](options_class& options, const std::vector<std::string>& vals, const std::string& prefix) {
        for (auto i = vals.cbegin(); i != vals.cend(); ++i)
        {
            options.push_argument_front(prefix + *i);
        }
    };

    process_pipes(options, options.stderror, "--err=");
    process_pipes(options, options.stdoutput, "--out=");
    process_pipes(options, options.stdinput, "--in=");

    std::string working_directory = options.working_directory;

    if (working_directory.length() == 0)
    {
        char dir[MAX_PATH + 1];

        GetCurrentDirectoryA(MAX_PATH, dir);

        working_directory = dir;
    }

    options.push_argument_front("-wd \"" + working_directory + "\"");

    if (options.hide_report)
    {
        options.push_argument_front("-hr 1");
    }

    for (auto i = options.environmentVars.cbegin(); i != options.environmentVars.cend(); ++i)
    {
        options.push_argument_front("-D " + i->first + "=" + i->second);
    }

    if (options.json)
    {
        options.push_argument_front("--json");
    }

    options.push_argument_front("-env " + options.environmentMode);

    std::string shared_memory_name = "mem" + options.session.hash();

    options.push_argument_front("--shared-memory=" + shared_memory_name);

    CreateFileMappingA(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        options_class::SHARED_MEMORY_BUF_SIZE,
        shared_memory_name.c_str()
   );

    options.shared_memory = shared_memory_name;

    options.push_argument_front("--delegated:1");

    runner::create_process();
}
Beispiel #8
0
/***************************************************************************
 * Called to initialize the global data. This will only be used on the
 * loading of the dll
 ***************************************************************************/
BOOL DPLAYX_ConstructData(void)
{
  SECURITY_ATTRIBUTES s_attrib;
  BOOL                bInitializeSharedMemory = FALSE;
  LPVOID              lpDesiredMemoryMapStart = (LPVOID)0x50000000;
  HANDLE              hInformOnStart;

  TRACE( "DPLAYX dll loaded - construct called\n" );

  /* Create a semaphore to block access to DPLAYX global data structs */

  s_attrib.bInheritHandle       = TRUE;
  s_attrib.lpSecurityDescriptor = NULL;
  s_attrib.nLength              = sizeof(s_attrib);

  hDplayxSema = CreateSemaphoreA( &s_attrib, 0, 1, lpszDplayxSemaName );

  /* First instance creates the semaphore. Others just use it */
  if( GetLastError() == ERROR_SUCCESS )
  {
    TRACE( "Semaphore %p created\n", hDplayxSema );

    /* The semaphore creator will also build the shared memory */
    bInitializeSharedMemory = TRUE;
  }
  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
  {
    TRACE( "Found semaphore handle %p\n", hDplayxSema );
    DPLAYX_AcquireSemaphore();
  }
  else
  {
    ERR( ": semaphore error %d\n", GetLastError() );
    return FALSE;
  }

  SetLastError( ERROR_SUCCESS );

  hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE,
                                         &s_attrib,
                                         PAGE_READWRITE | SEC_COMMIT,
                                         0,
                                         dwTotalSharedSize,
                                         lpszDplayxFileMapping );

  if( GetLastError() == ERROR_SUCCESS )
  {
    TRACE( "File mapped %p created\n", hDplayxSharedMem );
  }
  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
  {
    TRACE( "Found FileMapping handle %p\n", hDplayxSharedMem );
  }
  else
  {
    ERR( ": unable to create shared memory (%d)\n", GetLastError() );
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }

  lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem,
                                        FILE_MAP_WRITE,
                                        0, 0, 0, lpDesiredMemoryMapStart );

  if( lpSharedStaticData == NULL )
  {
    ERR( ": unable to map static data into process memory space (%d)\n",
         GetLastError() );
    DPLAYX_ReleaseSemaphore();
    return FALSE;
  }
  else
  {
    if( lpDesiredMemoryMapStart == lpSharedStaticData )
    {
      TRACE( "File mapped to %p\n", lpSharedStaticData );
    }
    else
    {
      /* Presently the shared data structures use pointers. If the
       * files are not mapped into the same area, the pointers will no
       * longer make any sense :(
       * FIXME: In the future make the shared data structures have some
       *        sort of fixup to make them independent between data spaces.
       *        This will also require a rework of the session data stuff.
       */
      ERR( "File mapped to %p (not %p). Expect failure\n",
            lpSharedStaticData, lpDesiredMemoryMapStart );
    }
  }

  /* Dynamic area starts just after the static area */
  lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize);

  /* FIXME: Crude hack */
  lobbyData   = lpSharedStaticData;
  sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2));

  /* Initialize shared data segments. */
  if( bInitializeSharedMemory )
  {
    UINT i;

    TRACE( "Initializing shared memory\n" );

    /* Set all lobbies to be "empty" */
    for( i=0; i < numSupportedLobbies; i++ )
    {
      DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
    }

    /* Set all sessions to be "empty" */
    for( i=0; i < numSupportedSessions; i++ )
    {
      sessionData[i].dwSize = 0;
    }

    /* Zero out the dynamic area */
    ZeroMemory( lpMemArea, dwDynamicSharedSize );

    /* Just for fun sync the whole data area */
    FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize );
  }

  DPLAYX_ReleaseSemaphore();

  /* Everything was created correctly. Signal the lobby client that
   * we started up correctly
   */
  if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) &&
      hInformOnStart
    )
  {
    BOOL bSuccess;
    bSuccess = SetEvent( hInformOnStart );
    TRACE( "Signalling lobby app start event %p %s\n",
             hInformOnStart, bSuccess ? "succeed" : "failed" );

    /* Close out handle */
    DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE );
  }

  return TRUE;
}
Beispiel #9
0
static int am_shm_extend(am_shm_t *am, size_t usize) {
    size_t size, osize;
    int rv = AM_SUCCESS;

    if (usize == 0 || am == NULL || am->pool == NULL) {
        return AM_EINVAL;
    }

    size = page_size(usize + SIZEOF_mem_pool);

#ifdef _WIN32    
    if (UnmapViewOfFile(am->pool) == 0) {
        am->error = GetLastError();
        return AM_ERROR;
    }
    if (CloseHandle(am->h[2]) == 0) {
        am->error = GetLastError();
        return AM_ERROR;
    }
    if (resize_file(am->h[1], size) == FALSE) {
        return AM_ERROR;
    }
    am->h[2] = CreateFileMappingA(am->h[1], NULL, PAGE_READWRITE, 0, (DWORD) size, NULL);
    am->error = GetLastError();
    if (am->h[2] == NULL) {
        return AM_ERROR;
    }
    am->pool = (struct mem_pool *) MapViewOfFile(am->h[2], FILE_MAP_ALL_ACCESS, 0, 0, 0);
    am->error = GetLastError();
    if (am->pool == NULL || (am->error != 0 && am->error != ERROR_ALREADY_EXISTS)) {
        rv = AM_ERROR;
    } else
#else
    osize = ((struct mem_pool *) am->pool)->size;
    rv = ftruncate(am->fd, size);
    if (rv == -1) {
        am->error = errno;
        return AM_EINVAL;
    }
    munmap(am->pool, osize);
    am->pool = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, am->fd, 0);
    if (am->pool == MAP_FAILED) {
        am->error = errno;
        rv = AM_ERROR;
    } else
#endif
    {
        struct mem_pool *pool = (struct mem_pool *) am->pool;
        struct mem_chunk *last = (struct mem_chunk *) AM_GET_POINTER(pool, pool->lh.next);

        if (last == NULL) {
            am->error = AM_ENOMEM;
            return AM_ERROR;
        }

        if (last->used == 0) {
            /* the last chunk is not used - add all newly allocated space there */
            last->size += size - pool->size;
        } else {
            /* the last chunk is used - add all newly allocated space right after the last chunk 
             * adjusting both - next pointer of the last chunk and head node to point to it
             */
            struct mem_chunk *e = (struct mem_chunk *) ((char *) pool + pool->size);
            e->used = 0;
            e->usize = 0;
            e->size = size - pool->size;
            e->lh.prev = AM_GET_OFFSET(pool, last);
            e->lh.next = 0;
            pool->lh.next = last->lh.next = AM_GET_OFFSET(pool, e);
        }

        *(am->global_size) = am->local_size = pool->size = size; /* new size */
        am->error = AM_SUCCESS;
    }
    return rv;
}
Beispiel #10
0
int am_shm_lock(am_shm_t *am) {
    struct mem_pool *pool;
    int rv = AM_SUCCESS;

    /* once we enter the critical section, check if any other process hasn't 
     * re-mapped our segment somewhere else (compare local_size to global_size which
     * will differ after successful am_shm_resize)
     */

#ifdef _WIN32
    do {
        am->error = WaitForSingleObject(am->h[0], INFINITE);
    } while (am->error == WAIT_ABANDONED);

    if (am->local_size != *(am->global_size)) {
        if (UnmapViewOfFile(am->pool) == 0) {
            am->error = GetLastError();
            return AM_EFAULT;
        }
        if (CloseHandle(am->h[2]) == 0) {
            am->error = GetLastError();
            return AM_EFAULT;
        }
        am->h[2] = CreateFileMappingA(am->h[1], NULL, PAGE_READWRITE, 0, (DWORD) *(am->global_size), NULL);
        am->error = GetLastError();
        if (am->h[2] == NULL) {
            return AM_EFAULT;
        }
        am->pool = (struct mem_pool *) MapViewOfFile(am->h[2], FILE_MAP_ALL_ACCESS, 0, 0, 0);
        am->error = GetLastError();
        if (am->pool == NULL || (am->error != 0 && am->error != ERROR_ALREADY_EXISTS)) {
            return AM_EFAULT;
        }

        pool = (struct mem_pool *) am->pool;
        am->local_size = *(am->global_size);
        if (pool->user_offset > 0) {
            am->user = AM_GET_POINTER(pool, pool->user_offset);
        }
    }

#else
    pthread_mutex_t *lock = (pthread_mutex_t *) am->lock;
    am->error = pthread_mutex_lock(lock);
#if !defined(__APPLE__) && !defined(AIX)
    if (am->error == EOWNERDEAD) {
        am->error = pthread_mutex_consistent_np(lock);
    }
#endif
    if (am->local_size != *(am->global_size)) {
        am->error = munmap(am->pool, am->local_size);
        if (am->error == -1) {
            am->error = errno;
            rv = AM_EFAULT;
        }
        am->pool = mmap(NULL, *(am->global_size), PROT_READ | PROT_WRITE, MAP_SHARED, am->fd, 0);
        if (am->pool == MAP_FAILED) {
            am->error = errno;
            rv = AM_EFAULT;
        }

        pool = (struct mem_pool *) am->pool;
        am->local_size = *(am->global_size);
        if (pool->user_offset > 0) {
            am->user = AM_GET_POINTER(pool, pool->user_offset);
        }
    }
#endif
    return rv;
}
Beispiel #11
0
am_shm_t *am_shm_create(const char *name, size_t usize) {
    struct mem_pool *pool = NULL;
    size_t size;
    char opened = AM_FALSE;
    void *area = NULL;
    am_shm_t *ret = NULL;
#ifdef _WIN32
    char dll_path[AM_URI_SIZE];
    DWORD error = 0;
    HMODULE hm = NULL;
    void *caller = _ReturnAddress();
#else
    int fdflags;
    int error = 0;
#endif

    ret = calloc(1, sizeof(am_shm_t));
    if (ret == NULL) return NULL;

#ifdef _WIN32
    if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
            GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) caller, &hm) &&
            GetModuleFileNameA(hm, dll_path, sizeof(dll_path) - 1) > 0) {
        PathRemoveFileSpecA(dll_path);
        strcat(dll_path, FILE_PATH_SEP);
        snprintf(ret->name[0], sizeof(ret->name[0]),
                AM_GLOBAL_PREFIX"%s_l", name); /* mutex/semaphore */
        snprintf(ret->name[1], sizeof(ret->name[1]),
                AM_GLOBAL_PREFIX"%s_s", name); /* shared memory name */
        snprintf(ret->name[2], sizeof(ret->name[2]),
                "%s.."FILE_PATH_SEP"log"FILE_PATH_SEP"%s_f", dll_path, name); /* shared memory file name */
        snprintf(ret->name[3], sizeof(ret->name[3]),
                AM_GLOBAL_PREFIX"%s_sz", name); /* shared memory name for global_size */
    } else {
        ret->error = AM_NOT_FOUND;
        return ret;
    }
#else
    snprintf(ret->name[0], sizeof(ret->name[0]),
            "/%s_l", name); /* mutex/semaphore */
    snprintf(ret->name[1], sizeof(ret->name[1]),
#ifdef __sun
            "/%s_s"
#else
            "%s_s"
#endif
            , name); /* shared memory name */
#endif

    size = page_size(usize + SIZEOF_mem_pool); /* need at least the size of the mem_pool header */

#ifdef _WIN32
    ret->h[0] = CreateMutexA(NULL, TRUE, ret->name[0]);
    error = GetLastError();
    if (ret->h[0] != NULL && error == ERROR_ALREADY_EXISTS) {
        do {
            error = WaitForSingleObject(ret->h[0], INFINITE);
        } while (error == WAIT_ABANDONED);
    } else {
        if (error == ERROR_ACCESS_DENIED) {
            ret->h[0] = OpenMutexA(SYNCHRONIZE, FALSE, ret->name[0]);
        }
        if (ret->h[0] == NULL) {
            ret->error = error;
            return ret;
        }
    }

    ret->h[1] = CreateFileA(ret->name[2], GENERIC_WRITE | GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
            NULL, CREATE_NEW, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
    error = GetLastError();
    if (ret->h[1] == INVALID_HANDLE_VALUE && error == ERROR_FILE_EXISTS) {
        ret->h[1] = CreateFileA(ret->name[2], GENERIC_WRITE | GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
        error = GetLastError();
        if (ret->h[1] != INVALID_HANDLE_VALUE) {
            opened = AM_TRUE;
            size = GetFileSize(ret->h[1], NULL);
        }
    }

    if (ret->h[1] == INVALID_HANDLE_VALUE || error != 0) {
        CloseHandle(ret->h[0]);
        ret->error = error;
        am_shm_unlock(ret);
        return ret;
    }

    if (!opened) {
        ret->h[2] = CreateFileMappingA(ret->h[1], NULL, PAGE_READWRITE, 0, (DWORD) size, ret->name[1]);
        error = GetLastError();
    } else {
        ret->h[2] = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, ret->name[1]);
        error = GetLastError();
        if (ret->h[2] == NULL && error == ERROR_FILE_NOT_FOUND) {
            ret->h[2] = CreateFileMappingA(ret->h[1], NULL, PAGE_READWRITE, 0, (DWORD) size, ret->name[1]);
            error = GetLastError();
        }
    }

    if (ret->h[2] == NULL || error != 0) {
        CloseHandle(ret->h[0]);
        CloseHandle(ret->h[1]);
        ret->error = error;
        am_shm_unlock(ret);
        return ret;
    }

    area = MapViewOfFile(ret->h[2], FILE_MAP_ALL_ACCESS, 0, 0, 0);
    error = GetLastError();
    if (area == NULL || (error != 0 && error != ERROR_ALREADY_EXISTS)) {
        CloseHandle(ret->h[0]);
        CloseHandle(ret->h[1]);
        CloseHandle(ret->h[2]);
        ret->error = error;
        am_shm_unlock(ret);
        return ret;
    }

    ret->h[3] = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD) sizeof(size_t), ret->name[3]);
    if (ret->h[3] == NULL) {
        ret->error = GetLastError();
        CloseHandle(ret->h[0]);
        CloseHandle(ret->h[1]);
        CloseHandle(ret->h[2]);
        am_shm_unlock(ret);
        return ret;
    }
    ret->global_size = MapViewOfFile(ret->h[3], FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (ret->global_size == NULL) {
        ret->error = GetLastError();
        CloseHandle(ret->h[0]);
        CloseHandle(ret->h[1]);
        CloseHandle(ret->h[2]);
        CloseHandle(ret->h[3]);
        am_shm_unlock(ret);
        return ret;
    }
    *(ret->global_size) = ret->local_size = size;

#else

    ret->lock = mmap(NULL, sizeof(pthread_mutex_t),
            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
    if (ret->lock == MAP_FAILED) {
        ret->error = errno;
        return ret;
    } else {
        pthread_mutexattr_t attr;
        pthread_mutex_t *lock = (pthread_mutex_t *) ret->lock;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#if defined(__sun)
#if defined(__SunOS_5_10) 
#if defined(_POSIX_THREAD_PRIO_INHERIT)
        pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
        pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP);
#endif
#else
        pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
#endif
#endif
#if defined(LINUX)
        pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP);
#endif
        pthread_mutex_init(lock, &attr);
        pthread_mutexattr_destroy(&attr);
    }

    ret->global_size = mmap(NULL, sizeof(size_t),
            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
    if (ret->global_size == MAP_FAILED) {
        ret->error = errno;
        return ret;
    }

    *(ret->global_size) = ret->local_size = size;

    am_shm_lock(ret);

    ret->fd = shm_open(ret->name[1], O_CREAT | O_EXCL | O_RDWR, 0666);
    error = errno;
    if (ret->fd == -1 && error != EEXIST) {
        munmap(ret->lock, sizeof(pthread_mutex_t));
        ret->error = error;
        am_shm_unlock(ret);
        return ret;
    }
    if (ret->fd == -1) {
        ret->fd = shm_open(ret->name[1], O_RDWR, 0666);
        error = errno;
        if (ret->fd == -1) {
            munmap(ret->lock, sizeof(pthread_mutex_t));
            ret->error = error;
            am_shm_unlock(ret);
            return ret;
        }
        /* reset FD_CLOEXEC */
        fdflags = fcntl(ret->fd, F_GETFD);
        fdflags &= ~FD_CLOEXEC;
        fcntl(ret->fd, F_SETFD, fdflags);
        /* try with just a header */
        area = mmap(NULL, SIZEOF_mem_pool, PROT_READ | PROT_WRITE, MAP_SHARED, ret->fd, 0);
        if (area == MAP_FAILED) {
            ret->error = errno;
            am_shm_unlock(ret);
            return ret;
        }
        size = ((struct mem_pool *) area)->size;
        if (munmap(area, SIZEOF_mem_pool) == -1) {
            ret->error = errno;
            am_shm_unlock(ret);
            return ret;
        }
        area = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ret->fd, 0);
        if (area == MAP_FAILED) {
            ret->error = errno;
            am_shm_unlock(ret);
            return ret;
        }
        opened = AM_TRUE;
    } else {
        /* reset FD_CLOEXEC */
        fdflags = fcntl(ret->fd, F_GETFD);
        fdflags &= ~FD_CLOEXEC;
        fcntl(ret->fd, F_SETFD, fdflags);
        if (ftruncate(ret->fd, size) == -1) {
            ret->error = errno;
            am_shm_unlock(ret);
            return ret;
        }
        area = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ret->fd, 0);
        if (area == MAP_FAILED) {
            ret->error = errno;
            am_shm_unlock(ret);
            return ret;
        }
    }

#endif

    ret->init = !opened;

    pool = (struct mem_pool *) area;
    if (ret->init) {
        struct mem_chunk *e = (struct mem_chunk *) ((char *) pool + SIZEOF_mem_pool);
        pool->size = size;
        pool->user_offset = 0;
        pool->open = 1;
        pool->resize = 0;

        /* add all available (free) space as one chunk in a freelist */
        e->used = 0;
        e->usize = 0;
        e->size = pool->size - SIZEOF_mem_pool;
        e->lh.next = e->lh.prev = 0;
        /* update head prev/next pointers */
        pool->lh.next = pool->lh.prev = AM_GET_OFFSET(pool, e);
    } else {
        if (pool->user_offset > 0) {
            ret->user = AM_GET_POINTER(pool, pool->user_offset);
        }
        pool->open++;
    }

    ret->pool = pool;
    ret->error = 0;
    am_shm_unlock(ret);
    return ret;
}
static int
mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
			    size_t offset)
{
  void * mmap_addr;
  HANDLE mmap_handle;

  /* Apparently, MS Vista puts unnamed file mapping objects into Global
     namespace when running an application in a Terminal Server
     session.  This causes failure since, by default, applications 
     don't get SeCreateGlobalPrivilege. We don't need global
     memory sharing so explicitly put object into Local namespace.

     If multiple concurrent GCC processes are using PCH functionality,
     MapViewOfFileEx returns "Access Denied" error.  So we ensure the
     session-wide mapping name is unique by appending process ID.  */

#define OBJECT_NAME_FMT "Local\\MinGWGCCPCH-"

  char* object_name = NULL;
  /* However, the documentation for CreateFileMapping says that on NT4
     and earlier, backslashes are invalid in object name.  So, we need
     to check if we are on Windows2000 or higher.  */
  OSVERSIONINFO version_info;
  version_info.dwOSVersionInfoSize = sizeof (version_info);

  if (size == 0)
    return 0; 

  /* Offset must be also be a multiple of allocation granularity for
     this to work.  We can't change the offset. */ 
  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
    return -1;


  /* Determine the version of Windows we are running on and use a
     uniquely-named local object if running > 4.  */
  GetVersionEx (&version_info);
  if (version_info.dwMajorVersion > 4)
    {
      char local_object_name [sizeof (OBJECT_NAME_FMT)
			      + sizeof (DWORD) * 2];
      snprintf (local_object_name, sizeof (local_object_name),
		OBJECT_NAME_FMT "%lx", GetCurrentProcessId());
      object_name = local_object_name;
    }
     
  mmap_handle = CreateFileMappingA ((HANDLE) _get_osfhandle (fd), NULL,
				    PAGE_WRITECOPY | SEC_COMMIT, 0, 0,
				    object_name);

  if (mmap_handle == NULL)
    {
      w32_error (__FUNCTION__,  __FILE__, __LINE__, "CreateFileMapping");
      return -1; 
    }
  mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
			       size, addr);
  if (mmap_addr != addr)
    {
      w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
      CloseHandle(mmap_handle);
      return  -1;
    }

  return 1;
}
Beispiel #13
0
/**********************************************************************
 *			PE_LoadImage
 * Load one PE format DLL/EXE into memory
 *
 * Unluckily we can't just mmap the sections where we want them, for
 * (at least) Linux does only support offsets which are page-aligned.
 *
 * BUT we have to map the whole image anyway, for Win32 programs sometimes
 * want to access them. (HMODULE32 point to the start of it)
 */
HMODULE
PE_LoadImage (int handle, LPCSTR filename, WORD * version)
{
  HMODULE hModule;
  HANDLE mapping;

  IMAGE_NT_HEADERS *nt;
  IMAGE_SECTION_HEADER *pe_sec;
  IMAGE_DATA_DIRECTORY *dir;
  /* BY_HANDLE_FILE_INFORMATION bhfi; -- unused */
  int i, rawsize, lowest_va, vma_size, file_size = 0;
  DWORD load_addr = 0, aoep, reloc = 0;
  //struct get_read_fd_request *req = get_req_buffer();
  int unix_handle = handle;
  int page_size = getpagesize ();


  //if ( GetFileInformationByHandle( hFile, &bhfi ) )
  //  file_size = bhfi.nFileSizeLow;
  file_size = lseek (handle, 0, SEEK_END);
  lseek (handle, 0, SEEK_SET);

  //#warning fix CreateFileMappingA
  mapping = CreateFileMappingA (handle, NULL, PAGE_READONLY | SEC_COMMIT,
      0, 0, NULL);
  if (!mapping) {
    WARN ("CreateFileMapping error %ld\n", GetLastError ());
    return 0;
  }
  //hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
  hModule = (HMODULE) mapping;
  //CloseHandle( mapping );
  if (!hModule) {
    WARN ("MapViewOfFile error %ld\n", GetLastError ());
    return 0;
  }
  if (*(WORD *) hModule != IMAGE_DOS_SIGNATURE) {
    WARN ("%s image doesn't have DOS signature, but 0x%04x\n", filename,
        *(WORD *) hModule);
    goto error;
  }

  nt = PE_HEADER (hModule);


  if (nt->Signature != IMAGE_NT_SIGNATURE) {
    WARN ("%s image doesn't have PE signature, but 0x%08lx\n", filename,
        nt->Signature);
    goto error;
  }


  if (nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
    MESSAGE ("Trying to load PE image for unsupported architecture (");
    switch (nt->FileHeader.Machine) {
      case IMAGE_FILE_MACHINE_UNKNOWN:
        MESSAGE ("Unknown");
        break;
      case IMAGE_FILE_MACHINE_I860:
        MESSAGE ("I860");
        break;
      case IMAGE_FILE_MACHINE_R3000:
        MESSAGE ("R3000");
        break;
      case IMAGE_FILE_MACHINE_R4000:
        MESSAGE ("R4000");
        break;
      case IMAGE_FILE_MACHINE_R10000:
        MESSAGE ("R10000");
        break;
      case IMAGE_FILE_MACHINE_ALPHA:
        MESSAGE ("Alpha");
        break;
      case IMAGE_FILE_MACHINE_POWERPC:
        MESSAGE ("PowerPC");
        break;
      default:
        MESSAGE ("Unknown-%04x", nt->FileHeader.Machine);
        break;
    }
    MESSAGE (")\n");
    goto error;
  }


  pe_sec = PE_SECTIONS (hModule);
  rawsize = 0;
  lowest_va = 0x10000;
  for (i = 0; i < nt->FileHeader.NumberOfSections; i++) {
    if (lowest_va > pe_sec[i].VirtualAddress)
      lowest_va = pe_sec[i].VirtualAddress;
    if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
      continue;
    if (pe_sec[i].PointerToRawData + pe_sec[i].SizeOfRawData > rawsize)
      rawsize = pe_sec[i].PointerToRawData + pe_sec[i].SizeOfRawData;
  }


  if (file_size && file_size < rawsize) {
    ERR ("PE module is too small (header: %d, filesize: %d), "
        "probably truncated download?\n", rawsize, file_size);
    goto error;
  }


  aoep = nt->OptionalHeader.AddressOfEntryPoint;
  if (aoep && (aoep < lowest_va))
    FIXME ("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
        "below the first virtual address (0x%08x) "
        "(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
        filename, aoep, lowest_va);


  /* FIXME:  Hack!  While we don't really support shared sections yet,
   *         this checks for those special cases where the whole DLL
   *         consists only of shared sections and is mapped into the
   *         shared address space > 2GB.  In this case, we assume that
   *         the module got mapped at its base address. Thus we simply
   *         check whether the module has actually been mapped there
   *         and use it, if so.  This is needed to get Win95 USER32.DLL
   *         to work (until we support shared sections properly).
   */

  if (nt->OptionalHeader.ImageBase & 0x80000000) {
    HMODULE sharedMod = (HMODULE) nt->OptionalHeader.ImageBase;
    IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
        ((LPBYTE) sharedMod + ((LPBYTE) nt - (LPBYTE) hModule));

    /* Well, this check is not really comprehensive,
       but should be good enough for now ... */
    if (!IsBadReadPtr ((LPBYTE) sharedMod, sizeof (IMAGE_DOS_HEADER))
        && memcmp ((LPBYTE) sharedMod, (LPBYTE) hModule,
            sizeof (IMAGE_DOS_HEADER)) == 0
        && !IsBadReadPtr (sharedNt, sizeof (IMAGE_NT_HEADERS))
        && memcmp (sharedNt, nt, sizeof (IMAGE_NT_HEADERS)) == 0) {
      UnmapViewOfFile ((LPVOID) hModule);
      return sharedMod;
    }
  }



  load_addr = nt->OptionalHeader.ImageBase;
  vma_size = calc_vma_size (hModule);

  load_addr = (DWORD) VirtualAlloc ((void *) load_addr, vma_size,
      MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if (load_addr == 0) {

    //FIXME("We need to perform base relocations for %s\n", filename);
    dir = nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_BASERELOC;
    if (dir->Size)
      reloc = dir->VirtualAddress;
    else {
      FIXME
          ("FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
          filename,
          (nt->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) ?
          "stripped during link" : "unknown reason");
      goto error;
    }

    /* FIXME: If we need to relocate a system DLL (base > 2GB) we should
     *        really make sure that the *new* base address is also > 2GB.
     *        Some DLLs really check the MSB of the module handle :-/
     */
    if (nt->OptionalHeader.ImageBase & 0x80000000)
      ERR ("Forced to relocate system DLL (base > 2GB). This is not good.\n");

    load_addr = (DWORD) VirtualAlloc (NULL, vma_size,
        MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (!load_addr) {
      FIXME_ (win32)
          ("FATAL: Couldn't load module %s (out of memory, %d needed)!\n",
          filename, vma_size);
      goto error;
    }
  }

/*
    TRACE("Load addr is %lx (base %lx), range %x\n",
          load_addr, nt->OptionalHeader.ImageBase, vma_size );
    TRACE_(segment)("Loading %s at %lx, range %x\n",
                    filename, load_addr, vma_size );
*/
#if 0

  *(PIMAGE_DOS_HEADER) load_addr = *(PIMAGE_DOS_HEADER) hModule;
  *PE_HEADER (load_addr) = *nt;
  memcpy (PE_SECTIONS (load_addr), PE_SECTIONS (hModule),
      sizeof (IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections);


  memcpy (load_addr, hModule, lowest_fa);
#endif

  if ((void *) FILE_dommap (handle, (void *) load_addr, 0,
          nt->OptionalHeader.SizeOfHeaders, 0, 0,
          PROT_EXEC | PROT_WRITE | PROT_READ,
          MAP_PRIVATE | MAP_FIXED) != (void *) load_addr) {
    ERR_ (win32)
        ("Critical Error: failed to map PE header to necessary address.\n");
    goto error;
  }


  pe_sec = PE_SECTIONS (hModule);
  for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++) {
    if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData)
      continue;
    /*
       TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
       filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
       pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
     */
    if ((void *) FILE_dommap (unix_handle,
            (void *) RVA (pe_sec->VirtualAddress), 0, pe_sec->SizeOfRawData, 0,
            pe_sec->PointerToRawData, PROT_EXEC | PROT_WRITE | PROT_READ,
            MAP_PRIVATE | MAP_FIXED) != (void *) RVA (pe_sec->VirtualAddress)) {
      ERR_ (win32)
          ("Critical Error: failed to map PE section to necessary address.\n");
      goto error;
    }
    if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
        (pe_sec->SizeOfRawData & (page_size - 1))) {
      DWORD end = (pe_sec->SizeOfRawData & ~(page_size - 1)) + page_size;
      if (end > pe_sec->Misc.VirtualSize)
        end = pe_sec->Misc.VirtualSize;
      TRACE ("clearing %p - %p\n",
          (char *) RVA (pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
          (char *) RVA (pe_sec->VirtualAddress) + end);
      memset ((char *) RVA (pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
          end - pe_sec->SizeOfRawData);
    }
  }


  if (reloc)
    do_relocations (load_addr, (IMAGE_BASE_RELOCATION *) RVA (reloc));


  *version = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8)
      | (nt->OptionalHeader.MinorSubsystemVersion & 0xff);


  UnmapViewOfFile ((LPVOID) hModule);
  return (HMODULE) load_addr;

error:
  if (unix_handle != -1)
    close (unix_handle);
  if (load_addr)
    VirtualFree ((LPVOID) load_addr, 0, MEM_RELEASE);
  UnmapViewOfFile ((LPVOID) hModule);
  return 0;
}