2 # Captive project doc Components page Perl template.
3 # Copyright (C) 2003-2005 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; exactly version 2 of June 1991 is required
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 package project::captive::doc::Components;
20 require 5.6.0; # at least 'use warnings;' but we need some 5.6.0+ modules anyway
21 our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
28 BEGIN { Wuse 'project::captive::doc::Macros'; }
33 project::captive::doc::Macros->init(
34 "__PACKAGE__"=>__PACKAGE__,
35 "title"=>'Captive NTFS Developer Documentation: Components',
36 "rel_prev"=>'Architecture.pm',
37 "rel_next"=>'Reverse.pm',
44 <h1>Project Components</h1>
46 @{[ doc_img 'dia/arch-all','Project Components Architecture' ]}
48 <p>Most of the work of this project is located in the single box called
49 "<span class="constant">libcaptive</span>" located in the center
50 of the scheme. This component implements the core W32 kernel API by
51 various methods described in this document.
52 The "<span class="constant">libcaptive</span>" box cannot be
53 further dissected as it is just an implementation of a set of
54 @{[ captive_srcfile 'src/libcaptive/ke/exports.captivesym','API functions' ]}.
55 It could be separated to several subsystems such as the
56 @{[ a_href '#cache_manager','Cache Manager' ]},
57 Memory Manager, Object Manager, Runtime Library, I/O Manager
58 etc. but they have no interesting referencing structure.</p>
60 <p>As this project is in fact just a filesystem implementation every
61 story must begin at the device file and end at the filesystem operations
62 interface. The unified suppported interfaces are
63 <span class="productname">@{[ a_href 'http://developer.gnome.org/doc/API/2.0/glib/','GLib' ]}</span>
64 (the most low level portability, data-types and utility library for Gnome)
65 <span class="type">GIOChannel</span> (for the device access) and the custom
66 <span class="constant">libcaptive</span> filesystem API. Each of these ends
67 can be connected either to some direct interface (such as the
68 <span class="constant">captive-cmdline</span> client),
69 @{[ a_href 'http://lufs.sourceforge.net/lufs/','Linux Userland File System (LUFS)' ]}
70 or as a general $GnomeVFS filter.
71 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} will be used in
72 most cases as it offers standard filesystem interface by Linux kernel.
74 You can also use $GnomeVFS as it offers nice filter interface on
75 the UNIX user-privileges level for transparent operation with archives and
76 network protocols. This filter interface was used by this project to turn
77 the device reference such as <span class="fname">/dev/hda3</span> or <span
78 class="fname">/dev/discs/disc0/part3</span> to the fully accessible
79 filesystem (pretending being an "archive" in the device
80 reference). This device access can be specified by $GnomeVFS URLs such as:
82 class="fname">file:///dev/hda3#captive-fastfat:/autoexec.bat</span></p>
84 <p><span class="constant">captive-bug-replay</span> serves just for debugging
85 purposes — you can 'replay' existing
86 <span class="fname">file.captivebug.xml.gz</span> automatically being
87 generated during W32 filesystem failure. This bugreport file will contain
88 all the touched data blocks of the device used in the moment of the
89 failure. <span class="constant">captive-bug-replay</span> will therefore
90 emulate internal virtual writable device out of these bugreported data.</p>
92 <p>If the passed device reference is requested by the user to be accessed
93 either in <span class="dashdash">--ro</span> (read-only) mode or in the
94 <span class="dashdash">--rw</span> (full read-write) mode there are no
95 further device layers needed. Just in the case of <span
96 class="dashdash">--blind</span> mode another layer is involved to emulate
97 read-write device on top of the real read-only device by the method of
98 non-persistent memory buffering of all the possible write requests.</p>
100 <p><span class="constant">sandbox commit buffer</span> is involved only in the
101 case @{[ a_href 'Details.pm#sandbox','sandboxing feature' ]} is active. It will
102 buffer any writes to the device during the sandbox run to prevent
103 filesystem damage if the driver would fail in the meantime. If the
104 filesystem gets finally successfully unmounted this sandbox buffer can be
105 <span id="safe_flush">safely flushed</span>
106 to its underlying physical media. The buffer will be dropped
107 in the case of filesystem failure, of course. The filesystem should be
108 unmounted from time to time — it can be transparently unmounted and mounted
109 by <span class="command">commit</span> of
110 <span class="constant">captive-cmdline</span> custom client. Currently you
111 cannot force remounting when using
112 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} interface client
113 but it will be remounted after approx each 1MB data written automatically
114 due to @{[ a_href '#log_file_full','NTFS log file full' ]}.
116 Now we need to transparently
117 @{[ captive_srcfile 'src/libcaptive/sandbox/sandbox.idl','connect' ]}
118 the device interface of <span class="type">GIOChannel</span> type through
119 @{[ a_href 'Details.pm#sandbox','CORBA/ORBit' ]} to the sandboxed slave.</p>
121 <p>Such device is still only a UNIX style GLib <span
122 class="type">GIOChannel</span> type at this point. As we need to supply it
123 to the W32 filesystem driver we must convert it to the W32 I/O Device
124 with its capability of handling <span class="type">IRP</span>
125 (<span class="constant">I/O Request Packet</span>; structure holding the
126 request and result data for any W32 filesystem or W32 block device
128 requests from its upper W32 filesystem driver. Such W32 I/O Device can
129 represent either <span class="type">CD-ROM</span> or
130 <span class="type">disk</span> device type as different W32 filesystem
131 drivers require different media types — currently only
132 <span class="fname">cdfs.sys</span> requires
133 <span class="type">CD-ROM</span> type.</p>
135 <p>W32 media I/O Device is accessed from the W32 filesystem driver.
136 The filesystem driver itself always creates volume object by
137 <span class="function">IoCreateStreamFileObject()</span> representing the
138 underlying W32 media I/O Device as the object handled by the
139 filesystem driver itself. All the client application filesystem requests
140 must be first resolved at the filesystem structures level, passed to the
141 volume stream object of the same filesystem and then finally passed to the
142 W32 media I/O Device (already implemented by this project as an
143 interface to <span class="type">GIOChannel</span> noted above).</p>
145 <p>The filesystem driver is called by the core W32 kernel implementation of
146 <span class="constant">libcaptive</span> in
147 @{[ a_href 'Details.pm#synchronous','synchronous way' ]} in single-shot manner instead of
148 the several reentrancies while waiting for the disk I/O completions as can
149 be seen in the original
150 <span class="productname">Microsoft Windows NT</span>.
151 This single-shot synchronous behaviour is possible since all the needed
152 resources (disk blocks etc.) can be always presented as instantly ready as
153 their acquirement is solved by @{[ a_href 'Architecture.pm#hostosnote','Host-OS' ]} outside of
154 the W32 emulated @{[ a_href 'Architecture.pm#guestosnote','Guest-OS' ]} environment.
155 For several cases needed only by <span class="fname">ntfs.sys</span>
156 there had to be supported asynchronous access — parallel execution
157 is emulated by GLib <span class="function">g_idle_add_full()</span>
158 with <span class="function">g_main_context_iteration()</span> called during
159 <span class="function">KeWaitForSingleObject()</span>.</p>
161 <p><span class="constant">libcaptive</span> offers the W32 kernel
162 filesystem API to the upper layers. This is still not the API the common
163 W32 applications are used to as they use W32 libraries which in turn pass
164 the call to W32 kernel. For example
165 <span class="function">CreateFileA()</span> is being implemented by several
166 libraries such as <span class="fname">user32.dll</span> as a relay
167 interface for the kernel function
168 <span class="function">IoCreateFile()</span> implemented by this
169 project's <span class="constant">libcaptive</span> W32 kernel
170 emulation component.</p>
172 <p>As it would be very inconvenient to use the legacy, bloated and UNIX
173 style unfriendly W32 kernel filesystem API this project offers its own
174 @{[ a_href '#client_interface','custom filesystem API interface' ]} inspired by
175 the $GnomeVFS client interface adapted to the specifics of W32 kernel API.
176 This interface is supposed to be easily utilized by
177 <a href="#client_interface_customapp">a custom application accessing
178 the W32 filesystem driver</a>.</p>
180 <p>@{[ a_href 'Details.pm#sandbox','CORBA/ORBit' ]} hits us again – we need to
181 @{[ captive_srcfile 'src/libcaptive/sandbox/sandbox.idl','translate' ]}
182 the @{[ a_href '#client_interface','custom filesystem API interface' ]}
183 out of the sandboxed slave to the UNIX space.</p>
185 <p><span class="constant">captive sandbox master</span> provides the
186 functionality of covering any possible sandboxed slave restarts and its
187 communication. It is also capable of
188 <span id="demultiplexing_master">demultiplexing single API operations</span>
189 to multiple its connected sandbox slaves in transparent way
190 as each of them handles
191 @{[ a_href 'Details.pm#mounted_one','just one filesystem device' ]}.</p>
193 <p>The rest of the story is not much special for this project since this is
194 a common UNIX problem how to offer user space implemented UNIX filesystem
195 as a generic system filesystem (as those are usually implemented only as
196 the components od UNIX kernel).</p>
198 <p>The filesystem service can be offered in several ways:</p>
201 <dt>Custom client</dt>
203 <p>One possibility would be to write
204 <span id="client_interface_customapp">a custom client application</span>
205 for this project such as file manager or a shell. Although it
206 would implement the most appropriate user interface to the set of
207 functions offered by this project (and W32 filesystem API) it has the
208 disadvantage of special client software. Appropriate client is provided
210 <span class="fname">src/client/cmdline/cmdline-captive</span></p>
213 <dt>@{[ a_href 'http://lufs.sourceforge.net/lufs/','Linux Userland File System (LUFS)' ]}</dt>
215 <p>The most usable interface is the
216 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} client
217 by <span class="constant">liblufs-captivefs</span>.
218 As @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]}
219 already assigns separate process for each filesystem mount the
220 @{[ a_href '#demultiplexing_master','demultiplexing feature' ]}
221 is not utilized in this case.</p>
223 <p>@{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]}
224 needs multiple operating threads (each UNIX kernel operation needs
225 one free lufsd slot/thread to not to fail immediately).
226 As <span class="constant">libcaptive</span> is
227 @{[ a_href 'Details.pm#synchronous','single-threaded' ]} all the operations
228 get always synchronized by
229 <span class="constant">liblufs-captivefs</span>
230 before their pass over to <span class="constant">libcaptive</span>.</p>
233 <dt>@{[ a_href '#offered_gnomevfs','Gnome-VFS' ]}</dt>
235 <p>This client allowing its filesystem access even without any
236 involvement of UNIX kernel from any $GnomeVFS aware client application
237 (such as <span class="fname">gnome-vfs/tests/test-shell</span>).
238 This @{[ a_href '#offered_gnomevfs','Gnome-VFS interface' ]} connects the
239 data flow of this project in two points — both as the lowest layer
240 device image source and also as the upper layer for the filesystem
241 operation requests.</p>
245 <p>Unimplemented and deprecated methods for providing filesystem
249 <dt>W32 filesystem in UNIX OS kernel</dt>
251 <p>The real UNIX OS filesystem implementation must be completely
252 implemented inside the hosting OS kernel. This requires special coding
253 methods with limited availability of coding features and libraries.
254 Also it would give the full system control to the untrusted W32
255 filesystem driver code with possibly fatal consequences of yet
256 unhandled W32 emulation code paths. It would benefit from the best
257 execution performance but this solution was never considered a real
261 <dt>Custom NFS server</dt>
263 <p>The common approach
264 <span id="offered_NFS">of filesystem implementations</span>
265 outside UNIX OS kernel were custom NFS servers usually running on the
266 same machine as the NFS-connected client as such NFS server is usually
267 an ordinary UNIX user space process. It would be possible to implement
268 this project as a custom NFS server but the NFS protocol itself
269 has a lot of fundamental flaws and complicated code for backward
278 project::captive::doc::Macros->footer();