plugins/networking/winsockprt/src/wsp_resolver.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // wsp_resolver.cpp
       
     2 // 
       
     3 // Copyright (c) 2002 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "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 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <winsock2.h>
       
    14 // Prevent e32std.inl from failing to compile with "ambiguous access to overloaded function".
       
    15 #define memmove _memmove
       
    16 #define memset _memset
       
    17 //
       
    18 #include <e32math.h>
       
    19 #include <in_sock.h>
       
    20 #include <utf.h>
       
    21 #include "wsp_resolver.h"
       
    22 #include "wsp_session.h"
       
    23 #include "wsp_factory.h"
       
    24 #include "wsp_panic.h"
       
    25 #include "wsp_log.h"
       
    26 
       
    27 
       
    28 //
       
    29 // Constants.
       
    30 //
       
    31 
       
    32 _LIT(KWspResolverWorkerThreadNameFormat, "WinSockPrtResolverWorkerThread_%x_%d");
       
    33 const TInt  KWspResolverWorkerThreadNameLength =  64;
       
    34 const TInt KWspResolverWorkerThreadStackSize = KDefaultStackSize;
       
    35 
       
    36 
       
    37 //
       
    38 // RWin32Socket.
       
    39 //
       
    40 
       
    41 RWin32Resolver::RWin32Resolver()
       
    42 	: iNameRecordPckg(NULL, 0, 0)
       
    43 	{
       
    44 	}
       
    45 
       
    46 TInt RWin32Resolver::Open(RWin32Factory& aFactory)
       
    47 	{
       
    48 	WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Open: this: 0x%x"), this));
       
    49 	return CreateSubSession(aFactory, CWin32Factory::ENewResolver);
       
    50 	}
       
    51 
       
    52 void RWin32Resolver::Close()
       
    53 	{
       
    54 	WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Close: this: 0x%x"), this));
       
    55 	RWin32SubSession::Close();
       
    56 	}
       
    57 
       
    58 TInt RWin32Resolver::GetByName(TNameRecord& aName, TRequestStatus& aStatus)
       
    59 	{
       
    60 	WSP_LOG(WspLog::Printf(_L("RWin32Resolver::GetByName: this: 0x%x"), this));
       
    61 	iNameRecordPckg.Set(reinterpret_cast<TUint8*>(&aName), sizeof(TNameRecord),sizeof(TNameRecord));
       
    62 	iWin32Message.Set(CWin32Resolver::EGetByName, iNameRecordPckg, aStatus);
       
    63 	return MakeRequest(iWin32Message);
       
    64 	}
       
    65 
       
    66 TInt RWin32Resolver::GetByAddress(TNameRecord& aName, TRequestStatus& aStatus)
       
    67 	{
       
    68 	WSP_LOG(WspLog::Printf(_L("RWin32Resolver::GetByAddress: this: 0x%x"), this));
       
    69 	iNameRecordPckg.Set(reinterpret_cast<TUint8*>(&aName), sizeof(TNameRecord),sizeof(TNameRecord));
       
    70 	iWin32Message.Set(CWin32Resolver::EGetByAddress, iNameRecordPckg, aStatus);
       
    71 	return MakeRequest(iWin32Message);
       
    72 	}
       
    73 
       
    74 void RWin32Resolver::Cancel()
       
    75 	{
       
    76 	WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Cancel: this: 0x%x"), this));
       
    77 	TWin32Message cancelWin32Message;
       
    78 	cancelWin32Message.Set(CWin32Resolver::ECancel);
       
    79 	MakeRequest(cancelWin32Message); // Throw away return code - can't do anything useful with it.
       
    80 	}
       
    81 
       
    82 
       
    83 //
       
    84 // CWin32Resolver.
       
    85 //
       
    86 
       
    87 CWin32Resolver* CWin32Resolver::NewL(CWin32Scheduler& aScheduler)
       
    88 	{
       
    89 	CWin32Resolver* self = new(ELeave) CWin32Resolver(aScheduler);
       
    90 	CleanupStack::PushL(self);
       
    91 	self->ConstructL();
       
    92 	CleanupStack::Pop(self);
       
    93 	return self;
       
    94 	}
       
    95 
       
    96 CWin32Resolver::CWin32Resolver(CWin32Scheduler& aScheduler)
       
    97 	: CWin32SubSession(aScheduler)
       
    98 	{
       
    99 	}
       
   100 
       
   101 void CWin32Resolver::ConstructL()
       
   102 	{
       
   103 	CWin32SubSession::ConstructL();
       
   104 	}
       
   105 
       
   106 CWin32Resolver::~CWin32Resolver()
       
   107 	{
       
   108 	}
       
   109 
       
   110 void CWin32Resolver::Run()
       
   111 	{
       
   112 	iMessage->Complete(iError);
       
   113 	iMessage = NULL;
       
   114 	iWorkerThread.Close();
       
   115 	}
       
   116 
       
   117 void CWin32Resolver::ServiceL(TWin32Message& aMessage)
       
   118 	{
       
   119 	switch (aMessage.OppCode())
       
   120 		{
       
   121 		case EGetByName:
       
   122 		case EGetByAddress:
       
   123 			{
       
   124 			__ASSERT_DEBUG(iMessage == NULL, Panic(EWinSockPrtCWin32ResolverMultipleRequests));
       
   125 			iMessage = &aMessage;
       
   126 			CreateWorkerThread();
       
   127 			break;
       
   128 			}
       
   129 		case ECancel:
       
   130 			{
       
   131 			Cancel();
       
   132 			break;
       
   133 			}
       
   134 		default:
       
   135 			{
       
   136 			__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtInvalidResolverOppCode));
       
   137 			}
       
   138 		}
       
   139 	}
       
   140 
       
   141 void CWin32Resolver::Cancel()
       
   142 	{
       
   143 	if (iWorkerThread.Handle() && (iWorkerThread.ExitType() == EExitPending))
       
   144 		{
       
   145 		iWorkerThread.Kill(KErrCancel);
       
   146 		iMessage->Complete(KErrCancel);
       
   147 		iMessage = NULL;
       
   148 		iWorkerThread.Close();
       
   149 		}
       
   150 	}
       
   151 
       
   152 void CWin32Resolver::CreateWorkerThread()
       
   153 	{
       
   154 	TBuf<KWspResolverWorkerThreadNameLength> threadName;
       
   155 	threadName.Format(KWspResolverWorkerThreadNameFormat, this, Math::Rand(iRandSeed));
       
   156 	TInt err = iWorkerThread.Create(threadName, WorkerThreadStart, KWspResolverWorkerThreadStackSize, NULL, this, EOwnerThread);
       
   157 	if (err == KErrNone)
       
   158 		{
       
   159 		iWorkerThread.Resume();
       
   160 		}
       
   161 	else
       
   162 		{
       
   163 		iMessage->Complete(err);
       
   164 		}
       
   165 	}
       
   166 
       
   167 
       
   168 //
       
   169 // CWin32Resolver worker thread methods.
       
   170 //
       
   171 
       
   172 TInt CWin32Resolver::WorkerThreadStart(TAny* aPtr)
       
   173 	{
       
   174 	CWin32Resolver* self = reinterpret_cast<CWin32Resolver*>(aPtr);
       
   175 
       
   176 	switch (self->iMessage->OppCode())
       
   177 		{
       
   178 		case EGetByName:
       
   179 			{
       
   180 			self->GetByName();
       
   181 			break;
       
   182 			}
       
   183 		case EGetByAddress:
       
   184 			{
       
   185 			self->GetByAddress();
       
   186 			break;
       
   187 			}
       
   188 		case ECancel:
       
   189 		default:
       
   190 			{
       
   191 			__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverInvalidWorkerThreadRequest));
       
   192 			}
       
   193 		}
       
   194 
       
   195 	return KErrNone;
       
   196 	}
       
   197 
       
   198 void CWin32Resolver::GetByName()
       
   199 	{
       
   200 	TNameRecord& nameRecord = (TNameRecord&)*iMessage->WriteBuffer().Ptr();
       
   201 	struct hostent* hp;
       
   202 	HBufC8* narrowHostNameBuf = HBufC8::New(nameRecord.iName.MaxLength() + 1); // Note, this is one bigger than the size of THostName to allow for a null termination character.
       
   203 	if (narrowHostNameBuf == NULL)
       
   204 		{
       
   205 		iError = KErrNoMemory;
       
   206 		}
       
   207 	else
       
   208 		{
       
   209 		TPtr8 narrowHostNamePtr(narrowHostNameBuf->Des());
       
   210 		CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowHostNamePtr, nameRecord.iName);
       
   211 		hp = gethostbyname(reinterpret_cast<const char*>(narrowHostNamePtr.PtrZ()));
       
   212 		delete narrowHostNameBuf;
       
   213 		if (hp)
       
   214 			{
       
   215 			TInetAddr& addr = reinterpret_cast<TInetAddr&>(nameRecord.iAddr);
       
   216 			__ASSERT_DEBUG(hp->h_addrtype == AF_INET, Panic(EWinSockPrtResolverInvalidFamily));
       
   217 			addr.SetFamily(KAfInet);
       
   218 			__ASSERT_DEBUG(hp->h_length == 4, Panic(EWinSockPrtResolverInvalidAddressLength));
       
   219 			TUint32* address = (TUint32*)hp->h_addr_list[0];
       
   220 			addr.SetAddress(htonl(*address));
       
   221 			iError = KErrNone;
       
   222 			}
       
   223 		else
       
   224 			{
       
   225 			iError = KErrNotFound;
       
   226 			}
       
   227 		}
       
   228 	
       
   229 	if (!SetEvent(iEvent))
       
   230 		{
       
   231 		__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverUnexpectedSetEventError));
       
   232 		}
       
   233 	}
       
   234 
       
   235 void CWin32Resolver::GetByAddress()
       
   236 	{
       
   237 	TNameRecord& nameRecord = (TNameRecord&)*iMessage->WriteBuffer().Ptr();
       
   238 	TInetAddr& addr = reinterpret_cast<TInetAddr&>(nameRecord.iAddr);
       
   239 	struct hostent* hp;
       
   240 	char addressBuf[4];
       
   241 	*((TUint32*)addressBuf) = htonl(addr.Address());
       
   242 	hp = gethostbyaddr(addressBuf, 4, AF_INET);
       
   243 	if (hp)
       
   244 		{
       
   245 		TPtrC8 narrowAddressPtr((TUint8*)hp->h_name, User::StringLength((TUint8*)hp->h_name));
       
   246 		CnvUtfConverter::ConvertToUnicodeFromUtf8(nameRecord.iName, narrowAddressPtr);
       
   247 		iError = KErrNone;
       
   248 		}
       
   249 	else
       
   250 		{
       
   251 		iError = KErrNotFound;
       
   252 		}
       
   253 	
       
   254 	if (!SetEvent(iEvent))
       
   255 		{
       
   256 		__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverUnexpectedSetEventError));
       
   257 		}
       
   258 	}
       
   259 
       
   260 
       
   261 //
       
   262 // CWin32ResolverWrapper.
       
   263 //
       
   264 
       
   265 CWin32ResolverWrapper* CWin32ResolverWrapper::NewL(MWin32ResolverObserver& aObserver, RWin32Factory& aWin32Factory)
       
   266 	{
       
   267 	CWin32ResolverWrapper* self = new(ELeave) CWin32ResolverWrapper(aObserver);
       
   268 	CleanupStack::PushL(self);
       
   269 	self->ConstructL(aWin32Factory);
       
   270 	CleanupStack::Pop(self);
       
   271 	return self;
       
   272 	}
       
   273 
       
   274 CWin32ResolverWrapper::~CWin32ResolverWrapper()
       
   275 	{
       
   276 	Cancel();
       
   277 	iWin32Resolver.Close();
       
   278 	}
       
   279 
       
   280 CWin32ResolverWrapper::CWin32ResolverWrapper(MWin32ResolverObserver& aObserver)
       
   281 	: CActive(CActive::EPriorityStandard), iObserver(aObserver)
       
   282 	{
       
   283 	}
       
   284 
       
   285 void CWin32ResolverWrapper::ConstructL(RWin32Factory& aWin32Factory)
       
   286 	{
       
   287 	User::LeaveIfError(iWin32Resolver.Open(aWin32Factory));
       
   288 	CActiveScheduler::Add(this);
       
   289 	}
       
   290 
       
   291 TInt CWin32ResolverWrapper::GetByName(TNameRecord& aName)
       
   292 	{
       
   293 	__ASSERT_DEBUG(!IsActive(), Panic(EWinSockPrtResolverWrapperGetByNameWhilstActive));
       
   294 	TInt err = iWin32Resolver.GetByName(aName, iStatus);
       
   295 	if (err == KErrNone)
       
   296 		{
       
   297 		SetActive();
       
   298 		}
       
   299 	return err;
       
   300 	}
       
   301 
       
   302 TInt CWin32ResolverWrapper::GetByAddress(TNameRecord& aName)
       
   303 	{
       
   304 	__ASSERT_DEBUG(!IsActive(), Panic(EWinSockPrtResolverWrapperGetByAddressWhilstActive));
       
   305 	TInt err = iWin32Resolver.GetByAddress(aName, iStatus);
       
   306 	if (err == KErrNone)
       
   307 		{
       
   308 		SetActive();
       
   309 		}
       
   310 	return err;
       
   311 	}
       
   312 
       
   313 void CWin32ResolverWrapper::DoCancel()
       
   314 	{
       
   315 	iWin32Resolver.Cancel();
       
   316 	}
       
   317 
       
   318 void CWin32ResolverWrapper::RunL()
       
   319 	{
       
   320 	iObserver.HandleWin32ResolverCompletion(iStatus.Int());
       
   321 	}
       
   322 
       
   323 TInt CWin32ResolverWrapper::RunError(TInt /*aError*/)
       
   324 	{
       
   325 	__ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverWrapperUnexpectedRunError));
       
   326 	return 0;
       
   327 	}
       
   328 
       
   329 
       
   330 //
       
   331 // CWinSockResolver.
       
   332 //
       
   333 
       
   334 CWinSockResolver* CWinSockResolver::NewL(RWin32Factory& aFactory)
       
   335 	{
       
   336 	CWinSockResolver* self = new(ELeave) CWinSockResolver();
       
   337 	CleanupStack::PushL(self);
       
   338 	self->ConstructL(aFactory);
       
   339 	CleanupStack::Pop(self);
       
   340 	return self;
       
   341 	}
       
   342 
       
   343 CWinSockResolver::~CWinSockResolver()
       
   344 	{
       
   345 	delete iResolverWrapper;
       
   346 	}
       
   347 
       
   348 void CWinSockResolver::CancelCurrentOperation()
       
   349 	{
       
   350 	iResolverWrapper->Cancel();
       
   351 	}
       
   352 
       
   353 void CWinSockResolver::GetByName(TNameRecord& aName)
       
   354 	{
       
   355 	iResolverWrapper->GetByName(aName);
       
   356 	}
       
   357 
       
   358 void CWinSockResolver::GetByAddress(TNameRecord& aName)
       
   359 	{
       
   360 	iResolverWrapper->GetByAddress(aName);
       
   361 	}
       
   362 
       
   363 void CWinSockResolver::SetHostName(TDes& /*aNameBuf*/)
       
   364 	{
       
   365 	// TODO:
       
   366 	ASSERT(EFalse);
       
   367 	}
       
   368 
       
   369 void CWinSockResolver::GetHostName(TDes& /*aNameBuf*/)
       
   370 	{
       
   371 	// TODO:
       
   372 	ASSERT(EFalse);
       
   373 	}
       
   374 
       
   375 void CWinSockResolver::HandleWin32ResolverCompletion(TInt aError)
       
   376 	{
       
   377 	iNotify->QueryComplete(aError);
       
   378 	}
       
   379 
       
   380 CWinSockResolver::CWinSockResolver()
       
   381 	{
       
   382 	}
       
   383 
       
   384 void CWinSockResolver::ConstructL(RWin32Factory& aFactory)
       
   385 	{
       
   386 	iResolverWrapper = CWin32ResolverWrapper::NewL(*this, aFactory);
       
   387 	}