Ejemplo n.º 1
1
static int socket_recvmsg_unsafe(struct socket_file *f, struct msghdr *msg, int flags)
{
	if (flags & ~LINUX_MSG_DONTWAIT)
		log_error("socket_sendmsg(): flags (0x%x) contains unsupported bits.", flags);

	if (f->shared->type != LINUX_SOCK_DGRAM && f->shared->type != LINUX_SOCK_RAW)
	{
		/* WSARecvMsg() only supports datagram and raw sockets
		 * For other types we emulate using recvfrom()
		 */
		/* TODO: MSG_WAITALL
		 * Per documentation, MSG_WAITALL should only return one type of message, i.e. only from one addr
		 * But in this case (TCP) this should be true
		 */
		msg->msg_controllen = 0;
		msg->msg_flags = 0; /* TODO */
		return socket_recvfrom_unsafe(f, msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len, flags, msg->msg_name, &msg->msg_namelen);
	}

	typedef int(*PFNWSARECVMSG)(
		_In_		SOCKET s,
		_Inout_		LPWSAMSG lpMsg,
		_Out_		LPDWORD lpdwNumberOfBytesRecvd,
		_In_		LPWSAOVERLAPPED lpOverlapped,
		_In_		LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
		);
	static PFNWSARECVMSG WSARecvMsg;
	if (!WSARecvMsg)
	{
		GUID guid = WSAID_WSARECVMSG;
		DWORD bytes;
		if (WSAIoctl(f->socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &WSARecvMsg, sizeof(WSARecvMsg), &bytes, NULL, NULL) == SOCKET_ERROR)
		{
			log_error("WSAIoctl(WSARecvMsg) failed, error code: %d", WSAGetLastError());
			return -L_EIO;
		}
	}

	WSABUF *buffers = (WSABUF *)alloca(sizeof(struct iovec) * msg->msg_iovlen);
	for (int i = 0; i < msg->msg_iovlen; i++)
	{
		buffers[i].len = msg->msg_iov[i].iov_len;
		buffers[i].buf = msg->msg_iov[i].iov_base;
	}
	struct sockaddr_storage addr_storage;
	int addr_storage_len = sizeof(struct sockaddr_storage);
	WSAMSG wsamsg;
	wsamsg.name = (LPSOCKADDR)&addr_storage;
	wsamsg.namelen = addr_storage_len;
	wsamsg.lpBuffers = buffers;
	wsamsg.dwBufferCount = msg->msg_iovlen;
	wsamsg.Control.buf = msg->msg_control;
	wsamsg.Control.len = msg->msg_controllen;
	wsamsg.dwFlags = 0;

	int r;
	while ((r = socket_wait_event(f, FD_READ | FD_CLOSE, flags)) == 0)
	{
		if (WSARecvMsg(f->socket, &wsamsg, &r, NULL, NULL) != SOCKET_ERROR)
			break;
		InterlockedAnd(&f->shared->events, ~FD_READ);
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			log_warning("WSARecvMsg() failed, error code: %d", err);
			return translate_socket_error(err);
		}
	}
	/* Translate WSAMSG back to msghdr */
	addr_storage_len = translate_socket_addr_to_linux(&addr_storage, wsamsg.namelen);
	int copylen = min(msg->msg_namelen, addr_storage_len);
	memcpy(msg->msg_name, &addr_storage, copylen);
	msg->msg_namelen = addr_storage_len;
	msg->msg_controllen = wsamsg.Control.len;
	msg->msg_flags = 0;
	if (wsamsg.dwFlags & MSG_TRUNC)
		msg->msg_flags |= LINUX_MSG_TRUNC;
	if (wsamsg.dwFlags & MSG_CTRUNC)
		msg->msg_flags |= LINUX_MSG_CTRUNC;
	/* TODO: MSG_EOR, MSG_OOB, and MSG_ERRQUEUE */
	return r;
}
Ejemplo n.º 2
0
static void
condSignal(
    os_cond *cond,
    long mask)
{
    HANDLE hQueue;
    DWORD result;
    long oldState;

    assert(cond != NULL);

    if (cond->scope == OS_SCOPE_SHARED) {
        hQueue = get_semaphore_handle(cond);
    } else {
        hQueue = (HANDLE)cond->qId;
    }

    oldState = InterlockedOr(&cond->state, mask);
    if (oldState == 0) { /* no waiters */
        InterlockedAnd(&cond->state, ~mask);
        return;
    }

    if (mask == BROADCAST_BIT_MASK) {
        result = ReleaseSemaphore(hQueue, oldState, 0);
    } else {
        result = ReleaseSemaphore(hQueue, 1, 0);
    }

    InterlockedAnd(&cond->state, ~mask);
}
Ejemplo n.º 3
0
static os_result
condSignal(
    os_cond *cond,
    long mask)
{
    char name[OS_SERVICE_ENTITY_NAME_MAX];
    HANDLE hQueue;
    DWORD result;
    long oldState;
    os_result osr;

    assert(cond != NULL);

    osr = os_resultSuccess;

    if (cond->scope == OS_SCOPE_SHARED) {

        _snprintf(name, sizeof(name), "%s%s%d%d",
            (os_sharedMemIsGlobal() ? OS_SERVICE_GLOBAL_NAME_PREFIX : ""),
            OS_SERVICE_SEM_NAME_PREFIX,
            cond->qId,
            os_getShmBaseAddressFromPointer(cond));

        hQueue = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, name);
        if (hQueue == NULL) {
            OS_DEBUG_1("condSignal", "OpenSemaphore failed %d", (int)GetLastError());
            assert(0);
            return os_resultFail;
        }
    } else {
        hQueue       = (HANDLE)cond->qId;
    }

    oldState = InterlockedOr(&cond->state, mask);
    if (oldState == 0) { /* no waiters */
        InterlockedAnd(&cond->state, ~mask);
        return osr;
    }

    if (mask == BROADCAST_BIT_MASK) {
        result = ReleaseSemaphore(hQueue, oldState, 0);
    } else {
        result = ReleaseSemaphore(hQueue, 1, 0);
    }
    InterlockedAnd(&cond->state, ~mask);

    if (cond->scope == OS_SCOPE_SHARED) {
        CloseHandle(hQueue);
    }

    return osr;
}
Ejemplo n.º 4
0
/* Reports current ready state
 * If one event in error_report_events has potential error code, the last WSA error code is set to that
 */
