Пример #1
0
INT
WINAPI
NSQUERY::LookupServiceNext(
    IN     DWORD           dwControlFlags,
    IN OUT LPDWORD         lpdwBufferLength,
    IN OUT LPWSAQUERYSETW  lpqsResults
    )
/*++

Routine Description:

    //***TODO Fill in description from the spec when it stabilizes.

Arguments:


Return Value:

--*/
{
    INT ReturnCode = SOCKET_ERROR;
    PNSPROVIDERSTATE NewProvider = NULL;
    PNSPROVIDERSTATE ThisProvider = NULL;

again:
    if (!m_shutting_down){
        //Snapshot the value of m_current_provider and bump up the calls in
        //progress counter
        EnterCriticalSection(&m_members_guard);
        InterlockedIncrement(&m_calls_in_progress);
        NewProvider = m_current_provider;
        LeaveCriticalSection(&m_members_guard);

        if ( !NewProvider )
            SetLastError( WSA_E_NO_MORE );

        while (NewProvider){
            ReturnCode = NewProvider->LookupServiceNext(
                dwControlFlags,
                lpdwBufferLength,
                lpqsResults);
            if ((ERROR_SUCCESS == ReturnCode)
                        ||
                (WSAEFAULT == GetLastError()) )
            {
                break;
            } //if

            EnterCriticalSection(&m_members_guard);
            ThisProvider = NewProvider;
            NewProvider = NextProvider(m_current_provider);
            if (ThisProvider == m_current_provider){
               m_current_provider = NewProvider ;
            } //if
            LeaveCriticalSection(&m_members_guard);
        } //while
        InterlockedDecrement(&m_calls_in_progress);

#ifdef RASAUTODIAL
        if (NewProvider == NULL &&
            m_restartable &&
            ReturnCode == SOCKET_ERROR)
        {
            PLIST_ENTRY ListEntry;
            DWORD errval;

            //
            // Save the error in case the Autodial
            // attempt fails.
            //
            errval = GetLastError();
            //
            // We only invoke Autodial once per query.
            //
            m_restartable = FALSE;
            if (WSAttemptAutodialName(m_query_set)) {
                //
                // Because the providers have cached state
                // about this query, we need to call
                // LookupServiceEnd/LookupServiceBegin
                // to reset them.
                //
                while (!IsListEmpty(&m_provider_list)){
                    ListEntry = RemoveHeadList(&m_provider_list);
                    ThisProvider = CONTAINING_RECORD( ListEntry,
                                                  NSPROVIDERSTATE,
                                                  m_query_linkage);
                    ThisProvider->LookupServiceEnd();
                    delete(ThisProvider);
                } //while
                //
                // Restart the query.
                //
                if (LookupServiceBegin(
                      m_query_set,
                      m_control_flags|LUP_FLUSHCACHE,
                      m_catalog) == ERROR_SUCCESS)
                {
                    goto again;
                }
            }
            else
                SetLastError(errval);
        }
#endif // RASAUTODIAL
    } //if
    else{
        ReturnCode = SOCKET_ERROR;
        SetLastError(WSAECANCELLED);
    } //else
    return(ReturnCode);
}
Пример #2
0
DWORD
WSAAPI
WsNqLookupServiceNext(IN PNSQUERY NsQuery,
                      IN DWORD ControlFlags,
                      OUT PDWORD BufferLength,
                      OUT LPWSAQUERYSETW Results)
{
    PNSQUERY_PROVIDER Provider, NextProvider;
    INT ErrorCode = SOCKET_ERROR, OldErrorCode;
    PLIST_ENTRY Entry;

    /* Make sure we're not shutting down */
    if (!NsQuery->ShuttingDown)
    {
        /* Acquire query lock */
        WsNqLock();

        /* Check if we already have an active provider */
        NextProvider = NsQuery->ActiveProvider;
        if (!NextProvider)
        {
            /* Make sure we have a current provider */
            if (!NsQuery->CurrentProvider)
            {
                /* We don't; fail */
                WsNqUnlock();
                SetLastError(WSA_E_NO_MORE);
                return SOCKET_ERROR;
            }

            /* Get the first provider on the list and start looping */
            Entry = NsQuery->ProviderList.Blink;
            NextProvider = CONTAINING_RECORD(Entry, NSQUERY_PROVIDER, QueryLink);
            while (NextProvider)
            {
                /* Check if this is a new-style provider */
                if (NextProvider->Provider->Service.NSPIoctl)
                {
                    /* Remove it and re-add it on top */
                    RemoveEntryList(&NextProvider->QueryLink);
                    InsertHeadList(&NsQuery->ProviderList, &NextProvider->QueryLink);

                    /* Set it as the active provider and exit the loop */
                    NsQuery->ActiveProvider = NextProvider;
                    break;
                }

                /* Get the previous provider */
                NextProvider = WsNqPreviousProvider(NsQuery, NextProvider);
            }
        }

        /* Release the lock */
        WsNqUnlock();

        /* Check if we have an active provider now */
        if (NextProvider)
        {
            /* Start loop */
            do
            {
                /* Call its routine */
                ErrorCode = WsNqProvLookupServiceNext(NextProvider,
                                                      ControlFlags,
                                                      BufferLength,
                                                      Results);
                /* Check for error or shutdown */
                if ((ErrorCode == ERROR_SUCCESS) ||
                    (GetLastError() == WSAEFAULT) || (NsQuery->ShuttingDown))
                {
                    /* Get out */
                    break;
                }

                /* Acquire Query Lock */
                WsNqLock();

                /* Save the current active provider */
                Provider = NsQuery->ActiveProvider;
                
                /* Check if one exists */
                if (Provider)
                {
                    /* Get the next one */
                    NextProvider = WsNqNextProvider(NsQuery,
                                                    NsQuery->ActiveProvider);

                    /* Was the old provider our active? */
                    if (Provider == NsQuery->ActiveProvider)
                    {
                        /* Change our active provider to the new one */
                        NsQuery->ActiveProvider = NextProvider;
                    }
                }
                else
                {
                    /* No next provider */
                    NextProvider = NULL;
                }

                /* Check if we failed and if we can try again */
                if (!(NextProvider) &&
                    (ErrorCode == SOCKET_ERROR) &&
                    (NsQuery->TryAgain))
                {
                    /* Save the error code so RAS doesn't overwrite it */
                    OldErrorCode = GetLastError();

                    /* Make sure we won't try for a 3rd time */
                    NsQuery->TryAgain = FALSE;

                    /* Call the helper to auto-dial */
                    if (WSAttemptAutodialName(NsQuery->QuerySet))
                    {
                        /* It suceeded, so we'll delete the current state. */
                        while (!IsListEmpty(&NsQuery->ProviderList))
                        {
                            /* Remove the entry and get its provider */
                            Entry = RemoveHeadList(&NsQuery->ProviderList);
                            Provider = CONTAINING_RECORD(Entry,
                                                         NSQUERY_PROVIDER,
                                                         QueryLink);

                            /* Reset it */
                            WsNqProvLookupServiceEnd(Provider);
                            WsNqProvDelete(Provider);
                        }                  

                        /* Start a new query */
                        if (!WsNqLookupServiceBegin(NsQuery,
                                                    NsQuery->QuerySet,
                                                    NsQuery->ControlFlags,
                                                    NsQuery->Catalog))
                        {
                            /* New query succeeded, set active provider now */
                            NsQuery->ActiveProvider = 
                                WsNqNextProvider(NsQuery,
                                                 NsQuery->ActiveProvider);
                        }
                    }
                    else
                    {
                        /* Reset the error code */
                        SetLastError(OldErrorCode);
                    }
                }

                /* Release lock */
                WsNqUnlock();

                /* Keep looping as long as there is a provider */
            } while (NextProvider);   
        }
    }
    else
    {
        /* We are shuting down; fail */
        SetLastError(WSAECANCELLED);
    }

    /* Return */
    return ErrorCode;
}