os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp
changeset 0 bde4ae8d615e
     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 +	}