/* $Id$ * reactos Cache Manager (Cc*) I/O W32 interface of libcaptive * Copyright (C) 2003 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; exactly version 2 of June 1991 is required * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "io.h" /* self */ #include #include "reactos/ddk/mmfuncs.h" #include "reactos/ddk/kefuncs.h" #include "reactos/ddk/iofuncs.h" ULONG captive_Cc_IoPageRead(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset) { MDL *Mdl; KEVENT Event; IO_STATUS_BLOCK IoStatus; NTSTATUS err; g_return_val_if_fail(FileObject!=NULL,0); g_return_val_if_fail(address!=0,0); g_return_val_if_fail(length!=0,0); g_return_val_if_fail(FileOffset!=NULL,0); /* VolumeRead on ext2fsd.sys will return IoStatus.Information==0 although it * successfuly read the data. Workaround it - preclear (not postclear) the * buffer and do not make any other assumptions about the data read. */ memset(address,0,length); /* pre-clear the buffer */ Mdl=MmCreateMdl(NULL,address,length); /* FIXME: Deprecated in favor of IoAllocateMdl() */ g_assert(Mdl!=NULL); MmBuildMdlForNonPagedPool(Mdl); KeInitializeEvent(&Event,NotificationEvent,FALSE); IoStatus.Information=0; /* preventive pre-clear for buggy filesystems */ err=IoPageRead(FileObject,Mdl,FileOffset,&Event,&IoStatus); g_assert(NT_SUCCESS(err)); g_assert(NT_SUCCESS(IoStatus.Status)); /* It is not == as the file may be shorter than requested */ g_assert(IoStatus.Information<=length); IoFreeMdl(Mdl); /* Forbidden, see the comment above about ext2fsd.sys. * memset(((char *)address)+IoStatus.Information,0,(length-IoStatus.Information)); */ return IoStatus.Information; /* may be shorter than real! */ } void captive_Cc_IoPageWrite(FILE_OBJECT *FileObject,gpointer address,ULONG length,LARGE_INTEGER *FileOffset) { MDL *Mdl; KEVENT Event; IO_STATUS_BLOCK IoStatus; NTSTATUS err; /* We can get 0=='FileObject->DeviceObject->SectorSize' during mount of ext2fsd.sys. * We are unable to find the correct sectorsize for a filesystem as * even the 'CommonFcb' below contains invalid information. * As we need to have sectorsize <=filesystem_blocksize at least for ext2fsd.sys * we choose PAGE_SIZE - the maximum libcaptive can with its design and also the maximum * size ever needed for ext2fsd.sys (PAGE_SIZE is the maximum ext2 block size). */ Mdl=MmCreateMdl(NULL,address,length); g_assert(Mdl!=NULL); MmBuildMdlForNonPagedPool(Mdl); KeInitializeEvent(&Event,NotificationEvent,FALSE); /* Use rather IoSynchronousPageWrite() than IoPageWrite() to prevent STATUS_PENDING. */ err=IoSynchronousPageWrite(FileObject,Mdl,FileOffset,&Event,&IoStatus); g_assert(NT_SUCCESS(err)); g_assert(NT_SUCCESS(IoStatus.Status)); /* Also we can get just value 0 if the write is considered 'not dirty' * during FAT write by fastfat.sys. * We can also get just value 8 during write of PAGE_SIZE aligned block * of MappedLength 512 during flush of LSNed buffer on captive_leave(), * probably no assumptions can be made about the returned value at all. */ #if 0 g_assert(IoStatus.Information==0 || IoStatus.Information>=CAPTIVE_ROUND_DOWN_EXCEEDING(address,PAGE_SIZE)+length); #endif g_assert(IoStatus.Information<=length); }