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