diff -r 51a74ef9ed63 -r ae94777fff8f Symbian3/SDK/Source/GUID-DEF3B8B3-5BD7-505B-93F9-A20CE00FFAE6.dita --- 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 @@ - - - - - -File Server -Plugin ConceptsThis topic describes the file server plug-in concepts. -

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.

-

There are some limitations to the file server plugin framework:

- - The improved framework will not prevent deadlock with existing plugins. -Plugins that currently issue RFs requests must be migrated -to the new APIs to prevent deadlock. Follow the guidelines within the plugin implementation tutorial - -
Plugin type

There -are two different types of file server plugins:

    -
  • Observer plugins - intercept -requests but do not modify file data or associated meta data.

    Examples -of observer plugins are those for virus scanning or logging.

  • -
  • Modifier plugins - intercept -requests and modify the data or associated meta data of the target files or -directories..

    Examples of file modifier plugins are compression and -encryption plugins.

  • -
-
Architecture

This -section describes the structure of the plugin framework and the changes that -have been made to the framework in v9.5:

    -
  • Threads and execution context,

  • -
  • Exclusive access,

  • -
  • Intercepting requests to the ROM drive,

  • -
  • Preventing deadlock.

  • -

The diagram below shows how plugins fit into the File Server software -stack.

- -

Note: more than one plugin can be loaded into the file server -at the same time. A plugin is not aware of other plugins.

Threads and execution context

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.

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 interception of file server requests.

Exclusive access

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).

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.

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.

Intercepting ROM drive requests

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 CFsPluginFactory for more details.

Preventing deadlock

The -new framework allows a plugin to have direct access to file data without the -need to issue new file server requests through the RFile, RDir and RFs client -APIs. In the pre-9.5 approach it was possible to reach deadlock if more than -one plugin was present.

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.

- File server deadlock - -

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 RFilePlugin, RDirPlugin and RFsPlugin APIs -and not by using the RFs, RFile and RDir APIs. -Internally issued requests are only dispatched to plugins mounted below the -issuing plugin and the appropriate drive thread.

The sequence of events -for a typical plugin intercepting a file read request is illustrated below:

- Read request intercepted by a plugin - - -

The classes RFilePlugin, RDirPlugin and RFsPlugin have -been introduced to facilitate plugins with direct access behaviour on file -and directory requests. These classes are analogous to the client-side RFile, RDir and RFs classes and have functions with similar or identical signitures.

In -order to perform requests on a file it is necessary to open a sub-session -by calling either AdoptFromClient() or Open(). AdoptFromClient() is -used in order to open a sub-session with the file associated with the client’s -request. Alternatively the Open() 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.

More than one file can be opened -at any time by creating multiple instances of RFilePlugin.

The -following example shows how to open many files from a plugin during a single -request:

// Define the object -RFilePlugin clientsFile(aRequest); - -// Opens the file associated with the intercepted request -Tint r = clientsFile.AdoptFromClient(); -User::LeaveIfError(r); -TBuf<20> 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<20> 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();

Issuing -an internal file system request

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.

The -last argument of the RFilePlugin constructor of the classes RFilePlugin, RFsPlugin and RDirPlugin is named aDirectToDrive. aDirectToDrive is -a boolean value (TBool) to indicate that the request is Direct -to Drive. The default value is EFalse indicating that the -request is interceptable by plugins further down the plugin-stack.

-
Plugin order

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).

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.

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.

Absolute position

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.

- Plugin stack showing absolute positions - - -

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.

Unique position

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 CFsPluginFactory class. -See the description in CFsPluginFactory.

The position value specifies the category and position of the plugin:

- - - -

plugin Type

-

Unique Position Range

-
- -

File Observers

-

0x20000000 - 0x2FFFFFFF

-
- -

File Modifiers

-

0x40000000 - 0x4FFFFFFF

-
- - -

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.

Note: a plugin has a unique position -then do not specify an absolute -position when mounting it, otherwise the error KErrNotSupported is -returned.

-
Drive selection

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 CFsPlugin::Deliver() function.

There are two ways to specify a drive:

    -
  • When the plugin is mounted. -See mounting -a plugin.

  • -
  • At run-time through -the use of CFsPluginFactory::iSupportedDrives. See the -tutorial for CFsPluginFactory.

  • -

If the drive is not specified then RFs::MountPlugin() attempts -to mount the plugin for all drives. If this behaviour is not supported by -the plugin KErrNotSupported is returned.

-
Interception -of file server requests

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:

    -
  • pre-operation intercepts,

  • -
  • post-operation intercepts.

  • -

Plugins can register for pre-intercepts, for post-intercepts or for -both pre and post-intercepts.

