--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/networking/winsockprt/src/wsp_resolver.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,387 @@
+// wsp_resolver.cpp
+//
+// Copyright (c) 2002 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <winsock2.h>
+// Prevent e32std.inl from failing to compile with "ambiguous access to overloaded function".
+#define memmove _memmove
+#define memset _memset
+//
+#include <e32math.h>
+#include <in_sock.h>
+#include <utf.h>
+#include "wsp_resolver.h"
+#include "wsp_session.h"
+#include "wsp_factory.h"
+#include "wsp_panic.h"
+#include "wsp_log.h"
+
+
+//
+// Constants.
+//
+
+_LIT(KWspResolverWorkerThreadNameFormat, "WinSockPrtResolverWorkerThread_%x_%d");
+const TInt KWspResolverWorkerThreadNameLength = 64;
+const TInt KWspResolverWorkerThreadStackSize = KDefaultStackSize;
+
+
+//
+// RWin32Socket.
+//
+
+RWin32Resolver::RWin32Resolver()
+ : iNameRecordPckg(NULL, 0, 0)
+ {
+ }
+
+TInt RWin32Resolver::Open(RWin32Factory& aFactory)
+ {
+ WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Open: this: 0x%x"), this));
+ return CreateSubSession(aFactory, CWin32Factory::ENewResolver);
+ }
+
+void RWin32Resolver::Close()
+ {
+ WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Close: this: 0x%x"), this));
+ RWin32SubSession::Close();
+ }
+
+TInt RWin32Resolver::GetByName(TNameRecord& aName, TRequestStatus& aStatus)
+ {
+ WSP_LOG(WspLog::Printf(_L("RWin32Resolver::GetByName: this: 0x%x"), this));
+ iNameRecordPckg.Set(reinterpret_cast<TUint8*>(&aName), sizeof(TNameRecord),sizeof(TNameRecord));
+ iWin32Message.Set(CWin32Resolver::EGetByName, iNameRecordPckg, aStatus);
+ return MakeRequest(iWin32Message);
+ }
+
+TInt RWin32Resolver::GetByAddress(TNameRecord& aName, TRequestStatus& aStatus)
+ {
+ WSP_LOG(WspLog::Printf(_L("RWin32Resolver::GetByAddress: this: 0x%x"), this));
+ iNameRecordPckg.Set(reinterpret_cast<TUint8*>(&aName), sizeof(TNameRecord),sizeof(TNameRecord));
+ iWin32Message.Set(CWin32Resolver::EGetByAddress, iNameRecordPckg, aStatus);
+ return MakeRequest(iWin32Message);
+ }
+
+void RWin32Resolver::Cancel()
+ {
+ WSP_LOG(WspLog::Printf(_L("RWin32Resolver::Cancel: this: 0x%x"), this));
+ TWin32Message cancelWin32Message;
+ cancelWin32Message.Set(CWin32Resolver::ECancel);
+ MakeRequest(cancelWin32Message); // Throw away return code - can't do anything useful with it.
+ }
+
+
+//
+// CWin32Resolver.
+//
+
+CWin32Resolver* CWin32Resolver::NewL(CWin32Scheduler& aScheduler)
+ {
+ CWin32Resolver* self = new(ELeave) CWin32Resolver(aScheduler);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CWin32Resolver::CWin32Resolver(CWin32Scheduler& aScheduler)
+ : CWin32SubSession(aScheduler)
+ {
+ }
+
+void CWin32Resolver::ConstructL()
+ {
+ CWin32SubSession::ConstructL();
+ }
+
+CWin32Resolver::~CWin32Resolver()
+ {
+ }
+
+void CWin32Resolver::Run()
+ {
+ iMessage->Complete(iError);
+ iMessage = NULL;
+ iWorkerThread.Close();
+ }
+
+void CWin32Resolver::ServiceL(TWin32Message& aMessage)
+ {
+ switch (aMessage.OppCode())
+ {
+ case EGetByName:
+ case EGetByAddress:
+ {
+ __ASSERT_DEBUG(iMessage == NULL, Panic(EWinSockPrtCWin32ResolverMultipleRequests));
+ iMessage = &aMessage;
+ CreateWorkerThread();
+ break;
+ }
+ case ECancel:
+ {
+ Cancel();
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EWinSockPrtInvalidResolverOppCode));
+ }
+ }
+ }
+
+void CWin32Resolver::Cancel()
+ {
+ if (iWorkerThread.Handle() && (iWorkerThread.ExitType() == EExitPending))
+ {
+ iWorkerThread.Kill(KErrCancel);
+ iMessage->Complete(KErrCancel);
+ iMessage = NULL;
+ iWorkerThread.Close();
+ }
+ }
+
+void CWin32Resolver::CreateWorkerThread()
+ {
+ TBuf<KWspResolverWorkerThreadNameLength> threadName;
+ threadName.Format(KWspResolverWorkerThreadNameFormat, this, Math::Rand(iRandSeed));
+ TInt err = iWorkerThread.Create(threadName, WorkerThreadStart, KWspResolverWorkerThreadStackSize, NULL, this, EOwnerThread);
+ if (err == KErrNone)
+ {
+ iWorkerThread.Resume();
+ }
+ else
+ {
+ iMessage->Complete(err);
+ }
+ }
+
+
+//
+// CWin32Resolver worker thread methods.
+//
+
+TInt CWin32Resolver::WorkerThreadStart(TAny* aPtr)
+ {
+ CWin32Resolver* self = reinterpret_cast<CWin32Resolver*>(aPtr);
+
+ switch (self->iMessage->OppCode())
+ {
+ case EGetByName:
+ {
+ self->GetByName();
+ break;
+ }
+ case EGetByAddress:
+ {
+ self->GetByAddress();
+ break;
+ }
+ case ECancel:
+ default:
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverInvalidWorkerThreadRequest));
+ }
+ }
+
+ return KErrNone;
+ }
+
+void CWin32Resolver::GetByName()
+ {
+ TNameRecord& nameRecord = (TNameRecord&)*iMessage->WriteBuffer().Ptr();
+ struct hostent* hp;
+ 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.
+ if (narrowHostNameBuf == NULL)
+ {
+ iError = KErrNoMemory;
+ }
+ else
+ {
+ TPtr8 narrowHostNamePtr(narrowHostNameBuf->Des());
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowHostNamePtr, nameRecord.iName);
+ hp = gethostbyname(reinterpret_cast<const char*>(narrowHostNamePtr.PtrZ()));
+ delete narrowHostNameBuf;
+ if (hp)
+ {
+ TInetAddr& addr = reinterpret_cast<TInetAddr&>(nameRecord.iAddr);
+ __ASSERT_DEBUG(hp->h_addrtype == AF_INET, Panic(EWinSockPrtResolverInvalidFamily));
+ addr.SetFamily(KAfInet);
+ __ASSERT_DEBUG(hp->h_length == 4, Panic(EWinSockPrtResolverInvalidAddressLength));
+ TUint32* address = (TUint32*)hp->h_addr_list[0];
+ addr.SetAddress(htonl(*address));
+ iError = KErrNone;
+ }
+ else
+ {
+ iError = KErrNotFound;
+ }
+ }
+
+ if (!SetEvent(iEvent))
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverUnexpectedSetEventError));
+ }
+ }
+
+void CWin32Resolver::GetByAddress()
+ {
+ TNameRecord& nameRecord = (TNameRecord&)*iMessage->WriteBuffer().Ptr();
+ TInetAddr& addr = reinterpret_cast<TInetAddr&>(nameRecord.iAddr);
+ struct hostent* hp;
+ char addressBuf[4];
+ *((TUint32*)addressBuf) = htonl(addr.Address());
+ hp = gethostbyaddr(addressBuf, 4, AF_INET);
+ if (hp)
+ {
+ TPtrC8 narrowAddressPtr((TUint8*)hp->h_name, User::StringLength((TUint8*)hp->h_name));
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(nameRecord.iName, narrowAddressPtr);
+ iError = KErrNone;
+ }
+ else
+ {
+ iError = KErrNotFound;
+ }
+
+ if (!SetEvent(iEvent))
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverUnexpectedSetEventError));
+ }
+ }
+
+
+//
+// CWin32ResolverWrapper.
+//
+
+CWin32ResolverWrapper* CWin32ResolverWrapper::NewL(MWin32ResolverObserver& aObserver, RWin32Factory& aWin32Factory)
+ {
+ CWin32ResolverWrapper* self = new(ELeave) CWin32ResolverWrapper(aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL(aWin32Factory);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CWin32ResolverWrapper::~CWin32ResolverWrapper()
+ {
+ Cancel();
+ iWin32Resolver.Close();
+ }
+
+CWin32ResolverWrapper::CWin32ResolverWrapper(MWin32ResolverObserver& aObserver)
+ : CActive(CActive::EPriorityStandard), iObserver(aObserver)
+ {
+ }
+
+void CWin32ResolverWrapper::ConstructL(RWin32Factory& aWin32Factory)
+ {
+ User::LeaveIfError(iWin32Resolver.Open(aWin32Factory));
+ CActiveScheduler::Add(this);
+ }
+
+TInt CWin32ResolverWrapper::GetByName(TNameRecord& aName)
+ {
+ __ASSERT_DEBUG(!IsActive(), Panic(EWinSockPrtResolverWrapperGetByNameWhilstActive));
+ TInt err = iWin32Resolver.GetByName(aName, iStatus);
+ if (err == KErrNone)
+ {
+ SetActive();
+ }
+ return err;
+ }
+
+TInt CWin32ResolverWrapper::GetByAddress(TNameRecord& aName)
+ {
+ __ASSERT_DEBUG(!IsActive(), Panic(EWinSockPrtResolverWrapperGetByAddressWhilstActive));
+ TInt err = iWin32Resolver.GetByAddress(aName, iStatus);
+ if (err == KErrNone)
+ {
+ SetActive();
+ }
+ return err;
+ }
+
+void CWin32ResolverWrapper::DoCancel()
+ {
+ iWin32Resolver.Cancel();
+ }
+
+void CWin32ResolverWrapper::RunL()
+ {
+ iObserver.HandleWin32ResolverCompletion(iStatus.Int());
+ }
+
+TInt CWin32ResolverWrapper::RunError(TInt /*aError*/)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EWinSockPrtResolverWrapperUnexpectedRunError));
+ return 0;
+ }
+
+
+//
+// CWinSockResolver.
+//
+
+CWinSockResolver* CWinSockResolver::NewL(RWin32Factory& aFactory)
+ {
+ CWinSockResolver* self = new(ELeave) CWinSockResolver();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFactory);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CWinSockResolver::~CWinSockResolver()
+ {
+ delete iResolverWrapper;
+ }
+
+void CWinSockResolver::CancelCurrentOperation()
+ {
+ iResolverWrapper->Cancel();
+ }
+
+void CWinSockResolver::GetByName(TNameRecord& aName)
+ {
+ iResolverWrapper->GetByName(aName);
+ }
+
+void CWinSockResolver::GetByAddress(TNameRecord& aName)
+ {
+ iResolverWrapper->GetByAddress(aName);
+ }
+
+void CWinSockResolver::SetHostName(TDes& /*aNameBuf*/)
+ {
+ // TODO:
+ ASSERT(EFalse);
+ }
+
+void CWinSockResolver::GetHostName(TDes& /*aNameBuf*/)
+ {
+ // TODO:
+ ASSERT(EFalse);
+ }
+
+void CWinSockResolver::HandleWin32ResolverCompletion(TInt aError)
+ {
+ iNotify->QueryComplete(aError);
+ }
+
+CWinSockResolver::CWinSockResolver()
+ {
+ }
+
+void CWinSockResolver::ConstructL(RWin32Factory& aFactory)
+ {
+ iResolverWrapper = CWin32ResolverWrapper::NewL(*this, aFactory);
+ }