static int socket_update_events_unsafe(struct socket_file *f, int error_report_events)
{
	WSANETWORKEVENTS events;
	WSAEnumNetworkEvents(f->socket, f->event_handle, &events);
	int e = 0;
	if (events.lNetworkEvents & FD_READ)
		e |= FD_READ;
	if (events.lNetworkEvents & FD_WRITE)
		e |= FD_WRITE;
	if (events.lNetworkEvents & FD_CONNECT)
	{
		e |= FD_CONNECT;
		f->shared->connect_error = events.iErrorCode[FD_CONNECT_BIT];
	}
	if (events.lNetworkEvents & FD_ACCEPT)
		e |= FD_ACCEPT;
	if (events.lNetworkEvents & FD_CLOSE)
		e |= FD_CLOSE;
	int original = InterlockedOr(&f->shared->events, e);
	if (error_report_events & f->shared->events & FD_CONNECT)
	{
		WSASetLastError(f->shared->connect_error);
		f->shared->connect_error = 0;
		InterlockedAnd(&f->shared->events, ~FD_CONNECT);
	}
	return original | e;
}
Ejemplo n.º 5
0
static int socket_sendto_unsafe(struct socket_file *f, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, int addrlen)
{
	if (flags & ~LINUX_MSG_DONTWAIT)
		log_error("flags (0x%x) contains unsupported bits.", flags);
	struct sockaddr_storage addr_storage;
	if (addrlen)
	{
		if ((addrlen = translate_socket_addr_to_winsock((const struct sockaddr_storage *)dest_addr, &addr_storage, addrlen)) == SOCKET_ERROR)
			return -L_EINVAL;
		dest_addr = (const struct sockaddr *)&addr_storage;
	}
	else
		dest_addr = NULL;
	int r;
	while ((r = socket_wait_event(f, FD_WRITE, flags)) == 0)
	{
		r = sendto(f->socket, buf, len, 0, dest_addr, addrlen);
		if (r != SOCKET_ERROR)
			break;
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			log_warning("sendto() failed, error code: %d", err);
			return translate_socket_error(err);
		}
		InterlockedAnd(&f->shared->events, ~FD_WRITE);
	}
	return r;
}
Ejemplo n.º 6
0
static int socket_recvfrom_unsafe(struct socket_file *f, void *buf, size_t len, int flags, struct sockaddr *src_addr, int *addrlen)
{
	if (flags & ~(LINUX_MSG_PEEK | LINUX_MSG_DONTWAIT))
		log_error("flags (0x%x) contains unsupported bits.", flags);
	struct sockaddr_storage addr_storage;
	int addr_storage_len = sizeof(struct sockaddr_storage);
	int r;
	while ((r = socket_wait_event(f, FD_READ | FD_CLOSE, flags)) == 0)
	{
		if (!(flags & LINUX_MSG_PEEK))
			InterlockedAnd(&f->shared->events, ~FD_READ);
		r = recvfrom(f->socket, buf, len, flags, (struct sockaddr *)&addr_storage, &addr_storage_len);
		if (r != SOCKET_ERROR)
			break;
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			log_warning("recvfrom() failed, error code: %d", err);
			return translate_socket_error(err);
		}
	}
	if (addrlen)
	{
		addr_storage_len = translate_socket_addr_to_linux(&addr_storage, addr_storage_len);
		int copylen = min(*addrlen, addr_storage_len);
		memcpy(src_addr, &addr_storage, copylen);
		*addrlen = addr_storage_len;
	}
	return r;
}
Ejemplo n.º 7
0
//////////////////////////////////////////////////////////////////////////
/// iocp action
//////////////////////////////////////////////////////////////////////////
static void iocp_accept(struct aio_context* ctx, struct aio_context_action* aio, DWORD error, DWORD bytes)
{
	int locallen, remotelen;
	struct sockaddr *local;
	struct sockaddr *remote;
	assert(0 != (AIO_READ & InterlockedAnd(&ctx->flags, ~AIO_READ)));
	if(0 == error)
	{
		// http://msdn.microsoft.com/en-us/library/windows/desktop/ms737524%28v=vs.85%29.aspx
		// When the AcceptEx function returns, 
		// the socket sAcceptSocket is in the default state for a connected socket. 
		// The socket sAcceptSocket does not inherit the properties of the socket associated 
		// with sListenSocket parameter until SO_UPDATE_ACCEPT_CONTEXT is set on the socket
		setsockopt(aio->accept.socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&ctx->socket, sizeof(ctx->socket));

		local = remote = NULL;
		locallen = remotelen = 0;
		GetAcceptExSockaddrs(aio->accept.buffer, 0, sizeof(aio->accept.buffer)/2, sizeof(aio->accept.buffer)/2, &local, &locallen, &remote, &remotelen);
		aio->accept.proc(aio->accept.param, 0, aio->accept.socket, remote, remotelen);
		//aio->accept.proc(aio->accept.param, 0, aio->accept.socket, ip, (int)ntohs(remote->sin_port));
	}
	else
	{
		closesocket(aio->accept.socket); // close handle
		aio->accept.proc(aio->accept.param, error, 0, NULL, 0);
	}
}
Ejemplo n.º 8
0
VOID MPCreateThread(VOID (*FunctionPointer)(IN PKDPC, IN PVOID, IN PVOID, IN PVOID))
{
	/*
	*
	* Multi-Processor Consideration ::
	*
	* Each processor has it's own IDT.
	* 
	*/
	CCHAR i;
	long currentProcessor =0;
	PKDPC pkDpc =NULL;
	KIRQL oldIrql, currentIrql;

	allProcessorDone =0;

	currentIrql = KeGetCurrentIrql();

	if (currentIrql < DISPATCH_LEVEL)
		KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);

	InterlockedAnd(&allProcessorDone, 0);

	pkDpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool, KeNumberProcessors * sizeof(KDPC), (ULONG)' pni');

	if (!pkDpc)
	{
		DbgPrint("Insufficient Resource error\n");
		return;
	}

	currentProcessor = KeGetCurrentProcessorNumber();

	for (i = 0; i < KeNumberProcessors; i++)
	{
		cpuNum[i] =i;
		KeInitializeDpc(&pkDpc[i],
			FunctionPointer,
			&cpuNum[i]);
		KeSetTargetProcessorDpc(&pkDpc[i], i);
		KeInsertQueueDpc(&pkDpc[i], NULL, NULL);
	}

	// wait for all of the processor's hooking initialization.
	while(InterlockedCompareExchange(&allProcessorDone, KeNumberProcessors - 1, KeNumberProcessors - 1) != KeNumberProcessors - 1)
	{
		_asm pause;
	}

	if (currentIrql < DISPATCH_LEVEL)
		KeLowerIrql(oldIrql);

	if (pkDpc)
	{
		ExFreePool(pkDpc);
		pkDpc = NULL;
	}
}
Ejemplo n.º 9
0
gsize
(g_atomic_pointer_and) (volatile void *atomic,
                        gsize          val)
{
#if GLIB_SIZEOF_VOID_P == 8
  return InterlockedAnd64 (atomic, val);
#else
  return InterlockedAnd (atomic, val);
#endif
}
Ejemplo n.º 10
0
static inline int aio_socket_result(struct aio_context_action *aio, int flag)
{
	DWORD ret = WSAGetLastError();
	if (WSA_IO_PENDING != ret)
	{
		assert(0 != (flag & InterlockedAnd(&aio->context->flags, ~flag)));
		util_free(aio);
		return ret;
	}
	return 0;
}
Ejemplo n.º 11
0
static void iocp_connect(struct aio_context* ctx, struct aio_context_action* aio, DWORD error, DWORD bytes)
{
	(void)bytes;
	assert(0 != (AIO_WRITE & InterlockedAnd(&ctx->flags, ~AIO_WRITE)));
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms737606%28v=vs.85%29.aspx
	// When the ConnectEx function returns TRUE, the socket s is in the default state for a connected socket. 
	// The socket s does not enable previously set properties or options until SO_UPDATE_CONNECT_CONTEXT is 
	// set on the socket. Use the setsockopt function to set the SO_UPDATE_CONNECT_CONTEXT option.
	// r = setsockopt( s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 );
	aio->connect.proc(aio->connect.param, error);
}
Ejemplo n.º 12
0
Archivo: fdo.c Proyecto: Sha0/winvblock
/**
 * IRP_MJ_PNP:IRP_MN_REMOVE_DEVICE handler
 *
 * IRQL == PASSIVE_LEVEL, system thread
 * Completed by PDO
 * Do not send this IRP
 * Any child PDOs receive one of these IRPs first, except possibly
 * if they've been surprise-removed
 *
 * @return
 *   Success:
 *     Irp->IoStatus.Status == STATUS_SUCCESS
 */