Pre-operation

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.

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 mounting a plugin. The request is dispatched by calling the plugin's CFsPlugin::Deliver() function.

The Deliver() function runs in the context of the previous calling thread, -this can be the main file server thread or a plugin thread. Override CFsPlugin::Deliver() to -filter the request. If the Deliver() function has not been -overridden then the request is dispatched for asynchronous processing by calling -the base class Deliver(). See the CFsPlugin::Deliver() tutorial section.

Post operation

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.

When the drive thread has finished -processing a request it dispatches it to the plugin lowest in the stack by -calling the plugin's Deliver() function.

Filtering requests internally

The CFSPlugin::Deliver() function -filters the request and decides what kind of action is neccessary in terms -of the flow of the request through the plugin stack:

    -
  • KPluginMessageForward 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.

  • -
  • KPluginMessageComplete 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.

  • -

If the request requires processing by the plugin then the plugin's Deliver() function -calls the base class Deliver() function and the request is -dispatched to the plugin's thread for asynchronous processing.

Asynchronous -processing is carried out in the plugin's DoRequestL() function. -A plugin can only have a single DoRequestL() function which -must handle both pre and post-intercepts. Plugin authors can use the IsPostOperation() function -of the utility class, TFsPluginRequest to indicate whether -the DoRequestL() is processing a request as a pre-intercept -or post-intercept. See the description of TFsPluginRequest.

Once the asynchronous processing is complete the DoRequestL() function -returns KErrNone and the request is passed to the next plugin -down the stack by calling its Deliver() function. If there -are no lower plugins then the request is passed to the appropriate drive thread -for processing.

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 KErrCompletion 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. KErrCompletion prevents any further -plugins further down the stack from intercepting the request.

When -a plugin intercepts file read or file write and does an early completion (i.e. -returns KErrCompletion in pre-intercept) then the plugin -author should call TFsPluginRequest::SetSharePos() to allow -share position to be updated after early read/write completion.

-
Security

File -server plugins are implemented as libraries that are loaded into the file -server process at runtime. Therefore, plugins must have the same platform -security capabilities as the file server process, these are TCB, ProtServ, DiskAdmin, AllFiles, PowerMgmt and CommDD.

Any -user side process that wishes to load and mount plugins must have the DiskAdmin capability.

+ + + + + +File Server +Plugin ConceptsThis topic describes the file server plug-in concepts. +

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.

+

There are some limitations to the file server plugin framework:

+
    +
  • 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.

  • +
  • 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 file +server extension rather than a plugin.

  • +
  • 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.

  • +
+ The improved framework will not prevent deadlock with existing plugins. +Plugins that currently issue RFs requests must be migrated +to the new APIs to prevent deadlock. Follow the guidelines within the plugin implementation tutorial +
    +
  • Plugin type,

  • +
  • Architecture,

  • +
  • Plugin order,

  • +
  • Drive selection,

  • +
  • Interception of file server requests,

  • +
  • Security.

  • +
+
Plugin type

There +are two different types of file server plugins:

    +
  • Observer plugins - intercept +requests but do not modify file data or associated meta data.

    Examples +of observer plugins are those for virus scanning or logging.

  • +
  • Modifier plugins - intercept +requests and modify the data or associated meta data of the target files or +directories..

    Examples of file modifier plugins are compression and +encryption plugins.

  • +
+
Architecture

This +section describes the structure of the plugin framework and the changes that +have been made to the framework in v9.5:

    +
  • Threads and execution context,

  • +
  • Exclusive access,

  • +
  • Intercepting requests to the ROM drive,

  • +
  • Preventing deadlock.

  • +

The diagram below shows how plugins fit into the File Server software +stack.

+ +

Note: more than one plugin can be loaded into the file server +at the same time. A plugin is not aware of other plugins.

Threads and execution context

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.

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 interception of file server requests.

Exclusive access

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).

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.

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.

Intercepting ROM drive requests

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 CFsPluginFactory for more details.

Preventing deadlock

The +new framework allows a plugin to have direct access to file data without the +need to issue new file server requests through the RFile, RDir and RFs client +APIs. In the pre-9.5 approach it was possible to reach deadlock if more than +one plugin was present.

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.

+ File server deadlock + +

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 RFilePlugin, RDirPlugin and RFsPlugin APIs +and not by using the RFs, RFile and RDir APIs. +Internally issued requests are only dispatched to plugins mounted below the +issuing plugin and the appropriate drive thread.

The sequence of events +for a typical plugin intercepting a file read request is illustrated below:

+ Read request intercepted by a plugin + + +

The classes RFilePlugin, RDirPlugin and RFsPlugin have +been introduced to facilitate plugins with direct access behaviour on file +and directory requests. These classes are analogous to the client-side RFile, RDir and RFs classes and have functions with similar or identical signitures.

