注册更改通知

以下示例代码演示如何在路由表中注册更改通知。 主题“使用事件通知回调”演示如何利用这些更改通知。

#include <windows.h>
#include <stdio.h>
#include "Rtmv2.h"
#include "nldef.h"
#include <tchar.h>

// The following #defines are from routprot.h in the Platform Software Development Kit (SDK)
#define PROTO_TYPE_UCAST        0
#define PROTOCOL_ID(Type, VendorId, ProtocolId) (((Type & 0x03)<<30)|((VendorId & 0x3FFF)<<16)|(ProtocolId & 0xFFFF))
#define PROTO_VENDOR_ID        0xFFFF

// This is a simple callback method used by the new client registering for change notifications
void WINAPI Method(RTM_ENTITY_HANDLE CallerHandle, RTM_ENTITY_HANDLE CalleeHandle, RTM_ENTITY_METHOD_INPUT *Input, RTM_ENTITY_METHOD_OUTPUT *Output){
   
    UNREFERENCED_PARAMETER(CallerHandle);
    UNREFERENCED_PARAMETER(CalleeHandle);
    UNREFERENCED_PARAMETER(Input);
    UNREFERENCED_PARAMETER(Output);
 
    wprintf(L"Hello World!");
    return;
}

int __cdecl main(){

    RTM_ENTITY_HANDLE ThisClientHandle, OtherClientHandle;
    RTM_ENTITY_INFO EntityInfo;
    RTM_REGN_PROFILE RegnProfile;
    UINT NumMethods = 0;
    DWORD dwRet = ERROR_SUCCESS;
    RTM_ENTITY_EXPORT_METHODS Methods;
    PRTM_NOTIFY_HANDLE NotifyHandle = NULL;

    //------------------------------------------------------
    // Register a new client with an export method (callback)
    //------------------------------------------------------
    
    // Set the callback Method() as the exported client function
    Methods.NumMethods = 1;
    Methods.Methods[0] = (RTM_ENTITY_EXPORT_METHOD) Method;
    
    // Set the new client's properties
    EntityInfo.RtmInstanceId = 0;
    EntityInfo.AddressFamily = AF_INET;
    EntityInfo.EntityId.EntityProtocolId = PROTO_IP_RIP;
    EntityInfo.EntityId.EntityInstanceId = PROTOCOL_ID(PROTO_TYPE_UCAST, PROTO_VENDOR_ID, PROTO_IP_RIP);

    // Register the new client in the routing table manager
    dwRet = RtmRegisterEntity(&EntityInfo, &Methods, NULL, FALSE, &RegnProfile, &ThisClientHandle);
    if (dwRet != ERROR_SUCCESS){
        // RtmRegisterEntity failed
        // Do something here
        // clean-up
        return 0;
    }
    
    //------------------------------------------------------
    //  Register the new client for change notifications
    //------------------------------------------------------

    // Register for change notifications to the best routes to all destinations in the unicast view of the routing table.
    // For simplicity in this example, set the caller client handle to be the same as the callee client handle
    OtherClientHandle = ThisClientHandle;
    NotifyHandle = (PRTM_NOTIFY_HANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RTM_NOTIFY_HANDLE));
    dwRet = RtmRegisterForChangeNotification(ThisClientHandle, RTM_VIEW_MASK_UCAST, RTM_CHANGE_TYPE_BEST, OtherClientHandle, NotifyHandle);
    
    if (dwRet != ERROR_SUCCESS){
        // RtmRegisterForChangeNotification failed
        // Do something here
        // clean-up
        return 0;
    }

    // Clean-up: Deregister the new entity and free heap memory
    dwRet = RtmDeregisterFromChangeNotification(ThisClientHandle, *NotifyHandle);
    dwRet |= RtmDeregisterEntity(ThisClientHandle);
    if (dwRet != ERROR_SUCCESS){
        // Deregistration failed
        // Do something here
    }
    HeapFree(GetProcessHeap(), 0, NotifyHandle);

    return 0;
}