static NTSTATUS STDCALL WvMemdiskPnpRemoveDevice(
    IN DEVICE_OBJECT * dev_obj,
    IN IRP * irp
  ) {
    S_WV_MEMDISK_BUS * bus;
    UCHAR i;
    DEVICE_OBJECT * child;
    NTSTATUS status;
    S_X86_SEG16OFF16 * safe_hook;
    UCHAR * phys_mem;
    UINT32 hook_phys_addr;
    WV_S_PROBE_SAFE_MBR_HOOK * hook;
    LONG flags;

    ASSERT(dev_obj);
    bus = dev_obj->DeviceExtension;
    ASSERT(bus);
    ASSERT(irp);

    /* Unlink the child PDOs, if any */
    for (i = 0; i < bus->BusRelations->Count; ++i) {
        child = bus->BusRelations->Objects[i];
        bus->BusRelations->Objects[i] = NULL;
        /* Best effort */
        WvlAssignDeviceToBus(child, NULL);
        WvlDeleteDevice(child);
      }
    bus->BusRelations->Count -= i;

    /* Send the IRP down */
    status = WvlPassIrpDown(dev_obj, irp);

    /* Detach FDO from PDO */
    WvlDetachDevice(dev_obj);

    /* Schedule deletion of this device when the thread finishes */
    WvlDeleteDevice(dev_obj);

    /* Best effort to "unclaim" the safe hook */
    phys_mem = WvlMapUnmapLowMemory(NULL);
    if (phys_mem) {
        safe_hook = WvlGetSafeHook(bus->PhysicalDeviceObject);
        ASSERT(safe_hook);
        hook_phys_addr = M_X86_SEG16OFF16_ADDR(safe_hook);
        hook = (VOID *) (phys_mem + hook_phys_addr);
        flags = InterlockedAnd(&hook->Flags, ~1);
        WvlMapUnmapLowMemory(phys_mem);
      }

    return status;
  }
