testtoolsconn/wintap/src/wintap.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "wintap.h"
       
    21 
       
    22 #include <assert.h>
       
    23 #include <stdio.h>
       
    24 
       
    25 #ifdef EKA2
       
    26 #include <platform/emulator.h>
       
    27 #endif
       
    28 /**
       
    29  *
       
    30  *	The start of most EtherTap specific routines
       
    31  *
       
    32  **/
       
    33 
       
    34 static TIsr GlobIsr = NULL;
       
    35 static void * GlobObj = NULL;
       
    36 
       
    37 static int MatchTunAdapter(const char* aDevName)
       
    38 	{
       
    39 	const char match[] = "TAP";
       
    40 	const char matchl[] = "tap";
       
    41 
       
    42 	// Check the first 3 charecters
       
    43 	if (aDevName[0] == match[0]
       
    44 		&& aDevName[1] == match[1]
       
    45 		&& aDevName[2] == match[2])
       
    46 		return 1;
       
    47 	else if (aDevName[0] == matchl[0]
       
    48 		&& aDevName[1] == matchl[1]
       
    49 		&& aDevName[2] == matchl[2])
       
    50 		return 1;
       
    51 	else
       
    52 		return 0;
       
    53 	}
       
    54 
       
    55 static int GetIfName(IP_ADAPTER_INFO& iAdapterinfo)
       
    56 	{
       
    57 	DWORD			numInterfaces;
       
    58     HMODULE hModule = LoadLibraryA("iphlpapi.dll");
       
    59     if(!hModule)
       
    60         return -1;
       
    61     DWORD (WINAPI * pfGetNumberOfInterfaces)(PDWORD) = (DWORD (WINAPI * )(PDWORD))GetProcAddress(hModule, "GetNumberOfInterfaces");
       
    62     DWORD (WINAPI * pfGetAdaptersInfo)(PIP_ADAPTER_INFO,PULONG) = (DWORD (WINAPI *)(PIP_ADAPTER_INFO,PULONG))GetProcAddress(hModule, "GetAdaptersInfo");
       
    63 
       
    64 	// weiredness alert - windows returns found adapters+1
       
    65 	if (pfGetNumberOfInterfaces(&numInterfaces) != ERROR_SUCCESS)
       
    66 		return -1;
       
    67 
       
    68 	ULONG            ulOutBufLen;
       
    69 	ulOutBufLen = sizeof(IP_ADAPTER_INFO) * (numInterfaces);
       
    70 	
       
    71 	IP_ADAPTER_INFO  *pAdapterInfo = NULL;
       
    72 
       
    73 	pAdapterInfo = new IP_ADAPTER_INFO[numInterfaces];
       
    74 	
       
    75 	if (pAdapterInfo && (pfGetAdaptersInfo( pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS)) 
       
    76 		{
       
    77 		delete pAdapterInfo;
       
    78 		return -1;
       
    79 		}
       
    80 
       
    81 	IP_ADAPTER_INFO  *pCurAdapterInfo = pAdapterInfo;
       
    82 	int count = 1, matchCount = 0;
       
    83 	while (pCurAdapterInfo != NULL)
       
    84 		{	
       
    85 		// Optimize for when we already have the index
       
    86 		if (iAdapterinfo.Index == pCurAdapterInfo->Index)
       
    87 			{
       
    88 			matchCount++;
       
    89 			iAdapterinfo = *pCurAdapterInfo;
       
    90 			break;
       
    91 			}
       
    92 
       
    93 		if (MatchTunAdapter(pCurAdapterInfo->Description))
       
    94 			{
       
    95 			matchCount++;
       
    96 			iAdapterinfo = *pCurAdapterInfo;
       
    97 			}
       
    98 
       
    99 		pCurAdapterInfo = pCurAdapterInfo->Next;
       
   100 		count++;
       
   101 		}
       
   102 
       
   103 	if (matchCount == 0)
       
   104 		{
       
   105 		delete[] pAdapterInfo;
       
   106 		return -1;
       
   107 		}
       
   108 	else if (matchCount > 1)
       
   109 		{}
       
   110 	iAdapterinfo.Next = NULL;
       
   111 	delete[] pAdapterInfo;
       
   112 	return 0;
       
   113 	}
       
   114 
       
   115 static int WorkThread(HANDLE * iWinTapHandle);
       
   116 
       
   117 int InitDriver(HANDLE& iWinTapHandle, HANDLE& iThreadHandle, PACKET& iWritePacket, IP_ADAPTER_INFO& iAdapterinfo)
       
   118 // Sets up the PDD
       
   119 	{
       
   120 	int ret = 0;
       
   121 
       
   122 	if ((ret = GetIfName(iAdapterinfo)) != 0)
       
   123 		return ret;	
       
   124 
       
   125 	// Fromat the GUID to get the file name
       
   126 	char szFileName[256];	
       
   127 	sprintf(szFileName, ("%s%s%s"), ("\\\\.\\"), iAdapterinfo.AdapterName, (".tap"));
       
   128 
       
   129 	iWinTapHandle = CreateFileA(szFileName,
       
   130 								GENERIC_READ | GENERIC_WRITE,
       
   131 								FILE_SHARE_READ | FILE_SHARE_WRITE,
       
   132 								NULL,
       
   133 								OPEN_EXISTING,
       
   134 								FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
       
   135 								NULL);
       
   136 
       
   137 	if (iWinTapHandle == INVALID_HANDLE_VALUE)
       
   138 		{
       
   139 		//OUTPUT_ERROR("could not open file handle\n");
       
   140 		CloseHandle(iWinTapHandle);
       
   141 		ret = -1;
       
   142 		return ret;
       
   143 		}
       
   144 
       
   145 	
       
   146 	// set the device to connected
       
   147 	ULONG status = 1;
       
   148 	DWORD len;
       
   149 	if (!DeviceIoControl(iWinTapHandle,
       
   150 		TAP_IOCTL_SET_MEDIA_STATUS ,&status, sizeof(status), &status, sizeof(status), &len, NULL))
       
   151 		{
       
   152 		// FUDGE alert
       
   153 		if (!DeviceIoControl(iWinTapHandle,
       
   154 			TAP_IOCTL_SET_MEDIA_STATUS_V8 ,&status, sizeof(status), &status, sizeof(status), &len, NULL))
       
   155 			{
       
   156 			//OUTPUT_ERROR("Could not set media status to open\n");
       
   157 			return ret;
       
   158 			}
       
   159 		}
       
   160 	
       
   161 	// Call GetDriverName again, this time to reset the correct info for the connected Device
       
   162 	if((ret = GetIfName(iAdapterinfo)) != 0)
       
   163 		return ret;
       
   164 
       
   165 	iWritePacket.OverLapped.hEvent 		= CreateEvent(NULL, TRUE, FALSE, NULL);
       
   166 
       
   167 	u_long WorkerThreadId;
       
   168 	    
       
   169 	if ((iThreadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkThread, &iWinTapHandle,
       
   170 		CREATE_SUSPENDED,&WorkerThreadId)) != NULL)
       
   171 		{
       
   172 		ret = 0;
       
   173 		}
       
   174 	else
       
   175 		{
       
   176 		//OUTPUT_ERROR("CreateThread() failed to create worker thread");
       
   177 		}
       
   178 
       
   179 	return ret;
       
   180 	}
       
   181 
       
   182 void DoClose(HANDLE& iWinTapHandle, HANDLE& iThreadHandle, PACKET& iWritePacket)
       
   183 	{
       
   184 	if (iWinTapHandle != INVALID_HANDLE_VALUE)
       
   185 		{
       
   186 		// Cancel reads, Writes 
       
   187 		CancelIo(iWinTapHandle);
       
   188 
       
   189 		// Close read and write events
       
   190 		CloseHandle(iWritePacket.OverLapped.hEvent);
       
   191 		
       
   192 		// Close the read thread
       
   193 		if (!TerminateThread(iThreadHandle, 0))
       
   194 			{
       
   195 			//__KTRACE_OPT(KHARDWARE, Kern::Printf("Could not Terminate thread\n"));
       
   196 			}
       
   197 		CloseHandle(iThreadHandle);
       
   198 
       
   199 		DWORD status = 0, len;
       
   200 		if (!DeviceIoControl(iWinTapHandle,
       
   201 			TAP_IOCTL_SET_MEDIA_STATUS ,&status, sizeof(status), &status, sizeof(status), &len, NULL))
       
   202 			{
       
   203 			// Big fudge --
       
   204 			if (!DeviceIoControl(iWinTapHandle,
       
   205 				TAP_IOCTL_SET_MEDIA_STATUS_V8 ,&status, sizeof(status), &status, sizeof(status), &len, NULL))
       
   206 				{
       
   207 				//__KTRACE_OPT(KHARDWARE, Kern::Printf("Could not set media status to close\n"));
       
   208 				}
       
   209 			}
       
   210 
       
   211 		CloseHandle(iWinTapHandle);
       
   212 		iWinTapHandle = INVALID_HANDLE_VALUE;
       
   213 		}
       
   214 	}
       
   215 
       
   216 void SetIsr(void * aObject, TIsr aIsr)
       
   217 	{
       
   218 	assert(aIsr != NULL);
       
   219 	assert(aObject != NULL);
       
   220 	GlobObj = aObject;
       
   221 	GlobIsr = aIsr;
       
   222 	}
       
   223 
       
   224 static int WorkThread(HANDLE * iWinTapHandle)
       
   225 	{
       
   226     //__KTRACE_OPT(KHARDWARE, Kern::Printf("WorkThread(DEthernetWins * aDEthernetWins)"));
       
   227 	int err = 0;
       
   228 
       
   229 	u_char			buffer[2000];
       
   230 	PACKET			m_ReadPacket;
       
   231 
       
   232 	m_ReadPacket.OverLapped.hEvent 		= CreateEvent(NULL, TRUE, FALSE, NULL);
       
   233 	
       
   234 	while( err == 0 )
       
   235 		{		
       
   236 		m_ReadPacket.OverLapped.Offset 		= 0;
       
   237 		m_ReadPacket.OverLapped.OffsetHigh 	= 0;
       
   238 		m_ReadPacket.OverLapped.Internal	= 0;
       
   239 		m_ReadPacket.OverLapped.InternalHigh= 0;
       
   240 		m_ReadPacket.Buffer					= buffer;
       
   241 		m_ReadPacket.Length					= 0;
       
   242 
       
   243     	//__KTRACE_OPT(KHARDWARE, Kern::Printf("Starting to Read \n"));
       
   244 	    if (*iWinTapHandle != INVALID_HANDLE_VALUE)
       
   245 			{
       
   246 			if (!ReadFile(*iWinTapHandle, m_ReadPacket.Buffer, 2000, 
       
   247 				&(m_ReadPacket.Length), &m_ReadPacket.OverLapped))
       
   248 				{
       
   249 				if(GetLastError() != ERROR_IO_PENDING) 
       
   250 					{
       
   251 					//__KTRACE_OPT(KHARDWARE, Kern::Printf("m_ReadPacket() Failed "));
       
   252 					err = -3;
       
   253 					break;
       
   254 					}
       
   255 				
       
   256 				DWORD Result = WaitForSingleObject(m_ReadPacket.OverLapped.hEvent, INFINITE);
       
   257 
       
   258 				switch(Result)
       
   259 					{
       
   260 					// OVERLAPPED structure's event has been signaled. 
       
   261 					case WAIT_OBJECT_0:
       
   262 						if (GetOverlappedResult(*iWinTapHandle, &m_ReadPacket.OverLapped, 
       
   263 							&m_ReadPacket.Length, FALSE) == 0)
       
   264 							{
       
   265     						//__KTRACE_OPT(KHARDWARE, Kern::Printf("** Error in m_ReadPacket() **\n"));
       
   266 							err = -3;
       
   267 							}
       
   268 						else
       
   269 							{
       
   270 							// m_ReadPacket operation completed successfully.
       
   271     						//__KTRACE_OPT(KHARDWARE, Kern::Printf("** Completed in m_ReadPacket() **\n"));
       
   272 							err = 0;
       
   273 							}
       
   274 						break;
       
   275 					default:
       
   276 						 // An error has occurred in WaitForSingleObject.
       
   277 						 // This usually indicates a problem with the
       
   278 						// OVERLAPPED structure's event handle.
       
   279 						err = -3;
       
   280 						break;
       
   281 					}
       
   282 				}
       
   283 			else
       
   284 				{
       
   285 				err = 0;
       
   286     			//__KTRACE_OPT(KHARDWARE, Kern::Printf("** Completed in m_ReadPacket() **\n"));
       
   287 				}			
       
   288 			}
       
   289 		else
       
   290 			{
       
   291     		//__KTRACE_OPT(KHARDWARE, Kern::Printf("ReadPacket() No adaptor open\n"));
       
   292 			err = -1;
       
   293 			}
       
   294 		GlobIsr(GlobObj, err, buffer, &m_ReadPacket.Length);
       
   295 		}
       
   296 	CloseHandle(m_ReadPacket.OverLapped.hEvent);
       
   297 	return -3;
       
   298 	}
       
   299 
       
   300 int DoSend(PACKET& iWritePacket, HANDLE& iWinTapHandle)
       
   301 	{
       
   302     //__KTRACE_OPT(KHARDWARE, Kern::Printf("DEthernetWins::Send(TBuf8<KMaxEthernetPacket+32> &aBuffer)"));
       
   303     int err;
       
   304     if ( iWinTapHandle != INVALID_HANDLE_VALUE )
       
   305 		{
       
   306 		iWritePacket.OverLapped.Offset 		= 0;
       
   307 		iWritePacket.OverLapped.OffsetHigh 	= 0;
       
   308 		iWritePacket.OverLapped.Internal		= 0;
       
   309 		iWritePacket.OverLapped.InternalHigh	= 0;
       
   310 		
       
   311 		if(!WriteFile(iWinTapHandle, iWritePacket.Buffer, iWritePacket.Length, NULL, &iWritePacket.OverLapped))
       
   312 			{
       
   313 			if(GetLastError() != ERROR_IO_PENDING) 
       
   314 				{
       
   315 				//__KTRACE_OPT(KHARDWARE, Kern::Printf("WriteFile() Failed  "));
       
   316 				err = -23; //KErrWrite
       
   317 				return err;
       
   318 				}
       
   319 			else	//Pending Write
       
   320 				{
       
   321 				DWORD written;
       
   322 				DWORD Result = WaitForSingleObject(iWritePacket.OverLapped.hEvent, INFINITE);
       
   323 				switch(Result)
       
   324 					{
       
   325 					// OVERLAPPED structure's event has been signaled. 
       
   326 					case WAIT_OBJECT_0:
       
   327 						if (!GetOverlappedResult(iWinTapHandle, &iWritePacket.OverLapped, &written, FALSE))
       
   328 							{
       
   329 			            	//__KTRACE_OPT(KHARDWARE, Kern::Printf("** Error in WritePacket() **\n"));
       
   330 							err = -23; //KErrWrite
       
   331 							}
       
   332 						else
       
   333 							{
       
   334 							// Write operation completed successfully.
       
   335             				//__KTRACE_OPT(KHARDWARE, Kern::Printf("** Completed in WritePacket() **"));
       
   336 							err = 0;
       
   337 							}
       
   338 						break;
       
   339 					default:
       
   340 						 // An error has occurred in WaitForSingleObject.
       
   341 						 // This usually indicates a problem with the
       
   342 						// OVERLAPPED structure's event handle.
       
   343 						err = -23; //KErrWrite
       
   344 						break;
       
   345 					}
       
   346 				}
       
   347 			}
       
   348 		else //Write went fine
       
   349 			{
       
   350             //__KTRACE_OPT(KHARDWARE, Kern::Printf("** Completed in WritePacket() **\n"));
       
   351 			err = 0;
       
   352 			}
       
   353 		}
       
   354     else
       
   355 		{
       
   356         //__KTRACE_OPT(KHARDWARE, Kern::Printf("WritePacket() No adaptor open\n"));
       
   357 		err = -12; //KErrPathNotFound
       
   358 		}
       
   359     return err;
       
   360 	}