📄 loadprotocol.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 + -