Example #1
0
BOOL GUIAPI EmptyMessageQueue (HWND hWnd)
{
    PMSGQUEUE   pMsgQueue;
    PQMSG       pQMsg, temp;

    if (!(pMsgQueue = GetMsgQueue(hWnd)))
        return FALSE;

    if (pMsgQueue->pFirstNotifyMsg) {
        pQMsg = pMsgQueue->pFirstNotifyMsg;
        while (pQMsg) {
            temp = pQMsg->next;
            FreeQMSG (pQMsg);
            pQMsg = temp;
        }
    }

    pMsgQueue->pFirstNotifyMsg = NULL;
    pMsgQueue->pLastNotifyMsg = NULL;

    pMsgQueue->readpos = 0;
    pMsgQueue->writepos = 0;

    TerminateTimer ();

    pMsgQueue->dwState = QS_EMPTY;
    pMsgQueue->TimerMask = 0;

    return TRUE;
}
Example #2
0
DLC_STATUS
LlcCloseStation(
    IN PLLC_OBJECT pStation,
    IN PLLC_PACKET pCompletionPacket
    )

/*++

Routine Description:

    The primitive closes a direct, sap or link station object.
    All pending transmit commands are terminated.
    This primitive does not support graceful termination, but
    the upper level must wait the pending transmit commands, if
    it want to make a clean close (without deleting the transmit queue).

    For a link station this  primitive releases a disconnected link
    station or discards a remote connection request.

Arguments:

    pStation            - handle of a link, sap or direct station
    pCompletionPacket   - returned context, when the command is complete

Return Value:

    DLC_STATUS
        Success - STATUS_SUCCESS
        Failure - DLC_STATUS_INVALID_PARAMETERS
                    the SAP has still active link stations. All active link
                    stations must be closed before sap can be closed.

--*/

{
    PADAPTER_CONTEXT pAdapterContext = pStation->Gen.pAdapterContext;
    PBINDING_CONTEXT pOldBinding;
    PDATA_LINK* ppLink;
    PVOID* ppLinkListBase;
    PEVENT_PACKET pEvent;

    if (pStation->Gen.ObjectType == LLC_LINK_OBJECT) {

        //
        // The remote connection requests are routed through all
        // SAP station reqistered on a SAP until someone accepts
        // the connection request or it has been routed to all
        // clients having opened the sap station.
        //

        if (pStation->Link.Flags & DLC_ACTIVE_REMOTE_CONNECT_REQUEST) {

            ACQUIRE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

            pOldBinding = pStation->Gen.pLlcBinding;
            if (pStation->Link.pSap->Gen.pNext != NULL) {
                pStation->Gen.pLlcBinding = pStation->Link.pSap->Gen.pNext->Gen.pLlcBinding;
            }

            RELEASE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

            //
            // Complete the close command immediately, if
            // the connect request was redirected to another
            // SAP station
            //

            if (pStation->Gen.pLlcBinding != pOldBinding) {

                ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);

                pEvent = ALLOCATE_PACKET_LLC_PKT(pAdapterContext->hPacketPool);

                if (pEvent != NULL) {
                    LlcInsertTailList(&pAdapterContext->QueueEvents, pEvent);
                    pEvent->pBinding = pStation->Gen.pLlcBinding;
                    pEvent->hClientHandle = pStation->Link.pSap->Gen.hClientHandle;
                    pEvent->Event = LLC_STATUS_CHANGE_ON_SAP;
                    pEvent->pEventInformation = &pStation->Link.DlcStatus;
                    pEvent->SecondaryInfo = INDICATE_CONNECT_REQUEST;
                }

                RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);

                if (pEvent != NULL) {
                    return STATUS_SUCCESS;
                }
            } else {

                //
                // Nobody accepted this connect request, we must discard it.
                //

                RunInterlockedStateMachineCommand((PDATA_LINK)pStation, SET_ADM);
            }
        }
    }
    ACQUIRE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);
    ACQUIRE_SPIN_LOCK(&pAdapterContext->SendSpinLock);

    DLC_TRACE('C');

    switch (pStation->Gen.ObjectType) {
    case LLC_DIRECT_OBJECT:

        //
        // This Direct must be in the linked list of Directs (having
        // the same source Direct).
        //

        ppLinkListBase = (PVOID*)&pAdapterContext->pDirectStation;

        DLC_TRACE('b');
        break;

    case LLC_DIX_OBJECT:

        //
        // This Direct must be in the linked list of Directs (having
        // the same source Direct).
        //

        ppLinkListBase = (PVOID*)&pAdapterContext->aDixStations[pStation->Dix.ObjectAddress % MAX_DIX_TABLE];
        DLC_TRACE('a');
        break;

    case LLC_SAP_OBJECT:

#if LLC_DBG
        if (pStation->Sap.pActiveLinks != NULL) {
            DbgPrint("Closing SAP before link stations!!!\n");
            DbgBreakPoint();

            //
            // Open the spin locks and return thge error status
            //

            RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
            RELEASE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

            return DLC_STATUS_LINK_STATIONS_OPEN;
        }
#endif

        DLC_TRACE('d');

    case LLC_GROUP_SAP_OBJECT:

        //
        // This SAP must be in the linked list of SAPs (having
        // the same source SAP).
        //

        ppLinkListBase = (PVOID*)&pAdapterContext->apSapBindings[pStation->Sap.SourceSap];

        DEALLOCATE_SPIN_LOCK(&pStation->Sap.FlowControlLock);

        break;

    case LLC_LINK_OBJECT:

        //
        // Only a disconnected link station can be deactivated.
        // If this fails, then we must disconnect the link station,
        // if it is not already disconnected.
        //

        if (RunStateMachineCommand((PDATA_LINK)pStation, DEACTIVATE_LS) != STATUS_SUCCESS
        && pStation->Link.State != DISCONNECTING) {

            //
            // We must disconnect the link station immediately.
            // We don't care if we are at the moment in
            // a checkpoint state, that would delay the disconnection
            // until the other side has acknowledged it.
            // The link station must be killed now!
            //

            SendLlcFrame((PDATA_LINK)pStation, DLC_DISC_TOKEN | 1);
            DisableSendProcess((PDATA_LINK)pStation);
        }
        pStation->Link.State = LINK_CLOSED;
        ppLinkListBase = (PVOID *)&pStation->Link.pSap->pActiveLinks;
        ppLink =  SearchLinkAddress(pAdapterContext, pStation->Link.LinkAddr);
        *ppLink = pStation->Link.pNextNode;

        TerminateTimer(pAdapterContext, &pStation->Link.T1);
        TerminateTimer(pAdapterContext, &pStation->Link.T2);
        TerminateTimer(pAdapterContext, &pStation->Link.Ti);
        DLC_TRACE('c');
        break;

#if LLC_DBG
    default:
        LlcInvalidObjectType();
        break;
#endif
    }
    RemoveFromLinkList(ppLinkListBase, pStation);

    //
    // Queue the asynchronous close command. Group sap and
    // disabling of non-existing link station may use
    // a null packet, because those commands are executed
    // synchronously (they cannot have pending packets)
    //

    if (pCompletionPacket != NULL) {
        AllocateCompletionPacket(pStation, LLC_CLOSE_COMPLETION, pCompletionPacket);
    }

    //
    // OK. Everything has been processed =>
    // now we can decrement the object counter.
    //

    RELEASE_SPIN_LOCK(&pAdapterContext->SendSpinLock);
    RELEASE_SPIN_LOCK(&pAdapterContext->ObjectDataBase);

    //
    // Delete the object NOW, if this was the last reference to it
    //

    LlcDereferenceObject(pStation);

    return STATUS_PENDING;
}
Example #3
0
DLC_STATUS
InitializeTimer(
    IN PADAPTER_CONTEXT pAdapterContext,
    IN OUT PLLC_TIMER pTimer,
    IN UCHAR TickCount,
    IN UCHAR TickOne,
    IN UCHAR TickTwo,
    IN UINT Input,
    IN PVOID hContextHandle,
    IN UINT ResponseDelay,
    IN BOOLEAN StartNewTimer
    )

