1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_plugin.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,836 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32\sfile\sf_plugin.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +/**
1.22 + @file
1.23 + @internalTechnology
1.24 +*/
1.25 +
1.26 +
1.27 +#include "sf_std.h"
1.28 +#include "sf_plugin_priv.h"
1.29 +
1.30 +
1.31 +EXPORT_C CFsPluginFactory::CFsPluginFactory()
1.32 + {}
1.33 +
1.34 +EXPORT_C CFsPluginFactory::~CFsPluginFactory()
1.35 + {}
1.36 +
1.37 +/**
1.38 +
1.39 +Uninstalls the plugin factory.
1.40 +
1.41 +This is called just before the plugin factory object is destroyed, and allows
1.42 +any clean up to be carried out.
1.43 +
1.44 +The default implementation does nothing except return KErrNone.
1.45 +Implementations should return an error code on error detection.
1.46 +
1.47 +@return KErrNone if successful, otherwise one of the other system wide error
1.48 + codes.
1.49 +*/
1.50 +EXPORT_C TInt CFsPluginFactory::Remove()
1.51 + {
1.52 + return(KErrNone);
1.53 + }
1.54 +
1.55 +/**
1.56 +
1.57 +Sets the plugin factory's resource library.
1.58 +This library represents the loaded plugin factory.
1.59 +This is called internally by InstallPluginFactory().
1.60 +
1.61 +@param aLib The resource library to be set.
1.62 +*/
1.63 +EXPORT_C void CFsPluginFactory::SetLibrary(RLibrary aLib)
1.64 + {
1.65 + iLibrary=aLib;
1.66 + }
1.67 +
1.68 +/**
1.69 +Gets the plugin factory's resource library.
1.70 +
1.71 +@return The plugin factory's resource library.
1.72 +*/
1.73 +EXPORT_C RLibrary CFsPluginFactory::Library() const
1.74 + {
1.75 + return(iLibrary);
1.76 + }
1.77 +
1.78 +/**
1.79 +
1.80 +*/
1.81 +TBool CFsPluginFactory::IsDriveSupported(TInt aDrive)
1.82 + {
1.83 + //If this is version 1 of the plugins, then if KPluginAutoAttach was specified at mount
1.84 + //then it just returned ETrue! This behaviour is preserved here:
1.85 + if(!(iSupportedDrives & KPluginVersionTwo) && (aDrive == KPluginAutoAttach))
1.86 + {
1.87 + return(ETrue);
1.88 + }
1.89 +
1.90 + //If we're version 2 plugin (or version1 && !KPluginAutoAttach) then check against what's been set in iSupportedDrives
1.91 + return((iSupportedDrives & (1 << aDrive)) ? (TBool)ETrue : (TBool)EFalse);
1.92 + }
1.93 +
1.94 +
1.95 +EXPORT_C CFsPlugin::CFsPlugin()
1.96 + : iReadOnly(0)
1.97 + {
1.98 + Mem::FillZ(iRegisteredIntercepts, sizeof(iRegisteredIntercepts));
1.99 + }
1.100 +
1.101 +EXPORT_C CFsPlugin::~CFsPlugin()
1.102 + {
1.103 + }
1.104 +
1.105 +/**
1.106 +Delivers the request to the end of plugin thread's queue.
1.107 +In certain circumstances, where the request requires priority handling
1.108 +it adds it to the front of the queue.
1.109 +
1.110 +@param aRequest: The request to be delivered
1.111 +@return KErrNone
1.112 +*/
1.113 +EXPORT_C TInt CFsPlugin::Deliver(TFsPluginRequest& aRequest)
1.114 + {
1.115 + __ASSERT_ALWAYS(iThreadP != NULL, User::Panic(_L("CFsPlugin::Dispatch"),999));
1.116 +
1.117 + TInt function = aRequest.Function();
1.118 +
1.119 + if(function == EFsPluginOpen)
1.120 + {
1.121 + // Don't dispatch open requests to the plugin thread
1.122 + return KPluginMessageForward;
1.123 + }
1.124 +
1.125 + if(function == EFsPluginDoRequest ||
1.126 + function == EFsPluginDoControl ||
1.127 + function == EFsPluginDoCancel)
1.128 + {
1.129 + iThreadP->DeliverFront(aRequest.Request());
1.130 + }
1.131 + else
1.132 + {
1.133 + iThreadP->DeliverBack(aRequest.Request());
1.134 + }
1.135 +
1.136 + return KErrNone;
1.137 + }
1.138 +
1.139 +/**
1.140 +Initialises the plugin but setting all registered intercepts to zero.
1.141 +Derived classes might wish to implement their own InitialiseL to add intercepts
1.142 +*/
1.143 +EXPORT_C void CFsPlugin::InitialiseL()
1.144 + {
1.145 + }
1.146 +
1.147 +/**
1.148 +Creates a new pluginconn object
1.149 +Leaves with KErrNotSupported
1.150 +
1.151 +@return NULL
1.152 +*/
1.153 +EXPORT_C CFsPluginConn* CFsPlugin::NewPluginConnL()
1.154 + {
1.155 + User::Leave(KErrNotSupported);
1.156 + return NULL;
1.157 + }
1.158 +
1.159 +/**
1.160 +Registers a particular function with plugin to be intercepted
1.161 +
1.162 +@param aMessage: the message to be intercepted
1.163 +@param aInterceptAtts: If it is post or pre intercept
1.164 +@return KErrNone on successful completion
1.165 + KErrNotSupported if message is invalid
1.166 +*/
1.167 +EXPORT_C TInt CFsPlugin::RegisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
1.168 + {
1.169 + if(aMessage >= EMaxClientOperations)
1.170 + {
1.171 + return KErrNotSupported;
1.172 + }
1.173 +
1.174 + const TUint32 index = aMessage >> 2; //-- index in the intercepts array
1.175 +
1.176 + if(index >= KIntcArrSize)
1.177 + {
1.178 + __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
1.179 + return KErrNotSupported;
1.180 + }
1.181 +
1.182 + const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
1.183 + iRegisteredIntercepts[index] |= msk;
1.184 +
1.185 + return KErrNone;
1.186 + }
1.187 +
1.188 +/**
1.189 +Unregisters a particular function with plugin
1.190 +
1.191 +@param aMessage: the message which should be unregistered
1.192 +@param aInterceptAtts: If it is post or pre intercept
1.193 +@return KErrNone on successful completion
1.194 + KErrNotSupported if message is invalid
1.195 +*/
1.196 +EXPORT_C TInt CFsPlugin::UnregisterIntercept(TInt aMessage, TInterceptAtts aInterceptAtts)
1.197 + {
1.198 + if(aMessage >= EMaxClientOperations)
1.199 + {
1.200 + return KErrNotSupported;
1.201 + }
1.202 +
1.203 + const TUint32 index = aMessage >> 2; //-- index in the intercepts array
1.204 + if(index >= KIntcArrSize)
1.205 + {
1.206 + __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
1.207 + return KErrNotSupported;
1.208 + }
1.209 +
1.210 + const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
1.211 + iRegisteredIntercepts[index] &= ~msk;
1.212 +
1.213 + return KErrNone;
1.214 + }
1.215 +
1.216 +/**
1.217 + @return ETrue if the message aMessage is registered with any TInterceptAtts type
1.218 +*/
1.219 +TBool CFsPlugin::IsRegistered(TInt aMessage)
1.220 + {
1.221 + if(IsRegistered(aMessage,(TInterceptAtts)EPreIntercept) ||
1.222 + IsRegistered(aMessage,(TInterceptAtts)EPrePostIntercept) ||
1.223 + IsRegistered(aMessage, (TInterceptAtts)EPostIntercept))
1.224 + {
1.225 + return (TBool)ETrue;
1.226 + }
1.227 + return (TBool)EFalse;
1.228 + }
1.229 +
1.230 +/**
1.231 + @return ETrue if the message aMessage is registered with the given aInterceptAtts attrubutes
1.232 +*/
1.233 +TBool CFsPlugin::IsRegistered(TInt aMessage, TInterceptAtts aInterceptAtts)
1.234 + {
1.235 + if(aMessage >= EMaxClientOperations)
1.236 + {
1.237 + return EFalse;
1.238 + }
1.239 +
1.240 + const TUint32 index = aMessage >> 2; //-- index in the intercepts array
1.241 + if(index >= KIntcArrSize)
1.242 + {
1.243 + __ASSERT_DEBUG(0,Fault(EArrayIndexOutOfRange));
1.244 + return EFalse;
1.245 + }
1.246 +
1.247 + const TUint8 msk = (TUint8)(aInterceptAtts << ((aMessage & 0x03) << 1));
1.248 +
1.249 + return((iRegisteredIntercepts[index] & msk) == msk);
1.250 + }
1.251 +
1.252 +/**
1.253 + Return ETrue if the calling thread is the plugin thread
1.254 +*/
1.255 +TBool CFsPlugin::IsPluginThread(CFsRequest& aRequest)
1.256 + {
1.257 + if(aRequest.iOwnerPlugin == this)
1.258 + return ETrue;
1.259 +
1.260 + if(aRequest.iClientThreadId == iThreadId)
1.261 + return ETrue;
1.262 +
1.263 + // Allow specific requests from the client connection...
1.264 + if(aRequest.IsPluginSpecific())
1.265 + return EFalse;
1.266 +
1.267 + // Check the client connections
1.268 + return FsPluginManager::IsPluginConnThread(aRequest.iClientThreadId, this);
1.269 + }
1.270 +
1.271 +TBool CFsPlugin::IsMounted(TInt aDrive)
1.272 + {
1.273 + CFsPluginFactory* pF = FsPluginManager::GetPluginFactory(this->Name());
1.274 + TInt supportedDrives = pF->SupportedDrives();
1.275 +
1.276 + //Version1 plugins could not mount on Z Drive as KPluginAutoAttach==0x19==25==EDriveZ
1.277 + //Drive Z is only supported for version two of the plugins.
1.278 + //Prevent version 1 plugins here.
1.279 + if (!(supportedDrives & KPluginVersionTwo) && (aDrive == EDriveZ))
1.280 + return EFalse;
1.281 +
1.282 + //Some requests have aDrive as -1, so for those requests
1.283 + // so long as the plugin was registered we shall say it's mounted.
1.284 + if(aDrive > EDriveZ || aDrive < EDriveA)
1.285 + return ETrue;
1.286 +
1.287 + //Otherwise Check iMountedOn
1.288 + if(iMountedOn&(1<<aDrive))
1.289 + {
1.290 + return ETrue;
1.291 + }
1.292 +
1.293 + return EFalse;
1.294 + }
1.295 +
1.296 +// NOTE: The following API classification might need changing
1.297 +
1.298 +/**
1.299 +@prototype
1.300 +@deprecated
1.301 +@see RFilePlugin::Read
1.302 + */
1.303 +EXPORT_C TInt CFsPlugin::FileRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos)
1.304 + {
1.305 + CFileShare* share;
1.306 + CFileCB* file;
1.307 + GetFileFromScratch((CFsMessageRequest*) aRequest.Request(), share, file);
1.308 + TInt64 fileSize = file->CachedSize64();
1.309 + if (aPos > fileSize)
1.310 + aPos = fileSize;
1.311 + TInt len = aDes.Length();
1.312 + if (aPos >= fileSize)
1.313 + len = 0;
1.314 + if (aPos + len > fileSize)
1.315 + // filesize - pos shall of TInt size
1.316 + // Hence to suppress warning
1.317 + len = (TInt)(fileSize - aPos);
1.318 + aDes.SetLength(len);
1.319 +
1.320 + return DispatchOperation(aRequest, aDes, aPos, EFsFileRead);
1.321 + }
1.322 +
1.323 +/**
1.324 +@prototype
1.325 +@deprecated
1.326 +@see RFilePlugin::Write
1.327 +*/
1.328 +EXPORT_C TInt CFsPlugin::FileWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt64 aPos)
1.329 + {
1.330 + return DispatchOperation(aRequest, (TDes8&) aDes, aPos, EFsFileWrite);
1.331 + }
1.332 +
1.333 +/**
1.334 +@internalTechnology
1.335 +@prototype
1.336 +@deprecated
1.337 +
1.338 +Pushes a msgop, dispatches it and waits for it to complete
1.339 +*/
1.340 +TInt CFsPlugin::DispatchOperation(TFsPluginRequest& aRequest, TDes8& aDes, TInt64 aPos, TInt aFunction)
1.341 + {
1.342 + if (aRequest.Function() != EFsFileRead && aRequest.Function() != EFsFileWrite)
1.343 + return KErrNotSupported;
1.344 + if (aFunction != EFsFileRead && aFunction != EFsFileWrite)
1.345 + return KErrNotSupported;
1.346 +
1.347 + CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
1.348 +
1.349 +
1.350 + TInt len = aDes.Length();
1.351 + if (len <= 0)
1.352 + return CFsRequest::EReqActionComplete;
1.353 +
1.354 + TUint8* ptr = (TUint8*) aDes.Ptr();
1.355 +
1.356 + TInt r = msgRequest.PushOperation(
1.357 + aPos, len, ptr,
1.358 + 0, // aOffset
1.359 + Complete, // callback
1.360 + 0, // next state
1.361 + aFunction);
1.362 + if (r != KErrNone)
1.363 + return r;
1.364 +
1.365 +
1.366 + CFsPlugin* plugin = this;
1.367 + FsPluginManager::NextPlugin(plugin, &msgRequest,(TBool)ETrue);
1.368 + msgRequest.iCurrentPlugin = plugin;
1.369 + msgRequest.Dispatch();
1.370 + iThreadP->OperationLockWait();
1.371 +
1.372 + aDes.SetLength(len);
1.373 +
1.374 + return msgRequest.LastError(); // KErrNone;
1.375 + }
1.376 +
1.377 +TInt CFsPlugin::WaitForRequest()
1.378 + {
1.379 + iLastError = KErrNone;
1.380 + iThreadP->OperationLockWait();
1.381 + return iLastError;
1.382 + }
1.383 +
1.384 +
1.385 +/** @prototype */
1.386 +TInt CFsPlugin::Complete(CFsRequest* aRequest, TInt aError)
1.387 + {
1.388 + CFsMessageRequest& msgRequest = *(CFsMessageRequest*) aRequest;
1.389 +
1.390 + CFsPlugin* plugin = msgRequest.iOwnerPlugin;
1.391 + if (plugin)
1.392 + {
1.393 + plugin->iLastError = aError;
1.394 + plugin->iThreadP->OperationLockSignal();
1.395 + msgRequest.iOwnerPlugin = NULL;
1.396 + return CFsRequest::EReqActionComplete;
1.397 + }
1.398 +
1.399 + TMsgOperation& currentOperation = msgRequest.CurrentOperation();
1.400 +
1.401 + if (currentOperation.iState == 0) // waiting ?
1.402 + {
1.403 + currentOperation.iState = 1;
1.404 + msgRequest.iCurrentPlugin->iThreadP->OperationLockSignal();
1.405 + // DON'T dispatch message again, DON'T complete message
1.406 + return CFsRequest::EReqActionOwnedByPlugin;
1.407 + }
1.408 + else
1.409 + {
1.410 + return CFsRequest::EReqActionComplete;
1.411 + }
1.412 + }
1.413 +
1.414 +/** @prototype */
1.415 +TInt CFsPlugin::Complete(CFsRequest* aRequest)
1.416 + {
1.417 + return CFsPlugin::Complete(aRequest, KErrNone);
1.418 + }
1.419 +
1.420 +/** @prototype */
1.421 +EXPORT_C TInt CFsPlugin::ClientWrite(TFsPluginRequest& aRequest, const TDesC8& aDes, TInt aOffset)
1.422 + {
1.423 + CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
1.424 + TMsgOperation& currentOperation = msgRequest.CurrentOperation();
1.425 +
1.426 + TInt r = KErrNone;
1.427 + if (currentOperation.iClientRequest)
1.428 + {
1.429 + r = msgRequest.Write(0, aDes, aOffset);
1.430 + }
1.431 + else
1.432 + {
1.433 + TInt len = aDes.Length();
1.434 + if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
1.435 + return KErrArgument;
1.436 + memcpy(((TUint8*) currentOperation.iReadWriteArgs.iData) + aOffset, aDes.Ptr(), len);
1.437 + currentOperation.iReadWriteArgs.iOffset = aOffset + len;
1.438 + }
1.439 + return r;
1.440 + }
1.441 +
1.442 +/** @prototype */
1.443 +EXPORT_C TInt CFsPlugin::ClientRead(TFsPluginRequest& aRequest, TDes8& aDes, TInt aOffset)
1.444 + {
1.445 + CFsMessageRequest& msgRequest = * (CFsMessageRequest*) aRequest.Request();
1.446 + TMsgOperation& currentOperation = msgRequest.CurrentOperation();
1.447 +
1.448 + TInt r = KErrNone;
1.449 + if (currentOperation.iClientRequest)
1.450 + {
1.451 + r = msgRequest.Read(0, aDes, aOffset);
1.452 + }
1.453 + else
1.454 + {
1.455 + TInt len = aDes.Length();
1.456 + if (len > (currentOperation.iReadWriteArgs.iTotalLength - aOffset))
1.457 + return KErrArgument;
1.458 + aDes.Copy ( (TUint8*) currentOperation.iReadWriteArgs.iData + aOffset, len );
1.459 + currentOperation.iReadWriteArgs.iOffset = aOffset + len;
1.460 + }
1.461 + return r;
1.462 + }
1.463 +
1.464 +/**
1.465 +Constructs a TFsPluginRequest object
1.466 +@param aReuqest client's request, to be wrapped by TFsPluginRequest object
1.467 +*/
1.468 +EXPORT_C TFsPluginRequest::TFsPluginRequest(CFsRequest* aRequest)
1.469 + : iFsRequest(aRequest)
1.470 + { }
1.471 +
1.472 +/**
1.473 +@return The function of the request
1.474 +*/
1.475 +EXPORT_C TInt TFsPluginRequest::Function() const
1.476 + { return(iFsRequest->Operation()->Function()); }
1.477 +
1.478 +/**
1.479 +@return The drive number of the request
1.480 +*/
1.481 +EXPORT_C TInt TFsPluginRequest::DriveNumber() const
1.482 + { return(iFsRequest->DriveNumber()); }
1.483 +
1.484 +/**
1.485 +@return The source of the request (often the filename)
1.486 +*/
1.487 +EXPORT_C TParse& TFsPluginRequest::Src() const
1.488 + { return(iFsRequest->Src()); }
1.489 +
1.490 +/**
1.491 +@return The destination of the request (often the filename)
1.492 +*/
1.493 +EXPORT_C TParse& TFsPluginRequest::Dest() const
1.494 + { return(iFsRequest->Dest()); }
1.495 +
1.496 +/**
1.497 +@return The drive of the request
1.498 +*/
1.499 +EXPORT_C TDrive* TFsPluginRequest::Drive() const
1.500 + { return(iFsRequest->Drive()); }
1.501 +
1.502 +/**
1.503 +@return The substitude drive of the request
1.504 +*/
1.505 +EXPORT_C TDrive* TFsPluginRequest::SubstedDrive() const
1.506 + { return(iFsRequest->SubstedDrive()); }
1.507 +
1.508 +/**
1.509 +@return The message of the request
1.510 +*/
1.511 +EXPORT_C const RMessage2& TFsPluginRequest::Message() const
1.512 + { return(iFsRequest->Message()); }
1.513 +
1.514 +/**
1.515 +@return The request itself
1.516 +*/
1.517 +EXPORT_C CFsRequest* TFsPluginRequest::Request() const
1.518 + {
1.519 + __ASSERT_DEBUG(iFsRequest != NULL, User::Invariant());
1.520 + return iFsRequest;
1.521 + }
1.522 +
1.523 +/**
1.524 +@return The scratch value of the request
1.525 +*/
1.526 +EXPORT_C TUint TFsPluginRequest::ScratchValue() const
1.527 + { return iFsRequest->ScratchValue(); }
1.528 +
1.529 +/**
1.530 +@return The scratch value of the request
1.531 +*/
1.532 +EXPORT_C TInt64 TFsPluginRequest::ScratchValue64() const
1.533 + { return iFsRequest->ScratchValue64(); }
1.534 +
1.535 +/**
1.536 +@return ETrue if the operation is in Post-Intercept
1.537 +*/
1.538 +EXPORT_C TInt TFsPluginRequest::IsPostOperation() const
1.539 + { return(iFsRequest->IsPostOperation()); }
1.540 +
1.541 +
1.542 +EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes8& aDes, TInt aOffset)
1.543 + {
1.544 + return(iFsRequest->Read(aType, aDes, aOffset));
1.545 + }
1.546 +
1.547 +EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TDes16& aDes, TInt aOffset)
1.548 + {
1.549 + //The following if packaged correctly will never come here
1.550 + //but just in case someone tries something wrong with a wonky wide descriptor
1.551 + switch(aType)
1.552 + {
1.553 + case (TF32ArgType)EEntryArray:
1.554 + case (TF32ArgType)EEntry:
1.555 + case (TF32ArgType)EUid:
1.556 + case (TF32ArgType)ETime:
1.557 + return KErrBadDescriptor;
1.558 + default:
1.559 + break;
1.560 + }
1.561 + return(iFsRequest->Read(aType, aDes, aOffset));
1.562 + }
1.563 +
1.564 +EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt& aVal)
1.565 + {
1.566 + //
1.567 + // Some messages require special handling...
1.568 + //
1.569 + if(aType == (TF32ArgType)EPosition)
1.570 + {
1.571 + return KErrArgument;
1.572 + }
1.573 +
1.574 + return iFsRequest->Read(aType, aVal);
1.575 + }
1.576 +
1.577 +EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TUint& aVal)
1.578 + {
1.579 + //
1.580 + // Some messages require special handling...
1.581 + //
1.582 + if(aType == (TF32ArgType)EPosition)
1.583 + {
1.584 + return KErrArgument;
1.585 + }
1.586 +
1.587 + return iFsRequest->Read(aType, aVal);
1.588 + }
1.589 +
1.590 +EXPORT_C TInt TFsPluginRequest::Read(TF32ArgType aType, TInt64& aVal)
1.591 + {
1.592 + TInt err = iFsRequest->Read(aType, aVal);
1.593 + if(err != KErrNone)
1.594 + return err;
1.595 +
1.596 + //
1.597 + // Some messages require special handling...
1.598 + //
1.599 + if(aType == (TF32ArgType)EPosition)
1.600 + {
1.601 + TInt op = Function();
1.602 + if(op == EFsFileRead || op == EFsFileWrite)
1.603 + {
1.604 + if (aVal == KCurrentPosition64)
1.605 + {
1.606 + CFileShare* share = (CFileShare*)iFsRequest->ScratchValue();
1.607 + if(share == NULL)
1.608 + return KErrBadHandle;
1.609 +
1.610 + aVal = share->iPos;
1.611 + }
1.612 + }
1.613 + }
1.614 +
1.615 + return KErrNone;
1.616 + }
1.617 +
1.618 +EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC8& aDes, TInt aOffset)
1.619 + {
1.620 + return(iFsRequest->Write(aType, aDes, aOffset));
1.621 + }
1.622 +
1.623 +
1.624 +EXPORT_C TInt TFsPluginRequest::Write(TF32ArgType aType, const TDesC16& aDes, TInt aOffset)
1.625 + {
1.626 + return(iFsRequest->Write(aType, aDes, aOffset));
1.627 + }
1.628 +
1.629 +EXPORT_C TInt TFsPluginRequest::FileName(TDes& aName)
1.630 + {
1.631 + //Special handling required for directories.
1.632 + switch(Function())
1.633 + {
1.634 + case EFsDirOpen:
1.635 + case EFsSetEntry:
1.636 + {
1.637 + aName.Copy(Request()->Src().FullName());
1.638 + break;
1.639 + }
1.640 + case EFsDirReadOne:
1.641 + case EFsDirReadPacked:
1.642 + case EFsDirSubClose:
1.643 + {
1.644 + //Get the name from CDirCB::iName
1.645 + CDirCB* dir = (CDirCB*) ScratchValue();
1.646 + __ASSERT_ALWAYS(dir!= NULL, Fault(EPluginOpError));
1.647 + TName name = dir->Name();
1.648 + if(name.Size() == 0)
1.649 + {
1.650 + return KErrNotFound;
1.651 + }
1.652 + aName.Copy(name);
1.653 + break;
1.654 + }
1.655 + default:
1.656 + {
1.657 + CFileShare* share;
1.658 + TInt err = ShareFromClientHandle(share);
1.659 + if(err != KErrNone || share == NULL)
1.660 + return(err);
1.661 +
1.662 + NameFromShare(*share, aName);
1.663 + }
1.664 + }
1.665 + return KErrNone;
1.666 + }
1.667 +
1.668 +EXPORT_C TInt TFsPluginRequest::SetSharePos(TInt64& aPos)
1.669 + {
1.670 + CFileShare* share;
1.671 + TInt err = ShareFromClientHandle(share);
1.672 + if(err != KErrNone || share == NULL)
1.673 + return(KErrBadHandle);
1.674 +
1.675 + share->File().Drive().Lock();
1.676 + share->iPos = aPos;
1.677 + share->File().Drive().UnLock();
1.678 +
1.679 + return KErrNone;
1.680 + }
1.681 +
1.682 +TInt TFsPluginRequest::ShareFromClientHandle(CFileShare*& aShare)
1.683 + {
1.684 + aShare = NULL;
1.685 +
1.686 + TInt handle;
1.687 + TInt err = ClientSubSessionHandle(handle);
1.688 + if(err != KErrNone)
1.689 + return err;
1.690 +
1.691 + aShare = GetShareFromHandle(iFsRequest->Session(), handle);
1.692 +
1.693 + return aShare ? KErrNone : KErrBadHandle;
1.694 + }
1.695 +
1.696 +TInt TFsPluginRequest::ClientSubSessionHandle(TInt& aHandle)
1.697 + {
1.698 + aHandle = 0;
1.699 +
1.700 + // Subsession handle is in Arg[3] for read/write etc, but
1.701 + // when subsession create it's contained in client descriptor
1.702 + if(iFsRequest->Operation()->IsOpenSubSess())
1.703 + {
1.704 + if(!IsPostOperation())
1.705 + return KErrNotSupported;
1.706 +
1.707 + TPtr8 handleDes((TUint8*)&aHandle,sizeof(TInt));
1.708 + TInt err = iFsRequest->Read(KMsgPtr3,handleDes);
1.709 + if(err != KErrNone)
1.710 + return err;
1.711 + }
1.712 + else
1.713 + {
1.714 + aHandle = iFsRequest->Message().Int3();
1.715 + }
1.716 +
1.717 + return KErrNone;
1.718 + }
1.719 +
1.720 +/**
1.721 +@publishedPartner
1.722 +
1.723 +Utility function to obtain the file name from a file share object
1.724 +
1.725 +@param aFileShare A pointer to the file share
1.726 +@param aName A reference to the descriptor to contain the file name
1.727 +*/
1.728 +void TFsPluginRequest::NameFromShare(CFileShare& aFileShare, TDes& aName)
1.729 + {
1.730 + CFileCB& theFile = aFileShare.File();
1.731 + aName = _L("?:");
1.732 + aName[0] = TText('A' + theFile.Drive().DriveNumber());
1.733 + aName.Append(theFile.FileName());
1.734 + }
1.735 +
1.736 +
1.737 +/**
1.738 +Constructor of plugin connection object
1.739 +*/
1.740 +EXPORT_C CFsPluginConn::CFsPluginConn()
1.741 + {
1.742 + }
1.743 +
1.744 +/**
1.745 +Destructor of plugin conn. object
1.746 +*/
1.747 +EXPORT_C CFsPluginConn::~CFsPluginConn()
1.748 + {
1.749 + }
1.750 +
1.751 +/**
1.752 +Closes the plugin conn.
1.753 +*/
1.754 +EXPORT_C void CFsPluginConn::Close()
1.755 + {
1.756 + iRequestQue.DoCancelAll(KErrCancel);
1.757 + CFsObject::Close();
1.758 + }
1.759 +
1.760 +CFsPluginConnRequest::CFsPluginConnRequest(CFsPluginConn* aPluginConn)
1.761 + : iPluginConn(*aPluginConn)
1.762 + {
1.763 + }
1.764 +
1.765 +TInt CFsPluginConnRequest::InitControl(CFsRequest* aRequest)
1.766 + {
1.767 + iMessage = aRequest->Message();
1.768 + const RMessage2& m = aRequest->Message();
1.769 + iFunction = m.Int0();
1.770 + iParam1 = (TDes8*)m.Ptr1();
1.771 + iParam2 = (TDes8*)m.Ptr2();
1.772 + return KErrNone;
1.773 + }
1.774 +
1.775 +TInt CFsPluginConnRequest::DoControl()
1.776 + {
1.777 + return iPluginConn.DoControl(*this);
1.778 + }
1.779 +
1.780 +TInt CFsPluginConnRequest::InitRequest(CFsRequest* aRequest)
1.781 + {
1.782 + InitControl(aRequest);
1.783 + iPluginConn.iRequestQue.DoAddRequest(this);
1.784 + return KErrNone;
1.785 + }
1.786 +
1.787 +void CFsPluginConnRequest::DoRequest()
1.788 + {
1.789 + iPluginConn.DoRequest(*this);
1.790 + }
1.791 +
1.792 +TPluginConnRequestQue::TPluginConnRequestQue()
1.793 + {
1.794 + iHeader.SetOffset(_FOFF(CFsPluginConnRequest,iLink));
1.795 + }
1.796 +
1.797 +TPluginConnRequestQue::~TPluginConnRequestQue()
1.798 + {
1.799 + }
1.800 +
1.801 +void TPluginConnRequestQue::DoAddRequest(CFsPluginConnRequest* aRequest)
1.802 + {
1.803 + iHeader.AddLast(*aRequest);
1.804 + }
1.805 +
1.806 +/**
1.807 +Cancels all the requests of plugin connection
1.808 +
1.809 +@param aCompletionCode: the code the request are completed
1.810 +*/
1.811 +EXPORT_C void TPluginConnRequestQue::DoCancelAll(TInt aCompletionCode)
1.812 + {
1.813 + TDblQueIter<CFsPluginConnRequest> q(iHeader);
1.814 + CFsPluginConnRequest* info;
1.815 + while((info=q++)!=NULL)
1.816 + {
1.817 + info->Complete(aCompletionCode);
1.818 + }
1.819 + __ASSERT_DEBUG(iHeader.IsEmpty(),Fault(EBaseQueCancel));
1.820 + }
1.821 +
1.822 +
1.823 +/**
1.824 +*/
1.825 +EXPORT_C TDes8& TRawEntryArray::Buf()
1.826 + { return iBuf; }
1.827 +
1.828 +/**
1.829 +*/
1.830 +EXPORT_C void TRawEntryArray::SetBuf(TDes8& aBuf)
1.831 + {
1.832 + iCount = KCountNeeded;
1.833 + iBuf.Copy(aBuf);
1.834 + }
1.835 +
1.836 +/**
1.837 +*/
1.838 +EXPORT_C TInt TRawEntryArray::EntrySize(TInt aIdx)
1.839 + { return Align4(::EntrySize((*this)[aIdx])); }