4 # Captive project doc Index page Perl template.
5 # Copyright (C) 2003 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; exactly version 2 of June 1991 is required
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 package project::captive::doc::Index;
22 require 5.6.0; # at least 'use warnings;' but we need some 5.6.0+ modules anyway
23 our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
28 BEGIN{ open F,"Makefile"; our $top_dir=pop @{[split /\s/,(grep /^top_srcdir/,<F>)[0]]}; eval "use lib '$top_dir'"; close F; }
34 "__PACKAGE__"=>__PACKAGE__,
35 "title"=>'Captive NTFS doc',
37 .productname { font-family: cursive; }
38 .fname { font-family: monospace; }
39 .constant { font-family: monospace; }
40 .author { font-family: cursive; }
41 .stuff { font-style: italic; font-size: larger; margin-left: 20%; margin-right: 10%; }
42 .function { font-family: monospace; }
43 .type { font-family: monospace; }
44 .command { font-family: monospace; }
45 .instruction { font-style: italic; }
53 my($img_base,$caption)=@_;
56 $r.='<table border="0" align="center">'."\n";
57 $r.="\t<tr><td>".img($img_base,$caption)."</td></tr>\n";
58 $r.="\t<caption>$caption</caption>\n";
64 sub captive_srcfile ($)
68 a_href 'http://cvs.jankratochvil.net/viewcvs/*checkout*/priv/captive/'.$filename.'?rev=HEAD',$filename;
71 my $freespeech=a_href 'http://www.gnu.org/philosophy/free-sw.html','Free';
72 my $freebeer=a_href 'http://www.gnu.org/philosophy/free-sw.html','free (as in beer)';
78 return '<span class="productname">'.a_href($url,CGI::escapeHTML($name)).'</span>';
80 my $Wine=productname 'http://www.winehq.com/','Wine';
81 my $ReactOS=productname 'http://www.reactos.com/','ReactOS';
82 my $LinuxNTFS=productname 'http://linux-ntfs.sourceforge.net/','Linux NTFS';
83 my $GnomeVFS=productname 'http://developer.gnome.org/doc/API/gnome-vfs/','Gnome-VFS';
84 my $GnomeVFSmodule=productname 'http://developer.gnome.org/doc/API/gnome-vfs/modules.html','Gnome-VFS-module';
85 my $gnulinux='GNU/Linux';
89 # Compatibility with NT4 etc. - just legal reasons.
92 # name="cache_manager" Cache Manager
101 <h1>Reasons for the Implementation</h1>
103 <p>Currently there is no possibility to any of the available $freespeech
104 ($freespeech used in the following text in the meaning of
105 "@{[ a_href 'http://www.gnu.org/philosophy/free-sw.html','free as in speech' ]}")
106 operating systems to reliably write to the most common disk partition
107 filesystem type – <span class="productname">Microsoft NTFS</span>. It would
108 be already supported a long time ago but there is no proper documentation of
109 <span class="productname">NTFS</span> filesystem data structures available.
110 Since <span class="productname">Microsoft</span> corporation continues in its
111 propagation of <span class="productname">Microsoft Windows NT</span>
112 (<span class="productname">NT</span> identifier used in the following text
113 applies to all the products of <span class="productname">Microsoft</span>
114 <span class="productname">NT</span> series such as
115 <span class="productname">NT 4.0</span>,
116 <span class="productname">2000</span> as NT-5.0
118 <span class="productname">XP</span> as NT-5.1.)
119 based operating systems <span class="productname">NTFS</span> is the default
120 disk file system type for vendor preinstalled <span class="productname">Microsoft Windows</span>.
122 <p>Unfortunately the <span class="productname">NTFS</span> filesystem has too
123 complex data structure to allow a complete reverse enginnering process in
124 reasonable time. Currently available $freespeech solutions such as $LinuxNTFS
125 filesystem have already implemented reliable reverse
126 engineered read-only access. However <a name="reliability">reliabile</a>
127 read-write part of the access would require much better
128 knowledge of the <span class="productname">NTFS</span> data structures.
129 Currently only rewriting of already existing file data blocks is supported
130 by $LinuxNTFS — no file creation, no file deletion, no directory operations etc.
131 Also any future versions of <span class="productname">NTFS</span> filesystem
132 would require another major reverse engineering effort.</p>
135 <h1>Challenges of the Project</h1>
137 <p>The <a name="NTFSgoal">ultimate goal</a> of this project is definitely the
138 free implementation of @{[ a_href '#reliability','reliable' ]} read-write <span
139 class="productname">NTFS</span> filesystem driver. This project chose to
140 solve this problem in the style of $Wine project by using the original binary
141 <span class="fname">ntfs.sys</span> and emulating all the required layers of
142 <span class="productname">Microsoft Windows NT</span> for it.</p>
144 <p>Unfortunately this effort is tainted by only partial and generally
145 insufficient documentation of API between filesystem driver
146 (<span class="fname">ntfs.sys</span>) and the
147 <span class="productname">Microsoft Windows NT</span>
148 ("@{[ a_href 'http://mail.gnu.org/archive/html/libtool/2000-09/msg00000.html','W32' ]}"
149 in the following text) kernel <span class="fname">ntoskrnl.exe</span>. Note
150 that this API is a different than the one being used in the $Wine project
151 since <span class="productname">Wine</span> implements only the user space
155 <h1>Architecture</h1>
157 <p>The principle of the
158 project lies in the glue between
159 <span class="productname">Microsoft Windows NT</span> kernel space
160 environment and $gnulinux user space process environment:</p>
162 @{[ doc_img 'arch-W32','Microsoft Windows Subsystems Architecture' ]}
163 @{[ doc_img 'arch-captive','Captive Subsystems Architecture' ]}
165 <a name="existing_emulation"><h2>Existing Emulation Projects</h2></a>
167 <p>There were two well-known $freespeech projects emulating W32 subsystems
168 to reach the compatibility with various W32 components:
169 $Wine and $ReactOS. Sad moment is that the goals of this project do not fit
170 very well into any role in those two ones. Therefore this project went
171 its own way of emulation:</p>
173 <table align="center" border="1">
175 <th>@{[ a_href '#guestosnote','Guest-OS' ]}</th>
176 <th>@{[ a_href '#hostosnote' ,'Host-OS' ]}</th>
178 <th>W32 kernel library</th>
183 <td>W32 user space</td>
184 <td><span class="fname">ntdll.dll</span></td>
188 <td><span class="constant">i386</span> hardware</td>
189 <td>W32 kernel and user space</td>
190 <td><span class="fname">ntoskrnl.exe</span></td>
192 <tr style="height: 1ex;"></tr>
194 <td>this project</td>
197 <td><span class="fname">ntoskrnl.exe</span></td>
199 <caption>Emulation Projects Characteristics</caption>
203 <a name="guestosnote"><dt>Guest-OS</dt></a>
204 <dd>@{[ a_href 'http://www.vmware.com/support/reference/common/glossary/#guestos','Guest OS' ]}:
205 An operating system that runs inside a virtual machine.</dd>
206 <a name="hostosnote" ><dt>Host OS</dt></a>
207 <dd>@{[ a_href 'http://www.vmware.com/support/reference/common/glossary/#hostos' ,'Host OS' ]}:
208 An operating system that runs on the host machine.</dd>
211 <p>While $ReactOS provides the necessary W32 kernel subsystem emulation
212 code we also need to run such @{[ a_href '#guestosnote','Guest-OS' ]} in the
213 @{[ a_href '#hostosnote','Host-OS' ]} $gnulinux. Initially it was planned to
214 extend $Wine with the W32 kernel space emulation functionality but
215 fortunately <span class="author">Steven Edwards</span> pointed to the $ReactOS
216 which better suits the needs of this project by its already implemented W32
217 kernel space emulation.</p>
219 <p>The <a name="reactos_nocare">original reasons</a> for developing
220 $ReactOS still make no sense to the author of this project. Free
221 implementation of W32 platform standalone running on the machine hardware
222 is no longer free as most od the W32 applications are usually closed source
223 and the user still looses its freedom on the application level anyway. Even
224 in the case of available free applications there still remains the
225 disadvantage of loosing the Host-OS platform availability if implemented in
226 the $Wine style. For these ideology incompatibilities not much effort was
227 made for acceptance the fixes and improvements of $ReactOS by this project.
228 Moreover new functionality is not being implemented to the $ReactOS part
229 but it is coded in Gnome style in the project specific source files
232 <p>The most serious problem of $ReactOS is its dependence on the direct
233 <span class="constant">i386</span> hardware instead of some
234 @{[ a_href '#hostosnote','Host-OS' ]} as required by the goals of this project.
235 W32 is designed to be hardware-independent using its
236 <span class="fname">hal.dll</span>. Unfortunately $ReactOS does not follow
237 this design and thus there are needed various patches and replaces of its
238 various parts and its hardware-dependent code. Despite it $ReactOS code
239 base still made a big asset for this project.</p>
241 <p class="stuff">... and @{[ a_href 'http://www.reactos.com/','ReactOS' ]} cannot run on Linux!<br />
245 <p>Some API functions are provided both by
246 <span class="fname">ntdll.dll</span> and
247 <span class="fname">ntoskrnl.exe</span> in W32.
248 <span class="author">Casper Hornstrup</span> enlightened such functions
249 calling conventions have to be differentiated as
250 <span class="fname">ntdll.dll</span> lives in the user space (low address
251 space – below <span class="constant">0x80000000</span>) and
252 <span class="fname">ntoskrnl.exe</span> in the kernel space (high address
253 space – above <span class="constant">0x80000000</span>). Although they
254 contain slightly different set of symbols (functions)
255 <span class="fname">ntdll.dll</span> still can be considered as a user
256 space interface to the kernel space implementation by
257 <span class="fname">ntoskrnl.exe</span>.</p>
259 <p>Currently there are
260 no plans to ever extend the project's crossplatformity beyond the
261 <span class="constant">i386</span> processor
262 (<span class="constant">i386</span> used here as
263 @{[ a_href 'http://www.intel.com/','Intel' ]} architecture covering 32-bit
264 processors compatible with <span class="constant">i386</span>,
265 <span class="constant">i486</span>, ...).</p>
267 <h2>API Function Implementation Choices</h2>
269 <p>During the initial point of the project development all the API
270 functions were defined as unimplemented, of course. Any call of such
271 unimplemented function is fatal and results in program termination. When we
272 need to implement any required API function we have multiple choices to do
274 @{[ a_href '#functype_pass','Direct pass to original <span class="fname">ntoskrnl.exe</span>' ]},
275 @{[ a_href '#functype_wrap','Wrap of the original <span class="fname">ntoskrnl.exe</span> function' ]},
276 @{[ a_href '#functype_native_reactos','Native implementation – $ReactOS' ]},
277 @{[ a_href '#functype_native_wine','Native implementation – $Wine' ]}
279 @{[ a_href '#functype_native_libcaptive','Native implementation – project specific' ]}.
280 <!-- a_href '#functype_undef','Undefined function' -->
282 <h2>"patched" vs. "unpatched" Libraries</h2>
284 <p>Library is called <span class="constant">patched</span> if we require
285 loading its original binary code file. Project needs to patch it to be able
286 to trap all the function entry points. The only currently
287 <span class="constant">patched</span> library of this project is
288 <span class="fname">ntoskrnl.exe</span>.</p>
290 <p>Library is called <span class="constant">unpatched</span> if no original
291 binary code is needed since all of its functions are completely emulated by
292 @{[ a_href '#functype_native','the native implementations' ]} of this project.
293 The typical <span class="constant">unpatched</span> representative is
294 <span class="fname">hal.dll</span> as it specializes on the hardware
295 dependent code and therefore it must be completely replaced by this project
296 running in the $gnulinux operating system environment. Early versions of
297 this project had also full <span class="constant">unpatched</span>
298 <a href="#native_ntoskrnl">native implementation of
299 <span class="fname">ntoskrnl.exe</span></a> but it no longer applies.</p>
301 <h2>Memory Management</h2>
303 <p>Original <span class="productname">Microsoft Windows NT</span>
304 architecture uses two address space areas – user space and kernel space.
305 User space is mapped in the range <span class="constant">0x00000000</span>
306 to <span class="constant">0x7FFFFFFF</span>, kernel space is mapped in the
307 range <span class="constant">0x80000000</span>
308 (<span class="constant">KERNEL_BASE</span> in $ReactOS sources) to
309 <span class="constant">0xFFFFFFFF</span>. All these virtual memory ranges
310 represent addresses after their MMU (Memory Management Unit) mapping, of
311 course. More discussion can be found in the
312 <a href="http://www.microsoft.com/hwdev/platform/server/PAE/PAEmem.asp">description
313 by <span class="productname">Microsoft</span></a>.</p>
315 <p>This project runs in the virtual address space used both for the UNIX
316 user space process part and for the W32 kernel space. Therefore this
317 project defines that W32 kernel runs in the whole range
318 <span class="constant">0x00000000</span> to
319 <span class="constant">0xFFFFFFFF</span> since there are no special mapping
320 assumptions about the UNIX user space process mapping. No W32 user space
321 exists in this project. Such approach also nullifies any special memory
322 moving operations between W32 kernel space and W32 user space memory areas
323 (such as <span class="function">MmSafeCopyToUser()</span>).</p>
325 <h2>Unicode Strings and Characters</h2>
327 <p>W32 platform uses 16-bit type <span class="type">wchar_t</span> while $gnulinux uses a
328 32-bit one. This can be problem during GCC (GNU C Compiler)
329 compilation of combination of native UNIX C sources (assuming 32-bit
330 GCC with 32-bit <span class="type">wchar_t</span>) and
331 $ReactOS C sources (assuming W32 compiler with 16-bit
332 <span class="type">wchar_t</span>) for literal wide strings
333 (C source file systax: <span class="command">L"wstring"</span>).
334 Possibilities to solve this issue list:</p>
338 <p>Using <span class="constant">-fshort-wchar</span> GCC option and
339 strictly differentiate between compilation of
340 <span class="productname">ReactOS</span> code and UNIX code.</p>
342 <p>pros: No source modifications needed, no runtime performance hit.</p>
344 <p>cons: No type checking if some part of code has bad compilation
345 flags, complicated way to completely split
346 <span class="productname">ReactOS</span> and UNIX code.</p>
349 <p>Wrap all <span class="productname">ReactOS</span> literal constants
350 by some conversions function call (implemented as macro
351 <span class="function">REACTOS_UCS2()</span> by this project).</p>
353 <p>pros: Any forgotten/mistaken conversions are type-checked and warned
354 during the compilation by GCC.</p>
356 <p>cons: All compiled <span class="productname">ReactOS</span> sources
357 files containing literal wide strings have to be wrapped/modified,
358 performance hit by runtime string conversions.</p>
360 <p>This solution was chosen to get the internal sanity checking
365 <h2>Supported Binary Formats</h2>
367 <p>The native W32 binary format is identified as
368 <span class="constant">PE-32</span> (Portable Executable 32-bit), such
369 files have all the usual extensions such as
370 <span class="fname">.sys</span>, <span class="fname">.exe</span>,
371 <span class="fname">.dll</span> etc. <span class="constant">PE-32</span>
372 loading support was already implemented by $ReactOS, its memory mapping
373 specifics just had to be ported to $gnulinux environment by this project.
374 This loading support does not (yet) cover importing of debug symbols from
375 W32 <span class="fname">.PDB</span> (Program DataBase) files in $gnulinux
376 ABI (Application Binary Interface) compatible way.</p>
378 <p>This project also supports transparent loading of UNIX
379 <span class="fname">.so</span> (Shared Object file) binary format. If you
380 have W32 source files for some W32 library you can try to compile it by GCC
381 to get the shared library with $gnulinux ABI compatible debug information
382 (GCC option <span class="constant">-ggdb3</span> recommended). Beware of
383 possible compilation problems as <span class="productname">Microsoft</span>
384 C code expects <span class="constant">exception</span> handling to be
385 supported by the compiler (definitely not the case of the plain C compiler
386 of GCC) — all the exception catching code should be discarded as any
387 @{[ a_href '#exception_fatal','generated exceptions are always fatal' ]} when
388 such driver is running in the scope of this project. You can use the
389 following script of this project to compile W32 filesystem source files as
390 UNIX <span class="fname">.so</span>:
391 @{[ captive_srcfile 'src/w32-mod/ext2fsd.so-build.sh' ]}</p>
393 <p>Be aware of some differences if you use
394 <span class="constant">PE-32</span> binary format file vs.
395 <span class="fname">.so</span> format file.
396 <span class="constant">PE-32</span> use the appropriate W32 specific
397 @{[ a_href '#calltype','cdecl/stdcall/fastcall call types' ]},
398 <span class="fname">.so</span> must be completely compiled in the standard
399 UNIX @{[ a_href '#calltype_cdecl','cdecl call type semantics' ]}.
400 @{[ a_href '#functype_native','Native function implementations' ]} do not need
401 to be explicitely exported by <span class="fname">captivesym</span> as they
402 are resolved automatically by the UNIX dynamic system linker. It may be
403 surprising you will have to fix all such missing symbol exports if you
404 advance during the development from the debugging
405 <span class="fname">.so</span> file for the production version of the
406 original <span class="constant">PE-32</span> binary file.</p>
408 <h2>Reverse Engineering</h2>
410 <p>This project has no intentions to reverse engineer and document the
411 filesystem data structures themselves since they are being encapsulated by
412 the filesystem driver. For these reasons the resources available in
413 projects such as $LinuxNTFS get out of any possible use. This project goal
414 is to provide fully compatible API interface to the rest of the W32 system
415 to persuade the filesystem driver it is running in the native
416 <span class="productname">Microsoft Windows XP</span> environment.</p>
418 <p>All the W32 filesystem drivers are running in the W32 kernel address
419 space and this area of W32 API is not much documented by
420 <span class="productname">Microsoft</span>. Some API functions are not
421 documented at all and the others are documented insufficiently for a their
422 possibly needed reimplementation from scratch. Documentation being
423 consulted primarily consists of
424 <span class="productname">@{[ a_href 'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kmarch/hh/kmarch/kmhdr_6enb.asp','MSDN (Microsoft Developer Network) Kernel-Mode Driver Architecture: Windows DDK' ]}</span>
425 documentation and also various other 3rd party documentation resources such as
426 <span class="productname">@{[ a_href 'http://www.osr.com/ntinsider/1996/cacheman.htm',
427 'The NT Cache Manager Description' ]}</span>,
428 <span class="productname">@{[ a_href 'http://www.winntmag.com/Articles/Print.cfm?ArticleID=3864',
429 'Learn About NT'."'".'s File-system Cache' ]}</span>,
430 <span class="productname">@{[ a_href 'http://www.ntfsd.org/archive/',
431 'NT File System Developers mailing list archives' ]}</span>
433 @{[ a_href 'http://www.google.com/search?q=site%3Amicrosoft.com','fulltext searches' ]}
434 through Internet from case to case.</p>
436 <p>Sometimes no sufficient documentation was found and some code behaviour
437 had to be reverse engineered directly from the binaries of
438 <span class="fname">ntoskrnl.exe</span>,
439 <span class="fname">cdfs.sys</span>,
440 <span class="fname">fastfat.sys</span>
442 <span class="fname">ntfs.sys</span>.
443 Up to now the code was disassembled by
444 <span class="productname">@{[ a_href 'http://www.simtel.net/pub/pd/29498.html','IDA Freeware' ]}</span>
446 <span class="productname">dumpbin.exe</span> of
447 <span class="productname">Microsoft Visual Studio</span>.
448 <span class="productname">dumpbin.exe</span> is fortunately able to
449 interpret debug symbols from W32 <span class="fname">.PDB</span>
450 (Program DataBase) debug information files.</p>
452 <h3><span class="productname">dumpbin.exe</span>:</p></h3>
454 <p>You should use the following options for
455 <span class="productname">dumpbin.exe</span>:</p>
457 <blockquote class="command">
458 <p>dumpbin.exe /all /rawdata:none /disasm /pdbpath:verbose FILENAME.SYS</p>
461 <p>You should see the following line in the output:</p>
463 <blockquote class="command">
464 <p>PDB file found at '.\\FILENAME.pdb'</p>
467 <h3><span class="productname">WinDbg</span> Windows NT kernel debugging</h3>
469 <p><span class="productname">WinDbg</span> is downloadable from:
470 @{[ a_href 'http://www.microsoft.com/whdc/ddk/debugging/installx86.mspx' ]}</p>
472 <p>This is (the only?) tool able to debug filesystem drivers incl.
473 <span class="fname">ntfs.sys</span>. You will need two computers running
474 <span class="productname">Microsoft Windows</span> — one computer will run
475 <span class="productname">WinDbg</span> while the other one will be
476 frozen in remote Windows NT kernel debug mode. It does not matter which
477 <span class="productname">Microsoft Windows</span> version will be run
478 on the <span class="productname">WinDbg</span> side.</p>
480 <p>The most easy way to setup two computers is to use commercial
481 <span class="productname">@{[ a_href 'http://www.vmware.com/download/workstation.html','VMware Workstation' ]}</span>
482 where you can run two virtual machines simultaneously on single PC
483 hardware and you can connect them by a virtual serial port provided by
484 <span class="productname">VMware</span>.</p>
486 <h4><span class="productname">WinDbg</span> side setup</h4>
488 @{[ doc_img 'ntdebug-vmware-windbg',
489 '<span class="productname">VMware</span> virtual serial port'
490 .' of <span class="productname">WinDbg</span> side' ]}
492 <p>You should setup <span class="productname">WinDbg</span> according
495 @{[ doc_img 'ntdebug-windbg-port','Port settings of <span class="productname">WinDbg</span>' ]}
496 @{[ doc_img 'ntdebug-windbg-sym','Symbols files location of <span class="productname">WinDbg</span>' ]}
498 <span class="constant">Symbols</span> should point to the directory where
499 reside files extracted from the symbol archive for your version of
500 <span class="productname">Microsoft Windows</span>. In the case of the
501 recommended <span class="productname">Microsoft Windows XP Service Pack 1 Checked Build</span>
503 @{[ a_href 'http://msdl.microsoft.com/download/symbols/packages/windowsxp/xpsp1sym_x86_chk.exe' ]}</p>
505 <blockquote class="command">
506 <p># Rename xpsp1sym_x86_chk.exe contents .pdb files for WinDbg<br />
507 @{[ CGI::escapeHTML(q{for i in *.pdb*;do ext="`echo $i|sed 's/^.*\.pdb\.\(.*\)$/\1/'`";if [ "$i" = "$ext" ];then echo "BAD:$i";break;fi;base="`echo $i|sed 's/\(\.pdb\)\..*$/\1/'`";echo "md $ext";echo "move /-y $i $ext\\$base";done|sort -u|sed 's/$/'`echo -ne '\r'`'/g' >/tmp/rename.bat}) ]}</p>
510 <p>The resulting <span class="command">rename.bat</span> for
511 <span class="command">xpsp1sym_x86_chk.exe</span> can be found at:
512 @{[ a_href 'xpsp1sym_x86_chk-rename.bat.zip' ]}</p>
514 <p>The resulting directory should contain at least
515 <span class="command">sys\\ntfs.pdb</span>
517 <span class="command">exe\\ntoskrnl.pdb</span>.</p>
519 <p>Your successfuly connected target (after the steps described
520 below) should look like:</p>
522 @{[ doc_img 'ntdebug-windbg-boot','Successfuly connected <span class="productname">WinDbg</span>' ]}
524 <h4>Setup of the side being kernel-debugged</h4>
526 @{[ doc_img 'ntdebug-vmware-xpdebug',
527 '<span class="productname">VMware</span> virtual serial port'
528 .' of the side being kernel-debugged' ]}
530 <p>You must use the following options in your
531 <span class="command">c:\\boot.init</span> command-line:</p>
533 <blockquote class="command">
534 <p>/debug /debugport=COM1 /baudrate=115200</p>
537 <p>After booting this <span class="command">boot.ini</span>-entry
538 should freeze at this point
539 (if no <span class="productname">WinDbg</span> is waiting in the other
540 virtual machine):</p>
542 @{[ doc_img 'ntdebug-wait','Side being kernel-debugged waiting for <span class="productname">WinDbg</span>' ]}
545 <a name="law"><h2>Laws and Licensing Conditions</h2></a>
547 <p>If you are an <span class="productname">authorized user</span> of
548 <span class="productname">Microsoft Windows NT</span> the laws in some
549 countries give you the right to fully handle the product in any way you
550 want. Therefore you can disassemble the product even in the case you had
551 to agree with the product license forbidding such disassembly as the
552 country laws override any such license agreement.</p>
554 <h3>Microsoft Service Pack</h3>
556 <p>Sometimes you may have the legal license for
557 <span class="productname">Microsoft Windows NT</span>
558 but for various technical reasons you do not have the media and/or
559 installation ready at the place of intended use of this project.</p>
561 <p>Fortunately <span class="productname">Microsoft</span> provides
562 $freebeer update packages for its
563 <span class="productname">Microsoft Windows</span> products called
564 <span class="productname">Service Packs</span>; the latest one is
565 <span class="productname">@{[ a_href 'http://www.microsoft.com/WindowsXP/pro/downloads/servicepacks/sp1/checkedbuild.asp','Microsoft Windows XP Service Pack 1a' ]}</span>.</p>
567 <p>This downloadable file contains the full versions of the essential
568 files needed for the current stage of this product:
569 <span class="fname">ntfs.sys</span>
571 <span class="fname">ntoskrnl.exe</span>.
573 <span class="fname">cdfs.sys</span> and
574 <span class="fname">fastfat.sys</span> for testing purposes.</p>
576 <p><span class="productname">Service Pack</span> also contains
577 EULA (End User License Agreement) paper disallowing any use of
578 <span class="productname">Service Pack</span> outside its original
579 intentions. According to the laws of some countries you need to be
580 <span class="productname">authorized user</span> of the
581 <span class="productname">Microsoft Windows XP</span> product to be
582 allowed to use the files contained in such
583 <span class="productname">Service Pack</span> without the bindings of its
584 EULA. Even the interpretation of such laws may vary.</p>
586 <p>It would be a breach of the law by the project author to provide
587 automatic (=hidden) functionality to download and extract the
588 <span class="productname">Service Pack</span> files. On the other hand it
589 is perfectly legal to ask user for his/her confirmation whether he/she is
590 really the <span class="productname">authorized user</span> of
591 <span class="productname">Microsoft Windows XP</span> product and
592 download/extract the <span class="productname">Service Pack</span> files
595 @{[ doc_img 'captive-install-acquire-ask','Microsoft Windows Drivers Acquire Affirmation' ]}
597 <h2>Project Architecture</h2>
599 @{[ doc_img 'dia/arch-all','Project Components Architecture' ]}
601 <p>Most of the work of this project is located in the single box called
602 "<span class="constant">libcaptive</span>" located in the center
603 of the scheme. This component implements the core W32 kernel API by
604 various methods described in this document.
605 The "<span class="constant">libcaptive</span>" box cannot be
606 further dissected as it is just an implementation of a set of
607 @{[ a_href 'http://cvs.jankratochvil.net/viewcvs/*checkout*/priv/captive/src/libcaptive/ke/exports.captivesym?rev=HEAD',
609 It could be separated to several subsystems such as the
610 @{[ a_href '#cache_manager','Cache Manager' ]},
611 Memory Manager, Object Manager, Runtime Library, I/O Manager
612 etc. but they have no interesting referencing structure.</p>
614 <p>As this project is in fact just a filesystem implementation every
615 story must begin at the device file and end at the filesystem operations
616 interface. The unified suppported interfaces are
617 <span class="productname">@{[ a_href 'http://developer.gnome.org/doc/API/2.0/glib/','GLib' ]}</span>
618 (the most low level portability, data-types and utility library for Gnome)
619 <span class="type">GIOChannel</span> (for the device access) and the custom
620 <span class="constant">libcaptive</span> filesystem API. Each of these ends
621 can be connected either to some direct interface (such as the
622 <span class="constant">captive-cmdline</span> client),
623 @{[ a_href 'http://lufs.sourceforge.net/lufs/','Linux Userland File System (LUFS)' ]}
624 or as a general $GnomeVFS filter.
625 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} will be used in
626 most cases as it offers standard filesystem interface by Linux kernel.
628 You can also use $GnomeVFS as it offers nice filter interface on
629 the UNIX user-privileges level for transparent operation with archives and
630 network protocols. This filter interface was used by this project to turn
631 the device reference such as <span class="fname">/dev/hda3</span> or <span
632 class="fname">/dev/discs/disc0/part3</span> to the fully accessible
633 filesystem (pretending being an "archive" in the device
634 reference). This device access can be specified by $GnomeVFS URLs such as:
636 class="fname">file:///dev/hda3#captive-fastfat:/autoexec.bat</span></p>
638 <span class="constant">captive-bug-replay</span> serves just for debugging
639 purposes — you can 'replay' existing
640 <span class="fname">file.captivebug.xml.gz</span> automatically being
641 generated during W32 filesystem failure. This bugreport file will contain
642 all the touched data blocks of the device used in the moment of the
643 failure. <span class="constant">captive-bug-replay</span> will therefore
644 emulate internal virtual writable device out of these bugreported data.
646 <p>If the passed device reference is requested by the user to be accessed
647 either in <span class="dashdash">--ro</span> (read-only) mode or in the
648 <span class="dashdash">--rw</span> (full read-write) mode there are no
649 further device layers needed. Just in the case of <span
650 class="dashdash">--blind</span> mode another layer is involved to emulate
651 read-write device on top of the real read-only device by the method of
652 non-persistent memory buffering of all the possible write requests.</p>
654 <span class="constant">sandbox commit buffer</span> is involved only in the
655 case @{[ a_href '#sandbox','sandboxing feature' ]} is active. It will
656 buffer any writes to the device during the sandbox run to prevent
657 filesystem damage if the driver would fail in the meantime. If the
658 filesystem gets finally successfully unmounted this sandbox buffer can be
659 <a name="safe_flush">safely flushed</a>
660 to its underlying physical media. The buffer will be dropped
661 in the case of filesystem failure, of course. The filesystem should be
662 unmounted from time to time — it can be transparently unmounted and mounted
663 by <span class="command">commit</span> of
664 <span class="constant">captive-cmdline</span> custom client. Currently you
665 cannot force remounting when using
666 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} interface client
667 but it will be remounted after approx each 1MB data written automatically
668 due to @{[ a_href '#log_file_full','NTFS log file full' ]}.
670 Now we need to transparently
671 @{[ a_href 'http://cvs.jankratochvil.net/viewcvs/*checkout*/priv/captive/src/libcaptive/sandbox/sandbox.idl?rev=HEAD',
673 the device interface of <span class="type">GIOChannel</span> type through
674 @{[ a_href '#sandbox','CORBA/ORBit' ]} to the sandboxed slave.
676 <p>Such device is still only a UNIX style GLib <span
677 class="type">GIOChannel</span> type at this point. As we need to supply it
678 to the W32 filesystem driver we must convert it to the W32 I/O Device
679 with its capability of handling <span class="type">IRP</span>
680 (<span class="constant">I/O Request Packet</span>; structure holding the
681 request and result data for any W32 filesystem or W32 block device
683 requests from its upper W32 filesystem driver. Such W32 I/O Device can
684 represent either <span class="type">CD-ROM</span> or
685 <span class="type">disk</span> device type as different W32 filesystem
686 drivers require different media types — currently only
687 <span class="fname">cdfs.sys</span> requires
688 <span class="type">CD-ROM</span> type.</p>
690 <p>W32 media I/O Device is accessed from the W32 filesystem driver.
691 The filesystem driver itself always creates volume object by
692 <span class="function">IoCreateStreamFileObject()</span> representing the
693 underlying W32 media I/O Device as the object handled by the
694 filesystem driver itself. All the client application filesystem requests
695 must be first resolved at the filesystem structures level, passed to the
696 volume stream object of the same filesystem and then finally passed to the
697 W32 media I/O Device (already implemented by this project as an
698 interface to <span class="type">GIOChannel</span> noted above).</p>
700 <p>The filesystem driver is called by the core W32 kernel implementation of
701 <span class="constant">libcaptive</span> in
702 @{[ a_href '#synchronous','synchronous way' ]} in single-shot manner instead of
703 the several reentrancies while waiting for the disk I/O completions as can
704 be seen in the original
705 <span class="productname">Microsoft Windows NT</span>.
706 This single-shot synchronous behaviour is possible since all the needed
707 resources (disk blocks etc.) can be always presented as instantly ready as
708 their acquirement is solved by @{[ a_href 'hostosnote','Host-OS' ]} outside of
709 the W32 emulated @{[ a_href 'guestosnote','Guest-OS' ]} environment.
710 For several cases needed only by <span class="fname">ntfs.sys</span>
711 there had to be supported asynchronous access — parallel execution
712 is emulated by GLib <span class="function">g_idle_add_full()</span>
713 with <span class="function">g_main_context_iteration()</span> called during
714 <span class="function">KeWaitForSingleObject()</span>.</p>
716 <p><span class="constant">libcaptive</span> offers the W32 kernel
717 filesystem API to the upper layers. This is still not the API the common
718 W32 applications are used to as they use W32 libraries which in turn pass
719 the call to W32 kernel. For example
720 <span class="function">CreateFileA()</span> is being implemented by several
721 libraries such as <span class="fname">user32.dll</span> as a relay
722 interface for the kernel function
723 <span class="function">IoCreateFile()</span> implemented by this
724 project's <span class="constant">libcaptive</span> W32 kernel
725 emulation component.</p>
727 <p>As it would be very inconvenient to use the legacy, bloated and UNIX
728 style unfriendly W32 kernel filesystem API this project offers its own
729 @{[ a_href '#client_interface','custom filesystem API interface' ]} inspired by
730 the $GnomeVFS client interface adapted to the specifics of W32 kernel API.
731 This interface is supposed to be easily utilized by
732 <a href="#client_interface_customapp">a custom application accessing
733 the W32 filesystem driver</a>.</p>
735 <p>@{[ a_href '#sandbox','CORBA/ORBit' ]} hits us again – we need to
736 @{[ a_href 'http://cvs.jankratochvil.net/viewcvs/*checkout*/priv/captive/src/libcaptive/sandbox/sandbox.idl?rev=HEAD',
738 the @{[ a_href '#client_interface','custom filesystem API interface' ]}
739 out of the sandboxed slave to the UNIX space.</p>
741 <p><span class="constant">captive sandbox master</span> provides the
742 functionality of covering any possible sandboxed slave restarts and its
743 communication. It is also capable of
744 <a name="demultiplexing_master">demultiplexing single API operations</a>
745 to multiple its connected sandbox slaves in transparent way
746 as each of them handles
747 @{[ a_href '#mounted_one','just one filesystem device' ]}.</p>
749 <p>The rest of the story is not much special for this project since this is
750 a common UNIX problem how to offer user space implemented UNIX filesystem
751 as a generic system filesystem (as those are usually implemented only as
752 the components od UNIX kernel).</p>
754 <p>The filesystem service can be offered in several ways:</p>
757 <dt>Custom client</dt>
759 <p>One possibility would be to write
760 <a name="client_interface_customapp">a custom client application</a>
761 for this project such as file manager or a shell. Although it
762 would implement the most appropriate user interface to the set of
763 functions offered by this project (and W32 filesystem API) it has the
764 disadvantage of special client software. Appropriate client is provided
766 <span class="fname">src/client/cmdline/cmdline-captive</span></p>
769 <dt>@{[ a_href 'http://lufs.sourceforge.net/lufs/','Linux Userland File System (LUFS)' ]}</dt>
771 <p>The most usable interface is the
772 @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]} client
773 by <span class="constant">liblufs-captivefs</span>.
774 As @{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]}
775 already assigns separate process for each filesystem mount the
776 @{[ a_href '#demultiplexing_master','demultiplexing feature' ]}
777 is not utilized in this case.</p>
779 <p>@{[ a_href 'http://lufs.sourceforge.net/lufs/','LUFS' ]}
780 needs multiple operating threads (each UNIX kernel operation needs
781 one free lufsd slot/thread to not to fail immediately).
782 As <span class="constant">libcaptive</span> is
783 @{[ a_href '#synchronous','single-threaded' ]} all the operations
784 get always synchronized by
785 <span class="constant">liblufs-captivefs</span>
786 before their pass over to <span class="constant">libcaptive</span>.</p>
789 <dt>@{[ a_href '#offered_gnomevfs','Gnome-VFS' ]}</dt>
791 <p>This client allowing its filesystem access even without any
792 involvement of UNIX kernel from any $GnomeVFS aware client application
793 (such as <span class="fname">gnome-vfs/tests/test-shell</span>).
794 This @{[ a_href '#offered_gnomevfs','Gnome-VFS interface' ]} connects the
795 data flow of this project in two points — both as the lowest layer
796 device image source and also as the upper layer for the filesystem
797 operation requests.</p>
801 <p>Unimplemented and deprecated methods for providing filesystem
805 <dt>W32 filesystem in UNIX OS kernel</dt>
807 <p>The real UNIX OS filesystem implementation must be completely
808 implemented inside the hosting OS kernel. This requires special coding
809 methods with limited availability of coding features and libraries.
810 Also it would give the full system control to the untrusted W32
811 filesystem driver code with possibly fatal consequences of yet
812 unhandled W32 emulation code paths. It would benefit from the best
813 execution performance but this solution was never considered a real
817 <dt>Custom NFS server</dt>
819 <p>The common approach
820 <a name="offered_NFS">of filesystem implementations</a>
821 outside UNIX OS kernel were custom NFS servers usually running on the
822 same machine as the NFS-connected client as such NFS server is usually
823 an ordinary UNIX user space process. It would be possible to implement
824 this project as a custom NFS server but the NFS protocol itself
825 has a lot of fundamental flaws and complicated code for backward
831 <a name="mounted_one"><h2>At Most One Mounted Filesystem</h2></a>
833 <p>The project technically supports only one (exactly one...) mounted
834 filesystem device and only one filesystem driver. There is nothing
835 complicated to support multiple disks and multiple loaded filesystem
836 modules but as they would share the address space it would only bring
837 a possible complications during bug reports and the bug solving
838 itself. It was considered as a more sane way to support multiple W32
839 mounted disks by completely separately running project instances in
840 a different UNIX processes communicating from their sandboxes via
841 @{[ a_href '#sandbox','CORBA sandbox interface' ]}. This sandboxing
842 feature is not yet deployed although its code is already prepared.</p>
844 <p>The project also does not support any state cleanup to be able to load
845 filesystem <span class="constant">A</span>,
846 cleanup <span class="constant">A</span> and load a different
847 filesystem <span class="constant">B</span> in the same process address
848 space. It complies with the preventions of the possible debugging
849 complications as noted above. Despite this you still must call the function
850 <span class="function">captive_shutdown()</span> to flush all the pending
851 filesystem buffers to the disk. After calling
852 <span class="function">captive_shutdown()</span> the process address space is
853 no longer usable for any further project operations and the process is
854 expected to be terminated in the manner compatible with its driving
855 @{[ a_href '#sandbox','CORBA sandbox interface' ]} control master.</p>
857 <p>Each sandbox executing the untrusted W32 binary filesystem driver code
858 is connected through its
859 @{[ a_href '#sandbox','CORBA sandbox interface' ]} at the point of upper
860 layer <span class="constant">libcaptive</span>-specific filesystem API, at
861 the point of the bottom layer of <span class="type">GIOChannel</span>
862 device access and also for transfers of GLib logging
863 messages/warnings/errors out of the sandbox to the user.</p>
866 <h1>Choice of the Emulation Methods</h1>
868 <p>The intent of the project was to get reliable read-write access to
869 <span class="productname">NTFS</span> partition. There are several possible
870 ways to achieve that:</p>
872 <h2>Virtualmachine Running the Original W32 Subsystem</h2>
874 <p>Creating virtual-hardware PC and running the original W32 binaries
875 including their boot-loader etc. Disk device access would be passed as
876 virtual IDE disk (=hard disk drive). File access API would be implemented
877 either by special escaping by some trapped instruction out of the
878 virtualmachine while using W32 file access API or using the standard W32
879 SMB (Server Message Block) network access through some virtual network
880 card. The latter network access solution is almost the currently available
881 possibility of running full-blown disk-sharing real
882 <span class="productname">Microsoft Windows NT</span> inside virtual
883 machine emulator such as <span class="productname">VMware</span>.</p>
885 <p>pros: Full compatibility due to fully native codebase.</p>
887 <p>cons: Hard to debug, missing documentation of NT booting internals,
888 possible problems by different PC virtual-hardware than expected by NT,
889 requirement of fully installed
890 <span class="productname">Microsoft Windows NT</span> product.</p>
892 <a name="method_ntoskrnl"><h2>"ntoskrnl.exe" Inside Virtual Address Space</h2></a>
894 <p>This solution was chosen by the project. Binary filesystem driver and
895 also <span class="fname">ntoskrnl.exe</span> binary file are required.
896 Unfortunately <span class="fname">ntoskrnl.exe</span> expects a native
897 PC virtual-hardware missing during regular UNIX user space process
898 emulation, therefore such instructions must be trapped and emulated/ignored
899 from case to case.</p>
901 <p>Also the <a name="init_ntoskrnl">initialization code of <span
902 class="fname">ntoskrnl.exe</span></a> is not executed by this project since
903 it expects to get full PC hardware access privileges and thus some
904 datastructures do not get initialized by it (need to be trapped later at
905 runtime stage). Some of the missing initializations are solved by
906 @{[ a_href '#functype_wrap','API functions wrapping' ]}.
908 <p>pros: Lightweight, easier to debug.</p>
910 <p>cons: Possible incompatible emulation of
911 <span class="fname">ntoskrnl.exe</span> parts, missing documentation needed
912 for the implementation.</p>
914 <h2>Filesystem Driver Inside Virtual Address Space</h2>
916 <p>Unlike @{[ a_href '#method_ntoskrnl','previous method' ]} here we do not use
917 even <span class="fname">ntoskrnl.exe</span> as the complete kernel part of
918 W32 is <a name="native_ntoskrnl">emulated from the project source
919 files</a>. <span class="fname">cdfs.sys</span> driver was successfuly ran
920 in this manner in the former versions of this project but the possibility
921 to run without <span class="fname">ntoskrnl.exe</span> was dropped since it
922 had no licensing gains (you need the original
923 <span class="productname">Microsoft Windows NT</span> files at least for
924 the filesystem driver itself) and the emulation of undocumented parts
925 reusable from <span class="fname">ntoskrnl.exe</span> binary was
928 <p>pros: Lightweight, easier to debug.</p>
930 <p>cons: Possible incompatible emulation of the whole
931 <span class="fname">ntoskrnl.exe</span>, its missing documentation.</p>
934 <h1>Implementation Details</h1>
936 <a name="functype"><h2>API Function Implementation Choices</h2></a>
938 <p>For each function exported by W32
939 <span class="fname">ntoskrnl.exe</span> and imported and called by the
940 filesystem driver a decision needs to be made to properly implement its
941 functionality. Currently implemented functionality statistics are provided
944 <table border="1" align="center">
945 <tr><th>Function type </th><th>Items</th><th>Portion</th></tr>
946 <tr><td>@{[ a_href '#functype_pass','pass' ]} </td><td> 81</td><td> 26%</td></tr>
947 <tr><td>@{[ a_href '#functype_wrap','wrap' ]} </td><td> 2</td><td> 0%</td></tr>
948 <tr><td>@{[ a_href '#functype_native_reactos','native-ReactOS' ]}</td><td> 113</td><td> 36%</td></tr>
949 <tr><td>@{[ a_href '#functype_native_libcaptive','native-own' ]} </td><td> 116</td><td> 38%</td></tr>
950 <caption>Function Implementation Types Statistics</caption>
953 <p>As there are several choices to implement each function the usual
954 attempts/investigations ordering is listed in the sections below.</p>
956 <p>Special case must be taken for data-type symbols since they are
957 referenced without the possibility of catching the code flow by some
958 breakpoints (it would be possible only in some special access cases). Data
959 export symbols of <span class="constant">unpatched</span> libraries must
960 contain already prepared content at the runtime. There is a problem
961 with <span class="constant">patched</span> libraries where it is necessary
962 to also fully implement the data symbol as
963 @{[ a_href '#functype_native','native implementation' ]} since there is no
964 possibility to @{[ a_href '#functype_pass','pass' ]} the data symbol instead of
965 the original W32 data location and therefore there will be two instances of
966 such data variable place. As there will be also the uncaught references for
967 such W32 data location from the <span class="constant">patched</span>
968 library itself such symbols should be usually only some constants (such as
969 <span class="constant">KeNumberProcessors</span>).</p>
971 <p>W32 platform symbols export/import can be based either on the symbol
972 name itself or it can be also exported and imported just by its
973 identification number called <span class="constant">Ordinal</span>.
974 Although it saves some jumptables file binary size it is currently no
975 longer used by W32 binaries and this project also does not support such
976 <span class="constant">Ordinal</span> symbol reference type at all.</p>
978 <p>All the exporting magic is handled by custom script
979 <span class="fname">captivesym</span> processing the definition file
980 <span class="fname">@{[ a_href
981 'http://cvs.jankratochvil.net/viewcvs/*checkout*/priv/captive/src/libcaptive/ke/exports.captivesym?rev=HEAD',
982 'src/libcaptive/ke/exports.captivesym' ]}</span>
983 to produce the intermediate relaying code
984 <span class="fname">src/libcaptive/ke/exports.c</span>. For details of the
985 <span class="fname">captivesym</span>-specific source file syntax please
986 see its documentation:
987 <span class="fname">@{[ a_href
988 $W->{"top_dir"}.'/project/Pod2Html.html.pl?cvs=priv/captive/src/libcaptive/ke/captivesym.pl',
989 'src/libcaptive/ke/captivesym.pl' ]}</span>
991 <a name="functype_pass"><h3>Direct Pass to Original "ntoskrnl.exe"</h3></a>
993 <p>Simple (standalone) functions such as
994 <span class="function">RtlTimeToSecondsSince1970()</span> can be simply
995 passed to the original implementation in
996 <span class="fname">ntoskrnl.exe</span> as they make no hardware access
997 and they do not expect any special internal data structures to be set up
998 in advance by an earlier library initialization. A common case are all
999 the data structures utility functions such as
1000 <span class="constant">GenericTable</span> subsystem or
1001 <span class="constant">LargeMcb</span> handling.</p>
1003 <a name="functype_pass_fromunix"><h4>Pass from UNIX Code</h4></a>
1005 <p>Control flow begins in some standard UNIX code. Such code is always
1006 using @{[ a_href '#calltype_cdecl','cdecl call type' ]} for all its
1007 intracalls. <a href="#functype_native_reactos">Native functions
1008 compiled from <span class="productname">ReactOS</span> sources</a> use
1009 their own @{[ a_href '#calltype','cdecl/stdcall/fastcall' ]} declarations
1010 but these call type modifications are discarded during compilation for
1011 this project by the <span class="constant">LIBCAPTIVE</span>
1014 <p>UNIX code calls <span class="function">FUNCTIONNAME()</span> relay
1015 from the generated UNIX jump table. Such relay will debug dump the
1016 passed arguments and finally pass the control to the original W32
1017 function code in the proper call type
1018 @{[ a_href '#calltype','cdecl/stdcall/fastcall' ]} for a given
1021 <p>Original W32 code entry point is always trapped by a breakpoint
1022 although it would not be needed during this specific direct pass from
1023 UNIX code to the original W32 implementation. Still the breakpoint has
1024 to be there to catch some other (such as intra-W32) possible calls
1025 described later. There are several more ways to define breakpoint in
1026 the code. One way is to use processor hardware breakpoint support but
1027 the number of breakpoints is limited. The other way is to patch in the
1028 <span class="instruction">@{[ 'int $3' ]}</span> instruction but it will invoke
1029 <span class="constant">SIGTRAP</span> signal handler conflicting with
1030 the possible debugger (<span class="productname">gdb(1)</span>)
1031 control. This project uses the <span class="instruction">hlt</span>
1032 instruction, which also has a single-byte opcode as
1033 <span class="instruction">@{[ 'int $3' ]}</span> and it is a privileged
1034 instruction forbidden to be used from the UNIX user space code.
1035 <span class="instruction">hlt</span> invokes
1036 <span class="constant">SIGSEGV</span> signal which can be resolved by
1037 a custom signal handler without any conflict with the possible
1038 debugger control; <span class="productname">gdb(1)</span> needs the
1039 following command to pass through such
1040 <span class="constant">SIGSEGV</span> signal:</p>
1042 <blockquote class="command">
1043 <p>handle SIGSEGV nostop noprint pass</p>
1046 <p>When a breakpoint gets caught, we usually need to return to the
1047 running code. Unfortunately it is not possible because of the patched
1048 breakpoint opcode. The breakpoint cannot be simply removed upon return
1049 as it would permanently loose control over the point of entry. Even if
1050 the return would include faking of the return address in the bottom
1051 stack frame to patch the breakpoint back during later function exit it
1052 still would not solve the caughts of inner calls of recursive
1053 functions. One of the working possibilities would be to patch the
1054 original instruction back and perform a singlestep provided by
1055 <span class="function">ptrace(2)</span> syscall. However such
1056 singlestep needs another controlling UNIX process and it would again
1057 conflict with the debuggers such as
1058 <span class="productname">gdb(1)</span>. This project implements the
1059 singlestep functionality by two consecutive breakpoints
1060 (<span class="instruction">hlt</span> instructions to be specific):
1061 The first two instruction addresses of the W32 functions are called
1062 <span class="productname">slot #1</span> and
1063 <span class="productname">slot #2</span>, the length of the first
1064 function instruction has to be analyzed to get the right address of
1065 <span class="productname">slot #2</span>. When the first breakpoint is
1066 caught it is necessary to patch the original instruction back and also
1067 patch another breakpoint in place of
1068 <span class="productname">slot #2</span>.
1069 During the <span class="productname">slot #2</span> breakpoint
1070 invocation the operation will be reverted — the breakpoint will be put
1071 to <span class="productname">slot #1</span> again and the instruction
1072 of <span class="productname">slot #2</span> will be restored to be able
1073 to continue the execution of the function.</p>
1075 <p>W32 function will finish in its specific
1076 @{[ a_href '#calltype','cdecl/stdcall/fastcall call type' ]}, the control
1077 will return to the UNIX jump table relay which will debug dump the
1078 return value and it will finally pass the control back to the UNIX
1079 caller in the standard UNIX
1080 @{[ a_href '#calltype_cdecl','cdecl call type' ]}.</p>
1082 @{[ doc_img 'fig/functype_patched_pass_fromunix',
1083 'Function Type: <span class="constant">pass</span> from UNIX Code' ]}
1085 <a name="functype_pass_fromw32"><h4>Pass from W32 Code</h4></a>
1087 <p>This function type is similiar to the
1088 @{[ a_href '#functype_pass_fromunix','previous one' ]} with the exception
1089 of more complicated entry point. Unfortunately W32 libraries call their
1090 own functions directly, using the <span class="instruction">call</span>
1091 instructions without any patchable jump table. Even the
1092 <span class="instruction">call</span> argument itself cannot be patched
1093 according to the relocation table record as such library intra-call
1094 instruction has no relocation due to its relative argument offset on
1095 <span class="constant">i386</span>. This time the double-breakpoint
1096 mechanism @{[ a_href '#functype_pass_fromunix','described above' ]} gets
1097 handy since it will catch the entry point when the function gets
1098 called. <span class="constant">SIGSEGV</span> handler gets invoked by
1099 the <span class="instruction">hlt</span> instruction and it will
1100 redirect the control to the jump table relay function to debug dump the
1101 function entry arguments (it has no other uses in this call type).</p>
1103 <p>When the relay needs to call the original function it will reach
1104 exactly the same breakpoint instruction as during the recent
1105 <span class="constant">SIGSEGV</span> handling redirecting to this
1106 calling relay. But this time the
1107 <span class="constant">through_w32_func</span> field of this function
1108 record will be set to to prevent repeated redirection and to pass the
1109 control through the breakpoint mangle instead this time.</p>
1111 <p>Returning is not much interesting as the first
1112 <span class="constant">SIGSEGV</span> handler did a straight jump
1113 for the redirection purposes without any needed consequent
1116 <p>The jump table relay used for the callers from W32 code is
1117 a different one than the relay being used for the callers
1118 @{[ a_href '#functype_pass_fromunix','from UNIX code' ]}. UNIX code always
1119 uses relay with external @{[ a_href '#calltype_cdecl','cdecl call type' ]}
1120 but in this case a relay with the appropriate
1121 @{[ a_href '#calltype','cdecl/stdcall/fastcall call type' ]} is used.</p>
1123 @{[ doc_img 'fig/functype_patched_pass_fromw32',
1124 'Function Type: <span class="constant">pass</span> from W32 Code' ]}
1128 <table border="1" align="center">
1129 <tr><td><span class="fname">captivesym</span> keyword</td><td>pass</td></tr>
1130 <tr><td>Native code function name </td><td>(no implementation)</td></tr>
1131 <tr><td>W32 traced code from UNIX function name </td><td>FUNCNAME</td></tr>
1132 <tr><td>W32 traced code from W32 function name </td><td>FUNCNAME_cdecl/_stdcall/_fastcall</td></tr>
1133 <tr><td>Entry/exit debug tracing from UNIX code </td><td>yes</td></tr>
1134 <tr><td>Entry/exit debug tracing from W32 code </td><td>yes</td></tr>
1135 <caption>Function Type <span class="constant">pass</span> Characteristics</caption>
1138 <a name="functype_wrap"><h3>Wrap of the Original "ntoskrnl.exe" Function</h3></a>
1140 <a name="functype_wrap_fromunix"><h4>Wrapping of Call from UNIX Code</h4></a>
1142 <p>The code control flow has no special hardcore features since it is
1143 very similiar to <a href="#functype_pass_fromunix">the direct pass to
1144 W32 function from UNIX code</a>. All the wrapping is done in the
1145 standard UNIX @{[ a_href '#calltype_cdecl','cdecl call type' ]} manner.
1146 Jump table debug dumping relays are provided twice — the
1147 "outer" one to trace the parameters from the function caller
1148 and the "inner" one to trace the call from the wrapper to the
1149 original W32 code. The "inner" relay also calls the W32 code
1150 with the appropriate <a href="#calltype">cdecl/stdcall/fastcall call
1153 @{[ doc_img 'fig/functype_patched_wrap_fromunix',
1154 'Function Type: <span class="constant">wrap</span> from UNIX Code' ]}
1156 <a name="functype_wrap_fromw32"><h4>Wrapping of Call from W32 Code</h4></a>
1158 <p>This scheme is a combination of the
1159 <a href="#functype_wrap_fromunix">previous wrap of a call from
1160 UNIX code</a> and the <a href="#functype_pass_fromw32">direct pass from
1161 the W32 code</a>. The control is caught and redirected by
1162 <span class="constant">SIGSEGV</span> handler from the breakpoint
1163 placed at the entry to the original W32 function code. The second entry
1164 to the original W32 function with the
1165 <span class="constant">through_w32_func</span> field of this function
1166 description already set is done from the "inner" jump table
1167 relay with the appropriate
1168 @{[ a_href '#calltype','cdecl/stdcall/fastcall call type' ]}.</p>
1170 @{[ doc_img 'fig/functype_patched_wrap_fromw32',
1171 'Function Type: <span class="constant">wrap</span> from W32 Code' ]}
1175 <p>Some functions can be <a href="#functype_pass">passed to the original
1176 code</a> but they need their parameters to be checked/prepared.
1177 Currently, such wrapping is only needed for the
1178 <span class="function">ExAllocateFromPagedLookasideList()</span> function
1179 where it is required due to <a href="#init_ntoskrnl">missing execution of
1180 <span class="fname">ntoskrnl.exe</span> initialization execution</a>,
1181 which would otherwise properly initialize some internal data structures.
1182 In this case the wrapping code detects passing of an uninitialized
1183 parameter and will search through the whole
1184 <span class="fname">ntoskrnl.exe</span> code body at runtime to find the
1185 proper initialization routine containing the correct initialization
1186 parameters. Passed addresses of static structures must be differentiated
1187 as each of them usually has different initialization parameters. It is
1188 proactive to not to have fixed parameters array as these parameters may
1189 differ across different <span class="fname">ntoskrnl.exe</span>
1192 <table border="1" align="center">
1193 <tr><td><span class="fname">captivesym</span> keyword</td><td>wrap</td></tr>
1194 <tr><td>Native UNIX wrapping code function name </td><td>FUNCNAME_wrap</td></tr>
1195 <tr><td>W32 traced wraping code from UNIX func. name </td><td>FUNCNAME</td></tr>
1196 <tr><td>W32 traced wrapping code from W32 func. name </td><td>FUNCNAME_cdecl/_stdcall/...</td></tr>
1197 <tr><td>W32 traced original code function name </td><td>FUNCNAME_orig</td></tr>
1198 <tr><td>Entry/exit debug tracing from UNIX code </td><td>yes</td></tr>
1199 <tr><td>Entry/exit debug tracing from W32 code </td><td>yes</td></tr>
1200 <caption>Function Type <span class="constant">wrap</span> Characteristics</caption>
1203 <a name="functype_native"><h3>Native Implementation</h3></a>
1205 <h4>Native Implementation Called from UNIX Code</h4>
1207 <p>This is the simplest case of a function call as it is fully
1208 handled only by the compiler and/or linker.</p>
1210 <p>In this case though, no debug dumping call relay is provided — such
1211 relay would need to rename the implementations of native functions to
1212 prevent its automatic linking with the caller code. This renaming would
1213 not be possible to do by simple <span class="constant">#define</span>
1214 since it would also rename any calling statements of such function in
1215 the same C sources. One of the possibilities to solve would be to
1216 utilize <span class="dashdash">--redefine-sym</span> feature of the
1217 <span class="productname">objcopy(1)</span> utility. On the other hand
1218 there is not much need to catch/debug such calls as both the caller and
1219 the callee are provided with full source file debug information for the
1220 debugger. Also the callee usually debug dumps its entry/exit parameters
1221 by custom debug dumps in the
1222 <a href="#functype_native_reactos"><span class="productname">ReactOS</span> implementations</a>.
1224 @{[ doc_img 'fig/functype_native_fromunix',
1225 'Function Type: <span class="constant">native</span> from UNIX Code' ]}
1227 <a name="functype_native_fromw32"><h4>Native Implementation of
1228 "unpatched" Library Function Called from W32 Code</h4></a>
1230 @{[ doc_img 'fig/functype_unpatched_native_fromw32',
1231 'Function Type: <span class="constant">native</span> of <span class="constant">unpatched</span> from W32 Code' ]}
1233 <p>Here comes the differentiation if the project deals either with
1234 a <span class="constant">patched</span> or an
1235 <span class="constant">unpatched</span> version of the library
1236 (<span class="constant">patched</span> is a loaded W32 binary
1237 library while <span class="constant">unpatched</span> library is
1238 completely provided by this project with no use of the library's
1239 original W32 binary file). As the project adjusts the exported symbol
1240 address during the patching operation, in some cases the
1241 <span class="constant">patched</span> library call may be handled
1242 simply as <span class="constant">unpatched</span> library call even for
1243 the <span class="constant">patched</span> libraries. Fortunately the
1244 distinction is not much important as the project is prepared to
1245 properly handle both cases.</p>
1247 <p>The W32 caller which imported the symbol will be pointed right to
1248 the relaying function. The debug dumping relay will be called from W32
1249 code with the appropriate
1250 @{[ a_href '#calltype','cdecl/stdcall/fastcall call type' ]} while the
1251 relay will call the implementation of the native function in the
1252 standard UNIX @{[ a_href '#calltype_cdecl','cdecl call type' ]} manner.</p>
1254 <h4>Native Implementation of "patched" Library Function Called from W32 Code</h4>
1256 @{[ doc_img 'fig/functype_patched_native_fromw32',
1257 'Function Type: <span class="constant">native</span> of <span class="constant">patched</span> from W32 Code' ]}
1259 <p>The calling scheme is similiar to the
1260 <a href="#functype_native_fromw32">previous call of
1261 <span class="constant">unpatched</span> library function from W32
1262 code</a> but the call control is redirected from the entry point of the
1263 original W32 binary implementation by the breakpoint and its
1264 <span class="constant">SIGSEGV</span> handler as in
1265 <a href="#functype_pass_fromw32">the case of passing control from W32
1268 <p>The original W32 function implementation located in the original
1269 loaded binary file is never executed but its entry point needs to be
1270 trapped by the breakpoint to be able to catch the function calls within
1275 <p>In all cases the final function implementation is a standard UNIX
1276 code compiled from C sources with full debug information available
1277 for the debugger. Fortunately all such functions do not need to be coded
1278 from scratch for this project since there already exist $freespeech
1279 $ReactOS and $Wine projects and their code can be used instead.</p>
1281 <p>$Wine project is listed mostly for a completeness as almost no
1282 code was suitable for reuse as it implements W32 user space while this
1283 project is running pure W32 kernel space environment (in $gnulinux user
1286 <a name="functype_native_reactos"><h4>Native Implementation
1287 - <span class="productname">ReactOS</span></h4></a>
1289 <p>Some functions are already implemented in the $ReactOS
1290 project and they can be used as they are. Although it would be
1291 possible to <a href="#functype_pass">pass some function calls to the
1292 original code</a> it is more handy to provide native implementation as
1293 there is better control of the data handling during debugging sessions
1294 due to the provided debugging symbols.</p>
1296 <p>Such functions can be found in
1297 <span class="fname">src/libcaptive/reactos/</span> subdirectory.
1298 Some functions had to be adjusted for this project
1299 - these modifications are compiled conditionally, depending on the
1300 <span class="constant">LIBCAPTIVE</span> symbol existence.</p>
1302 <p>Later stages of this project reached the level where
1303 $ReactOS is yet too immature and the needed functions are usually
1304 written just with the sad body:</p>
1306 <blockquote class="command">
1307 <p>UNIMPLEMENTED;</p>
1310 <p>Functions that were not possible to
1311 @{[ a_href '#functype_pass','pass' ]} were reimplemented by this project
1312 and placed in the project's implementation directories
1313 @{[ a_href '#reactos_nocare','instead of extending' ]} $ReactOS code.</p>
1315 <a name="functype_native_wine"><h4>Native Implementation – <span class="productname">Wine</span></h4></a>
1317 <p>Even though $Wine only implements the
1318 <span class="productname">Microsoft Windows NT</span> user space, there
1319 still are some common functions which could be copied from the $Wine
1322 <a name="functype_native_libcaptive"><h4>Native Implementation – Project Specific</h4></a>
1324 <p>As the last resort it was necessary to provide completely own
1325 implementation of some API functions such as PC hardware dependent
1326 parts or memory management functions.</p>
1330 <table border="1" align="center">
1331 <tr><td><span class="fname">captivesym</span> keyword</td><td>(none; just the symbol name)</td></tr>
1332 <tr><td>Native code function name </td><td>FUNCTIONNAME</td></tr>
1333 <tr><td>Native traced code from W32 code func. name </td><td>FUNCTIONNAME_cdecl/_std...</td></tr>
1334 <tr><td>Entry/exit debug tracing from UNIX code </td><td>no</td></tr>
1335 <tr><td>Entry/exit debug tracing from W32 code </td><td>yes</td></tr>
1336 <caption>Function Type <span class="constant">native</span> Characteristics</caption>
1339 <a name="functype_undef"><h3>Undefined Function</h3></a>
1341 <p>Functions not defined by any of the previous function types cannot be
1342 called by any W32 code including the code of the library implementing
1343 such function. All functions of <span class="constant">patch</span>ed
1344 libraries not listed in the <span class="fname">captivesym</span> exports
1345 file are automatically set to be trapped as fatal program execution
1348 <p>It is not necessary to list the symbols as
1349 <span class="constant">undef</span> as long as you are just loading the
1350 W32 <span class="constant">PE-32</span> code and the symbols belong to
1351 <span class="constant">patch</span>ed library. On the other hand if you
1352 are loading W32 <span class="fname">.so</span> code or if such symbol is
1353 a part of <span class="constant">unpatched</span> library (and thus
1354 being completely provided by the project) you need to list such symbol as
1355 <span class="constant">undef</span> type to prevent unresolved symbol
1358 <table border="1" align="center">
1359 <tr><td><span class="fname">captivesym</span> keyword</td><td>undef</td></tr>
1360 <tr><td>Native code function name </td><td>(no implementation)</td></tr>
1361 <tr><td>Native traced code function name </td><td>FUNCTIONNAME_cdecl/_stdcall/_fastcall</td></tr>
1362 <tr><td>Debug tracing message from UNIX code </td><td>yes</td></tr>
1363 <tr><td>Debug tracing message from W32 code </td><td>yes</td></tr>
1364 <caption>Function Type <span class="constant">undef</span> Characteristics</caption>
1368 <a name="calltype"><h2>API Function Calling Conventions</h2></a>
1370 <p>Standard UNIX code compiled by GCC (GNU C Compiler) running on host
1371 $gnulinux always uses @{[ a_href '#calltype_cdecl','cdecl' ]} ABI (Application
1372 Binary Interface) calling convention. This calling convention is also the
1373 default declaration type of UNIX functions.</p>
1375 <p>W32 uses three different calling conventions in its ABI. They are all
1377 <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_argument_passing_and_naming_conventions.asp"><span class="productname">Microsoft</span> documentation</a>.
1378 There is always necessary to have the proper function declaration
1379 (prototype) in the caller scope to prevent all sorts of unexpected
1382 <p>Unfortunately some non-matching combinations of calling conventions
1383 result in hard to debug bugs: the caller gets back an unexpected stack
1384 pointer from the callee and upon return it will restore registers from the
1385 wrong stack pointer place. Since the caller will finally reclaim its stack
1386 frame from its (uncorrupted) <span class="constant">EBP</span> stack frame
1387 pointer the caller will return to the caller of the caller correctly. Just
1388 the registers remain corrupted causing crashes of completely unrelated code
1389 executed far, far away...</p>
1391 <p><span class="constant">EDI</span>, <span class="constant">ESI</span> and
1392 <span class="constant">EBX</span> registers are always saved on the stack.
1393 They are stored on the stack in this particular order from bottom to top
1394 addresses (using the <span class="instruction">push EBX</span>,
1395 <span class="instruction">push ESI</span>,
1396 <span class="instruction">push EDI</span> sequence). Fortunately $gnulinux
1397 GCC has the same register saving behaviour. If some register corruption
1398 occurs the calling type presented between the caller and callee should be
1401 <a name="calltype_cdecl"><h3>W32 Calling Convention "cdecl"</h3></a>
1403 <p>The only calling convention in the UNIX world. The default one for all
1404 the compilers. All the arguments are passed on the stack, no arguments
1405 are cleaned by the callee. Possible inconsistencies in the number of
1406 function arguments with the function prototype used by the caller is
1407 harmless. Variable arguments lists can be passed by this convention.</p>
1409 @{[ doc_img 'fig/calltype_cdecl',
1410 'W32 Calling Convention <span class="constant">cdecl</span> Scheme' ]}
1412 <table border="1" align="center">
1413 <tr><td>Arguments freed by </td><td>caller</td></tr>
1414 <tr><td>Arguments on the stack </td><td>#0 ... #(n-1)</td></tr>
1415 <tr><td>Arguments in the registers </td><td>none</td></tr>
1416 <tr><td>GCC attribute </td><td><span class="command">__attribute__((__cdecl__))</span> (default)</td></tr>
1417 <caption>Calling Convention <span class="constant">cdecl</span> Characteristics</caption>
1420 <h3>W32 Calling Convention "stdcall"</h3>
1422 @{[ doc_img 'fig/calltype_stdcall',
1423 'W32 Calling Convention <span class="constant">stdcall</span> Scheme' ]}
1425 <p>Convention never used in the UNIX world. It needs to be specified for
1426 W32 compilers. All the arguments are passed on the stack, all the
1427 arguments are cleaned by the callee. Possible inconsistencies in the
1428 number of function arguments with the function prototype used by the
1429 caller will result in fatal crash. Variable arguments lists cannot be
1430 passed by this convention – use @{[ a_href '#calltype_cdecl','cdecl' ]}
1433 <table border="1" align="center">
1434 <tr><td>Arguments freed by </td><td>callee</td></tr>
1435 <tr><td>Arguments on the stack </td><td>#0 ... #(n-1)</td></tr>
1436 <tr><td>Arguments in the registers </td><td>none</td></tr>
1437 <tr><td>GCC attribute </td><td><span class="command">__attribute__((__stdcall__))</span></td></tr>
1438 <caption>Calling Convention <span class="constant">stdcall</span> Characteristics</caption>
1441 <h3>W32 Calling Convention "fastcall"</h3>
1443 <p>Convention never used in the UNIX world. It needs to be specified for
1444 W32 compilers. Convention used in the W32 world for its low calling
1445 overhead. All but the first two arguments are passed on the stack, such
1446 arguments are cleaned by the callee. First two arguments are passed in
1447 the registers <span class="constant">ECX</span> and
1448 <span class="constant">EDX</span> respectively. Possible inconsistencies
1449 in the number of function arguments with the function prototype used by
1450 the caller will result in fatal crash. Variable arguments lists cannot be
1451 passed by this convention – use @{[ a_href '#calltype_cdecl','cdecl' ]}
1454 <p>GCC (GNU C Compiler) native support for this calling convention
1455 is pretty fresh and it is currently present only in the recent CVS
1456 versions since 21st December of 2002 which should get released as GCC
1457 version 3.4. This project solved the unsupported calling convention by
1458 declaration of arguments passed in registers by
1459 <span class="command">__attribute__((__regparm__(3)))</span>.
1460 W32 passes the arguments in registers in the order
1461 <span class="constant">ECX</span>, <span class="constant">EDX</span> but
1462 GCC passes them in registers <span class="constant">EAX</span>,
1463 <span class="constant">EDX</span>, <span class="constant">ECX</span>.
1464 This incompatibility is compensated at C source level in the
1465 @{[ a_href '#functype','relaying code' ]} generated by
1466 <span class="fname">captivesym</span> relay generator.</p>
1468 @{[ doc_img 'fig/calltype_fastcall',
1469 'W32 Calling Convention <span class="constant">fastcall</span> Scheme' ]}
1471 <table border="1" align="center">
1472 <tr><td>Arguments freed by </td><td>callee</td></tr>
1473 <tr><td>Arguments on the stack </td><td>#2 ... #(n-1)</td></tr>
1474 <tr><td>Arguments in the registers </td><td><span class="constant">ECX</span>=#0,
1475 <span class="constant">EDX</span>=#1</td></tr>
1476 <tr><td>GCC ≥3.4 attribute </td><td><span class="command">__attribute__((__fastcall__))</span></td></tr>
1477 <tr><td>GCC <3.4 attr. emulation</td><td><span class="command">__attribute__((__stdcall__))</span></td></tr>
1478 <tr><td> </td><td><span class="command">__attribute__((__regparm__(3) /* EAX,EDX,ECX */))</span></td></tr>
1479 <caption>Calling Convention <span class="constant">fastcall</span> Characteristics</caption>
1482 <a name="synchronous"><h2>Multithreading and Multiple Processors</h2></a>
1484 <p>W32 platform stands on its thorough architecture parallelism. It
1485 must lock all its objects to maintain coherence in presence of
1486 multithreading and multiple processors. Since the author of this project
1487 considers any parallel execution a serious obstacle for debugging the whole
1488 project architecture was designed to prevent any undeterministic behaviour.
1489 Therefore this projects always emulates uniprocessor
1490 <span class="productname">Microsoft Windows NT</span> kernel
1491 (<span class="constant">KeNumberProcessors</span> symbol is always 1),
1492 everything runs in the single initial thread/process and all the filesystem
1493 operations are performed as synchronous
1494 ("synchronous" by flags
1495 <span class="constant">FILE_SYNCHRONOUS_IO_ALERT</span>,
1496 <span class="constant">FO_SYNCHRONOUS_IO</span>,
1497 <span class="constant">IRP_SYNCHRONOUS_API</span>,
1498 <span class="constant">IRP_SYNCHRONOUS_PAGING_IO</span>,
1499 forced <span class="constant">TRUE</span> result of
1500 <span class="function">IoIsOperationSynchronous()</span>
1502 For several cases needed only by <span class="fname">ntfs.sys</span> there
1503 had to be supported asynchronous access
1504 (<span class="constant">STATUS_PENDING</span> return code) – parallel
1505 execution is emulated by GLib
1506 <span class="function">g_idle_add_full()</span> with
1507 <span class="function">g_main_context_iteration()</span> called during
1508 <span class="function">KeWaitForSingleObject()</span>.</p>
1509 Since there is a possibility a real W32 parallel threading would
1510 be yet needed in the future all the code that would be hit by W32
1511 multithreading capability is marked by
1512 <span class="constant">TODO:thread</span> comment.</p>
1514 <p>Multiple processors (SMP) support will never need to be implemented
1515 since uniprocessor W32 kernels apparently run the filesystem driver modules
1516 fine. As this project implements only the uniprocessor W32 kernel all the
1517 processor locking functions and structures such as
1518 <span class="constant">KSPIN_LOCK</span> etc. can be safely implemented as
1521 <p>Asynchronous callbacks registered for
1522 <span class="constant">IO_WORKITEM</span>s are passed as GLib idle
1523 functions by <span class="function">g_idle_add_full()</span>. Although they
1524 will probably never be executed during non-interactive project's batch
1525 executions it is the responsibility of W32 driver implementation to
1526 complete all the pending tasks before its W32 shutdown. Such W32 shutdown
1527 is done during cleanup of the project's execution by
1528 <span class="function">captive_shutdown()</span>.</p>
1530 <a name="paranoia"><h2>Paranoia Checks</h2></a>
1532 <p>A general approach of software projects development is to implement
1533 many internal sanity checks during the development stage but to produce the
1534 most optimized final release product without those debugging checks.</p>
1536 <p>Facilities for these practices can be seen in the standard
1537 C include files for example as function
1538 <span class="function">assert()</span> which gets disabled by the
1539 <span class="constant">NDEBUG</span> symbol used during the final optimized
1540 executable compilation. This project uses Gnome GLib messaging subsystem
1541 offering sanity checks discarded by symbols
1542 <span class="constant">G_DISABLE_ASSERT</span> and
1543 <span class="constant">G_DISABLE_CHECKS</span>.
1544 <span class="productname">Microsoft</span> also produces two versions of
1545 its products – regular customers use the "free build" (also
1546 called "retail") while the programmers should develop their code
1547 on the "checked build" product releases.</p>
1549 <p>As this project will always run unknown binary code of proprietary W32
1550 filesystem drivers, the code can never be trusted. Such code even runs in
1551 the same unprotected address space as its controlling UNIX code. Since
1552 there is not enough documentation for the W32 components of the system and
1553 also such documentation is usually misleading it can never be considered as
1554 100% emulation. Even in the final releases all the sanity checks
1555 implemented in this project should remain active as all the project's code
1556 always interacts with unknown and untrusted W32 binaries.</p>
1558 <p><span class="productname">Microsoft Windows NT</span> code is written in
1559 a foolproof style as it accepts even invalid input values, and which
1560 it usually corrects. This makes long-term debugging a pain as it hides
1561 sources of problems. "Checked build" releases were probably
1562 designed to fix this flaw by strict consistency checks but it did not reach
1563 its goals as such checks are usually missing in the code.</p>
1565 <p>This project has strict consistency checks across all the code to make
1566 the debugging phase easy enough. Failed sanity check is not always
1567 a bug – sometimes it just means the real W32 binary code is more
1568 benevolent than it could be expected according to the documentation and
1569 such sanity check gets removed for the next version build. In other cases
1570 the failed sanity checks mean the execution path for some unexpected
1571 arguments combination was not yet implemented by this project. I may also
1572 mean a bug, of course...</p>
1574 <p>Last but not least – never miss a possible sanity check as its
1575 later removal is in an order of magnitude cheaper than an uncaught
1576 invalid assumption. Failed assertion is not always a bug although it
1577 has to be fixed, of course.</p>
1580 <h2>STATUS_LOG_FILE_FULL</h2>
1582 <p>After writing approx. 1MB of data on NTFS test partition NTFS driver
1583 returns for any further write requests
1584 <span class="constant">STATUS_LOG_FILE_FULL</status> error code.
1585 Apparently it is caused by the fact this project is
1586 @{[ a_href '#synchronous','single-threaded' ]} and it ignores the spawn
1587 of parallel journalling thread during <span class="fname">ntfs.sys</span>
1590 <p>Fortunately <span class="fname">ntfs.sys</span> will clear its
1591 journalling log file during filesystem unmount. This project will therefore
1592 remount the volume if <span class="constant">STATUS_LOG_FILE_FULL</status>
1593 is detected to workaround missing journalling thread.</p>
1595 <p>Similiar behaviour can be seen during write of compressed files —
1596 the file gets written uncompressed and its compression will proceed only
1597 during the final filesystem unmount.</p>
1599 <p>For these reasons it was mandatory to support
1600 @{[ a_href '#parent_connector','transparent volume remounting' ]}.</p>
1603 <a name="parent_connector"><h2><span class="constant">ParentConnector</span> volume remounter</h2></a>
1605 <p>The sandbox master component of this project has control of restarting
1606 its sandbox slaves containing the W32 filesystem. Target goal of
1607 <span class="constant">ParentConnector</span> component is to transparently
1608 provide persistent view of files and directories over the sandboxed slaves
1609 being restarted.</p>
1611 <p>In the case of read-only operations it would be simple as we could only
1612 save our state of currently opened filesystem objects with their read
1613 file/directory offset. Write operations can be handled as the read-only
1614 ones as long as all the operations are successful. In the case of W32
1615 filesystem crash we loose all the past write operations. If we would redo
1616 all the write operations we could very easily invoke the same crash.
1617 Therefore we write:</p>
1619 <blockquote class="command">
1620 <p>Filesystem crash broke dirty object: FILE/PATH/NAME</p>
1623 <p>message to syslog and refuse any further operations with this
1626 @{[ doc_img 'dia/parent-connector','Parent Connector' ]}
1628 <p><span class="constant">HANDLE</span> represents W32 object open in
1629 existing W32 filesystem.<span class="constant">HANDLE</span> is created
1630 on-demand according to the saved state of the object (such as its
1631 pathname). Even the whole <span class="constant">VFS</span> sandbox slave
1632 is spawn on-demand if some object operation requests it.</p>
1634 <p>W32 filesystem crash can obviously occur at any moment - it generates
1635 @{[ a_href 'http://developer.gnome.org/doc/API/2.0/gobject/','GObject' ]}
1636 @{[ a_href 'http://developer.gnome.org/doc/API/2.0/gobject/gobject-Signals.html','signal' ]}
1637 <span class="constant">abort</span>. Successful filesystem unmount
1638 (even as the part of remount operation) must be first preceded by
1639 <span class="constant">detach</span> signal to close all existing
1640 W32 <span class="constant">HANDLE</span>s. After their close the filesystem
1641 gets the unmount requests. Only in the case all the close operations
1642 succeeded including the final filesystem unmount the signal
1643 <span class="constant">cease</span> can be activated to notify all the
1644 dirty (written) objects they are now clean. During this
1645 <span class="constant">cease</span> signal the project will also
1646 @{[ a_href '#safe_flush','flush' ]} the sandbox commit buffer to its
1647 underlying media.</p>
1649 <p>Objects never written remain in <span class="constant">clean</span>
1650 state and they can be transparently reopened even if W32 filesystem crash
1654 <h1>TODO: Fsck of NTFS</h1>
1656 <p>Currently this project does not support checking of data structures
1657 of NTFS volume as being provided by <span class="command">chkdsk.exe</span>
1658 in W32 environment and <span class="command">fsck</span> in UNIX OS.</p>
1660 <p>W32 has its disk checking functionality split to
1661 <span class="fname">untfs.dll</span> W32 userland library.
1663 @{[ a_href 'http://www.sysinternals.com/ntw2k/source/fmifs.shtml',
1664 'Chkdskx and Formatx' ]}
1665 by @{[ a_href 'http://www.sysinternals.com/aboutus.shtml',
1666 'Mark Russinovich' ]}.
1668 <p>I assume its execution falls completely
1669 @{[ a_href '#existing_emulation','out of scope' ]}
1670 of this project as it is W32 userland.</p>
1672 <p>This possibility was not yet investigated in any way.</p>
1675 <h1>TODO: NTFS Support for
1676 <span class="productname">@{[ a_href 'http://surprise.sourceforge.net/','Partition Surprise' ]}</span></h1>
1678 <p>Although there currently exists
1679 <span class="productname">@{[ a_href 'http://mlf.linux.rulez.org/mlf/ezaz/ntfsresize.html','ntfsresize' ]}</span>
1680 I am not sure whether it is really reliable for all NTFS filesystems.
1681 <span class="productname">@{[ a_href 'http://surprise.sourceforge.net/','Partition Surprise' ]}</span>
1682 is the only partition manager capable of safely resize the disk
1683 by using just the original W32 filesystem driver by full rebuild of
1684 filesystem metadata.
1685 Almost no file data blocks would be moved even on these generic filesystems
1686 as W32 supports <span class="constant">FSCTL_MOVE_FILE</span> request
1688 @{[ a_href 'http://www.sysinternals.com/ntw2k/info/defrag.shtml',
1689 'Inside Windows NT Disk Defragmenting' ]}
1690 by @{[ a_href 'http://www.sysinternals.com/aboutus.shtml',
1691 'Mark Russinovich' ]}.
1694 <h1>Related Projects</h1>
1696 <p>The usual solution for file exchange between $freespeech operating systems
1697 and <span class="productname">Microsoft Windows NT</span> is to use
1698 <span class="productname">FAT32</span> (<span class="productname">vfat</span>
1699 called in $gnulinux) partition and swap the files over it. This method is not
1700 very comfortable as you never have access to all the files of the other
1701 operating system.</p>
1703 <a name="LinuxNTFScompet"><h2>$LinuxNTFS</h2></a>
1705 <p>Although this project takes a completely different approach and has
1706 a different architecture, the final goal is the same as for this
1707 project – reliable read-write <span class="productname">NTFS</span>
1708 filesystem support. $LinuxNTFS goes the way of reverse engineering
1709 filesystem data structures (and possibly
1710 <span class="fname">ntfs.sys</span> itself). Unfortunately after many years
1711 of its development it did not yet reach the state of reliable read-write
1712 access although its read-only part is considered trustworthy.</p>
1714 <p>Using $LinuxNTFS for read-only access to existing partition with
1715 <span class="productname">Microsoft Windows NT</span> installation is
1716 planned to be able to acquire existing <span class="fname">ntfs.sys</span>,
1717 <span class="fname">ntoskrnl.exe</span> and possibly
1718 <span class="fname">ksecdd.sys</span> (imported by
1719 <span class="fname">ntfs.sys</span>) files from the user's
1720 <span class="productname">NTFS</span> partition.</p>
1722 <h2><span class="productname">@{[ a_href 'http://www.cgsecurity.org/ntfs.html','NTPwd NTFS Driver' ]}</span></h2>
1724 <p>DOS based @{[ a_href 'http://www.gnu.org/licenses/gpl.html','GPL-2.0' ]}
1725 read-write NTFS driver. Filesystem structures are reverse engineered in the
1726 way of @{[ a_href '#LinuxNTFScompet','Linux-NTFS Project' ]}. As it is not very
1727 actively maintained it reaches a lower level of
1728 <span class="productname">NTFS</span> compatibility.</p>
1730 <h2>The only real competition: Closed-source read/write @{[ '$299' ]} equivalent</h2>
1732 <p>@{[ a_href 'http://www.vmware.com/download/workstation.html',
1733 'VMware Workstation' ]}</p>
1735 <p>Original Microsoft Windows operating system can be run inside a virtual
1736 machine running under GNU/Linux and share the read-write NTFS disk by using
1737 a network file sharing through a VMware virtual network card.</p>
1739 <p>You need @{[ '$299' ]} for this product and you need to
1740 give up your system security by running un@{[ a_href '#sandbox','sandbox' ]}ed
1741 closed-source program in your GNU/Linux.</p>
1743 <h2>@{[ a_href 'http://www.winehq.com/','Wine Project' ]}</h2>
1745 <p>No code could be shared – Wine emulates only Microsoft Windows userland.
1746 Filesystem drivers completely belong to Microsoft Windows kernelland.</p>
1748 <h2>@{[ a_href 'http://www.sysinternals.com/ntw2k/freeware/ntfswin98.shtml','NTFS for Windows 98' ]}</h2>
1750 <p>Closed-source read-only-crippled @{[ '$0' ]} equivalent for Microsoft Windows.</p>
1752 <p>There is a @{[ a_href 'http://www.sysinternals.com/images/screenshots/ntfs98ap.gif',
1753 'diagram' ]} showing exactly the principle of Captive NTFS project.
1754 There is apparently disabled read/write functionality in <i>NTFS for
1755 Windows 98</i> as the same company also sells the following product sharing
1756 the same codebase:</p>
1758 <h2>@{[ a_href 'http://www.winternals.com/products/repairandrecovery/ntfsdospro.asp','NTFSDOS Professional' ]}</h2>
1760 <p>Closed-source read/write @{[ '$299' ]} equivalent for MS-DOS.</p>
1762 <p>This product is the most close equivalent to Captive NTFS but it is
1763 a commercial product, closed-source and it has filesystem interface only
1767 <h1>Re: @{[ a_href 'http://linux-ntfs.sourceforge.net/info/ntfs.html#7.7',
1768 "7.7 Can't we write a wrapper for Windows' driver?" ]}</h1>
1770 <p class="re">> It sounds like a great idea, to start with, but there are numerous
1773 <p><span class="re">> The largest technical problem is joining the Windows
1774 system DLL to the Linux VFS. It could be done, but it wouldn't be pretty.</span><br />
1777 <p><span class="re">> It would have to run as part of the kernel which would mean
1778 that if it went wrong it could crash the machine. With no source, we might not
1779 be able to work around the problem.</span><br />
1780 @{[ a_href '#sandbox','Nope' ]},
1781 @{[ a_href 'http://lufs.sourceforge.net/lufs/','Linux Userland File System (LUFS)' ]}
1782 moves the filesystem implementation to UNIX userland where the Microsoft
1783 Windows filesystem is completely unarmed by Captive jail of chroot(2),
1784 setuid(2) and setrlimit(2). There only remains one narrow connection to the rest of
1785 system (by CORBA/ORBit). The filesystem's life environment gets kill(2)ed when
1786 UNIX is no longer satisfied with it. Safety similiar to
1787 @{[ a_href 'http://www.vmware.com/solutions/security.html','VMware sandbox' ]}.</p>
1789 <p><span class="re">> The next major problem is compati<!--orig. text typo-->bility.
1790 Which version of the Windows system file would we use? Picking one would limit
1791 its use, making the wrapper versatile for all of them would be a programming
1792 nightmare.</span><br />
1793 Microsoft Windows NTFS filesystem driver is capable of accessing older formats
1794 of the filesystem. This project currently runs Microsoft Windows XP version,
1795 porting to Microsoft Windows 2003 Server expected. (Microsoft Windows upgrades
1796 NTFS disk filesystem to its own version during complete CD-ROM Microsoft
1797 Windows system installation – such operation is not threat this project use.)</p>
1799 <p><span class="re">> And it gets worse. The legal implications of
1800 distributing Windows systems files would cause problems.</span><br />
1801 User must be careful to obey all licensing restrictions according to his
1802 local country laws.<br />
1803 <span class="re">> Also the proprietary nature of the driver would mean that
1804 the other kernel coders would not investigate any problems if someone had used
1805 the NTFS wrapper.</span><br />
1806 It does not apply to this project due to the implemented
1807 @{[ a_href '#sandbox','filesystem separation' ]}.</p>