Ejemplo n.º 13
0
__checkReturn
FLT_POSTOP_CALLBACK_STATUS
FLTAPI
PostWrite (
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
    )
{
    FLT_POSTOP_CALLBACK_STATUS fltStatus = FLT_POSTOP_FINISHED_PROCESSING;
    PStreamContext pStreamContext = (PStreamContext) CompletionContext;

    ASSERT( pStreamContext );

    __try
    {
        if ( FlagOn( Flags, FLTFL_POST_OPERATION_DRAINING ) )
        {
            __leave;
        }

        if ( !NT_SUCCESS( Data->IoStatus.Status ) )
        {
            __leave;
        }

        if ( !Data->IoStatus.Information )
        {
            __leave;
        }

        if ( FlagOn( Data->Iopb->IrpFlags, IRP_PAGING_IO ) )
        {
            //! \todo обработка MM файлов
            __leave;
        }

        InterlockedIncrement( &pStreamContext->m_WriteCount );
        InterlockedAnd( &pStreamContext->m_Flags, ~_STREAM_FLAGS_CASHE1 );
        InterlockedOr( &pStreamContext->m_Flags, _STREAM_FLAGS_MODIFIED );
    }
    __finally
    {
        ReleaseContext( (PFLT_CONTEXT*) &pStreamContext );
    }

    return fltStatus;
}
Ejemplo n.º 14
0
    inline ::LONG and ( volatile ::LONG& x, ::LONG y )
    {
#if defined(InterlockedAnd)
        return InterlockedAnd(&x, y);
#else
        LONG i;
        LONG j;
        j = x;
        do {
            i = j;
            j = InterlockedCompareExchange(&x, i&y, i);
        }
        while (i != j);
        return j;
#endif
    }
Ejemplo n.º 15
0
bool SetCOWPageBits(BYTE* pStart, size_t len, bool value)
{
    _ASSERTE(len > 0);

    // we don't need a barrier here, since:
    //  a) all supported hardware maintains ordering of dependent reads
    //  b) it's ok if additional reads happen, because this never changes
    //     once initialized.
    LONG* pCOWPageMap = g_pCOWPageMap;

    //
    // Write the bits in 32-bit chunks, to avoid doing one interlocked instruction for each bit.
    //
    size_t page = (size_t)pStart / PAGE_SIZE;
    size_t lastPage = (size_t)(pStart+len-1) / PAGE_SIZE;
    size_t elem = page / 32;
    LONG bits = 0;
    do
    {
        bits |= 1 << (page % 32);

        ++page;

        //
        // if we've moved to a new element of the map, or we've covered every page,
        // we need to write out the already-accumulated element.
        //
        size_t newElem = page / 32;
        if (page > lastPage || newElem != elem)
        {
            LONG* pElem = &pCOWPageMap[elem];
            if (!EnsureCOWPageMapElementAllocated(pElem))
                return false;

            if (value)
                InterlockedOr(&pCOWPageMap[elem], bits);
            else
                InterlockedAnd(&pCOWPageMap[elem], ~bits);

            elem = newElem;
            bits = 0;
        }
    }
    while (page <= lastPage);

    return true;
}
Ejemplo n.º 16
0
static int socket_sendmsg_unsafe(struct socket_file *f, const struct msghdr *msg, int flags)
{
	if (flags & ~LINUX_MSG_DONTWAIT)
		log_error("socket_sendmsg(): flags (0x%x) contains unsupported bits.", flags);
	WSABUF *buffers = (WSABUF *)alloca(sizeof(struct iovec) * msg->msg_iovlen);
	for (int i = 0; i < msg->msg_iovlen; i++)
	{
		buffers[i].len = msg->msg_iov[i].iov_len;
		buffers[i].buf = msg->msg_iov[i].iov_base;
	}
	struct sockaddr_storage addr_storage;
	WSAMSG wsamsg;
	if (msg->msg_namelen)
	{
		if ((wsamsg.namelen = translate_socket_addr_to_winsock(msg->msg_name, &addr_storage, msg->msg_namelen)) == SOCKET_ERROR)
			return -L_EINVAL;
		wsamsg.name = (LPSOCKADDR)&addr_storage;
	}
	else
	{
		wsamsg.name = NULL;
		wsamsg.namelen = 0;
	}
	wsamsg.lpBuffers = buffers;
	wsamsg.dwBufferCount = msg->msg_iovlen;
	wsamsg.Control.buf = msg->msg_control;
	wsamsg.Control.len = msg->msg_controllen;
	wsamsg.dwFlags = 0;
	
	int r;
	while ((r = socket_wait_event(f, FD_WRITE, flags)) == 0)
	{
		if (WSASendMsg(f->socket, &wsamsg, 0, &r, NULL, NULL) != SOCKET_ERROR)
			break;
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			log_warning("WSASendMsg() failed, error code: %d", err);
			return translate_socket_error(err);
		}
		InterlockedAnd(&f->shared->events, ~FD_WRITE);
	}
	return r;
}
Ejemplo n.º 17
0
__host__ __device__
typename enable_if<
  sizeof(Integer32) == 4,
  Integer32
