os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,254 @@
1.4 +// Copyright (c) 2008-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 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @internalTechnology
1.22 +*/
1.23 +
1.24 +#include <e32std.h>
1.25 +#include <f32file.h>
1.26 +
1.27 +#include "rusbhostmsdevice.h"
1.28 +#include "debug.h"
1.29 +#include "msgservice.h"
1.30 +
1.31 +_LIT(KFileSystem, "FAT");
1.32 +
1.33 +TVersion RUsbHostMsDevice::Version() const
1.34 + {
1.35 + __FNLOG("RUsbHostMsDevice::Version");
1.36 + return(TVersion(KUsbHostMsSrvMajorVersionNumber,
1.37 + KUsbHostMsSrvMinorVersionNumber,
1.38 + KUsbHostMsSrvBuildVersionNumber));
1.39 + }
1.40 +
1.41 +
1.42 +TInt RUsbHostMsDevice::StartServer()
1.43 + {
1.44 + __FNLOG("RUsbHostMsDevice::StartServer");
1.45 + TInt r;
1.46 + RProcess server;
1.47 +
1.48 + const TUid KServerUid3={0x10286A83};
1.49 + const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
1.50 +
1.51 + // Create the server process
1.52 + if((r=server.Create(KUsbHostMsServerName,KNullDesC,serverUid)) != KErrNone)
1.53 + {
1.54 + __PRINT1(_L("Server process create = %d\n"), r);
1.55 + return r;
1.56 + }
1.57 +
1.58 + // Create the rendezvous request with the server process
1.59 + TRequestStatus stat;
1.60 + server.Rendezvous(stat);
1.61 + if (stat!=KRequestPending)
1.62 + {
1.63 + server.Kill(0); // If the outstanding request is not pending then kill the server
1.64 + }
1.65 + else
1.66 + {
1.67 + server.SetPriority(EPriorityHigh);
1.68 + server.Resume(); // start the server
1.69 + }
1.70 +
1.71 + // Test whether the process has ended and if it has ended, return how it ended.
1.72 + User::WaitForRequest(stat);
1.73 + r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
1.74 +
1.75 + server.Close();
1.76 + return r;
1.77 + }
1.78 +
1.79 +EXPORT_C RUsbHostMsDevice::RUsbHostMsDevice()
1.80 + {
1.81 + // Intentionally left blank
1.82 + }
1.83 +
1.84 +
1.85 +/**
1.86 +@internalAll
1.87 +@prototype
1.88 +
1.89 +Add the Mass Storage device to the MSC server. This API is asynchronous, upon
1.90 +completion one could find the number of logical units present in the added
1.91 +device by calling GetNumLun API. Calling the Remove API before completing this
1.92 +asynchronous API will complete the pending request notification with KErrCancel.
1.93 +
1.94 +@param aConfig [In] A constant reference object to
1.95 + THostMassStorageConfig containing the confiquration values of
1.96 + the massstorage device requested to add to the MSC
1.97 +@param aStatus [In] A reference to TRequestStatus to be used for asynchronous
1.98 + request completion
1.99 +*/
1.100 +EXPORT_C void RUsbHostMsDevice::Add(const THostMassStorageConfig& aConfig, TRequestStatus& aStatus)
1.101 + {
1.102 + __FNLOG("RUsbHostMsDevice::Add");
1.103 + TInt err = KErrNone;
1.104 +
1.105 + err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
1.106 +
1.107 + // Being a transient server, the first session creation would fail with if
1.108 + // the server is not running
1.109 + if(err != KErrNone)
1.110 + {
1.111 + // Find whether the session creation failed because server was not
1.112 + // running
1.113 + if (err==KErrNotFound || err==KErrServerTerminated)
1.114 + {
1.115 + // Start the server
1.116 + err = StartServer();
1.117 + if(err == KErrNone)
1.118 + {
1.119 + // Try session creation again
1.120 + err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
1.121 + }
1.122 + }
1.123 + }
1.124 +
1.125 + TRequestStatus* statusPtr = &aStatus;
1.126 + if(err == KErrNone)
1.127 + {
1.128 + // Create a session handle that can be passed via IPC to another process
1.129 + // (also being shared by other threads in the current process)
1.130 + err = ShareProtected();
1.131 + if(err == KErrNone)
1.132 + {
1.133 + // synchronous call to register the interface
1.134 + TPckg<THostMassStorageConfig> pckg(aConfig);
1.135 + err = SendReceive(EUsbHostMsRegisterInterface, TIpcArgs(&pckg));
1.136 + if(err != KErrNone)
1.137 + {
1.138 + User::RequestComplete(statusPtr, err);
1.139 + }
1.140 + else
1.141 + {
1.142 + // Asynchronous call to initialise the interface
1.143 + SendReceive(EUsbHostMsInitialiseInterface, TIpcArgs(NULL), aStatus);
1.144 + }
1.145 + }
1.146 + else
1.147 + {
1.148 + Close(); // Close the session handle
1.149 + __PRINT1(_L("Could not create a sharable session handle %d\n"), err);
1.150 + User::RequestComplete(statusPtr, err);
1.151 + }
1.152 + }
1.153 + else
1.154 + {
1.155 + // Check whether the error is in starting the server or in creating the
1.156 + // session
1.157 + __PRINT1(_L("Creating server/session failed with %d\n"), err);
1.158 + User::RequestComplete(statusPtr, err);
1.159 + }
1.160 + }
1.161 +
1.162 +
1.163 +/**
1.164 +@internalAll
1.165 +@prototype
1.166 +
1.167 +Remove the Mass Storage device from the MSC server.
1.168 +*/
1.169 +EXPORT_C void RUsbHostMsDevice::Remove()
1.170 + {
1.171 + // Note: Here, at present we use only the interface token. But we still take
1.172 + // THostMassStorageConfig as parameter for future needs
1.173 + __FNLOG("RUsbHostMsDevice::Remove");
1.174 + _LIT(KUsbHostMsClientPanicCat, "usbhostmsclient");
1.175 +
1.176 + TInt r = SendReceive(EUsbHostMsUnRegisterInterface);
1.177 +
1.178 + r = SendReceive(EUsbHostMsFinalCleanup);
1.179 + if(r != KErrNone)
1.180 + {
1.181 + User::Panic(KUsbHostMsClientPanicCat ,KErrCouldNotDisconnect);
1.182 + }
1.183 + Close(); // Close the session handle
1.184 + }
1.185 +
1.186 +
1.187 +/**
1.188 +@internalAll
1.189 +@prototype
1.190 +
1.191 +Get the number of logical units suppoted by the device.
1.192 +
1.193 +@param aNumLuns [Out] Outputs the number of logical units found in the
1.194 + added Mass Storage device. A value of 'n' represents there are
1.195 + 'n' LUNs present in the device, where "n > 0"
1.196 +
1.197 +@return TInt
1.198 +*/
1.199 +EXPORT_C TInt RUsbHostMsDevice::GetNumLun(TUint32& aNumLuns)
1.200 + {
1.201 + __FNLOG("RUsbHostMsDevice::GetNumLun");
1.202 + TPckg<TUint32> pckg(aNumLuns);
1.203 + return SendReceive(EUsbHostMsGetNumLun,TIpcArgs(&pckg));
1.204 + }
1.205 +
1.206 +
1.207 +EXPORT_C TInt RUsbHostMsDevice::MountLun(TUint32 aLunId, TInt aDriveNum)
1.208 + {
1.209 + __FNLOG("RUsbHostMsDevice::MountLun");
1.210 + RFs TheFs;
1.211 + TInt r = TheFs.Connect();
1.212 + if(r == KErrNone)
1.213 + {
1.214 + TPckgBuf<TMassStorageUnitInfo> unitPkg;
1.215 + unitPkg().iLunID = aLunId;
1.216 +
1.217 + r = TheFs.MountProxyDrive(aDriveNum, _L("usbhostms"), &unitPkg, *this);
1.218 + if(r >= KErrNone)
1.219 + {
1.220 + r = TheFs.MountFileSystem(KFileSystem, aDriveNum);
1.221 +
1.222 + if(r != KErrNone && r != KErrNotReady && r != KErrCorrupt)
1.223 + {
1.224 + TheFs.DismountFileSystem(KFileSystem, aDriveNum);
1.225 + TheFs.DismountProxyDrive(aDriveNum);
1.226 + }
1.227 + }
1.228 + TheFs.Close();
1.229 + }
1.230 + return r;
1.231 + }
1.232 +
1.233 +EXPORT_C TInt RUsbHostMsDevice::DismountLun(TInt aDriveNum)
1.234 + {
1.235 + __FNLOG("RUsbHostMsDevice::DismountLun");
1.236 + RFs TheFs;
1.237 + TInt r;
1.238 + r = TheFs.Connect();
1.239 + if(r == KErrNone)
1.240 + {
1.241 + r = TheFs.DismountFileSystem(KFileSystem, aDriveNum);
1.242 + if(r != KErrNone)
1.243 + {
1.244 + // dismount failed - attempt a forced dismount
1.245 + TRequestStatus stat;
1.246 + TheFs.NotifyDismount(aDriveNum, stat, EFsDismountForceDismount);
1.247 + User::WaitForRequest(stat);
1.248 + r = stat.Int();
1.249 + }
1.250 + if(r == KErrNone)
1.251 + {
1.252 + r = TheFs.DismountProxyDrive(aDriveNum);
1.253 + }
1.254 + TheFs.Close();
1.255 + }
1.256 + return r;
1.257 + }