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

📄 mynsp.cpp

📁 这个是网络编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Module: mynsp.cpp
//
// Description:
//    This file contains the implemenation of an installable name
//    space provider. A name space provider is a DLL which provides
//    entry points for the Winsock 2 RNR functions. This DLL only 
//    provides a starting point for our namespace. We need some 
//    method to persist the information registered by the user.
//    We do this by running a simple Winsock app on the local
//    machine which waits for connections from this DLL. Each
//    routine defined here will connect to this service, send
//    an action command defined what we are to do, and send
//    some parameters. The namespace service will maintain each
//    registered service as well as service classes and queries.
//
//    This file contains only the DLL routines. It does not 
//    provide the mechanism for intalling the namespace on
//    the local computer. See nspinstall.c for namespace
//    installation.
//
// Compile:
//
// Command Line Arguments/Parameters
//    None.
//
#include <winsock2.h>
#include <ws2spi.h>
#include <windows.h>

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

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

//
// Function: MyNspConnect
//
// Description:
//    This is a helper function which simply establishes a conneection
//    to the our local MyNsp service in order to perform the desired
//    RNR operation. If successful, a SOCKET handle is returned; 
//    otherwise, SOCKET_ERROR is returned.
//
SOCKET WSPAPI MyNspConnect()
{
    SOCKET        s;
    SOCKADDR_IN   service;
    int           ret;

    // Create a TCP socket, a production quality RNR service would
    // most likely use a faster, less expensive protocol such as
    // UDP.
    //
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)
    {
        printf("MyNspConnect: socket() failed: %d\n",
            WSAGetLastError());
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }
    // Setup the address to connect to
    //
    service.sin_family = AF_INET;
    service.sin_port   = htons(5150);
    service.sin_addr.s_addr = inet_addr("127.0.0.1");

    ret = connect(s, (SOCKADDR *)&service, sizeof(service));
    if (ret == SOCKET_ERROR)
    {
        printf("MyNspConnect: connect() failed: %d\n", 
            WSAGetLastError());
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }
    return s;
}

//
// Function: DllMain
//
// Description:
//    This function is the main entry point for our DLL. If we needed
//    to maintain any per DLL data, we would allocate it here.
//
BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            break;
    	case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    	case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

//
// Function: NSPLookupServiceBegin
//
// Description:
//    This function maps to the Winsock call WSALookupServiceBegin.
//    Within this call we connect to our namespace service and 
//    transmit the query parameters (lpqsRestrictions) and a unique
//    handle for this query is returned. Subsequent calls only need
//    to refer to this query by the handle as opposed to specifying
//    the query parameters each time.
//
int WSPAPI NSPLookupServiceBegin(
    LPGUID lpProviderId,
    LPWSAQUERYSETW lpqsRestrictions,
    LPWSASERVICECLASSINFOW lpServiceClassInfo,
    DWORD dwControlFlags,   
    LPHANDLE lphLookup)
{
    SOCKET      s;
    int         ret,
                retcode,
                nLeft,
                bytesread,
                byteswritten;
    BYTE        action;
    char        databuf[MARSHALL_BUFFER_SZ];

    // Set the action and connect to the service
    //
    action = MYNSP_LOOKUP_SERVICE_BEGIN;
    s = MyNspConnect();
    if (s == SOCKET_ERROR)
        return SOCKET_ERROR;

    writedata(s, (char *)&action, sizeof(action), &byteswritten);
    //
    // Marshal the query parameters into a contiguous buffer
    //
    ret = MarshallServiceInfo(lpqsRestrictions, databuf, &nLeft);
    //
    // Write the query parameters and read the return code (handle)
    //
    writedata(s, (char *)&nLeft, sizeof(nLeft), &byteswritten);
    writedata(s, databuf, nLeft, &byteswritten);
	
    bytesread = sizeof(retcode);
    readdata(s, (char *)&retcode, sizeof(retcode), &bytesread);
   
    if (retcode == MYNSP_ERROR)
    {
        closesocket(s);
        WSASetLastError(WSAEINVAL);
        return SOCKET_ERROR;
    }
    *lphLookup = (HANDLE)retcode;
    closesocket(s);

    return NO_ERROR;
}

