/* * @implemented */ INT WINAPI WSALookupServiceBeginW(IN LPWSAQUERYSETW lpqsRestrictions, IN DWORD dwControlFlags, OUT LPHANDLE lphLookup) { PWSPROCESS Process; PWSTHREAD Thread; INT ErrorCode; PNSQUERY Query; DPRINT("WSALookupServiceBeginW: %p\n", lpqsRestrictions); /* Enter prolog */ if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) { /* Leave now */ SetLastError(ErrorCode); return SOCKET_ERROR; } /* Verify pointers */ if (IsBadWritePtr(lphLookup, sizeof(*lphLookup)) || IsBadReadPtr(lpqsRestrictions, sizeof(*lpqsRestrictions))) { /* They are invalid; fail */ SetLastError(WSAEFAULT); return SOCKET_ERROR; } /* Create a new query object */ if ((Query = WsNqAllocate())) { /* Initialize it */ WsNqInitialize(Query); /* Do the lookup */ ErrorCode = WsNqLookupServiceBegin(Query, lpqsRestrictions, dwControlFlags, WsProcGetNsCatalog(Process)); /* Check for success */ if (ErrorCode == ERROR_SUCCESS) { /* Return the handle */ *lphLookup = Query; } else { /* Fail */ *lphLookup = NULL; WsNqDelete(Query); } } else { /* No memory */ ErrorCode = SOCKET_ERROR; SetLastError(WSAENOBUFS); } /* Return */ return ErrorCode; }
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; }