sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32\sfile\sf_notifier_handlers.cpp sl@0: // sl@0: // sl@0: #include "sf_std.h" sl@0: #include "sf_notifier.h" sl@0: sl@0: #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION sl@0: sl@0: TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationOpen::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationOpen::DoRequestL()")); sl@0: //Check whether we've got a notification manager sl@0: //If not, create it and call OpenL sl@0: if(!FsNotificationManager::IsInitialised()) sl@0: { sl@0: FsNotificationManager::OpenL(); sl@0: } sl@0: sl@0: //Create a new CFsNotifyRequest and add it to the manager sl@0: CFsNotifyRequest* notifyRequest = CFsNotifyRequest::NewL(); sl@0: sl@0: //Get handle and add request to manager and Session->Handles sl@0: TInt handle = 0; sl@0: TBool addedToManager = EFalse; sl@0: TRAPD(ret,HandleRequestL(aRequest, notifyRequest, handle,addedToManager)); sl@0: if (ret!=KErrNone) sl@0: { sl@0: //Remove request from Session->Handles if it was already added sl@0: if (handle!=0) sl@0: aRequest->Session()->Handles().Remove(handle,ETrue); sl@0: sl@0: //Remove request from manager sl@0: if(addedToManager) sl@0: { sl@0: FsNotificationManager::Lock(); sl@0: FsNotificationManager::RemoveNotificationRequest(notifyRequest); sl@0: FsNotificationManager::Unlock(); sl@0: } sl@0: delete notifyRequest; sl@0: return(ret); sl@0: } sl@0: sl@0: notifyRequest->iSession = aRequest->Session(); sl@0: aRequest->Session()->IncResourceCount(); sl@0: return ret; sl@0: } sl@0: sl@0: //Get handle and add request to Session->Handles sl@0: void TFsNotificationOpen::HandleRequestL(CFsRequest* aRequest, CFsNotifyRequest* aNotifyRequest, TInt& aHandle,TBool& aAddedToManager) sl@0: { sl@0: aAddedToManager = EFalse; sl@0: FsNotificationManager::AddNotificationRequestL(aNotifyRequest); sl@0: aAddedToManager = ETrue; sl@0: aHandle = aRequest->Session()->Handles().AddL(aNotifyRequest,ETrue); sl@0: TPtrC8 pH((TUint8*)&aHandle, sizeof(TInt)); sl@0: aRequest->WriteL(KMsgPtr3,pH); sl@0: } sl@0: sl@0: TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationBuffer::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationBuffer::DoRequestL()")); sl@0: HBufC8* buffer = (HBufC8*)(aRequest->Message().Ptr0()); sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: return KErrBadHandle; sl@0: if(!buffer) sl@0: return KErrArgument; sl@0: sl@0: notifyRequest->iClientBufferSize = aRequest->Message().Int1(); sl@0: notifyRequest->iBufferMsg = aRequest->Message(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationRequest::Initialise(CFsRequest* aRequest) sl@0: { sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: return KErrBadHandle; sl@0: sl@0: //Check the tail's validity sl@0: TInt tail; sl@0: TPckg tailPkg(tail); sl@0: TInt r = aRequest->Read(KMsgPtr0,tailPkg); sl@0: sl@0: if(r!=KErrNone || tail < 0 || tail > notifyRequest->iClientBufferSize) sl@0: return KErrArgument; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationRequest::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationRequest::DoRequestL()")); sl@0: //We need to check whether there is anything in the buffer sl@0: //If so we should complete straight away. sl@0: FsNotificationManager::Lock(); sl@0: sl@0: //Get notification request sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: { sl@0: FsNotificationManager::Unlock(); sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: TInt r = notifyRequest->SetClientMessage(aRequest->Message()); sl@0: if(r != KErrNone) sl@0: { sl@0: FsNotificationManager::Unlock(); sl@0: return r; sl@0: } sl@0: sl@0: CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus(); sl@0: if(status==CFsNotifyRequest::EOutstanding || sl@0: status==CFsNotifyRequest::EOutstandingOverflow) sl@0: { sl@0: notifyRequest->CompleteClientRequest(KErrNone); sl@0: } sl@0: sl@0: //Update Status sl@0: if(status!=CFsNotifyRequest::EOutstandingOverflow) sl@0: { sl@0: notifyRequest->SetActive(CFsNotifyRequest::EActive); sl@0: // RDebug::Print(_L("TFsNotificationRequest::DoRequestL Not-OutOver- iClientHead==%d, iClientTail==%d"),notifyRequest->iClientHead,notifyRequest->iClientTail); sl@0: } sl@0: else sl@0: { sl@0: notifyRequest->SetActive(CFsNotifyRequest::EInactive); sl@0: sl@0: // RDebug::Print(_L("TFsNotificationRequest::DoRequestL OutOver- iClientHead==%d, iClientTail==%d"),notifyRequest->iClientHead,notifyRequest->iClientTail); sl@0: sl@0: // If the user is in OutstandingOverflow notification state, sl@0: // then we can set iClientHead to be equal to iServerTail now. sl@0: // That way if the client requests again and the state will go sl@0: // back to active, the server will see that buffer as empty sl@0: // rather than full/overflow. sl@0: sl@0: notifyRequest->iClientHead = notifyRequest->iClientTail; sl@0: } sl@0: FsNotificationManager::Unlock(); sl@0: return r; sl@0: } sl@0: sl@0: TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationCancel::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationCancel::DoRequestL()")); sl@0: FsNotificationManager::Lock(); sl@0: sl@0: //Get notification request and deactivate filter sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: { sl@0: FsNotificationManager::Unlock(); sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: if(notifyRequest->ClientMsgHandle()!=0) sl@0: { sl@0: notifyRequest->SetActive(CFsNotifyRequest::EInactive); sl@0: notifyRequest->CompleteClientRequest(KErrCancel,ETrue); sl@0: } sl@0: FsNotificationManager::Unlock(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationSubClose::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationSubClose::DoRequestL()")); sl@0: FsNotificationManager::Lock(); sl@0: sl@0: //We need to complete the buffer request here as this type of request is not sl@0: //completed in the normal way as it is kept open in order that we can access the buffer sl@0: //in the client-side for the lifetime of this subsession. sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: { sl@0: FsNotificationManager::Unlock(); sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: notifyRequest->RemoveFilters(); sl@0: notifyRequest->CloseNotification(); //Completes the buffer and the client requests. sl@0: sl@0: TInt count = FsNotificationManager::Count(); sl@0: sl@0: //Also deletes notifyRequest sl@0: aRequest->Session()->Handles().Remove(handle,ETrue); sl@0: if(count==1) sl@0: { sl@0: //If this is the last request then we need to remove the manager sl@0: FsNotificationManager::Close(); sl@0: } sl@0: sl@0: FsNotificationManager::Unlock(); sl@0: aRequest->Session()->DecResourceCount(); sl@0: notifyRequest = NULL; sl@0: sl@0: return(KErrNone); sl@0: } sl@0: sl@0: TInt TFsNotificationAdd::Initialise(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationAdd::Initialise()")); sl@0: TUint filter = (TUint) aRequest->Message().Int0(); sl@0: //If it's AllOps then it's ok sl@0: if (filter!=TFsNotification::EAllOps) sl@0: { sl@0: sl@0: TInt invalid = filter & ~KNotificationValidFiltersMask; sl@0: //Check: Non-valid values ARE NOT set sl@0: // and valid values ARE set. sl@0: if(invalid || !filter) sl@0: { sl@0: return KErrArgument; sl@0: } sl@0: } sl@0: sl@0: TFileName path; sl@0: TInt r = aRequest->Read(KMsgPtr1,path); sl@0: if(r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: sl@0: if(path.Length() >= 2) sl@0: r=PathCheck(aRequest,path.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("Notification Add Filter")); sl@0: return r; sl@0: } sl@0: sl@0: TInt TFsNotificationAdd::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationAdd::DoRequestL()")); sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: return KErrBadHandle; sl@0: sl@0: TFileName path; sl@0: aRequest->Read(KMsgPtr1,path); sl@0: sl@0: TFileName filename; sl@0: TInt r = aRequest->Read(KMsgPtr2,filename); sl@0: if(r!= KErrNone) sl@0: return r; sl@0: sl@0: __PRINT2(_L("TFsNotificationAdd::AddNotification() path=%S, filename=%S"),&path,&filename); sl@0: sl@0: //If this is a path starting with 'drive-letter:' sl@0: TInt driveNum = FsNotificationHelper::DriveNumber(path); sl@0: if(path.Length() >= 2 && (driveNum < 0 || driveNum > 25) && ((TChar)driveNum)!=((TChar)'?') && ((TChar)path[1])==(TChar)':') sl@0: { sl@0: return KErrPathNotFound; sl@0: } sl@0: sl@0: CleanupStack::PushL(notifyRequest); sl@0: CFsNotificationPathFilter* filter = CFsNotificationPathFilter::NewL(path,filename); sl@0: sl@0: //Bitmask of filter types sl@0: TUint filterMask = (TUint) aRequest->Message().Int0(); sl@0: sl@0: r = notifyRequest->AddFilterL(filter,filterMask); sl@0: CleanupStack::Pop(notifyRequest); sl@0: sl@0: if(r == KErrNone) sl@0: { sl@0: FsNotificationManager::Lock(); sl@0: //Increment global filter register sl@0: FsNotificationManager::SetFilterRegisterMask(filterMask,(TBool)ETrue); sl@0: FsNotificationManager::Unlock(); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: __PRINT(_L("TFsNotificationRemove::Initialise()")); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TFsNotificationRemove::DoRequestL(CFsRequest* aRequest) sl@0: { sl@0: __PRINT(_L("TFsNotificationRemove::DoRequestL()")); sl@0: FsNotificationManager::Lock(); sl@0: sl@0: TInt handle = aRequest->Message().Int3(); sl@0: CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session()); sl@0: if(!notifyRequest) sl@0: { sl@0: FsNotificationManager::Unlock(); sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: TInt r = notifyRequest->RemoveFilters(); sl@0: FsNotificationManager::Unlock(); sl@0: return r; sl@0: } sl@0: sl@0: #else //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION sl@0: sl@0: CFsObjectCon* FsNotificationManager::iNotifyRequests = NULL; sl@0: sl@0: CFsNotifyRequest::CFsNotifyRequest() sl@0: { sl@0: } sl@0: sl@0: CFsNotifyRequest::~CFsNotifyRequest() sl@0: { sl@0: } sl@0: sl@0: TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationOpen::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: void TFsNotificationOpen::HandleRequestL(CFsRequest* /*aRequest*/, CFsNotifyRequest* /*aNotifyRequest*/, TInt& /*aHandle*/,TBool& /*aAddedToManager*/) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationBuffer::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationRequest::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationRequest::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationCancel::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationSubClose::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationAdd::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationAdd::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: TInt TFsNotificationRemove::DoRequestL(CFsRequest* /*aRequest*/) sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION sl@0: