From 7287ff9aa0fac7fe873b45f7e21eb117df26bd50 Mon Sep 17 00:00:00 2001 From: Sonicadvance1 Date: Tue, 12 May 2009 17:03:49 +0000 Subject: [PATCH] Commit my Windows work on the TAP side of BBA. Probably breaks Windows build until someone adds a file the the Windows project. Dunno how far it gets, someone will need to test. You need to install OpenVPN and it's TAP-Win32 driver. Need to figure out more how to do this on the Linux side now git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3210 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp | 151 ++++++++++++++++-- .../Core/Core/Src/HW/EXI_DeviceEthernet.cpp | 3 + Source/Core/Core/Src/HW/EXI_DeviceEthernet.h | 14 +- 3 files changed, 158 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp index f2c8d63285..5818d9034f 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp @@ -18,6 +18,8 @@ #include "../Memmap.h" #include "../EXI_Device.h" #include "../EXI_DeviceEthernet.h" +#include "Tap_Win32.h" + bool CEXIETHERNET::deactivate() { @@ -31,10 +33,84 @@ bool CEXIETHERNET::isActivated() } bool CEXIETHERNET::activate() { - if (isActivated()) +if(isActivated()) return true; - else + + DEBUGPRINT("\nActivating BBA...\n"); + + DWORD len; + +#if 0 + device_guid = get_device_guid (dev_node, guid_buffer, sizeof (guid_buffer), tap_reg, panel_reg, &gc); + + if (!device_guid) + DEGUB("TAP-Win32 adapter '%s' not found\n", dev_node); + + /* Open Windows TAP-Win32 adapter */ + openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s", + USERMODEDEVICEDIR, + device_guid, + TAPSUFFIX); +#endif //0 + + mHAdapter = CreateFile (/*device_path*/ + USERMODEDEVICEDIR "{1B1F9D70-50B7-4F45-AA4A-ABD17451E736}" TAPSUFFIX, + GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, + FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + DEBUGPRINT("TAP-WIN32 device opened: %s\n", + USERMODEDEVICEDIR "{1B1F9D70-50B7-4F45-AA4A-ABD17451E736}" TAPSUFFIX); + if(mHAdapter == INVALID_HANDLE_VALUE) { return false; + } + + /* get driver version info */ + { + ULONG info[3]; + if (DeviceIoControl (mHAdapter, TAP_IOCTL_GET_VERSION, + &info, sizeof (info), &info, sizeof (info), &len, NULL)) + { + DEBUGPRINT("TAP-Win32 Driver Version %d.%d %s\n", + info[0], info[1], (info[2] ? "(DEBUG)" : "")); + } + if ( !(info[0] > TAP_WIN32_MIN_MAJOR + || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) ) + { +#define PACKAGE_NAME "Dolphin" + DEBUGPRINT("ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.\n", + TAP_WIN32_MIN_MAJOR, + TAP_WIN32_MIN_MINOR); + return false; + } + } + + /* get driver MTU */ + { + if(!DeviceIoControl(mHAdapter, TAP_IOCTL_GET_MTU, + &mMtu, sizeof (mMtu), &mMtu, sizeof (mMtu), &len, NULL)) + { + return false; + } + DEBUGPRINT("TAP-Win32 MTU=%d (ignored)\n", mMtu); + } + + /* set driver media status to 'connected' */ + { + ULONG status = TRUE; + if (!DeviceIoControl (mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), &status, sizeof (status), &len, NULL)) + { + DEBUGPRINT("WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.\n"); + return false; + } + } + + //set up recv event + mHRecvEvent = CreateEvent(NULL, false, false, NULL); + //ZERO_OBJECT(mReadOverlapped); + resume(); + + DEBUGPRINT("Success!\n\n"); + return true; //TODO: Activate Device! } bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) @@ -45,17 +121,16 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size) DEBUGPRINT( "%02X", etherpckt[a]); } DEBUGPRINT( " : Size: %d\n", size); - //fwrite(etherpckt, size, size, raw_socket); - /*DWORD numBytesWrit; + DWORD numBytesWrit; OVERLAPPED overlap; - ZERO_OBJECT(overlap); + //ZERO_OBJECT(overlap); //overlap.hEvent = mHRecvEvent; - TGLE(WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap)); + WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap); if(numBytesWrit != size) { - DEGUB("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit); - FAIL(UE_BBA_ERROR); - }*/ + DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit); + return false; + } recordSendComplete(); //exit(0); return true; @@ -65,3 +140,61 @@ bool CEXIETHERNET::handleRecvdPacket() DEBUGPRINT(" Handle received Packet!\n"); exit(0); } +bool CEXIETHERNET::resume() { + if(!isActivated()) + return true; + DEBUGPRINT("BBA resume\n"); + //mStop = false; + RegisterWaitForSingleObject(&mHReadWait, mHRecvEvent, ReadWaitCallback, + this, INFINITE, WT_EXECUTEDEFAULT);//WT_EXECUTEINWAITTHREAD + mReadOverlapped.hEvent = mHRecvEvent; + if(mBbaMem[BBA_NCRA] & BBA_NCRA_SR) { + startRecv(); + } + DEBUGPRINT("BBA resume complete\n"); + return true; +} +bool CEXIETHERNET::startRecv() { + if(!isActivated()) + return false;// Should actually be an assert + DEBUGPRINT("startRecv... "); + if(mWaiting) { + DEBUGPRINT("already waiting\n"); + return true; + } + DWORD BytesRead = 0; + DWORD *Buffer = (DWORD *)malloc(2048); // Should be enough + DWORD res = ReadFile(mHAdapter, Buffer, BytesRead, + &mRecvBufferLength, &mReadOverlapped); + mRecvBuffer.write(BytesRead, Buffer); + free(Buffer); + if(res) { //Operation completed immediately + DEBUGPRINT("completed, res %i\n", res); + mWaiting = true; + } else { + res = GetLastError(); + if (res == ERROR_IO_PENDING) { //'s ok :) + DEBUGPRINT("pending\n"); + //WaitCallback will be called + mWaiting = true; + } else { //error occurred + return false; + } + } + return true; +} +VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired) { + static int sNumber = 0; + int cNumber = sNumber++; + DEBUGPRINT("WaitCallback %i\n", cNumber); + if(TimerFired) + return; + CEXIETHERNET* self = (CEXIETHERNET*)lpParameter; + if(self->mHAdapter == INVALID_HANDLE_VALUE) + return; + GetOverlappedResult(self->mHAdapter, &self->mReadOverlapped, + &self->mRecvBufferLength, false); + self->mWaiting = false; + self->handleRecvdPacket(); + DEBUGPRINT("WaitCallback %i done\n", cNumber); +} \ No newline at end of file diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp index be058c4d37..7850e68ea1 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp @@ -71,6 +71,9 @@ CEXIETHERNET::CEXIETHERNET() : m_uPosition(0), m_uCommand(0), mWriteBuffer(2048), +#ifdef _WIN32 + mRecvBuffer(2048), +#endif mCbw(mBbaMem + CB_OFFSET, CB_SIZE) { ID = 0x04020200; diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h index d628ad1730..1b1a22fda8 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h @@ -93,8 +93,9 @@ private: u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer bool mRBEmpty; - +#ifndef _WIN32 u32 mRecvBufferLength; +#endif #define BBAMEM_SIZE 0x1000 u8 mBbaMem[BBAMEM_SIZE]; @@ -120,6 +121,17 @@ private: bool activate(); bool deactivate(); bool isActivated(); + bool resume(); + bool startRecv(); +#ifdef _WIN32 + HANDLE mHAdapter, mHRecvEvent, mHReadWait; + DWORD mMtu; + OVERLAPPED mReadOverlapped; + WriteBuffer mRecvBuffer; + DWORD mRecvBufferLength; + volatile bool mWaiting; + static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired); +#endif }; enum {