>::type
atomic_fetch_and(Integer32 *x, Integer32 y)
{
#if defined(__CUDA_ARCH__)
  return atomicAnd(x, y);
#elif defined(__GNUC__)
  return __atomic_fetch_and(x, y, __ATOMIC_SEQ_CST);
#elif defined(_MSC_VER)
  return InterlockedAnd(x, y);
#elif defined(__clang__)
  return __c11_atomic_fetch_and(x, y)
#else
#error "No atomic_fetch_and implementation."
#endif
}
Ejemplo n.º 18
0
Archivo: hal.c Proyecto: callcc/tekui
static TUINT
hal_timedwaitevent(struct THALBase *hal, struct HALThread *t,
	TTIME *tektime, TUINT sigmask)
{
	struct HALSpecific *hws = hal->hmb_Specific;
	struct HALThread *wth = TlsGetValue(hws->hsp_TLSIndex);

	TTIME waitt, curt;
	TUINT millis;
	TUINT sig;

	for (;;)
	{
#ifndef HAL_USE_ATOMICS
		EnterCriticalSection(&wth->hth_SigLock);
		sig = wth->hth_SigState & sigmask;
		wth->hth_SigState &= ~sigmask;
		LeaveCriticalSection(&wth->hth_SigLock);
#else
		sig = InterlockedAnd(&wth->hth_SigState, ~sigmask) & sigmask;
#endif
		if (sig)
			break;

		waitt = *tektime;
		hal_getsystime(hal, &curt);
		TSubTime(&waitt, &curt);
		if (waitt.tdt_Int64 < 0)
			break;

		if (waitt.tdt_Int64 > 1000000000000LL)
			millis = 1000000000;
		else
			millis = waitt.tdt_Int64 / 1000;

		if (millis > 0)
			WaitForSingleObject(wth->hth_SigEvent, millis);
	}

	return sig;
}
Ejemplo n.º 19
0
Archivo: hal.c Proyecto: callcc/tekui
EXPORT TUINT
hal_wait(struct THALBase *hal, TUINT sigmask)
{
	struct HALSpecific *hws = hal->hmb_Specific;
	struct HALThread *wth = TlsGetValue(hws->hsp_TLSIndex);
	TUINT sig;
	for (;;)
	{
#ifndef HAL_USE_ATOMICS
		EnterCriticalSection(&wth->hth_SigLock);
		sig = wth->hth_SigState & sigmask;
		wth->hth_SigState &= ~sigmask;
		LeaveCriticalSection(&wth->hth_SigLock);
#else
		sig = InterlockedAnd(&wth->hth_SigState, ~sigmask) & sigmask;
#endif
		if (sig) break;
		WaitForSingleObject(wth->hth_SigEvent, INFINITE);
	}
	return sig;
}
Ejemplo n.º 20
0
Archivo: hal.c Proyecto: callcc/tekui
EXPORT TUINT
hal_setsignal(struct THALBase *hal, TUINT newsig, TUINT sigmask)
{
	struct HALSpecific *hws = hal->hmb_Specific;
	struct HALThread *wth = TlsGetValue(hws->hsp_TLSIndex);
#ifndef HAL_USE_ATOMICS 
	TUINT oldsig;
	EnterCriticalSection(&wth->hth_SigLock);
	oldsig = wth->hth_SigState;
	wth->hth_SigState &= ~sigmask;
	wth->hth_SigState |= newsig;
	LeaveCriticalSection(&wth->hth_SigLock);
	return oldsig;
#else
	TUINT cmask = ~sigmask | newsig;
	TUINT before_consume = InterlockedAnd(&wth->hth_SigState, cmask);
	if (! newsig)
		return before_consume;
	TUINT before_publish = InterlockedOr(&wth->hth_SigState, newsig);
	return (before_consume & ~cmask) | (before_publish & cmask);
#endif
}
Ejemplo n.º 21
0
static NTSTATUS NTAPI
V4vDispatchPnP(PDEVICE_OBJECT fdo, PIRP irp)
{
    NTSTATUS           status = STATUS_SUCCESS;
    PIO_STACK_LOCATION isl = IoGetCurrentIrpStackLocation(irp);
    PXENV4V_EXTENSION  pde = V4vGetDeviceExtension(fdo);
    KEVENT             kev;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    TraceVerbose((" =PnP= 0x%x\n", isl->MinorFunction));

    status = IoAcquireRemoveLock(&pde->removeLock, irp);
    if (!NT_SUCCESS(status)) {
        TraceError(("failed to acquire IO lock - error: 0x%x\n", status));
        return V4vSimpleCompleteIrp(irp, status);
    }

    switch (isl->MinorFunction) {
    case IRP_MN_START_DEVICE:
        KeInitializeEvent(&kev, NotificationEvent, FALSE);
        // Send the start down and wait for it to complete
        IoCopyCurrentIrpStackLocationToNext(irp);
        IoSetCompletionRoutine(irp, V4vStartDeviceIoCompletion, &kev, TRUE, TRUE, TRUE);
        status = IoCallDriver(pde->ldo, irp);
        if (status == STATUS_PENDING) {
            // Wait for everything underneath us to complete
            TraceVerbose(("Device start waiting for lower device.\n"));
            KeWaitForSingleObject(&kev, Executive, KernelMode, FALSE, NULL);
            TraceVerbose(("Device start wait finished.\n"));
        }

        status = irp->IoStatus.Status;
        if (!NT_SUCCESS(status)) {
            TraceError(("Failed to start lower drivers: %x.\n", status));
            IoCompleteRequest(irp, IO_NO_INCREMENT);
            break;
        }

        status = STATUS_SUCCESS;

        // Connect our interrupt (ec).
        status = V4vInitializeEventChannel(fdo);
        if (NT_SUCCESS(status)) {
            InterlockedExchange(&pde->state, XENV4V_DEV_STARTED);
        }
        else {
            TraceError(("failed to initialize event channel - error: 0x%x\n", status));
        }

        irp->IoStatus.Status = status;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
        break;
    case IRP_MN_STOP_DEVICE:
        // Stop our device's IO processing
        V4vStopDevice(fdo, pde);

        // Pass it down
        irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);
        break;        
    case IRP_MN_REMOVE_DEVICE:
        // Stop our device's IO processing
        V4vStopDevice(fdo, pde);

        // Cleanup anything here that locks for IO
        IoReleaseRemoveLockAndWait(&pde->removeLock, irp);

        // Pass it down first
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);

        // Then detach and cleanup our device
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CLOSED);
        IoDetachDevice(pde->ldo);
        ExDeleteNPagedLookasideList(&pde->destLookasideList);
        XmFreeMemory(pde->frontendPath);
        IoDeleteSymbolicLink(&pde->symbolicLink);
        IoDeleteDevice(fdo);
        InterlockedAnd(&g_deviceCreated, 0);
        return status;
    default:
        // Pass it down
        TraceVerbose(("IRP_MJ_PNP MinorFunction %d passed down\n", isl->MinorFunction));
        IoSkipCurrentIrpStackLocation(irp);
        status = IoCallDriver(pde->ldo, irp);
    };

    // Everybody but REMOVE
    IoReleaseRemoveLock(&pde->removeLock, irp); 

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}
Ejemplo n.º 22
0
inline void CMyDevice::ExitProcessing(DWORD64 dwControlFlag)
{
    //Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry");

    InterlockedAnd (&m_dwShutdownControlFlags, ~dwControlFlag);
}
Ejemplo n.º 23
0
NTKERNELAPI
VOID
FASTCALL
ExfWakePushLock (
    IN PEX_PUSH_LOCK PushLock,
    IN EX_PUSH_LOCK TopValue
    )
