2 * reactos Cache Manager (Cc*) I/O W32 interface of libcaptive
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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"
29 ULONG captive_Cc_IoPageRead(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset)
33 IO_STATUS_BLOCK IoStatus;
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);
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.
45 memset(address,0,length); /* pre-clear the buffer */
46 Mdl=MmCreateMdl(NULL,address,length); /* FIXME: Deprecated in favor of IoAllocateMdl() */
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);
58 /* Forbidden, see the comment above about ext2fsd.sys.
59 * memset(((char *)address)+IoStatus.Information,0,(length-IoStatus.Information));
62 return IoStatus.Information; /* may be shorter than real! */
66 void captive_Cc_IoPageWrite(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset)
70 IO_STATUS_BLOCK IoStatus;
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).
81 Mdl=MmCreateMdl(NULL,address,length);
83 MmBuildMdlForNonPagedPool(Mdl);
85 KeInitializeEvent(&Event,NotificationEvent,FALSE);
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));
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.
99 g_assert(IoStatus.Information==0 || IoStatus.Information>=CAPTIVE_ROUND_DOWN_EXCEEDING(address,PAGE_SIZE)+length);
101 g_assert(IoStatus.Information<=length);