2657 lines
73 KiB
Plaintext
2657 lines
73 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.Network
|
|
{ }
|
|
{ Copyright (C) 2022 sunk }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.Network;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, System.Classes, System.SysUtils, Winapi.WinSock,
|
|
Tocsg.Obj, System.Generics.Collections, Winapi.IpTypes;
|
|
|
|
//------------- headers from Microsoft IPTYPES.H--------------------------------
|
|
|
|
const
|
|
REG_KEY_NAME_CUR = 'SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%s\Connection';
|
|
REG_KEY_NAME_001 = 'SYSTEM\ControlSet001\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%s\Connection';
|
|
REG_KEY_NAME_002 = 'SYSTEM\ControlSet002\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%s\Connection';
|
|
REG_KEY_DNS = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s';
|
|
|
|
IP_NULL = '0.0.0.0';
|
|
MAC_NULL = '000000000000';
|
|
|
|
ANY_SIZE = 1;
|
|
MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
|
|
MAX_ADAPTER_NAME_LENGTH = 256; // arb.
|
|
MAX_ADAPTER_ADDRESS_LENGTH = 8; // arb.
|
|
DEFAULT_MINIMUM_ENTITIES = 32; // arb.
|
|
MAX_HOSTNAME_LEN = 128; // arb.
|
|
MAX_DOMAIN_NAME_LEN = 128; // arb.
|
|
MAX_SCOPE_ID_LEN = 256; // arb.
|
|
|
|
// Node Types ( NETBIOS)
|
|
BROADCAST_NODETYPE = 1;
|
|
PEER_TO_PEER_NODETYPE = 2;
|
|
MIXED_NODETYPE = 4;
|
|
HYBRID_NODETYPE = 8;
|
|
|
|
NETBIOSTypes : array[0..8] of string[20] =
|
|
( 'UNKNOWN', 'BROADCAST', 'PEER_TO_PEER', '', 'MIXED', '', '', '', 'HYBRID'
|
|
);
|
|
|
|
// Adapter Types
|
|
IF_OTHER_ADAPTERTYPE = 0;
|
|
IF_ETHERNET_ADAPTERTYPE = 1;
|
|
IF_TOKEN_RING_ADAPTERTYPE = 2;
|
|
IF_FDDI_ADAPTERTYPE = 3;
|
|
IF_PPP_ADAPTERTYPE = 4;
|
|
IF_LOOPBACK_ADAPTERTYPE = 5;
|
|
IF_SLIP_ADAPTERTYPE = 6;
|
|
//
|
|
AdaptTypes : array[0..6] of string[10] =
|
|
( 'other', 'ethernet', 'tokenring', 'FDDI', 'PPP', 'loopback', 'SLIP' );
|
|
|
|
DLL_IPHLPAPI = 'iphlpapi.dll';
|
|
DLL_NETAPI32 = 'NetAPI32.dll';
|
|
|
|
TCP_TABLE_BASIC_LISTENER = 0;
|
|
TCP_TABLE_BASIC_CONNECTIONS = 1;
|
|
TCP_TABLE_BASIC_ALL = 2;
|
|
TCP_TABLE_OWNER_PID_LISTENER = 3;
|
|
TCP_TABLE_OWNER_PID_CONNECTIONS = 4;
|
|
TCP_TABLE_OWNER_PID_ALL = 5;
|
|
TCP_TABLE_OWNER_MODULE_LISTENER = 6;
|
|
TCP_TABLE_OWNER_MODULE_CONNECTIONS = 7;
|
|
TCP_TABLE_OWNER_MODULE_ALL = 8;
|
|
|
|
UDP_TABLE_BASIC = 0;
|
|
UDP_TABLE_OWNER_PID = 1;
|
|
UDP_TABLE_OWNER_MODULE = 2;
|
|
|
|
TCP_STATE_UNKNOWN = 0;
|
|
TCP_STATE_CLOSED = 1;
|
|
TCP_STATE_LISTEN = 2;
|
|
TCP_STATE_SENT = 3;
|
|
TCP_STATE_SYN_RECEIVED = 4;
|
|
TCP_STATE_ESTABLISHED = 5;
|
|
TCP_STATE_FIN_WAIT_1 = 6;
|
|
TCP_STATE_FIN_WAIT_2 = 7;
|
|
TCP_STATE_CLOSE_WAIT = 8;
|
|
TCP_STATE_CLOSING = 9;
|
|
TCP_STATE_LAST_ACK = 10;
|
|
TCP_STATE_TIME_WAIT = 11;
|
|
TCP_STATE_delete_TCB = 12;
|
|
|
|
STYPE_DISKTREE = 0;
|
|
STYPE_PRINTQ = 1;
|
|
STYPE_DEVICE = 2;
|
|
STYPE_IPC = 3;
|
|
STYPE_TEMPORARY = $40000000;
|
|
STYPE_SPECIAL = $80000000;
|
|
|
|
MIB_TCP_STATE: array[TCP_STATE_UNKNOWN..TCP_STATE_delete_TCB] of string =
|
|
('Unknown', 'CLOSED', 'LISTEN', 'SYN-SENT ','SYN-RECEIVED', 'ESTABLISHED', 'FIN-WAIT-1',
|
|
'FIN-WAIT-2', 'CLOSE-WAIT', 'CLOSING','LAST-ACK', 'TIME-WAIT', 'delete TCB');
|
|
|
|
//-------------from other MS header files---------------------------------------
|
|
|
|
MAX_INTERFACE_NAME_LEN = 256; { mrapi.h }
|
|
MAXLEN_PHYSADDR = 8; { iprtrmib.h }
|
|
MAXLEN_IFDESCR = 256; { --"--- }
|
|
|
|
//------IP address structures---------------------------------------------------
|
|
|
|
MIB_IF_TYPE_OTHER = 1; // Some other type of network interface. 기타 등등
|
|
MIB_IF_TYPE_ETHERNET = 6; // An Ethernet network interface. 이더넷(무선 포함)
|
|
IF_TYPE_ISO88025_TOKENRING = 9; // MIB_IF_TYPE_TOKENRING 토큰링
|
|
MIB_IF_TYPE_FDDI = 15; // 광
|
|
MIB_IF_TYPE_PPP = 23; // A PPP network interface. PPP
|
|
MIB_IF_TYPE_LOOPBACK = 24; // A software loopback network interface. 루프백 (localloop)
|
|
MIB_IF_TYPE_SLIP = 28; // An ATM network interface. SLIP
|
|
IF_TYPE_IEEE80211 = 71; // An IEEE 802.11 wireless network interface.
|
|
|
|
type
|
|
// 추가 17_1206 14:17:45 sunk
|
|
TCP_TABLE_CLASS = Integer;
|
|
UDP_TABLE_CLASS = Integer;
|
|
|
|
PMibTcpRowOwnerPid = ^TMibTcpRowOwnerPid;
|
|
TMibTcpRowOwnerPid = packed record
|
|
dwState,
|
|
dwLocalAddr,
|
|
dwLocalPort,
|
|
dwRemoteAddr,
|
|
dwRemotePort,
|
|
dwOwningPid: DWORD;
|
|
end;
|
|
|
|
PMIB_TCPTABLE_OWNER_PID = ^MIB_TCPTABLE_OWNER_PID;
|
|
MIB_TCPTABLE_OWNER_PID = packed record
|
|
dwNumEntries: DWORD;
|
|
table: array of TMibTcpRowOwnerPid;
|
|
// table: Array [0..ANY_SIZE - 1] of TMibTcpRowOwnerPid;
|
|
end;
|
|
|
|
PMibUdpRowOwnerPid = ^TMibUdpRowOwnerPid;
|
|
TMibUdpRowOwnerPid = packed record
|
|
dwLocalAddr,
|
|
dwLocalPort,
|
|
dwOwningPid: DWORD;
|
|
end;
|
|
|
|
PMIB_UDPTABLE_OWNER_PID = ^MIB_UDPTABLE_OWNER_PID;
|
|
MIB_UDPTABLE_OWNER_PID = packed record
|
|
dwNumEntries: DWORD;
|
|
table: Array [0..ANY_SIZE - 1] of TMibUdpRowOwnerPid;
|
|
end;
|
|
|
|
type
|
|
TMacAddress = array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
|
|
|
|
type
|
|
PTIP_ADDRESS_STRING = ^TIP_ADDRESS_STRING;
|
|
TIP_ADDRESS_STRING = array [0..15] of AnsiChar; // IP as xxx.xxx.xxx.xxx string
|
|
//
|
|
PTIP_ADDR_STRING = ^TIP_ADDR_STRING;
|
|
TIP_ADDR_STRING = packed record // for use in linked lists
|
|
Next : PTIP_ADDR_STRING;
|
|
IpAddress : TIP_ADDRESS_STRING;
|
|
IpMask : TIP_ADDRESS_STRING;
|
|
Context : DWORD;
|
|
end;
|
|
|
|
PTMibIPNetRow = ^TMibIPNetRow;
|
|
TMibIPNetRow = packed record
|
|
dwIndex : DWord;
|
|
dwPhysAddrLen : DWord;
|
|
bPhysAddr : TMACAddress;
|
|
dwAddr : DWord;
|
|
dwType : DWord;
|
|
end;
|
|
|
|
PTMibIPAddrRow = ^TMibIPAddrRow;
|
|
TMibIPAddrRow = packed record
|
|
dwAddr : DWORD;
|
|
dwIndex : DWORD;
|
|
dwMask : DWORD;
|
|
dwBCastAddr : DWORD;
|
|
dwReasmSize : DWORD;
|
|
Unused1,
|
|
Unused2 : WORD;
|
|
end;
|
|
|
|
TMibIPAddrArray = array of TMIBIPAddrRow;
|
|
|
|
PTMibIPAddrTable = ^TMibIPAddrTable;
|
|
TMibIPAddrTable = packed record
|
|
dwNumEntries : DWORD;
|
|
Table : array[0..ANY_SIZE - 1] of TMibIPAddrRow;
|
|
end;
|
|
|
|
PTMibIPNetTable = ^TMibIPNetTable;
|
|
TMibIPNetTable = packed record
|
|
dwNumEntries : DWORD;
|
|
Table : array[0..ANY_SIZE - 1] of TMibIPNetRow;
|
|
end;
|
|
|
|
PTMibIPStats = ^TMibIPStats;
|
|
TMibIPStats = packed record
|
|
dwForwarding : DWORD;
|
|
dwDefaultTTL : DWORD;
|
|
dwInReceives : DWORD;
|
|
dwInHdrErrors : DWORD;
|
|
dwInAddrErrors : DWORD;
|
|
dwForwDatagrams : DWORD;
|
|
dwInUnknownProtos : DWORD;
|
|
dwInDiscards : DWORD;
|
|
dwInDelivers : DWORD;
|
|
dwOutRequests : DWORD;
|
|
dwRoutingDiscards : DWORD;
|
|
dwOutDiscards : DWORD;
|
|
dwOutNoRoutes : DWORD;
|
|
dwReasmTimeOut : DWORD;
|
|
dwReasmReqds : DWORD;
|
|
dwReasmOKs : DWORD;
|
|
dwReasmFails : DWORD;
|
|
dwFragOKs : DWORD;
|
|
dwFragFails : DWORD;
|
|
dwFragCreates : DWORD;
|
|
dwNumIf : DWORD;
|
|
dwNumAddr : DWORD;
|
|
dwNumRoutes : DWORD;
|
|
end;
|
|
|
|
PTMibIPForwardRow = ^TMibIPForwardRow;
|
|
TMibIPForwardRow = packed record
|
|
dwForwardDest : DWORD;
|
|
dwForwardMask : DWORD;
|
|
dwForwardPolicy : DWORD;
|
|
dwForwardNextHop : DWORD;
|
|
dwForwardIFIndex : DWORD;
|
|
dwForwardType : DWORD;
|
|
dwForwardProto : DWORD;
|
|
dwForwardAge : DWORD;
|
|
dwForwardNextHopAS : DWORD;
|
|
dwForwardMetric1 : DWORD;
|
|
dwForwardMetric2 : DWORD;
|
|
dwForwardMetric3 : DWORD;
|
|
dwForwardMetric4 : DWORD;
|
|
dwForwardMetric5 : DWORD;
|
|
end;
|
|
|
|
PTMibIPForwardTable = ^TMibIPForwardTable;
|
|
TMibIPForwardTable = packed record
|
|
dwNumEntries : DWORD;
|
|
Table : array[0..ANY_SIZE - 1] of TMibIPForwardRow;
|
|
end;
|
|
|
|
//----------------TCP STRUCTURES------------------------------------------------
|
|
|
|
PTMibTCPRow = ^TMibTCPRow;
|
|
TMibTCPRow = packed record
|
|
dwState : DWORD;
|
|
dwLocalAddr : DWORD;
|
|
dwLocalPort : DWORD;
|
|
dwRemoteAddr : DWORD;
|
|
dwRemotePort : DWORD;
|
|
end;
|
|
//
|
|
PTMibTCPTable = ^TMibTCPTable;
|
|
TMibTCPTable = packed record
|
|
dwNumEntries : DWORD;
|
|
Table : array[0..0] of TMibTCPRow;
|
|
end;
|
|
//
|
|
PTMibTCPStats = ^TMibTCPStats;
|
|
TMibTCPStats = packed record
|
|
dwRTOAlgorithm : DWORD;
|
|
dwRTOMin : DWORD;
|
|
dwRTOMax : DWORD;
|
|
dwMaxConn : DWORD;
|
|
dwActiveOpens : DWORD;
|
|
dwPassiveOpens : DWORD;
|
|
dwAttemptFails : DWORD;
|
|
dwEstabResets : DWORD;
|
|
dwCurrEstab : DWORD;
|
|
dwInSegs : DWORD;
|
|
dwOutSegs : DWORD;
|
|
dwRetransSegs : DWORD;
|
|
dwInErrs : DWORD;
|
|
dwOutRsts : DWORD;
|
|
dwNumConns : DWORD;
|
|
end;
|
|
|
|
//---------UDP STRUCTURES-------------------------------------------------------
|
|
|
|
PTMibUDPRow = ^TMibUDPRow;
|
|
TMibUDPRow = packed record
|
|
dwLocalAddr: DWORD;
|
|
dwLocalPort: DWORD;
|
|
end;
|
|
//
|
|
PTMibUDPTable = ^TMIBUDPTable;
|
|
TMIBUDPTable = packed record
|
|
dwNumEntries : DWORD;
|
|
UDPTable : array[0..ANY_SIZE - 1] of TMibUDPRow;
|
|
end;
|
|
//
|
|
PTMibUdpStats = ^TMIBUdpStats;
|
|
TMIBUdpStats = packed record
|
|
dwInDatagrams : DWORD;
|
|
dwNoPorts : DWORD;
|
|
dwInErrors : DWORD;
|
|
dwOutDatagrams : DWORD;
|
|
dwNumAddrs : DWORD;
|
|
end;
|
|
|
|
//------ADAPTER INFO STRUCTURES-------------------------------------------------
|
|
type
|
|
// Winapi.IpTypes.pas에서 PIP_ADAPTER_INFO 로 대체 20_1016 12:3843 sunk
|
|
// 기존에 사용하던 아래 구조체는 64비트 환경에서 포인터 밀린다.
|
|
PTIP_ADAPTER_INFO = PIP_ADAPTER_INFO;
|
|
TIP_ADAPTER_INFO = IP_ADAPTER_INFO;
|
|
|
|
// TTIME_T = array[1..325] of byte; // hack! MS time.h missing!
|
|
|
|
// PTIP_ADAPTER_INFO = ^TIP_ADAPTER_INFO;
|
|
// TIP_ADAPTER_INFO = packed record
|
|
// Next : PTIP_ADAPTER_INFO;
|
|
// ComboIndex : DWORD;
|
|
// AdapterName : array[1..MAX_ADAPTER_NAME_LENGTH + 4] of AnsiChar;
|
|
// Description : array[1..MAX_ADAPTER_DESCRIPTION_LENGTH + 4] of AnsiChar;
|
|
// AddressLength : UINT;
|
|
// Address : array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
|
|
// Index : DWORD;
|
|
// aType : UINT;
|
|
// DHCPEnabled : UINT;
|
|
// CurrentIPAddress : PTIP_ADDR_STRING;
|
|
// IPAddressList : TIP_ADDR_STRING;
|
|
// GatewayList : TIP_ADDR_STRING;
|
|
// DHCPServer : TIP_ADDR_STRING;
|
|
// HaveWINS : BOOL;
|
|
// PrimaryWINSServer : TIP_ADDR_STRING;
|
|
// SecondaryWINSServer : TIP_ADDR_STRING;
|
|
// LeaseObtained : TTIME_T; //??
|
|
// LeaseExpires : TTIME_T; //??
|
|
// end;
|
|
|
|
//----------Fixed Info STRUCTURES---------------------------------------------
|
|
|
|
PTFixedInfo = ^TFixedInfo;
|
|
TFixedInfo = packed record
|
|
HostName : array[0..MAX_HOSTNAME_LEN + 4] of char;
|
|
DomainName : array[0..MAX_DOMAIN_NAME_LEN + 4] of char;
|
|
CurrentDNSServer : PTIP_ADDR_STRING;
|
|
DNSServerList : TIP_ADDR_STRING;
|
|
NodeType : UINT;
|
|
ScopeID : array[0..MAX_SCOPE_ID_LEN + 4] of char;
|
|
EnableRouting : UINT;
|
|
EnableProxy : UINT;
|
|
EnableDNS : UINT;
|
|
end;
|
|
|
|
//--------ICMP-STRUCTURES------------------------------------------------------
|
|
|
|
PTMibICMPStats = ^TMibICMPStats;
|
|
TMibICMPStats = packed record
|
|
dwMsgs : DWORD;
|
|
dwErrors : DWORD;
|
|
dwDestUnreachs : DWORD;
|
|
dwTimeEcxcds : DWORD;
|
|
dwParmProbs : DWORD;
|
|
dwSrcQuenchs : DWORD;
|
|
dwRedirects : DWORD;
|
|
dwEchos : DWORD;
|
|
dwEchoReps : DWORD;
|
|
dwTimeStamps : DWORD;
|
|
dwTimeStampReps : DWORD;
|
|
dwAddrMasks : DWORD;
|
|
dwAddrReps : DWORD;
|
|
end;
|
|
|
|
PTMibICMPInfo = ^TMibICMPInfo;
|
|
TMibICMPInfo = packed record
|
|
InStats : TMibICMPStats;
|
|
OutStats : TMibICMPStats;
|
|
end;
|
|
|
|
IPINFO = Record
|
|
Ttl : Char; // Time To Live
|
|
Tos : Char; // Type Of Service
|
|
IPFlags : Char; // IP flags
|
|
OptSize : Char; // Size of options data
|
|
Options : pChar; // Options data buffer
|
|
end;
|
|
|
|
ICMPECHO = Record
|
|
Source : ULONG; // Source address
|
|
Status : ULONG; // IP status
|
|
RTTime : ULONG; // Round trip time in milliseconds
|
|
DataSize : SHORT ; // Reply data size
|
|
Reserved : SHORT ; // Unknown
|
|
pData : Pchar; // Reply data buffer
|
|
ipInfo : IPINFO; // Reply options
|
|
end;
|
|
|
|
//----------INTERFACE STRUCTURES-------------------------------------------------
|
|
|
|
|
|
PTMibIfRow = ^TMibIfRow;
|
|
TMibIfRow = packed record
|
|
wszName : array[1..MAX_INTERFACE_NAME_LEN] of WCHAR;
|
|
dwIndex : DWORD;
|
|
dwType : DWORD;
|
|
dwMTU : DWORD;
|
|
dwSpeed : DWORD;
|
|
dwPhysAddrLen : DWORD;
|
|
bPhysAddr : array[1..MAXLEN_PHYSADDR] of byte;
|
|
dwAdminStatus : DWORD;
|
|
dwOperStatus : DWORD;
|
|
dwLastChange : DWORD;
|
|
dwInOctets : DWORD;
|
|
dwInUcastPkts : DWORD;
|
|
dwInNUCastPkts : DWORD;
|
|
dwInDiscards : DWORD;
|
|
dwInErrors : DWORD;
|
|
dwInUnknownProtos : DWORD;
|
|
dwOutOctets : DWORD;
|
|
dwOutUCastPkts : DWORD;
|
|
dwOutNUCastPkts : DWORD;
|
|
dwOutDiscards : DWORD;
|
|
dwOutErrors : DWORD;
|
|
dwOutQLen : DWORD;
|
|
dwDescrLen : DWORD;
|
|
bDescr : array[1..MAXLEN_IFDESCR] of char; //byte;
|
|
end;
|
|
|
|
TMIBIfArray = array of TMIBIFRow;
|
|
|
|
|
|
//
|
|
PTMibIfTable = ^TMIBIfTable;
|
|
TMibIfTable = packed record
|
|
dwNumEntries : DWORD;
|
|
Table : array[0..ANY_SIZE - 1] of TMibIfRow;
|
|
end;
|
|
|
|
//------------------imports from IPHLPAPI.DLL-----------------------------------
|
|
|
|
PRouteEnt = ^TRouteEnt;
|
|
TRouteEnt = record
|
|
sDestIp: String;
|
|
Info: TMibIPForwardRow;
|
|
end;
|
|
TRouteEntList = class(TList<PRouteEnt>)
|
|
protected
|
|
procedure Notify(const Item: PRouteEnt; Action: TCollectionNotification); override;
|
|
public
|
|
function GetEntByDestIp(sDestIp: String): PRouteEnt;
|
|
end;
|
|
|
|
SHARE_INFO_1 = record
|
|
shi1_netname : PWideChar;
|
|
shi1_type : DWORD;
|
|
shi1_remark : PWideChar;
|
|
end;
|
|
PSHARE_INFO_1 = ^SHARE_INFO_1;
|
|
|
|
SHARE_INFO_2 = record
|
|
shi2_netname : PWideChar;
|
|
shi2_type : DWORD;
|
|
shi2_remark : PWideChar;
|
|
shi2_permissions : DWORD;
|
|
shi2_max_uses : DWORD;
|
|
shi2_current_uses: DWORD;
|
|
shi2_path : PWideChar;
|
|
shi2_passwd : PWideChar;
|
|
end;
|
|
PSHARE_INFO_2 = ^SHARE_INFO_2;
|
|
|
|
NET_API_STATUS = DWORD;
|
|
|
|
TGetAdaptersInfo = function(pAdapterInfo: PTIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD; stdcall;
|
|
TGetExtendedTcpTable = function(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWORD; stdcall;
|
|
TGetExtendedUdpTable = function(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: UDP_TABLE_CLASS; Reserved: ULONG): DWORD; stdcall;
|
|
TGetIpForwardTable = function(pIPForwardTable: PTMibIPForwardTable; pdwSize: PULONG; bOrder: BOOL): DWORD; stdCall;
|
|
TDeleteIpForwardEntry = function(pEnt: PTMibIPForwardRow): DWORD; stdCall;
|
|
|
|
TNetShareEnum = function(ServerName: PWideChar; Level: DWORD; var BufPtr: Pointer;
|
|
PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
|
|
var ResumeHandle : DWORD): NET_API_STATUS; stdcall;
|
|
TNetApiBufferFree = function(Buffer : Pointer): NET_API_STATUS; stdcall;
|
|
|
|
function GetAdaptersInfo(pAdapterInfo: PTIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD;
|
|
function GetExtendedTcpTable(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWORD;
|
|
function GetExtendedUdpTable(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: UDP_TABLE_CLASS; Reserved: ULONG): DWORD;
|
|
//function GetNetworkParams(FixedInfo: PTFixedInfo; pOutPutLen: PULONG): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetTcpTable(pTCPTable: PTMibTCPTable; pDWSize: PDWORD; bOrder: BOOL): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetTcpStatistics(pStats: PTMibTCPStats): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetUdpTable(pUdpTable: PTMibUDPTable; pDWSize: PDWORD; bOrder: BOOL): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetUdpStatistics(pStats: PTMibUdpStats): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetIpStatistics(pStats: PTMibIPStats): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetIpNetTable(pIpNetTable: PTMibIPNetTable; pdwSize: PULONG; bOrder: BOOL): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
//function GetIpAddrTable(pIpAddrTable: PTMibIPAddrTable; pdwSize: PULONG; bOrder: BOOL): DWORD; stdcall; external 'IPHLPAPI.DLL';
|
|
function GetIpForwardTable(pIPForwardTable: PTMibIPForwardTable; pdwSize: PULONG; bOrder: BOOL): DWORD;
|
|
function DeleteIpForwardEntry(pEnt: PTMibIPForwardRow): DWORD;
|
|
//function GetIcmpStatistics(pStats: PTMibICMPInfo): DWORD; stdCall; external 'IPHLPAPI.DLL';
|
|
//function GetRTTAndHopCount(DestIPAddress: DWORD; HopCount: PULONG; MaxHops: ULONG; RTT: PULONG): BOOL; stdCall; external 'IPHLPAPI.DLL';
|
|
//function GetIfTable(pIfTable: PTMibIfTable; pdwSize: PULONG; bOrder: boolean): DWORD; stdCall; external 'IPHLPAPI.DLL';
|
|
//function GetIfEntry(pIfRow: PTMibIfRow): DWORD; stdCall; external 'IPHLPAPI.DLL';
|
|
//function GetBestInterface(pIfRow: in_addr; pnBestIndex: PDWORD): DWORD; stdCall; external 'IPHLPAPI.DLL';
|
|
|
|
function NetShareEnum(ServerName: PWideChar; Level: DWORD; var BufPtr: Pointer;
|
|
PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
|
|
var ResumeHandle : DWORD): NET_API_STATUS;
|
|
function NetApiBufferFree(Buffer : Pointer): NET_API_STATUS;
|
|
|
|
//function IcmpCreateFile: THandle; stdcall; external 'icmp.dll';
|
|
//function IcmpCloseHandle(icmpHandle: THandle): boolean; stdcall; external 'icmp.dll';
|
|
//function IcmpSendEcho(IcmpHandle: THandle; DestinationAddress: LongInt;
|
|
// RequestData: Pointer; RequestSize: Smallint;
|
|
// RequestOptions: pointer; ReplyBuffer: Pointer;
|
|
// ReplySize: DWORD; Timeout: DWORD): DWORD;
|
|
// stdcall; external 'icmp.dll';
|
|
|
|
|
|
function GetCurrentHostName: String;
|
|
|
|
function IPToDWORD(sIp: String) : Dword;
|
|
function DWORDToIP(IPDWord: DWORD; bBig: Boolean = true) : String;
|
|
function IncIP(sIp: String; nInc: Integer = 1): String;
|
|
function IsValidIP(const sIp: String; bIgrIpNull: Boolean = true; bIncIPv6: Boolean = false): Boolean;
|
|
function IsValidIPEx(const sIp: String): Boolean;
|
|
function IsValidIpRange(sIpRange: String): Boolean;
|
|
function IsIncludeIP(const sIpEx, sIp: String): Boolean;
|
|
|
|
function GetHostIP: String;
|
|
function GetHostIPsFromDomain(sDomain: AnsiString; sDm: AnsiString = ','): AnsiString;
|
|
function GetIPAddrsToList(lstIP: TStrings): Integer;
|
|
function GetIPAddrsToListEx(lstIP: TStrings): Integer;
|
|
function GetIPAddrsToCommaStr: String;
|
|
function GetIPAddrsToCommaStrEx: String;
|
|
function GetMACAddrToList(aMacList: TStrings): Boolean;
|
|
function GetMACAddrToCommaStr: String;
|
|
function GetMACAddr: String;
|
|
function GetMACAddrUsing: String;
|
|
|
|
function ExtractIPPort(sSrcIPort: String; var sIp: String; var nPort: Integer): Boolean;
|
|
|
|
function GetNetDrives(aDrives: TStrings): Integer;
|
|
function NetDriveToRemoteAddr(sNDrv: String): String;
|
|
function IsNetDrive(cLetter: Char): Boolean;
|
|
|
|
function GetNicEnable(sDesc: String): Boolean;
|
|
function SetNicEnable(sDesc: String; bVal: Boolean): Integer;
|
|
function SetNicEnableByIndex(nIdx: Integer; bVal: Boolean): Boolean;
|
|
function GetNetAdapterTypeToStr(dwType: DWORD): String;
|
|
function IsConnectedWIFI(aInterfaceGuid: TGUID): Boolean;
|
|
function DisconnectWIFI(aInterfaceGuid: TGUID): Boolean;
|
|
|
|
function GetRouteTables(aList: TRouteEntList): Integer;
|
|
function GetPublicIP: string;
|
|
function RemoveEveryoneFromShare(const sShareName: string): Boolean;
|
|
|
|
type
|
|
// dwType
|
|
// 1 = MIB_IF_TYPE_OTHER (다른 유형의 네트워크 인터페이스. Some other type of network interface.)
|
|
// 6 = MIB_IF_TYPE_ETHERNET (이더넷 네트워크 인터페이스. An Ethernet network interface.)
|
|
// 9 = IF_TYPE_ISO88025_TOKENRING (MIB_IF_TYPE_TOKENRING)
|
|
// 23 = MIB_IF_TYPE_PPP (PPP 네트워크 인터페이스. A PPP network interface.)
|
|
// 24 = B_IF_TYPE_LOOPBACK (소프트웨어 루프백 네트워크 인터페이스. A software loopback network interface.)
|
|
// 28 = MIB_IF_TYPE_SLIP (ATM 네트워크 인터페이스. An ATM network interface.)
|
|
// 71 = IF_TYPE_IEEE80211 (IEEE 802.11 무선 네트워크 인터페이스. An IEEE 802.11 wireless network interface.)
|
|
PNetAdapterEnt = ^TNetAdapterEnt;
|
|
TNetAdapterEnt = record
|
|
sName,
|
|
sDesc,
|
|
sMacAddr,
|
|
sIpAddrs,
|
|
// sCurIpAddr,
|
|
sGatewayIps,
|
|
sDHCPServer,
|
|
sPriWINSServer,
|
|
sSecWINSServer: AnsiString;
|
|
bDHCP,
|
|
bHaveWINS: Boolean;
|
|
dwComboIdx,
|
|
dwIndex,
|
|
dwType: DWORD;
|
|
end;
|
|
TNetAdapterEntList = TList<PNetAdapterEnt>;
|
|
|
|
TNetAdapterInfo = class(TTgObject)
|
|
private
|
|
AdapterList_: TNetAdapterEntList;
|
|
procedure OnAdapterNotify(Sender: TObject; const Item: PNetAdapterEnt;
|
|
Action: TCollectionNotification);
|
|
function GetByIndex(nIndex: Integer): PNetAdapterEnt;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
procedure UpdateNetAdapterInfo;
|
|
function Count: Integer;
|
|
|
|
property Items[nIndex: Integer]: PNetAdapterEnt read GetByIndex; default;
|
|
end;
|
|
|
|
PWLanEnt = ^TWLanEnt;
|
|
TWLanEnt = record
|
|
sName,
|
|
sBssid,
|
|
sProfile: String;
|
|
nQuality: Integer;
|
|
dwAlgo1,
|
|
dwAlgo2: DWORD;
|
|
bSecurety: Boolean;
|
|
InterfaceGuid: TGUID;
|
|
end;
|
|
TWLanEntList = TList<PWLanEnt>;
|
|
TWlanInfo = class(TTgObject)
|
|
private
|
|
WLanEntList_: TWLanEntList;
|
|
procedure OnWlanEntNotify(Sender: TObject; const Item: PWLanEnt;
|
|
Action: TCollectionNotification);
|
|
function GetByIndex(nIndex: Integer): PWLanEnt;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
procedure UpdateWlanInfo;
|
|
function Count: Integer;
|
|
function GetWlanEntByName(sName: String): PWLanEnt;
|
|
|
|
property Items[nIndex: Integer]: PWLanEnt read GetByIndex; default;
|
|
end;
|
|
|
|
PTcpInfoEnt = ^TTcpInfoEnt;
|
|
TTcpInfoEnt = record
|
|
sLocalIpAddr,
|
|
sRemoteIpAddr: String;
|
|
nLocalPort,
|
|
nRemotePort: Integer;
|
|
dwPid,
|
|
dwStatus: DWORD;
|
|
end;
|
|
TTcpInfoEntList = TList<PTcpInfoEnt>;
|
|
|
|
TTcpTableInfo = class(TTgObject)
|
|
private
|
|
TcpEnts_: TTcpInfoEntList;
|
|
procedure OnTcpInfoEntNotify(Sender: TObject; const Item: PTcpInfoEnt;
|
|
Action: TCollectionNotification);
|
|
function GetByIndex(nIndex: Integer): PTcpInfoEnt;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
procedure UpdateTcpTableInfo;
|
|
function Count: Integer;
|
|
procedure Delete(nIndex: Integer);
|
|
|
|
property Items[nIndex: Integer]: PTcpInfoEnt read GetByIndex; default;
|
|
end;
|
|
|
|
PUdpInfoEnt = ^TUdpInfoEnt;
|
|
TUdpInfoEnt = record
|
|
sLocalIpAddr: String;
|
|
nLocalPort: Integer;
|
|
dwPid: DWORD;
|
|
end;
|
|
TUdpInfoEntList = TList<PUdpInfoEnt>;
|
|
|
|
TUdpTableInfo = class(TTgObject)
|
|
private
|
|
UdpEnts_: TUdpInfoEntList;
|
|
procedure OnUdpInfoEntNotify(Sender: TObject; const Item: PUdpInfoEnt;
|
|
Action: TCollectionNotification);
|
|
function GetByIndex(nIndex: Integer): PUdpInfoEnt;
|
|
public
|
|
Constructor Create;
|
|
Destructor Destroy; override;
|
|
|
|
procedure UpdateUdpTableInfo;
|
|
function Count: Integer;
|
|
procedure Delete(nIndex: Integer);
|
|
|
|
property Items[nIndex: Integer]: PUdpInfoEnt read GetByIndex; default;
|
|
end;
|
|
|
|
PShdFldEnt = ^TShdFldEnt;
|
|
TShdFldEnt = record
|
|
sName,
|
|
sPath: String;
|
|
end;
|
|
TSharedFolder = class(TList<PShdFldEnt>)
|
|
protected
|
|
sSvrName_: String;
|
|
procedure Notify(const Item: PShdFldEnt; Action: TCollectionNotification); override;
|
|
public
|
|
Constructor Create(bUpdate: Boolean = false; sServerName: String = ''; bIgrSpecial: Boolean = false);
|
|
|
|
procedure UpdateShdFldList(bIgrSpecial: Boolean = false);
|
|
function ExistsSharedFolder(sPath: String): Boolean;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Safe, Tocsg.Strings, Tocsg.Path, Tocsg.Exception, Tocsg.Driver,
|
|
Tocsg.Convert, EM.nduWlanAPI, Tocsg.Trace, Tocsg.WMI, Tocsg.WinInfo,
|
|
System.Net.HttpClient, EM.nduWlanTypes, Winapi.AclAPI, Winapi.AccCtrl;
|
|
|
|
resourcestring
|
|
RS_NetOther = '기타';
|
|
RS_NetEthernet = '이더넷';
|
|
RS_NetTokenring = '토큰링';
|
|
RS_NetFDDI = '광';
|
|
RS_NetLoop = '루프백 (localloop)';
|
|
|
|
var
|
|
_hIpHlpApi: THandle = 0;
|
|
_fnGetAdaptersInfo: TGetAdaptersInfo = nil;
|
|
_fnGetExtendedTcpTable: TGetExtendedTcpTable = nil;
|
|
_fnGetExtendedUdpTable: TGetExtendedUdpTable = nil;
|
|
_fnGetIpForwardTable: TGetIpForwardTable = nil;
|
|
_fnDeleteIpForwardEntry: TDeleteIpForwardEntry = nil;
|
|
|
|
_hNetApi32: THandle = 0;
|
|
_fnNetShareEnum: TNetShareEnum = nil;
|
|
_fnNetApiBufferFree: TNetApiBufferFree = nil;
|
|
|
|
function InitIpHlpApiModule: Boolean;
|
|
begin
|
|
if _hIpHlpApi = 0 then
|
|
begin
|
|
_hIpHlpApi := GetModuleHandle(DLL_IPHLPAPI);
|
|
|
|
// 추가 22_0107 10:45:42 sunk
|
|
if _hIpHlpApi = 0 then
|
|
_hIpHlpApi := LoadLibrary(DLL_IPHLPAPI);
|
|
|
|
if _hIpHlpApi <> 0 then
|
|
begin
|
|
@_fnGetAdaptersInfo := GetProcAddress(_hIpHlpApi, 'GetAdaptersInfo');
|
|
@_fnGetExtendedTcpTable := GetProcAddress(_hIpHlpApi, 'GetExtendedTcpTable');
|
|
@_fnGetExtendedUdpTable := GetProcAddress(_hIpHlpApi, 'GetExtendedUdpTable');
|
|
|
|
@_fnGetIpForwardTable := GetProcAddress(_hIpHlpApi, 'GetIpForwardTable');
|
|
@_fnDeleteIpForwardEntry := GetProcAddress(_hIpHlpApi, 'DeleteIpForwardEntry');
|
|
end;
|
|
end;
|
|
Result := _hIpHlpApi <> 0;
|
|
end;
|
|
|
|
function InitNetApi32Module: Boolean;
|
|
begin
|
|
if _hNetApi32 = 0 then
|
|
begin
|
|
_hNetApi32 := GetModuleHandle(DLL_NETAPI32);
|
|
|
|
if _hNetApi32 = 0 then
|
|
_hNetApi32 := LoadLibrary(DLL_NETAPI32);
|
|
|
|
if _hNetApi32 <> 0 then
|
|
begin
|
|
@_fnNetShareEnum := GetProcAddress(_hNetApi32, 'NetShareEnum');
|
|
@_fnNetApiBufferFree := GetProcAddress(_hNetApi32, 'NetApiBufferFree');
|
|
end;
|
|
end;
|
|
Result := _hNetApi32 <> 0;
|
|
end;
|
|
|
|
function GetAdaptersInfo(pAdapterInfo: PTIP_ADAPTER_INFO; pOutBufLen: PULONG): DWORD;
|
|
begin
|
|
if InitIpHlpApiModule and Assigned(_fnGetAdaptersInfo) then
|
|
Result := _fnGetAdaptersInfo(pAdapterInfo, pOutBufLen)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function GetExtendedTcpTable(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWORD;
|
|
begin
|
|
if InitIpHlpApiModule and Assigned(_fnGetExtendedTcpTable) then
|
|
Result := _fnGetExtendedTcpTable(pTcpTable, dwSize, bOrder, lAf, TableClass, Reserved)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function GetExtendedUdpTable(pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL;
|
|
lAf: ULONG; TableClass: UDP_TABLE_CLASS; Reserved: ULONG): DWORD;
|
|
begin
|
|
if InitIpHlpApiModule and Assigned(_fnGetExtendedUdpTable) then
|
|
Result := _fnGetExtendedUdpTable(pTcpTable, dwSize, bOrder, lAf, TableClass, Reserved)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function GetIpForwardTable(pIPForwardTable: PTMibIPForwardTable; pdwSize: PULONG; bOrder: BOOL): DWORD;
|
|
begin
|
|
if InitIpHlpApiModule and Assigned(_fnGetIpForwardTable) then
|
|
Result := _fnGetIpForwardTable(pIPForwardTable, pdwSize, bOrder)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function DeleteIpForwardEntry(pEnt: PTMibIPForwardRow): DWORD;
|
|
begin
|
|
if InitIpHlpApiModule and Assigned(_fnDeleteIpForwardEntry) then
|
|
Result := _fnDeleteIpForwardEntry(pEnt)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function NetShareEnum(ServerName: PWideChar; Level: DWORD; var BufPtr: Pointer;
|
|
PrefMaxLen: DWORD; var EntriesRead: DWORD; var TotalEntries: DWORD;
|
|
var ResumeHandle : DWORD): NET_API_STATUS;
|
|
begin
|
|
if InitNetApi32Module and Assigned(_fnNetShareEnum) then
|
|
Result := _fnNetShareEnum(ServerName, Level, BufPtr, PrefMaxLen, EntriesRead,
|
|
TotalEntries, ResumeHandle)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function NetApiBufferFree(Buffer : Pointer): NET_API_STATUS;
|
|
begin
|
|
if InitNetApi32Module and Assigned(_fnNetApiBufferFree) then
|
|
Result := _fnNetApiBufferFree(Buffer)
|
|
else
|
|
Result := ERROR_INVALID_FUNCTION;
|
|
end;
|
|
|
|
function GetCurrentHostName: String;
|
|
var
|
|
wVersionRequested : WORD;
|
|
wsaData: TWSAData;
|
|
sHostName: array[0..128] of AnsiChar;
|
|
begin
|
|
ZeroMemory(@sHostName, SizeOf(sHostName));
|
|
wVersionRequested := MAKEWORD(1, 1);
|
|
WSAStartup(wVersionRequested, wsaData);
|
|
|
|
GetHostName(@sHostName, 128);
|
|
Result := sHostName;
|
|
|
|
WSACleanup;
|
|
end;
|
|
|
|
function IPToDWORD(sIp: String) : Dword;
|
|
var
|
|
SL : TStringList;
|
|
i : integer;
|
|
begin
|
|
Result := 0;
|
|
try
|
|
SL := TStringList.Create;
|
|
{replace points with commas}
|
|
for i := 1 to Length(sIp) do
|
|
if sIp[i] = '.' then
|
|
sIp[i] := ',';
|
|
{put in stringlist to split into separate strings}
|
|
SL.CommaText := sIp;
|
|
Result := 0;
|
|
{make a value from the individual parts}
|
|
with SL do
|
|
for i := 0 to Count - 1 do
|
|
Result := (Result * $100) + StrToInt(Strings[i]);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(E, 'Fail .. IPToDWORD()');
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function DWORDToIP(IPDWord: DWORD; bBig: Boolean = true) : String;
|
|
begin
|
|
if bBig then
|
|
begin
|
|
Result := Format('%d.%d.%d.%d', [(IPDWord div $1000000),
|
|
(IPDWord div $10000) mod $100,
|
|
(IPDWord div $100) mod $100,
|
|
IPDWord mod $100]);
|
|
end else begin
|
|
Result := Format('%d.%d.%d.%d', [IPDWord mod $100,
|
|
(IPDWord div $100) mod $100,
|
|
(IPDWord div $10000) mod $100,
|
|
(IPDWord div $1000000)]);
|
|
end;
|
|
end;
|
|
|
|
function IncIP(sIp: String; nInc: Integer = 1): String;
|
|
begin
|
|
Result := DWORDToIP(IPToDWord(sIp) + nInc)
|
|
end;
|
|
|
|
function IsValidIP(const sIp: String; bIgrIpNull: Boolean = true; bIncIPv6: Boolean = false): Boolean;
|
|
var
|
|
StrList: TStringList;
|
|
str: String;
|
|
nNum: Integer;
|
|
begin
|
|
Result := false;
|
|
if (sIp = '') or (bIgrIpNull and (sIp = IP_NULL)) then
|
|
exit;
|
|
|
|
if Pos('.', sIp) > 0 then
|
|
begin
|
|
// ipv4
|
|
Guard(StrList, TStringList.Create);
|
|
SplitString(sIp, '.', StrList);
|
|
|
|
if StrList.Count <> 4 then
|
|
exit;
|
|
|
|
for str in StrList do
|
|
begin
|
|
nNum := StrToIntDef(str, -1);
|
|
if (nNum < 0) or (nNum > 255) then
|
|
exit;
|
|
end;
|
|
end else begin
|
|
if not bIncIPv6 then
|
|
exit;
|
|
// ipv6
|
|
Guard(StrList, TStringList.Create);
|
|
SplitString(sIp, ':', StrList);
|
|
|
|
if StrList.Count <> 8 then
|
|
exit;
|
|
|
|
// todo : 자세히 체크
|
|
end;
|
|
Result := true;
|
|
end;
|
|
|
|
function IsValidIPEx(const sIp: String): Boolean;
|
|
var
|
|
lstStr: TStringList;
|
|
str: AnsiString;
|
|
nNum: Integer;
|
|
begin
|
|
Result := false;
|
|
|
|
if sIp = '*' then
|
|
begin
|
|
Result := true;
|
|
exit;
|
|
end;
|
|
|
|
Guard(lstStr, TStringList.Create);
|
|
lstStr.CommaText := StringReplace(sIp, '.', ',', [rfReplaceAll]);
|
|
|
|
if lstStr.Count > 4 then
|
|
exit;
|
|
|
|
if (lstStr.Count = 1) and (lstStr[0] <> '*') then
|
|
exit;
|
|
|
|
if (lstStr.Count < 4) and (lstStr[lstStr.Count-1] <> '*') then
|
|
exit;
|
|
|
|
for str in lstStr do
|
|
begin
|
|
if str = '*' then
|
|
continue;
|
|
|
|
nNum := StrToIntDef(str, -1);
|
|
if (nNum < 0) or (nNum > 255) then
|
|
exit;
|
|
end;
|
|
Result := true;
|
|
end;
|
|
|
|
// 아이피 범위 문법인지 확인 22_1011 14:00:30 kku
|
|
// 10.0.0.1-127.0.0.1
|
|
function IsValidIpRange(sIpRange: String): Boolean;
|
|
var
|
|
n: Integer;
|
|
sEnd: String;
|
|
begin
|
|
Result := false;
|
|
n := Pos('-', sIpRange);
|
|
if n > 0 then
|
|
begin
|
|
sEnd := Copy(sIpRange, n + 1, Length(sIpRange) - n);
|
|
Delete(sIpRange, n, Length(sIpRange) - n + 1);
|
|
Result := IsValidIP(sIpRange, false) and IsValidIP(sEnd) and
|
|
(IPToDWORD(sIpRange) < IPToDWORD(sEnd));
|
|
end;
|
|
end;
|
|
|
|
function IsIncludeIP(const sIpEx, sIp: String): Boolean;
|
|
var
|
|
lstSrcStr,
|
|
lstDecStr: TStringList;
|
|
i, nCheckCnt: Integer;
|
|
begin
|
|
Result := false;
|
|
|
|
if (sIpEx = '*') or (sIp = '*') then
|
|
begin
|
|
Result := true;
|
|
exit;
|
|
end;
|
|
|
|
Guard(lstSrcStr, TStringList.Create);
|
|
lstSrcStr.CommaText := StringReplace(sIpEx, '.', ',', [rfReplaceAll]);
|
|
Guard(lstDecStr, TStringList.Create);
|
|
lstDecStr.CommaText := StringReplace(sIp, '.', ',', [rfReplaceAll]);
|
|
|
|
if lstSrcStr.Count < lstDecStr.Count then
|
|
nCheckCnt := lstSrcStr.Count
|
|
else
|
|
nCheckCnt := lstDecStr.Count;
|
|
|
|
if (nCheckCnt > 0) and (nCheckCnt < 5) then
|
|
begin
|
|
for i := 0 to nCheckCnt - 1 do
|
|
begin
|
|
if (lstSrcStr[i] = '*') or (lstDecStr[i] = '*') then
|
|
continue;
|
|
|
|
if lstSrcStr[i] <> lstDecStr[i] then
|
|
exit;
|
|
end;
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
function ConvSsidToStr(aSrc: array of Byte; nSize: Integer): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if nSize = 0 then
|
|
begin
|
|
Result := '000000000000';
|
|
exit;
|
|
end else
|
|
Result := '';
|
|
|
|
for i := 0 to nSize - 1 do
|
|
Result := Result + IntToHex(aSrc[i], 2);
|
|
end;
|
|
|
|
function ConvMACAddrToStr(MacAddress: TMacAddress; nSize: Integer): String;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if nSize = 0 then
|
|
begin
|
|
Result := '000000000000';
|
|
exit;
|
|
end else
|
|
Result := '';
|
|
|
|
for i := 1 to nSize do
|
|
Result := Result + IntToHex(MacAddress[i], 2);
|
|
end;
|
|
|
|
function GetHostIP: String;
|
|
var
|
|
wVersionRequested : WORD;
|
|
wsaData: TWSAData;
|
|
sHostName: array[0..127] of AnsiChar;
|
|
pHEnt: PHostEnt;
|
|
p: PAnsiChar;
|
|
|
|
sIp,
|
|
sPath: String;
|
|
ss: TStringStream;
|
|
IPList: TStringList;
|
|
i: Integer;
|
|
begin
|
|
try
|
|
Result := '';
|
|
ZeroMemory(@sHostName, SizeOf(sHostName));
|
|
wVersionRequested := MAKEWORD(1, 1);
|
|
WSAStartup(wVersionRequested, wsaData);
|
|
|
|
try
|
|
GetHostName(@sHostName, 128);
|
|
pHEnt := GetHostByName(@sHostName);
|
|
|
|
if pHEnt <> nil then
|
|
begin
|
|
p := inet_ntoa(PInAddr(pHEnt^.h_addr_list^)^);
|
|
Result := AnsiString(p);
|
|
end;
|
|
finally
|
|
WSACleanup;
|
|
end;
|
|
|
|
// 가끔 127.0.0.1 로 잡히는 알수없는 상황이 발생한다...
|
|
// 그래서 아래처럼 보완
|
|
if Result = '127.0.0.1' then
|
|
begin
|
|
Guard(IPList, TStringList.Create);
|
|
if GetIPAddrsToList(IPList) > 0 then
|
|
begin
|
|
for i := 0 to IPList.Count - 1 do
|
|
begin
|
|
if IPList[i] <> Result then
|
|
begin
|
|
Result := IPList[i];
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetHostIP()');
|
|
end;
|
|
end;
|
|
|
|
function GetHostIPsFromDomain(sDomain: AnsiString; sDm: AnsiString = ','): AnsiString;
|
|
var
|
|
wVersionRequested : WORD;
|
|
wsaData: TWSAData;
|
|
pHEnt: PHostEnt;
|
|
pNext: PPAnsiChar;
|
|
sIp: PAnsiChar;
|
|
begin
|
|
try
|
|
Result := '';
|
|
wVersionRequested := MAKEWORD(1, 1);
|
|
// wVersionRequested := MAKEWORD(2, 2);
|
|
WSAStartup(wVersionRequested, wsaData);
|
|
|
|
try
|
|
pHEnt := GetHostByName(PAnsiChar(sDomain));
|
|
|
|
if pHEnt <> nil then
|
|
begin
|
|
pNext := PPAnsiChar(pHEnt^.h_addr_list);
|
|
while pNext^ <> nil do
|
|
begin
|
|
sIp := inet_ntoa(PInAddr(pNext^)^);
|
|
SumStringA(Result, sIp, sDm);
|
|
Inc(pNext);
|
|
end;
|
|
end;
|
|
finally
|
|
WSACleanup;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetHostIPsFromDomain()');
|
|
end;
|
|
end;
|
|
|
|
function GetIPAddrsToList(lstIP: TStrings): Integer;
|
|
var
|
|
dwError,
|
|
dwBufLen: DWORD;
|
|
pAdapterInfo,
|
|
pAdapterWalk: PTIP_ADAPTER_INFO;
|
|
pIpAddr: PTIP_ADDR_STRING;
|
|
sIp: String;
|
|
begin
|
|
Result := 0;
|
|
|
|
dwBufLen := SizeOf(TIP_ADAPTER_INFO);
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
try
|
|
// 오버플러우일 경우 메모리 다시 할당해줘서 시도해주자 09_0706
|
|
if dwError = ERROR_BUFFER_OVERFLOW then
|
|
begin
|
|
FreeMem(pAdapterInfo, SizeOf(TIP_ADAPTER_INFO));
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
end;
|
|
|
|
if dwError = NO_ERROR then
|
|
begin
|
|
pAdapterWalk := pAdapterInfo;
|
|
|
|
while pAdapterWalk <> nil do
|
|
with pAdapterWalk^ do
|
|
begin
|
|
pIpAddr := @IPAddressList;
|
|
while pIpAddr <> nil do
|
|
begin
|
|
sIp := pIpAddr.IpAddress;
|
|
if sIp <> '0.0.0.0' then
|
|
lstIP.Add(sIp);
|
|
pIpAddr := pIpAddr.Next;
|
|
end;
|
|
pAdapterWalk := Next;
|
|
end;
|
|
end;
|
|
finally
|
|
FreeMem(pAdapterInfo, dwBufLen);
|
|
end;
|
|
Result := lstIP.Count;
|
|
end;
|
|
|
|
function GetIPAddrsToListEx(lstIP: TStrings): Integer;
|
|
var
|
|
dwError,
|
|
dwBufLen: DWORD;
|
|
pAdapterInfo,
|
|
pAdapterWalk: PTIP_ADAPTER_INFO;
|
|
pIpAddr: PTIP_ADDR_STRING;
|
|
sIp: AnsiString;
|
|
begin
|
|
Result := 0;
|
|
lstIP.Clear;
|
|
|
|
try
|
|
dwBufLen := SizeOf(TIP_ADAPTER_INFO);
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
try
|
|
// 오버플러우일 경우 메모리 다시 할당해줘서 시도해주자 09_0706
|
|
if dwError = ERROR_BUFFER_OVERFLOW then
|
|
begin
|
|
FreeMem(pAdapterInfo, SizeOf(TIP_ADAPTER_INFO));
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
end;
|
|
|
|
if dwError = NO_ERROR then
|
|
begin
|
|
pAdapterWalk := pAdapterInfo;
|
|
|
|
while pAdapterWalk <> nil do
|
|
with pAdapterWalk^ do
|
|
begin
|
|
pIpAddr := @IPAddressList;
|
|
while pIpAddr <> nil do
|
|
begin
|
|
sIp := pIpAddr.IpAddress;
|
|
if (sIp <> '') and (sIp <> IP_NULL) then
|
|
begin
|
|
// VPN, 무선 식별 추가 19_1205 15:41:18 sunk
|
|
// case aType of
|
|
case Type_ of
|
|
MIB_IF_TYPE_PPP : sIp := 'VPN:' + sIp; // 23 : VPN
|
|
IF_TYPE_IEEE80211 : sIp := 'WLS:' + sIp; // 71 : Wireless
|
|
end;
|
|
lstIP.Add(sIp);
|
|
end;
|
|
pIpAddr := pIpAddr.Next;
|
|
end;
|
|
pAdapterWalk := Next;
|
|
end;
|
|
end;
|
|
finally
|
|
FreeMem(pAdapterInfo, dwBufLen);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetIPAddrsToListEx(), Step=%d');
|
|
end;
|
|
Result := lstIP.Count;
|
|
end;
|
|
|
|
function GetIPAddrsToCommaStr: String;
|
|
var
|
|
StrList: TStringList;
|
|
begin
|
|
Guard(StrList, TStringList.Create);
|
|
if GetIPAddrsToList(StrList) > 0 then
|
|
Result := StrList.CommaText
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function GetIPAddrsToCommaStrEx: String;
|
|
var
|
|
StrList: TStringList;
|
|
begin
|
|
Guard(StrList, TStringList.Create);
|
|
if GetIPAddrsToListEx(StrList) > 0 then
|
|
Result := StrList.CommaText
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function GetMACAddrToList(aMacList: TStrings): Boolean;
|
|
var
|
|
dwError,
|
|
dwBufLen: DWORD;
|
|
pAdapterInfo,
|
|
pAdapterWalk: PTIP_ADAPTER_INFO;
|
|
begin
|
|
Result := false;
|
|
aMacList.Clear;
|
|
|
|
try
|
|
dwBufLen := SizeOf(TIP_ADAPTER_INFO);
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
try
|
|
// 오버플러우일 경우 메모리 다시 할당해줘서 시도해주자 09_0706
|
|
if dwError = ERROR_BUFFER_OVERFLOW then
|
|
begin
|
|
FreeMem(pAdapterInfo, SizeOf(TIP_ADAPTER_INFO));
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
end;
|
|
|
|
if dwError = NO_ERROR then
|
|
begin
|
|
pAdapterWalk := pAdapterInfo;
|
|
|
|
while pAdapterWalk <> nil do
|
|
with pAdapterWalk^ do
|
|
begin
|
|
if AddressLength > 0 then
|
|
aMacList.Add(ConvMACAddrToStr(TMacAddress(Address), AddressLength));
|
|
pAdapterWalk := Next;
|
|
end;
|
|
|
|
Result := aMacList.Count > 0;
|
|
end;
|
|
finally
|
|
FreeMem(pAdapterInfo, dwBufLen);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetMACAddrToList()');
|
|
end;
|
|
end;
|
|
|
|
function GetMACAddrToCommaStr: String;
|
|
var
|
|
lstMac: TStringList;
|
|
begin
|
|
Result := '';
|
|
Guard(lstMac, TStringList.Create);
|
|
if GetMACAddrToList(lstMac) then
|
|
Result := lstMac.CommaText;
|
|
end;
|
|
|
|
function GetMACAddr: String;
|
|
var
|
|
UuidCreateFunc: function (var guid: TGUID): HResult; stdcall;
|
|
hLib: THandle;
|
|
GUID: TGUID;
|
|
WinVer: TOSVersionInfo;
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
|
|
try
|
|
WinVer.dwOSVersionInfoSize := SizeOf(WinVer);
|
|
GetVersionEx(WinVer);
|
|
|
|
hLib := LoadLibrary('RPCRT4.DLL');
|
|
try
|
|
if WinVer.dwMajorVersion >= 5 then {Windows 2000 }
|
|
@UuidCreateFunc := GetProcAddress(hLib, 'UuidCreateSequential')
|
|
else
|
|
@UuidCreateFunc := GetProcAddress(hLib, 'UuidCreate') ;
|
|
|
|
UuidCreateFunc(GUID);
|
|
for i := 2 to 7 do
|
|
Result := Result + IntToHex(GUID.D4[i], 2);
|
|
finally
|
|
FreeLibrary(hLib);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetMACAddr()');
|
|
end;
|
|
end;
|
|
|
|
function GetMACAddrUsing: String;
|
|
var
|
|
dwError,
|
|
dwBufLen : DWORD;
|
|
pAdapterWalk,
|
|
pAdapterInfo : PTIP_ADAPTER_INFO;
|
|
sIp : AnsiString;
|
|
begin
|
|
Result := '';
|
|
try
|
|
sIp := GetHostIP;
|
|
|
|
if sIp = '' then
|
|
exit;
|
|
|
|
dwBufLen := SizeOf(TIP_ADAPTER_INFO);
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
try
|
|
// 오버플러우일 경우 메모리 다시 할당해줘서 시도해주자 09_0706
|
|
if dwError = ERROR_BUFFER_OVERFLOW then
|
|
begin
|
|
FreeMem(pAdapterInfo, SizeOf(TIP_ADAPTER_INFO));
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
end;
|
|
|
|
if dwError = NO_ERROR then
|
|
begin
|
|
pAdapterWalk := pAdapterInfo;
|
|
while pAdapterWalk <> nil do
|
|
begin
|
|
with pAdapterWalk^ do
|
|
begin
|
|
if (AddressLength > 0) and
|
|
(AnsiString(IPAddressList.IpAddress.S) = sIp) then
|
|
begin
|
|
Result := ConvMACAddrToStr(TMacAddress(Address), AddressLength);
|
|
exit;
|
|
end;
|
|
pAdapterWalk := Next;
|
|
end
|
|
end;
|
|
end;
|
|
finally
|
|
FreeMem(pAdapterInfo, dwBufLen);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetMACAddrUsing()');
|
|
end;
|
|
end;
|
|
|
|
function ExtractIPPort(sSrcIPort: String; var sIp: String; var nPort: Integer): Boolean;
|
|
var
|
|
nPos: Integer;
|
|
begin
|
|
Result := false;
|
|
sIp := '';
|
|
nPort := 0;
|
|
|
|
nPos := Pos(':', sSrcIPort);
|
|
if nPos > 0 then
|
|
begin
|
|
sIp := sSrcIPort;
|
|
nPort := StrToIntDef(Copy(sIp, nPos + 1, Length(sIp) - nPos), 0);
|
|
Delete(sIp, nPos, Length(sIp) - nPos + 1);
|
|
Result := IsValidIP(sIp);
|
|
if not Result then
|
|
begin
|
|
sIp := '';
|
|
nPort := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetNetDrives(aDrives: TStrings): Integer;
|
|
const
|
|
NET_BUFSIZE = 16384;
|
|
var
|
|
hEnum: THandle;
|
|
dwResult,
|
|
dwEntries,
|
|
dwBufSize: DWORD;
|
|
pBuf,
|
|
pDriveRes: PNetResource;
|
|
i: Integer;
|
|
begin
|
|
Result := 0;
|
|
aDrives.Clear;
|
|
|
|
hEnum := 0;
|
|
dwResult := WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, nil, hEnum);
|
|
if dwResult = NO_ERROR then
|
|
begin
|
|
dwEntries := $FFFFFFFF;
|
|
dwBufSize := NET_BUFSIZE;
|
|
Guard(pBuf, AllocMem(dwBufSize));
|
|
|
|
try
|
|
repeat
|
|
dwResult := WNetEnumResource(hEnum, dwEntries, pBuf, dwBufSize);
|
|
case dwResult of
|
|
NO_ERROR :
|
|
begin
|
|
pDriveRes := pBuf;
|
|
for i := 0 to dwEntries - 1 do
|
|
try
|
|
if pDriveRes.lpLocalName <> '' then
|
|
begin
|
|
aDrives.Add(UpperCase(pDriveRes.lpLocalName));
|
|
Inc(Result);
|
|
end;
|
|
finally
|
|
Inc(pDriveRes);
|
|
end;
|
|
end;
|
|
ERROR_NO_MORE_ITEMS : ;
|
|
else break;
|
|
end;
|
|
until dwResult = ERROR_NO_MORE_ITEMS;
|
|
finally
|
|
WNetCloseEnum(hEnum);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function NetDriveToRemoteAddr(sNDrv: String): String;
|
|
const
|
|
NET_BUFSIZE = 16384;
|
|
var
|
|
hEnum: THandle;
|
|
dwResult,
|
|
dwEntries,
|
|
dwBufSize: DWORD;
|
|
pBuf,
|
|
pDriveRes: PNetResource;
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
if sNDrv = '' then
|
|
exit;
|
|
sNDrv := UpperCase(sNDrv);
|
|
|
|
hEnum := 0;
|
|
dwResult := WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, nil, hEnum);
|
|
if dwResult = NO_ERROR then
|
|
begin
|
|
dwEntries := $FFFFFFFF;
|
|
dwBufSize := NET_BUFSIZE;
|
|
Guard(pBuf, AllocMem(dwBufSize));
|
|
|
|
try
|
|
repeat
|
|
dwResult := WNetEnumResource(hEnum, dwEntries, pBuf, dwBufSize);
|
|
case dwResult of
|
|
NO_ERROR :
|
|
begin
|
|
pDriveRes := pBuf;
|
|
for i := 0 to dwEntries - 1 do
|
|
try
|
|
if (pDriveRes.lpLocalName <> '') and
|
|
(UpperCase(pDriveRes.lpLocalName)[1] = sNDrv[1]) then
|
|
begin
|
|
Result := pDriveRes.lpRemoteName;
|
|
exit;
|
|
end;
|
|
finally
|
|
Inc(pDriveRes);
|
|
end;
|
|
end;
|
|
ERROR_NO_MORE_ITEMS : ;
|
|
else break;
|
|
end;
|
|
until dwResult = ERROR_NO_MORE_ITEMS;
|
|
finally
|
|
WNetCloseEnum(hEnum);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function IsNetDrive(cLetter: Char): Boolean;
|
|
var
|
|
NetDriveList: TStringList;
|
|
begin
|
|
cLetter := UpCase(cLetter);
|
|
Guard(NetDriveList, TStringList.Create);
|
|
Result := GetNetDrives(NetDriveList) > 0;
|
|
if Result then
|
|
Result := NetDriveList.IndexOf(Format('%s:', [cLetter])) <> -1;
|
|
end;
|
|
|
|
function GetNicEnable(sDesc: String): Boolean;
|
|
var
|
|
hDev: HDEVINFO;
|
|
sdd: TSPDevInfoData;
|
|
i: Integer;
|
|
dwBufSize,
|
|
dwStatus, dwProblem,
|
|
dwPropertyRegDataType: DWORD;
|
|
pBuf: Pointer;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
hDev := SetupDiGetClassDevs(@GUID_DEVCLASS_NET, nil, 0, DIGCF_PRESENT);
|
|
if hDev = INVALID_HANDLE_VALUE then
|
|
exit;
|
|
|
|
pBuf := nil;
|
|
try
|
|
ZeroMemory(@sdd, SizeOf(sdd));
|
|
sdd.cbSize := SizeOf(sdd);
|
|
|
|
i := 0;
|
|
while SetupDiEnumDeviceInfo(hDev, i, sdd) do
|
|
begin
|
|
dwBufSize := 0;
|
|
if pBuf <> nil then
|
|
begin
|
|
FreeMem(pBuf);
|
|
pBuf := nil;
|
|
end;
|
|
|
|
while not SetupDiGetDeviceRegistryProperty(hDev, sdd,
|
|
SPDRP_DEVICEDESC, dwPropertyRegDataType, pBuf, dwBufSize, dwBufSize) do
|
|
begin
|
|
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
|
|
begin
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
pBuf := AllocMem(dwBufSize);
|
|
end else break;
|
|
end;
|
|
|
|
if pBuf <> nil then
|
|
begin
|
|
if CompareText(sDesc, String(PChar(pBuf))) = 0 then
|
|
begin
|
|
dwStatus := 0;
|
|
dwProblem := 0;
|
|
|
|
if CM_Get_DevNode_Status(dwStatus, dwProblem, sdd.DevInst, 0) = CR_SUCCESS then
|
|
Result := not (((dwStatus and DN_HAS_PROBLEM) = 0) and (dwProblem = CM_PROB_DISABLED));
|
|
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
Inc(i);
|
|
end;
|
|
|
|
finally
|
|
SetupDiDestroyDeviceInfoList(hDev);
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. SetNicEnable()');
|
|
end;
|
|
end;
|
|
|
|
function SetNicEnable(sDesc: String; bVal: Boolean): Integer;
|
|
var
|
|
hDev: HDEVINFO;
|
|
sdd: TSPDevInfoData;
|
|
i: Integer;
|
|
dwBufSize,
|
|
dwStatus, dwProblem,
|
|
dwPropertyRegDataType: DWORD;
|
|
pBuf: Pointer;
|
|
begin
|
|
Result := -1;
|
|
|
|
try
|
|
hDev := SetupDiGetClassDevs(@GUID_DEVCLASS_NET, nil, 0, DIGCF_PRESENT);
|
|
if hDev = INVALID_HANDLE_VALUE then
|
|
exit;
|
|
|
|
pBuf := nil;
|
|
try
|
|
ZeroMemory(@sdd, SizeOf(sdd));
|
|
sdd.cbSize := SizeOf(sdd);
|
|
|
|
i := 0;
|
|
while SetupDiEnumDeviceInfo(hDev, i, sdd) do
|
|
begin
|
|
dwBufSize := 0;
|
|
if pBuf <> nil then
|
|
begin
|
|
FreeMem(pBuf);
|
|
pBuf := nil;
|
|
end;
|
|
|
|
while not SetupDiGetDeviceRegistryProperty(hDev, sdd,
|
|
SPDRP_FRIENDLYNAME, dwPropertyRegDataType, pBuf, dwBufSize, dwBufSize) do
|
|
begin
|
|
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
|
|
begin
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
pBuf := AllocMem(dwBufSize);
|
|
end else break;
|
|
end;
|
|
|
|
if pBuf <> nil then
|
|
begin
|
|
if CompareText(sDesc, String(PChar(pBuf))) = 0 then
|
|
begin
|
|
dwStatus := 0;
|
|
dwProblem := 0;
|
|
|
|
if CM_Get_DevNode_Status(dwStatus, dwProblem, sdd.DevInst, 0) = CR_SUCCESS then
|
|
begin
|
|
// var bDisabled: Boolean := (((dwStatus and DN_HAS_PROBLEM) = 0) and (dwProblem = CM_PROB_DISABLED));
|
|
// if bVal = bDisabled then
|
|
begin
|
|
var PropChangeParams: TSPPropChangeParams;
|
|
ZeroMemory(@PropChangeParams, SizeOf(PropChangeParams));
|
|
PropChangeParams.ClassInstallHeader.cbSize := SizeOf(TSPClassInstallHeader);
|
|
PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
|
|
PropChangeParams.Scope := DICS_FLAG_GLOBAL;
|
|
PropChangeParams.StateChange := BooleanToInt(bVal, DICS_ENABLE, DICS_DISABLE);
|
|
|
|
if SetupDiSetClassInstallParams(hDev, @sdd, PSPClassInstallHeader(@PropChangeParams), SizeOf(PropChangeParams)) then
|
|
begin
|
|
// 64bit OS 에서는 64bit 프로그램 에서만 실행 가능하다 22_0621 13:59:21 kku
|
|
if SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDev, @sdd) then
|
|
Result := i;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
Inc(i);
|
|
end;
|
|
|
|
finally
|
|
SetupDiDestroyDeviceInfoList(hDev);
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. SetNicEnable()');
|
|
end;
|
|
end;
|
|
|
|
function SetNicEnableByIndex(nIdx: Integer; bVal: Boolean): Boolean;
|
|
var
|
|
hDev: HDEVINFO;
|
|
sdd: TSPDevInfoData;
|
|
dwBufSize,
|
|
dwStatus, dwProblem,
|
|
dwPropertyRegDataType: DWORD;
|
|
pBuf: Pointer;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
hDev := SetupDiGetClassDevs(@GUID_DEVCLASS_NET, nil, 0, DIGCF_PRESENT);
|
|
if hDev = INVALID_HANDLE_VALUE then
|
|
exit;
|
|
|
|
pBuf := nil;
|
|
try
|
|
ZeroMemory(@sdd, SizeOf(sdd));
|
|
sdd.cbSize := SizeOf(sdd);
|
|
|
|
if SetupDiEnumDeviceInfo(hDev, nIdx, sdd) then
|
|
begin
|
|
dwBufSize := 0;
|
|
if pBuf <> nil then
|
|
begin
|
|
FreeMem(pBuf);
|
|
pBuf := nil;
|
|
end;
|
|
|
|
while not SetupDiGetDeviceRegistryProperty(hDev, sdd,
|
|
SPDRP_FRIENDLYNAME, dwPropertyRegDataType, pBuf, dwBufSize, dwBufSize) do
|
|
begin
|
|
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
|
|
begin
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
pBuf := AllocMem(dwBufSize);
|
|
end else break;
|
|
end;
|
|
|
|
if pBuf <> nil then
|
|
begin
|
|
dwStatus := 0;
|
|
dwProblem := 0;
|
|
|
|
if CM_Get_DevNode_Status(dwStatus, dwProblem, sdd.DevInst, 0) = CR_SUCCESS then
|
|
begin
|
|
var PropChangeParams: TSPPropChangeParams;
|
|
ZeroMemory(@PropChangeParams, SizeOf(PropChangeParams));
|
|
PropChangeParams.ClassInstallHeader.cbSize := SizeOf(TSPClassInstallHeader);
|
|
PropChangeParams.ClassInstallHeader.InstallFunction := DIF_PROPERTYCHANGE;
|
|
PropChangeParams.Scope := DICS_FLAG_GLOBAL;
|
|
PropChangeParams.StateChange := BooleanToInt(bVal, DICS_ENABLE, DICS_DISABLE);
|
|
|
|
if SetupDiSetClassInstallParams(hDev, @sdd, PSPClassInstallHeader(@PropChangeParams), SizeOf(PropChangeParams)) then
|
|
begin
|
|
// 64bit OS 에서는 64bit 프로그램 에서만 실행 가능하다 22_0621 13:59:21 kku
|
|
Result := SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDev, @sdd);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
SetupDiDestroyDeviceInfoList(hDev);
|
|
if pBuf <> nil then
|
|
FreeMem(pBuf);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. SetNicEnable()');
|
|
end;
|
|
end;
|
|
|
|
{ TNetAdapterInfo }
|
|
|
|
Constructor TNetAdapterInfo.Create;
|
|
begin
|
|
Inherited Create;
|
|
AdapterList_ := TNetAdapterEntList.Create;
|
|
AdapterList_.OnNotify := OnAdapterNotify;
|
|
UpdateNetAdapterInfo;
|
|
end;
|
|
|
|
Destructor TNetAdapterInfo.Destroy;
|
|
begin
|
|
FreeAndNil(AdapterList_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TNetAdapterInfo.OnAdapterNotify(Sender: TObject; const Item: PNetAdapterEnt;
|
|
Action: TCollectionNotification);
|
|
begin
|
|
case Action of
|
|
cnAdded: ;
|
|
cnRemoved: Dispose(Item);
|
|
cnExtracted: ;
|
|
end;
|
|
end;
|
|
|
|
function TNetAdapterInfo.GetByIndex(nIndex: Integer): PNetAdapterEnt;
|
|
begin
|
|
if (nIndex > -1) and (nIndex < AdapterList_.Count) then
|
|
Result := AdapterList_[nIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TNetAdapterInfo.UpdateNetAdapterInfo;
|
|
|
|
function GetIpAddrs(pIpAddr: PTIP_ADDR_STRING): String;
|
|
begin
|
|
Result := '';
|
|
while pIpAddr <> nil do
|
|
begin
|
|
SumString(Result, pIpAddr.IpAddress, ',');
|
|
pIpAddr := pIpAddr.Next;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
dwError,
|
|
dwBufLen: DWORD;
|
|
pAdapterInfo,
|
|
pAdapterWalk: PTIP_ADAPTER_INFO;
|
|
pEnt: PNetAdapterEnt;
|
|
begin
|
|
AdapterList_.Clear;
|
|
|
|
dwBufLen := SizeOf(TIP_ADAPTER_INFO);
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
try
|
|
// 오버플러우일 경우 메모리 다시 할당해줘서 시도해주자 09_0706
|
|
if dwError = ERROR_BUFFER_OVERFLOW then
|
|
begin
|
|
FreeMem(pAdapterInfo, SizeOf(TIP_ADAPTER_INFO));
|
|
pAdapterInfo := AllocMem(dwBufLen);
|
|
dwError := GetAdaptersInfo(pAdapterInfo, @dwBufLen);
|
|
end;
|
|
|
|
if dwError = NO_ERROR then
|
|
begin
|
|
pAdapterWalk := pAdapterInfo;
|
|
|
|
while pAdapterWalk <> nil do
|
|
begin
|
|
New(pEnt);
|
|
ZeroMemory(pEnt, SizeOf(TNetAdapterEnt));
|
|
with pAdapterWalk^ do
|
|
begin
|
|
pEnt.sName := AdapterName;
|
|
pEnt.sDesc := Description;
|
|
if AddressLength > 0 then
|
|
pEnt.sMacAddr := UpperCase(ConvMACAddrToStr(TMacAddress(Address), AddressLength));
|
|
// pEnt.sCurIpAddr := GetIpAddrs(CurrentIPAddress);
|
|
pEnt.sIpAddrs := GetIpAddrs(@IPAddressList);
|
|
pEnt.sGatewayIps := GetIpAddrs(@GatewayList);
|
|
pEnt.sDHCPServer := GetIpAddrs(@DHCPServer);
|
|
pEnt.sPriWINSServer := GetIpAddrs(@PrimaryWINSServer);
|
|
pEnt.sSecWINSServer := GetIpAddrs(@SecondaryWINSServer);
|
|
pEnt.bDHCP := DHCPEnabled <> 0;
|
|
pEnt.bHaveWINS := HaveWINS;
|
|
pEnt.dwComboIdx := ComboIndex;
|
|
pEnt.dwIndex := Index;
|
|
// pEnt.dwType := aType;
|
|
pEnt.dwType := Type_;
|
|
|
|
pAdapterWalk := Next;
|
|
end;
|
|
AdapterList_.Add(pEnt);
|
|
end;
|
|
end;
|
|
finally
|
|
FreeMem(pAdapterInfo, dwBufLen);
|
|
end;
|
|
end;
|
|
|
|
function TNetAdapterInfo.Count: Integer;
|
|
begin
|
|
Result := AdapterList_.Count;
|
|
end;
|
|
|
|
{ TWlanInfo }
|
|
|
|
Constructor TWlanInfo.Create;
|
|
begin
|
|
Inherited Create;
|
|
WLanEntList_ := TWLanEntList.Create;
|
|
WLanEntList_.OnNotify := OnWlanEntNotify;
|
|
UpdateWlanInfo;
|
|
end;
|
|
|
|
Destructor TWlanInfo.Destroy;
|
|
begin
|
|
FreeAndNil(WLanEntList_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TWlanInfo.OnWlanEntNotify(Sender: TObject; const Item: PWLanEnt;
|
|
Action: TCollectionNotification);
|
|
begin
|
|
if Action = cnRemoved then
|
|
Dispose(Item);
|
|
end;
|
|
|
|
procedure TWlanInfo.UpdateWlanInfo;
|
|
const
|
|
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES = $00000001;
|
|
var
|
|
hClient: THandle;
|
|
dwVersion, dwResult: DWORD;
|
|
pInterface: Pndu_WLAN_INTERFACE_INFO_LIST;
|
|
i, j, c: Integer;
|
|
pAvNetList: Pndu_WLAN_AVAILABLE_NETWORK_LIST;
|
|
pBssList: Pndu_WLAN_BSS_LIST;
|
|
// pInterfaceGuid: PGUID;
|
|
InfcInfo: Tndu_WLAN_INTERFACE_INFO;
|
|
sBssid: String;
|
|
// sInterface: String;
|
|
pInfo: PWLanEnt;
|
|
begin
|
|
try
|
|
WLanEntList_.Clear;
|
|
hClient := 0;
|
|
pInterface := nil;
|
|
dwResult := WlanOpenHandle(NDU_WLAN_API_VERSION, nil, @dwVersion, @hClient);
|
|
try
|
|
if dwResult <> ERROR_SUCCESS then
|
|
begin
|
|
_Trace(Format('Error Open Client %d', [dwResult]));
|
|
exit;
|
|
end;
|
|
|
|
dwResult := WlanEnumInterfaces(hClient, nil, @pInterface);
|
|
if dwResult <> ERROR_SUCCESS then
|
|
begin
|
|
_Trace('Error Enum Interfaces ' + IntToStr(dwResult));
|
|
Exit;
|
|
end;
|
|
|
|
if pInterface.dwNumberOfItems = 0 then
|
|
exit;
|
|
|
|
for i := 0 to pInterface.dwNumberOfItems - 1 do
|
|
begin
|
|
InfcInfo := pInterface.InterfaceInfo[i];
|
|
// sInterface := pInterface.InterfaceInfo[i].strInterfaceDescription;
|
|
// pInterfaceGuid := @pInterface.InterfaceInfo[pInterface.dwIndex].InterfaceGuid;
|
|
|
|
dwResult := WlanGetAvailableNetworkList(hClient, @InfcInfo.InterfaceGuid, // pInterfaceGuid,
|
|
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES, nil, pAvNetList);
|
|
if dwResult <> ERROR_SUCCESS then
|
|
begin
|
|
_Trace('Error WlanGetAvailableNetworkList, Idx=%d, Error=%d', [i, dwResult], 1);
|
|
continue;
|
|
end;
|
|
|
|
if pAvNetList.dwNumberOfItems = 0 then
|
|
continue;
|
|
|
|
for j := 0 to pAvNetList.dwNumberOfItems - 1 do
|
|
Begin
|
|
if j > High(pAvNetList.Network) then
|
|
break;
|
|
|
|
New(pInfo);
|
|
pInfo.sName := InfcInfo.strInterfaceDescription; // sInterface;
|
|
pInfo.sProfile := pAvNetList.Network[j].strProfileName;
|
|
pInfo.sBssid := '';
|
|
pInfo.nQuality := pAvNetList.Network[j].wlanSignalQuality;
|
|
pInfo.dwAlgo1 := pAvNetList.Network[j].dot11DefaultAuthAlgorithm;
|
|
pInfo.dwAlgo2 := pAvNetList.Network[j].dot11DefaultCipherAlgorithm;
|
|
pInfo.bSecurety := pAvNetList.Network[j].bSecurityEnabled;
|
|
pInfo.InterfaceGuid := InfcInfo.InterfaceGuid; // pInterfaceGuid^;
|
|
|
|
// 아래 bssid 가져오기 잘되는데 일단 막아놓음 25_0715 15:17:45 kku
|
|
// cmd : netsh wlan show interfaces
|
|
(*
|
|
pBssList := nil;
|
|
if WlanGetNetworkBssList(hClient, @pInterface.InterfaceInfo[i].InterfaceGuid,
|
|
{@pAvNetList.Network[j].dot11Ssid}nil, dot11_BSS_type_infrastructure,
|
|
true, nil, @pBssList) = ERROR_SUCCESS then
|
|
begin
|
|
if pBssList.dwNumberOfItems > 0 then
|
|
begin
|
|
for c := 0 to High(pBssList.wlanBssEntries) do
|
|
begin
|
|
with pBssList.wlanBssEntries[c] do
|
|
sBssid := Format('%.2x:%.2x:%.2x:%.2x:%.2x:%.2x',
|
|
[dot11Bssid[0], dot11Bssid[1], dot11Bssid[2],
|
|
dot11Bssid[3], dot11Bssid[4], dot11Bssid[5]]);
|
|
|
|
SumString(pInfo.sBssid, sBssid, ',');
|
|
end;
|
|
end;
|
|
|
|
if pBssList <> nil then
|
|
WlanFreeMemory(pBssList);
|
|
end;
|
|
*)
|
|
|
|
WLanEntList_.Add(pInfo);
|
|
End;
|
|
end;
|
|
finally
|
|
if pInterface <> nil then
|
|
WlanFreeMemory(pInterface);
|
|
if hClient <> 0 then
|
|
WlanCloseHandle(hClient, nil);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Error .. UpdateWlanInfo()');
|
|
end;
|
|
end;
|
|
|
|
function TWlanInfo.GetByIndex(nIndex: Integer): PWLanEnt;
|
|
begin
|
|
if (nIndex > -1) and (nIndex < WLanEntList_.Count) then
|
|
Result := WLanEntList_[nIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TWlanInfo.Count: Integer;
|
|
begin
|
|
Result := WLanEntList_.Count;
|
|
end;
|
|
|
|
function TWlanInfo.GetWlanEntByName(sName: String): PWLanEnt;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
try
|
|
for i := 0 to WLanEntList_.Count - 1 do
|
|
if CompareText(WLanEntList_[i].sName, sName) = 0 then
|
|
begin
|
|
Result := WLanEntList_[i];
|
|
exit;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Error .. GetWlanEntByName()');
|
|
end;
|
|
end;
|
|
|
|
{ TTcpTableInfo }
|
|
|
|
Constructor TTcpTableInfo.Create;
|
|
begin
|
|
Inherited Create;
|
|
TcpEnts_ := TTcpInfoEntList.Create;
|
|
TcpEnts_.OnNotify := OnTcpInfoEntNotify;
|
|
end;
|
|
|
|
Destructor TTcpTableInfo.Destroy;
|
|
begin
|
|
FreeAndNil(TcpEnts_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TTcpTableInfo.OnTcpInfoEntNotify(Sender: TObject; const
|
|
Item: PTcpInfoEnt; Action: TCollectionNotification);
|
|
begin
|
|
case Action of
|
|
cnAdded: ;
|
|
cnRemoved: Dispose(Item);
|
|
cnExtracted: ;
|
|
end;
|
|
end;
|
|
|
|
procedure TTcpTableInfo.UpdateTcpTableInfo;
|
|
var
|
|
dwResult,
|
|
dtTableSize: DWORD;
|
|
i: Integer;
|
|
IpAddress: in_addr;
|
|
pTcpTable: PMIB_TCPTABLE_OWNER_PID;
|
|
pEnt: PTcpInfoEnt;
|
|
begin
|
|
TcpEnts_.Clear;
|
|
|
|
dtTableSize := 0;
|
|
dwResult := GetExtendedTcpTable(nil, @dtTableSize, False, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
|
|
if dwResult <> ERROR_INSUFFICIENT_BUFFER then
|
|
exit;
|
|
|
|
Guard(pTcpTable, AllocMem(dtTableSize));
|
|
if GetExtendedTcpTable(pTcpTable, @dtTableSize, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then
|
|
for i := 0 to pTcpTable.dwNumEntries - 1 do
|
|
begin
|
|
New(pEnt);
|
|
|
|
IpAddress.s_addr := pTcpTable.Table[i].dwLocalAddr;
|
|
pEnt.sLocalIpAddr := string(inet_ntoa(IpAddress));
|
|
|
|
IpAddress.s_addr := pTcpTable.Table[i].dwRemoteAddr;
|
|
pEnt.sRemoteIpAddr := string(inet_ntoa(IpAddress));
|
|
|
|
pEnt.nLocalPort := ntohs(pTcpTable.Table[i].dwLocalPort);
|
|
pEnt.nRemotePort := ntohs(pTcpTable.Table[i].dwRemotePort);
|
|
pEnt.dwPid := pTcpTable.Table[i].dwOwningPid;
|
|
pEnt.dwStatus := pTcpTable.Table[i].dwState;
|
|
|
|
TcpEnts_.Add(pEnt);
|
|
end;
|
|
end;
|
|
|
|
function TTcpTableInfo.Count: Integer;
|
|
begin
|
|
Result := TcpEnts_.Count;
|
|
end;
|
|
|
|
procedure TTcpTableInfo.Delete(nIndex: Integer);
|
|
begin
|
|
if (nIndex > -1) and (nIndex < TcpEnts_.Count) then
|
|
TcpEnts_.Delete(nIndex);
|
|
end;
|
|
|
|
function TTcpTableInfo.GetByIndex(nIndex: Integer): PTcpInfoEnt;
|
|
begin
|
|
if (nIndex > -1) and (nIndex < TcpEnts_.Count) then
|
|
Result := TcpEnts_[nIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TUdpTableInfo }
|
|
|
|
Constructor TUdpTableInfo.Create;
|
|
begin
|
|
Inherited Create;
|
|
UdpEnts_ := TUdpInfoEntList.Create;
|
|
UdpEnts_.OnNotify := OnUdpInfoEntNotify;
|
|
end;
|
|
|
|
Destructor TUdpTableInfo.Destroy;
|
|
begin
|
|
FreeAndNil(UdpEnts_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TUdpTableInfo.OnUdpInfoEntNotify(Sender: TObject; const Item: PUdpInfoEnt;
|
|
Action: TCollectionNotification);
|
|
begin
|
|
case Action of
|
|
cnAdded: ;
|
|
cnRemoved: Dispose(Item);
|
|
cnExtracted: ;
|
|
end;
|
|
end;
|
|
|
|
procedure TUdpTableInfo.UpdateUdpTableInfo;
|
|
var
|
|
dwResult,
|
|
dtTableSize: DWORD;
|
|
i: Integer;
|
|
IpAddress: in_addr;
|
|
pUdpTable: PMIB_UDPTABLE_OWNER_PID;
|
|
pEnt: PUdpInfoEnt;
|
|
begin
|
|
UdpEnts_.Clear;
|
|
|
|
dtTableSize := 0;
|
|
dwResult := GetExtendedUdpTable(nil, @dtTableSize, False, AF_INET, UDP_TABLE_OWNER_PID, 0);
|
|
if dwResult <> ERROR_INSUFFICIENT_BUFFER then
|
|
exit;
|
|
|
|
Guard(pUdpTable, AllocMem(dtTableSize));
|
|
if GetExtendedUdpTable(pUdpTable, @dtTableSize, true, AF_INET, UDP_TABLE_OWNER_PID, 0) = NO_ERROR then
|
|
for i := 0 to pUdpTable.dwNumEntries - 1 do
|
|
begin
|
|
New(pEnt);
|
|
|
|
IpAddress.s_addr := pUdpTable.Table[i].dwLocalAddr;
|
|
pEnt.sLocalIpAddr := string(inet_ntoa(IpAddress));
|
|
pEnt.nLocalPort := ntohs(pUdpTable.Table[i].dwLocalPort);
|
|
pEnt.dwPid := pUdpTable.Table[i].dwOwningPid;
|
|
|
|
UdpEnts_.Add(pEnt);
|
|
end;
|
|
end;
|
|
|
|
function TUdpTableInfo.Count: Integer;
|
|
begin
|
|
Result := UdpEnts_.Count;
|
|
end;
|
|
|
|
procedure TUdpTableInfo.Delete(nIndex: Integer);
|
|
begin
|
|
if (nIndex > -1) and (nIndex < UdpEnts_.Count) then
|
|
UdpEnts_.Delete(nIndex);
|
|
end;
|
|
|
|
function TUdpTableInfo.GetByIndex(nIndex: Integer): PUdpInfoEnt;
|
|
begin
|
|
if (nIndex > -1) and (nIndex < UdpEnts_.Count) then
|
|
Result := UdpEnts_[nIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
{ TSharedFolder }
|
|
|
|
Constructor TSharedFolder.Create(bUpdate: Boolean = false; sServerName: String = ''; bIgrSpecial: Boolean = false);
|
|
begin
|
|
Inherited Create;
|
|
|
|
sSvrName_ := sServerName;
|
|
if sSvrName_ = '' then
|
|
sSvrName_ := GetComName;
|
|
if bUpdate then
|
|
UpdateShdFldList(bIgrSpecial);
|
|
end;
|
|
|
|
procedure TSharedFolder.Notify(const Item: PShdFldEnt; Action: TCollectionNotification);
|
|
begin
|
|
if Action = cnRemoved then
|
|
Dispose(Item);
|
|
end;
|
|
|
|
procedure TSharedFolder.UpdateShdFldList(bIgrSpecial: Boolean = false);
|
|
const
|
|
MAX_PREFERRED_LENGTH = -1;
|
|
NERR_SUCCESS = 0;
|
|
var
|
|
EntriesRead,
|
|
TotalEntries,
|
|
ResHandle: DWORD;
|
|
ShareInfo2, P: PSHARE_INFO_2;
|
|
dwStatus: NET_API_STATUS;
|
|
i: Integer;
|
|
pEnt: PShdFldEnt;
|
|
begin
|
|
try
|
|
Clear;
|
|
{
|
|
// WMI 사용하면 메모리 릭이 발생해서 뺌. 22_1221 15:18:10 kku
|
|
if WMI_GetInformationEx('', WMI_ROOT_OBJECT, '', '', 'Win32_Share', wmiResults, nVerCnt) then
|
|
begin
|
|
for i := 0 to nVerCnt - 1 do
|
|
begin
|
|
New(pEnt);
|
|
pEnt.sName := WMI_GetPropertyData(wmiResults, 'Name', i);
|
|
pEnt.sPath := WMI_GetPropertyData(wmiResults, 'Path', i);
|
|
Add(pEnt);
|
|
end;
|
|
end;
|
|
}
|
|
ResHandle := 0;
|
|
dwStatus := NetShareEnum(PChar(sSvrName_), 2, Pointer(ShareInfo2),
|
|
DWORD(MAX_PREFERRED_LENGTH),
|
|
EntriesRead, TotalEntries, ResHandle);
|
|
try
|
|
if dwStatus <> NERR_SUCCESS then
|
|
exit;
|
|
|
|
P := ShareInfo2;
|
|
for i := 0 to TotalEntries - 1 do
|
|
begin
|
|
if bIgrSpecial then
|
|
begin
|
|
if (CompareText(P.shi2_netname, 'ADMIN$') = 0) or
|
|
(CompareText(P.shi2_netname, 'IPC$') = 0) or
|
|
(CompareText(P.shi2_netname, 'PRINT$') = 0) then
|
|
begin
|
|
Inc(P);
|
|
continue;
|
|
end;
|
|
end;
|
|
|
|
New(pEnt);
|
|
pEnt.sName := P.shi2_netname;
|
|
pEnt.sPath := P.shi2_path;
|
|
Add(pEnt);
|
|
Inc(P);
|
|
end;
|
|
finally
|
|
NetApiBufferFree(ShareInfo2);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. UpdateShdFldList()');
|
|
end;
|
|
end;
|
|
|
|
function TSharedFolder.ExistsSharedFolder(sPath: String): Boolean;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := false;
|
|
for i := 0 to Count - 1 do
|
|
begin
|
|
if CompareText(Items[i].sPath, sPath) = 0 then
|
|
begin
|
|
Result := true;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TRouteEntList }
|
|
|
|
procedure TRouteEntList.Notify(const Item: PRouteEnt; Action: TCollectionNotification);
|
|
begin
|
|
if Action = cnRemoved then
|
|
Dispose(Item);
|
|
end;
|
|
|
|
function TRouteEntList.GetEntByDestIp(sDestIp: String): PRouteEnt;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
try
|
|
for i := 0 to Count - 1 do
|
|
begin
|
|
if Items[i].sDestIp = sDestIp then
|
|
begin
|
|
Result := Items[i];
|
|
exit;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. GetEntByDestIp()');
|
|
end;
|
|
end;
|
|
|
|
{ Functions }
|
|
|
|
function GetNetAdapterTypeToStr(dwType: DWORD): String;
|
|
begin
|
|
case dwType of
|
|
MIB_IF_TYPE_OTHER : Result := RS_NetOther;
|
|
MIB_IF_TYPE_ETHERNET : Result := RS_NetEthernet;
|
|
IF_TYPE_ISO88025_TOKENRING : Result := RS_NetTokenring;
|
|
MIB_IF_TYPE_FDDI : Result := RS_NetFDDI;
|
|
MIB_IF_TYPE_PPP : Result := 'PPP';
|
|
MIB_IF_TYPE_LOOPBACK : Result := RS_NetLoop;
|
|
MIB_IF_TYPE_SLIP : Result := 'SLIP';
|
|
IF_TYPE_IEEE80211 : Result := 'IEEE 802.11 (Wireless)';
|
|
else Result := Format('Unknown (%d)', [dwType]);
|
|
end;
|
|
end;
|
|
|
|
function IsConnectedWIFI(aInterfaceGuid: TGUID): Boolean;
|
|
var
|
|
hClient: THandle;
|
|
dwVersion,
|
|
dwResult, dwSize: DWORD;
|
|
pConnInfo: Pndu_WLAN_CONNECTION_ATTRIBUTES;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
hClient := 0;
|
|
pConnInfo := nil;
|
|
dwResult := WlanOpenHandle(NDU_WLAN_API_VERSION, nil, @dwVersion, @hClient);
|
|
try
|
|
if dwResult <> ERROR_SUCCESS then
|
|
begin
|
|
TTgTrace.T(Format('Error Open Client %d', [dwResult]));
|
|
exit;
|
|
end;
|
|
|
|
dwSize := 0;
|
|
dwResult := WlanQueryInterface(
|
|
hClient,
|
|
@aInterfaceGuid,
|
|
wlan_intf_opcode_current_connection,
|
|
nil,
|
|
@dwSize,
|
|
@pConnInfo,
|
|
nil
|
|
);
|
|
|
|
if dwResult = ERROR_SUCCESS then
|
|
Result := pConnInfo.isState = wlan_interface_state_connected;
|
|
finally
|
|
if pConnInfo <> nil then
|
|
WlanFreeMemory(pConnInfo);
|
|
if hClient <> 0 then
|
|
WlanCloseHandle(hClient, nil);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. IsConnectedWIFI()');
|
|
end;
|
|
end;
|
|
|
|
function DisconnectWIFI(aInterfaceGuid: TGUID): Boolean;
|
|
var
|
|
hClient: THandle;
|
|
dwVersion, dwResult: DWORD;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
hClient := 0;
|
|
dwResult := WlanOpenHandle(NDU_WLAN_API_VERSION, nil, @dwVersion, @hClient);
|
|
try
|
|
if dwResult <> ERROR_SUCCESS then
|
|
begin
|
|
TTgTrace.T(Format('Error Open Client %d', [dwResult]));
|
|
exit;
|
|
end;
|
|
|
|
Result := WlanDisconnect(hClient, @aInterfaceGuid, nil) = ERROR_SUCCESS;
|
|
finally
|
|
if hClient <> 0 then
|
|
WlanCloseHandle(hClient, nil);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. DisconnectWIFI()');
|
|
end;
|
|
end;
|
|
|
|
function GetRouteTables(aList: TRouteEntList): Integer;
|
|
var
|
|
pTable: PTMibIPForwardTable;
|
|
dwSize: DWORD;
|
|
i: Integer;
|
|
pRow: PTMibIPForwardRow;
|
|
pEnt: PRouteEnt;
|
|
begin
|
|
Result := 0;
|
|
try
|
|
aList.Clear;
|
|
|
|
pTable := nil;
|
|
dwSize := 0;
|
|
|
|
if GetIpForwardTable(pTable, @dwSize, FALSE) <> ERROR_INSUFFICIENT_BUFFER then
|
|
exit;
|
|
|
|
pTable := AllocMem(dwSize);
|
|
try
|
|
if GetIpForwardTable(pTable, @dwSize, FALSE) <> NO_ERROR then
|
|
exit;
|
|
|
|
if pTable.dwNumEntries = 0 then
|
|
exit;
|
|
|
|
for i := 0 to pTable.dwNumEntries - 1 do
|
|
begin
|
|
pRow := PTMibIPForwardRow(LONGLONG(@pTable.Table[0]) + (i * SizeOf(TMibIPForwardRow)));
|
|
New(pEnt);
|
|
ZeroMemory(pEnt, SizeOf(TRouteEnt));
|
|
pEnt.sDestIp := DWORDToIP(pRow.dwForwardDest, false);
|
|
pEnt.Info := pRow^;
|
|
aList.Add(pEnt);
|
|
end;
|
|
|
|
Result := aList.Count;
|
|
finally
|
|
FreeMem(pTable);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetRouteTables()');
|
|
end;
|
|
end;
|
|
|
|
function GetPublicIP: string;
|
|
var
|
|
HttpClient: THTTPClient;
|
|
Response: IHTTPResponse;
|
|
begin
|
|
Result := '';
|
|
try
|
|
Guard(HttpClient, THTTPClient.Create);
|
|
Response := HttpClient.Get('http://api.ipify.org');
|
|
Result := Response.ContentAsString();
|
|
|
|
if (Result <> '') and not IsValidIP(Result) then
|
|
Result := '';
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. GetPublicIP()');
|
|
end;
|
|
end;
|
|
|
|
function RemoveEveryoneFromShare(const sShareName: string): Boolean;
|
|
const
|
|
ACCESS_ALLOWED_ACE_TYPE = 0;
|
|
ACCESS_DENIED_ACE_TYPE = 1;
|
|
SYSTEM_AUDIT_ACE_TYPE = 2;
|
|
SYSTEM_ALARM_ACE_TYPE = 3;
|
|
|
|
// ACL Revision
|
|
ACL_REVISION = 2;
|
|
ACL_REVISION_DS = 4;
|
|
|
|
type
|
|
PACE_HEADER = ^ACE_HEADER;
|
|
ACE_HEADER = packed record
|
|
AceType: Byte;
|
|
AceFlags: Byte;
|
|
AceSize: Word;
|
|
end;
|
|
|
|
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
|
|
ACCESS_ALLOWED_ACE = packed record
|
|
Header: ACE_HEADER;
|
|
Mask: ACCESS_MASK;
|
|
SidStart: DWORD; // 실제 SID가 여기부터 시작
|
|
end;
|
|
|
|
PACCESS_DENIED_ACE = ^ACCESS_DENIED_ACE;
|
|
ACCESS_DENIED_ACE = packed record
|
|
Header: ACE_HEADER;
|
|
Mask: ACCESS_MASK;
|
|
SidStart: DWORD;
|
|
end;
|
|
|
|
var
|
|
pSD: PSECURITY_DESCRIPTOR;
|
|
pDACL: PACL;
|
|
pNewDACL: PACL;
|
|
eaCount, i: DWORD;
|
|
aceHeader: PACE_HEADER;
|
|
sidEveryone: PSID;
|
|
dwAceSize: DWORD;
|
|
pAceSID: PSID;
|
|
aceAccessMask: ACCESS_MASK;
|
|
dwRes: DWORD;
|
|
begin
|
|
Result := false;
|
|
try
|
|
pSD := nil;
|
|
|
|
// 1. 공유의 보안 정보 가져오기
|
|
dwRes := GetNamedSecurityInfo(
|
|
PChar('\\localhost\' + sShareName),
|
|
SE_LMSHARE,
|
|
DACL_SECURITY_INFORMATION,
|
|
nil, nil,
|
|
@pDACL,
|
|
nil,
|
|
pSD
|
|
);
|
|
|
|
if dwRes <> ERROR_SUCCESS then
|
|
begin
|
|
TTgTrace.T('GetNamedSecurityInfo failed: %d', [dwRes]);
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
// 2. Everyone SID 생성
|
|
if not ConvertStringSidToSid('S-1-1-0', sidEveryone) then
|
|
begin
|
|
TTgTrace.T('Failed to create Everyone SID');
|
|
exit;
|
|
end;
|
|
|
|
// 3. 새 DACL 생성 (기존 DACL 크기 그대로 확보)
|
|
GetAclInformation(pDACL, @eaCount, SizeOf(eaCount), AclSizeInformation);
|
|
pNewDACL := AllocMem(1024); // 충분한 크기 확보
|
|
InitializeAcl(pNewDACL^, 1024, ACL_REVISION);
|
|
|
|
// 4. 기존 ACE들 순회하면서 Everyone 아닌 것만 복사
|
|
i := 0;
|
|
while GetAce(pDACL, i, Pointer(aceHeader)) do
|
|
begin
|
|
Inc(i);
|
|
// ACE SID 가져오기
|
|
case aceHeader.AceType of
|
|
ACCESS_ALLOWED_ACE_TYPE:
|
|
begin
|
|
aceAccessMask := PACCESS_ALLOWED_ACE(aceHeader)^.Mask;
|
|
pAceSID := @PACCESS_ALLOWED_ACE(aceHeader)^.SidStart;
|
|
end;
|
|
ACCESS_DENIED_ACE_TYPE:
|
|
begin
|
|
aceAccessMask := PACCESS_DENIED_ACE(aceHeader)^.Mask;
|
|
pAceSID := @PACCESS_DENIED_ACE(aceHeader)^.SidStart;
|
|
end;
|
|
else
|
|
Continue; // 다른 ACE 타입은 패스
|
|
end;
|
|
|
|
// Everyone과 같으면 건너뜀
|
|
if EqualSid(sidEveryone, pAceSID) then
|
|
Continue;
|
|
|
|
// 새 DACL에 추가
|
|
AddAccessAllowedAceEx(
|
|
pNewDACL^,
|
|
ACL_REVISION,
|
|
0,
|
|
aceAccessMask,
|
|
pAceSID
|
|
);
|
|
end;
|
|
|
|
// 5. 수정된 DACL을 다시 설정
|
|
dwRes := SetNamedSecurityInfo(
|
|
PChar('\\localhost\' + sShareName),
|
|
SE_LMSHARE,
|
|
DACL_SECURITY_INFORMATION,
|
|
nil, nil,
|
|
pNewDACL,
|
|
nil
|
|
);
|
|
|
|
Result := dwRes = ERROR_SUCCESS;
|
|
finally
|
|
if pSD <> nil then
|
|
LocalFree(HLOCAL(pSD));
|
|
if sidEveryone <> nil then
|
|
LocalFree(HLOCAL(sidEveryone));
|
|
if pNewDACL <> nil then
|
|
FreeMem(pNewDACL);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(E, 'Fail .. RemoveEveryoneFromShare()');
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|