Symbian3/SDK/Source/GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita
changeset 8 ae94777fff8f
parent 7 51a74ef9ed63
child 13 48780e181b38
--- a/Symbian3/SDK/Source/GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita	Wed Mar 31 11:11:55 2010 +0100
+++ b/Symbian3/SDK/Source/GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita	Fri Jun 11 12:39:03 2010 +0100
@@ -1,297 +1,297 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 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: 
--->
-<!DOCTYPE concept
-  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
-<concept id="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6" xml:lang="en"><title>File Server
-Plugin Concepts</title><shortdesc>This topic describes the file server plug-in concepts.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
-<p>File server plugins can issue direct file server requests, interpret and
-modify inbound messages and change file and metadata. A compression plugin
-may need to intercept file read or file write requests which are sent from
-the client to provide a seamless user experience. This operation requires
-the modification of the data, position and length arguments that are sent
-from the client to the file server. </p>
-<p>There are some limitations to the file server plugin framework: </p>
-<ul>
-<li id="GUID-1C02ECAE-A711-5E2A-8006-EC2D1BF5A859"><p>The file server plugin
-framework only operates on one client file at any time. However, a plugin
-itself can operate on any number of files during a single request from the
-client. </p> </li>
-<li id="GUID-F82C8E71-479B-5482-8234-C5AD2AD05A91"><p>The file server plugin
-framework does not enable the compression or encryption of whole volumes.
-If access to the whole media volume is needed use a <xref href="GUID-983F0ABD-470C-51C3-B6AE-1B1AA55AB4A2.dita">file
-server extension</xref> rather than a plugin. </p> </li>
-<li id="GUID-386C0911-30EF-56B0-BD3B-4BC97A7CEFA3"><p>File modification plugins
-cannot operate on demand paged executables. Demand paging does not use the
-file server, so the plugin framework cannot be used to encrypt/process the
-executable. </p> </li>
-</ul>
-<note> The improved framework will not prevent deadlock with existing plugins.
-Plugins that currently issue <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> requests must be migrated
-to the new APIs to prevent deadlock. Follow the guidelines within the <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita">plugin implementation tutorial</xref></note>
-<ul>
-<li id="GUID-0A5ECCEA-CD70-528D-8880-463CA77D797B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-8B5B325D-D88C-55A7-9684-C2DCF81FCD79">Plugin type</xref>, </p> </li>
-<li id="GUID-40202D9E-C136-55BB-A5A1-DF64971B99D1"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-C76B06C8-DEDC-57AC-A510-3DD1E232241A">Architecture</xref>, </p> </li>
-<li id="GUID-60C8A1F1-6BE6-59A3-8F33-BD7FBFF9FB59"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-6234893D-A1C8-5870-9761-9EA2BD6909F0">Plugin order</xref>, </p> </li>
-<li id="GUID-20D4D10F-5E92-5FE3-A89C-DAF45E52EB0B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-DB21C0FD-46F8-5E4F-9288-69AE8609482B">Drive selection</xref>, </p> </li>
-<li id="GUID-91E1927C-3AA6-5594-8238-EA7B590278B2"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-50F7CD3A-A051-5498-8886-B4501523FD1D">Interception of file server requests</xref>, </p> </li>
-<li id="GUID-59EB5503-3D02-5E2D-80A4-A20EA8364D81"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-0B7B373D-41ED-5C91-ACC4-393A8669815A">Security</xref>. </p> </li>
-</ul>
-<section id="GUID-8B5B325D-D88C-55A7-9684-C2DCF81FCD79"><title>Plugin type</title> <p>There
-are two different types of file server plugins: </p> <ul>
-<li id="GUID-0FBE9E75-D164-5BCC-B00A-A5A76DBD200C"><p>Observer plugins - intercept
-requests but do not modify file data or associated meta data. </p> <p>Examples
-of observer plugins are those for virus scanning or logging. </p> </li>
-<li id="GUID-69708845-9C79-5C19-B758-AEF8F8A693E0"><p>Modifier plugins - intercept
-requests and modify the data or associated meta data of the target files or
-directories.. </p> <p>Examples of file modifier plugins are compression and
-encryption plugins. </p> </li>
-</ul> </section>
-<section id="GUID-C76B06C8-DEDC-57AC-A510-3DD1E232241A"><title>Architecture</title> <p>This
-section describes the structure of the plugin framework and the changes that
-have been made to the framework in v9.5: </p> <ul>
-<li id="GUID-399FE2E3-6576-5F98-83A8-70B9F77C65B7"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-3D91570E-8939-557B-8E1E-3A3C5BD27A26">Threads and execution context</xref>, </p> </li>
-<li id="GUID-609612CB-E684-5BDA-88FC-16FFB71D70C2"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-71DC7464-0EF0-5F78-816E-24F73F5FCA12">Exclusive access</xref>, </p> </li>
-<li id="GUID-665C36D1-DDD3-5DA4-86A3-574DFDC38AFF"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-9C152BE3-9113-5A0C-8EE2-81ADD09BEAD2">Intercepting requests to the ROM drive</xref>, </p> </li>
-<li id="GUID-F06D0F56-40AA-5631-9686-BA955E8E263B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-AA3990F3-52AB-5B14-8ED4-50CCA824AF84">Preventing deadlock</xref>. </p> </li>
-</ul> <p>The diagram below shows how plugins fit into the File Server software
-stack. </p> <fig id="GUID-EF5AECEC-9CB0-54B0-B6D2-46266B5FF49E">
-<image href="GUID-9A4543B3-2A79-5604-AE11-5087507C6755_d0e265930_href.png" placement="inline"/>
-</fig> <p> <b>Note</b>: more than one plugin can be loaded into the file server
-at the same time. A plugin is not aware of other plugins. </p> <p id="GUID-3D91570E-8939-557B-8E1E-3A3C5BD27A26"><b> Threads and execution context</b> </p> <p>The
-Symbian platform File Server has multiple threads. There is a thread for each
-drive in use and a main thread that receives the requests from clients and
-sends them to the drive threads. Synchronous drives, however, do not have
-their own drive thread; requests for these are processed by the main thread.
-There is also a separate thread for processing session disconnect requests. </p> <p>Each
-plugin also has its own thread for processing requests. Requests are dispatched
-to the plugin thread associated with the request's drive before they are dispatched
-to the drive thread. This is discussed in more detail in <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-50F7CD3A-A051-5498-8886-B4501523FD1D">interception of file server requests</xref>. </p> <p id="GUID-71DC7464-0EF0-5F78-816E-24F73F5FCA12"><b>Exclusive access</b> </p> <p>Previously,
-when a client application opens a file for exclusive write access, no other
-clients could access the file until the client closed its associated subsession.
-This also applied to plugins that needed to modify file data (as they are
-also clients of the file server). </p> <p>Symbian platform provides plugins
-that are able to perform operations on files and directories irrespective
-of the mode in which the file has been opened. </p> <p>Operations are now
-able to use the same file handle as the originating request (run in the same
-context as the original request) so files opened for exclusive access can
-still be written to by a plugin wishing to modify the file. </p> <p id="GUID-9C152BE3-9113-5A0C-8EE2-81ADD09BEAD2"><b>Intercepting ROM drive requests</b> </p> <p>Previously,
-plugins could not intercept any requests to the ROM drive (Z) however, there
-is a requirement to be able to intercept requests on this drive to enable
-secure-load and logging plugins. Requests to drive Z can now be intercepted
-by plugins. See the tutorial for <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref> for more details. </p> <p id="GUID-AA3990F3-52AB-5B14-8ED4-50CCA824AF84"><b>Preventing deadlock</b> </p> <p>The
-new framework allows a plugin to have direct access to file data without the
-need to issue new file server requests through the <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref>, <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> and <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> client
-APIs. In the pre-9.5 approach it was possible to reach deadlock if more than
-one plugin was present. </p> <p>The diagram below shows two plugins in the
-pre v9.5 framework. If both plugins issue new file server requests and if
-the plugins are not re-entrant safe this can lead to deadlock in the file
-server. </p> <fig id="GUID-01A69E82-BF01-520A-A8C5-927F1ED85E04">
-<title>                 File server deadlock               </title>
-<image href="GUID-9CC5E096-74FB-59AB-BAB9-A5486B961B7D_d0e266006_href.png" placement="inline"/>
-</fig> <p>The framework introduced in v9.5 prevents deadlock by allowing plugins
-to issue internal file server requests after intercepting a request by using
-the newly introduced <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> and <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> APIs
-and not by using the <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref>, <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref> and <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> APIs.
-Internally issued requests are only dispatched to plugins mounted below the
-issuing plugin and the appropriate drive thread. </p> <p>The sequence of events
-for a typical plugin intercepting a file read request is illustrated below: </p> <fig id="GUID-E366027F-3112-520F-A118-4C048102749E">
-<title>                 Read request intercepted by a plugin             
- </title>
-<image href="GUID-2ABCF233-7DCC-59E2-B075-81E148A1D2AB_d0e266044_href.png" placement="inline"/>
-</fig> <p>The classes <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> and <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> have
-been introduced to facilitate plugins with direct access behaviour on file
-and directory requests. These classes are analogous to the client-side <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref>, <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> and <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> classes and have functions with similar or identical signitures. </p> <p>In
-order to perform requests on a file it is necessary to open a sub-session
-by calling either <xref href="GUID-EC8FDB25-3DD7-3F1C-9875-0FA9315AE9AC.dita"><apiname>AdoptFromClient()</apiname></xref> or <xref href="GUID-20D0D10F-3401-3F72-8AF6-DC35F6025DC2.dita"><apiname>Open()</apiname></xref>. <codeph>AdoptFromClient()</codeph> is
-used in order to open a sub-session with the file associated with the client’s
-request. Alternatively the <codeph>Open()</codeph> method can be used to open
-either a different file, or the file associated with the client’s request
-possibly with a different access mode. </p> <p>More than one file can be opened
-at any time by creating multiple instances of <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>. </p> <p>The
-following example shows how to open many files from a plugin during a single
-request: </p> <codeblock id="GUID-AFCA6392-2414-591A-98C5-A9FC2C103755" xml:space="preserve">// Define the object
-RFilePlugin clientsFile(aRequest); 
-
-// Opens the file associated with the intercepted request
-Tint r = clientsFile.AdoptFromClient();
-User::LeaveIfError(r);
-TBuf&lt;20&gt; data;
-TInt64 pos = (Tint64)0;
-Tint length = 0;
-
-// Read the file
-r = clientsFile.Read(pos, data, length);
-User::LeaveIfError(r);
-
-// Open a second file
-RFilePlugin secondFile(aRequest);
-_LIT(KSecondName, ”D:\\myfile.txt”);
-r = secondFile.Open(KSecondName(), EFileRead);
-User::LeaveIfError(r);
-
-// Read from second file
-TBuf&lt;20&gt; data2;
-TInt64 pos2 = (Tint64)0;
-Tint length2 = 0;
-
-// Read the file
-r = secondFile.Read(pos2, data2, length2);
-User::LeaveIfError(r);
-
-// Close the files
-clientsFile.Close();
-secondFile.Close();</codeblock> <p><b>Issuing
-an internal file system request</b> </p> <p>An internal request can be marked
-as ‘Direct to Drive’. This allows requests that are generated by a plugin
-to be dispatched straight to the drive thread bypassing all other plugins
-which may be mounted below the plugin that issued the request. After being
-processed by the drive thread the request also bypasses the plugins between
-the drive thread and the plugin that the Direct to Drive request originated
-from. Once returned to the plugin that generated the request, the Direct to
-Drive request is complete and any other requests issued from the plugin are
-processed by plugins further down the plugin-stack in the normal manner. </p> <p>The
-last argument of the <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref> constructor of the classes <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> and <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> is named <codeph>aDirectToDrive</codeph>. <codeph>aDirectToDrive</codeph> is
-a boolean value (<codeph>TBool</codeph>) to indicate that the request is Direct
-to Drive. The default value is <codeph>EFalse</codeph> indicating that the
-request is interceptable by plugins further down the plugin-stack. </p> </section>
-<section id="GUID-6234893D-A1C8-5870-9761-9EA2BD6909F0"><title>Plugin order</title> <p>The
-Plugin framework provides support for multiple plugins to be present and active.
-Plugins are arranged in a stack. Plugins intercept requests in the order they
-are arranged in the stack with the plugin at the top of the stack (at the
-smallest numerical absolute position) getting the first intercept. The order
-of plugins in the stack is therefore crucial to the correct operation of the
-file server when more than one plugin is active, especially when the plugins
-are modifier plugins (i.e when both modify the data or parameters of the requests). </p> <p>If
-two plugins are active and one of those is a virus scanner, for the virus
-scanner to operate correctly it must be the first plugin to intercept requests.
-This is so that the virus scanner can have first refusal to block any requests
-for files which it believes may not be safe for opening. If there is another
-plugin higher in the stack then this plugin could send Direct To Drive requests,
-for example, and would significantly reduce the virus scanning ability of
-the virus scanning plugin. </p> <p>Two mechanisms are provided that allow
-plugin authors to control the position of their plugins in the plugin stack
-these are Absolute position and Unique position. </p> <p id="GUID-5C258D67-C324-5FA4-894A-88532F925EFF"><b>Absolute position </b> </p> <p>Plugins
-can be inserted into the stack by specifying an absolute position at mount
-time. This absolute position is the index in the internal array of plugins
-in which the plugin should be mounted. The plugin at position 0 being the
-first plugin to be able to intercept requests. </p> <fig id="GUID-41EB2F58-407F-52C7-A40C-0E3858CF718B">
-<title>                 Plugin stack showing absolute positions          
-    </title>
-<image href="GUID-64BDD1DA-6B93-5F45-8CBD-7DBAF92CC4C7_d0e266170_href.png" placement="inline"/>
-</fig> <p>The absolute position method is more appropriate for mounting plugins
-that operate regardless of their position in the plugin stack or when all
-of the plugins for a device are known and installed when manufactured. This
-method does not suit plugins that are added after manufacture where the dependencies
-of other available plugins is not known. If this is the case use the unique
-position method described below. </p> <p id="GUID-90FC1AD9-D709-5105-A445-0AA3D7BA85B7"><b>Unique position</b> </p> <p>Plugins
-can be ordered according to a unique position stored within the plugin. Unique
-position identifiers are defined by the manufacturer during the software validation/signing
-process. Unique positions are defined in the derived <xref href="GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E.dita"><apiname>CFsPluginFactory</apiname></xref> class.
-See the description in <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref>. </p> <p>The position value specifies the category and position of the plugin: </p> <table id="GUID-22362455-13BE-5A26-8750-A94E79941EF3">
-<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
-<tbody>
-<row>
-<entry><p> <b>plugin Type</b>  </p> </entry>
-<entry><p> <b>Unique Position Range</b>  </p> </entry>
-</row>
-<row>
-<entry><p>File Observers </p> </entry>
-<entry><p> <codeph>0x20000000 - 0x2FFFFFFF</codeph>  </p> </entry>
-</row>
-<row>
-<entry><p>File Modifiers </p> </entry>
-<entry><p> <codeph>0x40000000 - 0x4FFFFFFF</codeph>  </p> </entry>
-</row>
-</tbody>
-</tgroup>
-</table> <p>File Observers do not modify data so they are allocated a lower
-range of numbers placing them at the top of the plugin stack. File Modifiers
-modify the data stream so they are allocated a higher range placing them lower
-down the plugin stack. </p> <p> <b>Note</b>: a plugin has a unique position
-then do not specify an <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-5C258D67-C324-5FA4-894A-88532F925EFF">absolute
-position</xref> when mounting it, otherwise the error <codeph>KErrNotSupported</codeph> is
-returned. </p> </section>
-<section id="GUID-DB21C0FD-46F8-5E4F-9288-69AE8609482B"><title>Drive selection</title> <p>A
-File Server Plugin can intercept requests for a specific drive or for all
-drives. A plugin that intercepts requests for all drives must filter requests
-that are not appropriate for some drives. Requests can be filtered within
-an overridden <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-97427151-C6E4-5FE4-8197-0D7C58EDB29F">CFsPlugin::Deliver()</xref> function. </p> <p>There are two ways to specify a drive: </p> <ul>
-<li id="GUID-296E3A2E-5985-5E4B-96A2-D247D1FAA07C"><p>When the plugin is mounted.
-See <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-BED54BD9-2F3F-588E-854B-C28745C8F30A">mounting
-a plugin</xref>. </p> </li>
-<li id="GUID-080CD9C3-2BEA-5209-974A-910606EBF22A"><p>At run-time through
-the use of <xref href="GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E.dita#GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E/GUID-45A67073-5EF4-3966-A2FD-555B56C89284"><apiname>CFsPluginFactory::iSupportedDrives</apiname></xref>. See the
-tutorial for <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref>. </p> </li>
-</ul> <p>If the drive is not specified then <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita#GUID-E263C747-946F-35AA-9F1D-41833BD350FC/GUID-61640192-646E-33DA-B186-5EE63B07A998"><apiname>RFs::MountPlugin()</apiname></xref> attempts
-to mount the plugin for all drives. If this behaviour is not supported by
-the plugin <xref href="GUID-F89DA3F0-2A48-3F9B-8F08-29350E92D0E4.dita"><apiname>KErrNotSupported</apiname></xref> is returned. </p> </section>
-<section id="GUID-50F7CD3A-A051-5498-8886-B4501523FD1D"><title> Interception
-of file server requests</title> <p>After a file server request has been initialised
-by the main file server thread it can be intercepted by a plugin. There are
-two types of intercept: </p> <ul>
-<li id="GUID-288866F8-ABE5-5569-A70C-2C86B4F073B9"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-05F613B8-FF66-54B6-8D49-2BF92914E54E">pre-operation intercepts</xref>, </p> </li>
-<li id="GUID-E876E576-1E94-5F06-8305-22D620A82B6F"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-59FD1CED-5A32-5F6E-A256-821A2783D065">post-operation intercepts</xref>. </p> </li>
-</ul> <p>Plugins can register for pre-intercepts, for post-intercepts or for
-both pre and post-intercepts. </p> <p id="GUID-05F613B8-FF66-54B6-8D49-2BF92914E54E"><b>Pre-operation</b> </p> <p>Pre-operation
-intercepts occur before the drive associated with a request processes it.
-In a file write request for example, the pre-intercept operations occur before
-data has been written to the file. Requests are passed down the plugin-stack
-from the file server towards the drive thread. </p> <p>When the main file
-server thread has initialised a request, the request is dispatched to the
-highest plugin in the stack. This plugin must have been mounted on the requested
-drive and registered to pre-intercept this type of request. See <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-BED54BD9-2F3F-588E-854B-C28745C8F30A">mounting a plugin</xref>. The request is dispatched by calling the plugin's <xref href="GUID-BC0DB991-EF52-3344-8E6A-F8060B75A189.dita#GUID-BC0DB991-EF52-3344-8E6A-F8060B75A189/GUID-2EACA8A8-D569-3D6A-9383-451587A65839"><apiname>CFsPlugin::Deliver()</apiname></xref> function. </p> <p>The <codeph>Deliver()</codeph> function runs in the context of the previous calling thread,
-this can be the main file server thread or a plugin thread. Override <codeph>CFsPlugin::Deliver()</codeph> to
-filter the request. If the <codeph>Deliver()</codeph> function has not been
-overridden then the request is dispatched for asynchronous processing by calling
-the base class <codeph>Deliver()</codeph>. See the <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-97427151-C6E4-5FE4-8197-0D7C58EDB29F">CFsPlugin::Deliver()</xref> tutorial section. </p> <p id="GUID-59FD1CED-5A32-5F6E-A256-821A2783D065"><b>Post operation</b> </p> <p>Post-operation
-intercepts occur after the drive associated with a request has processed it.
-In a file write request for example, the post-intercept occurs after data
-has been written to the file. Requests are passed from the drive thread back
-up the stack towards the client. </p> <p>When the drive thread has finished
-processing a request it dispatches it to the plugin lowest in the stack by
-calling the plugin's <xref href="GUID-C6F20230-3D6C-3392-B040-CF627534B930.dita"><apiname>Deliver()</apiname></xref> function. </p> <p><b> Filtering requests internally</b> </p> <p>The <xref href="GUID-F1B37142-1EEF-3777-82B1-303982B888EC.dita#GUID-F1B37142-1EEF-3777-82B1-303982B888EC/GUID-8EBEAD17-B03C-3DBA-9A47-0F7DB07785F9"><apiname>CFSPlugin::Deliver()</apiname></xref> function
-filters the request and decides what kind of action is neccessary in terms
-of the flow of the request through the plugin stack: </p> <ul>
-<li id="GUID-3E8CAD7B-BE13-531E-A387-432F4CD463C9"><p> <xref href="GUID-1E025D93-3D66-3E88-830D-CBB3A471A777.dita"><apiname>KPluginMessageForward</apiname></xref> is
-returned if the intercept is pre-operation. The request is passed to the next
-plugin down the stack or to the drive thread if there are no more plugins. </p> </li>
-<li id="GUID-1FFEFFF4-3D5F-590F-8884-CA27B2B5B916"><p> <xref href="GUID-81C5F6A1-3FCA-33E5-99C6-7901D41BCBDE.dita"><apiname>KPluginMessageComplete</apiname></xref> is
-returned if the intercept is post-operation. The request is passed to the
-next plugin up the stack or if there are no more plugins to process the request
-it is passed to the main file server thread. </p> </li>
-</ul> <p>If the request requires processing by the plugin then the plugin's <codeph>Deliver()</codeph> function
-calls the base class <codeph>Deliver()</codeph> function and the request is
-dispatched to the plugin's thread for asynchronous processing. </p> <p>Asynchronous
-processing is carried out in the plugin's <xref href="GUID-8EF10689-68B7-391B-AD5C-4F51780165FF.dita"><apiname>DoRequestL()</apiname></xref> function.
-A plugin can only have a single <codeph>DoRequestL()</codeph> function which
-must handle both pre and post-intercepts. Plugin authors can use the <xref href="GUID-06E787C2-FAC1-36D2-9C64-11BDA1B656F1.dita"><apiname>IsPostOperation()</apiname></xref> function
-of the utility class, <xref href="GUID-A814151C-8AEC-3E16-8691-33174B64E36F.dita"><apiname>TFsPluginRequest</apiname></xref> to indicate whether
-the <codeph>DoRequestL()</codeph> is processing a request as a pre-intercept
-or post-intercept. See the description of <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-14773530-7C15-52E2-A542-72A0B2163461">TFsPluginRequest</xref>. </p> <p>Once the asynchronous processing is complete the <codeph>DoRequestL()</codeph> function
-returns <codeph>KErrNone</codeph> and the request is passed to the next plugin
-down the stack by calling its <xref href="GUID-C6F20230-3D6C-3392-B040-CF627534B930.dita"><apiname>Deliver()</apiname></xref> function. If there
-are no lower plugins then the request is passed to the appropriate drive thread
-for processing. </p> <p>If the plugin intercepts a request in pre-operation
-and wants to complete the request on behalf of the client then the plugin
-can return <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> to indicate that the request
-has been completed and that the request is now in post operation mode. The
-flow will then proceed to any previous plugins if mounted or directly back
-to the client otherwise. <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> prevents any further
-plugins further down the stack from intercepting the request. </p> <p>When
-a plugin intercepts file read or file write and does an early completion (i.e.
-returns <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> in pre-intercept) then the plugin
-author should call <xref href="GUID-A814151C-8AEC-3E16-8691-33174B64E36F.dita#GUID-A814151C-8AEC-3E16-8691-33174B64E36F/GUID-149E1448-63AA-3F08-A3A2-606D240A8927"><apiname>TFsPluginRequest::SetSharePos()</apiname></xref> to allow
-share position to be updated after early read/write completion. </p> </section>
-<section id="GUID-0B7B373D-41ED-5C91-ACC4-393A8669815A"><title>Security</title> <p>File
-server plugins are implemented as libraries that are loaded into the file
-server process at runtime. Therefore, plugins must have the same <xref href="GUID-4BFEDD79-9502-526A-BA7B-97550A6F0601.dita">platform
-security</xref> capabilities as the file server process, these are <xref href="GUID-2A022229-C333-3B0A-99A5-13CA0710025D.dita"><apiname>TCB</apiname></xref>, <xref href="GUID-E5C21B79-529B-397E-8A22-63612CA52869.dita"><apiname>ProtServ</apiname></xref>, <xref href="GUID-8DC76E7B-9EB3-3848-AD8D-3D519388A504.dita"><apiname>DiskAdmin</apiname></xref>, <xref href="GUID-ECCA7246-B2BA-3261-95C9-9E72C6EC51D4.dita"><apiname>AllFiles</apiname></xref>, <xref href="GUID-93881606-AA56-385F-A958-3957142BEFE3.dita"><apiname>PowerMgmt</apiname></xref> and <xref href="GUID-616F0C5B-D2C1-39D8-9BFC-53A2AEC7C850.dita"><apiname>CommDD</apiname></xref>. </p> <p>Any
-user side process that wishes to load and mount plugins must have the <codeph>DiskAdmin</codeph> capability. </p> </section>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 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: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6" xml:lang="en"><title>File Server
+Plugin Concepts</title><shortdesc>This topic describes the file server plug-in concepts.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>File server plugins can issue direct file server requests, interpret and
+modify inbound messages and change file and metadata. A compression plugin
+may need to intercept file read or file write requests which are sent from
+the client to provide a seamless user experience. This operation requires
+the modification of the data, position and length arguments that are sent
+from the client to the file server. </p>
+<p>There are some limitations to the file server plugin framework: </p>
+<ul>
+<li id="GUID-1C02ECAE-A711-5E2A-8006-EC2D1BF5A859"><p>The file server plugin
+framework only operates on one client file at any time. However, a plugin
+itself can operate on any number of files during a single request from the
+client. </p> </li>
+<li id="GUID-F82C8E71-479B-5482-8234-C5AD2AD05A91"><p>The file server plugin
+framework does not enable the compression or encryption of whole volumes.
+If access to the whole media volume is needed use a <xref href="GUID-983F0ABD-470C-51C3-B6AE-1B1AA55AB4A2.dita">file
+server extension</xref> rather than a plugin. </p> </li>
+<li id="GUID-386C0911-30EF-56B0-BD3B-4BC97A7CEFA3"><p>File modification plugins
+cannot operate on demand paged executables. Demand paging does not use the
+file server, so the plugin framework cannot be used to encrypt/process the
+executable. </p> </li>
+</ul>
+<note> The improved framework will not prevent deadlock with existing plugins.
+Plugins that currently issue <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> requests must be migrated
+to the new APIs to prevent deadlock. Follow the guidelines within the <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita">plugin implementation tutorial</xref></note>
+<ul>
+<li id="GUID-0A5ECCEA-CD70-528D-8880-463CA77D797B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-8B5B325D-D88C-55A7-9684-C2DCF81FCD79">Plugin type</xref>, </p> </li>
+<li id="GUID-40202D9E-C136-55BB-A5A1-DF64971B99D1"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-C76B06C8-DEDC-57AC-A510-3DD1E232241A">Architecture</xref>, </p> </li>
+<li id="GUID-60C8A1F1-6BE6-59A3-8F33-BD7FBFF9FB59"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-6234893D-A1C8-5870-9761-9EA2BD6909F0">Plugin order</xref>, </p> </li>
+<li id="GUID-20D4D10F-5E92-5FE3-A89C-DAF45E52EB0B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-DB21C0FD-46F8-5E4F-9288-69AE8609482B">Drive selection</xref>, </p> </li>
+<li id="GUID-91E1927C-3AA6-5594-8238-EA7B590278B2"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-50F7CD3A-A051-5498-8886-B4501523FD1D">Interception of file server requests</xref>, </p> </li>
+<li id="GUID-59EB5503-3D02-5E2D-80A4-A20EA8364D81"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-0B7B373D-41ED-5C91-ACC4-393A8669815A">Security</xref>. </p> </li>
+</ul>
+<section id="GUID-8B5B325D-D88C-55A7-9684-C2DCF81FCD79"><title>Plugin type</title> <p>There
+are two different types of file server plugins: </p> <ul>
+<li id="GUID-0FBE9E75-D164-5BCC-B00A-A5A76DBD200C"><p>Observer plugins - intercept
+requests but do not modify file data or associated meta data. </p> <p>Examples
+of observer plugins are those for virus scanning or logging. </p> </li>
+<li id="GUID-69708845-9C79-5C19-B758-AEF8F8A693E0"><p>Modifier plugins - intercept
+requests and modify the data or associated meta data of the target files or
+directories.. </p> <p>Examples of file modifier plugins are compression and
+encryption plugins. </p> </li>
+</ul> </section>
+<section id="GUID-C76B06C8-DEDC-57AC-A510-3DD1E232241A"><title>Architecture</title> <p>This
+section describes the structure of the plugin framework and the changes that
+have been made to the framework in v9.5: </p> <ul>
+<li id="GUID-399FE2E3-6576-5F98-83A8-70B9F77C65B7"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-3D91570E-8939-557B-8E1E-3A3C5BD27A26">Threads and execution context</xref>, </p> </li>
+<li id="GUID-609612CB-E684-5BDA-88FC-16FFB71D70C2"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-71DC7464-0EF0-5F78-816E-24F73F5FCA12">Exclusive access</xref>, </p> </li>
+<li id="GUID-665C36D1-DDD3-5DA4-86A3-574DFDC38AFF"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-9C152BE3-9113-5A0C-8EE2-81ADD09BEAD2">Intercepting requests to the ROM drive</xref>, </p> </li>
+<li id="GUID-F06D0F56-40AA-5631-9686-BA955E8E263B"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-AA3990F3-52AB-5B14-8ED4-50CCA824AF84">Preventing deadlock</xref>. </p> </li>
+</ul> <p>The diagram below shows how plugins fit into the File Server software
+stack. </p> <fig id="GUID-EF5AECEC-9CB0-54B0-B6D2-46266B5FF49E">
+<image href="GUID-9A4543B3-2A79-5604-AE11-5087507C6755_d0e262222_href.png" placement="inline"/>
+</fig> <p> <b>Note</b>: more than one plugin can be loaded into the file server
+at the same time. A plugin is not aware of other plugins. </p> <p id="GUID-3D91570E-8939-557B-8E1E-3A3C5BD27A26"><b> Threads and execution context</b> </p> <p>The
+Symbian platform File Server has multiple threads. There is a thread for each
+drive in use and a main thread that receives the requests from clients and
+sends them to the drive threads. Synchronous drives, however, do not have
+their own drive thread; requests for these are processed by the main thread.
+There is also a separate thread for processing session disconnect requests. </p> <p>Each
+plugin also has its own thread for processing requests. Requests are dispatched
+to the plugin thread associated with the request's drive before they are dispatched
+to the drive thread. This is discussed in more detail in <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-50F7CD3A-A051-5498-8886-B4501523FD1D">interception of file server requests</xref>. </p> <p id="GUID-71DC7464-0EF0-5F78-816E-24F73F5FCA12"><b>Exclusive access</b> </p> <p>Previously,
+when a client application opens a file for exclusive write access, no other
+clients could access the file until the client closed its associated subsession.
+This also applied to plugins that needed to modify file data (as they are
+also clients of the file server). </p> <p>Symbian platform provides plugins
+that are able to perform operations on files and directories irrespective
+of the mode in which the file has been opened. </p> <p>Operations are now
+able to use the same file handle as the originating request (run in the same
+context as the original request) so files opened for exclusive access can
+still be written to by a plugin wishing to modify the file. </p> <p id="GUID-9C152BE3-9113-5A0C-8EE2-81ADD09BEAD2"><b>Intercepting ROM drive requests</b> </p> <p>Previously,
+plugins could not intercept any requests to the ROM drive (Z) however, there
+is a requirement to be able to intercept requests on this drive to enable
+secure-load and logging plugins. Requests to drive Z can now be intercepted
+by plugins. See the tutorial for <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref> for more details. </p> <p id="GUID-AA3990F3-52AB-5B14-8ED4-50CCA824AF84"><b>Preventing deadlock</b> </p> <p>The
+new framework allows a plugin to have direct access to file data without the
+need to issue new file server requests through the <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref>, <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> and <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> client
+APIs. In the pre-9.5 approach it was possible to reach deadlock if more than
+one plugin was present. </p> <p>The diagram below shows two plugins in the
+pre v9.5 framework. If both plugins issue new file server requests and if
+the plugins are not re-entrant safe this can lead to deadlock in the file
+server. </p> <fig id="GUID-01A69E82-BF01-520A-A8C5-927F1ED85E04">
+<title>                 File server deadlock               </title>
+<image href="GUID-9CC5E096-74FB-59AB-BAB9-A5486B961B7D_d0e262298_href.png" placement="inline"/>
+</fig> <p>The framework introduced in v9.5 prevents deadlock by allowing plugins
+to issue internal file server requests after intercepting a request by using
+the newly introduced <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> and <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> APIs
+and not by using the <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref>, <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref> and <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> APIs.
+Internally issued requests are only dispatched to plugins mounted below the
+issuing plugin and the appropriate drive thread. </p> <p>The sequence of events
+for a typical plugin intercepting a file read request is illustrated below: </p> <fig id="GUID-E366027F-3112-520F-A118-4C048102749E">
+<title>                 Read request intercepted by a plugin             
+ </title>
+<image href="GUID-2ABCF233-7DCC-59E2-B075-81E148A1D2AB_d0e262336_href.png" placement="inline"/>
+</fig> <p>The classes <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> and <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> have
+been introduced to facilitate plugins with direct access behaviour on file
+and directory requests. These classes are analogous to the client-side <xref href="GUID-BE0804F6-4375-3C8A-8C83-968F510466E0.dita"><apiname>RFile</apiname></xref>, <xref href="GUID-12AE154F-7741-38C0-ADFE-9784FCF5E516.dita"><apiname>RDir</apiname></xref> and <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref> classes and have functions with similar or identical signitures. </p> <p>In
+order to perform requests on a file it is necessary to open a sub-session
+by calling either <xref href="GUID-EC8FDB25-3DD7-3F1C-9875-0FA9315AE9AC.dita"><apiname>AdoptFromClient()</apiname></xref> or <xref href="GUID-20D0D10F-3401-3F72-8AF6-DC35F6025DC2.dita"><apiname>Open()</apiname></xref>. <codeph>AdoptFromClient()</codeph> is
+used in order to open a sub-session with the file associated with the client’s
+request. Alternatively the <codeph>Open()</codeph> method can be used to open
+either a different file, or the file associated with the client’s request
+possibly with a different access mode. </p> <p>More than one file can be opened
+at any time by creating multiple instances of <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>. </p> <p>The
+following example shows how to open many files from a plugin during a single
+request: </p> <codeblock id="GUID-AFCA6392-2414-591A-98C5-A9FC2C103755" xml:space="preserve">// Define the object
+RFilePlugin clientsFile(aRequest); 
+
+// Opens the file associated with the intercepted request
+Tint r = clientsFile.AdoptFromClient();
+User::LeaveIfError(r);
+TBuf&lt;20&gt; data;
+TInt64 pos = (Tint64)0;
+Tint length = 0;
+
+// Read the file
+r = clientsFile.Read(pos, data, length);
+User::LeaveIfError(r);
+
+// Open a second file
+RFilePlugin secondFile(aRequest);
+_LIT(KSecondName, ”D:\\myfile.txt”);
+r = secondFile.Open(KSecondName(), EFileRead);
+User::LeaveIfError(r);
+
+// Read from second file
+TBuf&lt;20&gt; data2;
+TInt64 pos2 = (Tint64)0;
+Tint length2 = 0;
+
+// Read the file
+r = secondFile.Read(pos2, data2, length2);
+User::LeaveIfError(r);
+
+// Close the files
+clientsFile.Close();
+secondFile.Close();</codeblock> <p><b>Issuing
+an internal file system request</b> </p> <p>An internal request can be marked
+as ‘Direct to Drive’. This allows requests that are generated by a plugin
+to be dispatched straight to the drive thread bypassing all other plugins
+which may be mounted below the plugin that issued the request. After being
+processed by the drive thread the request also bypasses the plugins between
+the drive thread and the plugin that the Direct to Drive request originated
+from. Once returned to the plugin that generated the request, the Direct to
+Drive request is complete and any other requests issued from the plugin are
+processed by plugins further down the plugin-stack in the normal manner. </p> <p>The
+last argument of the <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref> constructor of the classes <xref href="GUID-3C50CF63-9AF4-3F36-8B8F-3FBB613E1CAC.dita"><apiname>RFilePlugin</apiname></xref>, <xref href="GUID-DE8D8017-6E9C-38CE-A023-98A53CDF7152.dita"><apiname>RFsPlugin</apiname></xref> and <xref href="GUID-2E871434-D08F-3275-AC55-260A9A78661A.dita"><apiname>RDirPlugin</apiname></xref> is named <codeph>aDirectToDrive</codeph>. <codeph>aDirectToDrive</codeph> is
+a boolean value (<codeph>TBool</codeph>) to indicate that the request is Direct
+to Drive. The default value is <codeph>EFalse</codeph> indicating that the
+request is interceptable by plugins further down the plugin-stack. </p> </section>
+<section id="GUID-6234893D-A1C8-5870-9761-9EA2BD6909F0"><title>Plugin order</title> <p>The
+Plugin framework provides support for multiple plugins to be present and active.
+Plugins are arranged in a stack. Plugins intercept requests in the order they
+are arranged in the stack with the plugin at the top of the stack (at the
+smallest numerical absolute position) getting the first intercept. The order
+of plugins in the stack is therefore crucial to the correct operation of the
+file server when more than one plugin is active, especially when the plugins
+are modifier plugins (i.e when both modify the data or parameters of the requests). </p> <p>If
+two plugins are active and one of those is a virus scanner, for the virus
+scanner to operate correctly it must be the first plugin to intercept requests.
+This is so that the virus scanner can have first refusal to block any requests
+for files which it believes may not be safe for opening. If there is another
+plugin higher in the stack then this plugin could send Direct To Drive requests,
+for example, and would significantly reduce the virus scanning ability of
+the virus scanning plugin. </p> <p>Two mechanisms are provided that allow
+plugin authors to control the position of their plugins in the plugin stack
+these are Absolute position and Unique position. </p> <p id="GUID-5C258D67-C324-5FA4-894A-88532F925EFF"><b>Absolute position </b> </p> <p>Plugins
+can be inserted into the stack by specifying an absolute position at mount
+time. This absolute position is the index in the internal array of plugins
+in which the plugin should be mounted. The plugin at position 0 being the
+first plugin to be able to intercept requests. </p> <fig id="GUID-41EB2F58-407F-52C7-A40C-0E3858CF718B">
+<title>                 Plugin stack showing absolute positions          
+    </title>
+<image href="GUID-64BDD1DA-6B93-5F45-8CBD-7DBAF92CC4C7_d0e262462_href.png" placement="inline"/>
+</fig> <p>The absolute position method is more appropriate for mounting plugins
+that operate regardless of their position in the plugin stack or when all
+of the plugins for a device are known and installed when manufactured. This
+method does not suit plugins that are added after manufacture where the dependencies
+of other available plugins is not known. If this is the case use the unique
+position method described below. </p> <p id="GUID-90FC1AD9-D709-5105-A445-0AA3D7BA85B7"><b>Unique position</b> </p> <p>Plugins
+can be ordered according to a unique position stored within the plugin. Unique
+position identifiers are defined by the manufacturer during the software validation/signing
+process. Unique positions are defined in the derived <xref href="GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E.dita"><apiname>CFsPluginFactory</apiname></xref> class.
+See the description in <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref>. </p> <p>The position value specifies the category and position of the plugin: </p> <table id="GUID-22362455-13BE-5A26-8750-A94E79941EF3">
+<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
+<tbody>
+<row>
+<entry><p> <b>plugin Type</b>  </p> </entry>
+<entry><p> <b>Unique Position Range</b>  </p> </entry>
+</row>
+<row>
+<entry><p>File Observers </p> </entry>
+<entry><p> <codeph>0x20000000 - 0x2FFFFFFF</codeph>  </p> </entry>
+</row>
+<row>
+<entry><p>File Modifiers </p> </entry>
+<entry><p> <codeph>0x40000000 - 0x4FFFFFFF</codeph>  </p> </entry>
+</row>
+</tbody>
+</tgroup>
+</table> <p>File Observers do not modify data so they are allocated a lower
+range of numbers placing them at the top of the plugin stack. File Modifiers
+modify the data stream so they are allocated a higher range placing them lower
+down the plugin stack. </p> <p> <b>Note</b>: a plugin has a unique position
+then do not specify an <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-5C258D67-C324-5FA4-894A-88532F925EFF">absolute
+position</xref> when mounting it, otherwise the error <codeph>KErrNotSupported</codeph> is
+returned. </p> </section>
+<section id="GUID-DB21C0FD-46F8-5E4F-9288-69AE8609482B"><title>Drive selection</title> <p>A
+File Server Plugin can intercept requests for a specific drive or for all
+drives. A plugin that intercepts requests for all drives must filter requests
+that are not appropriate for some drives. Requests can be filtered within
+an overridden <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-97427151-C6E4-5FE4-8197-0D7C58EDB29F">CFsPlugin::Deliver()</xref> function. </p> <p>There are two ways to specify a drive: </p> <ul>
+<li id="GUID-296E3A2E-5985-5E4B-96A2-D247D1FAA07C"><p>When the plugin is mounted.
+See <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-BED54BD9-2F3F-588E-854B-C28745C8F30A">mounting
+a plugin</xref>. </p> </li>
+<li id="GUID-080CD9C3-2BEA-5209-974A-910606EBF22A"><p>At run-time through
+the use of <xref href="GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E.dita#GUID-8A3B2A79-05A6-3BD7-AEA9-02435476F45E/GUID-45A67073-5EF4-3966-A2FD-555B56C89284"><apiname>CFsPluginFactory::iSupportedDrives</apiname></xref>. See the
+tutorial for <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-89CF85BE-784F-5237-9F78-69D603B650C4">CFsPluginFactory</xref>. </p> </li>
+</ul> <p>If the drive is not specified then <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita#GUID-E263C747-946F-35AA-9F1D-41833BD350FC/GUID-61640192-646E-33DA-B186-5EE63B07A998"><apiname>RFs::MountPlugin()</apiname></xref> attempts
+to mount the plugin for all drives. If this behaviour is not supported by
+the plugin <xref href="GUID-F89DA3F0-2A48-3F9B-8F08-29350E92D0E4.dita"><apiname>KErrNotSupported</apiname></xref> is returned. </p> </section>
+<section id="GUID-50F7CD3A-A051-5498-8886-B4501523FD1D"><title> Interception
+of file server requests</title> <p>After a file server request has been initialised
+by the main file server thread it can be intercepted by a plugin. There are
+two types of intercept: </p> <ul>
+<li id="GUID-288866F8-ABE5-5569-A70C-2C86B4F073B9"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-05F613B8-FF66-54B6-8D49-2BF92914E54E">pre-operation intercepts</xref>, </p> </li>
+<li id="GUID-E876E576-1E94-5F06-8305-22D620A82B6F"><p> <xref href="GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita#GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6/GUID-59FD1CED-5A32-5F6E-A256-821A2783D065">post-operation intercepts</xref>. </p> </li>
+</ul> <p>Plugins can register for pre-intercepts, for post-intercepts or for
+both pre and post-intercepts. </p> <p id="GUID-05F613B8-FF66-54B6-8D49-2BF92914E54E"><b>Pre-operation</b> </p> <p>Pre-operation
+intercepts occur before the drive associated with a request processes it.
+In a file write request for example, the pre-intercept operations occur before
+data has been written to the file. Requests are passed down the plugin-stack
+from the file server towards the drive thread. </p> <p>When the main file
+server thread has initialised a request, the request is dispatched to the
+highest plugin in the stack. This plugin must have been mounted on the requested
+drive and registered to pre-intercept this type of request. See <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-BED54BD9-2F3F-588E-854B-C28745C8F30A">mounting a plugin</xref>. The request is dispatched by calling the plugin's <xref href="GUID-BC0DB991-EF52-3344-8E6A-F8060B75A189.dita#GUID-BC0DB991-EF52-3344-8E6A-F8060B75A189/GUID-2EACA8A8-D569-3D6A-9383-451587A65839"><apiname>CFsPlugin::Deliver()</apiname></xref> function. </p> <p>The <codeph>Deliver()</codeph> function runs in the context of the previous calling thread,
+this can be the main file server thread or a plugin thread. Override <codeph>CFsPlugin::Deliver()</codeph> to
+filter the request. If the <codeph>Deliver()</codeph> function has not been
+overridden then the request is dispatched for asynchronous processing by calling
+the base class <codeph>Deliver()</codeph>. See the <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-97427151-C6E4-5FE4-8197-0D7C58EDB29F">CFsPlugin::Deliver()</xref> tutorial section. </p> <p id="GUID-59FD1CED-5A32-5F6E-A256-821A2783D065"><b>Post operation</b> </p> <p>Post-operation
+intercepts occur after the drive associated with a request has processed it.
+In a file write request for example, the post-intercept occurs after data
+has been written to the file. Requests are passed from the drive thread back
+up the stack towards the client. </p> <p>When the drive thread has finished
+processing a request it dispatches it to the plugin lowest in the stack by
+calling the plugin's <xref href="GUID-C6F20230-3D6C-3392-B040-CF627534B930.dita"><apiname>Deliver()</apiname></xref> function. </p> <p><b> Filtering requests internally</b> </p> <p>The <xref href="GUID-F1B37142-1EEF-3777-82B1-303982B888EC.dita#GUID-F1B37142-1EEF-3777-82B1-303982B888EC/GUID-8EBEAD17-B03C-3DBA-9A47-0F7DB07785F9"><apiname>CFSPlugin::Deliver()</apiname></xref> function
+filters the request and decides what kind of action is neccessary in terms
+of the flow of the request through the plugin stack: </p> <ul>
+<li id="GUID-3E8CAD7B-BE13-531E-A387-432F4CD463C9"><p> <xref href="GUID-1E025D93-3D66-3E88-830D-CBB3A471A777.dita"><apiname>KPluginMessageForward</apiname></xref> is
+returned if the intercept is pre-operation. The request is passed to the next
+plugin down the stack or to the drive thread if there are no more plugins. </p> </li>
+<li id="GUID-1FFEFFF4-3D5F-590F-8884-CA27B2B5B916"><p> <xref href="GUID-81C5F6A1-3FCA-33E5-99C6-7901D41BCBDE.dita"><apiname>KPluginMessageComplete</apiname></xref> is
+returned if the intercept is post-operation. The request is passed to the
+next plugin up the stack or if there are no more plugins to process the request
+it is passed to the main file server thread. </p> </li>
+</ul> <p>If the request requires processing by the plugin then the plugin's <codeph>Deliver()</codeph> function
+calls the base class <codeph>Deliver()</codeph> function and the request is
+dispatched to the plugin's thread for asynchronous processing. </p> <p>Asynchronous
+processing is carried out in the plugin's <xref href="GUID-8EF10689-68B7-391B-AD5C-4F51780165FF.dita"><apiname>DoRequestL()</apiname></xref> function.
+A plugin can only have a single <codeph>DoRequestL()</codeph> function which
+must handle both pre and post-intercepts. Plugin authors can use the <xref href="GUID-06E787C2-FAC1-36D2-9C64-11BDA1B656F1.dita"><apiname>IsPostOperation()</apiname></xref> function
+of the utility class, <xref href="GUID-A814151C-8AEC-3E16-8691-33174B64E36F.dita"><apiname>TFsPluginRequest</apiname></xref> to indicate whether
+the <codeph>DoRequestL()</codeph> is processing a request as a pre-intercept
+or post-intercept. See the description of <xref href="GUID-00764271-AD6B-5F41-AF72-843107EBF95F.dita#GUID-00764271-AD6B-5F41-AF72-843107EBF95F/GUID-14773530-7C15-52E2-A542-72A0B2163461">TFsPluginRequest</xref>. </p> <p>Once the asynchronous processing is complete the <codeph>DoRequestL()</codeph> function
+returns <codeph>KErrNone</codeph> and the request is passed to the next plugin
+down the stack by calling its <xref href="GUID-C6F20230-3D6C-3392-B040-CF627534B930.dita"><apiname>Deliver()</apiname></xref> function. If there
+are no lower plugins then the request is passed to the appropriate drive thread
+for processing. </p> <p>If the plugin intercepts a request in pre-operation
+and wants to complete the request on behalf of the client then the plugin
+can return <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> to indicate that the request
+has been completed and that the request is now in post operation mode. The
+flow will then proceed to any previous plugins if mounted or directly back
+to the client otherwise. <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> prevents any further
+plugins further down the stack from intercepting the request. </p> <p>When
+a plugin intercepts file read or file write and does an early completion (i.e.
+returns <xref href="GUID-DCECEF73-9C33-3C14-951D-E75D89B21FBA.dita"><apiname>KErrCompletion</apiname></xref> in pre-intercept) then the plugin
+author should call <xref href="GUID-A814151C-8AEC-3E16-8691-33174B64E36F.dita#GUID-A814151C-8AEC-3E16-8691-33174B64E36F/GUID-149E1448-63AA-3F08-A3A2-606D240A8927"><apiname>TFsPluginRequest::SetSharePos()</apiname></xref> to allow
+share position to be updated after early read/write completion. </p> </section>
+<section id="GUID-0B7B373D-41ED-5C91-ACC4-393A8669815A"><title>Security</title> <p>File
+server plugins are implemented as libraries that are loaded into the file
+server process at runtime. Therefore, plugins must have the same <xref href="GUID-4BFEDD79-9502-526A-BA7B-97550A6F0601.dita">platform
+security</xref> capabilities as the file server process, these are <xref href="GUID-2A022229-C333-3B0A-99A5-13CA0710025D.dita"><apiname>TCB</apiname></xref>, <xref href="GUID-E5C21B79-529B-397E-8A22-63612CA52869.dita"><apiname>ProtServ</apiname></xref>, <xref href="GUID-8DC76E7B-9EB3-3848-AD8D-3D519388A504.dita"><apiname>DiskAdmin</apiname></xref>, <xref href="GUID-ECCA7246-B2BA-3261-95C9-9E72C6EC51D4.dita"><apiname>AllFiles</apiname></xref>, <xref href="GUID-93881606-AA56-385F-A958-3957142BEFE3.dita"><apiname>PowerMgmt</apiname></xref> and <xref href="GUID-616F0C5B-D2C1-39D8-9BFC-53A2AEC7C850.dita"><apiname>CommDD</apiname></xref>. </p> <p>Any
+user side process that wishes to load and mount plugins must have the <codeph>DiskAdmin</codeph> capability. </p> </section>
 </conbody></concept>
\ No newline at end of file