os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_notifier_handlers.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32\sfile\sf_notifier_handlers.cpp
    15 // 
    16 //
    17 #include "sf_std.h"
    18 #include "sf_notifier.h"
    19 
    20 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
    21 
    22 TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/)
    23 	{
    24 	return KErrNone;
    25 	}
    26 
    27 TInt TFsNotificationOpen::DoRequestL(CFsRequest* aRequest)
    28 	{
    29 	__PRINT(_L("TFsNotificationOpen::DoRequestL()"));
    30 	//Check whether we've got a notification manager 
    31 	//If not, create it and call OpenL
    32 	if(!FsNotificationManager::IsInitialised())
    33 		{
    34 		FsNotificationManager::OpenL();
    35 		}
    36 	
    37 	//Create a new CFsNotifyRequest and add it to the manager
    38 	CFsNotifyRequest* notifyRequest = CFsNotifyRequest::NewL();
    39 
    40 	//Get handle and add request to manager and Session->Handles
    41 	TInt handle = 0;
    42 	TBool addedToManager = EFalse;
    43 	TRAPD(ret,HandleRequestL(aRequest, notifyRequest, handle,addedToManager));	
    44 	if (ret!=KErrNone)
    45 		{
    46 		//Remove request from Session->Handles if it was already added
    47 		if (handle!=0)
    48 			aRequest->Session()->Handles().Remove(handle,ETrue);
    49 		
    50 		//Remove request from manager
    51 		if(addedToManager)
    52 			{
    53 			FsNotificationManager::Lock();
    54 			FsNotificationManager::RemoveNotificationRequest(notifyRequest);
    55 			FsNotificationManager::Unlock();
    56 			}
    57 		delete notifyRequest;
    58 		return(ret);
    59 		}
    60 	
    61 	notifyRequest->iSession = aRequest->Session();
    62 	aRequest->Session()->IncResourceCount();
    63 	return ret;
    64 	}
    65 
    66 //Get handle and add request to Session->Handles
    67 void TFsNotificationOpen::HandleRequestL(CFsRequest* aRequest, CFsNotifyRequest* aNotifyRequest, TInt& aHandle,TBool& aAddedToManager)
    68 	{
    69 	aAddedToManager = EFalse;
    70 	FsNotificationManager::AddNotificationRequestL(aNotifyRequest);
    71 	aAddedToManager = ETrue;
    72 	aHandle = aRequest->Session()->Handles().AddL(aNotifyRequest,ETrue);
    73 	TPtrC8 pH((TUint8*)&aHandle, sizeof(TInt));
    74 	aRequest->WriteL(KMsgPtr3,pH);
    75 	}
    76 
    77 TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/)
    78 	{
    79 	return KErrNone;
    80 	}
    81 
    82 TInt TFsNotificationBuffer::DoRequestL(CFsRequest* aRequest)
    83 	{
    84 	__PRINT(_L("TFsNotificationBuffer::DoRequestL()"));
    85 	HBufC8* buffer = (HBufC8*)(aRequest->Message().Ptr0());
    86 	TInt handle = aRequest->Message().Int3();
    87 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session());
    88 	if(!notifyRequest)
    89 		return KErrBadHandle;
    90 	if(!buffer)
    91 		return KErrArgument;
    92 
    93 	notifyRequest->iClientBufferSize = aRequest->Message().Int1();
    94 	notifyRequest->iBufferMsg = aRequest->Message();
    95 	return KErrNone;
    96 	}
    97 
    98 TInt TFsNotificationRequest::Initialise(CFsRequest* aRequest)
    99 	{
   100 	TInt handle = aRequest->Message().Int3();	
   101 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session());
   102 	if(!notifyRequest)
   103 		return KErrBadHandle;
   104 	
   105 	//Check the tail's validity
   106 	TInt tail;
   107 	TPckg<TInt> tailPkg(tail);
   108 	TInt r = aRequest->Read(KMsgPtr0,tailPkg);
   109 	
   110 	if(r!=KErrNone || tail < 0 || tail > notifyRequest->iClientBufferSize)
   111 		return KErrArgument;
   112 		
   113 	return KErrNone;
   114 	}
   115 
   116 TInt TFsNotificationRequest::DoRequestL(CFsRequest* aRequest)
   117 	{
   118 	__PRINT(_L("TFsNotificationRequest::DoRequestL()"));
   119 	//We need to check whether there is anything in the buffer
   120 	//If so we should complete straight away.
   121 	FsNotificationManager::Lock();
   122 	
   123 	//Get notification request
   124 	TInt handle = aRequest->Message().Int3();	
   125 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session());
   126 	if(!notifyRequest)
   127 		{
   128 		FsNotificationManager::Unlock();
   129 		return KErrBadHandle;
   130 		}
   131 	
   132 	TInt r = notifyRequest->SetClientMessage(aRequest->Message());
   133 	if(r != KErrNone)
   134 		{
   135 		FsNotificationManager::Unlock();
   136 		return r;
   137 		}
   138 
   139 	CFsNotifyRequest::TNotifyRequestStatus status = notifyRequest->ActiveStatus();
   140 	if(status==CFsNotifyRequest::EOutstanding ||
   141 		status==CFsNotifyRequest::EOutstandingOverflow)
   142 		{
   143 		notifyRequest->CompleteClientRequest(KErrNone);
   144 		}
   145 
   146 	//Update Status
   147 	if(status!=CFsNotifyRequest::EOutstandingOverflow)
   148 		{
   149 		notifyRequest->SetActive(CFsNotifyRequest::EActive);
   150 		// RDebug::Print(_L("TFsNotificationRequest::DoRequestL Not-OutOver- iClientHead==%d, iClientTail==%d"),notifyRequest->iClientHead,notifyRequest->iClientTail);
   151 		}
   152 	else
   153 		{
   154 		notifyRequest->SetActive(CFsNotifyRequest::EInactive);
   155 		
   156 		// RDebug::Print(_L("TFsNotificationRequest::DoRequestL OutOver- iClientHead==%d, iClientTail==%d"),notifyRequest->iClientHead,notifyRequest->iClientTail);
   157 		
   158 		// If the user is in OutstandingOverflow notification state, 
   159 		// then we can set iClientHead to be equal to iServerTail now.
   160 		// That way if the client requests again and the state will go 
   161 		// back to active, the server will see that buffer as empty 
   162 		// rather than full/overflow.
   163 		
   164 		notifyRequest->iClientHead = notifyRequest->iClientTail;
   165 		}
   166 	FsNotificationManager::Unlock();
   167 	return r;
   168 	}
   169 
   170 TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/)
   171 	{
   172 	return KErrNone;
   173 	}
   174 
   175 TInt TFsNotificationCancel::DoRequestL(CFsRequest* aRequest)
   176 	{
   177 	__PRINT(_L("TFsNotificationCancel::DoRequestL()"));
   178 	FsNotificationManager::Lock();
   179 	
   180 	//Get notification request and deactivate filter
   181 	TInt handle = aRequest->Message().Int3();	
   182 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*)SessionObjectFromHandle(handle,0,aRequest->Session());
   183 	if(!notifyRequest)
   184 		{
   185 		FsNotificationManager::Unlock();
   186 		return KErrBadHandle;
   187 		}
   188 	
   189 	if(notifyRequest->ClientMsgHandle()!=0)
   190 		{	
   191 		notifyRequest->SetActive(CFsNotifyRequest::EInactive);
   192 		notifyRequest->CompleteClientRequest(KErrCancel,ETrue);
   193 		}
   194 	FsNotificationManager::Unlock();
   195 	return KErrNone;
   196 	}
   197 
   198 TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/)
   199 	{
   200 	return KErrNone;
   201 	}
   202 
   203 TInt TFsNotificationSubClose::DoRequestL(CFsRequest* aRequest)
   204 	{
   205 	__PRINT(_L("TFsNotificationSubClose::DoRequestL()"));
   206 	FsNotificationManager::Lock();
   207 	
   208 	//We need to complete the buffer request here as this type of request is not
   209 	//completed in the normal way as it is kept open in order that we can access the buffer
   210 	//in the client-side for the lifetime of this subsession.
   211 	TInt handle = aRequest->Message().Int3();
   212 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session());
   213 	if(!notifyRequest)
   214 		{
   215 		FsNotificationManager::Unlock();
   216 		return KErrBadHandle;
   217 		}
   218 	
   219 	notifyRequest->RemoveFilters();
   220 	notifyRequest->CloseNotification(); //Completes the buffer and the client requests.
   221 	
   222 	TInt count = FsNotificationManager::Count();
   223 	
   224 	//Also deletes notifyRequest
   225 	aRequest->Session()->Handles().Remove(handle,ETrue);
   226 	if(count==1)
   227 		{
   228 		//If this is the last request then we need to remove the manager
   229 		FsNotificationManager::Close();
   230 		}
   231 	
   232 	FsNotificationManager::Unlock();
   233 	aRequest->Session()->DecResourceCount();
   234 	notifyRequest = NULL;
   235 
   236 	return(KErrNone);
   237 	}
   238 
   239 TInt TFsNotificationAdd::Initialise(CFsRequest* aRequest)
   240 	{
   241 	__PRINT(_L("TFsNotificationAdd::Initialise()"));
   242 	TUint filter = (TUint) aRequest->Message().Int0();
   243 	//If it's AllOps then it's ok
   244 	if (filter!=TFsNotification::EAllOps)
   245 		{
   246 
   247 		TInt invalid = filter & ~KNotificationValidFiltersMask;
   248 		//Check: Non-valid values ARE NOT set
   249 		//		 and valid values ARE set.
   250 		if(invalid || !filter)
   251 			{
   252 			return KErrArgument;
   253 			}
   254 		}
   255 	
   256 	TFileName path;
   257 	TInt r = aRequest->Read(KMsgPtr1,path);
   258 	if(r != KErrNone)
   259 		{
   260 		return r;
   261 		}
   262 	
   263 	if(path.Length() >= 2)
   264 		r=PathCheck(aRequest,path.Mid(2),&KCapFsSysFileTemp,&KCapFsPriFileTemp,&KCapFsROFileTemp, __PLATSEC_DIAGNOSTIC_STRING("Notification Add Filter"));
   265 	return r;
   266 	}
   267 
   268 TInt TFsNotificationAdd::DoRequestL(CFsRequest* aRequest)
   269 	{
   270 	__PRINT(_L("TFsNotificationAdd::DoRequestL()"));
   271 	TInt handle = aRequest->Message().Int3();
   272 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session());
   273 	if(!notifyRequest)
   274 		return KErrBadHandle;
   275 	
   276 	TFileName path;
   277 	aRequest->Read(KMsgPtr1,path);
   278 	
   279 	TFileName filename;
   280 	TInt r = aRequest->Read(KMsgPtr2,filename);
   281 	if(r!= KErrNone)
   282 		return r;
   283 	
   284 	__PRINT2(_L("TFsNotificationAdd::AddNotification() path=%S, filename=%S"),&path,&filename);
   285 	
   286 	//If this is a path starting with 'drive-letter:'
   287 	TInt driveNum = FsNotificationHelper::DriveNumber(path);
   288 	if(path.Length() >= 2 && (driveNum < 0 || driveNum > 25) && ((TChar)driveNum)!=((TChar)'?') && ((TChar)path[1])==(TChar)':')
   289 		{
   290 		return KErrPathNotFound;
   291 		}
   292 
   293 	CleanupStack::PushL(notifyRequest);
   294 	CFsNotificationPathFilter* filter = CFsNotificationPathFilter::NewL(path,filename);
   295 
   296 	//Bitmask of filter types
   297 	TUint filterMask = (TUint) aRequest->Message().Int0();
   298 	
   299 	r = notifyRequest->AddFilterL(filter,filterMask);
   300 	CleanupStack::Pop(notifyRequest);
   301 
   302 	if(r == KErrNone)
   303 		{
   304 		FsNotificationManager::Lock();
   305 		//Increment global filter register
   306 		FsNotificationManager::SetFilterRegisterMask(filterMask,(TBool)ETrue);
   307 		FsNotificationManager::Unlock();
   308 		}
   309 	return r;
   310 	}
   311 
   312 TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/)
   313 	{
   314 	__PRINT(_L("TFsNotificationRemove::Initialise()"));
   315 	return KErrNone;
   316 	}
   317 
   318 TInt TFsNotificationRemove::DoRequestL(CFsRequest* aRequest)
   319 	{
   320 	__PRINT(_L("TFsNotificationRemove::DoRequestL()"));
   321 	FsNotificationManager::Lock();
   322 	
   323 	TInt handle = aRequest->Message().Int3();
   324 	CFsNotifyRequest* notifyRequest = (CFsNotifyRequest*) SessionObjectFromHandle(handle,0,aRequest->Session());
   325 	if(!notifyRequest)
   326 		{
   327 		FsNotificationManager::Unlock();
   328 		return KErrBadHandle;
   329 		}
   330 	
   331 	TInt r = notifyRequest->RemoveFilters();
   332 	FsNotificationManager::Unlock();
   333 	return r;
   334 	}
   335 
   336 #else //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
   337 
   338 CFsObjectCon* FsNotificationManager::iNotifyRequests = NULL;
   339 
   340 CFsNotifyRequest::CFsNotifyRequest()
   341 	{
   342 	}
   343 
   344 CFsNotifyRequest::~CFsNotifyRequest()
   345 	{
   346 	}
   347 
   348 TInt TFsNotificationOpen::Initialise(CFsRequest* /*aRequest*/)
   349 	{
   350 	return KErrNotSupported;
   351 	}
   352 
   353 TInt TFsNotificationOpen::DoRequestL(CFsRequest* /*aRequest*/)
   354 	{
   355 	return KErrNotSupported;
   356 	}
   357 
   358 void TFsNotificationOpen::HandleRequestL(CFsRequest* /*aRequest*/, CFsNotifyRequest* /*aNotifyRequest*/, TInt& /*aHandle*/,TBool& /*aAddedToManager*/)
   359 	{
   360 	User::Leave(KErrNotSupported);
   361 	}
   362 
   363 TInt TFsNotificationBuffer::Initialise(CFsRequest* /*aRequest*/)
   364 	{
   365 	return KErrNotSupported;
   366 	}
   367 
   368 TInt TFsNotificationBuffer::DoRequestL(CFsRequest* /*aRequest*/)
   369 	{
   370 	return KErrNotSupported;
   371 	}
   372 
   373 TInt TFsNotificationRequest::Initialise(CFsRequest* /*aRequest*/)
   374 	{
   375 	return KErrNotSupported;
   376 	}
   377 
   378 TInt TFsNotificationRequest::DoRequestL(CFsRequest* /*aRequest*/)
   379 	{
   380 	return KErrNotSupported;
   381 	}
   382 
   383 TInt TFsNotificationCancel::Initialise(CFsRequest* /*aRequest*/)
   384 	{
   385 	return KErrNotSupported;
   386 	}
   387 
   388 TInt TFsNotificationCancel::DoRequestL(CFsRequest* /*aRequest*/)
   389 	{
   390 	return KErrNotSupported;
   391 	}
   392 
   393 TInt TFsNotificationSubClose::Initialise(CFsRequest* /*aRequest*/)
   394 	{
   395 	return KErrNotSupported;
   396 	}
   397 
   398 TInt TFsNotificationSubClose::DoRequestL(CFsRequest* /*aRequest*/)
   399 	{
   400 	return KErrNotSupported;
   401 	}
   402 
   403 TInt TFsNotificationAdd::Initialise(CFsRequest* /*aRequest*/)
   404 	{
   405 	return KErrNotSupported;
   406 	}
   407 
   408 TInt TFsNotificationAdd::DoRequestL(CFsRequest* /*aRequest*/)
   409 	{
   410 	return KErrNotSupported;
   411 	}
   412 
   413 TInt TFsNotificationRemove::Initialise(CFsRequest* /*aRequest*/)
   414 	{
   415 	return KErrNotSupported;
   416 	}
   417 
   418 TInt TFsNotificationRemove::DoRequestL(CFsRequest* /*aRequest*/)
   419 	{
   420 	return KErrNotSupported;
   421 	}
   422 
   423 #endif //SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
   424