/**********************************************************
NDIS-required procedure for DPC handling
Parameters:
    PVOID  MiniportInterruptContext (Adapter context)
***********************************************************/
static VOID MiniportInterruptDPC(
    IN NDIS_HANDLE  MiniportInterruptContext,
    IN PVOID  MiniportDpcContext,
    IN PVOID                   ReceiveThrottleParameters,
    IN PVOID                   NdisReserved2
    )
{
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportInterruptContext;
    ULONG requiresProcessing;

#if NDIS_SUPPORT_NDIS620
    PNDIS_RECEIVE_THROTTLE_PARAMETERS RxThrottleParameters = (PNDIS_RECEIVE_THROTTLE_PARAMETERS)ReceiveThrottleParameters;
    DEBUG_ENTRY(5);
    RxThrottleParameters->MoreNblsPending = 0;
    requiresProcessing = ParaNdis_DPCWorkBody(pContext, RxThrottleParameters->MaxNblsToIndicate);
    if(requiresProcessing)
    {
        BOOLEAN bSpawnNextDpc = FALSE;
        DPrintf(4, ("[%s] Queued additional DPC for %d\n", __FUNCTION__,  requiresProcessing));
        InterlockedOr(&pContext->InterruptStatus, requiresProcessing);
        if(requiresProcessing & isReceive)
        {
            if (NDIS_INDICATE_ALL_NBLS != RxThrottleParameters->MaxNblsToIndicate)
                RxThrottleParameters->MoreNblsPending = 1;
            else
                bSpawnNextDpc = TRUE;
        }
        if(requiresProcessing & isTransmit)
            bSpawnNextDpc = TRUE;
        if (bSpawnNextDpc)
        {
            GROUP_AFFINITY Affinity;
            GetAffinityForCurrentCpu(&Affinity);

            NdisMQueueDpcEx(pContext->InterruptHandle, 0, &Affinity, MiniportDpcContext);
        }
    }
#else /* NDIS 6.0*/
    DEBUG_ENTRY(5);
    UNREFERENCED_PARAMETER(ReceiveThrottleParameters);

    requiresProcessing = ParaNdis_DPCWorkBody(pContext, PARANDIS_UNLIMITED_PACKETS_TO_INDICATE);
    if (requiresProcessing)
    {
        DPrintf(4, ("[%s] Queued additional DPC for %d\n", __FUNCTION__,  requiresProcessing));
        InterlockedOr(&pContext->InterruptStatus, requiresProcessing);
        NdisMQueueDpc(pContext->InterruptHandle, 0, 1 << KeGetCurrentProcessorNumber(), MiniportDpcContext);
    }
#endif /* NDIS_SUPPORT_NDIS620 */

    UNREFERENCED_PARAMETER(NdisReserved2);
}
Example #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);
}
Example #3
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;
}
Example #4
0
File: emutls.c Project: 0mp/freebsd
static __inline uintptr_t __atomic_load_n(void *ptr, unsigned type) {
    assert(type == __ATOMIC_ACQUIRE);
    // These return the previous value - but since we do an OR with 0,
    // it's equivalent to a plain load.
#ifdef _WIN64
    return InterlockedOr64(ptr, 0);
#else
    return InterlockedOr(ptr, 0);
#endif
}
Example #5
0
gsize
(g_atomic_pointer_or) (volatile void *atomic,
                       gsize          val)
{
#if GLIB_SIZEOF_VOID_P == 8
  return InterlockedOr64 (atomic, val);
#else
  return InterlockedOr (atomic, val);
#endif
}
Example #6
0
inline void CMyDevice::EnterShutdown()
{
    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry");
    //
    //  Begin shutdown.  Spin if control handler is in progress.
    //
    while (((InterlockedOr (&m_dwShutdownControlFlags, SHUTDOWN_IN_PROGRESS) & PROCESSING_IN_PROGRESS) != 0))
    {
        Yield();
    }
}
Example #7
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;
}
Example #8
0
inline HRESULT CMyDevice::EnterProcessing(DWORD64 dwControlFlag)
{
    //Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry");

    HRESULT hr = S_OK;

    if ((InterlockedOr (&m_dwShutdownControlFlags, dwControlFlag) & 
            SHUTDOWN_IN_PROGRESS) != 0)
    {
        hr = HRESULT_FROM_WIN32(ERROR_SHUTDOWN_IN_PROGRESS);
    }

    return hr;
}
Example #9
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;
}
Example #10
0
NTSTATUS
FltpStartingToDrainObject(_Inout_ PFLT_OBJECT Object)
{
    /*
     * Set the draining flag for the filter. This let's us force
     * a post op callback for minifilters currently awaiting one.
     */
    if (InterlockedOr((PLONG)&Object->Flags, FLT_OBFL_DRAINING) & 1)
    {
        /* We've been called once, we're already being deleted */
        return STATUS_FLT_DELETING_OBJECT;
    }

    return STATUS_SUCCESS;
}
Example #11
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;
}
Example #12
0
int aio_socket_sendto_v(aio_socket_t socket, const struct sockaddr *addr, socklen_t addrlen, socket_bufvec_t* vec, int n, aio_onsend proc, void* param)
{
	struct aio_context *ctx = (struct aio_context*)socket;
	struct aio_context_action *aio;
	
	aio = util_alloc(ctx);
	aio->action = iocp_send;
	aio->send.proc = proc;
	aio->send.param = param;

	assert(0 == (AIO_WRITE & InterlockedOr(&ctx->flags, AIO_WRITE)));
	if(SOCKET_ERROR == WSASendTo(ctx->socket, vec, (DWORD)n, NULL/*&dwBytes*/, 0, addr, addrlen, &aio->overlapped, NULL))
	{
		return aio_socket_result(aio, AIO_WRITE);
	}
	return 0;
}
Example #13
0
NTSTATUS
NTAPI
PspTerminateProcess(IN PEPROCESS Process,
                    IN NTSTATUS ExitStatus)
{
    PETHREAD Thread;
    NTSTATUS Status = STATUS_NOTHING_TO_TERMINATE;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG,
            "Process: %p ExitStatus: %d\n", Process, ExitStatus);
    PSREFTRACE(Process);

    /* Check if this is a Critical Process */
    if (Process->BreakOnTermination)
    {
        /* Break to debugger */
        PspCatchCriticalBreak("Terminating critical process 0x%p (%s)\n",
                              Process,
                              Process->ImageFileName);
    }

    /* Set the delete flag */
    InterlockedOr((PLONG)&Process->Flags, PSF_PROCESS_DELETE_BIT);

    /* Get the first thread */
    Thread = PsGetNextProcessThread(Process, NULL);
    while (Thread)
    {
        /* Kill it */
        PspTerminateThreadByPointer(Thread, ExitStatus, FALSE);
        Thread = PsGetNextProcessThread(Process, Thread);

        /* We had at least one thread, so termination is OK */
        Status = STATUS_SUCCESS;
    }

    /* Check if there was nothing to terminate or if we have a debug port */
    if ((Status == STATUS_NOTHING_TO_TERMINATE) || (Process->DebugPort))
    {
        /* Clear the handle table anyway */
        ObClearProcessHandleTable(Process);
    }

    /* Return status */
    return Status;
}
Example #14
0
int aio_socket_connect(aio_socket_t socket, const struct sockaddr *addr, socklen_t addrlen, aio_onconnect proc, void* param)
{
	struct aio_context *ctx = (struct aio_context*)socket;
	struct aio_context_action *aio;

	aio = util_alloc(ctx);
	aio->action = iocp_connect;
	aio->connect.proc = proc;
	aio->connect.param = param;

	assert(0 == (AIO_WRITE & InterlockedOr(&ctx->flags, AIO_WRITE)));
	if (!ConnectEx(ctx->socket, addr, addrlen, NULL, 0, NULL, &aio->overlapped))
	{
		return aio_socket_result(aio, AIO_WRITE);
	}
	return 0;
}
Example #15
0
int aio_socket_recv_v(aio_socket_t socket, socket_bufvec_t* vec, int n, aio_onrecv proc, void* param)
{
	DWORD flags = 0;
	struct aio_context *ctx = (struct aio_context*)socket;
	struct aio_context_action *aio;

	aio = util_alloc(ctx);
	aio->action = iocp_recv;
	aio->recv.proc = proc;
	aio->recv.param = param;

	assert(0 == (AIO_READ & InterlockedOr(&ctx->flags, AIO_READ)));
	if(SOCKET_ERROR == WSARecv(ctx->socket, vec, n, NULL/*&dwBytes*/, &flags, &aio->overlapped, NULL))
	{
		return aio_socket_result(aio, AIO_READ);
	}
	return 0;
}
Example #16
0
File: hal.c Project: callcc/tekui
EXPORT void
hal_signal(struct THALBase *hal, struct THALObject *thread, TUINT signals)
{
	struct HALThread *wth = THALGetObject(thread, struct HALThread);

#ifndef HAL_USE_ATOMICS
	EnterCriticalSection(&wth->hth_SigLock);
	if (signals & ~wth->hth_SigState)
	{
		wth->hth_SigState |= signals;
		SetEvent(wth->hth_SigEvent);
	}
	LeaveCriticalSection(&wth->hth_SigLock);
#else
	if (signals & ~(TUINT) InterlockedOr(&wth->hth_SigState, signals))
		SetEvent(wth->hth_SigEvent);
#endif

}
Example #17
0
__host__ __device__
typename enable_if<
  sizeof(Integer32) == 4,
  Integer32
