diff --git a/desmume/src/driver.h b/desmume/src/driver.h index f900c4d03..aa006542f 100644 --- a/desmume/src/driver.h +++ b/desmume/src/driver.h @@ -27,6 +27,10 @@ #include "debug.h" #include +#ifdef EXPERIMENTAL_WIFI_COMM +#include +#endif + class VIEW3D_Driver { public: @@ -41,8 +45,18 @@ public: BaseDriver(); ~BaseDriver(); - virtual bool WIFI_Host_InitSystem() { return FALSE; } - virtual void WIFI_Host_ShutdownSystem() {} +#ifdef EXPERIMENTAL_WIFI_COMM + virtual bool WIFI_SocketsAvailable() { return true; } + virtual bool WIFI_PCapAvailable() { return false; } + + virtual int PCAP_findalldevs(pcap_if_t** alldevs, char* errbuf) { return -1; } + virtual void PCAP_freealldevs(pcap_if_t* alldevs) {} + virtual pcap_t* PCAP_open(const char* source, int snaplen, int flags, int readtimeout, char* errbuf) { return NULL; } + virtual void PCAP_close(pcap_t* dev) {} + virtual int PCAP_setnonblock(pcap_t* dev, int nonblock, char* errbuf) { return -1; } + virtual int PCAP_sendpacket(pcap_t* dev, const u_char* data, int len) { return -1; } + virtual int PCAP_dispatch(pcap_t* dev, int num, pcap_handler callback, u_char* userdata) { return -1; } +#endif virtual void AVI_SoundUpdate(void* soundData, int soundLen) {} virtual bool AVI_IsRecording() { return FALSE; } diff --git a/desmume/src/wifi.cpp b/desmume/src/wifi.cpp index e49d672ee..9f157433e 100644 --- a/desmume/src/wifi.cpp +++ b/desmume/src/wifi.cpp @@ -50,7 +50,6 @@ #define BASEPORT 7000 -bool wifi_netEnabled = false; socket_t wifi_socket = INVALID_SOCKET; sockaddr_t sendAddr; @@ -317,87 +316,6 @@ INLINE bool WIFI_compareMAC(u8* a, u8* b) return ((*(u32*)&a[0]) == (*(u32*)&b[0])) && ((*(u16*)&a[4]) == (*(u16*)&b[4])); } -// TODO: implement all the PCAP wrapping better -// put that in the platform-driver class -// Win32: retrieve the PCAP functions through GetProcAddress()? - -#ifdef EXPERIMENTAL_WIFI_COMM -#ifdef WIN32 -static pcap_t *desmume_pcap_open(const char *source, int snaplen, int flags, - int read_timeout, char *errbuf) -{ - return PCAP::pcap_open(source, snaplen, flags, read_timeout, NULL, errbuf); -} - -static int desmume_pcap_findalldevs(pcap_if_t **alldevs, char *errbuf) -{ - return PCAP::pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, alldevs, errbuf); -} - -static void desmume_pcap_freealldevs(pcap_if_t *alldevs) -{ - return PCAP::pcap_freealldevs(alldevs); -} - -static void desmume_pcap_close(pcap_t *p) -{ - return PCAP::pcap_close(p); -} - -static int desmume_pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) -{ - return PCAP::pcap_setnonblock(p, nonblock, errbuf); -} - -static int desmume_pcap_sendpacket(pcap_t *p, u_char *buf, int size) -{ - return PCAP::pcap_sendpacket(p, buf, size); -} - -static int desmume_pcap_dispatch(pcap_t* p, int cnt, pcap_handler callback, u_char* user) -{ - return PCAP::pcap_dispatch(p, cnt, callback, user); -} - -#else -static pcap_t *desmume_pcap_open(const char *device, int snaplen, int promisc, - int to_ms, char *errbuf) -{ - return pcap_open_live(device, snaplen, promisc, to_ms, errbuf); -} - -static int desmume_pcap_findalldevs(pcap_if_t **alldevs, char *errbuf) -{ - return pcap_findalldevs(alldevs, errbuf); -} - -static void desmume_pcap_freealldevs(pcap_if_t *alldevs) -{ - return pcap_freealldevs(alldevs); -} - -static void desmume_pcap_close(pcap_t *p) -{ - return pcap_close(p); -} - -static int desmume_pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) -{ - return pcap_setnonblock(p, nonblock, errbuf); -} - -static int desmume_pcap_sendpacket(pcap_t *p, u_char *buf, int size) -{ - return pcap_sendpacket(p, buf, size); -} - -static int desmume_pcap_dispatch(pcap_t* p, int cnt, pcap_handler callback, u_char* user) -{ - return pcap_dispatch(p, cnt, callback, user); -} -#endif -#endif - /******************************************************************************* CRC32 (http://www.codeproject.com/KB/recipes/crc32_large.aspx) @@ -710,13 +628,7 @@ bool WIFI_Init() WIFI_initCRC32Table(); WIFI_resetRF(&wifiMac.RF) ; - wifi_netEnabled = false; -#ifdef EXPERIMENTAL_WIFI_COMM - if(driver->WIFI_Host_InitSystem()) - { - wifi_netEnabled = true; - } -#endif + wifiMac.powerOn = FALSE; wifiMac.powerOnPending = FALSE; @@ -743,13 +655,7 @@ void WIFI_Reset() memset(&wifiMac, 0, sizeof(wifimac_t)); WIFI_resetRF(&wifiMac.RF) ; - wifi_netEnabled = false; -#ifdef EXPERIMENTAL_WIFI_COMM - if(driver->WIFI_Host_InitSystem()) - { - wifi_netEnabled = true; - } -#endif + wifiMac.powerOn = FALSE; wifiMac.powerOnPending = FALSE; @@ -1762,6 +1668,12 @@ bool Adhoc_Init() wifiMac.Adhoc.usecCounter = 0; + if (!driver->WIFI_SocketsAvailable()) + { + WIFI_LOG(1, "Ad-hoc: failed to initialize sockets.\n"); + return false; + } + // Create an UDP socket wifi_socket = socket(AF_INET, SOCK_DGRAM, 0); if (wifi_socket < 0) @@ -1817,6 +1729,9 @@ void Adhoc_Reset() void Adhoc_SendPacket(u8* packet, u32 len) { + if (!driver->WIFI_SocketsAvailable()) + return; + WIFI_LOG(2, "Ad-hoc: sending a packet of %i bytes, frame control: %04X\n", len, *(u16*)&packet[0]); u32 frameLen = sizeof(Adhoc_FrameHeader) + len; @@ -1844,6 +1759,9 @@ void Adhoc_usTrigger() { wifiMac.Adhoc.usecCounter++; + if (!driver->WIFI_SocketsAvailable()) + return; + // Check every millisecond if we received a packet if (!(wifiMac.Adhoc.usecCounter & 1023)) { @@ -2002,49 +1920,54 @@ const u8 SoftAP_AssocResponse[] = { //todo - make a class to wrap this //todo - zeromus - inspect memory leak safety of all this -static pcap_if_t * WIFI_index_device(pcap_if_t *alldevs, int index) { +static pcap_if_t * WIFI_index_device(pcap_if_t *alldevs, int index) +{ pcap_if_t *curr = alldevs; - for(int i=0;inext; + return curr; } bool SoftAP_Init() { - wifiMac.SoftAP.usecCounter = 0; wifiMac.SoftAP.curPacketSize = 0; wifiMac.SoftAP.curPacketPos = 0; wifiMac.SoftAP.curPacketSending = FALSE; + + if (!driver->WIFI_PCapAvailable()) + { + WIFI_LOG(1, "SoftAP: failed to initialize PCap.\n"); + return false; + } char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs; - if(wifi_netEnabled) + if(driver->PCAP_findalldevs(&alldevs, errbuf) == -1) { - if(desmume_pcap_findalldevs(&alldevs, errbuf) == -1) - { - printf("SoftAP: PCap: failed to find any network adapter: %s\n", errbuf); - return false; - } + WIFI_LOG(1, "SoftAP: PCap: failed to find any network adapter: %s\n", errbuf); + return false; + } - pcap_if_t* dev = WIFI_index_device(alldevs,CommonSettings.wifi.infraBridgeAdapter); - wifi_bridge = desmume_pcap_open(dev->name, PACKET_SIZE, 0, 1, errbuf); - if(wifi_bridge == NULL) - { - printf("SoftAP: PCap: failed to open %s: %s\n", (dev->description ? dev->description : "the network adapter"), errbuf); - return false; - } + pcap_if_t* dev = WIFI_index_device(alldevs,CommonSettings.wifi.infraBridgeAdapter); + wifi_bridge = driver->PCAP_open(dev->name, PACKET_SIZE, 0, 1, errbuf); + if(wifi_bridge == NULL) + { + WIFI_LOG(1, "SoftAP: PCap: failed to open %s: %s\n", (dev->description ? dev->description : "the network adapter"), errbuf); + return false; + } - desmume_pcap_freealldevs(alldevs); + driver->PCAP_freealldevs(alldevs); - // Set non-blocking mode - if (desmume_pcap_setnonblock(wifi_bridge, 1, errbuf) == -1) - { - printf("SoftAP: PCap: failed to set non-blocking mode: %s\n", errbuf); - return false; - } + // Set non-blocking mode + if (driver->PCAP_setnonblock(wifi_bridge, 1, errbuf) == -1) + { + WIFI_LOG(1, "SoftAP: PCap: failed to set non-blocking mode: %s\n", errbuf); + return false; } return true; @@ -2052,11 +1975,8 @@ bool SoftAP_Init() void SoftAP_DeInit() { - if(wifi_netEnabled) - { - if(wifi_bridge != NULL) - desmume_pcap_close(wifi_bridge); - } + if(wifi_bridge != NULL) + driver->PCAP_close(wifi_bridge); } void SoftAP_Reset() @@ -2170,8 +2090,8 @@ void SoftAP_SendPacket(u8 *packet, u32 len) // Checksum // TODO ? - if(wifi_netEnabled) //dont try to pcap out the packet unless network is enabled - desmume_pcap_sendpacket(wifi_bridge, ethernetframe, eflen); + if (driver->WIFI_PCapAvailable()) + driver->PCAP_sendpacket(wifi_bridge, ethernetframe, eflen); delete ethernetframe; } @@ -2322,7 +2242,8 @@ void SoftAP_usTrigger() // Can now receive 64 packets per millisecond. Completely arbitrary limit. Todo: tweak if needed. // But due to using non-blocking mode, this shouldn't be as slow as it used to be. if ((wifiMac.SoftAP.usecCounter & 1023) == 0) - desmume_pcap_dispatch(wifi_bridge, 64, SoftAP_RXHandler, NULL); + if (driver->WIFI_PCapAvailable()) + driver->PCAP_dispatch(wifi_bridge, 64, SoftAP_RXHandler, NULL); } #endif diff --git a/desmume/src/wifi.h b/desmume/src/wifi.h index 0856f4b4f..c0acada86 100644 --- a/desmume/src/wifi.h +++ b/desmume/src/wifi.h @@ -372,6 +372,15 @@ typedef union u16 val ; } wifiirq_t ; +typedef struct +{ + bool enabled; + u16 address; + + bool sending; + u16 remtime; +} Wifi_TXLoc; + /* wifimac_t: the buildin mac (arm7 addressrange: 0x04800000-0x04FFFFFF )*/ /* http://www.akkit.org/info/dswifi.htm#WifiIOMap */ @@ -410,6 +419,10 @@ typedef struct u32 txSlotAddr[3]; u32 txSlotLen[3]; u32 txSlotRemainingBytes[3]; + bool ExtraSlotBusy; + u16 ExtraSlotAddr; + u16 ExtraSlotLen; + u16 ExtraSlotRemBytes; /* receiving */ u16 RXCnt ; @@ -513,7 +526,6 @@ typedef struct typedef struct pcap pcap_t; extern pcap_t *wifi_bridge; #endif -extern bool wifi_netEnabled; extern wifimac_t wifiMac; diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index ced1dd6f7..1c3c2cf79 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -77,10 +77,10 @@ /> + + diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index dfd8f1f76..781eccd5f 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -109,12 +109,10 @@ using namespace std; -#define HAVE_REMOTE -#define WPCAP -#define PACKET_SIZE 65535 - -#include -#include //uh? +#ifdef EXPERIMENTAL_WIFI_COMM +bool bSocketsAvailable = false; +#include "winpcap.h" +#endif VideoInfo video; @@ -382,7 +380,9 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp); LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK EmulationSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK MicrophoneSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +#ifdef EXPERIMENTAL_WIFI_COMM LRESULT CALLBACK WifiSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +#endif //struct configured_features { // u16 arm9_gdb_port; @@ -1970,6 +1970,7 @@ void OpenRecentROM(int listNum) NDS_UnPause(); } + /* * The thread handling functions needed by the GDB stub code. */ @@ -2074,36 +2075,37 @@ static void ExitRunLoop() emu_halt(); } +//----------------------------------------------------------------------------- +// Platform driver for Win32 +//----------------------------------------------------------------------------- + class WinDriver : public BaseDriver { - virtual bool WIFI_Host_InitSystem() - { - #ifdef EXPERIMENTAL_WIFI_COMM - WSADATA wsaData; - WORD version = MAKEWORD(1,1); - if (WSAStartup(version, &wsaData)) - { - printf("Failed initializing WSA.\n"); - return false ; - } - //require wpcap.dll - HMODULE temp = LoadLibrary("wpcap.dll"); - if(temp == NULL) { - printf("Failed initializing wpcap.dll - SoftAP support disabled.\n"); - return false; - } - FreeLibrary(temp); - return true; - #else - return false; - #endif - } - virtual void WIFI_Host_ShutdownSystem() - { - #ifdef EXPERIMENTAL_WIFI_COMM - WSACleanup(); - #endif - } +#ifdef EXPERIMENTAL_WIFI_COMM + virtual bool WIFI_SocketsAvailable() { return bSocketsAvailable; } + virtual bool WIFI_PCapAvailable() { return bWinPCapAvailable; } + + virtual int PCAP_findalldevs(pcap_if_t** alldevs, char* errbuf) { + return _pcap_findalldevs(alldevs, errbuf); } + + virtual void PCAP_freealldevs(pcap_if_t* alldevs) { + _pcap_freealldevs(alldevs); } + + virtual pcap_t* PCAP_open(const char* source, int snaplen, int flags, int readtimeout, char* errbuf) { + return _pcap_open_live(source, snaplen, flags, readtimeout, errbuf); } + + virtual void PCAP_close(pcap_t* dev) { + _pcap_close(dev); } + + virtual int PCAP_setnonblock(pcap_t* dev, int nonblock, char* errbuf) { + return _pcap_setnonblock(dev, nonblock, errbuf); } + + virtual int PCAP_sendpacket(pcap_t* dev, const u_char* data, int len) { + return _pcap_sendpacket(dev, data, len); } + + virtual int PCAP_dispatch(pcap_t* dev, int num, pcap_handler callback, u_char* userdata) { + return _pcap_dispatch(dev, num, callback, userdata); } +#endif virtual bool AVI_IsRecording() { @@ -2229,6 +2231,9 @@ class WinDriver : public BaseDriver } }; +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + static void RefreshMicSettings() { Mic_DeInit_Physical(); @@ -2262,6 +2267,16 @@ int _main() wxInitialize(); #endif +#ifdef EXPERIMENTAL_WIFI_COMM + WSADATA wsaData; + WORD version = MAKEWORD(1,1); + + if (WSAStartup(version, &wsaData) == 0) + bSocketsAvailable = true; + + LoadWinPCap(); +#endif + driver = new WinDriver(); InitializeCriticalSection(&win_execute_sync); @@ -2744,6 +2759,10 @@ int _main() UnregWndClass("DeSmuME"); +#ifdef EXPERIMENTAL_WIFI_COMM + WSACleanup(); +#endif + return 0; } @@ -3470,18 +3489,11 @@ void RunConfig(CONFIGSCREEN which) case CONFIGSCREEN_PATHSETTINGS: DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_PATHSETTINGS), hwnd, (DLGPROC)PathSettingsDlgProc); break; - case CONFIGSCREEN_WIFI: #ifdef EXPERIMENTAL_WIFI_COMM - if(wifi_netEnabled) - { - DialogBoxW(hAppInst,MAKEINTRESOURCEW(IDD_WIFISETTINGS), hwnd, (DLGPROC) WifiSettingsDlgProc); - } - else - { - MessageBox(MainWindow->getHWnd(),"winpcap failed to initialize, and so wifi cannot be configured.","wifi system failure",0); - } -#endif + case CONFIGSCREEN_WIFI: + DialogBoxW(hAppInst,MAKEINTRESOURCEW(IDD_WIFISETTINGS), hwnd, (DLGPROC) WifiSettingsDlgProc); break; +#endif } if (tpaused) @@ -3527,6 +3539,15 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM static int tmp_execute; switch (message) // handle the messages { + case WM_INITMENU: + { +#ifdef EXPERIMENTAL_WIFI_COMM + if (!(bSocketsAvailable && bWinPCapAvailable)) +#endif + DeleteMenu(GetMenu(hwnd), IDM_WIFISETTINGS, MF_BYCOMMAND); + } + return 0; + case WM_EXITMENULOOP: SPU_Pause(0); if (autoframeskipenab && frameskiprate) AutoFrameSkip_IgnorePreviousDelay(); @@ -5661,9 +5682,9 @@ LRESULT CALLBACK MicrophoneSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, return FALSE; } +#ifdef EXPERIMENTAL_WIFI_COMM LRESULT CALLBACK WifiSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - #ifdef EXPERIMENTAL_WIFI_COMM switch(uMsg) { case WM_INITDIALOG: @@ -5674,21 +5695,37 @@ LRESULT CALLBACK WifiSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM int i; HWND cur; - CheckRadioButton(hDlg, IDC_WIFIMODE0, IDC_WIFIMODE1, IDC_WIFIMODE0 + CommonSettings.wifi.mode); + if (bSocketsAvailable && bWinPCapAvailable) + CheckRadioButton(hDlg, IDC_WIFIMODE0, IDC_WIFIMODE1, IDC_WIFIMODE0 + CommonSettings.wifi.mode); + else if(bSocketsAvailable) + CheckRadioButton(hDlg, IDC_WIFIMODE0, IDC_WIFIMODE1, IDC_WIFIMODE0); + else if(bWinPCapAvailable) + CheckRadioButton(hDlg, IDC_WIFIMODE0, IDC_WIFIMODE1, IDC_WIFIMODE1); - if(PCAP::pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + if (bWinPCapAvailable) { - // TODO: fail more gracefully! - EndDialog(hDlg, TRUE); - return TRUE; + if(driver->PCAP_findalldevs(&alldevs, errbuf) == -1) + { + // TODO: fail more gracefully! + EndDialog(hDlg, TRUE); + return TRUE; + } + + cur = GetDlgItem(hDlg, IDC_BRIDGEADAPTER); + for(i = 0, d = alldevs; d != NULL; i++, d = d->next) + { + ComboBox_AddString(cur, d->description); + } + ComboBox_SetCurSel(cur, CommonSettings.wifi.infraBridgeAdapter); + } + else + { + EnableWindow(GetDlgItem(hDlg, IDC_WIFIMODE1), FALSE); + EnableWindow(GetDlgItem(hDlg, IDC_BRIDGEADAPTER), FALSE); } - cur = GetDlgItem(hDlg, IDC_BRIDGEADAPTER); - for(i = 0, d = alldevs; d != NULL; i++, d = d->next) - { - ComboBox_AddString(cur, d->description); - } - ComboBox_SetCurSel(cur, CommonSettings.wifi.infraBridgeAdapter); + if (!bSocketsAvailable) + EnableWindow(GetDlgItem(hDlg, IDC_WIFIMODE0), FALSE); } return TRUE; @@ -5728,9 +5765,10 @@ LRESULT CALLBACK WifiSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM } return TRUE; } -#endif + return FALSE; } +#endif static void SoundSettings_updateVolumeReadout(HWND hDlg) { diff --git a/desmume/src/windows/windriver.h b/desmume/src/windows/windriver.h index fa6d78dc1..e0ca08e28 100644 --- a/desmume/src/windows/windriver.h +++ b/desmume/src/windows/windriver.h @@ -26,26 +26,6 @@ #include "../common.h" #include "CWindow.h" -#ifdef EXPERIMENTAL_WIFI_COMM -#include -#include //uh? - -//because the pcap headers are written poorly, we need to declare these as cdecl -//this may cause the code to fail to compile on non-windows platforms; -//we may have to use a macro to call these functions which chooses whether to call them -//through the namespace -namespace PCAP { - extern "C" __declspec(dllexport) int __cdecl pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf); - extern "C" __declspec(dllexport) int __cdecl pcap_sendpacket(pcap_t *, const u_char *, int); - extern "C" __declspec(dllexport) void __cdecl pcap_close(pcap_t *); - extern "C" __declspec(dllexport) pcap_t* __cdecl pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf); - extern "C" __declspec(dllexport) void __cdecl pcap_freealldevs(pcap_if_t *); - extern "C" __declspec(dllexport) int __cdecl pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf); - extern "C" __declspec(dllexport) int __cdecl pcap_dispatch(pcap_t* p, int cnt, pcap_handler callback, u_char* user); -} - -#endif - extern WINCLASS *MainWindow; class Lock { diff --git a/desmume/src/windows/winpcap.h b/desmume/src/windows/winpcap.h new file mode 100644 index 000000000..7ab9fd840 --- /dev/null +++ b/desmume/src/windows/winpcap.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2010 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef WINPCAP_H +#define WINPCAP_H + +#define HAVE_REMOTE +#define WPCAP +#define PACKET_SIZE 65535 + +#include + +static bool bWinPCapAvailable = false; + +typedef int (__cdecl *T_pcap_findalldevs)(pcap_if_t** alldevs, char* errbuf); +typedef void (__cdecl *T_pcap_freealldevs)(pcap_if_t* alldevs); +typedef pcap_t* (__cdecl *T_pcap_open_live)(const char* source, int snaplen, int flags, int readtimeout, char* errbuf); +typedef void (__cdecl *T_pcap_close)(pcap_t* dev); +typedef int (__cdecl *T_pcap_setnonblock)(pcap_t* dev, int nonblock, char* errbuf); +typedef int (__cdecl *T_pcap_sendpacket)(pcap_t* dev, const u_char* data, int len); +typedef int (__cdecl *T_pcap_dispatch)(pcap_t* dev, int num, pcap_handler callback, u_char* userdata); + +T_pcap_findalldevs _pcap_findalldevs = NULL; +T_pcap_freealldevs _pcap_freealldevs = NULL; +T_pcap_open_live _pcap_open_live = NULL; +T_pcap_close _pcap_close = NULL; +T_pcap_setnonblock _pcap_setnonblock = NULL; +T_pcap_sendpacket _pcap_sendpacket = NULL; +T_pcap_dispatch _pcap_dispatch = NULL; + + +#define LOADSYMBOL(name) \ + _##name = (T_##name)GetProcAddress(wpcap, #name); \ + if (_##name == NULL) return; + + +static void LoadWinPCap() +{ + HMODULE wpcap = LoadLibrary("wpcap.dll"); + if (wpcap == NULL) + return; + + LOADSYMBOL(pcap_findalldevs); + LOADSYMBOL(pcap_freealldevs); + LOADSYMBOL(pcap_open_live); + LOADSYMBOL(pcap_close); + LOADSYMBOL(pcap_setnonblock); + LOADSYMBOL(pcap_sendpacket); + LOADSYMBOL(pcap_dispatch); + + CloseHandle(wpcap); + bWinPCapAvailable = true; +} + +#endif