In +order to perform requests on a file it is necessary to open a sub-session +by calling either AdoptFromClient() or Open(). AdoptFromClient() is +used in order to open a sub-session with the file associated with the client’s +request. Alternatively the Open() 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.

More than one file can be opened +at any time by creating multiple instances of RFilePlugin.

The +following example shows how to open many files from a plugin during a single +request:

// Define the object +RFilePlugin clientsFile(aRequest); + +// Opens the file associated with the intercepted request +Tint r = clientsFile.AdoptFromClient(); +User::LeaveIfError(r); +TBuf<20> 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<20> 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();

Issuing +an internal file system request

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.

The +last argument of the RFilePlugin constructor of the classes RFilePlugin, RFsPlugin and RDirPlugin is named aDirectToDrive. aDirectToDrive is +a boolean value (TBool) to indicate that the request is Direct +to Drive. The default value is EFalse indicating that the +request is interceptable by plugins further down the plugin-stack.

+
Plugin order

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).

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.

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.

Absolute position

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.

+ Plugin stack showing absolute positions + + +

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.

Unique position

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 CFsPluginFactory class. +See the description in CFsPluginFactory.

The position value specifies the category and position of the plugin:

+ + + +

plugin Type

+

Unique Position Range

+
+ +

File Observers

+

0x20000000 - 0x2FFFFFFF

+
+ +

File Modifiers

+

0x40000000 - 0x4FFFFFFF

+
+ + +

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.

Note: a plugin has a unique position +then do not specify an absolute +position when mounting it, otherwise the error KErrNotSupported is +returned.

+
Drive selection

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 CFsPlugin::Deliver() function.

There are two ways to specify a drive:

    +
  • When the plugin is mounted. +See mounting +a plugin.

  • +
  • At run-time through +the use of CFsPluginFactory::iSupportedDrives. See the +tutorial for CFsPluginFactory.

  • +

If the drive is not specified then RFs::MountPlugin() attempts +to mount the plugin for all drives. If this behaviour is not supported by +the plugin KErrNotSupported is returned.

+
Interception +of file server requests

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:

    +
  • pre-operation intercepts,

  • +
  • post-operation intercepts.

  • +

Plugins can register for pre-intercepts, for post-intercepts or for +both pre and post-intercepts.

Pre-operation

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.

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 mounting a plugin. The request is dispatched by calling the plugin's CFsPlugin::Deliver() function.

The Deliver() function runs in the context of the previous calling thread, +this can be the main file server thread or a plugin thread. Override CFsPlugin::Deliver() to +filter the request. If the Deliver() function has not been +overridden then the request is dispatched for asynchronous processing by calling +the base class Deliver(). See the CFsPlugin::Deliver() tutorial section.

Post operation

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.

When the drive thread has finished +processing a request it dispatches it to the plugin lowest in the stack by +calling the plugin's Deliver() function.

Filtering requests internally

The CFSPlugin::Deliver() function +filters the request and decides what kind of action is neccessary in terms +of the flow of the request through the plugin stack:

    +
  • KPluginMessageForward 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.

  • +
  • KPluginMessageComplete 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.

  • +

If the request requires processing by the plugin then the plugin's Deliver() function +calls the base class Deliver() function and the request is +dispatched to the plugin's thread for asynchronous processing.

Asynchronous +processing is carried out in the plugin's DoRequestL() function. +A plugin can only have a single DoRequestL() function which +must handle both pre and post-intercepts. Plugin authors can use the IsPostOperation() function +of the utility class, TFsPluginRequest to indicate whether +the DoRequestL() is processing a request as a pre-intercept +or post-intercept. See the description of TFsPluginRequest.

Once the asynchronous processing is complete the DoRequestL() function +returns KErrNone and the request is passed to the next plugin +down the stack by calling its Deliver() function. If there +are no lower plugins then the request is passed to the appropriate drive thread +for processing.

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 KErrCompletion 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. KErrCompletion prevents any further +plugins further down the stack from intercepting the request.

When +a plugin intercepts file read or file write and does an early completion (i.e. +returns KErrCompletion in pre-intercept) then the plugin +author should call TFsPluginRequest::SetSharePos() to allow +share position to be updated after early read/write completion.

+
Security

File +server plugins are implemented as libraries that are loaded into the file +server process at runtime. Therefore, plugins must have the same platform +security capabilities as the file server process, these are TCB, ProtServ, DiskAdmin, AllFiles, PowerMgmt and CommDD.

Any +user side process that wishes to load and mount plugins must have the DiskAdmin capability.

\ No newline at end of file