>::type
atomic_fetch_xor(Integer32 *x, Integer32 y)
{
#if defined(__CUDA_ARCH__)
  return atomicXor(x, y);
#elif defined(__GNUC__)
  return __atomic_fetch_xor(x, y, __ATOMIC_SEQ_CST);
#elif defined(_MSC_VER)
  return InterlockedOr(x, y);
#elif defined(__clang__)
  return __c11_atomic_fetch_xor(x, y)
#else
#error "No atomic_fetch_xor implementation."
#endif
}
Example #18
0
bool EnsureCOWPageMapElementAllocated(LONG* elem)
{
    _ASSERTE(elem > g_pCOWPageMap);
    _ASSERTE(g_pCOWPageMap != NULL);

    size_t offset = (size_t)elem - (size_t)g_pCOWPageMap;
    size_t page = offset / PAGE_SIZE;
    
    _ASSERTE(page < 32);
    int bit = (int)(1 << page);
    
    if (!(g_COWPageMapMap & bit))
    {
        if (!VirtualAlloc(elem, 1, MEM_COMMIT, PAGE_READWRITE))
            return false;

        InterlockedOr(&g_COWPageMapMap, bit);
    }

    return true;
}
Example #19
0
File: hal.c Project: 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
}
Example #20
0
int aio_socket_accept(aio_socket_t socket, aio_onaccept proc, void* param)
{
	int ret;
	DWORD dwBytes = 0;
	WSAPROTOCOL_INFOW pi;
	struct aio_context *ctx = (struct aio_context*)socket;
	struct aio_context_action *aio;
	
	ret = sizeof(pi);
	if (0 != getsockopt(ctx->socket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&pi, &ret))
		return WSAGetLastError();

	aio = util_alloc(ctx);
	aio->action = iocp_accept;
	aio->accept.proc = proc;
	aio->accept.param = param;
	aio->accept.socket = WSASocket(pi.iAddressFamily, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
	if(INVALID_SOCKET == aio->accept.socket)
	{
		closesocket(aio->accept.socket);
		util_free(aio);
		return WSAGetLastError();
	}

	dwBytes = sizeof(aio->accept.buffer) / 2;
	assert(0 == (AIO_READ & InterlockedOr(&ctx->flags, AIO_READ)));
	if (!AcceptEx(ctx->socket, aio->accept.socket, aio->accept.buffer, 0, dwBytes, dwBytes, &dwBytes, &aio->overlapped))
	{
		ret = aio_socket_result(aio, AIO_READ);
		if(0 != ret)
		{
			closesocket(aio->accept.socket);
			return ret;
		}
	}
	return 0;
}
Example #21
0
File: hal.c Project: callcc/tekui
static TBOOL hal_replytimereq(struct TTimeRequest *tr)
{
	TBOOL success = TFALSE;
	struct TMessage *msg = TGETMSGPTR(tr);
	struct TMsgPort *mp = msg->tmsg_RPort;
	CRITICAL_SECTION *mplock = THALGetObject((TAPTR) &mp->tmp_Lock,
		CRITICAL_SECTION);
	if (TryEnterCriticalSection(mplock))
	{
		struct TTask *sigtask = mp->tmp_SigTask;
		struct HALThread *t =
			THALGetObject((TAPTR) &sigtask->tsk_Thread, struct HALThread);
#ifndef HAL_USE_ATOMICS
		if (TryEnterCriticalSection(&t->hth_SigLock))
#endif
		{
			tr->ttr_Req.io_Error = 0;
			msg->tmsg_Flags = TMSG_STATUS_REPLIED | TMSGF_QUEUED;
			TAddTail(&mp->tmp_MsgList, &msg->tmsg_Node);
#ifndef HAL_USE_ATOMICS
			if (mp->tmp_Signal & ~t->hth_SigState)
			{
				t->hth_SigState |= mp->tmp_Signal;
				SetEvent(t->hth_SigEvent);
			}
			LeaveCriticalSection(&t->hth_SigLock);
#else
			if (mp->tmp_Signal &
					~(TUINT) InterlockedOr(&t->hth_SigState, mp->tmp_Signal))
				SetEvent(t->hth_SigEvent);
#endif
			success = TTRUE;
		}
		LeaveCriticalSection(mplock);
	}
	return success;
}
Example #22
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;
  }
