cliphelper.c
来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C语言 代码 · 共 613 行
C
613 行
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CLiphelper.c,v 1.2 2002/08/06 20:09:19 dallen Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"
// project header files
#include "PGPclx.h"
#include "pgpSockets.h"
#include <iphlpapi.h>
// external globals
extern HINSTANCE g_hInst;
extern PGPContextRef g_context;
// The following contants and structures are used for coaxing
// information out of the WsControl entry
#define CONTROLSIZE (0x100/8)
// Constants for use in the command field
#define COMMAND_SPANINFO 0
#define COMMAND_BASEINFO 1
#define COMMAND_INFO2 0x102
// Constants for use in various flags fields
#define PARAMETER 0x301
#define PARAMETER2 0x303
// An array of this is returned by the spaninfo command. They tell
// what type of info is there and are used as an index to get more
// in-depth info.
struct _span {
PGPInt32 magicValue1;
PGPInt32 magicValue2;
};
struct _wsControl {
PGPInt32 magicValue1;
PGPInt32 magicValue2;
PGPInt32 controlFlag1;
PGPInt32 controlFlag2;
PGPInt32 command;
};
// This is the control structure
struct _wsxControl {
struct _wsControl baseCommand;
PGPByte padding[16];
};
// Before retrieving IP info, we retrieve one of these
struct _IPcount /* size 5c */ {
PGPInt32 ofs0;
PGPByte unk[0x50];
PGPUInt32 basicIPCount;
PGPInt32 extendedIPCount;
};
// Once we have retrieved the infostruct we retrieve an array of these
// based on the baseInfoCount filed. This is where we get the IP and
// Subnet
struct _basicIPInfo /* size 0x18 */ {
PGPInt32 ipAddress;
PGPInt32 ident;
PGPInt32 subnetMask;
PGPInt32 unk2[2];
PGPInt32 ofs14;
};
// This is the info structure returned by the DHCP VxD
// DHCP block
typedef struct _DHCPblock {
DWORD addrOff; // Physical address offset
DWORD unknown1;
DWORD unknown2;
DWORD unknown3;
time_t leaseObtained; // Lease obtained, secs from 1980/1/1
time_t leaseExpires; // Lease obtained, secs from 1980/1/1
DWORD ip; // IP address
DWORD dnsLen; // Size of DNS array
DWORD dnsOff; // DNS array offset
DWORD isDomain; // domainOff is valid
DWORD domainOff; // Domain name offset
};
typedef struct _DHCPinfo {
int cnt; // Number of blocks
struct _DHCPblock b[1];
};
// these are the prototypes for the IPHelper calls
typedef DWORD (WINAPI *GetIpAddrTableProc) (
PMIB_IPADDRTABLE pIpAddrTable,
PULONG pdwSize,
BOOL bOrder);
typedef DWORD (WINAPI *GetNetworkParamsProc) (
PFIXED_INFO pfinfo,
PULONG pdwSize);
// the prototype for the WsControl call
typedef DWORD (WINAPI *WsControlProc) (
DWORD cmd1,
DWORD cmd2,
LPVOID inbuf,
LPDWORD szinbuf,
LPVOID outbuf,
LPDWORD szoutbuf);
static GetIpAddrTableProc s_fpGetIpAddrTable = NULL;
static GetNetworkParamsProc s_fpGetNetworkParams = NULL;
static WsControlProc s_fpWsControl = NULL;
// ______________________________________________
//
// load the needed libraries
static void
sInitializeLibraries()
{
static BOOL bIsInitialized = FALSE;
HINSTANCE hLib;
PGPclWindowsGenus genus;
if (bIsInitialized)
return;
bIsInitialized = TRUE;
PGPclGetWindowsVersion (NULL, &genus, NULL);
if (genus == kPGPclWindowsGenus95)
{
// On Win95 we have to use the undocumented call WsControl into
// the Winsock library
if (!(hLib = LoadLibrary ("WSOCK32.DLL")))
return;
s_fpWsControl = (WsControlProc)GetProcAddress (hLib, "WsControl");
}
else
{
// Otherwise we use the IPHELPER library
if (!(hLib = LoadLibrary ("IPHLPAPI.DLL")))
return;
s_fpGetIpAddrTable =
(GetIpAddrTableProc)GetProcAddress (hLib, "GetIpAddrTable");
s_fpGetNetworkParams =
(GetNetworkParamsProc)GetProcAddress (hLib, "GetNetworkParams");
}
}
// ______________________________________________
//
// a subroutine to read the base adapter array
static void*
sGetBaseAdapterInfo (
PGPInt32* piBufCount)
{
PGPUInt32 bufsize, controlsize;
void* pbuffer;
struct _wsxControl commandx;
// Format the command packet
pgpClearMemory (&commandx, sizeof(commandx));
commandx.baseCommand.magicValue1 = 0;
commandx.baseCommand.magicValue2 = 0;
commandx.baseCommand.controlFlag1 = 0x100;
commandx.baseCommand.controlFlag2 = 0x100;
commandx.baseCommand.command = COMMAND_SPANINFO;
controlsize = sizeof(commandx);
// allocate the response packet
bufsize = CONTROLSIZE*8;
pbuffer = PGPNewData (PGPPeekContextMemoryMgr (g_context),
bufsize, kPGPMemoryMgrFlags_Clear);
if (IsNull (pbuffer))
return 0;
// issue the command
if (s_fpWsControl (6, 0, &commandx, &controlsize, pbuffer, &bufsize))
{
PGPFreeData (pbuffer);
return 0;
}
// return the count and buffer
*piBufCount = bufsize / sizeof (struct _span);
return pbuffer;
}
// ______________________________________________
//
// returns a valid IP address and subnet mask for this machine
PGPError PGPclExport
PGPclGetIPandSubnetMask (
PGPUInt32* puIP,
PGPUInt32* puSubnetMask)
{
PGPError err = kPGPError_NoErr;
PGPInt32 i;
PGPInt32 iIPcount;
sInitializeLibraries ();
// use the IPHLP stuff, if available
if (IsntNull (s_fpGetIpAddrTable))
{
MIB_IPADDRTABLE* pIPTable = NULL;
PGPUInt32 iret = NO_ERROR;
PGPUInt32 uIPTableSize = 0;
// Get IP addresses table size
err = kPGPError_Win32_IPHelperLibError;
iret = s_fpGetIpAddrTable (NULL, &uIPTableSize, TRUE);
// Now allocate the table and fill it in
if ((uIPTableSize > 0) &&
(iret == ERROR_INSUFFICIENT_BUFFER))
{
pIPTable = (PMIB_IPADDRTABLE)PGPNewData (
PGPPeekContextMemoryMgr (g_context),
uIPTableSize, kPGPMemoryMgrFlags_Clear);
iret = s_fpGetIpAddrTable (pIPTable, &uIPTableSize, TRUE);
if (iret == NO_ERROR)
err = kPGPError_NoErr;
}
if (IsntPGPError (err))
{
iIPcount = pIPTable->dwNumEntries;
for (i=0; i<iIPcount; i++)
{
if ((pIPTable->table[i].dwAddr != 0) &&
(pIPTable->table[i].dwAddr != 0x0100007F))
{
if (puIP)
*puIP = pIPTable->table[i].dwAddr;
if (puSubnetMask)
*puSubnetMask = pIPTable->table[i].dwMask;
break;
}
}
}
if (pIPTable)
PGPFreeData (pIPTable);
}
// otherwise use the undocumented WsControl entry into the Winsock DLL
else if (IsntNull (s_fpWsControl))
{
struct _span* pBaseAddr = NULL;
struct _span* pBasePtr = NULL;
struct _basicIPInfo* pBaseIPinfo = NULL;
PGPInt32 ibasecount, index;
PGPUInt32 structsize, commandlen, returnedFlags;
struct _wsxControl commandx;
struct _wsControl command;
struct _IPcount ipCount;
// Get the adapter list
if (!(pBaseAddr = (struct _span *)sGetBaseAdapterInfo (&ibasecount)))
return kPGPError_OutOfMemory;
// Now go through the list looking for ip parameter packets
for (index=0, pBasePtr=pBaseAddr; index<ibasecount; index++, pBasePtr++)
{
if (pBasePtr->magicValue1 == PARAMETER)
{
pgpClearMemory (&commandx, sizeof(commandx));
command.magicValue1 = pBasePtr->magicValue1;
command.magicValue2 = pBasePtr->magicValue2;
command.controlFlag1 = 0x100;
command.controlFlag2 = 0x100;
command.command = COMMAND_BASEINFO;
commandlen = sizeof(commandx);
structsize = sizeof(PGPUInt32);
pgpCopyMemory (&command,
&commandx.baseCommand, sizeof(command));
if (s_fpWsControl (6, 0, &commandx,
&commandlen, &returnedFlags, &structsize))
{
err = kPGPError_Win32_WsControlError;
}
// Get the number of IP entries
if (IsntPGPError (err) &&
(returnedFlags == PARAMETER2))
{
command.controlFlag1 = 0x200;
command.command = COMMAND_BASEINFO;
pgpClearMemory (&commandx, sizeof(commandx));
pgpCopyMemory (&command,
&commandx.baseCommand, sizeof(command));
commandlen = sizeof(commandx);
structsize = 0x5c;
if (s_fpWsControl (6, 0, &commandx,
&commandlen, &ipCount, &structsize) ||
(structsize != 0x5c))
{
err = kPGPError_Win32_WsControlError;
}
// Get the IP information
if (IsntPGPError (err) &&
(ipCount.basicIPCount != 0))
{
structsize = ipCount.basicIPCount *
sizeof(struct _basicIPInfo);
pBaseIPinfo = (struct _basicIPInfo*) PGPNewData (
PGPPeekContextMemoryMgr (g_context),
structsize, kPGPMemoryMgrFlags_Clear);
if (!pBaseIPinfo)
err = kPGPError_OutOfMemory;
if (IsntPGPError (err))
{
pgpClearMemory (&commandx, sizeof(commandx));
command.command = COMMAND_INFO2;
pgpCopyMemory (&command,
&commandx.baseCommand, sizeof(command));
commandlen = 0x24;
if (s_fpWsControl (6, 0, &commandx,
&commandlen, pBaseIPinfo, &structsize))
{
err = kPGPError_Win32_WsControlError;
}
}
if (IsntPGPError (err))
{
if (structsize / sizeof(struct _basicIPInfo) >=
ipCount.basicIPCount)
{
iIPcount =
structsize / sizeof(struct _basicIPInfo);
}
else
iIPcount = ipCount.basicIPCount;
for (i=0; i<iIPcount; i++)
{
if ((pBaseIPinfo[i].ipAddress != 0) &&
(pBaseIPinfo[i].ipAddress != 0x0100007F))
{
if (puIP)
*puIP = pBaseIPinfo[i].ipAddress;
if (puSubnetMask)
*puSubnetMask = pBaseIPinfo[i].subnetMask;
break;
}
}
}
if (IsntNull (pBaseIPinfo))
PGPFreeData (pBaseIPinfo);
}
}
}
if (IsPGPError (err))
break;
}
if (IsntNull (pBaseAddr))
PGPFreeData (pBaseAddr);
}
// no libaries to use
else
err = kPGPError_Win32DllOpFailed;
return err;
}
// ______________________________________________
//
// returns a valid IP address and subnet mask for this machine
PGPBoolean PGPclExport
PGPclIsLocalMachineOnline (void)
{
PGPUInt32 uIP = 0;
if (IsntPGPError (PGPclGetIPandSubnetMask (&uIP, NULL)))
{
if (uIP != 0)
{
return TRUE;
}
}
return FALSE;
}
// ____________________________________
//
// Gets list of DNS servers, skips duplicates
static void
sQueryDHCPForDNSServerAddress (
PGPUInt32* puDNSAddress)
{
CHAR szVxD[32];
HANDLE hVxD;
// attempt to open the DHCP VxD
lstrcpy (szVxD, "\\\\.\\VDHCP");
hVxD = CreateFile (szVxD, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE, 0);
if (hVxD == INVALID_HANDLE_VALUE)
{
lstrcat (szVxD, ".VXD");
hVxD = CreateFile (szVxD, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE, 0);
}
if (hVxD != INVALID_HANDLE_VALUE)
{
DWORD dw, dwRet;
// this first call should fail, returning required buffer size
if (!DeviceIoControl (hVxD, 0x01, (LPVOID)&dw, sizeof(dw),
(LPVOID)&dw, sizeof(dw), &dwRet, 0))
{
if (GetLastError () == ERROR_BUFFER_OVERFLOW)
{
struct _DHCPinfo* pDHCPinfo;
pDHCPinfo = PGPNewData (
PGPPeekContextMemoryMgr (g_context),
dw, kPGPMemoryMgrFlags_Clear);
if (pDHCPinfo)
{
if (DeviceIoControl (hVxD, 0x01, (LPVOID)pDHCPinfo, dw,
(LPVOID)pDHCPinfo, dw, &dwRet, 0))
{
// copy the first DNS server address
PGPByte* p = (PGPByte*)pDHCPinfo;
p += pDHCPinfo->b[0].dnsOff;
pgpCopyMemory (p, puDNSAddress, sizeof(PGPUInt32));
}
PGPFreeData (pDHCPinfo);
}
}
}
CloseHandle (hVxD);
}
}
// ____________________________________
//
// ask IPHelper for the DNS server IP address for the local machine
static void
sQueryIPHelperForDNSServerAddress (
PGPUInt32* puDNSAddress)
{
sInitializeLibraries ();
if (IsntNull (s_fpGetNetworkParams))
{
ULONG ulSize = 0;
FIXED_INFO* pfi;
DWORD dwRet;
dwRet = s_fpGetNetworkParams (NULL, &ulSize);
if ((dwRet == ERROR_BUFFER_OVERFLOW) && (ulSize > 0))
{
pfi = (FIXED_INFO*)PGPNewData (
PGPPeekContextMemoryMgr (g_context),
ulSize, kPGPMemoryMgrFlags_Clear);
if (pfi)
{
dwRet = s_fpGetNetworkParams (pfi, &ulSize);
if (dwRet == ERROR_SUCCESS)
{
*puDNSAddress = PGPDottedToInternetAddress (
pfi->DnsServerList.IpAddress.String);
}
PGPFreeData (pfi);
}
}
}
}
// ____________________________________
//
// get the DNS server IP address for the local machine
PGPError PGPclExport
PGPclGetDNSServerAddress (
PGPUInt32* puDNSAddress)
{
PGPError err;
HKEY hkey;
LONG lResult;
DWORD dwValueType, dwSize;
CHAR sz[32];
LPSTR p;
*puDNSAddress = 0;
// first try using the IPHelper library
sQueryIPHelperForDNSServerAddress (puDNSAddress);
if (*puDNSAddress != 0)
return kPGPError_NoErr;
// OK, that didn't work, now look in the WinNT key
err = kPGPError_ItemNotFound;
lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_READ, &hkey);
if (lResult == ERROR_SUCCESS)
{
dwSize = sizeof(sz);
lResult = RegQueryValueEx (hkey,
"NameServer", 0, &dwValueType, (LPBYTE)sz, &dwSize);
if (lResult == ERROR_SUCCESS)
err = kPGPError_NoErr;
RegCloseKey (hkey);
}
// if that didn't work, look in the Win9x key
if (IsPGPError (err))
{
lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\VxD\\MSTCP",
0, KEY_READ, &hkey);
if (lResult == ERROR_SUCCESS)
{
dwSize = sizeof(sz);
lResult = RegQueryValueEx (hkey,
"NameServer", 0, &dwValueType, (LPBYTE)sz, &dwSize);
if (lResult == ERROR_SUCCESS)
err = kPGPError_NoErr;
RegCloseKey (hkey);
}
}
// finally try the Win9x DHCP call
if (IsPGPError (err))
{
if (IsntNull (s_fpWsControl))
sQueryDHCPForDNSServerAddress (puDNSAddress);
if (*puDNSAddress != 0)
return kPGPError_NoErr;
}
// if here, and no error, then the address came from the registry and
// is in string format
if (IsntPGPError (err))
{
// string can be a space-separated list
p = strchr (sz, ' ');
if (p)
*p = '\0';
// or a comma-separated list
p = strchr (sz, ',');
if (p)
*p = '\0';
*puDNSAddress = PGPDottedToInternetAddress (sz);
}
return err;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?