⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mynspsvc.cpp

📁 《Windows网络编程技术》附书源码源码. 运行环境:9x/Me/NT/2000/XP/ 源码语言:简体中文 第十四章
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Module: mynspsvc.cpp
//
// Description:
//    This is the implementation of our namespace service. This
//    is what persists the data registered by applications. This
//    is implemented as a simple Winsock application which listens
//    for connections on a specific port (5150). Our namespace DLL
//    connects to this service and sends commands indicating to
//    register and lookup services as well as register and remove 
//    service classes, etc. This service maintains a list of all
//    registered service classes and services as well as queries
//    intiated by clients.
//
//    This service is implemented using the TCP protocol for the
//    sake of simplicity. A real name space would most likely use
//    UDP for the sake of speed. Of course, this would require
//    more logic to ensure that operations are successfully sent
//    and received by both this service and the namespace DLL.
//
// Compile:
//    cl mynspsvc.cpp nspsvc.cpp printobj.cpp ws2_32.lib
//
// Command Line Arguments/Parameters
//    None
//
#define UNICODE
#define _UNICODE

#include <winsock2.h>
#include <windows.h>

#include "nspsvc.h"
#include "printobj.h"


#include "mynsp.h"

#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SZ        4096

#define MAX_SERVICE_CLASSES        25
#define MAX_SERVICES               50

#define MAX_SERVICE_NAME_SZ        128

#define MAX_QUERIES                50

// These two globals contain all service classes registered
// by the namespace DLL
//
WSASERVICECLASSINFO *ServiceClasses[MAX_SERVICE_CLASSES];
DWORD                dwNumServiceClasses = 0;

// These two globals contain all services registered by the
// namespace DLL
//
WSAQUERYSET         *Services[MAX_SERVICES];
DWORD                dwNumServices = 0;

// This structure maintains each client query as well as the
// current state of the query
//
typedef struct _QUERYINFO
{
    HANDLE           hHandle;  // query handle
    int              iIndex;   // last position in Services which
                               //  we found a service instance
    WSAQUERYSET     *Query;    // query parameters
} QUERYINFO;

// These two globals maintain those queries currently registered
//
QUERYINFO            QueryInfo[MAX_QUERIES];
DWORD                dwNumQueries = 0;
DWORD                dwHandleValue = 0;  // Next handle to return

//
// Function: DeregisterServiceClass
//
// Description:
//    This routine removes the given service class. The GUID 
//    corresponding to the service class is the only parameter.
//
int DeregisterServiceClass(GUID *guid)
{
    DWORD   i, j;

    for(i=0; i < dwNumServiceClasses ;i++)
    {
        // Try to find a match
        //
        if (!memcmp(guid, &ServiceClasses[i]->lpServiceClassId, sizeof(GUID)))
        {
            for(j=0; j < dwNumServices ;j++)
            {
                // If an installed services references this service class
                //  we can't delete it.
                //
                if (!memcpy(guid, &Services[j]->lpServiceClassId, sizeof(GUID)))
                    return MYNSP_ERROR;
                
            }
            // Free the memory
            //
            GlobalFree(ServiceClasses[i]);

            for(j=i; j < dwNumServiceClasses-1 ;j++)
            {
                ServiceClasses[j] = ServiceClasses[j+1];
            }
            dwNumServiceClasses--;
        
            return MYNSP_SUCCESS;
        }
    }
    return MYNSP_ERROR;
}

//
// Function: LookupServiceClass
//
// Description:
//    This function simply searches through the registered service
//    classes for a specific instance. If found that service class
//    structure is returned.
//
WSASERVICECLASSINFO *LookupServiceClass(GUID *guid)
{
    for(DWORD i = 0; i < dwNumServiceClasses; i++)
    {
        if (!memcmp(guid, ServiceClasses[i]->lpServiceClassId, sizeof(GUID)))
        {
            return ServiceClasses[i];
        }
    }
    return NULL;
}

// 
// Function: LookupService
//
// Description:
//    This function looks up a service. First it makes sure
//    that the service class specified in the query does exist.
//    If it does then search through all registered service
//    instances for a service of the given name. If so that
//    service is returned.
//
WSAQUERYSET *LookupService(GUID *guid, WCHAR *service)
{
    WSASERVICECLASSINFO        *si=NULL;

    // Make sure the service class exists
    //
    si = LookupServiceClass(guid);
    if (!si)
        return NULL;
    //
    // Search through the registered services
    //
    for(DWORD i=0; i < dwNumServices ;i++)
    {
        if (!lstrcmpW(service, Services[i]->lpszServiceInstanceName))
        {
            return Services[i];
        }
    }
    return NULL;
}