/**********************************************************
NDIS-required procedure for MSI DPC handling
Parameters:
    PVOID  MiniportInterruptContext (Adapter context)
    IN ULONG  MessageId - specific interrupt index
***********************************************************/
static VOID MiniportMSIInterruptDpc(
    IN PVOID  MiniportInterruptContext,
    IN ULONG  MessageId,
    IN PVOID  MiniportDpcContext,
#if NDIS_SUPPORT_NDIS620
    IN PVOID                   ReceiveThrottleParameters,
    IN PVOID                   NdisReserved2
#else
    IN PULONG                  NdisReserved1,
    IN PULONG                  NdisReserved2
#endif
    )
{
    PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportInterruptContext;
    ULONG interruptSource = MessageToInterruptSource(pContext, MessageId);

#if NDIS_SUPPORT_NDIS620
    BOOLEAN bSpawnNextDpc = FALSE;
    PNDIS_RECEIVE_THROTTLE_PARAMETERS RxThrottleParameters = (PNDIS_RECEIVE_THROTTLE_PARAMETERS)ReceiveThrottleParameters;

    DPrintf(5, ("[%s] (Message %d, source %d)\n", __FUNCTION__, MessageId, interruptSource));

    RxThrottleParameters->MoreNblsPending = 0;
    interruptSource = ParaNdis_DPCWorkBody(pContext, RxThrottleParameters->MaxNblsToIndicate);

    if (interruptSource)
    {
        InterlockedOr(&pContext->InterruptStatus, interruptSource);
        if (interruptSource & isReceive)
        {
            if (NDIS_INDICATE_ALL_NBLS != RxThrottleParameters->MaxNblsToIndicate)
            {
                RxThrottleParameters->MoreNblsPending = 1;
                DPrintf(3, ("[%s] Requested additional RX DPC\n", __FUNCTION__));
            }
            else
                bSpawnNextDpc = TRUE;
        }

        if (interruptSource & isTransmit)
            bSpawnNextDpc = TRUE;

        if (bSpawnNextDpc)
        {
            GROUP_AFFINITY Affinity;
            GetAffinityForCurrentCpu(&Affinity);

            NdisMQueueDpcEx(pContext->InterruptHandle, MessageId, &Affinity, MiniportDpcContext);
        }
    }
#else
    UNREFERENCED_PARAMETER(NdisReserved1);

    DPrintf(5, ("[%s] (Message %d, source %d)\n", __FUNCTION__, MessageId, interruptSource));
    interruptSource = ParaNdis_DPCWorkBody(pContext, PARANDIS_UNLIMITED_PACKETS_TO_INDICATE);
    if (interruptSource)
    {
        DPrintf(4, ("[%s] Queued additional DPC for %d\n", __FUNCTION__, interruptSource));
        InterlockedOr(&pContext->InterruptStatus, interruptSource);
        NdisMQueueDpc(pContext->InterruptHandle, MessageId, 1 << KeGetCurrentProcessorNumber(), MiniportDpcContext);
    }
#endif

    UNREFERENCED_PARAMETER(NdisReserved2);
}
Example #24
0
void FastInterlockOr(uint32_t volatile *p, uint32_t msk)
{
    InterlockedOr((LONG *)p, msk);
}
Example #25
0
guint
(g_atomic_int_or) (volatile guint *atomic,
                   guint           val)
{
  return InterlockedOr (atomic, val);
}
Example #26
0
//
// Routine Description:
//
//  PL011pInterruptIsr is called by PL011EvtInterruptIsr 
//  to process interrupts events at ISR level.
//  The routine saves the received event mask in the device extension
//  for DPC processing.
//  If RX/TX FIFO events occur, the routine calls the RX/TX handlers
//  to copy new/pending data from/to RX/TX FIFOs.
//
// Arguments:
//
//  DevExtPtr - Our device extension.
//
// Return Value:
//
//  TRUE If interrupt has been serviced, i.e. the source was the PL011 UART,
//  otherwise FALSE.
//
_Use_decl_annotations_
BOOLEAN
PL011pInterruptIsr(
    PL011_DEVICE_EXTENSION* DevExtPtr
    )
{
    //
    // Interrupt status register
    //
    ULONG regUARTRIS = PL011HwReadRegisterUlong(
        PL011HwRegAddress(DevExtPtr, UARTRIS)
        );
    if ((regUARTRIS & UART_INTERUPPTS_ALL) == 0) {
        //
        // Not the UART interrupt
        //
        return FALSE;
    }

    //
    // Update the events mask to be handled at DPC 
    // level.
    //
    InterlockedOr(
        reinterpret_cast<volatile LONG*>(&DevExtPtr->IntEventsForDpc),
        regUARTRIS
        );

    //
    // RX interrupt:
    // If a character has been received, or the FIFO is
    // not empty, and RX timeout has occurred.
    // Basically if RX FIFO is not empty.
    //
    // Copy the RX FIFO to our local RX buffer.
    //
    if ((regUARTRIS & (UARTRIS_RXIS|UARTRIS_RTIS)) != 0) {
        //
        // Copy new data from RX FIFO to PIO RX buffer.
        //
        (void)PL011RxPioFifoCopy(DevExtPtr, nullptr);

        //
        // Update the state to RX_PIO_STATE__DATA_READY if
        // we are still reading data to let the read engine 
        // know new data is ready.
        //
        (void)PL011RxPioStateSetCompare(
            DevExtPtr->SerCx2PioReceive,
            PL011_RX_PIO_STATE::RX_PIO_STATE__DATA_READY,
            PL011_RX_PIO_STATE::RX_PIO_STATE__READ_DATA
            );

    } // if (RX interrupt)

    //
    // TX interrupt:
    // If TX FIFOs occupancy has gone bellow the configured
    // trigger level.
    //
    // Copy our local TX buffer to TX FIFO.
    //
    if ((regUARTRIS & UARTRIS_TXIS) != 0) {
        //
        // Copy pending data from PIO TX buffer to TX FIFO.
        //
        PL011TxPioFifoCopy(DevExtPtr, nullptr);

        (void)PL011TxPioStateSetCompare(
            DevExtPtr->SerCx2PioTransmit,
            PL011_TX_PIO_STATE::TX_PIO_STATE__DATA_SENT,
            PL011_TX_PIO_STATE::TX_PIO_STATE__SEND_DATA
            );

    } // if (TX interrupt)

    //
    // Acknowledge the events we just processed.
    //
    PL011HwWriteRegisterUlong(
        PL011HwRegAddress(DevExtPtr, UARTICR),
        regUARTRIS
        );

    return TRUE;
}
Example #27
0
NTSTATUS
NTAPI
VdmpStartExecution(VOID)
{
    PETHREAD Thread = PsGetCurrentThread();
    PKTRAP_FRAME VdmFrame;
    NTSTATUS Status;
    PVDM_TIB VdmTib;
    BOOLEAN Interrupts;
    KIRQL OldIrql;
    CONTEXT VdmContext;
    PAGED_CODE();

    /* Get the thread's VDM frame and TIB */
    VdmFrame = (PVOID)((ULONG_PTR)Thread->Tcb.InitialStack -
                                  sizeof(FX_SAVE_AREA) -
                                  sizeof(KTRAP_FRAME));
    Status = VdmpGetVdmTib(&VdmTib);
    if (!NT_SUCCESS(Status)) return STATUS_INVALID_SYSTEM_SERVICE;

    /* Go to APC level */
    KeRaiseIrql(APC_LEVEL, &OldIrql);

    /* Check if interrupts are enabled */
    Interrupts = (BOOLEAN)(VdmTib->VdmContext.EFlags & EFLAGS_INTERRUPT_MASK);

    /* We don't support full VDM yet, this shouldn't happen */
    ASSERT(*VdmState == 0);
    ASSERT(VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK);

    /* Check if VME is supported and V86 mode was enabled */
    if ((KeI386VirtualIntExtensions) &&
        (VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK))
    {
        /* Check if interrupts are enabled */
        if (Interrupts)
        {
            /* Set fake IF flag */
            VdmTib->VdmContext.EFlags |= EFLAGS_VIF;
        }
        else
        {
            /* Remove fake IF flag, turn on real IF flag */
            VdmTib->VdmContext.EFlags &= ~EFLAGS_VIF;
            VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK;
        }
    }
    else
    {
        /* Set interrupt state in the VDM State */
        if (VdmTib->VdmContext.EFlags & EFLAGS_INTERRUPT_MASK)
        {
            /* Enable them as well */
            InterlockedOr((PLONG)VdmState, EFLAGS_INTERRUPT_MASK);
        }
        else
        {
            /* Disable them */
            InterlockedAnd((PLONG)VdmState, ~EFLAGS_INTERRUPT_MASK);
        }

        /* Enable the interrupt flag */
        VdmTib->VdmContext.EFlags |= EFLAGS_INTERRUPT_MASK;
    }

    /*  Get the VDM context and make sure it's not an edited frame */
    VdmContext = VdmTib->VdmContext;
    if (!(VdmContext.SegCs & FRAME_EDITED))
    {
        /* Fail */
        KeLowerIrql(OldIrql);
        return STATUS_INVALID_SYSTEM_SERVICE;
    }
    
    /* Now do the VDM Swap */
    VdmSwapContext(VdmFrame, &VdmTib->MonitorContext, &VdmContext);

    /* Lower the IRQL and return EAX */
    KeLowerIrql(OldIrql);
    return VdmFrame->Eax;
}
Example #28
0
/*
 * FUNCTION: Terminates the current thread
 * See "Windows Internals" - Chapter 13, Page 50-53
 */
