diff -r 000000000000 -r b26acd06ea60 sdkcreationmw/sdkruntimes/wsock/src/wsock.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdkcreationmw/sdkruntimes/wsock/src/wsock.cpp Mon Mar 08 12:09:11 2010 +0530 @@ -0,0 +1,1525 @@ +/* +* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#define TRACE_PREFIX "WSOCK: " +#include "wsock.h" +#include +#include +#include +#include +#include "WinsockAgentFactory.h" +#include "WinsockProtocolFamily.h" +#include "WinsockInterfaceFactory.h" +#include "WinsockUtils.h" + +_LIT(KProxyTableName,"Proxies"); +static const TInt KDefaultProxyPort = 8080; + +enum TProxyUpdateFlags +{ + TProxyUpdateUseProxy = 0x00000001, + TProxyUpdateServerName = 0x00000002, + TProxyUpdateProtocol = 0x00000004, + TProxyUpdatePort = 0x00000008, + TProxyUpdateName = 0x00000010 +}; + +enum TBearerUpdateFlags +{ + TBearerUpdateAgent = 0x00000001, + TBearerUpdateSocketActivityTimeout = 0x00000002, + TBearerUpdateSessionClosedTimeout = 0x00000004, + TBearerUpdateSocketClosedTimeout = 0x00000008 +}; + +enum TServiceUpdateFlags +{ + TServiceUpdateNetworks = 0x00000001, + TServiceUpdateAuthPrompt = 0x00000002, + TServiceUpdateAPN = 0x00000004, + TServiceUpdateAPType = 0x00000008 +}; + +enum TIAPUpdateFlags +{ + TIAPUpdateService = 0x00000001, + TIAPUpdateServiceType = 0x00000002, + TIAPUpdateBearer = 0x00000004, + TIAPUpdateBearerType = 0x00000008, + TIAPUpdateNetwork = 0x00000010 +}; + +enum TWapIpBearerUpdateFlags +{ + TWapIpBearerUpdateIAP = 0x00000001, + TWapIpBearerUpdateWspOption = 0x00000002, + TWapIpBearerUpdateProxyPort = 0x00000004, + TWapIpBearerUpdateSecurity = 0x00000008, + TWapIpBearerUpdateGatewayAddress = 0x00000010, + TWapIpBearerUpdateProxyLoginName = 0x00000020, + TWapIpBearerUpdateProxyLoginPass = 0x00000040 +}; + +#ifdef _REALLY_DEBUG +extern "C" int __stdcall IsDebuggerPresent(void); +void WsockAssert(const TText* s, const TText* file, TInt line) +{ + TRACE1("Assertion failed: %s",s); + TRACE1("File: %s",file); + TRACE1("Line: %d",line); + + #ifdef WSOCK_ASSERT_BREAKPOINT + if (IsDebuggerPresent()) + { + __BREAKPOINT(); + } + #endif +} +TInt WsockAssertSuccess(TInt err, const TText* s, const TText* file, TInt line) +{ + if (err != KErrNone) + { + TRACE1("Unexpected error: %d",err); + TRACE1("Expression: %s",s); + TRACE1("File: %s",file); + TRACE1("Line: %d",line); + + #ifdef WSOCK_ASSERT_BREAKPOINT + if (IsDebuggerPresent()) + { + __BREAKPOINT(); + } + #endif + } + return err; +} +void WsockLeave(TInt err, const TText* s, const TText* file, TInt line) +{ + TRACE2("Leaving with error %d (%s)",err,s); + TRACE1("File: %s",file); + TRACE1("Line: %d",line); + + #ifdef WSOCK_ASSERT_BREAKPOINT + if (IsDebuggerPresent()) + { + __BREAKPOINT(); + } + #endif + User::Leave(err); +} +void WsockLeaveIfError(TInt err, const TText* s, const TText* file, TInt line) +{ + if (err != KErrNone) + { + TRACE1("Unexpected error: %d",err); + TRACE1("Expression: %s",s); + TRACE1("File: %s",file); + TRACE1("Line: %d",line); + + #ifdef WSOCK_ASSERT_BREAKPOINT + if (IsDebuggerPresent()) + { + __BREAKPOINT(); + } + #endif + User::Leave(err); + } +} +#endif // _REALLY_DEBUG + +// WSOCK lock +class WsockLock +{ +private: + TBool iLocked; + RMutex iMutex; +public: + WsockLock() : iLocked(EFalse) {} + ~WsockLock() { + ASSERT(!iLocked); + if (iLocked) Unlock(); + } + + // Locks the mutex, returning KErrNone on success + TInt Lock() + { + _LIT(KMutexName, "WsockLock"); + ASSERT(!iLocked); + TInt err = iMutex.CreateGlobal(KMutexName, EOwnerThread); + while (err == KErrAlreadyExists) { + err = iMutex.OpenGlobal(KMutexName, EOwnerThread); + if (err == KErrNone) { + TRACE("opened existing CommDb mutex"); + } else { + TRACE("couldn't either create or open CommDb mutex, retry"); + err = iMutex.CreateGlobal(KMutexName, EOwnerThread); + } + } + ASSERT_SUCCESS(err); + if (err == KErrNone) { + iMutex.Wait(); + iLocked = ETrue; + } + return err; + } + + // Locks the mutex, leaves on failure + void LockL() + { + LEAVE_IF_ERROR(Lock()); + } + + // Locks the mutex, leaves on failure, sets up cleanup callback + void LockLC() + { + LEAVE_IF_ERROR(Lock()); + CleanupStack::PushL(TCleanupItem(UnlockOnLeave,this)); + } + + // Releases the mutex + void Unlock() + { + ASSERT(iLocked); + if (iLocked) { + iLocked = EFalse; + iMutex.Signal(); + iMutex.Close(); + } + } + + // Cleanup callback. Unlocks WsockLock + static void UnlockOnLeave(TAny* aPtr) + { + WsockLock* lock = (WsockLock*)aPtr; + lock->Unlock(); + } +}; + +// Cleanup callback. Rolls back the transaction +static void WsockRollbackOnLeave(TAny* aDb) +{ + CCommsDatabase* db = (CCommsDatabase*)aDb; + db->RollbackTransaction(); +} + +// Begins CommDb transaction +static void WsockBeginCommDbTransactionLC(CCommsDatabase* aDb) +{ + TInt err = aDb->BeginTransaction(); + TInt retriesLeft = KRetryCount; + while ((err == KErrLocked || err == KErrAccessDenied) && --retriesLeft) + { + User::After(KRetryWait); + err = aDb->BeginTransaction(); + } + LEAVE_IF_ERROR(err); // Leaves if error + CleanupStack::PushL(TCleanupItem(WsockRollbackOnLeave,aDb)); +} + +// Checks proxy settings in CommDb. Returns ETrue if transaction needs +// to be commited. If aProxyHost is NULL, does not check the proxy values, +// only makes sure that there is on and only one proxy record in CommDb. +// If we allow more than one record, Symbian HTTP framework gets confused +// what to use and more often than not uses the wrong one. Particularly, +// it appears to prefer proxy records associated with OutgoingGPRS service, +// ignoring LANService. +static TBool WsockCheckProxyL(CCommsDatabase* aDb, + TUint32 aServiceId, + TBool aUseProxy, + const TDesC* aProxyHost, + TUint aProxyPort) +{ + _LIT(KProxyProtocol,"http"); + _LIT(KProxyName, "Winsock Proxy Settings"); + const TDesC& TableName = KProxyTableName(); + const TDesC& ServiceType = KWinsockServiceType(); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC ISPColumn(PROXY_ISP); + TPtrC UseProxyColumn(PROXY_USE_PROXY_SERVER); + TPtrC ServiceTypeColumn(PROXY_SERVICE_TYPE); + TPtrC ServerNameColumn(PROXY_SERVER_NAME); + TPtrC ProtocolColumn(PROXY_PROTOCOL_NAME); + TPtrC ProxyPortColumn(PROXY_PORT_NUMBER); + + // Delete everything except our record + TInt err; + TUint32 id = 0; + TBool recordFound = EFalse; + TBool databaseUpdated = EFalse; + if (view->GotoFirstRecord() == KErrNone) + { + TUint32 number = 0; + TBuf text; + do + { + // This one must exist + TRAP(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + // We detect our record based on the values of "ISP" + // and "ProxyServiceType" columns + number = 0; + TRAP(err, view->ReadUintL(ISPColumn,number)); + TRAP(err, view->ReadTextL(ServiceTypeColumn,text)); + TRACE4(" %S #%d -> %d,%S",&TableName,id,number,&text); + if (err == KErrNone && + text == ServiceType && + number == aServiceId && + !recordFound) + { + TUint updateFlags = 0; + if (aProxyHost) + { + TBool useProxy = EFalse; + TRAP(err, view->ReadBoolL(UseProxyColumn,useProxy)); + if (err != KErrNone || useProxy != aUseProxy) + { + updateFlags |= TProxyUpdateUseProxy; + } + + HBufC* val = NULL; + TRAP(err, val = view->ReadLongTextLC(ServerNameColumn); + CleanupStack::Pop(val)); + if (err != KErrNone || *val != *aProxyHost) + { + updateFlags |= TProxyUpdateServerName; + } + delete val; + + TRAP(err, view->ReadUintL(ProxyPortColumn,number)); + if (err != KErrNone || number != aProxyPort) + { + updateFlags |= TProxyUpdatePort; + } + } + + TRAP(err, view->ReadTextL(NameColumn,text)); + if (err != KErrNone || text != KProxyName()) + { + updateFlags |= TProxyUpdateName; + } + + TRAP(err, view->ReadTextL(ProtocolColumn,text)); + if (err != KErrNone || text != KProxyProtocol()) + { + updateFlags |= TProxyUpdateProtocol; + } + + if (updateFlags) + { + TRACE3("updating %S #%d (flags: %08X)",&TableName,id,updateFlags); + LEAVE_IF_ERROR(view->UpdateRecord()); + + if (updateFlags & TProxyUpdateUseProxy) + { + TRAP(err,view->WriteBoolL(UseProxyColumn,aUseProxy)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TProxyUpdateServerName) + { + TRAP(err,view->WriteLongTextL(ServerNameColumn,*aProxyHost)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TProxyUpdateName) + { + TRAP(err,view->WriteTextL(NameColumn,KProxyName())); + ASSERT_SUCCESS(err); + } + if (updateFlags & TProxyUpdateProtocol) + { + TRAP(err,view->WriteTextL(ProtocolColumn,KProxyProtocol())); + ASSERT_SUCCESS(err); + } + if (updateFlags & TProxyUpdatePort) + { + TRAP(err,view->WriteUintL(ProxyPortColumn,aProxyPort)); + ASSERT_SUCCESS(err); + } + + LEAVE_IF_ERROR(view->PutRecordChanges()); + databaseUpdated = ETrue; + } + + recordFound = ETrue; + continue; + } + } + TRACE4(" deleting proxy record: %S #%d -> %d,%S",&TableName,id,number,&text); + VERIFY_SUCCESS(view->DeleteRecord()); + databaseUpdated = ETrue; + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry if it doesn't exist + if (!recordFound) + { + LEAVE_IF_ERROR(view->InsertRecord(id)); + + const TDesC& host = aProxyHost ? (*aProxyHost) : KNullDesC(); + TRACE2("created %S #%d",&TableName,id); + TRAP(err,view->WriteUintL(ISPColumn,aServiceId)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(ServiceTypeColumn,ServiceType)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteBoolL(UseProxyColumn, aUseProxy)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(NameColumn, KProxyName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(ProtocolColumn, KProxyProtocol)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(ProxyPortColumn, aProxyPort)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteLongTextL(ServerNameColumn, host)); + ASSERT_SUCCESS(err); + LEAVE_IF_ERROR(view->PutRecordChanges()); + databaseUpdated = ETrue; + } + + CleanupStack::PopAndDestroy(view); + return databaseUpdated; +} + +// Shortcut for making sure that there's no garbage in the proxy settings table +static TBool WsockCheckProxyL(CCommsDatabase* aDb, TUint32 aServiceId) +{ + return WsockCheckProxyL(aDb, aServiceId, EFalse, NULL, KDefaultProxyPort); +} + +// Makes sure our IAP is in the Network table +static TBool WsockCheckNetworkL(CCommsDatabase* aDb, TUint32& aNetworkId) +{ + _LIT(KNetworkTable,"Network"); + const TDesC& TableName = KNetworkTable(); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + + // Walk the table + TInt err; + TUint32 id = 0; + TBool found = EFalse; + TBool needCommit = EFalse; + if (view->GotoFirstRecord() == KErrNone) + { + TBuf text; + do + { + // This one must exist + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + TRAP(err, view->ReadTextL(NameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockAPName) + { + if (!found) + { + found = ETrue; + } + else + { + TRACE1(" deleting record #%d",id); + LEAVE_IF_ERROR(view->DeleteRecord()); + needCommit = ETrue; + } + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry if it doesn't exist + if (!found) + { + LEAVE_IF_ERROR(view->InsertRecord(id)); + TRACE2("created %S #%d",&TableName,id); + TRAP(err,view->WriteTextL(NameColumn, KWinsockAPName)); + ASSERT_SUCCESS(err); + LEAVE_IF_ERROR(view->PutRecordChanges()); + needCommit = ETrue; + } + + aNetworkId = id; + CleanupStack::PopAndDestroy(view); + return needCommit; +} + +// Finds our records in CommDb, creating one if necessary. Returns ETrue +// if transaction needs to be commited. +static TBool WsockCheckBearerTypeL(CCommsDatabase* aDb, TUint32& aBearerId) +{ + const TDesC& TableName = KWinsockBearerType(); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + TBuf agent; + agent.Copy(KWinsockAgent); + agent.Append(_L(".agt")); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC IfNameColumn(IF_NAME); + TPtrC AgentColumn(AGENT_NAME); + TPtrC SocketActivityTimeoutColumn(LAST_SOCKET_ACTIVITY_TIMEOUT); + TPtrC SessionClosedTimeoutColumn(LAST_SESSION_CLOSED_TIMEOUT); + TPtrC SocketClosedTimeoutColumn(LAST_SOCKET_CLOSED_TIMEOUT); + + // Walk the table + TInt err; + TBool needCommit = EFalse; + if (view->GotoFirstRecord() == KErrNone) + { + TUint32 number = 0; + TBuf text; + do + { + // This one must exist + TUint32 id = 0; + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + // We detect our record based on the value of the "IfName" + // column, it must point to our interface. + TRAP(err, view->ReadTextL(IfNameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockInterface) + { + aBearerId = id; + TUint updateFlags = 0; + TRAP(err, view->ReadTextL(AgentColumn,text)); + if (err != KErrNone || text != agent) + { + updateFlags |= TBearerUpdateAgent; + } + TRAP(err, view->ReadUintL(SocketActivityTimeoutColumn,number)); + if (err != KErrNone || number != KWinsockSocketActivityTimeout) + { + updateFlags |= TBearerUpdateSocketActivityTimeout; + } + TRAP(err, view->ReadUintL(SessionClosedTimeoutColumn,number)); + if (err != KErrNone || number != KWinsockSessionClosedTimeout) + { + updateFlags |= TBearerUpdateSessionClosedTimeout; + } + TRAP(err, view->ReadUintL(SocketClosedTimeoutColumn,number)); + if (err != KErrNone || number != KWinsockSocketClosedTimeout) + { + updateFlags |= TBearerUpdateSocketClosedTimeout; + } + + if (updateFlags) + { + needCommit = ETrue; + TRACE3("updating %S #%d (flags: %08X)",&TableName,id,updateFlags); + LEAVE_IF_ERROR(view->UpdateRecord()); + + if (updateFlags & TBearerUpdateAgent) + { + TRAP(err,view->WriteTextL(AgentColumn,agent)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TBearerUpdateSocketActivityTimeout) + { + TRAP(err,view->WriteUintL(SocketActivityTimeoutColumn, + KWinsockSocketActivityTimeout)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TBearerUpdateSessionClosedTimeout) + { + TRAP(err,view->WriteUintL(SessionClosedTimeoutColumn, + KWinsockSessionClosedTimeout)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TBearerUpdateSocketClosedTimeout) + { + TRAP(err,view->WriteUintL(SocketClosedTimeoutColumn, + KWinsockSocketClosedTimeout)); + ASSERT_SUCCESS(err); + } + + LEAVE_IF_ERROR(view->PutRecordChanges()); + } + + // Done + CleanupStack::PopAndDestroy(view); + return needCommit; + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry + LEAVE_IF_ERROR(view->InsertRecord(aBearerId)); + + TRACE2("created %S #%d",&TableName,aBearerId); + TRAP(err,view->WriteTextL(NameColumn,KWinsockBearerName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(IfNameColumn,KWinsockInterface)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(AgentColumn,agent)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(SocketActivityTimeoutColumn, KWinsockSocketClosedTimeout)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(SessionClosedTimeoutColumn, KWinsockSessionClosedTimeout)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(SocketClosedTimeoutColumn, KWinsockSocketClosedTimeout)); + ASSERT_SUCCESS(err); + + // These must be present in the LANBearer table, otherwise + // PutRecordChanges fails because these fields are mandatory + _LIT(something,"foo"); + TRAP(err,view->WriteTextL(TPtrC(LAN_BEARER_LDD_NAME),something)); + TRAP(err,view->WriteTextL(TPtrC(LAN_BEARER_PDD_NAME),something)); + + LEAVE_IF_ERROR(view->PutRecordChanges()); + CleanupStack::PopAndDestroy(view); + return ETrue; +} + +// Finds our records in CommDb, creating one if necessary. Returns ETrue +// if transaction needs to be commited. +static TBool WsockCheckServiceTypeL(CCommsDatabase* aDb, TUint32& aServiceId) +{ + const TDesC& TableName = KWinsockServiceType(); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // We will need the list of networks and the agent ame + TBuf networks; + CWinsockProtocolFamily::ProtocolNames(networks); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC APNColumn(GPRS_APN); + TPtrC APTypeColumn(GPRS_AP_TYPE); + TPtrC NetworksColumn(SERVICE_IF_NETWORKS); + TPtrC AuthPromptColumn(ISP_IF_PROMPT_FOR_AUTH); + + // Walk the table + TInt err; + if (view->GotoFirstRecord() == KErrNone) + { + TBuf text; + do + { + // This one must exist + TUint32 id = 0; + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + TRAP(err, view->ReadTextL(NameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockServiceName) + { + // This is our record. Make sure it looks right. + aServiceId = id; + TBool authPrompt = EFalse; + TInt updateFlags = 0; + TRAP(err, view->ReadTextL(NetworksColumn,text)); + if (err != KErrNone || text != networks) + { + updateFlags |= TServiceUpdateNetworks; + } + // The following one is not present in the LANService + // table. Ignore it if it's not there. + TRAP(err, view->ReadBoolL(AuthPromptColumn,authPrompt)); + if (err == KErrNone && authPrompt) + { + updateFlags |= TServiceUpdateAuthPrompt; + } + + // The above statement also applies to APN column + TBuf text; + TRAP(err, view->ReadTextL(APNColumn,text)); + if (err == KErrNone && text != KWinsockAPName) + { + updateFlags |= TServiceUpdateAPN; + } + +#ifndef WSOCK_LAN_SERVICE + // This one is important. If this number isn't set, our + // access point almost (!) never shows up in the list of + // access points, at least if we use "OutgoingGPRS" + // service type (hence the #ifdef). + TUint32 n = 0; + TRAP(err, view->ReadUintL(APTypeColumn, n)); + if (err != KErrNone || n != KWinsockAPType) + { + updateFlags |= TServiceUpdateAPType; + } +#endif // !WSOCK_LAN_SERVICE + + TBool update = (updateFlags != 0); + if (update) + { + TRACE3("updating %S #%d (flags: %08X)",&TableName,id,updateFlags); + LEAVE_IF_ERROR(view->UpdateRecord()); + + if (updateFlags & TServiceUpdateNetworks) + { + TRAP(err,view->WriteTextL(NetworksColumn,networks)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TServiceUpdateAuthPrompt) + { + TRAP(err,view->WriteBoolL(AuthPromptColumn,EFalse)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TServiceUpdateAPN) + { + TRAP(err,view->WriteTextL(APNColumn,KWinsockAPName)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TServiceUpdateAPType) + { + TRAP(err,view->WriteUintL(APTypeColumn,KWinsockAPType)); + ASSERT_SUCCESS(err); + } + + LEAVE_IF_ERROR(view->PutRecordChanges()); + } + + // Done + CleanupStack::PopAndDestroy(view); + return update; + } + } + } + while (view->GotoNextRecord() == KErrNone); + + TRACE1(" did not find %S",&KWinsockServiceName); + } + + // Create a new entry + LEAVE_IF_ERROR(view->InsertRecord(aServiceId)); + + TRACE2("created %S #%d",&TableName,aServiceId); + TRAP(err,view->WriteTextL(NameColumn,KWinsockServiceName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(NetworksColumn,networks)); + ASSERT_SUCCESS(err); + + // Ignore the errors below - LANService table does not have these entries. + // Only OutgoingGPRS does. But we try anyway, in case if Symbian unifies + // the formats of the service tables in CommDb. + TRAP(err,view->WriteBoolL(AuthPromptColumn,EFalse)); + TRAP(err,view->WriteTextL(APNColumn,KWinsockAPName)); + TRAP(err,view->WriteUintL(APTypeColumn,KWinsockAPType)); + TRAP(err,view->WriteUintL(TPtrC(GPRS_PDP_TYPE),KWinsockPdpType)); + + // We don't use these fields, but they are mandatory. + TRAP(err,view->WriteBoolL(TPtrC(SERVICE_IP_ADDR_FROM_SERVER),EFalse)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteBoolL(TPtrC(SERVICE_IP_DNS_ADDR_FROM_SERVER),EFalse)); + ASSERT_SUCCESS(err); + + LEAVE_IF_ERROR(view->PutRecordChanges()); + CleanupStack::PopAndDestroy(view); + return ETrue; +} + +// Finds our record in WAPAccessPoint table, creating one if necessary. +// Returns ETrue if transaction needs to be commited. +static TBool WsockCheckWapAccessPointL(CCommsDatabase* aDb, TUint32& aWapApId) +{ + TPtrC TableName(WAP_ACCESS_POINT); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC CurrentBearerColumn(WAP_CURRENT_BEARER); + + // Walk the table + TInt err; + TUint32 id = 0; + TBool found = EFalse; + TBool commit = EFalse; + if (view->GotoFirstRecord() == KErrNone) + { + TBuf text; + do + { + // This one must exist + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + TRAP(err, view->ReadTextL(NameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockAPName) + { + if (!found) + { + aWapApId = id; + found = ETrue; + TRAP(err, view->ReadTextL(CurrentBearerColumn,text)); + if (err != KErrNone || text != KWinsockWapBearer) + { + TRACE1(" updating \"%S\"",&CurrentBearerColumn); + LEAVE_IF_ERROR(view->UpdateRecord()); + TRAP(err,view->WriteTextL(CurrentBearerColumn, + KWinsockWapBearer)); + ASSERT_SUCCESS(err); + LEAVE_IF_ERROR(view->PutRecordChanges()); + commit = ETrue; + } + } + else + { + TRACE1(" deleting record #%d",id); + LEAVE_IF_ERROR(view->DeleteRecord()); + commit = ETrue; + } + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry if it doesn't exist + if (!found) + { + LEAVE_IF_ERROR(view->InsertRecord(id)); + TRACE2("created %S #%d",&TableName,id); + TRAP(err,view->WriteTextL(NameColumn, KWinsockAPName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(CurrentBearerColumn, KWinsockWapBearer)); + ASSERT_SUCCESS(err); + LEAVE_IF_ERROR(view->PutRecordChanges()); + aWapApId = id; + commit = ETrue; + } + + CleanupStack::PopAndDestroy(view); + return commit; +} + +// Finds our records in WAPIPBearer table, creating one if necessary. +// Returns ETrue if transaction needs to be commited. +static TBool WsockCheckWapIpBearerL(CCommsDatabase* aDb, + TUint32 aWapApId, + TUint32 aIapId) +{ + const TDesC& TableName = KWinsockWapBearer(); + TRACE1("examining %S table...",&TableName); + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // Column names + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC AccessPointIdColumn(WAP_ACCESS_POINT_ID); + TPtrC IAPColumn(WAP_IAP); + TPtrC ProxyPortColumn(WAP_PROXY_PORT); + TPtrC WspOptionColumn(WAP_WSP_OPTION); + TPtrC SecurityColumn(WAP_SECURITY); + TPtrC GatewayAddressColumn(WAP_GATEWAY_ADDRESS); + TPtrC ProxyLoginNameColumn(WAP_PROXY_LOGIN_NAME); + TPtrC ProxyLoginPassColumn(WAP_PROXY_LOGIN_PASS); + + // Walk the table + TInt err; + TUint32 id = 0; + if (view->GotoFirstRecord() == KErrNone) + { + do + { + // This one must exist + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + // We detect our record based on WAP access point id + TUint32 wap = 0; + TRAPD(err, view->ReadUintL(AccessPointIdColumn, wap)); + TRACE3(" %S #%d -> %d", &TableName, id, wap); + if (err == KErrNone && wap == aWapApId) + { + TUint32 n = 0; + TBool b = EFalse; + TUint updateFlags = 0; + TBuf text; + TBool commit = EFalse; + + TRAPD(err, view->ReadUintL(IAPColumn, n)); + if (err != KErrNone || n != aIapId) + { + updateFlags |= TWapIpBearerUpdateIAP; + } + TRAP(err, view->ReadUintL(WspOptionColumn, n)); + if (err != KErrNone) + { + updateFlags |= TWapIpBearerUpdateWspOption; + } + TRAP(err, view->ReadUintL(ProxyPortColumn, n)); + if (err != KErrNone) + { + updateFlags |= TWapIpBearerUpdateProxyPort; + } + TRAP(err, view->ReadBoolL(SecurityColumn, b)); + if (err != KErrNone) + { + updateFlags |= TWapIpBearerUpdateSecurity; + } + TRAP(err, view->ReadTextL(GatewayAddressColumn,text)); + if (err != KErrNone || text != KWinsockGatewayAddress) + { + updateFlags |= TWapIpBearerUpdateGatewayAddress; + } + TRAP(err, view->ReadTextL(ProxyLoginNameColumn,text)); + if (err != KErrNone) + { + updateFlags |= TWapIpBearerUpdateProxyLoginName; + } + TRAP(err, view->ReadTextL(ProxyLoginPassColumn,text)); + if (err != KErrNone) + { + updateFlags |= TWapIpBearerUpdateProxyLoginPass; + } + + TBool update = (updateFlags != 0); + if (updateFlags) + { + // Update the existing table + TRACE3("updating %S #%d (flags: %08X)",&TableName,id,updateFlags); + LEAVE_IF_ERROR(view->UpdateRecord()); + if (updateFlags & TWapIpBearerUpdateIAP) + { + TRACE1(" updating \"%S\"",&IAPColumn); + TRAP(err,view->WriteUintL(IAPColumn, aIapId)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateWspOption) + { + TRACE1(" updating \"%S\"",&WspOptionColumn); + TRAP(err,view->WriteUintL(WspOptionColumn,0)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateProxyPort) + { + TRACE1(" updating \"%S\"",&ProxyPortColumn); + TRAP(err,view->WriteUintL(ProxyPortColumn,0)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateSecurity) + { + TRACE1(" updating \"%S\"",&SecurityColumn); + TRAP(err,view->WriteBoolL(SecurityColumn,EFalse)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateGatewayAddress) + { + TRACE1(" updating \"%S\"",&GatewayAddressColumn); + TRAP(err,view->WriteTextL(GatewayAddressColumn, + KWinsockGatewayAddress)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateProxyLoginName) + { + TRACE1(" updating \"%S\"",&ProxyLoginNameColumn); + TRAP(err,view->WriteTextL(ProxyLoginNameColumn, + KNullDesC)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TWapIpBearerUpdateProxyLoginPass) + { + TRACE1(" updating \"%S\"",&ProxyLoginPassColumn); + TRAP(err,view->WriteTextL(ProxyLoginPassColumn, + KNullDesC)); + ASSERT_SUCCESS(err); + } + LEAVE_IF_ERROR(view->PutRecordChanges()); + commit = ETrue; + } + + // Done + CleanupStack::PopAndDestroy(view); + return commit; + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry + LEAVE_IF_ERROR(view->InsertRecord(id)); + + TRACE2("created %S #%d",&TableName,id); + TRAP(err,view->WriteTextL(NameColumn,KWinsockBearerName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(AccessPointIdColumn, aWapApId)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(IAPColumn, aIapId)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(ProxyPortColumn, 0)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(WspOptionColumn, 0)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteBoolL(SecurityColumn, EFalse)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(GatewayAddressColumn,KWinsockGatewayAddress)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(ProxyLoginNameColumn,KNullDesC)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(ProxyLoginPassColumn,KNullDesC)); + ASSERT_SUCCESS(err); + + LEAVE_IF_ERROR(view->PutRecordChanges()); + CleanupStack::PopAndDestroy(view); + return ETrue; +} + +static TBool WsockCheckConnPreferencesL(CCommsDatabase* aDb, TUint32 aIapId) +{ + TRACE("examining Connection Preferences..."); + CCommsDbConnectionPrefTableView *view = aDb->OpenConnectionPrefTableLC(); + + CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref myPrefs; + myPrefs.iBearer.iIapId = aIapId; + myPrefs.iDirection = ECommDbConnectionDirectionOutgoing; + myPrefs.iDialogPref = ECommDbDialogPrefPrompt; + myPrefs.iRanking = 1; + myPrefs.iBearer.iBearerSet = KCommDbBearerCSD + | KCommDbBearerWcdma + | KCommDbBearerLAN + | KCommDbBearerVirtual; + // Walk the table + TInt err; + if (view->GotoFirstRecord() == KErrNone) + { + do + { + CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref prefs; + TRAP(err, view->ReadConnectionPreferenceL(prefs)); + if (err == KErrNone) + { + // check, whether this is our record + if (prefs.iBearer.iIapId == myPrefs.iBearer.iIapId) + { + TBool update = EFalse; + + // This is our record. Make sure it looks right. + if (prefs.iDialogPref != myPrefs.iDialogPref) + { + TRACE("updating DialogPref"); + view->UpdateDialogPrefL(myPrefs.iDialogPref); + update = ETrue; + } + if (prefs.iRanking != myPrefs.iRanking) + { + TRACE("updating Ranking"); + view->ChangeConnectionPreferenceRankL(myPrefs.iRanking); + update = ETrue; + } + if (prefs.iBearer.iBearerSet != myPrefs.iBearer.iBearerSet) + { + TRACE("updating Bearer"); + view->UpdateBearerL(myPrefs.iBearer); + update = ETrue; + } + CleanupStack::PopAndDestroy(view); + return update; + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Create a new entry + view->InsertConnectionPreferenceL(myPrefs); + TRACE("created connection preferences"); + CleanupStack::PopAndDestroy(view); + return ETrue; +} + +// Finds our records in CommDb, creating one if necessary. +void WsockCheckCommDbL(TUint32& aIapId, + TUint32& aNetworkId, + TUint32& aServiceId, + TUint32& aBearerId) +{ + TRACE("checking CommDb"); + CCommsDatabase* db = CCommsDatabase::NewL(); + CleanupStack::PushL(db); + WsockBeginCommDbTransactionLC(db); + TBool commit = EFalse; + TUint32 number = 0; + TInt err; + + // This must be 2 + TPtrC ConnectionAttempts(CONNECTION_ATTEMPTS); + TRAP(err, db->GetGlobalSettingL(ConnectionAttempts, number)); + if (err != KErrNone || number < 2) + { + TRACE1("Resetting ConnectionAttempts (%d) to 2",number); + TRAP(err, db->SetGlobalSettingL(ConnectionAttempts, 2)); + ASSERT_SUCCESS(err); + commit = ETrue; + } + + // Not sure if we need this check... + _LIT(KTsy, "PHONETSY"); + TFileName tsy; + TPtrC BearerAvailabilityCheckTsy(BEARER_AVAILABILITY_CHECK_TSY); + TRAP(err, db->GetGlobalSettingL(BearerAvailabilityCheckTsy, tsy)); + if (err != KErrNone || tsy.CompareF(KTsy)) + { + TRACE1("Updating BearerAvailabilityCheckTSY (%S)",&tsy); + TRAP(err, db->SetGlobalSettingL(BearerAvailabilityCheckTsy, KTsy)); + ASSERT_SUCCESS(err); + commit = ETrue; + } + + // Check a few other things + if (WsockCheckServiceTypeL(db, aServiceId)) commit = ETrue; + if (WsockCheckBearerTypeL(db, aBearerId)) commit = ETrue; + if (WsockCheckNetworkL(db, aNetworkId)) commit = ETrue; + + // Initialize descriptors + TPtrC TableName(IAP); + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + TPtrC IAPNetworkColumn(IAP_NETWORK); + TPtrC IAPServiceColumn(IAP_SERVICE); + TPtrC IAPServiceTypeColumn(IAP_SERVICE_TYPE); + TPtrC IAPBearerColumn(IAP_BEARER); + TPtrC IAPBearerTypeColumn(IAP_BEARER_TYPE); + + // Open the IAP table + CCommsDbTableView* view = db->OpenTableLC(TableName); + + // Find our access point + TRACE("examining APs..."); + if (view->GotoFirstRecord() == KErrNone) + { + TBuf text; + do + { + // This one must exist + TUint32 id = 0; + TRAP(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + TRAP(err, view->ReadTextL(NameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockAPName) + { + aIapId = id; + TUint updateFlags = 0; + TRAP(err, view->ReadUintL(IAPServiceColumn,number)); + if (err != KErrNone || number != aServiceId) + { + updateFlags |= TIAPUpdateService; + } + TRAP(err, view->ReadTextL(IAPServiceTypeColumn,text)); + if (err == KErrNone && text != KWinsockServiceType) + { + updateFlags |= TIAPUpdateServiceType; + } + TRAP(err, view->ReadUintL(IAPBearerColumn,number)); + if (err != KErrNone || number != aBearerId) + { + updateFlags |= TIAPUpdateBearer; + } + TRAP(err, view->ReadTextL(IAPBearerTypeColumn,text)); + if (err == KErrNone && text != KWinsockBearerType) + { + updateFlags |= TIAPUpdateBearerType; + } + TRAP(err, view->ReadUintL(IAPNetworkColumn,number)); + if (err != KErrNone || number != aNetworkId) + { + updateFlags |= TIAPUpdateNetwork; + } + + if (updateFlags) + { + // Update the existing table + TRACE2("updating AP \"%S\" (flags: %08X)",&KWinsockAPName(), updateFlags); + LEAVE_IF_ERROR(view->UpdateRecord()); + + if (updateFlags & TIAPUpdateService) + { + TRACE2(" updating \"%S\": %u",&IAPServiceColumn, aServiceId); + TRAP(err,view->WriteUintL(IAPServiceColumn,aServiceId)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TIAPUpdateServiceType) + { + TRACE2(" updating \"%S\": %S",&IAPServiceTypeColumn, &KWinsockServiceType); + TRAP(err,view->WriteTextL(IAPServiceTypeColumn,KWinsockServiceType)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TIAPUpdateBearer) + { + TRACE2(" updating \"%S\": %u",&IAPServiceTypeColumn, aBearerId); + TRAP(err,view->WriteUintL(IAPBearerColumn,aBearerId)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TIAPUpdateBearerType) + { + TRACE2(" updating \"%S\": %S",&IAPBearerTypeColumn, &KWinsockBearerType); + TRAP(err,view->WriteTextL(IAPBearerTypeColumn,KWinsockBearerType)); + ASSERT_SUCCESS(err); + } + if (updateFlags & TIAPUpdateNetwork) + { + TRACE2(" updating \"%S\": %u",&IAPNetworkColumn, aNetworkId); + TRAP(err,view->WriteUintL(IAPNetworkColumn,aNetworkId)); + ASSERT_SUCCESS(err); + } + + LEAVE_IF_ERROR(view->PutRecordChanges()); + commit = ETrue; + } + + TUint32 wap = 0; + if (WsockCheckWapAccessPointL(db,wap)) commit = ETrue; + if (WsockCheckWapIpBearerL(db,wap,aIapId)) commit = ETrue; + if (WsockCheckConnPreferencesL(db, aIapId)) commit = ETrue; + if (commit) + { + TRACE("commit CommDb transaction"); + LEAVE_IF_ERROR(db->CommitTransaction()); + } + + // Done + CleanupStack::PopAndDestroy(view); + CleanupStack::Pop(); // WsockRollbackOnLeave + CleanupStack::PopAndDestroy(db); + + TRACE4("selected AP=%d, network=%d, service=%d, bearer=%d", + aIapId,aNetworkId,aServiceId,aBearerId); + return; + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + // Find any valid location id + TUint32 locationId = 1; + CCommsDbTableView* locationView = db->OpenTableLC(TPtrC(LOCATION)); + if (locationView->GotoFirstRecord() == KErrNone) + { + TRAPD(err, locationView->ReadUintL(IdColumn, locationId)); + } + CleanupStack::PopAndDestroy(locationView); + + // Create new IAP entry + err = view->InsertRecord(aIapId); + ASSERT_SUCCESS(err); + + TRACE1("created AP #%d",aIapId); + TRAP(err,view->WriteTextL(NameColumn,KWinsockAPName)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(IAPServiceColumn,aServiceId)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(IAPServiceTypeColumn,KWinsockServiceType)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(IAPBearerColumn,aBearerId)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteTextL(IAPBearerTypeColumn,KWinsockBearerType)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(IAPNetworkColumn,aNetworkId)); + ASSERT_SUCCESS(err); + + // These must be present in the LANBearer table, otherwise + // PutRecordChanges fails because these fields are mandatory + _LIT(something,"foo"); + TRAP(err,view->WriteUintL(TPtrC(IAP_NETWORK_WEIGHTING),0)); + ASSERT_SUCCESS(err); + TRAP(err,view->WriteUintL(TPtrC(IAP_LOCATION),locationId)); + ASSERT_SUCCESS(err); + + LEAVE_IF_ERROR(view->PutRecordChanges()); + CleanupStack::PopAndDestroy(view); + CleanupStack::Pop(); // WsockRollbackOnLeave + + TUint32 wap = 0; + WsockCheckWapAccessPointL(db, wap); + WsockCheckWapIpBearerL(db, wap, aIapId); + WsockCheckConnPreferencesL(db, aIapId); + + TRACE("commit CommDb transaction"); + LEAVE_IF_ERROR(db->CommitTransaction()); + CleanupStack::PopAndDestroy(db); + TRACE4("selected AP=%d, network=%d, service=%d, bearer=%d", + aIapId,aNetworkId,aServiceId,aBearerId); +} + +// Creating necessary entries in CommDB if necessary. +static TInt WsockCheckCommDb() +{ + TUint32 apId, apNetwork, apService, apBearer; + + // Make sure Winsock is initialized + static TBool initWinsock = ETrue; + if (initWinsock) { + WSADATA wsaData; + TRACE("initializing Winsock"); + WSAStartup(MAKEWORD(1,1),&wsaData); + initWinsock = EFalse; + } + + WsockLock lock; + lock.Lock(); + TRAPD(err, WsockCheckCommDbL(apId, apNetwork, apService, apBearer)); + lock.Unlock(); + + if (err == KErrNone) + { + TRACE("CommDB check successful"); + } + else + { + TRACE1("CommDB check failed, err %d",err); + } + return err; +} + +// Deletes Wsock access points +static TBool WsockDeleteApsL(CCommsDatabase* aDb) +{ + TBool needCommit = EFalse; + + // Initialize descriptors + TPtrC TableName(IAP); + TPtrC IdColumn(COMMDB_ID); + TPtrC NameColumn(COMMDB_NAME); + + // Open the IAP table + CCommsDbTableView* view = aDb->OpenTableLC(TableName); + + // Find our access points + TRACE("looking for APs to delete..."); + if (view->GotoFirstRecord() == KErrNone) + { + TUint32 number = 0; + TBuf text; + do + { + // This one must exist + TUint32 id = 0; + TRAPD(err, view->ReadUintL(IdColumn, id)); + if (err == KErrNone) + { + TRAP(err, view->ReadTextL(NameColumn,text)); + TRACE3(" %S #%d -> %S",&TableName,id,&text); + if (err == KErrNone && text == KWinsockAPName) + { + TRACE1("deleting AP #%d",id); + LEAVE_IF_ERROR(view->DeleteRecord()); + needCommit = ETrue; + } + } + } + while (view->GotoNextRecord() == KErrNone); + } + + CleanupStack::PopAndDestroy(view); + return needCommit; +} + +// Configures wsock settings, leaves on failure +static void WsockSetConfigL(TBool aUseWsock, TBool aUseProxy, + const TDesC* aHost, TUint aPort) +{ + // Synchronize access to the database + WsockLock lock; + lock.LockLC(); + + // Figure out the service id - we will need it + CCommsDatabase* db = CCommsDatabase::NewL(); + CleanupStack::PushL(db); + WsockBeginCommDbTransactionLC(db); + TUint32 serviceId; + TBool commit = WsockCheckServiceTypeL(db, serviceId); + + // Now that we know the service id, we can update the proxy settings + if (WsockCheckProxyL(db,serviceId,aUseProxy,aHost,aPort)) commit = ETrue; + if (!aUseWsock && WsockDeleteApsL(db)) commit = ETrue; + if (commit) + { + TRACE("commit CommDb transaction"); + LEAVE_IF_ERROR(db->CommitTransaction()); + } + CleanupStack::Pop(); // WsockRollbackOnLeave + CleanupStack::PopAndDestroy(db); + + if (aUseWsock) + { + // Final touch + TUint32 apId, networkId, bearerId; + TRAPD(err, WsockCheckCommDbL(apId, networkId, serviceId, bearerId)); + } + + CleanupStack::PopAndDestroy(); // WsockLock::UnlockOnLeave +} + +// Reads Wsock settings, leaves on failure +static void WsockQueryConfigL(TBool& aUseProxy, HBufC*& aHost, TUint& aPort) +{ + // Default values + aUseProxy = EFalse; + aHost = NULL; + aPort = KDefaultProxyPort; + + // Synchronize access to the database + WsockLock lock; + lock.LockLC(); + + // Figure out the service id - we will need it + CCommsDatabase* db = CCommsDatabase::NewL(); + CleanupStack::PushL(db); + WsockBeginCommDbTransactionLC(db); + TUint32 serviceId; + TBool commit = EFalse; + if (WsockCheckServiceTypeL(db, serviceId)) commit = ETrue; + if (WsockCheckProxyL(db, serviceId)) commit = ETrue; + + // At this point there should be only one record in the proxy table + const TDesC& TableName = KProxyTableName(); + const TDesC& ServiceType = KWinsockServiceType(); + CCommsDbTableView* view = db->OpenTableLC(TableName); + + // Column names + TPtrC UseProxyColumn(PROXY_USE_PROXY_SERVER); + TPtrC ProxyPortColumn(PROXY_PORT_NUMBER); + TPtrC ServerNameColumn(PROXY_SERVER_NAME); + + // Walk the table and deleted everything except our settings + TInt status = KErrNotFound; + if (view->GotoFirstRecord() == KErrNone) + { + status = KErrNone; + TUint32 number = KDefaultProxyPort; + view->ReadBoolL(UseProxyColumn,aUseProxy); + view->ReadUintL(ProxyPortColumn, number); + aPort = number; + aHost = view->ReadLongTextLC(ServerNameColumn); + CleanupStack::Pop(aHost); + } + + if (commit) + { + TRACE("commit CommDb transaction"); + LEAVE_IF_ERROR(db->CommitTransaction()); + } + + CleanupStack::PopAndDestroy(view); + CleanupStack::Pop(); // WsockRollbackOnLeave + CleanupStack::PopAndDestroy(db); + CleanupStack::PopAndDestroy(); // WsockLock::UnlockOnLeave + + LEAVE_IF_ERROR(status); +} + +// Entry point #1 +extern "C"EXPORT_C CProtocolFamilyBase * WsockCreateProtocolFamily() +{ + TRACE("WsockCreateProtocolFamily"); + VERIFY_SUCCESS(WsockCheckCommDb()); + return new CWinsockProtocolFamily(KAfInet); +} + +// Entry point #2 +extern "C" EXPORT_C CNifAgentFactory* WsockCreateAgentFactory() +{ + TRACE("WsockCreateAgentFactory"); + return new CWinsockAgentFactory; +} + +// Entry point #3 +extern "C" EXPORT_C CNifIfFactory* WsockCreateInterfaceFactory() +{ + TRACE("WsockCreateInterfaceFactory"); + return new CWinsockInterfaceFactory; +} + +// Entry point #4 +extern "C" EXPORT_C TInt WsockQueryConfiguration(TBool& aUseProxy, + HBufC*& aProxyHost, + TUint& aProxyPort) +{ + TRACE("WsockQueryProxy"); + TRAPD(err,WsockQueryConfigL(aUseProxy,aProxyHost,aProxyPort)); + if (err == KErrNone) + { + TRACE3("WsockQueryConfig: %d,%S:%d",aUseProxy,aProxyHost,aProxyPort); + } + else + { + TRACE1("configuration query failed, err %d",err); + } + return err; +} + +// Entry point #5 +extern "C" EXPORT_C TInt WsockSetConfiguration(TBool aUseWsock, + TBool aUseProxy, + const TDesC* aProxyHost, + TUint aProxyPort) +{ + TRACE4("WsockSetConfig(%d,%d,%S:%d)",aUseWsock,aUseProxy, + aProxyHost,aProxyPort); + TRAPD(err,WsockSetConfigL(aUseWsock, aUseProxy, aProxyHost, aProxyPort)); + if (err == KErrNone) + { + TRACE("configuration updated ok"); + } + else + { + TRACE1("configuration update failed, err %d",err); + } + return err; +} + +// Entry point #6 +extern "C"EXPORT_C CProtocolFamilyBase * WsockCreateProtocolFamily6() +{ + TRACE("WsockCreateProtocolFamily6"); + VERIFY_SUCCESS(WsockCheckCommDb()); + return new CWinsockProtocolFamily(KAfInet6); +} + +#ifndef EKA2 +// Required function +GLDEF_C TInt E32Dll(TDllReason /*aReason*/) +{ + return(KErrNone); +} +#endif // !EKA2 + +/** + * Local Variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */