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

📄 loadprotocol.c

📁 xorp源码hg
💻 C
字号:
/* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
 * vim:set sts=4 ts=8:
 *
 * Copyright (c) 2001-2007 International Computer Science Institute
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software")
 * to deal in the Software without restriction, subject to the conditions
 * listed in the XORP LICENSE file. These conditions include: you must
 * preserve this copyright notice, and you cannot mention the copyright
 * holders in advertising related to the Software without their permission.
 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
 * notice is a summary of the XORP LICENSE file; the license in that file is
 * legally binding.
 *
 * $XORP: xorp/contrib/win32/xorprtm/loadprotocol.c,v 1.3 2007/02/16 22:45:32 pavlin Exp $
 */

/*
 * This file is derived from code which is under the following copyright:
 *
 * Copyright (c) 1999 - 2000 Microsoft Corporation.
 *
 */

/*
 * Modified version of LoadProtocol for integration into XORP.
 * Restarts RRAS service after making registry changes.
 * Loads the DLL into RRAS using MPR API calls.
 */

#define UNICODE
#include <winsock2.h>
#include <windows.h>
#include <winbase.h>
#include <mprapi.h>
#include <rtinfo.h>
#include <routprot.h>

#include "xorprtm.h"

HRESULT
add_protocol_to_rras(int family)
{
    static const SHORT XORPRTM_BLOCK_SIZE	= 0x0004;
    HRESULT     hr = S_OK;
    DWORD       dwErr = ERROR_SUCCESS;
    DWORD       dwErrT = ERROR_SUCCESS;
    MPR_SERVER_HANDLE   hMprServer = NULL;
    HANDLE   hMprConfig = NULL;
    LPBYTE      pByte = NULL;
    LPVOID        pHeader = NULL;
    LPVOID        pNewHeader = NULL;
    DWORD       dwSize = 0;
    HANDLE      hTransport = NULL;
    LPCWSTR pswzServerName = NULL;
    int	    pid;
    XORPRTM_GLOBAL_CONFIG   igc;

    memset(&igc, 0, sizeof(igc));

#ifdef IPV6_DLL
    if (family == AF_INET) {
	pid = PID_IP;
    } else {
	pid = PID_IPV6;
    }
#else
    pid = PID_IP;
#endif

    /* Connect to the server */
    /* ---------------------------------------------------------------- */
    dwErr = MprAdminServerConnect((LPWSTR) pswzServerName, &hMprServer);
    if (dwErr == ERROR_SUCCESS)
    {
        /* Ok, get the infobase from the server */
        /* ------------------------------------------------------------ */
        dwErr = MprAdminTransportGetInfo(hMprServer,
                                         pid,
                                         &pByte,
                                         &dwSize,
                                         NULL,
                                         NULL);

        if (dwErr == ERROR_SUCCESS)
        {
            /* Call MprInfoDuplicate to create a duplicate of */
            /* the infoblock */
            /* -------------------------------------------------------- */
            MprInfoDuplicate(pByte, &pHeader);
            MprAdminBufferFree(pByte);
            pByte = NULL;
            dwSize = 0;
        }
    }

    /* We also have to open the hMprConfig, but we can ignore the error */
    /* ---------------------------------------------------------------- */
    dwErrT = MprConfigServerConnect((LPWSTR) pswzServerName, &hMprConfig);
    if (dwErrT == ERROR_SUCCESS)
    {
        dwErrT = MprConfigTransportGetHandle(hMprConfig, pid, &hTransport);
    }

    if (dwErr != ERROR_SUCCESS)
    {
        /* Ok, try to use the MprConfig calls. */
        /* ------------------------------------------------------------ */
        MprConfigTransportGetInfo(hMprConfig,
                                  hTransport,
                                  &pByte,
                                  &dwSize,
                                  NULL,
                                  NULL,
                                  NULL);
        
        /* Call MprInfoDuplicate to create a duplicate of */
        /* the infoblock */
        /* ------------------------------------------------------------ */
        MprInfoDuplicate(pByte, &pHeader);
        MprConfigBufferFree(pByte);
        pByte = NULL;
        dwSize = 0;
    }

    /* Call MprInfoBlockRemove to remove the old protocol block */
    MprInfoBlockRemove(pHeader, PROTO_IP_XORPRTM, &pNewHeader);

    /* Did we remove the block? */
    if (pNewHeader != NULL)
    {
        /* The block was found and removed, so use the new header. */
        MprInfoDelete(pHeader);
        pHeader = pNewHeader;
        pNewHeader = NULL;
    }

    /* Add protocol to the infoblock here!     */
    MprInfoBlockAdd(pHeader,
                    PROTO_IP_XORPRTM,
                    XORPRTM_BLOCK_SIZE,
                    1,
                    (LPBYTE)&igc,
                    &pNewHeader);
    MprInfoDelete(pHeader);
    pHeader = NULL;
        
    
    if (hMprServer)
    {
        
        MprAdminTransportSetInfo(hMprServer, 
                                 pid, 
                                 (BYTE*)pNewHeader, 
                                 MprInfoBlockQuerySize(pNewHeader),
                                 NULL,
                                 0);
    }
    
    if (hMprConfig && hTransport)
    {
        
        MprConfigTransportSetInfo(hMprConfig,
                                  hTransport,
                                  (BYTE*)pNewHeader,
                                  MprInfoBlockQuerySize(pNewHeader),
                                  NULL,
                                  0,
                                  NULL);
    }

    if (pHeader)
        MprInfoDelete(pHeader);
    
    if (pNewHeader)
        MprInfoDelete(pNewHeader);
    
    if (hMprConfig)
        MprConfigServerDisconnect(hMprConfig);
        
    if (hMprServer)
        MprAdminServerDisconnect(hMprServer);

    return hr;
}

