--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/shostmassstorage/client/rusbhostmsdevice.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,254 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <e32std.h>
+#include <f32file.h>
+
+#include "rusbhostmsdevice.h"
+#include "debug.h"
+#include "msgservice.h"
+
+_LIT(KFileSystem, "FAT");
+
+TVersion RUsbHostMsDevice::Version() const
+ {
+ __FNLOG("RUsbHostMsDevice::Version");
+ return(TVersion(KUsbHostMsSrvMajorVersionNumber,
+ KUsbHostMsSrvMinorVersionNumber,
+ KUsbHostMsSrvBuildVersionNumber));
+ }
+
+
+TInt RUsbHostMsDevice::StartServer()
+ {
+ __FNLOG("RUsbHostMsDevice::StartServer");
+ TInt r;
+ RProcess server;
+
+ const TUid KServerUid3={0x10286A83};
+ const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
+
+ // Create the server process
+ if((r=server.Create(KUsbHostMsServerName,KNullDesC,serverUid)) != KErrNone)
+ {
+ __PRINT1(_L("Server process create = %d\n"), r);
+ return r;
+ }
+
+ // Create the rendezvous request with the server process
+ TRequestStatus stat;
+ server.Rendezvous(stat);
+ if (stat!=KRequestPending)
+ {
+ server.Kill(0); // If the outstanding request is not pending then kill the server
+ }
+ else
+ {
+ server.SetPriority(EPriorityHigh);
+ server.Resume(); // start the server
+ }
+
+ // Test whether the process has ended and if it has ended, return how it ended.
+ User::WaitForRequest(stat);
+ r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
+
+ server.Close();
+ return r;
+ }
+
+EXPORT_C RUsbHostMsDevice::RUsbHostMsDevice()
+ {
+ // Intentionally left blank
+ }
+
+
+/**
+@internalAll
+@prototype
+
+Add the Mass Storage device to the MSC server. This API is asynchronous, upon
+completion one could find the number of logical units present in the added
+device by calling GetNumLun API. Calling the Remove API before completing this
+asynchronous API will complete the pending request notification with KErrCancel.
+
+@param aConfig [In] A constant reference object to
+ THostMassStorageConfig containing the confiquration values of
+ the massstorage device requested to add to the MSC
+@param aStatus [In] A reference to TRequestStatus to be used for asynchronous
+ request completion
+*/
+EXPORT_C void RUsbHostMsDevice::Add(const THostMassStorageConfig& aConfig, TRequestStatus& aStatus)
+ {
+ __FNLOG("RUsbHostMsDevice::Add");
+ TInt err = KErrNone;
+
+ err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
+
+ // Being a transient server, the first session creation would fail with if
+ // the server is not running
+ if(err != KErrNone)
+ {
+ // Find whether the session creation failed because server was not
+ // running
+ if (err==KErrNotFound || err==KErrServerTerminated)
+ {
+ // Start the server
+ err = StartServer();
+ if(err == KErrNone)
+ {
+ // Try session creation again
+ err = CreateSession(KUsbHostMsServerName, Version(), 128, EIpcSession_GlobalSharable);
+ }
+ }
+ }
+
+ TRequestStatus* statusPtr = &aStatus;
+ if(err == KErrNone)
+ {
+ // Create a session handle that can be passed via IPC to another process
+ // (also being shared by other threads in the current process)
+ err = ShareProtected();
+ if(err == KErrNone)
+ {
+ // synchronous call to register the interface
+ TPckg<THostMassStorageConfig> pckg(aConfig);
+ err = SendReceive(EUsbHostMsRegisterInterface, TIpcArgs(&pckg));
+ if(err != KErrNone)
+ {
+ User::RequestComplete(statusPtr, err);
+ }
+ else
+ {
+ // Asynchronous call to initialise the interface
+ SendReceive(EUsbHostMsInitialiseInterface, TIpcArgs(NULL), aStatus);
+ }
+ }
+ else
+ {
+ Close(); // Close the session handle
+ __PRINT1(_L("Could not create a sharable session handle %d\n"), err);
+ User::RequestComplete(statusPtr, err);
+ }
+ }
+ else
+ {
+ // Check whether the error is in starting the server or in creating the
+ // session
+ __PRINT1(_L("Creating server/session failed with %d\n"), err);
+ User::RequestComplete(statusPtr, err);
+ }
+ }
+
+
+/**
+@internalAll
+@prototype
+
+Remove the Mass Storage device from the MSC server.
+*/
+EXPORT_C void RUsbHostMsDevice::Remove()
+ {
+ // Note: Here, at present we use only the interface token. But we still take
+ // THostMassStorageConfig as parameter for future needs
+ __FNLOG("RUsbHostMsDevice::Remove");
+ _LIT(KUsbHostMsClientPanicCat, "usbhostmsclient");
+
+ TInt r = SendReceive(EUsbHostMsUnRegisterInterface);
+
+ r = SendReceive(EUsbHostMsFinalCleanup);
+ if(r != KErrNone)
+ {
+ User::Panic(KUsbHostMsClientPanicCat ,KErrCouldNotDisconnect);
+ }
+ Close(); // Close the session handle
+ }
+
+
+/**
+@internalAll
+@prototype
+
+Get the number of logical units suppoted by the device.
+
+@param aNumLuns [Out] Outputs the number of logical units found in the
+ added Mass Storage device. A value of 'n' represents there are
+ 'n' LUNs present in the device, where "n > 0"
+
+@return TInt
+*/
+EXPORT_C TInt RUsbHostMsDevice::GetNumLun(TUint32& aNumLuns)
+ {
+ __FNLOG("RUsbHostMsDevice::GetNumLun");
+ TPckg<TUint32> pckg(aNumLuns);
+ return SendReceive(EUsbHostMsGetNumLun,TIpcArgs(&pckg));
+ }
+
+
+EXPORT_C TInt RUsbHostMsDevice::MountLun(TUint32 aLunId, TInt aDriveNum)
+ {
+ __FNLOG("RUsbHostMsDevice::MountLun");
+ RFs TheFs;
+ TInt r = TheFs.Connect();
+ if(r == KErrNone)
+ {
+ TPckgBuf<TMassStorageUnitInfo> unitPkg;
+ unitPkg().iLunID = aLunId;
+
+ r = TheFs.MountProxyDrive(aDriveNum, _L("usbhostms"), &unitPkg, *this);
+ if(r >= KErrNone)
+ {
+ r = TheFs.MountFileSystem(KFileSystem, aDriveNum);
+
+ if(r != KErrNone && r != KErrNotReady && r != KErrCorrupt)
+ {
+ TheFs.DismountFileSystem(KFileSystem, aDriveNum);
+ TheFs.DismountProxyDrive(aDriveNum);
+ }
+ }
+ TheFs.Close();
+ }
+ return r;
+ }
+
+EXPORT_C TInt RUsbHostMsDevice::DismountLun(TInt aDriveNum)
+ {
+ __FNLOG("RUsbHostMsDevice::DismountLun");
+ RFs TheFs;
+ TInt r;
+ r = TheFs.Connect();
+ if(r == KErrNone)
+ {
+ r = TheFs.DismountFileSystem(KFileSystem, aDriveNum);
+ if(r != KErrNone)
+ {
+ // dismount failed - attempt a forced dismount
+ TRequestStatus stat;
+ TheFs.NotifyDismount(aDriveNum, stat, EFsDismountForceDismount);
+ User::WaitForRequest(stat);
+ r = stat.Int();
+ }
+ if(r == KErrNone)
+ {
+ r = TheFs.DismountProxyDrive(aDriveNum);
+ }
+ TheFs.Close();
+ }
+ return r;
+ }