Wiley.Symbian.OS.Internals.Real.time.Kernel.Programming.Dec.2005.eBook-DDU (779891), страница 73
Текст из файла (страница 73)
All remaining file areas are public and anyprogram can read from them and write to them.So the data caging mechanism allows processes, and the OS itself, tohide private files from other processes. However, there will be circumstances in which a process will need to share a private file with anotherchosen process.
In other words, a situation in which we want to keep afile safe from most processes, but want the ability to grant access to achosen process without that process having to have special capabilities.Also we don’t want to reveal the full (and private) path of the file in orderfor the recipient to open it (although we can allow the recipient to knowthe file’s name and extension).To support this, the EKA2 version of the file server provides new RFilemethods that allow a process to pass an open file to another process.Sharing an open file is a two-stage operation.
The owner of the RFileobject first needs to transfer it to the other process. The RFile classprovides three methods for this purpose:• RFile::TransferToServer() – for passing from client to server• RFile::TransferToClient() – for passing from server to client• RFile::TransferToProcess() – for passing from one processto another process.Let’s take a closer look at the last of these, as an example:TInt RFile::TransferToProcess(RProcess& aProcess,TInt aFsHandleIndex, TInt aFileHandleIndex) const;346THE FILE SERVERThis transfers the RFile sub-session object to the process specified by thefirst argument. In doing this, the file server generates a duplicate handleon this same sub-session object.
However, this handle is only useable inthe context of the session on which it was created and so the file servermust share the session as well as the sub-session object. The duplicatesub-session handle and the session handle are passed to the other processusing two of that process’s sixteen environment slots. (The slot numbersare specified in the second and third parameters.) The sending processcan continue to access the file after it has transferred it. If the sendingprocess closes the file and the session, then the corresponding file serverobjects are not destroyed – because they have been transferred.To access the open file that was transferred, the receiving process mustadopt the RFile object.
Again, three different methods are provided,corresponding to the three file transfer methods:• RFile::AdoptFromClient() – for a server adopting a file froma client• RFile::AdoptFromServer() – for a client adopting a file froma server• RFile::AdoptFromCreator() – for one process adopting a filefrom another.Again, let’s look at the last of these as an example:TInt RFile::AdoptFromCreator(TInt aFsIndex, TInt aFileHandleIndex);This is used to adopt an open file that was sent using the TransferToProcess() method. The file server retrieves the session andsub-session handles from the environment data slots specified in the twoarguments – these must correspond with those specified in the transferfunction. The receiving process can then access the file as it would anyother open RFile object.
The adopted file retains the access attributesthat were set when the sending process opened the file.Although the receiving process shares the session that was used toopen and transfer the file, it doesn’t have to adopt and manage thisshared session directly. Once the receiving process closes the RFileobject, both the session and sub-session file server objects are destroyed(assuming the sending process has already done likewise).Because the session is shared between the two processes involved,it is recommended that the sending process opens a file server sessionspecifically for the transfer. Other files opened in the same session bythe sending process could be accessible by the receiving process, whichcould pose a security risk.THE FILE SERVER3479.3 The file serverAs we have seen, the file server handles requests from its clients for allmounted drives.
It is a system server, which means that if it panics, thewhole OS is restarted. The main file server thread is always one of thehighest priority user threads running on the system.9.3.1 Interfacing with clientsFigure 9.3 shows a diagram of the server-side classes that form theinterface with F32 clients.CServerFsCSessionFsiSessionQiPath : HBufC*iDisconnectRequest : CFsMessageRequestRunL()ServiceL()1iHandlesiMessageiServerRMessage2iFunction : TIntiArgs[4] : TInt1CFsObjectIx1Complete()nCFsDispatchObjectiRequest : CFsRequestCFileCBCFileShareiFileName : HBufC*iSize : TIntiAtt : TIntiModified : TTimeiFile iMode : TUintn iPos : TInt1CDirCBiAtt : TUintTOperationiIsSync : TBoolInitialise()DoRequestL()IsSync()CFormatCBCRawDiskCBFigure 9.3 Server-side classes forming the interface with the F32 clientsCServerFs is a singleton that is derived from CServer2, the Symbian OS client/server framework’s server class.
CServerFs is an activeobject; each time a client request is received, its event-handling method,RunL(), is called to accept that request from the client thread andforward it to the relevant server-side client session.CServerFs handles the creation of the server-side sessions. A clientrequests a connection by calling RFs::Connect(), which sendsa connect message to the server. If connection is successful, thisleads to the creation of an instance of the class CSessionFs, the348THE FILE SERVERserver-side session object. The session is initialized in the method CSessionFs::CreateL().
CServerFs maintains a queue, iSessionQ,of all the sessions open on it.Each time the server receives a request from an open session, it callsthe request servicing method of the relevant session:void CSessionFs::ServiceL(const RMessage2& aMessage)The details of every client request are contained in a message object,RMessage2, which is passed as an argument to the service method.RMessage2 contains a 32-bit operation identifier, which is read by theserver using RMessage2::Function(). It also holds a copy of therequest arguments – up to four 32-bit values. After handling a request, theserver conveys a 32-bit result back to the client by calling the messageobject’s base class method:void RMessagePtr2::Complete(TInt aReason) constThe class TOperation encapsulates a type of operation that the serveris able to perform. It contains various data members that categorizethe operation, as well as two important methods.
The first is TOperation::Initialise(), which the server calls prior to requestexecution. This method parses and preprocesses the data supplied by theclient. The second method is TOperation::DoRequestL(), whichperforms the requested operation. The server holds a constant array ofTOperation objects, containing a separate entry for each operation thatit is capable of performing. (This is of the order of 90 different operations.) The session’s ServiceL() method uses the operation identifierto index this array and obtain the corresponding TOperation object forthe request.When a client closes a session, the server will receive a disconnectmessage and then call this method:void CSessionFs::Disconnect(const RMessage2& aMessage)As we will see shortly, session disconnection can involve more than justdeleting the session object.For each of the client-side sub-session objects that I mentioned in theprevious section, there is a corresponding server-side object, and theseare all managed by their associated session.
The following table lists theserver-side sub-session objects and their client/server relationship:THE FILE SERVERServer-sideclassDescriptionCFileShare Abstraction for a client view of anopen file.349Correspondingclient-side classRFileCDirCBAbstraction of an open directory.RDirCFormatCBAbstraction of a format operation.RFormatCRawdiskCB Abstraction for direct drive access.RRawDiskEach time the file server creates a server-side sub-session object, forexample because a client calls RFile::Create(), it adds this objectto the object index (CSessionFs::iHandles) of the session to whichthe object belongs. This generates a unique sub-session handle that theserver returns to the client-side object, which stores it.
After this, thehandle is passed as a message argument in each request involving thesame sub-session, to identify the appropriate server-side object. If theclient closes the session, the file server will first close any sub-sessionobjects still remaining in the object index.