Fixed LSN flushing typo.
[captive.git] / src / libcaptive / cc / io.c
1 /* $Id$
2  * reactos Cache Manager (Cc*) I/O W32 interface of libcaptive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "io.h" /* self */
23 #include <glib/gmessages.h>
24 #include "reactos/ddk/mmfuncs.h"
25 #include "reactos/ddk/kefuncs.h"
26 #include "reactos/ddk/iofuncs.h"
27
28
29 ULONG captive_Cc_IoPageRead(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset)
30 {
31 MDL *Mdl;
32 KEVENT Event;
33 IO_STATUS_BLOCK IoStatus;
34 NTSTATUS err;
35
36         g_return_val_if_fail(FileObject!=NULL,0);
37         g_return_val_if_fail(address!=0,0);
38         g_return_val_if_fail(length!=0,0);
39         g_return_val_if_fail(FileOffset!=NULL,0);
40
41         /* VolumeRead on ext2fsd.sys will return IoStatus.Information==0 although it
42          * successfuly read the data. Workaround it - preclear (not postclear) the
43          * buffer and do not make any other assumptions about the data read.
44          */
45         memset(address,0,length);       /* pre-clear the buffer */
46         Mdl=MmCreateMdl(NULL,address,length);   /* FIXME: Deprecated in favor of IoAllocateMdl() */
47         g_assert(Mdl!=NULL);
48         MmBuildMdlForNonPagedPool(Mdl);
49         KeInitializeEvent(&Event,NotificationEvent,FALSE);
50         IoStatus.Information=0; /* preventive pre-clear for buggy filesystems */
51         err=IoPageRead(FileObject,Mdl,FileOffset,&Event,&IoStatus);
52         g_assert(NT_SUCCESS(err));
53         g_assert(NT_SUCCESS(IoStatus.Status));
54         /* It is not == as the file may be shorter than requested */
55         g_assert(IoStatus.Information<=length);
56         IoFreeMdl(Mdl);
57
58         /* Forbidden, see the comment above about ext2fsd.sys.
59          * memset(((char *)address)+IoStatus.Information,0,(length-IoStatus.Information));
60          */
61
62         return IoStatus.Information;    /* may be shorter than real! */
63 }
64
65
66 void captive_Cc_IoPageWrite(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset)
67 {
68 MDL *Mdl;
69 KEVENT Event;
70 IO_STATUS_BLOCK IoStatus;
71 NTSTATUS err;
72
73         /* We can get 0=='FileObject->DeviceObject->SectorSize' during mount of ext2fsd.sys.
74          * We are unable to find the correct sectorsize for a filesystem as
75          * even the 'CommonFcb' below contains invalid information.
76          * As we need to have sectorsize <=filesystem_blocksize at least for ext2fsd.sys
77          * we choose PAGE_SIZE - the maximum libcaptive can with its design and also the maximum
78          * size ever needed for ext2fsd.sys (PAGE_SIZE is the maximum ext2 block size).
79          */
80
81         Mdl=MmCreateMdl(NULL,address,length);
82         g_assert(Mdl!=NULL);
83         MmBuildMdlForNonPagedPool(Mdl);
84
85         KeInitializeEvent(&Event,NotificationEvent,FALSE);
86
87         /* Use rather IoSynchronousPageWrite() than IoPageWrite() to prevent STATUS_PENDING. */
88         err=IoSynchronousPageWrite(FileObject,Mdl,FileOffset,&Event,&IoStatus);
89         g_assert(NT_SUCCESS(err));
90         g_assert(NT_SUCCESS(IoStatus.Status));
91
92         /* Also we can get just value 0 if the write is considered 'not dirty'
93          * during FAT write by fastfat.sys.
94          * We can also get just value 8 during write of PAGE_SIZE aligned block
95          * of MappedLength 512 during flush of LSNed buffer on captive_leave(),
96          * probably no assumptions can be made about the returned value at all.
97          */
98 #if 0
99         g_assert(IoStatus.Information==0 || IoStatus.Information>=CAPTIVE_ROUND_DOWN_EXCEEDING(address,PAGE_SIZE)+length);
100 #endif
101         g_assert(IoStatus.Information<=length);
102 }