VOID
NTAPI
PspExitThread(IN NTSTATUS ExitStatus)
{
    CLIENT_DIED_MSG TerminationMsg;
    NTSTATUS Status;
    PTEB Teb;
    PEPROCESS CurrentProcess;
    PETHREAD Thread, OtherThread, PreviousThread = NULL;
    PVOID DeallocationStack;
    SIZE_T Dummy;
    BOOLEAN Last = FALSE;
    PTERMINATION_PORT TerminationPort, NextPort;
    PLIST_ENTRY FirstEntry, CurrentEntry;
    PKAPC Apc;
    PTOKEN PrimaryToken;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);

    /* Get the Current Thread and Process */
    Thread = PsGetCurrentThread();
    CurrentProcess = Thread->ThreadsProcess;
    ASSERT((Thread) == PsGetCurrentThread());

    /* Can't terminate a thread if it attached another process */
    if (KeIsAttachedProcess())
    {
        /* Bugcheck */
        KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
                     (ULONG_PTR)CurrentProcess,
                     (ULONG_PTR)Thread->Tcb.ApcState.Process,
                     (ULONG_PTR)Thread->Tcb.ApcStateIndex,
                     (ULONG_PTR)Thread);
    }

    /* Lower to Passive Level */
    KeLowerIrql(PASSIVE_LEVEL);

    /* Can't be a worker thread */
    if (Thread->ActiveExWorker)
    {
        /* Bugcheck */
        KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
                     (ULONG_PTR)Thread,
                     0,
                     0,
                     0);
    }

    /* Can't have pending APCs */
    if (Thread->Tcb.CombinedApcDisable != 0)
    {
        /* Bugcheck */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     0,
                     Thread->Tcb.CombinedApcDisable,
                     0,
                     1);
    }

    /* Lock the thread */
    ExWaitForRundownProtectionRelease(&Thread->RundownProtect);

    /* Cleanup the power state */
    PopCleanupPowerState((PPOWER_STATE)&Thread->Tcb.PowerState);

    /* Call the WMI Callback for Threads */
    //WmiTraceThread(Thread, NULL, FALSE);

    /* Run Thread Notify Routines before we desintegrate the thread */
    PspRunCreateThreadNotifyRoutines(Thread, FALSE);

    /* Lock the Process before we modify its thread entries */
    KeEnterCriticalRegion();
    ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);

    /* Decrease the active thread count, and check if it's 0 */
    if (!(--CurrentProcess->ActiveThreads))
    {
        /* Set the delete flag */
        InterlockedOr((PLONG)&CurrentProcess->Flags, PSF_PROCESS_DELETE_BIT);

        /* Remember we are last */
        Last = TRUE;

        /* Check if this termination is due to the thread dying */
        if (ExitStatus == STATUS_THREAD_IS_TERMINATING)
        {
            /* Check if the last thread was pending */
            if (CurrentProcess->ExitStatus == STATUS_PENDING)
            {
                /* Use the last exit status */
                CurrentProcess->ExitStatus = CurrentProcess->
                                             LastThreadExitStatus;
            }
        }
        else
        {
            /* Just a normal exit, write the code */
            CurrentProcess->ExitStatus = ExitStatus;
        }

        /* Loop all the current threads */
        FirstEntry = &CurrentProcess->ThreadListHead;
        CurrentEntry = FirstEntry->Flink;
        while (FirstEntry != CurrentEntry)
        {
            /* Get the thread on the list */
            OtherThread = CONTAINING_RECORD(CurrentEntry,
                                            ETHREAD,
                                            ThreadListEntry);

            /* Check if it's a thread that's still alive */
            if ((OtherThread != Thread) &&
                !(KeReadStateThread(&OtherThread->Tcb)) &&
                (ObReferenceObjectSafe(OtherThread)))
            {
                /* It's a live thread and we referenced it, unlock process */
                ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
                KeLeaveCriticalRegion();

                /* Wait on the thread */
                KeWaitForSingleObject(OtherThread,
                                      Executive,
                                      KernelMode,
                                      FALSE,
                                      NULL);

                /* Check if we had a previous thread to dereference */
                if (PreviousThread) ObDereferenceObject(PreviousThread);

                /* Remember the thread and re-lock the process */
                PreviousThread = OtherThread;
                KeEnterCriticalRegion();
                ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
            }

            /* Go to the next thread */
            CurrentEntry = CurrentEntry->Flink;
        }
    }
    else if (ExitStatus != STATUS_THREAD_IS_TERMINATING)
    {
        /* Write down the exit status of the last thread to get killed */
        CurrentProcess->LastThreadExitStatus = ExitStatus;
    }

    /* Unlock the Process */
    ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
    KeLeaveCriticalRegion();

    /* Check if we had a previous thread to dereference */
    if (PreviousThread) ObDereferenceObject(PreviousThread);

    /* Check if the process has a debug port and if this is a user thread */
    if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
    {
        /* Notify the Debug API. */
        Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
               DbgkExitThread(ExitStatus);
    }

    /* Check if this is a Critical Thread */
    if ((KdDebuggerEnabled) && (Thread->BreakOnTermination))
    {
        /* Break to debugger */
        PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
                              Thread,
                              CurrentProcess->ImageFileName);
    }

    /* Check if it's the last thread and this is a Critical Process */
    if ((Last) && (CurrentProcess->BreakOnTermination))
    {
        /* Check if a debugger is here to handle this */
        if (KdDebuggerEnabled)
        {
            /* Break to debugger */
            PspCatchCriticalBreak("Critical  process 0x%p (in %s) exited\n",
                                  CurrentProcess,
                                  CurrentProcess->ImageFileName);
        }
        else
        {
            /* Bugcheck, we can't allow this */
            KeBugCheckEx(CRITICAL_PROCESS_DIED,
                         (ULONG_PTR)CurrentProcess,
                         0,
                         0,
                         0);
        }
    }

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Process the Termination Ports */
    TerminationPort = Thread->TerminationPort;
    if (TerminationPort)
    {
        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Loop each port */
        do
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(TerminationPort->Port,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }

            /* Dereference this LPC Port */
            ObDereferenceObject(TerminationPort->Port);

            /* Move to the next one */
            NextPort = TerminationPort->Next;

            /* Free the Termination Port Object */
            ExFreePoolWithTag(TerminationPort, '=TsP');

            /* Keep looping as long as there is a port */
            TerminationPort = NextPort;
        } while (TerminationPort);
    }
    else if (((ExitStatus == STATUS_THREAD_IS_TERMINATING) &&
              (Thread->DeadThread)) ||
             !(Thread->DeadThread))
    {
        /*
         * This case is special and deserves some extra comments. What
         * basically happens here is that this thread doesn't have a termination
         * port, which means that it died before being fully created. Since we
         * still have to notify an LPC Server, we'll use the exception port,
         * which we know exists. However, we need to know how far the thread
         * actually got created. We have three possibilities:
         *
         *  - NtCreateThread returned an error really early: DeadThread is set.
         *  - NtCreateThread managed to create the thread: DeadThread is off.
         *  - NtCreateThread was creating the thread (with DeadThread set,
         *    but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
         *    is our exit code.)
         *
         * For the 2 & 3rd scenarios, the thread has been created far enough to
         * warrant notification to the LPC Server.
         */

        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Make sure the process has an exception port */
        if (CurrentProcess->ExceptionPort)
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(CurrentProcess->ExceptionPort,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }
        }
    }

    /* Rundown Win32 Thread if there is one */
    if (Thread->Tcb.Win32Thread) PspW32ThreadCallout(Thread,
                                                     PsW32ThreadCalloutExit);

    /* If we are the last thread and have a W32 Process */
    if ((Last) && (CurrentProcess->Win32Process))
    {
        /* Run it down too */
        PspW32ProcessCallout(CurrentProcess, FALSE);
    }

    /* Make sure Stack Swap is enabled */
    if (!Thread->Tcb.EnableStackSwap)
    {
        /* Stack swap really shouldn't be disabled during exit! */
        KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
    }

    /* Cancel I/O for the thread. */
    IoCancelThreadIo(Thread);

    /* Rundown Timers */
    ExTimerRundown();

    /* FIXME: Rundown Registry Notifications (NtChangeNotify)
    CmNotifyRunDown(Thread); */

    /* Rundown Mutexes */
    KeRundownThread();

    /* Check if we have a TEB */
    Teb = Thread->Tcb.Teb;
    if (Teb)
    {
        /* Check if the thread is still alive */
        if (!Thread->DeadThread)
        {
            /* Check if we need to free its stack */
            if (Teb->FreeStackOnTermination)
            {
                /* Set the TEB's Deallocation Stack as the Base Address */
                Dummy = 0;
                DeallocationStack = Teb->DeallocationStack;

                /* Free the Thread's Stack */
                ZwFreeVirtualMemory(NtCurrentProcess(),
                                    &DeallocationStack,
                                    &Dummy,
                                    MEM_RELEASE);
            }

            /* Free the debug handle */
            if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
                                                     UserMode);
        }

        /* Decommit the TEB */
        MmDeleteTeb(CurrentProcess, Teb);
        Thread->Tcb.Teb = NULL;
    }

    /* Free LPC Data */
    LpcExitThread(Thread);

    /* Save the exit status and exit time */
    Thread->ExitStatus = ExitStatus;
    KeQuerySystemTime(&Thread->ExitTime);

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Check if this is the final thread or not */
    if (Last)
    {
        /* Set the process exit time */
        CurrentProcess->ExitTime = Thread->ExitTime;

        /* Exit the process */
        PspExitProcess(TRUE, CurrentProcess);

        /* Get the process token and check if we need to audit */
        PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
        if (SeDetailedAuditingWithToken(PrimaryToken))
        {
            /* Audit the exit */
            SeAuditProcessExit(CurrentProcess);
        }

        /* Dereference the process token */
        ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);

        /* Check if this is a VDM Process and rundown the VDM DPCs if so */
        if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }

        /* Kill the process in the Object Manager */
        ObKillProcess(CurrentProcess);

        /* Check if we have a section object */
        if (CurrentProcess->SectionObject)
        {
            /* Dereference and clear the Section Object */
            ObDereferenceObject(CurrentProcess->SectionObject);
            CurrentProcess->SectionObject = NULL;
        }

        /* Check if the process is part of a job */
        if (CurrentProcess->Job)
        {
            /* Remove the process from the job */
            PspExitProcessFromJob(CurrentProcess->Job, CurrentProcess);
        }
    }

    /* Disable APCs */
    KeEnterCriticalRegion();

    /* Disable APC queueing, force a resumption */
    Thread->Tcb.ApcQueueable = FALSE;
    KeForceResumeThread(&Thread->Tcb);

    /* Re-enable APCs */
    KeLeaveCriticalRegion();

    /* Flush the User APCs */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
    if (FirstEntry)
    {
        /* Start with the first entry */
        CurrentEntry = FirstEntry;
        do
        {
           /* Get the APC */
           Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);

           /* Move to the next one */
           CurrentEntry = CurrentEntry->Flink;

           /* Rundown the APC or de-allocate it */
           if (Apc->RundownRoutine)
           {
              /* Call its own routine */
              Apc->RundownRoutine(Apc);
           }
           else
           {
              /* Do it ourselves */
              ExFreePool(Apc);
           }
        }
        while (CurrentEntry != FirstEntry);
    }

    /* Clean address space if this was the last thread */
    if (Last) MmCleanProcessAddressSpace(CurrentProcess);

    /* Call the Lego routine */
    if (Thread->Tcb.LegoData) PspRunLegoRoutine(&Thread->Tcb);

    /* Flush the APC queue, which should be empty */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
    if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
    {
        /* Bugcheck time */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     (ULONG_PTR)FirstEntry,
                     Thread->Tcb.CombinedApcDisable,
                     KeGetCurrentIrql(),
                     0);
    }

    /* Signal the process if this was the last thread */
    if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);

    /* Terminate the Thread from the Scheduler */
    KeTerminateThread(0);
}
Example #29
0
VOID
NTAPI
PspExitProcess(IN BOOLEAN LastThread,
               IN PEPROCESS Process)
{
    ULONG Actual;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG,
            "LastThread: %u Process: %p\n", LastThread, Process);
    PSREFTRACE(Process);

    /* Set Process Exit flag */
    InterlockedOr((PLONG)&Process->Flags, PSF_PROCESS_EXITING_BIT);

    /* Check if we are the last thread */
    if (LastThread)
    {
        /* Notify the WMI Process Callback */
        //WmiTraceProcess(Process, FALSE);

        /* Run the Notification Routines */
        PspRunCreateProcessNotifyRoutines(Process, FALSE);
    }

    /* Cleanup the power state */
    PopCleanupPowerState((PPOWER_STATE)&Process->Pcb.PowerState);

    /* Clear the security port */
    if (!Process->SecurityPort)
    {
        /* So we don't double-dereference */
        Process->SecurityPort = (PVOID)1;
    }
    else if (Process->SecurityPort != (PVOID)1)
    {
        /* Dereference it */
        ObDereferenceObject(Process->SecurityPort);
        Process->SecurityPort = (PVOID)1;
    }

    /* Check if we are the last thread */
    if (LastThread)
    {
        /* Check if we have to set the Timer Resolution */
        if (Process->SetTimerResolution)
        {
            /* Set it to default */
            ZwSetTimerResolution(KeMaximumIncrement, 0, &Actual);
        }

        /* Check if we are part of a Job that has a completion port */
        if ((Process->Job) && (Process->Job->CompletionPort))
        {
            /* FIXME: Check job status code and do I/O completion if needed */
        }

        /* FIXME: Notify the Prefetcher */
    }
    else
    {
        /* Clear process' address space here */
        MmCleanProcessAddressSpace(Process);
    }
}
Example #30
0
/** PnP IRP dispatcher */
static NTSTATUS STDCALL WvDummyDispatchPnpIrp(
    IN DEVICE_OBJECT * dev_obj,
    IN IRP * irp
  ) {
    IO_STACK_LOCATION * io_stack_loc;
    NTSTATUS status;
    S_WVL_DUMMY_PDO * dummy;
    LONG flags;

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

    io_stack_loc = IoGetCurrentIrpStackLocation(irp);
    ASSERT(io_stack_loc);

    switch (io_stack_loc->MinorFunction) {
        case IRP_MN_QUERY_ID:
        return WvDummyPnpQueryId(dev_obj, irp);

        case IRP_MN_QUERY_DEVICE_TEXT:
        return WvDummyPnpQueryDeviceText(dev_obj, irp);

        case IRP_MN_QUERY_BUS_INFORMATION:
        return WvDummyPnpQueryBusInfo(dev_obj, irp);

        case IRP_MN_QUERY_CAPABILITIES:
        return WvDummyPnpQueryCapabilities(dev_obj, irp);

        case IRP_MN_QUERY_REMOVE_DEVICE:
        status = STATUS_SUCCESS;
        irp->IoStatus.Information = 0;
        break;

        case IRP_MN_SURPRISE_REMOVAL:
        WvlIncrementResourceUsage(dummy->DeviceExtension->Usage);
        flags = InterlockedOr(&dummy->Flags, CvWvDummyFlagSurpriseRemoved);
        status = STATUS_SUCCESS;
        irp->IoStatus.Information = 0;
        break;

        case IRP_MN_REMOVE_DEVICE:
        flags = InterlockedOr(&dummy->Flags, 0);
        if (flags & CvWvDummyFlagSurpriseRemoved)
          WvlDecrementResourceUsage(dummy->DeviceExtension->Usage);
        status = STATUS_SUCCESS;
        irp->IoStatus.Information = 0;
        break;

        case IRP_MN_START_DEVICE:
        status = STATUS_SUCCESS;
        break;

        default:
        /* Return whatever upper drivers in the stack yielded */
        status = irp->IoStatus.Status;
      }

    irp->IoStatus.Status = status;
    WvlPassIrpUp(dev_obj, irp, IO_NO_INCREMENT);
    return status;
  }