/*++

Routine Description:

    Walks the pushlock waiting list and wakes waiters if the lock is still unacquired.

Arguments:

    PushLock - Push lock to be walked

    TopValue - Start of the chain (*PushLock)

Return Value:

    None

--*/
{
    EX_PUSH_LOCK OldValue, NewValue;
    PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock, NextWaitBlock, FirstWaitBlock, PreviousWaitBlock;
    KIRQL OldIrql;

    OldValue = TopValue;

    while (1) {

        //
        // Nobody should be walking the list while we manipulate it.
        //

        ASSERT (!OldValue.MultipleShared);

        //
        // No point waking somebody to find a locked lock. Just clear the waking bit
        //

        while (OldValue.Locked) {
            NewValue.Value = OldValue.Value - EX_PUSH_LOCK_WAKING;
            ASSERT (!NewValue.Waking);
            ASSERT (NewValue.Locked);
            ASSERT (NewValue.Waiting);
            if ((NewValue.Ptr = InterlockedCompareExchangePointer (&PushLock->Ptr,
                                                                   NewValue.Ptr,
                                                                   OldValue.Ptr)) == OldValue.Ptr) {
                return;
            }
            OldValue = NewValue;
        }

        WaitBlock = (PEX_PUSH_LOCK_WAIT_BLOCK)
           (OldValue.Value & ~(ULONG_PTR)EX_PUSH_LOCK_PTR_BITS);

        FirstWaitBlock = WaitBlock;

        while (1) {

            NextWaitBlock = WaitBlock->Last;
            if (NextWaitBlock != NULL) {
                WaitBlock = NextWaitBlock;
                break;
            }

            PreviousWaitBlock = WaitBlock;
            WaitBlock = WaitBlock->Next;
            WaitBlock->Previous = PreviousWaitBlock;
        }

        if (WaitBlock->Flags&EX_PUSH_LOCK_FLAGS_EXCLUSIVE &&
            (PreviousWaitBlock = WaitBlock->Previous) != NULL) {

            FirstWaitBlock->Last = PreviousWaitBlock;

            WaitBlock->Previous = NULL;

            ASSERT (FirstWaitBlock != WaitBlock);

            ASSERT (PushLock->Waiting);

#if defined (_WIN64)
            InterlockedAnd64 ((LONG64 *)&PushLock->Value, ~EX_PUSH_LOCK_WAKING);
#else
            InterlockedAnd ((LONG *)&PushLock->Value, ~EX_PUSH_LOCK_WAKING);
#endif

            break;
        } else {
            NewValue.Value = 0;
            ASSERT (!NewValue.Waking);
            if ((NewValue.Ptr = InterlockedCompareExchangePointer (&PushLock->Ptr,
                                                                   NewValue.Ptr,
                                                                   OldValue.Ptr)) == OldValue.Ptr) {
                break;
            }
            OldValue = NewValue;
        }
    }

    //
    // If we are waking more than one thread then raise to DPC level to prevent us
    // getting rescheduled part way through the operation
    //

    OldIrql = DISPATCH_LEVEL;
    if (WaitBlock->Previous != NULL) {
        KeRaiseIrql (DISPATCH_LEVEL, &OldIrql);
    }

    while (1) {

        NextWaitBlock = WaitBlock->Previous;
#if DBG
        ASSERT (!WaitBlock->Signaled);
        WaitBlock->Signaled = TRUE;
#endif

        if (!InterlockedBitTestAndReset (&WaitBlock->Flags, EX_PUSH_LOCK_FLAGS_SPINNING_V)) {
            KeSignalGateBoostPriority (&WaitBlock->WakeGate);
        }

        WaitBlock = NextWaitBlock;
        if (WaitBlock == NULL) {
            break;
        }
    }

    if (OldIrql != DISPATCH_LEVEL) {
        KeLowerIrql (OldIrql);
    }
}
Ejemplo n.º 24
0
static int socket_accept4(struct file *f, struct sockaddr *addr, int *addrlen, int flags)
{
	struct socket_file *socket = (struct socket_file *)f;
	WaitForSingleObject(socket->mutex, INFINITE);
	struct sockaddr_storage addr_storage;
	int addr_storage_len;
	int r;
	while ((r = socket_wait_event(socket, FD_ACCEPT, 0)) == 0)
	{
		SOCKET socket_handle;
		addr_storage_len = sizeof(struct sockaddr_storage);
		if ((socket_handle = accept(socket->socket, (struct sockaddr *)&addr_storage, &addr_storage_len)) != SOCKET_ERROR)
		{
			/* Create a new socket */
			HANDLE event_handle = init_socket_event(socket_handle);
			if (!event_handle)
			{
				closesocket(socket_handle);
				log_error("init_socket_event() failed.");
				r = -L_ENFILE;
				break;
			}
			HANDLE mutex;
			SECURITY_ATTRIBUTES attr;
			attr.nLength = sizeof(SECURITY_ATTRIBUTES);
			attr.lpSecurityDescriptor = NULL;
			attr.bInheritHandle = TRUE;
			mutex = CreateMutexW(&attr, FALSE, NULL);
			struct socket_file *conn_socket = (struct socket_file *)kmalloc(sizeof(struct socket_file));
			file_init(&conn_socket->base_file, &socket_ops, 0);
			conn_socket->socket = socket_handle;
			conn_socket->event_handle = event_handle;
			conn_socket->mutex = mutex;
			conn_socket->shared = (struct socket_file_shared *)kmalloc_shared(sizeof(struct socket_file_shared));
			conn_socket->shared->af = socket->shared->af;
			conn_socket->shared->type = socket->shared->type;
			conn_socket->shared->events = 0;
			conn_socket->shared->connect_error = 0;
			if (flags & O_NONBLOCK)
				conn_socket->base_file.flags |= O_NONBLOCK;
			r = vfs_store_file((struct file *)conn_socket, 0);
			if (r < 0)
				vfs_release((struct file *)conn_socket);
			/* Translate address back to Linux format */
			if (addr && addrlen)
			{
				if (socket->shared->af == LINUX_AF_UNIX)
				{
					/* Set addr to unnamed */
					struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
					*addrlen = sizeof(addr_un->sun_family);
				}
				else
				{
					*addrlen = translate_socket_addr_to_linux(&addr_storage, addr_storage_len);
					memcpy(addr, &addr_storage, *addrlen);
				}
			}
			break;
		}
		int err = WSAGetLastError();
		if (err != WSAEWOULDBLOCK)
		{
			log_warning("accept() failed, error code: %d", err);
			r = translate_socket_error(err);
			break;
		}
		InterlockedAnd(&socket->shared->events, ~FD_ACCEPT);
	}
	ReleaseMutex(socket->mutex);
	return r;
}
Ejemplo n.º 25
0
static void iocp_recv(struct aio_context* ctx, struct aio_context_action* aio, DWORD error, DWORD bytes)
{
	assert(0 != (AIO_READ & InterlockedAnd(&ctx->flags, ~AIO_READ)));
	aio->recv.proc(aio->recv.param, error, bytes);
}
Ejemplo n.º 26
0
static void iocp_send(struct aio_context* ctx, struct aio_context_action* aio, DWORD error, DWORD bytes)
{
	assert(0 != (AIO_WRITE & InterlockedAnd(&ctx->flags, ~AIO_WRITE)));
	aio->send.proc(aio->send.param, error, bytes);
}
Ejemplo n.º 27
0
static void iocp_recvfrom(struct aio_context* ctx, struct aio_context_action* aio, DWORD error, DWORD bytes)
{
	assert(0 != (AIO_READ & InterlockedAnd(&ctx->flags, ~AIO_READ)));
	aio->recvfrom.proc(aio->recvfrom.param, error, bytes, (struct sockaddr*)&aio->recvfrom.addr, aio->recvfrom.addrlen);
}
Ejemplo n.º 28
0
/**
 * Drive a safe hook PDO with a safe hook FDO
 *
 * @param DriverObject
 *   The driver object provided by the caller
 *
 * @param PhysicalDeviceObject
 *   The PDO to probe and attach the safe hook FDO to
 *
 * @return
 *   The status of the operation
 */