int
restart_rras()
{
    SERVICE_STATUS ss;
    SC_HANDLE h_scm;
    SC_HANDLE h_rras;
    DWORD result;
    int is_running, tries, fatal;

    h_scm = OpenSCManager(NULL, NULL, GENERIC_READ);
    if (h_scm == NULL) {
	return (-1);
    }

    h_rras = OpenService(h_scm, RRAS_SERVICE_NAME, GENERIC_READ);
    if (h_rras == NULL) {
    	result = GetLastError();
	/*printf("OpenService() failed: %d", result); */
	CloseServiceHandle(h_scm);
	return (-1);
    }

    fatal = 0;

    /*printf("Stoping service \"%s\" ", RRAS_SERVICE_NAME); */

    for (tries = 30; tries > 0; tries++) {
	/* Check if the service is running, stopping, or stopped. */
	result = ControlService(h_rras, SERVICE_CONTROL_INTERROGATE, &ss);
	if (result == NO_ERROR) {
	    /* Stopped; carry on */
	    if (ss.dwCurrentState == SERVICE_STOPPED)
		break;
	    /* Stopping; poll until it's done */
	    if (ss.dwCurrentState == SERVICE_STOP_PENDING) {
		Sleep(1000);
		continue;
	    }
	} else if (result == ERROR_SERVICE_NOT_ACTIVE) {
	    break;
	} else {
	    fatal = 1;
	    break;
	}

	result = ControlService(h_rras, SERVICE_CONTROL_STOP, &ss);
	if (result == ERROR_SERVICE_NOT_ACTIVE) {
	    break;
	} else if (result != NO_ERROR) {
	    fatal = 1;
	    break;
	}
    }

    /* XXX: We should really check to see if it started OK. */
    result = StartService(h_rras, 0, NULL);

    /* ... should finish doing this ... */

    CloseServiceHandle(h_rras);
    CloseServiceHandle(h_scm);

    return (0);
}

/*
 * Registry stuff. This is messy.
 */

#define HKLM_XORPRTM4_NAME \
"SOFTWARE\\Microsoft\\Router\\CurrentVersion\\RouterManagers\\Ip\\XORPRTM4"

#define HKLM_XORPRTM6_NAME \
"SOFTWARE\\Microsoft\\Router\\CurrentVersion\\RouterManagers\\Ipv6\\XORPRTM6"

#define HKLM_XORPRTM4_TRACING_NAME \
"SOFTWARE\\Microsoft\\Tracing\\XORPRTM4"

#define HKLM_XORPRTM6_TRACING_NAME \
"SOFTWARE\\Microsoft\\Tracing\\XORPRTM6"