// 
// Function: DeregisterService
//
// Description:
//    This function removes an instance of a service of the given
//    service name. First a search is performed to find the service.
//    If found, the last service in the array is copied into the
//    just removed service's location.
//
int DeregisterService(GUID *guid, TCHAR *service)
{
    WSASERVICECLASSINFO    *si=NULL;

    // Make sure the given service class exists
    //
    si = LookupServiceClass(guid);
    if (!si)
    {
        return MYNSP_ERROR;
    }

    for(DWORD i=0; i < dwNumServices ;i++)
    {
        // Try to find a match
        //
        if (!lstrcmp(service, Services[i]->lpszServiceInstanceName))
        {
            // Free the memory 
            //
            GlobalFree(Services[i]);
            Services[i] = NULL;

            Services[i] = Services[dwNumServices-1];
            dwNumServices--;

            return MYNSP_SUCCESS;
        }
    }
    return MYNSP_ERROR;
}

//
// Function: RegisterQuery
//
// Description:
//    This function registers a user query and returns a unique
//    handle to identify the query.
//
BOOL RegisterQuery(WSAQUERYSET *qs, HANDLE *handle)
{
    if (dwNumQueries >= MAX_QUERIES)
        return FALSE;
    //
    // Assign the next handle value to this query. Set the iIndex
    //  to -1 to indicate no query has actually been performed
    //  yet.
    //
    QueryInfo[dwNumQueries].hHandle = (HANDLE)++dwHandleValue;
    QueryInfo[dwNumQueries].iIndex  = -1;
    QueryInfo[dwNumQueries].Query   = qs;
    dwNumQueries++;

    *handle = (HANDLE)dwHandleValue;

    return TRUE;
}

//
// Function: FindQuery
//
// Description:
//    This function find a query based on the query handle. If
//    found, the index of the QueryInfo array which contains the
//    match is returned.
//
int FindQuery(HANDLE hQuery)
{
    for(DWORD i=0; i < dwNumQueries ;i++)
    {
        if (QueryInfo[i].hHandle == hQuery)
            return i;
    }
    return -1;
}

// Function: PerformQuery
//
// Description:
//    This funcion performs the query for the given query handle.
//    First the actual query is retrieved based on its handle.
//    Next we iterate through all registered services looking
//    for those that match the search criteria.
//    NOTE! For simplicity our service only attempts to match 
//    service names (either an exact match or through the wildcard
//    asterisk). To make a full fledged namespace provider you need 
//    to match all the criteria supplied in the query!
//
int PerformQuery(HANDLE hQuery, int *iError)
{
    BOOL       bFound;
    int        index;

    // Lookup the query parameters
    //
    *iError = 0;
    index = FindQuery(hQuery);
    //
    // Search for an instance of the service starting where
    //  we left off (i.e. the iIndex value of the QueryInfo
    //  structure).
    // 
    bFound = FALSE;
    for(DWORD i=QueryInfo[index].iIndex+1; i < dwNumServices ;i++)
    {
        // If the query is a wildcard we automatically match names
        //
        if (QueryInfo[index].Query->lpszServiceInstanceName[0] == '*')
        {
            bFound = TRUE;
        }
        else
        {
            if (!lstrcmpW(QueryInfo[index].Query->lpszServiceInstanceName,
                Services[i]->lpszServiceInstanceName))
            {
                bFound = TRUE;
            }
        }
        // If we found a match update the index value
        //
        if (bFound)
        {
            QueryInfo[index].iIndex = i;
            return i;
        }
    }
    if (QueryInfo[index].iIndex == -1)
        *iError = WSASERVICE_NOT_FOUND;
    else
        *iError = WSA_E_NO_MORE;

    return -1;
}

// 
// Function: DeleteQuery
//
// Description:
//    This function removes a query associated with a query handle.
//    We first make sure the query is valid and we then move the
//    last query in the array into the position of the deleted
//    query.
// 
int DeleteQuery(HANDLE hQuery)
{
    int     index;

    // Make sure the query handle is valid
    //
    index = FindQuery(hQuery);
    if (index == -1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -