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
This commit is contained in:
parent
ecfe86efe3
commit
7287ff9aa0
|
@ -18,6 +18,8 @@
|
||||||
#include "../Memmap.h"
|
#include "../Memmap.h"
|
||||||
#include "../EXI_Device.h"
|
#include "../EXI_Device.h"
|
||||||
#include "../EXI_DeviceEthernet.h"
|
#include "../EXI_DeviceEthernet.h"
|
||||||
|
#include "Tap_Win32.h"
|
||||||
|
|
||||||
|
|
||||||
bool CEXIETHERNET::deactivate()
|
bool CEXIETHERNET::deactivate()
|
||||||
{
|
{
|
||||||
|
@ -31,10 +33,84 @@ bool CEXIETHERNET::isActivated()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::activate() {
|
bool CEXIETHERNET::activate() {
|
||||||
if (isActivated())
|
if(isActivated())
|
||||||
return true;
|
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;
|
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!
|
//TODO: Activate Device!
|
||||||
}
|
}
|
||||||
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||||
|
@ -45,17 +121,16 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||||
DEBUGPRINT( "%02X", etherpckt[a]);
|
DEBUGPRINT( "%02X", etherpckt[a]);
|
||||||
}
|
}
|
||||||
DEBUGPRINT( " : Size: %d\n", size);
|
DEBUGPRINT( " : Size: %d\n", size);
|
||||||
//fwrite(etherpckt, size, size, raw_socket);
|
DWORD numBytesWrit;
|
||||||
/*DWORD numBytesWrit;
|
|
||||||
OVERLAPPED overlap;
|
OVERLAPPED overlap;
|
||||||
ZERO_OBJECT(overlap);
|
//ZERO_OBJECT(overlap);
|
||||||
//overlap.hEvent = mHRecvEvent;
|
//overlap.hEvent = mHRecvEvent;
|
||||||
TGLE(WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap));
|
WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap);
|
||||||
if(numBytesWrit != size)
|
if(numBytesWrit != size)
|
||||||
{
|
{
|
||||||
DEGUB("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
|
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
|
||||||
FAIL(UE_BBA_ERROR);
|
return false;
|
||||||
}*/
|
}
|
||||||
recordSendComplete();
|
recordSendComplete();
|
||||||
//exit(0);
|
//exit(0);
|
||||||
return true;
|
return true;
|
||||||
|
@ -65,3 +140,61 @@ bool CEXIETHERNET::handleRecvdPacket()
|
||||||
DEBUGPRINT(" Handle received Packet!\n");
|
DEBUGPRINT(" Handle received Packet!\n");
|
||||||
exit(0);
|
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);
|
||||||
|
}
|
|
@ -71,6 +71,9 @@ CEXIETHERNET::CEXIETHERNET() :
|
||||||
m_uPosition(0),
|
m_uPosition(0),
|
||||||
m_uCommand(0),
|
m_uCommand(0),
|
||||||
mWriteBuffer(2048),
|
mWriteBuffer(2048),
|
||||||
|
#ifdef _WIN32
|
||||||
|
mRecvBuffer(2048),
|
||||||
|
#endif
|
||||||
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
mCbw(mBbaMem + CB_OFFSET, CB_SIZE)
|
||||||
{
|
{
|
||||||
ID = 0x04020200;
|
ID = 0x04020200;
|
||||||
|
|
|
@ -93,8 +93,9 @@ private:
|
||||||
|
|
||||||
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
u16 mRBRPP; //RRP - Receive Buffer Read Page Pointer
|
||||||
bool mRBEmpty;
|
bool mRBEmpty;
|
||||||
|
#ifndef _WIN32
|
||||||
u32 mRecvBufferLength;
|
u32 mRecvBufferLength;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BBAMEM_SIZE 0x1000
|
#define BBAMEM_SIZE 0x1000
|
||||||
u8 mBbaMem[BBAMEM_SIZE];
|
u8 mBbaMem[BBAMEM_SIZE];
|
||||||
|
@ -120,6 +121,17 @@ private:
|
||||||
bool activate();
|
bool activate();
|
||||||
bool deactivate();
|
bool deactivate();
|
||||||
bool isActivated();
|
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 {
|
enum {
|
||||||
|
|
Loading…
Reference in New Issue