static NTSTATUS STDCALL WvSafeHookDriveDevice(
    IN DRIVER_OBJECT * drv_obj,
    IN DEVICE_OBJECT * pdo
  ) {
    NTSTATUS status;
    S_X86_SEG16OFF16 * safe_hook;
    UCHAR * phys_mem;
    UINT32 hook_phys_addr;
    WV_S_PROBE_SAFE_MBR_HOOK * hook;
    LONG flags;
    DEVICE_OBJECT * fdo;
    S_WV_SAFE_HOOK_BUS * bus;

    if (pdo->DriverObject != drv_obj || !(safe_hook = WvlGetSafeHook(pdo))) {
        status = STATUS_NOT_SUPPORTED;
        goto err_safe_hook;
      }

    /* Ok, we'll try to drive this PDO with an FDO */
    phys_mem = WvlMapUnmapLowMemory(NULL);
    if (!phys_mem) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto err_phys_mem;
      }

    hook_phys_addr = M_X86_SEG16OFF16_ADDR(safe_hook);
    hook = (VOID *) (phys_mem + hook_phys_addr);

    /*
     * Quickly claim the safe hook.  Let's hope other drivers offer
     * the same courtesy
     */
    flags = InterlockedOr(&hook->Flags, 1);
    if (flags & 1) {
        DBG("Safe hook already claimed\n");
        status = STATUS_DEVICE_BUSY;
        goto err_claimed;
      }

    fdo = NULL;
    status = WvlCreateDevice(
        WvSafeHookMiniDriver,
        sizeof *bus,
        NULL,
        FILE_DEVICE_CONTROLLER,
        FILE_DEVICE_SECURE_OPEN,
        FALSE,
        &fdo
      );
    if (!NT_SUCCESS(status))
      goto err_fdo;
    ASSERT(fdo);

    bus = fdo->DeviceExtension;
    ASSERT(bus);

    bus->DeviceExtension->IrpDispatch = WvSafeHookIrpDispatch;
    bus->Flags = 0;
    bus->PhysicalDeviceObject = pdo;
    bus->BusRelations->Count = 0;
    bus->BusRelations->Objects[0] = NULL;
    bus->PreviousInt13hHandler[0] = hook->PrevHook;

    /* Attach the FDO to the PDO */
    if (!WvlAttachDeviceToDeviceStack(fdo, pdo)) {
        DBG("Error driving PDO %p!\n", (VOID *) pdo);
        status = STATUS_DRIVER_INTERNAL_ERROR;
        goto err_lower;
      }

    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
    DBG("Driving PDO %p with FDO %p\n", (VOID *) pdo, (VOID *) fdo);
    status = STATUS_SUCCESS;
    goto out;

    err_lower:

    WvlDeleteDevice(fdo);
    err_fdo:

    flags = InterlockedAnd(&hook->Flags, ~1);
    err_claimed:

    out:

    WvlMapUnmapLowMemory(phys_mem);
    err_phys_mem:

    err_safe_hook:

    if (!NT_SUCCESS(status))
      DBG("Refusing to drive PDO %p\n", (VOID *) pdo);
    return status;
  }
Ejemplo n.º 29
0
void FastInterlockAnd(uint32_t volatile *p, uint32_t msk)
{
    InterlockedAnd((LONG *)p, msk);
}
Ejemplo n.º 30
0
guint
(g_atomic_int_and) (volatile guint *atomic,
                    guint           val)
{
  return InterlockedAnd (atomic, val);
}