Esempio n. 1
0
static int
mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
			    size_t offset)
{
  void * mmap_addr;
  static HANDLE mmap_handle;

  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;

  mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd),
				   NULL, PAGE_WRITECOPY | SEC_COMMIT,
				   0, 0,  NULL);
  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;
}
Esempio n. 2
0
static void
w32_reset_event(HANDLE handle)
{
    if (ResetEvent(handle) == 0) {
	w32_error();
    }
}
Esempio n. 3
0
static void
w32_resume_thread(HANDLE handle)
{
    if (ResumeThread(handle) == -1) {
	w32_error();
    }
}
Esempio n. 4
0
static void
w32_close_handle(HANDLE handle)
{
    if (CloseHandle(handle) == 0) {
	w32_error();
    }
}
Esempio n. 5
0
static void
w32_set_event(HANDLE handle)
{
    if (SetEvent(handle) == 0) {
	w32_error("w32_set_event");
    }
}
Esempio n. 6
0
static void
w32_resume_thread(HANDLE handle)
{
    if (ResumeThread(handle) == (DWORD)-1) {
	w32_error("w32_resume_thread");
    }
}
Esempio n. 7
0
static void *
mingw32_gt_pch_get_address (size_t size, int)
{
  void* res;
  size = (size + va_granularity - 1) & ~(va_granularity - 1);
  if (size > pch_VA_max_size)
    return NULL;

  /* FIXME: We let system determine base by setting first arg to NULL.
     Allocating at top of available address space avoids unnecessary
     fragmentation of "ordinary" (malloc's)  address space but may not
     be safe  with delayed load of system dll's. Preferred addresses
     for NT system dlls is in 0x70000000 to 0x78000000 range.
     If we allocate at bottom we need to reserve the address as early
     as possible and at the same point in each invocation. */
 
  res = VirtualAlloc (NULL, pch_VA_max_size,
		      MEM_RESERVE | MEM_TOP_DOWN,
		      PAGE_NOACCESS);
  if (!res)
    w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
  else
    /* We do not need the address space for now, so free it.  */
    VirtualFree (res, 0, MEM_RELEASE);

  return res; 
}
Esempio n. 8
0
static HANDLE
w32_mutex_create(void)
{
    HANDLE lock = CreateMutex(NULL, FALSE, NULL);
    if (lock == NULL) {
	w32_error("native_mutex_initialize");
    }
    return lock;
}
Esempio n. 9
0
/* Initialise a UDP socket. */
static void _init_socket(SOCKET *sock, uint16_t port, BOOL reuseaddr)
{
	/* Socket used for sending and receiving packets on the network. */
	
	if((*sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
		log_printf(LOG_ERROR, "Error creating UDP socket: %s", w32_error(WSAGetLastError()));
		abort();
	}
	
	/* Enable broadcast and address reuse. */
	
	BOOL broadcast = TRUE;
	
	setsockopt(*sock, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(BOOL));
	setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(BOOL));
	
	/* Set send/receive buffer size to 512KiB. */
	
	int bufsize = 524288;
	
	setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, sizeof(int));
	setsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char*)&bufsize, sizeof(int));
	
	struct sockaddr_in addr;
	
	addr.sin_family      = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port        = htons(port);
	
	if(bind(*sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
	{
		log_printf(LOG_ERROR, "Error binding UDP socket: %s", w32_error(WSAGetLastError()));
		abort();
	}
	
	if(WSAEventSelect(*sock, router_event, FD_READ) == -1)
	{
		log_printf(LOG_ERROR, "WSAEventSelect error: %s", w32_error(WSAGetLastError()));
		abort();
	}
}
Esempio n. 10
0
/* Initialise the UDP socket and router worker thread.
 * Aborts on failure.
*/
void router_init(void)
{
	/* Event object used for notification of new packets and exit signal. */
	
	if((router_event = WSACreateEvent()) == WSA_INVALID_EVENT)
	{
		log_printf(LOG_ERROR, "Error creating WSA event object: %s", w32_error(WSAGetLastError()));
		abort();
	}
	
	if(ipx_use_pcap)
	{
		if((private_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		{
			log_printf(LOG_ERROR, "Error creating retransmit socket: %s", w32_error(WSAGetLastError()));
			abort();
		}
		
		struct sockaddr_in addr;
		addr.sin_family      = AF_INET;
		addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		addr.sin_port        = htons(0);
		
		if(bind(private_socket, (struct sockaddr*)(&addr), sizeof(addr)) == -1)
		{
			log_printf(LOG_ERROR, "Error binding retransmit socket: %s", w32_error(WSAGetLastError()));
			abort();
		}
	}
	else{
		_init_socket(&shared_socket, main_config.udp_port, TRUE);
		_init_socket(&private_socket, 0, FALSE);
	}
	
	router_running = true;
	
	if(!(router_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&router_main), NULL, 0, NULL)))
	{
		log_printf(LOG_ERROR, "Cannot create router worker thread: %s", w32_error(GetLastError()));
		abort();
	}
}
Esempio n. 11
0
void
native_mutex_initialize(rb_thread_lock_t *lock)
{
#if USE_WIN32_MUTEX
    *lock = CreateMutex(NULL, FALSE, NULL);
    if (*lock == NULL) {
	w32_error();
    }
    /* thread_debug("initialize mutex: %p\n", *lock); */
#else
    InitializeCriticalSection(lock);
#endif
}
Esempio n. 12
0
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;
  int r;

  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; 
    }

  /* Retry five times, as here might occure a race with multiple gcc's
     instances at same time.  */
  for (r = 0; r < 5; r++)
   {
      mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
				   size, addr);
      if (mmap_addr == addr)
	break;
      if (r != 4)
        Sleep (500);
   }
      
  if (mmap_addr != addr)
    {
      w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
      CloseHandle(mmap_handle);
      return  -1;
    }

  return 1;
}
Esempio n. 13
0
static BSTR _get_exe_desc(const wchar_t *path)
{
	DWORD vd_size = GetFileVersionInfoSizeW(path, NULL);
	if(vd_size == 0)
	{
		/* Ignore ERROR_RESOURCE_TYPE_NOT_FOUND as it most likely means
		 * the executable doesn't HAVE any version information.
		*/
		
		if(GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND)
		{
			log_printf(LOG_ERROR, "Cannot get version information: %s", w32_error(GetLastError()));
		}
		
		return NULL;
	}
	
	void *ver_data = malloc(vd_size);
	if(!ver_data)
	{
		log_printf(LOG_ERROR, "Cannot allocate %u bytes for version information!", (unsigned int)(vd_size));
		return NULL;
	}
	
	BSTR exe_desc = NULL;
	
	if(GetFileVersionInfoW(path, 0, vd_size, ver_data))
	{
		struct {
			WORD wLanguage;
			WORD wCodePage;
		} *tr_data;
		UINT tr_size;
		
		if(VerQueryValueW(ver_data, L"\\VarFileInfo\\Translation", (void**)(&tr_data), &tr_size))
		{
			for(unsigned int i = 0; i < (tr_size / sizeof(*tr_data)); ++i)
			{
				/* Integrate the language into the key in hex
				 * form?
				 * 
				 * F**k yeah!
				*/
				
				wchar_t key[64];
				wsprintfW(key, L"\\StringFileInfo\\%04x%04x\\FileDescription", tr_data[i].wLanguage, tr_data[i].wCodePage);
				
				wchar_t *desc;
				UINT desc_size;
				
				if(VerQueryValueW(ver_data, key, (void**)(&desc), &desc_size))
				{
					if((exe_desc = SysAllocStringLen(desc, desc_size)))
					{
						break;
					}
				}
			}
		}
	}
	else{
		log_printf(LOG_ERROR, "Cannot get version information: %s", w32_error(GetLastError()));
	}
	
	free(ver_data);
	
	return exe_desc;
}
Esempio n. 14
0
static void _handle_udp_recv(ipx_packet *packet, size_t packet_size, struct sockaddr_in src_ip)
{
	size_t data_size = ntohs(packet->size);
	
	if(packet_size < sizeof(ipx_packet) - 1 || data_size > MAX_DATA_SIZE || data_size + sizeof(ipx_packet) - 1 != packet_size)
	{
		/* Packet size field is incorrect. */
		return;
	}
	
	if(packet->src_socket == 0)
	{
		/* A source socket of zero indicates internal IPXWrapper
		 * traffic. The ptype determines what should be done.
		 * 
		 * The destination address of any such packet will usually be
		 * all zeroes to prevent older versions of IPXWrapper from
		 * passing them on to applications, since they can't bind to
		 * socket zero. This is also what prevents them from generating
		 * such packets.
		*/
		
		if(packet->ptype == IPX_MAGIC_SPXLOOKUP)
		{
			/* The other system is trying to resolve the IP address
			 * and port number of a listening SPX socket.
			*/
			
			if(data_size != sizeof(spxlookup_req_t))
			{
				log_printf(LOG_DEBUG, "Recieved IPX_MAGIC_SPXLOOKUP packet with %hu byte payload, dropping", data_size);
				return;
			}
			
			spxlookup_req_t *req = (spxlookup_req_t*)(packet->data);
			
			/* Search the sockets table for a listening socket which
			 * is bound to the requested address.
			*/
			
			lock_sockets();
			
			ipx_socket *s, *tmp;
			HASH_ITER(hh, sockets, s, tmp)
			{
				if(
					s->flags & IPX_IS_SPX
					&& s->flags & IPX_LISTENING
					&& (memcmp(req->net, s->addr.sa_netnum, 4) == 0
						|| addr32_in(req->net) == ZERO_NET)
					&& memcmp(req->node, s->addr.sa_nodenum, 6) == 0
					&& req->socket == s->addr.sa_socket)
				{
					/* This socket seems to fit the bill.
					 * Reply with the port number.
					*/
					
					spxlookup_reply_t reply;
					memset(&reply, 0, sizeof(reply));
					
					memcpy(reply.net, req->net, 4);
					memcpy(reply.node, req->node, 6);
					reply.socket = req->socket;
					
					reply.port = s->port;
					
					if(sendto(private_socket, (char*)(&reply), sizeof(reply), 0, (struct sockaddr*)(&src_ip), sizeof(src_ip)) == -1)
					{
						log_printf(LOG_ERROR, "Cannot send spxlookup_reply packet: %s", w32_error(WSAGetLastError()));
					}
					
					break;
				}
			}
			
			unlock_sockets();
		}
		else{
			log_printf(LOG_DEBUG, "Recieved magic packet unknown ptype %u, dropping", (unsigned int)(packet->ptype));
		}
		
		return;
	}
Esempio n. 15
0
static void _deliver_packet(
	uint8_t type,
	addr32_t src_net,
	addr48_t src_node,
	uint16_t src_socket,
	addr32_t dest_net,
	addr48_t dest_node,
	uint16_t dest_socket,
	const void *data,
	size_t data_size)
{
	{
		IPX_STRING_ADDR(src_addr, src_net, src_node, src_socket);
		IPX_STRING_ADDR(dest_addr, dest_net, dest_node, dest_socket);
		
		log_printf(LOG_DEBUG, "Delivering %u byte payload from %s to %s",
			(unsigned int)(data_size), src_addr, dest_addr);
	}
	
	lock_sockets();
	
	ipx_socket *sock, *tmp;
	HASH_ITER(hh, sockets, sock, tmp)
	{
		if(sock->flags & IPX_IS_SPX)
		{
			/* Socket is SPX */
			continue;
		}
		
		if(!(sock->flags & IPX_BOUND))
		{
			/* Socket isn't bound */
			continue;
		}
		
		if(!(sock->flags & IPX_RECV))
		{
			/* Socket is shut down for receive operations. */
			continue;
		}
		
		if((sock->flags & IPX_FILTER) && sock->f_ptype != type)
		{
			/* Socket has packet type filtering enabled and this
			 * packet is of the wrong type.
			*/
			continue;
		}
		
		if((dest_net != addr32_in(sock->addr.sa_netnum) && dest_net != BCAST_NET)
			|| (dest_node != addr48_in(sock->addr.sa_nodenum) && dest_node != BCAST_NODE)
			|| dest_socket != sock->addr.sa_socket)
		{
			/* Packet destination address is neither the local
			 * address of this socket nor broadcast.
			*/
			continue;
		}
		
		if((dest_net == BCAST_NET || dest_node == BCAST_NODE)
			&& !(sock->flags & IPX_RECV_BCAST))
		{
			/* Packet destination address includes a broadcast part
			 * and this socket has explicitly disabled reception of
			 * broadcasts.
			*/
			continue;
		}
		
		if((dest_net == BCAST_NET || dest_node == BCAST_NODE)
			&& (main_config.w95_bug && !(sock->flags & IPX_BROADCAST)))
		{
			/* Packet destination address includes a broadcast part,
			 * socket has not enabled the SO_BROADCAST option and
			 * the Windows 95 SO_BROADCAST bug is being emulated.
			*/
			continue;
		}
		
		if((sock->flags & IPX_CONNECTED)
			&& (src_net != addr32_in(sock->remote_addr.sa_netnum)
			|| src_node != addr48_in(sock->remote_addr.sa_nodenum)
			|| src_socket != sock->remote_addr.sa_socket))
		{
			/* Socket is "connected" and the source address isn't
			 * the remote address of the socket.
			*/
			continue;
		}
		
		log_printf(LOG_DEBUG, "...relaying to local port %hu", ntohs(sock->port));
		
		size_t packet_size = (sizeof(ipx_packet) + data_size) - 1;
		
		ipx_packet *packet = malloc(packet_size);
		if(!packet)
		{
			log_printf(LOG_ERROR, "Cannot allocate memory!");
			continue;
		}
		
		packet->ptype = type;
		
		addr32_out(packet->dest_net, dest_net);
		addr48_out(packet->dest_node, dest_node);
		packet->dest_socket = dest_socket;
		
		addr32_out(packet->src_net, src_net);
		addr48_out(packet->src_node, src_node);
		packet->src_socket = src_socket;
		
		packet->size = data_size;
		memcpy(packet->data, data, data_size);
		
		struct sockaddr_in send_addr;
		
		send_addr.sin_family      = AF_INET;
		send_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		send_addr.sin_port        = sock->port;
		
		if(sendto(private_socket, (void*)(packet), packet_size, 0, (struct sockaddr*)(&send_addr), sizeof(send_addr)) == -1)
		{
			log_printf(LOG_ERROR, "Error relaying packet: %s", w32_error(WSAGetLastError()));
		}
		
		free(packet);
	}
	
	unlock_sockets();
}