📄 ethsock.cxx
字号:
if (hDriver == INVALID_HANDLE_VALUE) { hDriver = CreateFile("\\\\.\\" PACKET_VXD_NAME ".VXD", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, NULL); if (hDriver == INVALID_HANDLE_VALUE) { dwError = ::GetLastError(); return FALSE; }#ifndef USE_VPACKET rxsize = 0; if (!IoControl(IOCTL_EPACKET_VERSION, NULL, 0, buf, sizeof(buf), rxsize)) { dwError = ::GetLastError(); return FALSE; } if (rxsize != 2 || buf[0] < 1 || buf[1] < 1) { // Require driver version 1.1 Close(); dwError = ERROR_BAD_DRIVER; return FALSE; }#endif } PString devName; PINDEX colon = interfaceName.Find(':'); if (colon != P_MAX_INDEX) devName = interfaceName.Left(colon); else devName = interfaceName; rxsize = 0; if (!IoControl(IOCTL_EPACKET_BIND, (const char *)devName, devName.GetLength()+1, buf, sizeof(buf), rxsize) || rxsize == 0) { dwError = ::GetLastError(); if (dwError == 0) dwError = ERROR_BAD_DRIVER; return FALSE; } // Get a random OID to verify that the driver did actually open if (!QueryOid(OID_GEN_DRIVER_VERSION, 2, buf)) return FALSE; dwError = ERROR_SUCCESS; // Successful, even if may not be bound. PString devKey = SearchRegistryKeys("HKEY_LOCAL_MACHINE\\Enum\\", "Driver", "Net\\" + devName); if (devKey.IsEmpty()) return TRUE; RegistryKey bindRegistry(devKey + "Bindings", RegistryKey::ReadOnly); PString binding; PINDEX idx = 0; while (bindRegistry.EnumValue(idx++, binding)) { if (binding.Left(6) *= "MSTCP\\") { RegistryKey mstcpRegistry("HKEY_LOCAL_MACHINE\\Enum\\Network\\" + binding, RegistryKey::ReadOnly); PString str; if (mstcpRegistry.QueryValue("Driver", str)) transportBinding.AppendString(SERVICES_REGISTRY_KEY "Class\\" + str); } }#endif // !_WIN32_WCE return TRUE;}BOOL PWin32PacketVxD::EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask){ if (idx >= transportBinding.GetSize()) return FALSE; RegistryKey transportRegistry(transportBinding[idx], RegistryKey::ReadOnly); PString str; if (transportRegistry.QueryValue("IPAddress", str)) addr = str; else addr = 0; if (addr != 0) { if (addr.GetVersion() == 6) { net_mask = 0; // Seb: Something to do ? } else { if (transportRegistry.QueryValue("IPMask", str)) net_mask = str; else { if (IN_CLASSA(addr)) net_mask = "255.0.0.0"; else if (IN_CLASSB(addr)) net_mask = "255.255.0.0"; else if (IN_CLASSC(addr)) net_mask = "255.255.255.0"; else net_mask = 0; } } return TRUE; } PEthSocket::Address macAddress; if (!QueryOid(OID_802_3_CURRENT_ADDRESS, sizeof(macAddress), macAddress.b)) return FALSE; PINDEX dhcpCount; for (dhcpCount = 0; dhcpCount < 8; dhcpCount++) { RegistryKey dhcpRegistry(psprintf(SERVICES_REGISTRY_KEY "VxD\\DHCP\\DhcpInfo%02u", dhcpCount), RegistryKey::ReadOnly); if (dhcpRegistry.QueryValue("DhcpInfo", str)) { struct DhcpInfo { DWORD index; PIPSocket::Address ipAddress; PIPSocket::Address mask; PIPSocket::Address server; PIPSocket::Address anotherAddress; DWORD unknown1; DWORD unknown2; DWORD unknown3; DWORD unknown4; DWORD unknown5; DWORD unknown6; BYTE unknown7; PEthSocket::Address macAddress; } * dhcpInfo = (DhcpInfo *)(const char *)str; if (dhcpInfo->macAddress == macAddress) { addr = dhcpInfo->ipAddress; net_mask = dhcpInfo->mask; return TRUE; } } else if (dhcpRegistry.QueryValue("HardwareAddress", str) && str.GetSize() >= sizeof(PEthSocket::Address)) { PEthSocket::Address hardwareAddress; memcpy(&hardwareAddress, (const char *)str, sizeof(hardwareAddress)); if (hardwareAddress == macAddress) { if (dhcpRegistry.QueryValue("DhcpIPAddress", str) && str.GetSize() >= sizeof(addr)) { memcpy(&addr, (const char *)str, sizeof(addr)); if (dhcpRegistry.QueryValue("DhcpSubnetMask", str) && str.GetSize() >= sizeof(net_mask)) { memcpy(&net_mask, (const char *)str, sizeof(net_mask)); return TRUE; } } } } } return FALSE;}BOOL PWin32PacketVxD::BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap){ received = 0; if (DeviceIoControl(hDriver, IOCTL_EPACKET_READ, buf, size, buf, size, &received, &overlap)) { dwError = ERROR_SUCCESS; return TRUE; } dwError = ::GetLastError(); return dwError == ERROR_IO_PENDING;}BOOL PWin32PacketVxD::BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap){ DWORD rxsize = 0; BYTE dummy[2]; if (DeviceIoControl(hDriver, IOCTL_EPACKET_WRITE, (void *)buf, len, dummy, sizeof(dummy), &rxsize, &overlap)) { dwError = ERROR_SUCCESS; return TRUE; } dwError = ::GetLastError(); return dwError == ERROR_IO_PENDING;}///////////////////////////////////////////////////////////////////////////////PWin32PacketSYS::PWin32PacketSYS(){#ifndef _WIN32_WCE // Start the packet driver service SC_HANDLE hManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hManager != NULL) { SC_HANDLE hService = OpenService(hManager, PACKET_SERVICE_NAME, SERVICE_START); if (hService != NULL) { StartService(hService, 0, NULL); dwError = ::GetLastError(); CloseServiceHandle(hService); } CloseServiceHandle(hManager); }#endif // !_WIN32_WCE}static const char PacketDeviceStr[] = "\\Device\\" PACKET_SERVICE_NAME "_";BOOL PWin32PacketSYS::EnumInterfaces(PINDEX idx, PString & name){#ifndef _WIN32_WCE RegistryKey registry(SERVICES_REGISTRY_KEY PACKET_SERVICE_NAME "\\Linkage", RegistryKey::ReadOnly); if (!RegistryQueryMultiSz(registry, "Export", idx, name)) { dwError = ERROR_NO_MORE_ITEMS; return FALSE; } if (strnicmp(name, PacketDeviceStr, sizeof(PacketDeviceStr)-1) == 0) name.Delete(0, sizeof(PacketDeviceStr)-1);#endif // !_WIN32_WCE return TRUE;}BOOL PWin32PacketSYS::BindInterface(const PString & interfaceName){#ifndef _WIN32_WCE Close(); if (!DefineDosDevice(DDD_RAW_TARGET_PATH, PACKET_SERVICE_NAME "_" + interfaceName, PacketDeviceStr + interfaceName)) { dwError = ::GetLastError(); return FALSE; } ::SetLastError(0); hDriver = CreateFile("\\\\.\\" PACKET_SERVICE_NAME "_" + interfaceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, NULL); if (hDriver == INVALID_HANDLE_VALUE) { dwError = ::GetLastError(); return FALSE; } registryKey = SERVICES_REGISTRY_KEY + interfaceName + "\\Parameters\\Tcpip"; dwError = ERROR_SUCCESS;#endif // !_WIN32_WCE return TRUE;}BOOL PWin32PacketSYS::EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask){ PString str; RegistryKey registry(registryKey, RegistryKey::ReadOnly); if (!RegistryQueryMultiSz(registry, "IPAddress", idx, str)) { dwError = ERROR_NO_MORE_ITEMS; return FALSE; } addr = str; if (!RegistryQueryMultiSz(registry, "SubnetMask", idx, str)) { dwError = ERROR_NO_MORE_ITEMS; return FALSE; } net_mask = str; return TRUE;}BOOL PWin32PacketSYS::BeginRead(void * buf, DWORD size, DWORD & received, PWin32Overlapped & overlap){ overlap.Reset(); received = 0; if (ReadFile(hDriver, buf, size, &received, &overlap)) { dwError = ERROR_SUCCESS; return TRUE; } return (dwError = ::GetLastError()) == ERROR_IO_PENDING;}BOOL PWin32PacketSYS::BeginWrite(const void * buf, DWORD len, PWin32Overlapped & overlap){ overlap.Reset(); DWORD sent = 0; if (WriteFile(hDriver, buf, len, &sent, &overlap)) { dwError = ERROR_SUCCESS; return TRUE; } dwError = ::GetLastError(); return dwError == ERROR_IO_PENDING;}///////////////////////////////////////////////////////////////////////////////#ifdef _WIN32_WCEPWin32PacketCe::PWin32PacketCe(){ PString str, driver, nameStr, keyStr, driverStr, miniportStr, linkageStr, routeStr, tcpipStr; static const PString ActiveDrivers = "HKEY_LOCAL_MACHINE\\Drivers\\Active"; static const PString CommBase = "HKEY_LOCAL_MACHINE\\Comm"; // Collecting active drivers RegistryKey registry(ActiveDrivers, RegistryKey::ReadOnly); for (PINDEX idx = 0; registry.EnumKey(idx, str); idx++) { driver = ActiveDrivers + "\\" + str; RegistryKey driverKey( driver, RegistryKey::ReadOnly ); // Filter out non - NDS drivers if( !driverKey.QueryValue( "Name", nameStr ) || nameStr.Find("NDS") == P_MAX_INDEX ) continue; // Active network driver found // // e.g. built-in driver has "Key" = Drivers\BuiltIn\NDIS if( driverKey.QueryValue( "Key", keyStr ) ) { if( P_MAX_INDEX != keyStr.Find("BuiltIn") ) { // Built-in driver case continue; } else { driverStr = "HKEY_LOCAL_MACHINE\\"+ keyStr; RegistryKey ActiveDriverKey( driverStr, RegistryKey::ReadOnly ); // Get miniport value if( ActiveDriverKey.QueryValue( "Miniport", miniportStr ) ) { // Get miniport linkage // // e.g. [HKEY_LOCAL_MACHINE\Comm\SOCKETLPE\Linkage] linkageStr = CommBase + "\\" + miniportStr + "\\Linkage"; RegistryKey LinkageKey( linkageStr, RegistryKey::ReadOnly ); // Get route to real driver if( LinkageKey.QueryValue( "Route", routeStr ) ) { tcpipStr = CommBase + "\\" + routeStr + "\\Parms\\TcpIp"; RegistryKey TcpIpKey( tcpipStr, RegistryKey::ReadOnly ); DWORD dwDHCPEnabled = FALSE; TcpIpKey.QueryValue( "EnableDHCP", dwDHCPEnabled, TRUE ); /// Collect IP addresses and net masks PString ipAddress, netMask; if( !dwDHCPEnabled ) { if(TcpIpKey.QueryValue( "IpAddress", ipAddress ) && (ipAddress != "0.0.0.0") ) { interfaces[interfaces.GetSize()] = tcpipStr; // Registry key for the driver ipAddresses[ipAddresses.GetSize()] = ipAddress; // It's IP if( driverKey.QueryValue( "Subnetmask", netMask ) ) netMasks[netMasks.GetSize()] = netMask; // It's mask else netMasks[netMasks.GetSize()] = "255.255.255.0"; } } else // DHCP enabled if( TcpIpKey.QueryValue( "DhcpIpAddress", ipAddress ) && (ipAddress != "0.0.0.0") ) { interfaces[interfaces.GetSize()] = str; ipAddresses[ipAddresses.GetSize()] = ipAddress; if( driverKey.QueryValue( "DhcpSubnetMask", netMask ) ) netMasks[netMasks.GetSize()] = netMask; else netMasks[netMasks.GetSize()] = "255.255.255.0"; } } } } } }}BOOL PWin32PacketCe::EnumInterfaces(PINDEX idx, PString & name){ if( idx >= interfaces.GetSize() ) return FALSE; name = interfaces[idx]; return TRUE;}BOOL PWin32PacketCe::BindInterface(const PString &){ return TRUE;}BOOL PWin32PacketCe::EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask){ if( idx >= interfaces.GetSize() ) return FALSE; addr = ipAddresses[idx]; net_mask = netMasks[idx]; return TRUE;}BOOL PWin32PacketCe::BeginRead(void *, DWORD, DWORD & , PWin32Overlapped &){ return TRUE;}BOOL PWin32PacketCe::BeginWrite(const void *, DWORD, PWin32Overlapped &){ return TRUE;}#endif // _WIN32_WCE///////////////////////////////////////////////////////////////////////////////PEthSocket::PEthSocket(PINDEX nReadBuffers, PINDEX nWriteBuffers, PINDEX size) : readBuffers(min(nReadBuffers, MAXIMUM_WAIT_OBJECTS)), writeBuffers(min(nWriteBuffers, MAXIMUM_WAIT_OBJECTS)){ driver = PWin32PacketDriver::Create(); PINDEX i; for (i = 0; i < nReadBuffers; i++) readBuffers.SetAt(i, new PWin32PacketBuffer(size)); for (i = 0; i < nWriteBuffers; i++) writeBuffers.SetAt(i, new PWin32PacketBuffer(size)); filterType = TypeAll;}PEthSocket::~PEthSocket(){ Close(); delete driver;}BOOL PEthSocket::OpenSocket(){ PAssertAlways(PUnimplementedFunction); return FALSE;}BOOL PEthSocket::Close(){ driver->Close(); os_handle = -1; return TRUE;}PString PEthSocket::GetName() const{ return interfaceName;}BOOL PEthSocket::Connect(const PString & newName){ Close(); if (!driver->BindInterface(newName)) return SetErrorValues(Miscellaneous, driver->GetLastError()|PWIN32ErrorFlag); interfaceName = newName; os_handle = 1; return TRUE;}BOOL PEthSocket::EnumInterfaces(PINDEX idx, PString & name){ return driver->EnumInterfaces(idx, name);}BOOL PEthSocket::GetAddress(Address & addr){ if (driver->QueryOid(OID_802_3_CURRENT_ADDRESS, sizeof(addr), addr.b)) return TRUE; return SetErrorValues(Miscellaneous, driver->GetLastError()|PWIN32ErrorFlag);}BOOL PEthSocket::EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask){ if (IsOpen()) { if (driver->EnumIpAddress(idx, addr, net_mask)) return TRUE; return SetErrorValues(NotFound, ENOENT); } return SetErrorValues(NotOpen, EBADF);}static const struct { unsigned pwlib; DWORD ndis;} FilterMasks[] = { { PEthSocket::FilterDirected, NDIS_PACKET_TYPE_DIRECTED }, { PEthSocket::FilterMulticast, NDIS_PACKET_TYPE_MULTICAST }, { PEthSocket::FilterAllMulticast, NDIS_PACKET_TYPE_ALL_MULTICAST }, { PEthSocket::FilterBroadcast, NDIS_PACKET_TYPE_BROADCAST }, { PEthSocket::FilterPromiscuous, NDIS_PACKET_TYPE_PROMISCUOUS }};BOOL PEthSocket::GetFilter(unsigned & mask, WORD & type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -