Implemented RObjectIx-based memoryaccess APIs.
Upshot is that objinfo now works again on platforms that define FSHELL_NO_DOBJECTIX_SUPPORT.
// 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);
}