diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/sfile/sf_notifier_handlers.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfile/sf_notifier_handlers.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,422 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// f32\sfile\sf_notifier_handlers.cpp +// +// +#include "sf_std.h" +#include "sf_notifier.h" + +#ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION + +TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNone; + } + +TInt TFsNotificationOpen::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationOpen::DoRequestL()")); + //Check whether we've got a notification manager + //If not, create it and call OpenL + if(!FsNotificationManager::IsInitialised()) + { + FsNotificationManager::OpenL(); + } + + //Create a new CFsNotifyRequest and add it to the manager + CFsNotifyRequest* notifyRequest = CFsNotifyRequest::NewL(); + + //Get handle and add request to manager and Session->Handles + TInt handle = 0; + TBool addedToManager = EFalse; + TRAPD(ret,HandleRequestL(aRequest, notifyRequest, handle,addedToManager)); + if (ret!=KErrNone) + { + //Remove request from Session->Handles if it was already added + if (handle!=0) + aRequest->Session()->Handles().Remove(handle,ETrue); + + //Remove request from manager + if(addedToManager) + { + FsNotificationManager::Lock(); + FsNotificationManager::RemoveNotificationRequest(notifyRequest); + FsNotificationManager::Unlock(); + } + delete notifyRequest; + return(ret); + } + + notifyRequest->iSession = aRequest->Session(); + aRequest->Session()->IncResourceCount(); + return ret; + } + +//Get handle and add request to Session->Handles +void TFsNotificationOpen::HandleRequestL(CFsRequest* aRequest, CFsNotifyRequest* aNotifyRequest, TInt& aHandle,TBool& aAddedToManager) + { + aAddedToManager = EFalse; + FsNotificationManager::AddNotificationRequestL(aNotifyRequest); + aAddedToManager = ETrue; + aHandle = aRequest->Session()->Handles().AddL(aNotifyRequest,ETrue); + TPtrC8 pH((TUint8*)&aHandle, sizeof(TInt)); + aRequest->WriteL(KMsgPtr3,pH); + } + +TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNone; + } + +TInt TFsNotificationBuffer::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationBuffer::DoRequestL()")); + HBufC8* buffer = (HBufC8*)(aRequest->Message().Ptr0()); + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + return KErrBadHandle; + if(!buffer) + return KErrArgument; + + notifyRequest->iClientBufferSize = aRequest->Message().Int1(); + notifyRequest->iBufferMsg = aRequest->Message(); + return KErrNone; + } + +TInt TFsNotificationRequest::Initialise(CFsRequest* aRequest) + { + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + return KErrBadHandle; + + //Check the tail's validity + TInt tail; + TPckg tailPkg(tail); + TInt r = aRequest->Read(KMsgPtr0,tailPkg); + + if(r!=KErrNone || tail < 0 || tail > notifyRequest->iClientBufferSize) + return KErrArgument; + + return KErrNone; + } + +TInt TFsNotificationRequest::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationRequest::DoRequestL()")); + //We need to check whether there is anything in the buffer + //If so we should complete straight away. + FsNotificationManager::Lock(); + + //Get notification request + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + { + FsNotificationManager::Unlock(); + return KErrBadHandle; + } + + TInt r = notifyRequest->SetClientMessage(aRequest->Message()); + if(r != KErrNone) + { + FsNotificationManager::Unlock(); + return r; + } + + CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus(); + if(status==CFsNotifyRequest::EOutstanding || + status==CFsNotifyRequest::EOutstandingOverflow) + { + notifyRequest->CompleteClientRequest(KErrNone); + } + + //Update Status + if(status!=CFsNotifyRequest::EOutstandingOverflow) + { + notifyRequest->SetActive(CFsNotifyRequest::EActive); + + // DEF140387: + // If this is not the first call to RequestNotifications then if the + // user just got an overflow notification (and requested again) + // then its possible that iClientTail is not zero now. + + // We should set iClientHead to iClientTail, otherwise the client + // can receive another overflow straight away. + notifyRequest->iClientHead = notifyRequest->iClientTail; + } + else + { + notifyRequest->SetActive(CFsNotifyRequest::EInactive); + } + FsNotificationManager::Unlock(); + return r; + } + +TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNone; + } + +TInt TFsNotificationCancel::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationCancel::DoRequestL()")); + FsNotificationManager::Lock(); + + //Get notification request and deactivate filter + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + { + FsNotificationManager::Unlock(); + return KErrBadHandle; + } + + if(notifyRequest->ClientMsgHandle()!=0) + { + notifyRequest->SetActive(CFsNotifyRequest::EInactive); + notifyRequest->CompleteClientRequest(KErrCancel,ETrue); + } + FsNotificationManager::Unlock(); + return KErrNone; + } + +TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNone; + } + +TInt TFsNotificationSubClose::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationSubClose::DoRequestL()")); + FsNotificationManager::Lock(); + + //We need to complete the buffer request here as this type of request is not + //completed in the normal way as it is kept open in order that we can access the buffer + //in the client-side for the lifetime of this subsession. + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + { + FsNotificationManager::Unlock(); + return KErrBadHandle; + } + + notifyRequest->RemoveFilters(); + notifyRequest->CloseNotification(); //Completes the buffer and the client requests. + + TInt count = FsNotificationManager::Count(); + + //Also deletes notifyRequest + aRequest->Session()->Handles().Remove(handle,ETrue); + if(count==1) + { + //If this is the last request then we need to remove the manager + FsNotificationManager::Close(); + } + + FsNotificationManager::Unlock(); + aRequest->Session()->DecResourceCount(); + notifyRequest = NULL; + + return(KErrNone); + } + +TInt TFsNotificationAdd::Initialise(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationAdd::Initialise()")); + TUint filter = (TUint) aRequest->Message().Int0(); + //If it's AllOps then it's ok + if (filter!=TFsNotification::EAllOps) + { + + TInt invalid = filter & ~KNotificationValidFiltersMask; + //Check: Non-valid values ARE NOT set + // and valid values ARE set. + if(invalid || !filter) + { + return KErrArgument; + } + } + + TFileName path; + TInt r = aRequest->Read(KMsgPtr1,path); + if(r != KErrNone) + { + return r; + } + + if(path.Length() >= 2) + r=PathCheck(aRequest,path.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("Notification Add Filter")); + return r; + } + +TInt TFsNotificationAdd::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationAdd::DoRequestL()")); + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + return KErrBadHandle; + + TFileName path; + aRequest->Read(KMsgPtr1,path); + + TFileName filename; + TInt r = aRequest->Read(KMsgPtr2,filename); + if(r!= KErrNone) + return r; + + __PRINT2(_L("TFsNotificationAdd::AddNotification() path=%S, filename=%S"),&path,&filename); + + //If this is a path starting with 'drive-letter:' + TInt driveNum = FsNotificationHelper::DriveNumber(path); + if(path.Length() >= 2 && (driveNum < 0 || driveNum > 25) && ((TChar)driveNum)!=((TChar)'?') && ((TChar)path[1])==(TChar)':') + { + return KErrPathNotFound; + } + + CleanupStack::PushL(notifyRequest); + CFsNotificationPathFilter* filter = CFsNotificationPathFilter::NewL(path,filename); + + //Bitmask of filter types + TUint filterMask = (TUint) aRequest->Message().Int0(); + + r = notifyRequest->AddFilterL(filter,filterMask); + CleanupStack::Pop(notifyRequest); + + if(r == KErrNone) + { + FsNotificationManager::Lock(); + //Increment global filter register + FsNotificationManager::SetFilterRegisterMask(filterMask,(TBool)ETrue); + FsNotificationManager::Unlock(); + } + return r; + } + +TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/) + { + __PRINT(_L("TFsNotificationRemove::Initialise()")); + return KErrNone; + } + +TInt TFsNotificationRemove::DoRequestL(CFsRequest* aRequest) + { + __PRINT(_L("TFsNotificationRemove::DoRequestL()")); + FsNotificationManager::Lock(); + + TInt handle = aRequest->Message().Int3(); + CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); + if(!notifyRequest) + { + FsNotificationManager::Unlock(); + return KErrBadHandle; + } + + TInt r = notifyRequest->RemoveFilters(); + FsNotificationManager::Unlock(); + return r; + } + +#else //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION + +CFsObjectCon* FsNotificationManager::iNotifyRequests = NULL; + +CFsNotifyRequest::CFsNotifyRequest() + { + } + +CFsNotifyRequest::~CFsNotifyRequest() + { + } + +TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationOpen::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +void TFsNotificationOpen::HandleRequestL(CFsRequest* /*aRequest*/, CFsNotifyRequest* /*aNotifyRequest*/, TInt& /*aHandle*/,TBool& /*aAddedToManager*/) + { + User::Leave(KErrNotSupported); + } + +TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationBuffer::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationRequest::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationRequest::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationCancel::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationSubClose::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationAdd::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationAdd::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +TInt TFsNotificationRemove::DoRequestL(CFsRequest* /*aRequest*/) + { + return KErrNotSupported; + } + +#endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION +