userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp
changeset 0 a41df078684a
child 97 41f0cfe18c80
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #include <e32std.h>
       
    22 #include <f32file.h>
       
    23 
       
    24 #include "rusbhostmsdevice.h"
       
    25 #include "debug.h"
       
    26 #include "msgservice.h"
       
    27 
       
    28 _LIT(KFileSystem, "FAT");
       
    29 
       
    30 TVersion RUsbHostMsDevice::Version() const
       
    31     {
       
    32 	__FNLOG("RUsbHostMsDevice::Version");
       
    33     return(TVersion(KUsbHostMsSrvMajorVersionNumber,
       
    34                     KUsbHostMsSrvMinorVersionNumber,
       
    35                     KUsbHostMsSrvBuildVersionNumber));
       
    36     }
       
    37 
       
    38 
       
    39 TInt RUsbHostMsDevice::StartServer()
       
    40     {
       
    41 	__FNLOG("RUsbHostMsDevice::StartServer");
       
    42     TInt r;
       
    43     RProcess server;
       
    44 
       
    45     const TUid KServerUid3={0x10286A83};
       
    46     const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
       
    47 
       
    48     // Create the server process
       
    49     if((r=server.Create(KUsbHostMsServerName,KNullDesC,serverUid)) != KErrNone)
       
    50         {
       
    51         __PRINT1(_L("Server process create = %d\n"), r);
       
    52         return r;
       
    53         }
       
    54 
       
    55     // Create the rendezvous request with the server process
       
    56     TRequestStatus stat;
       
    57     server.Rendezvous(stat);
       
    58     if (stat!=KRequestPending)
       
    59         {
       
    60         server.Kill(0);    // If the outstanding request is not pending then kill the server
       
    61         }
       
    62     else
       
    63         {
       
    64 		server.SetPriority(EPriorityHigh);
       
    65         server.Resume(); // start the server
       
    66         }
       
    67 
       
    68     // Test whether the process has ended and if it has ended, return how it ended.
       
    69     User::WaitForRequest(stat);
       
    70     r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
       
    71 
       
    72     server.Close();
       
    73     return r;
       
    74     }
       
    75 
       
    76 EXPORT_C RUsbHostMsDevice::RUsbHostMsDevice()
       
    77     {
       
    78         // Intentionally left blank
       
    79     }
       
    80 
       
    81 
       
    82 /**
       
    83 @internalAll
       
    84 @prototype
       
    85 
       
    86 Add the Mass Storage device to the MSC server. This API is asynchronous, upon
       
    87 completion one could find the number of logical units present in the added
       
    88 device by calling GetNumLun API. Calling the Remove API before completing this
       
    89 asynchronous API will complete the pending request notification with KErrCancel.
       
    90 
       
    91 @param aConfig [In] A constant reference object to
       
    92                 THostMassStorageConfig containing the confiquration values of
       
    93                 the massstorage device requested to add to the MSC
       
    94 @param aStatus [In] A reference to TRequestStatus to be used for asynchronous
       
    95                 request completion
       
    96 */
       
    97 EXPORT_C void RUsbHostMsDevice::Add(const THostMassStorageConfig& aConfig, TRequestStatus& aStatus)
       
    98     {
       
    99 	__FNLOG("RUsbHostMsDevice::Add");
       
   100     TInt err = KErrNone;
       
   101 
       
   102     err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
       
   103 
       
   104     // Being a transient server, the first session creation would fail with if
       
   105     // the server is not running
       
   106     if(err != KErrNone)
       
   107         {
       
   108         // Find whether the session creation failed because server was not
       
   109         // running
       
   110         if (err==KErrNotFound || err==KErrServerTerminated)
       
   111             {
       
   112             // Start the server
       
   113             err = StartServer();
       
   114             if(err == KErrNone)
       
   115                 {
       
   116                 // Try session creation again
       
   117                 err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
       
   118                 }
       
   119             }
       
   120         }
       
   121 
       
   122 	TRequestStatus* statusPtr = &aStatus;
       
   123     if(err == KErrNone)
       
   124         {
       
   125         // Create a session handle that can be passed via IPC to another process
       
   126         // (also being shared by other threads in the current process)
       
   127 		err = ShareProtected();
       
   128         if(err == KErrNone)
       
   129             {
       
   130             // synchronous call to register the interface
       
   131 			TPckg<THostMassStorageConfig> pckg(aConfig);
       
   132 	        err = SendReceive(EUsbHostMsRegisterInterface, TIpcArgs(&pckg));
       
   133 			if(err != KErrNone)
       
   134 				{
       
   135 		        User::RequestComplete(statusPtr, err);
       
   136 				}
       
   137 			else
       
   138 				{
       
   139 	            // Asynchronous call to initialise the interface
       
   140 				SendReceive(EUsbHostMsInitialiseInterface, TIpcArgs(NULL), aStatus);
       
   141 				}
       
   142 			}
       
   143         else
       
   144             {
       
   145             Close(); // Close the session handle
       
   146             __PRINT1(_L("Could not create a sharable session handle %d\n"), err);
       
   147             User::RequestComplete(statusPtr, err);
       
   148             }
       
   149         }
       
   150     else
       
   151         {
       
   152 		// Check whether the error is in starting the server or in creating the
       
   153         // session
       
   154         __PRINT1(_L("Creating server/session failed with %d\n"), err);
       
   155         User::RequestComplete(statusPtr, err);
       
   156         }
       
   157     }
       
   158 
       
   159 
       
   160 /**
       
   161 @internalAll
       
   162 @prototype
       
   163 
       
   164 Remove the Mass Storage device from the MSC server.
       
   165 */
       
   166 EXPORT_C void RUsbHostMsDevice::Remove()
       
   167     {
       
   168 	// Note: Here, at present we use only the interface token. But we still take
       
   169     // THostMassStorageConfig as parameter for future needs
       
   170 	__FNLOG("RUsbHostMsDevice::Remove");
       
   171 	_LIT(KUsbHostMsClientPanicCat, "usbhostmsclient");
       
   172 
       
   173 	TInt r = SendReceive(EUsbHostMsUnRegisterInterface);
       
   174 
       
   175 	r = SendReceive(EUsbHostMsFinalCleanup);
       
   176 	if(r != KErrNone)
       
   177 		{
       
   178 		User::Panic(KUsbHostMsClientPanicCat ,KErrCouldNotDisconnect);
       
   179 		}
       
   180     Close(); // Close the session handle
       
   181     }
       
   182 
       
   183 
       
   184 /**
       
   185 @internalAll
       
   186 @prototype
       
   187 
       
   188 Get the number of logical units suppoted by the device.
       
   189 
       
   190 @param aNumLuns [Out] Outputs the number of logical units found in the
       
   191                  added Mass Storage device. A value of 'n' represents there are
       
   192                  'n' LUNs present in the device, where "n > 0"
       
   193 
       
   194 @return TInt
       
   195 */
       
   196 EXPORT_C TInt RUsbHostMsDevice::GetNumLun(TUint32& aNumLuns)
       
   197     {
       
   198 	__FNLOG("RUsbHostMsDevice::GetNumLun");
       
   199     TPckg<TUint32> pckg(aNumLuns);
       
   200     return SendReceive(EUsbHostMsGetNumLun,TIpcArgs(&pckg));
       
   201     }
       
   202 
       
   203 
       
   204 EXPORT_C TInt RUsbHostMsDevice::MountLun(TUint32 aLunId, TInt aDriveNum)
       
   205 	{
       
   206 	__FNLOG("RUsbHostMsDevice::MountLun");
       
   207 	RFs TheFs;
       
   208 	TInt r = TheFs.Connect();
       
   209 	if(r == KErrNone)
       
   210 		{
       
   211 		TPckgBuf<TMassStorageUnitInfo> unitPkg;
       
   212 		unitPkg().iLunID = aLunId;
       
   213 
       
   214 		r = TheFs.MountProxyDrive(aDriveNum, _L("usbhostms"), &unitPkg, *this);
       
   215 		if(r >= KErrNone)
       
   216 			{
       
   217 			r = TheFs.MountFileSystem(KFileSystem, aDriveNum);
       
   218 
       
   219 			if(r != KErrNone && r != KErrNotReady && r != KErrCorrupt)
       
   220 				{
       
   221 				TheFs.DismountFileSystem(KFileSystem, aDriveNum);
       
   222 				TheFs.DismountProxyDrive(aDriveNum);
       
   223 				}
       
   224 			}
       
   225 		TheFs.Close();
       
   226 		}
       
   227 	return r;
       
   228 	}
       
   229 
       
   230 EXPORT_C TInt RUsbHostMsDevice::DismountLun(TInt aDriveNum)
       
   231 	{
       
   232 	__FNLOG("RUsbHostMsDevice::DismountLun");
       
   233 	RFs TheFs;
       
   234 	TInt r;
       
   235 	r = TheFs.Connect();
       
   236 	if(r == KErrNone)
       
   237 		{
       
   238 		r = TheFs.DismountFileSystem(KFileSystem, aDriveNum);
       
   239 		if(r != KErrNone)
       
   240 			{
       
   241 			// dismount failed - attempt a forced dismount
       
   242 			TRequestStatus stat;
       
   243 			TheFs.NotifyDismount(aDriveNum, stat, EFsDismountForceDismount);
       
   244 			User::WaitForRequest(stat);
       
   245 			r = stat.Int();
       
   246 			}
       
   247 		if(r == KErrNone)
       
   248 			{
       
   249 			r = TheFs.DismountProxyDrive(aDriveNum);
       
   250 			}
       
   251 		TheFs.Close();
       
   252 		}
       
   253 	return r;
       
   254 	}