//
// Function: NSPLookupServiceNext
//
// Description:
//    This function maps to the Winsock call WSALookupServiceNext.
//    This routine takes a handle to a previously defined query and
//    attempts to locate a service matching the criteria defined by
//    the query. If so, that instance is returned in the lpqsResults
//    parameter. This function accomplishes this by connecting to 
//    our service and writing the query handle. The service maintains
//    a state for the handle and begins searching for matching 
//    services. If found, the WSAQUERYSET defining the service is
//    marshalled and written back at which point it is demarshalled
//    into the lpqsResults buffer.
//
int WSPAPI NSPLookupServiceNext(  
    HANDLE hLookup,
    DWORD dwControlFlags,
    LPDWORD lpdwBufferLength,
    LPWSAQUERYSETW lpqsResults)
{

    SOCKET      s;
    int         bytesread,
                byteswritten,
                bytes2follow;
    BYTE        action;
    char        buf[MARSHALL_BUFFER_SZ];

    // Set the action and connect to the service
    //
    action = MYNSP_LOOKUP_SERVICE_NEXT;
    s = MyNspConnect();
    if (s == SOCKET_ERROR)
        return SOCKET_ERROR;

    writedata(s, (char *)&action, sizeof(action), &byteswritten);
    //
    // Write the handle so the service knows which query we are
    //  executing
    //
    writedata(s, (char *)&hLookup, sizeof(hLookup), &byteswritten);
    //
    // Read the number of bytes to follow. If this value is 0 or
    //  -1 then it means an error occured
    // 
    bytesread = sizeof(bytes2follow);
    readdata(s, (char *)&bytes2follow, sizeof(bytes2follow), &bytesread);
    
    if (bytes2follow == -1)         // Service not found
    {
        closesocket(s);
        WSASetLastError(WSASERVICE_NOT_FOUND);
        return SOCKET_ERROR;
    }
    if (bytes2follow == 0)          // No more data
    {
        closesocket(s);
        WSASetLastError(WSA_E_NO_MORE);
        return SOCKET_ERROR;
    }
    // Make sure the user supplied buffer is large enough
    //
    if ((DWORD)bytes2follow > *lpdwBufferLength)
    {		
        *lpdwBufferLength = bytes2follow;
        closesocket(s);
        WSASetLastError(WSAEFAULT);
        return SOCKET_ERROR;
    }
    readdata(s, buf, MARSHALL_BUFFER_SZ, &bytes2follow);

    DeMarshallServiceInfo(lpqsResults, buf);

    *lpdwBufferLength = bytesread;

    closesocket(s);

    return NO_ERROR;
}

//
// Function: NSPLookupServiceEnd
//
// Description:
//    This function maps to the Winsock call WSALookupServiceEnd.
//    Once the user process has finished is query (usually indicated
//    when WSALookupServiceNext returns the error WSA_E_NO_MORE) a
//    call to this function is made to release any allocated
//    resources associated with the query. In our case, we connect
//    to our service and write the query handle. The service will
//    remove its copy of the query parameters and return a status
//    code.
//
int WSPAPI NSPLookupServiceEnd(HANDLE hLookup)
{
    SOCKET      s;
    int         retcode,
                bytesread,
                byteswritten;
    BYTE        action;
    
    // Set the action and connect to the service
    //
    action = MYNSP_LOOKUP_SERVICE_NEXT;
    s = MyNspConnect();
    if (s == SOCKET_ERROR)
        return SOCKET_ERROR;

    writedata(s, (char *)&action, sizeof(action), &byteswritten);
    //
    // Write the handle to the query we wish to close
    //
    writedata(s, (char *)&hLookup, sizeof(hLookup), &byteswritten);

    bytesread = sizeof(retcode);
    readdata(s, (char *)&retcode, sizeof(retcode), &bytesread);

    if (retcode == MYNSP_ERROR)        // Invalid handle
    {
        closesocket(s);
        SetLastError(WSA_INVALID_HANDLE);
        return SOCKET_ERROR;
    }
    closesocket(s);
 

⌨️ 快捷键说明

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