Platform SDK: Active Directory, ADSI, and Directory Services

Example Code for a Winsock Client Locating a Service Using an RnR Query

The following program locates the example Winsock service and connects to it.

/*
** Simple Winsock Client
*/
#include <winsock2.h>
#include <stdio.h>
 
#define BUFSIZE 3000
 
/ {A9033BC1-ECA4-11cf-A054-00AA006C33ED}
static GUID SVCID_EXAMPLE_SERVICE = 
{ 0xa9033bc1, 0xeca4, 0x11cf, { 0xa0, 0x54, 0x0, 0xaa, 0x0, 0x6c, 0x33, 0xed } };
 
static WCHAR    ServiceInstanceName[] = L"Example Service Instance";
static WCHAR    wszClientMessage[] = L"The directory service.";
 
HRESULT
main(void)
{
 
    //Data structures for initializing Winsock
 
    WSADATA wsData;
    WORD    wVer = MAKEWORD(2,2);
 
 
    //Data structures for searching
 
    HANDLE                 hQ;
    WSAQUERYSET            QuerySet;
    PWSAQUERYSET           ResultSet;
    DWORD                  dwResultSize;
    WCHAR                  wBuffer[BUFSIZE];
 
 
    //Data structures for setting up communications
 
    SOCKET        s;
 
 
    //Miscellaneous variables
 
    INT status;
    DWORD iAddr;
    BOOL bConnected = FALSE;
 
    //Clear out the data structures
 
    ResultSet = (PWSAQUERYSET)wBuffer;
    memset(&QuerySet,0,sizeof(QuerySet));
    memset(ResultSet,0,sizeof(*ResultSet));
    
 
    //Begin: Init Winsock2
 
 
    status = WSAStartup(wVer,&wsData);
    if (status != NO_ERROR)
        return -1;
 
    //Create the socket
 
    s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (s == INVALID_SOCKET) 
    {
        printf("Failed to create socket: %d\n",WSAGetLastError());
        WSACleanup();
        return -1;
    }
 
    //Set up the search
 
    QuerySet.dwSize = sizeof(QuerySet);
    QuerySet.lpServiceClassId = &SVCID_EXAMPLE_SERVICE;
    QuerySet.dwNameSpace = NS_NTDS;
    QuerySet.lpszServiceInstanceName = ServiceInstanceName;
 
 
    printf("Client: querying the directory service for service instance...\n");
 
    //Look up the service to use
 
    status = WSALookupServiceBegin(&QuerySet,
                                    LUP_RETURN_NAME |
                                    LUP_RETURN_ADDR |
                                    LUP_RETURN_TYPE,
                                    &hQ);
    if (status != NO_ERROR) 
        {
        if (status == WSASERVICE_NOT_FOUND) 
            {
            printf("The service was not found.\n");
            } 
        else 
            {
            printf("Query failed with error %d\n",WSAGetLastError());
            }
        WSACleanup();
        return -1;
        }
 
    //Call LookupNext to collect an instance to use. Note that this
    //can be called in a loop until WSA_E_NO_MORE is returned to get 
    //all the instances returned by the query. Try each instance
    //until one works.
 
 
    printf("Client: search successful. Trying to connect...\n");
    dwResultSize = BUFSIZE;
    while (WSALookupServiceNext(hQ,
                                0,
                                &dwResultSize,
                                ResultSet) == NO_ERROR)
    {
    for (iAddr=0;iAddr<ResultSet->dwNumberOfCsAddrs;iAddr++) 
        {
        if (connect(s,
            ResultSet->lpcsaBuffer[iAddr].RemoteAddr.lpSockaddr,
            sizeof(SOCKADDR)) == NO_ERROR) 
            {
            bConnected = TRUE;
            break;
            } 
         else 
            {
            printf("Connection failed %d. Error was %d\n",iAddr,WSAGetLastError());
            }
        }
        if (bConnected)
            break;
    }
 
    //Close out the search service found and connected to
 
    status = WSALookupServiceEnd(hQ);
 
 
    printf("Client: connected!\n");
 
    //Send the service a message
 
    printf("Client: Sending message to service...\n");
    status = send(s,(char *)wszClientMessage,sizeof(wszClientMessage),0);
 
    //Clean up
 
    WSACleanup();
    printf("Client: Finis!\n");
    return 0;
 
}