/*++

Routine Description:

    This routine initializes a timer tick objects of a link station.

Arguments:

    pTimer          - timer tick object of a link station
    TickCount       - DLC ticks, see DLC documentation (or code)
    TickOne         - see DLC documentation
    TickTwo         - see DLC documentation
    Input           - the used state machine input, when the timer expires
    hContextHandle  - context handle when the state machine is called
    StartNewTimer   - set if the timer must be started when it is initialized
                      for the first time. Subsequent times, the timer keeps its
                      old state
    ResponseDelay   - an optional base value that is added to the timer value

Return Value:

    DLC_STATUS
        Success - STATUS_SUCCESS
        Failure - DLC_STATUS_NO_MEMORY
                    out of system memory

--*/

{
    UINT DeltaTime;
    PTIMER_TICK pTick;

    ASSUME_IRQL(DISPATCH_LEVEL);

    //
    // All times are multiples of 40 milliseconds
    // (I am not sure how portable is this design)
    // See LAN Manager Network Device Driver Guide
    // ('Remoteboot protocol') for further details
    // about TickOne and TickTwo
    // We have already checked, that the
    // timer tick count is less than 11.
    //

    DeltaTime = (TickCount > 5 ? (UINT)(TickCount - 5) * (UINT)TickTwo
                               : (UINT)TickCount * (UINT)TickOne);

    //
    // We discard the low bits in the reponse delay.
    //

    DeltaTime += (ResponseDelay & 0xfff0);

    //
    // Return immediately, if the old value is the
    // same as the new one (T2 link station is reinitialized
    // unnecessary, when the T1 and Ti timers are retuned
    // for changed response time.
    //

    if (pTimer->pTimerTick && (pTimer->pTimerTick->DeltaTime == DeltaTime)) {
        return STATUS_SUCCESS;
    }

    //
    // Try to find a timer tick object having the same delta time and input
    //

    for (pTick = pAdapterContext->pTimerTicks; pTick; pTick = pTick->pNext) {
        if ((pTick->DeltaTime == DeltaTime) && (pTick->Input == (USHORT)Input)) {
            break;
        }
    }
    if (!pTick) {
        pTick = ALLOCATE_ZEROMEMORY_ADAPTER(sizeof(TIMER_TICK));
        if (!pTick) {
            return DLC_STATUS_NO_MEMORY;
        }
        pTick->DeltaTime = DeltaTime;
        pTick->Input = (USHORT)Input;
        pTick->pNext = pAdapterContext->pTimerTicks;
        pAdapterContext->pTimerTicks = pTick;
    }
    pTick->ReferenceCount++;

    //
    // We must delete the previous timer reference
    // when we know if the memory allocation operation
    // was successfull or not. Otherwise the setting of
    // the link parameters might delete old timer tick,
    // but it would not be able to allocate the new one.
    // The link must be protected, when this routine is called.
    //

    if (pTimer->pTimerTick) {
        StartNewTimer = TerminateTimer(pAdapterContext, pTimer);
    }
    pTimer->pTimerTick = pTick;
    pTimer->hContext = hContextHandle;

    if (StartNewTimer) {
        StartTimer(pTimer);
    }
    return STATUS_SUCCESS;
}