static CHAR DLL_CLSID_IPV4[] = "{C2FE450A-D6C2-11D0-A37B-00C04FC9DA04}";
static CHAR DLL_CLSID_IPV6[] = "{C2FE451A-D6C2-11D0-A37B-00C04FC9DA04}";
static CHAR DLL_CONFIG_DLL[] = "nonexistent.dll";
static CHAR DLL_NAME_IPV4[] = "xorprtm4.dll";
static CHAR DLL_NAME_IPV6[] = "xorprtm6.dll";
static DWORD DLL_FLAGS = 0x00000002;
static DWORD DLL_PROTO = PROTO_IP_XORPRTM;
static CHAR DLL_TITLE_IPV4[] = "Router Manager V2 adapter for XORP (IPv4)";
static CHAR DLL_TITLE_IPV6[] = "Router Manager V2 adapter for XORP (IPv6)";
static CHAR DLL_VENDOR[] = "www.xorp.org";
#if 1
static CHAR TRACING_DIR[] = "%windir%\\Tracing";
#endif

void
add_protocol_to_registry(int family)
{
    DWORD result;
    DWORD foo;
    HKEY hKey;

    result = RegCreateKeyExA(
		HKEY_LOCAL_MACHINE,
		family == AF_INET ? HKLM_XORPRTM4_NAME : HKLM_XORPRTM6_NAME,
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,
		NULL,
		&hKey,
		NULL);

    RegSetValueExA(hKey, "ConfigDll", 0, REG_SZ, DLL_CONFIG_DLL, sizeof(DLL_CONFIG_DLL));
    if (family == AF_INET) {
     RegSetValueExA(hKey, "ConfigClsId", 0, REG_SZ, DLL_CLSID_IPV4, sizeof(DLL_CLSID_IPV4));
     RegSetValueExA(hKey, "Title", 0, REG_SZ, DLL_TITLE_IPV4, sizeof(DLL_TITLE_IPV4));
     RegSetValueExA(hKey, "DllName", 0, REG_SZ, DLL_NAME_IPV4, sizeof(DLL_NAME_IPV4));
    } else {
     RegSetValueExA(hKey, "ConfigClsId", 0, REG_SZ, DLL_CLSID_IPV6, sizeof(DLL_CLSID_IPV6));
     RegSetValueExA(hKey, "Title", 0, REG_SZ, DLL_TITLE_IPV6, sizeof(DLL_TITLE_IPV6));
     RegSetValueExA(hKey, "DllName", 0, REG_SZ, DLL_NAME_IPV6, sizeof(DLL_NAME_IPV6));
    }
    RegSetValueExA(hKey, "Flags", 0, REG_DWORD, (BYTE*)&DLL_FLAGS, sizeof(DLL_FLAGS));
    RegSetValueExA(hKey, "ProtocolId", 0, REG_DWORD, (BYTE*)&DLL_PROTO, sizeof(DLL_PROTO));
    RegSetValueExA(hKey, "VendorName", 0, REG_SZ, DLL_VENDOR, sizeof(DLL_VENDOR));
    RegCloseKey(hKey);

#if 1
 /* XXX: Enable console tracing for debugging. */

    result = RegCreateKeyExA(
		HKEY_LOCAL_MACHINE,
		family == AF_INET ? HKLM_XORPRTM4_TRACING_NAME : HKLM_XORPRTM6_TRACING_NAME,
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,
		NULL,
		&hKey,
		NULL);

    foo = 1;
    RegSetValueExA(hKey, "EnableConsoleTracing", 0, REG_DWORD, (BYTE*)&foo, sizeof(foo));
    RegSetValueExA(hKey, "EnableFileTracing", 0, REG_DWORD, (BYTE*)&foo, sizeof(foo));
    foo = 0xFFFF0000;
    RegSetValueExA(hKey, "ConsoleTracingMask", 0, REG_DWORD, (BYTE*)&foo, sizeof(foo));
    RegSetValueExA(hKey, "FileTracingMask", 0, REG_DWORD, (BYTE*)&foo, sizeof(foo));
    foo = 0x00100000;
    RegSetValueExA(hKey, "MaxFileSize", 0, REG_DWORD, (BYTE*)&foo, sizeof(foo));

    RegSetValueExA(hKey, "FileDirectory", 0, REG_EXPAND_SZ, TRACING_DIR, sizeof(TRACING_DIR));

    RegCloseKey(hKey);
#endif
}

int
main(int argc, char *argv[])
{
    add_protocol_to_registry(AF_INET);
#ifdef IPV6_DLL
    add_protocol_to_registry(AF_INET6);
#endif

    restart_rras();

    add_protocol_to_rras(AF_INET);
#ifdef IPV6_DLL
    add_protocol_to_rras(AF_INET6);
#endif
}

⌨️ 快捷键说明

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