diff --git a/reactos/Makefile b/reactos/Makefile index 8aad6102a42..d3e3daf42bf 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -61,7 +61,7 @@ APPS = args hello test cat bench apc shm lpc thread event file gditest \ # objdir #NET_APPS = ping roshttpd -NET_APPS = ping roshttpd +NET_APPS = ping KERNEL_SERVICES = $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS) $(NET_DEVICE_DRIVERS) diff --git a/reactos/apps/utils/net/roshttpd/common/list.cpp b/reactos/apps/utils/net/roshttpd/common/list.cpp index 6f03924cb7d..29c6912cf55 100644 --- a/reactos/apps/utils/net/roshttpd/common/list.cpp +++ b/reactos/apps/utils/net/roshttpd/common/list.cpp @@ -34,7 +34,7 @@ CListNode::CListNode(PVOID element, CListNode *next, CListNode *prev) Prev = prev; } -PVOID CListNode::operator new(/*size_t*/ UINT size) +void* CListNode::operator new(/*size_t*/ UINT size) { PVOID p; if (hHeap == NULL) { @@ -47,7 +47,7 @@ PVOID CListNode::operator new(/*size_t*/ UINT size) return p; } -VOID CListNode::operator delete(PVOID p) +VOID CListNode::operator delete(void* p) { if (HeapFree(hHeap, 0, p) != FALSE) nRef--; diff --git a/reactos/apps/utils/net/roshttpd/httpd.cpp b/reactos/apps/utils/net/roshttpd/httpd.cpp index f3d357a398f..2ab38c88471 100644 --- a/reactos/apps/utils/net/roshttpd/httpd.cpp +++ b/reactos/apps/utils/net/roshttpd/httpd.cpp @@ -162,11 +162,12 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename) CHAR str[255]; CHAR str2[32]; union BigNum { - unsigned __int64 Big; + // unsigned __int64 Big; + unsigned long long Big; struct { DWORD Low; DWORD High; - }; + } u; } nTotalBytes; DWORD nBytesToRead; DWORD nBytesRead; @@ -186,8 +187,8 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename) return; } // Get file size - nTotalBytes.Low = GetFileSize(hFile, &nTotalBytes.High); - if ((nTotalBytes.Low == 0xFFFFFFFF) && ((GetLastError()) != NO_ERROR)) { + nTotalBytes.u.Low = GetFileSize(hFile, &nTotalBytes.u.High); + if ((nTotalBytes.u.Low == 0xFFFFFFFF) && ((GetLastError()) != NO_ERROR)) { // Internal server error Report("500 Internal Server Error", HttpMsg500); // Close file @@ -217,7 +218,7 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename) SendText("Content-Type: text/plain"); SendText("Accept-Ranges: bytes"); strcpy(str, "Content-Length: "); - _itoa(nTotalBytes.Low, str2, 10); + _itoa(nTotalBytes.u.Low, str2, 10); strcat(str, str2); SendText(str); SendText(""); diff --git a/reactos/apps/utils/net/roshttpd/include/httpd.h b/reactos/apps/utils/net/roshttpd/include/httpd.h index ef75591d5c8..d281c0c8a59 100644 --- a/reactos/apps/utils/net/roshttpd/include/httpd.h +++ b/reactos/apps/utils/net/roshttpd/include/httpd.h @@ -42,8 +42,10 @@ private: BOOL bStop; LPSTR lpsBuffer; LONG nBufferSize; - unsigned __int64 nTotalRead; - unsigned __int64 nFileSize; + // unsigned __int64 nTotalRead; + unsigned long long nTotalRead; + // unsigned __int64 nFileSize; + unsigned long long nFileSize; HANDLE hFile; }; typedef CHttpClient* LPCHttpClient; diff --git a/reactos/apps/utils/net/roshttpd/include/list.h b/reactos/apps/utils/net/roshttpd/include/list.h index 7a9963e456e..5f261f92291 100644 --- a/reactos/apps/utils/net/roshttpd/include/list.h +++ b/reactos/apps/utils/net/roshttpd/include/list.h @@ -14,8 +14,8 @@ public: CListNode(); CListNode(VOID *element, CListNode *next, CListNode *prev); ~CListNode() {}; - PVOID operator new(/*size_t s*/ UINT s); - VOID operator delete(PVOID p); + void* operator new(/*size_t s*/ UINT s); + VOID operator delete(void* p); VOID SetElement(PVOID element); VOID SetNext(CListNode *next); diff --git a/reactos/apps/utils/net/roshttpd/makefile b/reactos/apps/utils/net/roshttpd/makefile index 5cba8b05328..639bcaf7dd9 100644 --- a/reactos/apps/utils/net/roshttpd/makefile +++ b/reactos/apps/utils/net/roshttpd/makefile @@ -13,7 +13,8 @@ COMMON_OBJECTS = common/list.o common/socket.o common/thread.o OBJECTS = $(MAIN_OBJECTS) $(COMMON_OBJECTS) PROGS = $(TARGETNAME).exe LIBS = ../../../lib/kernel32/kernel32.a \ - ../../../lib/ws2_32/ws2_32.a + ../../../lib/ws2_32/ws2_32.a \ + ../../../lib/user32/user32.a ifeq ($(DOSCLI), yes) CLEAN_FILES = *.o $(TARGETNAME).exe $(TARGETNAME).sym common\*.o diff --git a/reactos/drivers/fs/vfat/blockdev.c b/reactos/drivers/fs/vfat/blockdev.c index a2d26dbb75d..cf8c290fc51 100644 --- a/reactos/drivers/fs/vfat/blockdev.c +++ b/reactos/drivers/fs/vfat/blockdev.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: services/fs/vfat/blockdev.c * PURPOSE: Temporary sector reading support - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: */ @@ -134,7 +134,7 @@ VfatWriteSectors (IN PDEVICE_OBJECT pDeviceObject, if (!NT_SUCCESS (Status)) { - DPRINT ("IO failed!!! VFATWriteSectors : Error code: %x\n", Status); + DPRINT1 ("IO failed!!! VFATWriteSectors : Error code: %x\n", Status); return (Status); } diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index 2ae22f8c775..367e2be289c 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.3 2000/12/29 23:17:12 dwelch Exp $ +/* $Id: close.c,v 1.4 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -28,7 +28,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) PVFATCCB pCcb; KIRQL oldIrql; - DPRINT ("FsdCloseFile(DeviceExt %x, FileObject %x)\n", + DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); //FIXME : update entry in directory ? @@ -65,7 +65,7 @@ VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; - DPRINT ("FsdClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); + DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); Status = VfatCloseFile (DeviceExtension, FileObject); diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index d564925a2ff..299f9a396e4 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.13 2001/01/12 21:00:08 dwelch Exp $ +/* $Id: create.c,v 1.14 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -150,7 +150,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) ULONG NextCluster; NTSTATUS Status; - Size = DeviceExt->rootDirectorySectors; //FIXME : in fat32, no limit + Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */ StartingSector = DeviceExt->rootStart; NextCluster = 0; @@ -183,7 +183,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) return (STATUS_UNSUCCESSFUL); } } - // not found in this sector, try next : + /* not found in this sector, try next : */ /* directory can be fragmented although it is best to keep them unfragmented */ @@ -192,7 +192,8 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb) { if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1)) { - Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster); + Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster, + FALSE); if (NextCluster == 0 || NextCluster == 0xffffffff) { *(Vpb->VolumeLabel) = 0; @@ -235,17 +236,11 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, CHECKPOINT; TempStr[0] = (WCHAR) '.'; TempStr[1] = 0; - FileToFind = (PWSTR) & TempStr; - } - if (Parent != NULL) - { - DPRINT ("Parent->entry.FirstCluster %d\n", Parent->entry.FirstCluster); + FileToFind = (PWSTR)&TempStr; } - DPRINT ("FindFile '%S'\n", FileToFind); if (Parent == NULL || Parent->entry.FirstCluster == 1) { - CHECKPOINT; Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */ StartingSector = DeviceExt->rootStart; NextCluster = 0; @@ -253,7 +248,6 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, || (FileToFind[0] == '.' && FileToFind[1] == 0)) { /* it's root : complete essentials fields then return ok */ - CHECKPOINT; memset (Fcb, 0, sizeof (VFATFCB)); memset (Fcb->entry.Filename, ' ', 11); Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE; @@ -261,7 +255,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, if (DeviceExt->FatType == FAT32) Fcb->entry.FirstCluster = 2; else - Fcb->entry.FirstCluster = 1; /* FIXME : is 1 the good value for mark root? */ + Fcb->entry.FirstCluster = 1; if (StartSector) *StartSector = StartingSector; if (Entry) @@ -286,13 +280,10 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, StartingSector = DeviceExt->rootStart; } } - CHECKPOINT; block = ExAllocatePool (NonPagedPool, BLOCKSIZE); - CHECKPOINT; if (StartSector && (*StartSector)) StartingSector = *StartSector; i = (Entry) ? (*Entry) : 0; - DPRINT ("FindFile : start at sector %lx, entry %ld\n", StartingSector, i); for (j = 0; j < Size; j++) { /* FIXME: Check status */ @@ -316,8 +307,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, { if (wstrcmpjoki (name, FileToFind)) { - /* In the case of a long filename, the firstcluster is stored in - the next record -- where it's short name is */ + /* In the case of a long filename, the firstcluster is + stored in the next record -- where it's short name is */ if (((FATDirEntry *) block)[i].Attrib == 0x0f) i++; if (i == (ENTRIES_PER_SECTOR)) @@ -354,7 +345,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, { if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1)) { - Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster); + Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster, + FALSE); if (NextCluster == 0 || NextCluster == 0xffffffff) { if (StartSector) @@ -379,7 +371,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, NTSTATUS -FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, +VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName) /* * FUNCTION: Opens a file @@ -400,7 +392,7 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, KIRQL oldIrql; ULONG BytesPerCluster; - DPRINT ("FsdOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName); + DPRINT ("VfatOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName); /* FIXME : treat relative name */ if (FileObject->RelatedFileObject) @@ -641,9 +633,12 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) DeviceExt = DeviceObject->DeviceExtension; assert (DeviceExt); - Status = FsdOpenFile (DeviceExt, FileObject, FileObject->FileName.Buffer); + Status = VfatOpenFile (DeviceExt, FileObject, FileObject->FileName.Buffer); - CHECKPOINT; + /* + * If the directory containing the file to open doesn't exist then + * fail immediately + */ Irp->IoStatus.Information = 0; if (Status == STATUS_OBJECT_PATH_NOT_FOUND) { @@ -651,23 +646,21 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) return Status; } - CHECKPOINT; if (!NT_SUCCESS (Status)) { - if (RequestedDisposition == FILE_CREATE - || RequestedDisposition == FILE_OPEN_IF - || RequestedDisposition == FILE_OVERWRITE_IF - || RequestedDisposition == FILE_SUPERSEDE) + /* + * If the file open failed then create the required file + */ + if (RequestedDisposition == FILE_CREATE || + RequestedDisposition == FILE_OPEN_IF || + RequestedDisposition == FILE_OVERWRITE_IF || + RequestedDisposition == FILE_SUPERSEDE) { CHECKPOINT; -#if 0 - Status = + Status = addEntry (DeviceExt, FileObject, RequestedOptions, (Stack->Parameters. Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS)); -#else - Status = STATUS_UNSUCCESSFUL; -#endif if (NT_SUCCESS (Status)) Irp->IoStatus.Information = FILE_CREATED; /* FIXME set size if AllocationSize requested */ @@ -680,13 +673,20 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) } else { + /* + * Otherwise fail if the caller wanted to create a new file + */ if (RequestedDisposition == FILE_CREATE) { Irp->IoStatus.Information = FILE_EXISTS; Status = STATUS_OBJECT_NAME_COLLISION; - } + } pCcb = FileObject->FsContext2; pFcb = pCcb->pFcb; + /* + * If requested then delete the file and create a new one with the + * same name + */ if (RequestedDisposition == FILE_SUPERSEDE) { ULONG Cluster, NextCluster; @@ -699,14 +699,18 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) Cluster = pFcb->entry.FirstCluster; pFcb->entry.FirstCluster = 0; pFcb->entry.FirstClusterHigh = 0; - // updEntry (DeviceExt, FileObject); + updEntry (DeviceExt, FileObject); while (Cluster != 0xffffffff && Cluster > 1) { - Status = GetNextCluster (DeviceExt, Cluster, &NextCluster); + Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE); // WriteCluster (DeviceExt, Cluster, 0); Cluster = NextCluster; } } + + /* + * Check the file has the requested attributes + */ if ((RequestedOptions & FILE_NON_DIRECTORY_FILE) && (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) { diff --git a/reactos/drivers/fs/vfat/dirwr.c b/reactos/drivers/fs/vfat/dirwr.c index 40ab5762946..e4bd9f1c8a6 100644 --- a/reactos/drivers/fs/vfat/dirwr.c +++ b/reactos/drivers/fs/vfat/dirwr.c @@ -1,4 +1,4 @@ -/* $Id: dirwr.c,v 1.15 2001/01/01 04:42:11 dwelch Exp $ +/* $Id: dirwr.c,v 1.16 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,7 +19,6 @@ #include "vfat.h" -#if 0 /* * Copies a file name into a directory slot (long file name entry) * and fills trailing slot space with 0xFFFF. This keeps scandisk @@ -127,7 +126,7 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) memset (&FileObject, 0, sizeof (FILE_OBJECT)); DPRINT ("open directory \'%S\' for update of entry \'%S\'\n", DirName, FileName); - status = FsdOpenFile (DeviceExt, &FileObject, DirName); + status = VfatOpenFile (DeviceExt, &FileObject, DirName); if (!NT_SUCCESS (status)) { DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, status); @@ -143,10 +142,10 @@ NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) { Buffer = ExAllocatePool (NonPagedPool, BLOCKSIZE); DPRINT ("update entry: sector %d, entry %d\n", Sector, Entry); - VFATReadSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); + VfatReadSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); pEntries = (FATDirEntry *) Buffer; memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry)); - VFATWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); + VfatWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer); ExFreePool (Buffer); } VfatCloseFile (DeviceExt, &FileObject); @@ -177,6 +176,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster; KIRQL oldIrql; LARGE_INTEGER SystemTime, LocalTime; + ULONG BytesPerCluster; + NTSTATUS Status; PathFileName = pFileObject->FileName.Buffer; DPRINT ("addEntry: Pathname=%S\n", PathFileName); @@ -194,7 +195,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, DirName[posCar] = 0; // open parent directory memset (&FileObject, 0, sizeof (FILE_OBJECT)); - status = FsdOpenFile (DeviceExt, &FileObject, DirName); + status = VfatOpenFile (DeviceExt, &FileObject, DirName); nbSlots = (NameLen + 12) / 13 + 1; //nb of entry needed for long name+normal entry DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots); Buffer = @@ -356,7 +357,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, { status = VfatReadFile (DeviceExt, &FileObject, &FatEntry, sizeof (FATDirEntry), - i * sizeof (FATDirEntry), &LengthRead); + i * sizeof (FATDirEntry), &LengthRead, FALSE); if (status == STATUS_END_OF_FILE) break; if (!NT_SUCCESS (status)) @@ -381,11 +382,11 @@ addEntry (PDEVICE_EXTENSION DeviceExt, if (RequestedOptions & FILE_DIRECTORY_FILE) { - CurrentCluster = GetNextWriteCluster (DeviceExt, 0); + NextCluster (DeviceExt, 0, &CurrentCluster, TRUE); // zero the cluster Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster); memset (Buffer2, 0, DeviceExt->BytesPerCluster); - VFATWriteCluster (DeviceExt, Buffer2, CurrentCluster); + VfatRawWriteCluster (DeviceExt, 0, Buffer2, CurrentCluster); ExFreePool (Buffer2); if (DeviceExt->FatType == FAT32) { @@ -400,7 +401,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, Offset = (i - nbSlots + 1) * sizeof (FATDirEntry); status = VfatWriteFile (DeviceExt, &FileObject, Buffer, - sizeof (FATDirEntry) * nbSlots, Offset); + sizeof (FATDirEntry) * nbSlots, Offset, FALSE); DPRINT ("VfatWriteFile() returned: %x\n", status); } else @@ -408,7 +409,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, Offset = (i - nbFree) * sizeof (FATDirEntry); status = VfatWriteFile (DeviceExt, &FileObject, Buffer, - sizeof (FATDirEntry) * (nbSlots + 1), Offset); + sizeof (FATDirEntry) * (nbSlots + 1), Offset, FALSE); } DPRINT ("write entry offset %d status=%x\n", Offset, status); newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB)); @@ -418,6 +419,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt, newCCB->pFcb = newFCB; newCCB->PtrFileObject = pFileObject; newFCB->RefCount++; + + BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE; + if (BytesPerCluster >= PAGESIZE) + { + Status = CcInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb, + BytesPerCluster); + } + else + { + Status = CcInitializeFileCache(pFileObject, &newFCB->RFCB.Bcb, + PAGESIZE); + } /* * FIXME : initialize all fields in FCB and CCB @@ -441,7 +454,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, memcpy (pEntry->Filename, ". ", 11); status = VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry), - 0L); + 0L, FALSE); pEntry->FirstCluster = ((VFATCCB *) (FileObject.FsContext2))->pFcb->entry.FirstCluster; pEntry->FirstClusterHigh = @@ -451,13 +464,12 @@ addEntry (PDEVICE_EXTENSION DeviceExt, pEntry->FirstCluster = 0; status = VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry), - sizeof (FATDirEntry)); + sizeof (FATDirEntry), FALSE); } VfatCloseFile (DeviceExt, &FileObject); ExFreePool (Buffer); DPRINT ("addentry ok\n"); return STATUS_SUCCESS; } -#endif /* EOF */ diff --git a/reactos/drivers/fs/vfat/fat.c b/reactos/drivers/fs/vfat/fat.c index 8be24e3cb7e..0f44447075c 100644 --- a/reactos/drivers/fs/vfat/fat.c +++ b/reactos/drivers/fs/vfat/fat.c @@ -1,5 +1,5 @@ /* - * $Id: fat.c,v 1.13 2001/01/14 15:05:53 dwelch Exp $ + * $Id: fat.c,v 1.14 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -109,24 +109,21 @@ Fat12GetNextCluster (PDEVICE_EXTENSION DeviceExt, * FUNCTION: Retrieve the next FAT12 cluster from the FAT table */ { - ULONG FATOffset; - ULONG Entry; - NTSTATUS Status; - PVOID BaseAddress; - BOOLEAN Valid; - PCACHE_SEGMENT CacheSeg; - UCHAR Value1, Value2; + unsigned char* CBlock; + ULONG FATOffset; + ULONG Entry; + BOOLEAN Valid; + PCACHE_SEGMENT CacheSeg; + NTSTATUS Status; + PVOID BaseAddress; - FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + ((CurrentCluster * 12) / 8); + *NextCluster = 0; - /* - * Get the page containing this offset - */ - Status = CcRequestCacheSegment(DeviceExt->StorageBcb, - PAGE_ROUND_DOWN(FATOffset), - &BaseAddress, - &Valid, - &CacheSeg); + Status = CcRequestCacheSegment(DeviceExt->Fat12StorageBcb, + 0, + &BaseAddress, + &Valid, + &CacheSeg); if (!NT_SUCCESS(Status)) { return(Status); @@ -134,106 +131,35 @@ Fat12GetNextCluster (PDEVICE_EXTENSION DeviceExt, if (!Valid) { Status = VfatReadSectors(DeviceExt->StorageDevice, - PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE, - PAGESIZE / BLOCKSIZE, - BaseAddress); + DeviceExt->FATStart, + DeviceExt->Boot->FATSectors, + BaseAddress); if (!NT_SUCCESS(Status)) { - CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, FALSE); + CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, FALSE); return(Status); } } - Value1 = ((PUCHAR)BaseAddress)[FATOffset % PAGESIZE]; - - /* - * A FAT12 entry may straggle two sectors - */ - if ((FATOffset + 1) == PAGESIZE) - { - CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); - Status = CcRequestCacheSegment(DeviceExt->StorageBcb, - PAGE_ROUND_DOWN(FATOffset) + PAGESIZE, - &BaseAddress, - &Valid, - &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - if (!Valid) - { - ULONG NextOffset; - - NextOffset = (PAGE_ROUND_DOWN(FATOffset) + PAGESIZE) / BLOCKSIZE; - Status = - VfatReadSectors(DeviceExt->StorageDevice, - NextOffset, - PAGESIZE / BLOCKSIZE, - BaseAddress); - if (!NT_SUCCESS(Status)) - { - CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, FALSE); - return(Status); - } - } - Value2 = ((PUCHAR)BaseAddress)[0]; - CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); - } - else - { - Value2 = ((PUCHAR)BaseAddress)[(FATOffset % PAGESIZE) + 1]; - CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); - } - + CBlock = (PUCHAR)BaseAddress; + + FATOffset = (CurrentCluster * 12) / 8; /* first byte containing value */ if ((CurrentCluster % 2) == 0) { - Entry = Value1; - Entry |= ((Value2 & 0xf) << 8); + Entry = CBlock[FATOffset]; + Entry |= ((CBlock[FATOffset+1] & 0xf)<<8); } else { - Entry = (Value1 >> 4); - Entry |= (Value2 << 4); + Entry = (CBlock[FATOffset] >> 4); + Entry |= (CBlock[FATOffset+1] << 4); } - DPRINT ("Entry %x\n", Entry); + DPRINT("Entry %x\n",Entry); if (Entry >= 0xff8 && Entry <= 0xfff) Entry = 0xffffffff; - DPRINT ("Returning %x\n", Entry); + DPRINT("Returning %x\n",Entry); *NextCluster = Entry; - return (STATUS_SUCCESS); -} - -NTSTATUS -GetNextCluster (PDEVICE_EXTENSION DeviceExt, - ULONG CurrentCluster, - PULONG NextCluster) -/* - * FUNCTION: Retrieve the next cluster depending on the FAT type - */ -{ - NTSTATUS Status; - - DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n", - DeviceExt, CurrentCluster); - - ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE); - - if (DeviceExt->FatType == FAT16) - { - Status = Fat16GetNextCluster (DeviceExt, CurrentCluster, NextCluster); - } - else if (DeviceExt->FatType == FAT32) - { - Status = Fat32GetNextCluster (DeviceExt, CurrentCluster, NextCluster); - } - else - { - Status = Fat12GetNextCluster (DeviceExt, CurrentCluster, NextCluster); - } - - ExReleaseResourceLite (&DeviceExt->FatResource); - - return (Status); + CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, TRUE); + return(STATUS_SUCCESS); } NTSTATUS @@ -256,16 +182,16 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, CacheSeg = NULL; *Cluster = 0; - for (i = 0; i < FatLength; i+=2) + for (i = 2; i < FatLength; i+=2) { - if ((i % PAGESIZE) == 0) + if (((FatStart + i) % PAGESIZE) == 0 || CacheSeg == NULL) { if (CacheSeg != NULL) { CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); } Status = CcRequestCacheSegment(DeviceExt->StorageBcb, - FatStart + i, + PAGE_ROUND_DOWN(FatStart + i), &BaseAddress, &Valid, &CacheSeg); @@ -276,7 +202,8 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, if (!Valid) { Status = VfatReadSectors(DeviceExt->StorageDevice, - (FatStart + i) / BLOCKSIZE, + PAGE_ROUND_DOWN(FatStart + i) + / BLOCKSIZE, PAGESIZE / BLOCKSIZE, BaseAddress); if (!NT_SUCCESS(Status)) @@ -287,13 +214,15 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, } } } - if (*((PUSHORT)(BaseAddress + (i % PAGESIZE))) == 0) + if (*((PUSHORT)(BaseAddress + ((FatStart + i) % PAGESIZE))) == 0) { + DPRINT1("Found available cluster 0x%x\n", i); *Cluster = i / 2; + CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); return(STATUS_SUCCESS); } } - + CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); return(STATUS_DISK_FULL); } @@ -303,14 +232,40 @@ FAT12FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster) * FUNCTION: Finds the first available cluster in a FAT12 table */ { - *Cluster = 0; - return(STATUS_UNSUCCESSFUL); - -#if 0 ULONG FATOffset; ULONG Entry; - PUCHAR CBlock = DeviceExt->FAT; + PUCHAR CBlock; ULONG i; + PVOID BaseAddress; + BOOLEAN Valid; + PCACHE_SEGMENT CacheSeg; + NTSTATUS Status; + + *Cluster = 0; + + Status = CcRequestCacheSegment(DeviceExt->Fat12StorageBcb, + 0, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (!Valid) + { + Status = VfatReadSectors(DeviceExt->StorageDevice, + DeviceExt->FATStart, + DeviceExt->Boot->FATSectors, + BaseAddress); + if (!NT_SUCCESS(Status)) + { + CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, FALSE); + return(Status); + } + } + CBlock = (PUCHAR)BaseAddress; + for (i = 2; i < ((DeviceExt->Boot->FATSectors * 512 * 8) / 12); i++) { FATOffset = (i * 12) / 8; @@ -325,12 +280,14 @@ FAT12FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster) Entry |= (CBlock[FATOffset + 1] << 4); } if (Entry == 0) - return (i); + { + DPRINT1("Found available cluster 0x%x\n", i); + *Cluster = i; + CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); + } } - /* Give an error message (out of disk space) if we reach here) */ - DbgPrint ("Disk full, %d clusters used\n", i); - return 0; -#endif + CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); + return (STATUS_DISK_FULL); } NTSTATUS @@ -474,14 +431,41 @@ FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, * FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables */ { - return(STATUS_UNSUCCESSFUL); - -#if 0 ULONG FATsector; ULONG FATOffset; - PUCHAR CBlock = DeviceExt->FAT; + PUCHAR CBlock; int i; + NTSTATUS Status; + PVOID BaseAddress; + BOOLEAN Valid; + PCACHE_SEGMENT CacheSeg; + + Status = CcRequestCacheSegment(DeviceExt->Fat12StorageBcb, + 0, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (!Valid) + { + Status = VfatReadSectors(DeviceExt->StorageDevice, + DeviceExt->FATStart, + DeviceExt->Boot->FATSectors, + BaseAddress); + if (!NT_SUCCESS(Status)) + { + CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, FALSE); + return(Status); + } + } + CBlock = (PUCHAR)BaseAddress; + FATOffset = (ClusterToWrite * 12) / 8; + DPRINT1("Writing 0x%x for 0x%x at 0x%x\n", + NewValue, ClusterToWrite, FATOffset); if ((ClusterToWrite % 2) == 0) { CBlock[FATOffset] = NewValue; @@ -515,7 +499,8 @@ FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, 1, CBlock + FATsector * 512); } } -#endif + CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); + return(STATUS_SUCCESS); } NTSTATUS @@ -535,10 +520,10 @@ FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, Start = DeviceExt->FATStart; + FATOffset = (Start * BLOCKSIZE) + (ClusterToWrite * 2); + for (i = 0; i < DeviceExt->Boot->FATCount; i++) - { - FATOffset = (Start * BLOCKSIZE) + (ClusterToWrite * 2); - + { Status = CcRequestCacheSegment(DeviceExt->StorageBcb, PAGE_ROUND_DOWN(FATOffset), &BaseAddress, @@ -560,11 +545,19 @@ FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, return(Status); } } - + + DPRINT1("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset, + ClusterToWrite); *((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))) = NewValue; + Status = VfatWriteSectors(DeviceExt->StorageDevice, + PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE, + PAGESIZE / BLOCKSIZE, + BaseAddress); CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE); - - Start = Start + DeviceExt->Boot->FATSectors; + + DPRINT1("DeviceExt->Boot->FATSectors %d\n", + DeviceExt->Boot->FATSectors); + FATOffset = FATOffset + DeviceExt->Boot->FATSectors * BLOCKSIZE; } return (STATUS_SUCCESS); @@ -629,77 +622,6 @@ WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite, return(Status); } -NTSTATUS -GetNextWriteCluster (PDEVICE_EXTENSION DeviceExt, - ULONG CurrentCluster, - PULONG NextCluster) -/* - * FUNCTION: Determines the next cluster to be written - */ -{ - ULONG LastCluster, NewCluster; - UCHAR *Buffer2; - NTSTATUS Status; - - DPRINT ("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n", - DeviceExt, CurrentCluster); - - *NextCluster = 0; - - /* Find out what was happening in the last cluster's AU */ - Status = GetNextCluster (DeviceExt, CurrentCluster, &LastCluster); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - /* Check to see if we must append or overwrite */ - if (LastCluster == 0xFFFFFFFF) - { - /* we are after last existing cluster : we must add one to file */ - /* Append */ - /* Firstly, find the next available open allocation unit */ - if (DeviceExt->FatType == FAT16) - { - Status = FAT16FindAvailableCluster (DeviceExt, &NewCluster); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - else if (DeviceExt->FatType == FAT32) - { - Status = FAT32FindAvailableCluster (DeviceExt, &NewCluster); - } - else - { - Status = FAT12FindAvailableCluster (DeviceExt, &NewCluster); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - /* Mark the new AU as the EOF */ - WriteCluster (DeviceExt, NewCluster, 0xFFFFFFFF); - /* Now, write the AU of the LastCluster with the value of the newly - found AU */ - WriteCluster (DeviceExt, CurrentCluster, NewCluster); - /* fill cluster with zero */ - Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster); - memset (Buffer2, 0, DeviceExt->BytesPerCluster); - VfatWriteCluster (DeviceExt, Buffer2, NewCluster); - ExFreePool (Buffer2); - /* Return NewCluster as CurrentCluster */ - *NextCluster = NewCluster; - return(STATUS_SUCCESS); - } - else - { - /* Overwrite: Return LastCluster as CurrentCluster */ - *NextCluster = LastCluster; - return(STATUS_SUCCESS); - } -} - ULONG ClusterToSector (PDEVICE_EXTENSION DeviceExt, unsigned long Cluster) /* @@ -745,7 +667,10 @@ VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt, } NTSTATUS -VfatWriteCluster (PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster) +VfatRawWriteCluster (PDEVICE_EXTENSION DeviceExt, + ULONG FirstCluster, + PVOID Buffer, + ULONG Cluster) /* * FUNCTION: Write a cluster to the physical device */ @@ -756,11 +681,134 @@ VfatWriteCluster (PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster) DPRINT ("VfatWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n", DeviceExt, Buffer, Cluster); - Sector = ClusterToSector (DeviceExt, Cluster); - - Status = VfatWriteSectors (DeviceExt->StorageDevice, - Sector, DeviceExt->Boot->SectorsPerCluster, - Buffer); + if (FirstCluster == 1) + { + Status = VfatWriteSectors (DeviceExt->StorageDevice, + Cluster, + DeviceExt->Boot->SectorsPerCluster, Buffer); + } + else + { + Sector = ClusterToSector (DeviceExt, Cluster); + + Status = VfatWriteSectors (DeviceExt->StorageDevice, + Sector, DeviceExt->Boot->SectorsPerCluster, + Buffer); + } return(Status); } +NTSTATUS +GetNextCluster (PDEVICE_EXTENSION DeviceExt, + ULONG CurrentCluster, + PULONG NextCluster, + BOOLEAN Extend) +/* + * FUNCTION: Retrieve the next cluster depending on the FAT type + */ +{ + NTSTATUS Status; + + DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n", + DeviceExt, CurrentCluster); + + if (Extend) + { + ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE); + } + else + { + ExAcquireResourceExclusiveLite (&DeviceExt->FatResource, TRUE); + } + + /* + * If the file hasn't any clusters allocated then we need special + * handling + */ + if (CurrentCluster == 0 && Extend) + { + ULONG NewCluster; + + if (DeviceExt->FatType == FAT16) + { + Status = FAT16FindAvailableCluster (DeviceExt, &NewCluster); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else if (DeviceExt->FatType == FAT32) + { + Status = FAT32FindAvailableCluster (DeviceExt, &NewCluster); + } + else + { + Status = FAT12FindAvailableCluster (DeviceExt, &NewCluster); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + /* Mark the new AU as the EOF */ + WriteCluster (DeviceExt, NewCluster, 0xFFFFFFFF); + *NextCluster = NewCluster; + ExReleaseResourceLite(&DeviceExt->FatResource); + return(STATUS_SUCCESS); + } + else if (CurrentCluster == 0) + { + ExReleaseResourceLite(&DeviceExt->FatResource); + return(STATUS_UNSUCCESSFUL); + } + + if (DeviceExt->FatType == FAT16) + { + Status = Fat16GetNextCluster (DeviceExt, CurrentCluster, NextCluster); + } + else if (DeviceExt->FatType == FAT32) + { + Status = Fat32GetNextCluster (DeviceExt, CurrentCluster, NextCluster); + } + else + { + Status = Fat12GetNextCluster (DeviceExt, CurrentCluster, NextCluster); + } + if (Extend && (*NextCluster) == 0xFFFFFFFF) + { + ULONG NewCluster; + + /* We are after last existing cluster, we must add one to file */ + /* Firstly, find the next available open allocation unit */ + if (DeviceExt->FatType == FAT16) + { + Status = FAT16FindAvailableCluster (DeviceExt, &NewCluster); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else if (DeviceExt->FatType == FAT32) + { + Status = FAT32FindAvailableCluster (DeviceExt, &NewCluster); + } + else + { + Status = FAT12FindAvailableCluster (DeviceExt, &NewCluster); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + /* Mark the new AU as the EOF */ + WriteCluster (DeviceExt, NewCluster, 0xFFFFFFFF); + /* Now, write the AU of the LastCluster with the value of the newly + found AU */ + WriteCluster (DeviceExt, CurrentCluster, NewCluster); + *NextCluster = NewCluster; + } + + ExReleaseResourceLite (&DeviceExt->FatResource); + + return (Status); +} + diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 1724131444d..b3605b00f29 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -1,4 +1,4 @@ -/* $Id: iface.c,v 1.48 2001/01/12 21:00:08 dwelch Exp $ +/* $Id: iface.c,v 1.49 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -157,6 +157,14 @@ VfatMount (PDEVICE_OBJECT DeviceToMount) Status = CcInitializeFileCache(DeviceExt->StreamStorageDevice, &DeviceExt->StorageBcb, PAGESIZE); + if (DeviceExt->FatType == FAT12) + { + DeviceExt->Fat12StorageDevice = + IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice); + Status = CcInitializeFileCache(DeviceExt->Fat12StorageDevice, + &DeviceExt->Fat12StorageBcb, + PAGESIZE * 3); + } ExInitializeResourceLite (&DeviceExt->DirResource); ExInitializeResourceLite (&DeviceExt->FatResource); diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index 721e91eb0bd..0b4a8603f28 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.18 2001/01/14 15:05:53 dwelch Exp $ +/* $Id: rw.c,v 1.19 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,7 +30,12 @@ NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, - PULONG CurrentCluster) + PULONG CurrentCluster, + BOOLEAN Extend) + /* + * Return the next cluster in a FAT chain, possibly extending the chain if + * necessary + */ { if (FirstCluster == 1) { @@ -41,7 +46,8 @@ NextCluster(PDEVICE_EXTENSION DeviceExt, { NTSTATUS Status; - Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster); + Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster, + Extend); return(Status); } } @@ -50,7 +56,12 @@ NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, ULONG FileOffset, - PULONG Cluster) + PULONG Cluster, + BOOLEAN Extend) + /* + * Return the cluster corresponding to an offset within a file, + * possibly extending the file if necessary + */ { ULONG CurrentCluster; ULONG i; @@ -68,7 +79,8 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt, CurrentCluster = FirstCluster; for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++) { - Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster); + Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster, + Extend); if (!NT_SUCCESS(Status)) { return(Status); @@ -79,6 +91,209 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt, } } +NTSTATUS +VfatReadBigCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, + ULONG StartOffset, + ULONG FirstCluster, + PULONG CurrentCluster, + PVOID Destination, + ULONG NoCache, + ULONG InternalOffset, + ULONG InternalLength) +{ + BOOLEAN Valid; + PVOID BaseAddress = NULL; + PCACHE_SEGMENT CacheSeg = NULL; + NTSTATUS Status; + + /* + * In this case the size of a cache segment is the same as a cluster + */ + + if (!NoCache) + { + Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, + StartOffset, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + Valid = FALSE; + if (InternalOffset == 0) + { + BaseAddress = Destination; + } + else + { + BaseAddress = ExAllocatePool(NonPagedPool, + DeviceExt->BytesPerCluster); + if (BaseAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + } + } + + if (!Valid) + { + /* + * If necessary read the cluster from the disk + */ + Status = VfatRawReadCluster(DeviceExt, FirstCluster, BaseAddress, + *CurrentCluster); + if (!NT_SUCCESS(Status)) + { + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(Status); + } + } + /* + * Copy the data from the cache to the caller + */ + memcpy(Destination, BaseAddress + InternalOffset, InternalLength); + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + + Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + return(STATUS_SUCCESS); +} + +NTSTATUS +VfatReadSmallCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, + ULONG StartOffset, + ULONG FirstCluster, + PULONG CurrentCluster, + PVOID Destination, + ULONG NoCache, + ULONG InternalOffset, + ULONG InternalLength) +{ + BOOLEAN Valid; + PVOID BaseAddress = NULL; + PCACHE_SEGMENT CacheSeg = NULL; + NTSTATUS Status; + ULONG i; + + /* + * Otherwise we read a page of clusters together + */ + if (!NoCache) + { + Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, + StartOffset, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + Valid = FALSE; + if (InternalOffset == 0) + { + BaseAddress = Destination; + } + else + { + BaseAddress = ExAllocatePool(NonPagedPool, PAGESIZE); + if (BaseAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + } + } + + /* + * If necessary read all the data for the page, unfortunately the + * file length may not be page aligned in which case the page will + * only be partially filled. + * FIXME: So zero fill the rest? + */ + if (!Valid) + { + for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) + { + Status = VfatRawReadCluster(DeviceExt, + FirstCluster, + BaseAddress + + (i * DeviceExt->BytesPerCluster), + *CurrentCluster); + if (!NT_SUCCESS(Status)) + { + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(Status); + } + Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE); + if ((*CurrentCluster) == 0xFFFFFFFF) + { + break; + } + } + } + else + { + /* + * Otherwise just move onto the next cluster + */ + for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) + { + NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE); + if ((*CurrentCluster) == 0xFFFFFFFF) + { + break; + } + } + } + /* + * Copy the data from the cache to the caller + */ + memcpy(Destination, BaseAddress + InternalOffset, InternalLength); + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(STATUS_SUCCESS); +} + NTSTATUS VfatReadCluster(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb, @@ -90,143 +305,29 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt, ULONG InternalOffset, ULONG InternalLength) { - ULONG BytesPerCluster; - BOOLEAN Valid; - PVOID BaseAddress; - PCACHE_SEGMENT CacheSeg; - NTSTATUS Status; - - BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE; - - if (BytesPerCluster >= PAGESIZE) + if (DeviceExt->BytesPerCluster >= PAGESIZE) { - /* - * In this case the size of a cache segment is the same as a cluster - */ - - if (!NoCache) - { - Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, - StartOffset, - &BaseAddress, - &Valid, - &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - else - { - Valid = FALSE; - } - if (!Valid) - { - /* - * If necessary read the cluster from the disk - */ - Status = VfatRawReadCluster(DeviceExt, FirstCluster, BaseAddress, - *CurrentCluster); - if (!NT_SUCCESS(Status)) - { - if (!NoCache) - { - CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); - } - return(Status); - } - } - /* - * Copy the data from the cache to the caller - */ - memcpy(Destination, BaseAddress + InternalOffset, InternalLength); - if (!NoCache) - { - CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); - } - - Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + return(VfatReadBigCluster(DeviceExt, + Fcb, + StartOffset, + FirstCluster, + CurrentCluster, + Destination, + NoCache, + InternalOffset, + InternalLength)); } else { - ULONG i; - - /* - * Otherwise we read a page of clusters together - */ - - if (!NoCache) - { - Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, - StartOffset, - &BaseAddress, - &Valid, - &CacheSeg); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - } - else - { - Valid = FALSE; - } - - /* - * If necessary read all the data for the page, unfortunately the - * file length may not be page aligned in which case the page will - * only be partially filled. - * FIXME: So zero fill the rest? - */ - if (!Valid) - { - for (i = 0; i < (PAGESIZE / BytesPerCluster); i++) - { - Status = VfatRawReadCluster(DeviceExt, - FirstCluster, - BaseAddress + (i * BytesPerCluster), - *CurrentCluster); - if (!NT_SUCCESS(Status)) - { - if (!NoCache) - { - CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); - } - return(Status); - } - Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster); - if ((*CurrentCluster) == 0xFFFFFFFF) - { - break; - } - } - } - else - { - /* - * Otherwise just move onto the next cluster - */ - for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) - { - NextCluster(DeviceExt, FirstCluster, CurrentCluster); - if ((*CurrentCluster) == 0xFFFFFFFF) - { - break; - } - } - } - /* - * Copy the data from the cache to the caller - */ - memcpy(Destination, BaseAddress + InternalOffset, InternalLength); - if (!NoCache) - { - CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); - } + return(VfatReadSmallCluster(DeviceExt, + Fcb, + StartOffset, + FirstCluster, + CurrentCluster, + Destination, + NoCache, + InternalOffset, + InternalLength)); } return(STATUS_SUCCESS); } @@ -282,7 +383,10 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Length = Fcb->entry.FileSize - ReadOffset; } } - + + /* + * Select an appropiate size for reads + */ if (DeviceExt->BytesPerCluster >= PAGESIZE) { ChunkSize = DeviceExt->BytesPerCluster; @@ -302,21 +406,21 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Status = OffsetToCluster(DeviceExt, FirstCluster, ROUND_DOWN(ReadOffset, ChunkSize), - &CurrentCluster); + &CurrentCluster, + FALSE); if (!NT_SUCCESS(Status)) { return(Status); } /* - * If the read doesn't begin on a cluster boundary then read a full - * cluster and copy it. + * If the read doesn't begin on a chunk boundary then we need special + * handling */ if ((ReadOffset % ChunkSize) != 0) { TempLength = min (Length, ChunkSize - (ReadOffset % ChunkSize)); - VfatReadCluster(DeviceExt, Fcb, - ROUND_DOWN(ReadOffset, ChunkSize), + VfatReadCluster(DeviceExt, Fcb, ROUND_DOWN(ReadOffset, ChunkSize), FirstCluster, &CurrentCluster, Buffer, NoCache, ReadOffset % ChunkSize, TempLength); @@ -331,10 +435,6 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, VfatReadCluster(DeviceExt, Fcb, ReadOffset, FirstCluster, &CurrentCluster, Buffer, NoCache, 0, ChunkSize); - if (CurrentCluster == 0xffffffff) - { - return (STATUS_SUCCESS); - } (*LengthRead) = (*LengthRead) + ChunkSize; Buffer = Buffer + ChunkSize; @@ -351,21 +451,324 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, return (STATUS_SUCCESS); } +NTSTATUS +VfatWriteBigCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, + ULONG StartOffset, + ULONG FirstCluster, + PULONG CurrentCluster, + PVOID Source, + ULONG NoCache, + ULONG InternalOffset, + ULONG InternalLength, + BOOLEAN Extend) +{ + BOOLEAN Valid; + PVOID BaseAddress; + PCACHE_SEGMENT CacheSeg; + NTSTATUS Status; + + /* + * In this case the size of a cache segment is the same as a cluster + */ + if (!NoCache) + { + Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, + StartOffset, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + Valid = FALSE; + /* + * If we are bypassing the cache and not writing starting on + * cluster boundary then allocate a temporary buffer + */ + if (InternalOffset != 0) + { + BaseAddress = ExAllocatePool(NonPagedPool, + DeviceExt->BytesPerCluster); + if (BaseAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + } + } + if (!Valid && InternalLength != DeviceExt->BytesPerCluster) + { + /* + * If the data in the cache isn't valid or we are bypassing the + * cache and not writing a cluster aligned, cluster sized region + * then read data in to base address + */ + Status = VfatRawReadCluster(DeviceExt, FirstCluster, BaseAddress, + *CurrentCluster); + if (!NT_SUCCESS(Status)) + { + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(Status); + } + } + if (!NoCache || InternalLength != DeviceExt->BytesPerCluster) + { + /* + * If we are writing into the cache or we are writing from a + * temporary buffer then copy the data over + */ + DPRINT1("InternalOffset 0x%x InternalLength 0x%x BA %x Byte1 %c\n", + InternalOffset, InternalLength, BaseAddress, *(PUCHAR)Source); + memcpy(BaseAddress + InternalOffset, Source, InternalLength); + } + /* + * Write the data back to disk + */ + DPRINT("Writing 0x%x\n", *CurrentCluster); + Status = VfatRawWriteCluster(DeviceExt, FirstCluster, BaseAddress, + *CurrentCluster); + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + + Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, Extend); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + return(STATUS_SUCCESS); +} + +NTSTATUS +VfatWriteSmallCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, + ULONG StartOffset, + ULONG FirstCluster, + PULONG CurrentCluster, + PVOID Source, + ULONG NoCache, + ULONG InternalOffset, + ULONG InternalLength, + BOOLEAN Extend) +{ + BOOLEAN Valid; + PVOID BaseAddress; + PCACHE_SEGMENT CacheSeg; + NTSTATUS Status; + ULONG NCluster; + ULONG i; + + /* + * Otherwise we read a page of clusters together + */ + + if (!NoCache) + { + Status = CcRequestCacheSegment(Fcb->RFCB.Bcb, + StartOffset, + &BaseAddress, + &Valid, + &CacheSeg); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + Valid = FALSE; + if (InternalOffset != 0) + { + BaseAddress = ExAllocatePool(NonPagedPool, PAGESIZE); + if (BaseAddress == NULL) + { + return(STATUS_NO_MEMORY); + } + } + else + { + BaseAddress = Source; + } + } + + /* + * If necessary read all the data for the page, unfortunately the + * file length may not be page aligned in which case the page will + * only be partially filled. + * FIXME: So zero fill the rest? + */ + if (!Valid || InternalLength != PAGESIZE) + { + NCluster = *CurrentCluster; + + for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) + { + Status = VfatRawReadCluster(DeviceExt, + FirstCluster, + BaseAddress + + (i * DeviceExt->BytesPerCluster), + NCluster); + if (!NT_SUCCESS(Status)) + { + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(Status); + } + Status = NextCluster(DeviceExt, FirstCluster, &NCluster, Extend); + if (NCluster == 0xFFFFFFFF) + { + break; + } + } + } + else + { + /* + * Otherwise just move onto the next cluster + */ + for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) + { + NextCluster(DeviceExt, FirstCluster, &NCluster, Extend); + if (NCluster == 0xFFFFFFFF) + { + break; + } + } + } + + if (!NoCache || InternalLength != PAGESIZE) + { + /* + * Copy the caller's data if we are using the cache or writing + * from temporary buffer + */ + memcpy(BaseAddress + InternalOffset, Source, InternalLength); + } + + /* + * Write the data to the disk + */ + NCluster = *CurrentCluster; + + for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++) + { + Status = VfatRawWriteCluster(DeviceExt, + FirstCluster, + BaseAddress + + (i * DeviceExt->BytesPerCluster), + NCluster); + if (!NT_SUCCESS(Status)) + { + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(Status); + } + Status = NextCluster(DeviceExt, FirstCluster, &NCluster, Extend); + if (NCluster == 0xFFFFFFFF) + { + break; + } + } + *CurrentCluster = NCluster; + + if (!NoCache) + { + CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE); + } + else if (InternalOffset != 0) + { + ExFreePool(BaseAddress); + } + return(STATUS_SUCCESS); +} + +NTSTATUS +VfatWriteCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, + ULONG StartOffset, + ULONG FirstCluster, + PULONG CurrentCluster, + PVOID Source, + ULONG NoCache, + ULONG InternalOffset, + ULONG InternalLength, + BOOLEAN Extend) +{ + + + if (DeviceExt->BytesPerCluster >= PAGESIZE) + { + return(VfatWriteBigCluster(DeviceExt, + Fcb, + StartOffset, + FirstCluster, + CurrentCluster, + Source, + NoCache, + InternalOffset, + InternalLength, + Extend)); + } + else + { + return(VfatWriteSmallCluster(DeviceExt, + Fcb, + StartOffset, + FirstCluster, + CurrentCluster, + Source, + NoCache, + InternalOffset, + InternalLength, + Extend)); + } +} + NTSTATUS VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, - PVOID Buffer, ULONG Length, ULONG WriteOffset) + PVOID Buffer, ULONG Length, ULONG WriteOffset, + ULONG NoCache) /* * FUNCTION: Writes data to file */ { ULONG CurrentCluster; - ULONG FileOffset; ULONG FirstCluster; PVFATFCB Fcb; PVFATCCB pCcb; - PVOID Temp; - ULONG TempLength, Length2 = Length; + ULONG TempLength; LARGE_INTEGER SystemTime, LocalTime; + ULONG ChunkSize; + NTSTATUS Status; + BOOLEAN Extend; DPRINT1 ("VfatWriteFile(FileObject %x, Buffer %x, Length %x, " "WriteOffset %x\n", FileObject, Buffer, Length, WriteOffset); @@ -376,6 +779,16 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, assert (pCcb); Fcb = pCcb->pFcb; assert (Fcb); + + if (DeviceExt->BytesPerCluster >= PAGESIZE) + { + ChunkSize = DeviceExt->BytesPerCluster; + } + else + { + ChunkSize = PAGESIZE; + } + if (DeviceExt->FatType == FAT32) { CurrentCluster = @@ -386,46 +799,33 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, CurrentCluster = Fcb->entry.FirstCluster; } FirstCluster = CurrentCluster; - - /* Allocate a buffer to hold 1 cluster of data */ - Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster); - assert (Temp); - + /* Find the cluster according to the offset in the file */ - if (CurrentCluster == 1) + if (CurrentCluster == 0) { - CurrentCluster = DeviceExt->rootStart + WriteOffset - / DeviceExt->BytesPerCluster * DeviceExt->Boot->SectorsPerCluster; - } - else - { - if (CurrentCluster == 0) + /* + * File of size zero + */ + Status = NextCluster (DeviceExt, FirstCluster, &CurrentCluster, + TRUE); + if (DeviceExt->FatType == FAT32) { - /* - * File of size zero - */ - // CurrentCluster = GetNextWriteCluster (DeviceExt, 0); - if (DeviceExt->FatType == FAT32) - { - Fcb->entry.FirstClusterHigh = CurrentCluster >> 16; - Fcb->entry.FirstCluster = CurrentCluster; - } - else - Fcb->entry.FirstCluster = CurrentCluster; + Fcb->entry.FirstClusterHigh = CurrentCluster >> 16; + Fcb->entry.FirstCluster = CurrentCluster; } else { - for (FileOffset = 0; - FileOffset < WriteOffset / DeviceExt->BytesPerCluster; - FileOffset++) - { -#if 0 - CurrentCluster = - GetNextWriteCluster (DeviceExt, CurrentCluster); -#endif - } + Fcb->entry.FirstCluster = CurrentCluster; } - CHECKPOINT; + FirstCluster = CurrentCluster; + } + Status = OffsetToCluster(DeviceExt, FirstCluster, WriteOffset, + &CurrentCluster, TRUE); + + if (WriteOffset + Length > Fcb->entry.FileSize && + !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) + { + Fcb->entry.FileSize = WriteOffset + Length; } /* @@ -433,137 +833,85 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, * then we have to write only from the specified offset */ - if ((WriteOffset % DeviceExt->BytesPerCluster) != 0) + if ((WriteOffset % ChunkSize) != 0) { - CHECKPOINT; - TempLength = min (Length, DeviceExt->BytesPerCluster - - (WriteOffset % DeviceExt->BytesPerCluster)); - /* Read in the existing cluster data */ - if (FirstCluster == 1) + TempLength = min (Length, ChunkSize - (WriteOffset % ChunkSize)); + if ((Length - TempLength) > 0) { - /* FIXME: Check status */ - VfatReadSectors (DeviceExt->StorageDevice, - CurrentCluster, - DeviceExt->Boot->SectorsPerCluster, Temp); + Extend = TRUE; } else { - VfatRawReadCluster (DeviceExt, FirstCluster, Temp, CurrentCluster); - } - - /* Overwrite the last parts of the data as necessary */ - memcpy (Temp + (WriteOffset % DeviceExt->BytesPerCluster), - Buffer, TempLength); - - /* Write the cluster back */ - Length2 -= TempLength; - if (FirstCluster == 1) - { - VfatWriteSectors (DeviceExt->StorageDevice, - CurrentCluster, - DeviceExt->Boot->SectorsPerCluster, Temp); - CurrentCluster += DeviceExt->Boot->SectorsPerCluster; - } - else - { - VfatWriteCluster (DeviceExt, Temp, CurrentCluster); -#if 0 - if (Length2 > 0) - CurrentCluster = GetNextWriteCluster (DeviceExt, CurrentCluster); -#endif + Extend = FALSE; } + Status = VfatWriteCluster(DeviceExt, + Fcb, + ROUND_DOWN(WriteOffset, ChunkSize), + FirstCluster, + &CurrentCluster, + Buffer, + NoCache, + WriteOffset % ChunkSize, + TempLength, + Extend); Buffer = Buffer + TempLength; + Length = Length - TempLength; + WriteOffset = WriteOffset + TempLength; } - CHECKPOINT; - /* Write the buffer in chunks of 1 cluster */ - - while (Length2 >= DeviceExt->BytesPerCluster) + while (Length >= ChunkSize) { - CHECKPOINT; - if (CurrentCluster == 0) + if ((Length - ChunkSize) > 0) { - ExFreePool (Temp); - return (STATUS_UNSUCCESSFUL); - } - Length2 -= DeviceExt->BytesPerCluster; - if (FirstCluster == 1) - { - VfatWriteSectors (DeviceExt->StorageDevice, - CurrentCluster, - DeviceExt->Boot->SectorsPerCluster, Buffer); - CurrentCluster += DeviceExt->Boot->SectorsPerCluster; + Extend = TRUE; } else { - VfatWriteCluster (DeviceExt, Buffer, CurrentCluster); -#if 0 - if (Length2 > 0) - CurrentCluster = GetNextWriteCluster (DeviceExt, CurrentCluster); -#endif + Extend = FALSE; } - Buffer = Buffer + DeviceExt->BytesPerCluster; + Status = VfatWriteCluster(DeviceExt, + Fcb, + ROUND_DOWN(WriteOffset, ChunkSize), + FirstCluster, + &CurrentCluster, + Buffer, + NoCache, + 0, + ChunkSize, + Extend); + Buffer = Buffer + ChunkSize; + Length = Length - ChunkSize; + WriteOffset = WriteOffset + ChunkSize; } - CHECKPOINT; /* Write the remainder */ - - if (Length2 > 0) + if (Length > 0) { - CHECKPOINT; - if (CurrentCluster == 0) - { - ExFreePool (Temp); - return (STATUS_UNSUCCESSFUL); - } - CHECKPOINT; - /* Read in the existing cluster data */ - if (FirstCluster == 1) - { - /* FIXME: Check status */ - VfatReadSectors (DeviceExt->StorageDevice, - CurrentCluster, - DeviceExt->Boot->SectorsPerCluster, Temp); - } - else - { - VfatRawReadCluster (DeviceExt, FirstCluster, Temp, CurrentCluster); - CHECKPOINT; - memcpy (Temp, Buffer, Length2); - CHECKPOINT; - if (FirstCluster == 1) - { - VfatWriteSectors (DeviceExt->StorageDevice, - CurrentCluster, - DeviceExt->Boot->SectorsPerCluster, Temp); - } - else - { - VfatWriteCluster (DeviceExt, Temp, CurrentCluster); - } - } - CHECKPOINT; + Status = VfatWriteCluster(DeviceExt, + Fcb, + ROUND_DOWN(WriteOffset, ChunkSize), + FirstCluster, + &CurrentCluster, + Buffer, + NoCache, + 0, + Length, + FALSE); } /* set dates and times */ - KeQuerySystemTime (&SystemTime); - ExSystemTimeToLocalTime (&SystemTime, &LocalTime); - FsdFileTimeToDosDateTime ((TIME *) & LocalTime, - &Fcb->entry.UpdateDate, &Fcb->entry.UpdateTime); - Fcb->entry.AccessDate = Fcb->entry.UpdateDate; - - if (Fcb->entry.FileSize < WriteOffset + Length - && !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) + if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)) { - Fcb->entry.FileSize = WriteOffset + Length; - /* - * update entry in directory - */ - // updEntry (DeviceExt, FileObject); + KeQuerySystemTime (&SystemTime); + ExSystemTimeToLocalTime (&SystemTime, &LocalTime); + FsdFileTimeToDosDateTime ((TIME*)&LocalTime, + &Fcb->entry.UpdateDate, + &Fcb->entry.UpdateTime); + Fcb->entry.AccessDate = Fcb->entry.UpdateDate; + updEntry (DeviceExt, FileObject); } - ExFreePool (Temp); return (STATUS_SUCCESS); } @@ -580,6 +928,7 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp) PFILE_OBJECT FileObject = Stack->FileObject; PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; NTSTATUS Status; + ULONG NoCache; DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp); @@ -587,7 +936,18 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp) Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); Offset = Stack->Parameters.Write.ByteOffset.u.LowPart; - Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset); + if (Irp->Flags & IRP_PAGING_IO || + FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) + { + NoCache = TRUE; + } + else + { + NoCache = FALSE; + } + + Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset, + NoCache); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Length; diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index 54d35314b77..35ff0af87d9 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -1,4 +1,4 @@ -/* $Id: vfat.h,v 1.23 2001/01/14 15:05:53 dwelch Exp $ */ +/* $Id: vfat.h,v 1.24 2001/01/16 09:55:02 dwelch Exp $ */ #include @@ -83,6 +83,8 @@ typedef struct PDEVICE_OBJECT StorageDevice; PFILE_OBJECT StreamStorageDevice; PBCB StorageBcb; + PFILE_OBJECT Fat12StorageDevice; + PBCB Fat12StorageBcb; BootSector *Boot; int rootDirectorySectors, FATStart, rootStart, dataStart; int FATEntriesPerSector, FATUnit; @@ -153,6 +155,12 @@ NTSTATUS STDCALL VfatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); +NTSTATUS +NextCluster(PDEVICE_EXTENSION DeviceExt, + ULONG FirstCluster, + PULONG CurrentCluster, + BOOLEAN Extend); + /* internal functions in blockdev.c */ NTSTATUS VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject, @@ -188,9 +196,11 @@ VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PULONG LengthRead, ULONG NoCache); NTSTATUS VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, - PVOID Buffer, ULONG Length, ULONG WriteOffset); + PVOID Buffer, ULONG Length, ULONG WriteOffset, ULONG NoCache); NTSTATUS -GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, +GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, + ULONG FirstCluster, + ULONG CurrentCluster, PULONG NextCluster); BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset); @@ -199,7 +209,8 @@ IsLastEntry(PVOID Block, ULONG Offset); wchar_t* vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount); NTSTATUS -VfatWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster); +VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt, + ULONG FirstCluster, PVOID Buffer, ULONG Cluster); /* internal functions in dirwr.c */ NTSTATUS @@ -236,7 +247,8 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster); NTSTATUS GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster, - PULONG NextCluster); + PULONG NextCluster, + BOOLEAN Extend); NTSTATUS VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt, ULONG FirstCluster, @@ -269,6 +281,9 @@ VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp); */ NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb); +NTSTATUS +VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, + PWSTR FileName); /* * functions from shutdown.c diff --git a/reactos/install.sh b/reactos/install.sh index b6c81e5331e..c88c53ea4c3 100644 --- a/reactos/install.sh +++ b/reactos/install.sh @@ -10,7 +10,7 @@ cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers cp services/dd/vidport/vidport.sys $1/reactos/system32/drivers cp services/fs/minix/minixfs.sys $1/reactos/system32/drivers -cp apps/shell/shell.exe $1/reactos/system32 +cp apps/system/shell/shell.exe $1/reactos/system32 cp lib/ntdll/ntdll.dll $1/reactos/system32 cp lib/kernel32/kernel32.dll $1/reactos/system32 cp lib/crtdll/crtdll.dll $1/reactos/system32 diff --git a/reactos/lib/kernel32/file/rw.c b/reactos/lib/kernel32/file/rw.c index f7f8d26416a..e659b2bb2f3 100644 --- a/reactos/lib/kernel32/file/rw.c +++ b/reactos/lib/kernel32/file/rw.c @@ -1,4 +1,4 @@ -/* $Id: rw.c,v 1.14 2000/10/11 20:50:31 dwelch Exp $ +/* $Id: rw.c,v 1.15 2001/01/16 09:55:02 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -101,8 +101,6 @@ WINBOOL STDCALL ReadFile(HANDLE hFile, PIO_STATUS_BLOCK IoStatusBlock; PLARGE_INTEGER ptrOffset; - DbgPrint("ReadFile(hFile %x)\n", hFile); - if (IsConsoleHandle(hFile)) { return(ReadConsoleA(hFile, diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 6c4602704d8..c26391d75c4 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -101,6 +101,7 @@ MmGetContinuousPages(ULONG NumberOfBytes, MmPageArray[i].SavedSwapEntry = 0; InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry); } + KeReleaseSpinLock(&PageListLock, oldIrql); return((PVOID)(start * 4096)); } diff --git a/reactos/rules.mak b/reactos/rules.mak index 2dab3729d8d..eed53e51d20 100644 --- a/reactos/rules.mak +++ b/reactos/rules.mak @@ -48,6 +48,7 @@ DIST_DIR = dist endif CC = $(PREFIX)gcc +CXX = $(PREFIX)g++ HOST_CC = gcc HOST_NM = nm CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe