mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Fix bug in MmAllocateContinuousPages spotted by Philip Susi
Fixed compilation bugs in roshttpd Work on write support (still not working) svn path=/trunk/; revision=1524
This commit is contained in:
parent
7887cc9965
commit
25dc208536
18 changed files with 1027 additions and 576 deletions
|
@ -61,7 +61,7 @@ APPS = args hello test cat bench apc shm lpc thread event file gditest \
|
||||||
# objdir
|
# objdir
|
||||||
|
|
||||||
#NET_APPS = ping roshttpd
|
#NET_APPS = ping roshttpd
|
||||||
NET_APPS = ping roshttpd
|
NET_APPS = ping
|
||||||
|
|
||||||
|
|
||||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS) $(NET_DEVICE_DRIVERS)
|
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS) $(NET_DEVICE_DRIVERS)
|
||||||
|
|
|
@ -34,7 +34,7 @@ CListNode::CListNode(PVOID element, CListNode *next, CListNode *prev)
|
||||||
Prev = prev;
|
Prev = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID CListNode::operator new(/*size_t*/ UINT size)
|
void* CListNode::operator new(/*size_t*/ UINT size)
|
||||||
{
|
{
|
||||||
PVOID p;
|
PVOID p;
|
||||||
if (hHeap == NULL) {
|
if (hHeap == NULL) {
|
||||||
|
@ -47,7 +47,7 @@ PVOID CListNode::operator new(/*size_t*/ UINT size)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID CListNode::operator delete(PVOID p)
|
VOID CListNode::operator delete(void* p)
|
||||||
{
|
{
|
||||||
if (HeapFree(hHeap, 0, p) != FALSE)
|
if (HeapFree(hHeap, 0, p) != FALSE)
|
||||||
nRef--;
|
nRef--;
|
||||||
|
|
|
@ -162,11 +162,12 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename)
|
||||||
CHAR str[255];
|
CHAR str[255];
|
||||||
CHAR str2[32];
|
CHAR str2[32];
|
||||||
union BigNum {
|
union BigNum {
|
||||||
unsigned __int64 Big;
|
// unsigned __int64 Big;
|
||||||
|
unsigned long long Big;
|
||||||
struct {
|
struct {
|
||||||
DWORD Low;
|
DWORD Low;
|
||||||
DWORD High;
|
DWORD High;
|
||||||
};
|
} u;
|
||||||
} nTotalBytes;
|
} nTotalBytes;
|
||||||
DWORD nBytesToRead;
|
DWORD nBytesToRead;
|
||||||
DWORD nBytesRead;
|
DWORD nBytesRead;
|
||||||
|
@ -186,8 +187,8 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Get file size
|
// Get file size
|
||||||
nTotalBytes.Low = GetFileSize(hFile, &nTotalBytes.High);
|
nTotalBytes.u.Low = GetFileSize(hFile, &nTotalBytes.u.High);
|
||||||
if ((nTotalBytes.Low == 0xFFFFFFFF) && ((GetLastError()) != NO_ERROR)) {
|
if ((nTotalBytes.u.Low == 0xFFFFFFFF) && ((GetLastError()) != NO_ERROR)) {
|
||||||
// Internal server error
|
// Internal server error
|
||||||
Report("500 Internal Server Error", HttpMsg500);
|
Report("500 Internal Server Error", HttpMsg500);
|
||||||
// Close file
|
// Close file
|
||||||
|
@ -217,7 +218,7 @@ VOID CHttpClient::SendFile(LPSTR lpsFilename)
|
||||||
SendText("Content-Type: text/plain");
|
SendText("Content-Type: text/plain");
|
||||||
SendText("Accept-Ranges: bytes");
|
SendText("Accept-Ranges: bytes");
|
||||||
strcpy(str, "Content-Length: ");
|
strcpy(str, "Content-Length: ");
|
||||||
_itoa(nTotalBytes.Low, str2, 10);
|
_itoa(nTotalBytes.u.Low, str2, 10);
|
||||||
strcat(str, str2);
|
strcat(str, str2);
|
||||||
SendText(str);
|
SendText(str);
|
||||||
SendText("");
|
SendText("");
|
||||||
|
|
|
@ -42,8 +42,10 @@ private:
|
||||||
BOOL bStop;
|
BOOL bStop;
|
||||||
LPSTR lpsBuffer;
|
LPSTR lpsBuffer;
|
||||||
LONG nBufferSize;
|
LONG nBufferSize;
|
||||||
unsigned __int64 nTotalRead;
|
// unsigned __int64 nTotalRead;
|
||||||
unsigned __int64 nFileSize;
|
unsigned long long nTotalRead;
|
||||||
|
// unsigned __int64 nFileSize;
|
||||||
|
unsigned long long nFileSize;
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
};
|
};
|
||||||
typedef CHttpClient* LPCHttpClient;
|
typedef CHttpClient* LPCHttpClient;
|
||||||
|
|
|
@ -14,8 +14,8 @@ public:
|
||||||
CListNode();
|
CListNode();
|
||||||
CListNode(VOID *element, CListNode *next, CListNode *prev);
|
CListNode(VOID *element, CListNode *next, CListNode *prev);
|
||||||
~CListNode() {};
|
~CListNode() {};
|
||||||
PVOID operator new(/*size_t s*/ UINT s);
|
void* operator new(/*size_t s*/ UINT s);
|
||||||
VOID operator delete(PVOID p);
|
VOID operator delete(void* p);
|
||||||
|
|
||||||
VOID SetElement(PVOID element);
|
VOID SetElement(PVOID element);
|
||||||
VOID SetNext(CListNode *next);
|
VOID SetNext(CListNode *next);
|
||||||
|
|
|
@ -13,7 +13,8 @@ COMMON_OBJECTS = common/list.o common/socket.o common/thread.o
|
||||||
OBJECTS = $(MAIN_OBJECTS) $(COMMON_OBJECTS)
|
OBJECTS = $(MAIN_OBJECTS) $(COMMON_OBJECTS)
|
||||||
PROGS = $(TARGETNAME).exe
|
PROGS = $(TARGETNAME).exe
|
||||||
LIBS = ../../../lib/kernel32/kernel32.a \
|
LIBS = ../../../lib/kernel32/kernel32.a \
|
||||||
../../../lib/ws2_32/ws2_32.a
|
../../../lib/ws2_32/ws2_32.a \
|
||||||
|
../../../lib/user32/user32.a
|
||||||
|
|
||||||
ifeq ($(DOSCLI), yes)
|
ifeq ($(DOSCLI), yes)
|
||||||
CLEAN_FILES = *.o $(TARGETNAME).exe $(TARGETNAME).sym common\*.o
|
CLEAN_FILES = *.o $(TARGETNAME).exe $(TARGETNAME).sym common\*.o
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: services/fs/vfat/blockdev.c
|
* FILE: services/fs/vfat/blockdev.c
|
||||||
* PURPOSE: Temporary sector reading support
|
* PURPOSE: Temporary sector reading support
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ VfatWriteSectors (IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
|
||||||
if (!NT_SUCCESS (Status))
|
if (!NT_SUCCESS (Status))
|
||||||
{
|
{
|
||||||
DPRINT ("IO failed!!! VFATWriteSectors : Error code: %x\n", Status);
|
DPRINT1 ("IO failed!!! VFATWriteSectors : Error code: %x\n", Status);
|
||||||
return (Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -28,7 +28,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
PVFATCCB pCcb;
|
PVFATCCB pCcb;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT ("FsdCloseFile(DeviceExt %x, FileObject %x)\n",
|
DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n",
|
||||||
DeviceExt, FileObject);
|
DeviceExt, FileObject);
|
||||||
|
|
||||||
//FIXME : update entry in directory ?
|
//FIXME : update entry in directory ?
|
||||||
|
@ -65,7 +65,7 @@ VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT ("FsdClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
|
DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
Status = VfatCloseFile (DeviceExtension, FileObject);
|
Status = VfatCloseFile (DeviceExtension, FileObject);
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -150,7 +150,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
ULONG NextCluster;
|
ULONG NextCluster;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Size = DeviceExt->rootDirectorySectors; //FIXME : in fat32, no limit
|
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
|
||||||
StartingSector = DeviceExt->rootStart;
|
StartingSector = DeviceExt->rootStart;
|
||||||
NextCluster = 0;
|
NextCluster = 0;
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
return (STATUS_UNSUCCESSFUL);
|
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
|
/* directory can be fragmented although it is best to keep them
|
||||||
unfragmented */
|
unfragmented */
|
||||||
|
@ -192,7 +192,8 @@ ReadVolumeLabel (PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
|
||||||
{
|
{
|
||||||
if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
|
if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
|
||||||
{
|
{
|
||||||
Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster);
|
Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster,
|
||||||
|
FALSE);
|
||||||
if (NextCluster == 0 || NextCluster == 0xffffffff)
|
if (NextCluster == 0 || NextCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
*(Vpb->VolumeLabel) = 0;
|
*(Vpb->VolumeLabel) = 0;
|
||||||
|
@ -235,17 +236,11 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
TempStr[0] = (WCHAR) '.';
|
TempStr[0] = (WCHAR) '.';
|
||||||
TempStr[1] = 0;
|
TempStr[1] = 0;
|
||||||
FileToFind = (PWSTR) & TempStr;
|
FileToFind = (PWSTR)&TempStr;
|
||||||
}
|
|
||||||
if (Parent != NULL)
|
|
||||||
{
|
|
||||||
DPRINT ("Parent->entry.FirstCluster %d\n", Parent->entry.FirstCluster);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT ("FindFile '%S'\n", FileToFind);
|
|
||||||
if (Parent == NULL || Parent->entry.FirstCluster == 1)
|
if (Parent == NULL || Parent->entry.FirstCluster == 1)
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
|
||||||
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
|
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
|
||||||
StartingSector = DeviceExt->rootStart;
|
StartingSector = DeviceExt->rootStart;
|
||||||
NextCluster = 0;
|
NextCluster = 0;
|
||||||
|
@ -253,7 +248,6 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
||||||
{
|
{
|
||||||
/* it's root : complete essentials fields then return ok */
|
/* it's root : complete essentials fields then return ok */
|
||||||
CHECKPOINT;
|
|
||||||
memset (Fcb, 0, sizeof (VFATFCB));
|
memset (Fcb, 0, sizeof (VFATFCB));
|
||||||
memset (Fcb->entry.Filename, ' ', 11);
|
memset (Fcb->entry.Filename, ' ', 11);
|
||||||
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
|
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
|
||||||
|
@ -261,7 +255,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
Fcb->entry.FirstCluster = 2;
|
Fcb->entry.FirstCluster = 2;
|
||||||
else
|
else
|
||||||
Fcb->entry.FirstCluster = 1; /* FIXME : is 1 the good value for mark root? */
|
Fcb->entry.FirstCluster = 1;
|
||||||
if (StartSector)
|
if (StartSector)
|
||||||
*StartSector = StartingSector;
|
*StartSector = StartingSector;
|
||||||
if (Entry)
|
if (Entry)
|
||||||
|
@ -286,13 +280,10 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
StartingSector = DeviceExt->rootStart;
|
StartingSector = DeviceExt->rootStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
|
||||||
block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
CHECKPOINT;
|
|
||||||
if (StartSector && (*StartSector))
|
if (StartSector && (*StartSector))
|
||||||
StartingSector = *StartSector;
|
StartingSector = *StartSector;
|
||||||
i = (Entry) ? (*Entry) : 0;
|
i = (Entry) ? (*Entry) : 0;
|
||||||
DPRINT ("FindFile : start at sector %lx, entry %ld\n", StartingSector, i);
|
|
||||||
for (j = 0; j < Size; j++)
|
for (j = 0; j < Size; j++)
|
||||||
{
|
{
|
||||||
/* FIXME: Check status */
|
/* FIXME: Check status */
|
||||||
|
@ -316,8 +307,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
{
|
{
|
||||||
if (wstrcmpjoki (name, FileToFind))
|
if (wstrcmpjoki (name, FileToFind))
|
||||||
{
|
{
|
||||||
/* In the case of a long filename, the firstcluster is stored in
|
/* In the case of a long filename, the firstcluster is
|
||||||
the next record -- where it's short name is */
|
stored in the next record -- where it's short name is */
|
||||||
if (((FATDirEntry *) block)[i].Attrib == 0x0f)
|
if (((FATDirEntry *) block)[i].Attrib == 0x0f)
|
||||||
i++;
|
i++;
|
||||||
if (i == (ENTRIES_PER_SECTOR))
|
if (i == (ENTRIES_PER_SECTOR))
|
||||||
|
@ -354,7 +345,8 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
{
|
{
|
||||||
if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
|
if (StartingSector == ClusterToSector (DeviceExt, NextCluster + 1))
|
||||||
{
|
{
|
||||||
Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster);
|
Status = GetNextCluster (DeviceExt, NextCluster, &NextCluster,
|
||||||
|
FALSE);
|
||||||
if (NextCluster == 0 || NextCluster == 0xffffffff)
|
if (NextCluster == 0 || NextCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
if (StartSector)
|
if (StartSector)
|
||||||
|
@ -379,7 +371,7 @@ FindFile (PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PWSTR FileName)
|
PWSTR FileName)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Opens a file
|
* FUNCTION: Opens a file
|
||||||
|
@ -400,7 +392,7 @@ FsdOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG BytesPerCluster;
|
ULONG BytesPerCluster;
|
||||||
|
|
||||||
DPRINT ("FsdOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
|
DPRINT ("VfatOpenFile(%08lx, %08lx, %S)\n", DeviceExt, FileObject, FileName);
|
||||||
|
|
||||||
/* FIXME : treat relative name */
|
/* FIXME : treat relative name */
|
||||||
if (FileObject->RelatedFileObject)
|
if (FileObject->RelatedFileObject)
|
||||||
|
@ -641,9 +633,12 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
assert (DeviceExt);
|
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;
|
Irp->IoStatus.Information = 0;
|
||||||
if (Status == STATUS_OBJECT_PATH_NOT_FOUND)
|
if (Status == STATUS_OBJECT_PATH_NOT_FOUND)
|
||||||
{
|
{
|
||||||
|
@ -651,23 +646,21 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKPOINT;
|
|
||||||
if (!NT_SUCCESS (Status))
|
if (!NT_SUCCESS (Status))
|
||||||
{
|
{
|
||||||
if (RequestedDisposition == FILE_CREATE
|
/*
|
||||||
|| RequestedDisposition == FILE_OPEN_IF
|
* If the file open failed then create the required file
|
||||||
|| RequestedDisposition == FILE_OVERWRITE_IF
|
*/
|
||||||
|| RequestedDisposition == FILE_SUPERSEDE)
|
if (RequestedDisposition == FILE_CREATE ||
|
||||||
|
RequestedDisposition == FILE_OPEN_IF ||
|
||||||
|
RequestedDisposition == FILE_OVERWRITE_IF ||
|
||||||
|
RequestedDisposition == FILE_SUPERSEDE)
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
#if 0
|
|
||||||
Status =
|
Status =
|
||||||
addEntry (DeviceExt, FileObject, RequestedOptions,
|
addEntry (DeviceExt, FileObject, RequestedOptions,
|
||||||
(Stack->Parameters.
|
(Stack->Parameters.
|
||||||
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
|
Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
|
||||||
#else
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
#endif
|
|
||||||
if (NT_SUCCESS (Status))
|
if (NT_SUCCESS (Status))
|
||||||
Irp->IoStatus.Information = FILE_CREATED;
|
Irp->IoStatus.Information = FILE_CREATED;
|
||||||
/* FIXME set size if AllocationSize requested */
|
/* FIXME set size if AllocationSize requested */
|
||||||
|
@ -680,6 +673,9 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Otherwise fail if the caller wanted to create a new file
|
||||||
|
*/
|
||||||
if (RequestedDisposition == FILE_CREATE)
|
if (RequestedDisposition == FILE_CREATE)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = FILE_EXISTS;
|
Irp->IoStatus.Information = FILE_EXISTS;
|
||||||
|
@ -687,6 +683,10 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
}
|
}
|
||||||
pCcb = FileObject->FsContext2;
|
pCcb = FileObject->FsContext2;
|
||||||
pFcb = pCcb->pFcb;
|
pFcb = pCcb->pFcb;
|
||||||
|
/*
|
||||||
|
* If requested then delete the file and create a new one with the
|
||||||
|
* same name
|
||||||
|
*/
|
||||||
if (RequestedDisposition == FILE_SUPERSEDE)
|
if (RequestedDisposition == FILE_SUPERSEDE)
|
||||||
{
|
{
|
||||||
ULONG Cluster, NextCluster;
|
ULONG Cluster, NextCluster;
|
||||||
|
@ -699,14 +699,18 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
Cluster = pFcb->entry.FirstCluster;
|
Cluster = pFcb->entry.FirstCluster;
|
||||||
pFcb->entry.FirstCluster = 0;
|
pFcb->entry.FirstCluster = 0;
|
||||||
pFcb->entry.FirstClusterHigh = 0;
|
pFcb->entry.FirstClusterHigh = 0;
|
||||||
// updEntry (DeviceExt, FileObject);
|
updEntry (DeviceExt, FileObject);
|
||||||
while (Cluster != 0xffffffff && Cluster > 1)
|
while (Cluster != 0xffffffff && Cluster > 1)
|
||||||
{
|
{
|
||||||
Status = GetNextCluster (DeviceExt, Cluster, &NextCluster);
|
Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE);
|
||||||
// WriteCluster (DeviceExt, Cluster, 0);
|
// WriteCluster (DeviceExt, Cluster, 0);
|
||||||
Cluster = NextCluster;
|
Cluster = NextCluster;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the file has the requested attributes
|
||||||
|
*/
|
||||||
if ((RequestedOptions & FILE_NON_DIRECTORY_FILE)
|
if ((RequestedOptions & FILE_NON_DIRECTORY_FILE)
|
||||||
&& (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
&& (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#include "vfat.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
/*
|
||||||
* Copies a file name into a directory slot (long file name entry)
|
* Copies a file name into a directory slot (long file name entry)
|
||||||
* and fills trailing slot space with 0xFFFF. This keeps scandisk
|
* 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));
|
memset (&FileObject, 0, sizeof (FILE_OBJECT));
|
||||||
DPRINT ("open directory \'%S\' for update of entry \'%S\'\n", DirName,
|
DPRINT ("open directory \'%S\' for update of entry \'%S\'\n", DirName,
|
||||||
FileName);
|
FileName);
|
||||||
status = FsdOpenFile (DeviceExt, &FileObject, DirName);
|
status = VfatOpenFile (DeviceExt, &FileObject, DirName);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, 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);
|
Buffer = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
DPRINT ("update entry: sector %d, entry %d\n", Sector, Entry);
|
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;
|
pEntries = (FATDirEntry *) Buffer;
|
||||||
memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry));
|
memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry));
|
||||||
VFATWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
|
VfatWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
|
||||||
ExFreePool (Buffer);
|
ExFreePool (Buffer);
|
||||||
}
|
}
|
||||||
VfatCloseFile (DeviceExt, &FileObject);
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
|
@ -177,6 +176,8 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
LARGE_INTEGER SystemTime, LocalTime;
|
LARGE_INTEGER SystemTime, LocalTime;
|
||||||
|
ULONG BytesPerCluster;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
PathFileName = pFileObject->FileName.Buffer;
|
PathFileName = pFileObject->FileName.Buffer;
|
||||||
DPRINT ("addEntry: Pathname=%S\n", PathFileName);
|
DPRINT ("addEntry: Pathname=%S\n", PathFileName);
|
||||||
|
@ -194,7 +195,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
DirName[posCar] = 0;
|
DirName[posCar] = 0;
|
||||||
// open parent directory
|
// open parent directory
|
||||||
memset (&FileObject, 0, sizeof (FILE_OBJECT));
|
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
|
nbSlots = (NameLen + 12) / 13 + 1; //nb of entry needed for long name+normal entry
|
||||||
DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots);
|
DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots);
|
||||||
Buffer =
|
Buffer =
|
||||||
|
@ -356,7 +357,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
status =
|
status =
|
||||||
VfatReadFile (DeviceExt, &FileObject, &FatEntry, sizeof (FATDirEntry),
|
VfatReadFile (DeviceExt, &FileObject, &FatEntry, sizeof (FATDirEntry),
|
||||||
i * sizeof (FATDirEntry), &LengthRead);
|
i * sizeof (FATDirEntry), &LengthRead, FALSE);
|
||||||
if (status == STATUS_END_OF_FILE)
|
if (status == STATUS_END_OF_FILE)
|
||||||
break;
|
break;
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
|
@ -381,11 +382,11 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextWriteCluster (DeviceExt, 0);
|
NextCluster (DeviceExt, 0, &CurrentCluster, TRUE);
|
||||||
// zero the cluster
|
// zero the cluster
|
||||||
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||||
memset (Buffer2, 0, DeviceExt->BytesPerCluster);
|
memset (Buffer2, 0, DeviceExt->BytesPerCluster);
|
||||||
VFATWriteCluster (DeviceExt, Buffer2, CurrentCluster);
|
VfatRawWriteCluster (DeviceExt, 0, Buffer2, CurrentCluster);
|
||||||
ExFreePool (Buffer2);
|
ExFreePool (Buffer2);
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
|
@ -400,7 +401,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
Offset = (i - nbSlots + 1) * sizeof (FATDirEntry);
|
Offset = (i - nbSlots + 1) * sizeof (FATDirEntry);
|
||||||
status =
|
status =
|
||||||
VfatWriteFile (DeviceExt, &FileObject, Buffer,
|
VfatWriteFile (DeviceExt, &FileObject, Buffer,
|
||||||
sizeof (FATDirEntry) * nbSlots, Offset);
|
sizeof (FATDirEntry) * nbSlots, Offset, FALSE);
|
||||||
DPRINT ("VfatWriteFile() returned: %x\n", status);
|
DPRINT ("VfatWriteFile() returned: %x\n", status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -408,7 +409,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
Offset = (i - nbFree) * sizeof (FATDirEntry);
|
Offset = (i - nbFree) * sizeof (FATDirEntry);
|
||||||
status =
|
status =
|
||||||
VfatWriteFile (DeviceExt, &FileObject, Buffer,
|
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);
|
DPRINT ("write entry offset %d status=%x\n", Offset, status);
|
||||||
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
|
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
|
||||||
|
@ -419,6 +420,18 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
newCCB->PtrFileObject = pFileObject;
|
newCCB->PtrFileObject = pFileObject;
|
||||||
newFCB->RefCount++;
|
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
|
* FIXME : initialize all fields in FCB and CCB
|
||||||
*/
|
*/
|
||||||
|
@ -441,7 +454,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
memcpy (pEntry->Filename, ". ", 11);
|
memcpy (pEntry->Filename, ". ", 11);
|
||||||
status =
|
status =
|
||||||
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
||||||
0L);
|
0L, FALSE);
|
||||||
pEntry->FirstCluster =
|
pEntry->FirstCluster =
|
||||||
((VFATCCB *) (FileObject.FsContext2))->pFcb->entry.FirstCluster;
|
((VFATCCB *) (FileObject.FsContext2))->pFcb->entry.FirstCluster;
|
||||||
pEntry->FirstClusterHigh =
|
pEntry->FirstClusterHigh =
|
||||||
|
@ -451,13 +464,12 @@ addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
pEntry->FirstCluster = 0;
|
pEntry->FirstCluster = 0;
|
||||||
status =
|
status =
|
||||||
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
||||||
sizeof (FATDirEntry));
|
sizeof (FATDirEntry), FALSE);
|
||||||
}
|
}
|
||||||
VfatCloseFile (DeviceExt, &FileObject);
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
ExFreePool (Buffer);
|
ExFreePool (Buffer);
|
||||||
DPRINT ("addentry ok\n");
|
DPRINT ("addentry ok\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -109,21 +109,18 @@ Fat12GetNextCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
|
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
unsigned char* CBlock;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
NTSTATUS Status;
|
|
||||||
PVOID BaseAddress;
|
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PCACHE_SEGMENT CacheSeg;
|
||||||
UCHAR Value1, Value2;
|
NTSTATUS Status;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
|
||||||
FATOffset = (DeviceExt->FATStart * BLOCKSIZE) + ((CurrentCluster * 12) / 8);
|
*NextCluster = 0;
|
||||||
|
|
||||||
/*
|
Status = CcRequestCacheSegment(DeviceExt->Fat12StorageBcb,
|
||||||
* Get the page containing this offset
|
0,
|
||||||
*/
|
|
||||||
Status = CcRequestCacheSegment(DeviceExt->StorageBcb,
|
|
||||||
PAGE_ROUND_DOWN(FATOffset),
|
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&CacheSeg);
|
||||||
|
@ -134,106 +131,35 @@ Fat12GetNextCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
||||||
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE,
|
DeviceExt->FATStart,
|
||||||
PAGESIZE / BLOCKSIZE,
|
DeviceExt->Boot->FATSectors,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, FALSE);
|
CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, FALSE);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value1 = ((PUCHAR)BaseAddress)[FATOffset % PAGESIZE];
|
CBlock = (PUCHAR)BaseAddress;
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
FATOffset = (CurrentCluster * 12) / 8; /* first byte containing value */
|
||||||
if ((CurrentCluster % 2) == 0)
|
if ((CurrentCluster % 2) == 0)
|
||||||
{
|
{
|
||||||
Entry = Value1;
|
Entry = CBlock[FATOffset];
|
||||||
Entry |= ((Value2 & 0xf) << 8);
|
Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Entry = (Value1 >> 4);
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
Entry |= (Value2 << 4);
|
Entry |= (CBlock[FATOffset+1] << 4);
|
||||||
}
|
}
|
||||||
DPRINT ("Entry %x\n", Entry);
|
DPRINT("Entry %x\n",Entry);
|
||||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
Entry = 0xffffffff;
|
Entry = 0xffffffff;
|
||||||
DPRINT ("Returning %x\n", Entry);
|
DPRINT("Returning %x\n",Entry);
|
||||||
*NextCluster = Entry;
|
*NextCluster = Entry;
|
||||||
return (STATUS_SUCCESS);
|
CcReleaseCacheSegment(DeviceExt->Fat12StorageBcb, CacheSeg, TRUE);
|
||||||
}
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -256,16 +182,16 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
CacheSeg = NULL;
|
CacheSeg = NULL;
|
||||||
*Cluster = 0;
|
*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)
|
if (CacheSeg != NULL)
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
}
|
}
|
||||||
Status = CcRequestCacheSegment(DeviceExt->StorageBcb,
|
Status = CcRequestCacheSegment(DeviceExt->StorageBcb,
|
||||||
FatStart + i,
|
PAGE_ROUND_DOWN(FatStart + i),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&Valid,
|
&Valid,
|
||||||
&CacheSeg);
|
&CacheSeg);
|
||||||
|
@ -276,7 +202,8 @@ FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
Status = VfatReadSectors(DeviceExt->StorageDevice,
|
||||||
(FatStart + i) / BLOCKSIZE,
|
PAGE_ROUND_DOWN(FatStart + i)
|
||||||
|
/ BLOCKSIZE,
|
||||||
PAGESIZE / BLOCKSIZE,
|
PAGESIZE / BLOCKSIZE,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
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;
|
*Cluster = i / 2;
|
||||||
|
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
return(STATUS_DISK_FULL);
|
return(STATUS_DISK_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,14 +232,40 @@ FAT12FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
|
||||||
* FUNCTION: Finds the first available cluster in a FAT12 table
|
* FUNCTION: Finds the first available cluster in a FAT12 table
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
*Cluster = 0;
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
PUCHAR CBlock = DeviceExt->FAT;
|
PUCHAR CBlock;
|
||||||
ULONG i;
|
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++)
|
for (i = 2; i < ((DeviceExt->Boot->FATSectors * 512 * 8) / 12); i++)
|
||||||
{
|
{
|
||||||
FATOffset = (i * 12) / 8;
|
FATOffset = (i * 12) / 8;
|
||||||
|
@ -325,12 +280,14 @@ FAT12FindAvailableCluster (PDEVICE_EXTENSION DeviceExt, PULONG Cluster)
|
||||||
Entry |= (CBlock[FATOffset + 1] << 4);
|
Entry |= (CBlock[FATOffset + 1] << 4);
|
||||||
}
|
}
|
||||||
if (Entry == 0)
|
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);
|
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
return 0;
|
return (STATUS_DISK_FULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -474,14 +431,41 @@ FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
PUCHAR CBlock = DeviceExt->FAT;
|
PUCHAR CBlock;
|
||||||
int i;
|
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;
|
FATOffset = (ClusterToWrite * 12) / 8;
|
||||||
|
DPRINT1("Writing 0x%x for 0x%x at 0x%x\n",
|
||||||
|
NewValue, ClusterToWrite, FATOffset);
|
||||||
if ((ClusterToWrite % 2) == 0)
|
if ((ClusterToWrite % 2) == 0)
|
||||||
{
|
{
|
||||||
CBlock[FATOffset] = NewValue;
|
CBlock[FATOffset] = NewValue;
|
||||||
|
@ -515,7 +499,8 @@ FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
1, CBlock + FATsector * 512);
|
1, CBlock + FATsector * 512);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -535,10 +520,10 @@ FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
|
|
||||||
Start = DeviceExt->FATStart;
|
Start = DeviceExt->FATStart;
|
||||||
|
|
||||||
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
|
||||||
{
|
|
||||||
FATOffset = (Start * BLOCKSIZE) + (ClusterToWrite * 2);
|
FATOffset = (Start * BLOCKSIZE) + (ClusterToWrite * 2);
|
||||||
|
|
||||||
|
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
||||||
|
{
|
||||||
Status = CcRequestCacheSegment(DeviceExt->StorageBcb,
|
Status = CcRequestCacheSegment(DeviceExt->StorageBcb,
|
||||||
PAGE_ROUND_DOWN(FATOffset),
|
PAGE_ROUND_DOWN(FATOffset),
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
|
@ -561,10 +546,18 @@ FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("Writing 0x%x for offset 0x%x 0x%x\n", NewValue, FATOffset,
|
||||||
|
ClusterToWrite);
|
||||||
*((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))) = NewValue;
|
*((PUSHORT)(BaseAddress + (FATOffset % PAGESIZE))) = NewValue;
|
||||||
|
Status = VfatWriteSectors(DeviceExt->StorageDevice,
|
||||||
|
PAGE_ROUND_DOWN(FATOffset) / BLOCKSIZE,
|
||||||
|
PAGESIZE / BLOCKSIZE,
|
||||||
|
BaseAddress);
|
||||||
CcReleaseCacheSegment(DeviceExt->StorageBcb, CacheSeg, TRUE);
|
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);
|
return (STATUS_SUCCESS);
|
||||||
|
@ -629,77 +622,6 @@ WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
return(Status);
|
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
|
ULONG
|
||||||
ClusterToSector (PDEVICE_EXTENSION DeviceExt, unsigned long Cluster)
|
ClusterToSector (PDEVICE_EXTENSION DeviceExt, unsigned long Cluster)
|
||||||
/*
|
/*
|
||||||
|
@ -745,7 +667,10 @@ VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
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
|
* 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",
|
DPRINT ("VfatWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
DeviceExt, Buffer, Cluster);
|
DeviceExt, Buffer, Cluster);
|
||||||
|
|
||||||
|
if (FirstCluster == 1)
|
||||||
|
{
|
||||||
|
Status = VfatWriteSectors (DeviceExt->StorageDevice,
|
||||||
|
Cluster,
|
||||||
|
DeviceExt->Boot->SectorsPerCluster, Buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Sector = ClusterToSector (DeviceExt, Cluster);
|
Sector = ClusterToSector (DeviceExt, Cluster);
|
||||||
|
|
||||||
Status = VfatWriteSectors (DeviceExt->StorageDevice,
|
Status = VfatWriteSectors (DeviceExt->StorageDevice,
|
||||||
Sector, DeviceExt->Boot->SectorsPerCluster,
|
Sector, DeviceExt->Boot->SectorsPerCluster,
|
||||||
Buffer);
|
Buffer);
|
||||||
|
}
|
||||||
return(Status);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -157,6 +157,14 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
|
||||||
Status = CcInitializeFileCache(DeviceExt->StreamStorageDevice,
|
Status = CcInitializeFileCache(DeviceExt->StreamStorageDevice,
|
||||||
&DeviceExt->StorageBcb,
|
&DeviceExt->StorageBcb,
|
||||||
PAGESIZE);
|
PAGESIZE);
|
||||||
|
if (DeviceExt->FatType == FAT12)
|
||||||
|
{
|
||||||
|
DeviceExt->Fat12StorageDevice =
|
||||||
|
IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
|
||||||
|
Status = CcInitializeFileCache(DeviceExt->Fat12StorageDevice,
|
||||||
|
&DeviceExt->Fat12StorageBcb,
|
||||||
|
PAGESIZE * 3);
|
||||||
|
}
|
||||||
ExInitializeResourceLite (&DeviceExt->DirResource);
|
ExInitializeResourceLite (&DeviceExt->DirResource);
|
||||||
ExInitializeResourceLite (&DeviceExt->FatResource);
|
ExInitializeResourceLite (&DeviceExt->FatResource);
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -30,7 +30,12 @@
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NextCluster(PDEVICE_EXTENSION DeviceExt,
|
NextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG FirstCluster,
|
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)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +46,8 @@ NextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster);
|
Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster,
|
||||||
|
Extend);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +56,12 @@ NTSTATUS
|
||||||
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG FirstCluster,
|
ULONG FirstCluster,
|
||||||
ULONG FileOffset,
|
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 CurrentCluster;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -68,7 +79,8 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
CurrentCluster = FirstCluster;
|
CurrentCluster = FirstCluster;
|
||||||
for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
|
for (i = 0; i < FileOffset / DeviceExt->BytesPerCluster; i++)
|
||||||
{
|
{
|
||||||
Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster);
|
Status = GetNextCluster (DeviceExt, CurrentCluster, &CurrentCluster,
|
||||||
|
Extend);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -80,7 +92,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
VfatReadBigCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
PVFATFCB Fcb,
|
PVFATFCB Fcb,
|
||||||
ULONG StartOffset,
|
ULONG StartOffset,
|
||||||
ULONG FirstCluster,
|
ULONG FirstCluster,
|
||||||
|
@ -90,16 +102,11 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG InternalOffset,
|
ULONG InternalOffset,
|
||||||
ULONG InternalLength)
|
ULONG InternalLength)
|
||||||
{
|
{
|
||||||
ULONG BytesPerCluster;
|
|
||||||
BOOLEAN Valid;
|
BOOLEAN Valid;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress = NULL;
|
||||||
PCACHE_SEGMENT CacheSeg;
|
PCACHE_SEGMENT CacheSeg = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
BytesPerCluster = DeviceExt->Boot->SectorsPerCluster * BLOCKSIZE;
|
|
||||||
|
|
||||||
if (BytesPerCluster >= PAGESIZE)
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* In this case the size of a cache segment is the same as a cluster
|
* In this case the size of a cache segment is the same as a cluster
|
||||||
*/
|
*/
|
||||||
|
@ -119,7 +126,21 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Valid = FALSE;
|
Valid = FALSE;
|
||||||
|
if (InternalOffset == 0)
|
||||||
|
{
|
||||||
|
BaseAddress = Destination;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BaseAddress = ExAllocatePool(NonPagedPool,
|
||||||
|
DeviceExt->BytesPerCluster);
|
||||||
|
if (BaseAddress == NULL)
|
||||||
|
{
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -133,6 +154,10 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
||||||
}
|
}
|
||||||
|
else if (InternalOffset != 0)
|
||||||
|
{
|
||||||
|
ExFreePool(BaseAddress);
|
||||||
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,21 +169,39 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
||||||
}
|
}
|
||||||
|
else if (InternalOffset != 0)
|
||||||
|
{
|
||||||
|
ExFreePool(BaseAddress);
|
||||||
|
}
|
||||||
|
|
||||||
Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster);
|
Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
return(STATUS_SUCCESS);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
|
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;
|
ULONG i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Otherwise we read a page of clusters together
|
* Otherwise we read a page of clusters together
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!NoCache)
|
if (!NoCache)
|
||||||
{
|
{
|
||||||
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
|
Status = CcRequestCacheSegment(Fcb->RFCB.Bcb,
|
||||||
|
@ -174,6 +217,18 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Valid = FALSE;
|
Valid = FALSE;
|
||||||
|
if (InternalOffset == 0)
|
||||||
|
{
|
||||||
|
BaseAddress = Destination;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BaseAddress = ExAllocatePool(NonPagedPool, PAGESIZE);
|
||||||
|
if (BaseAddress == NULL)
|
||||||
|
{
|
||||||
|
return(STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -184,11 +239,12 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
*/
|
*/
|
||||||
if (!Valid)
|
if (!Valid)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (PAGESIZE / BytesPerCluster); i++)
|
for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++)
|
||||||
{
|
{
|
||||||
Status = VfatRawReadCluster(DeviceExt,
|
Status = VfatRawReadCluster(DeviceExt,
|
||||||
FirstCluster,
|
FirstCluster,
|
||||||
BaseAddress + (i * BytesPerCluster),
|
BaseAddress +
|
||||||
|
(i * DeviceExt->BytesPerCluster),
|
||||||
*CurrentCluster);
|
*CurrentCluster);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -196,9 +252,13 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, FALSE);
|
||||||
}
|
}
|
||||||
|
else if (InternalOffset != 0)
|
||||||
|
{
|
||||||
|
ExFreePool(BaseAddress);
|
||||||
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster);
|
Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE);
|
||||||
if ((*CurrentCluster) == 0xFFFFFFFF)
|
if ((*CurrentCluster) == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -212,7 +272,7 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++)
|
for (i = 0; i < (PAGESIZE / DeviceExt->BytesPerCluster); i++)
|
||||||
{
|
{
|
||||||
NextCluster(DeviceExt, FirstCluster, CurrentCluster);
|
NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE);
|
||||||
if ((*CurrentCluster) == 0xFFFFFFFF)
|
if ((*CurrentCluster) == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -227,6 +287,47 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
CcReleaseCacheSegment(Fcb->RFCB.Bcb, CacheSeg, TRUE);
|
||||||
}
|
}
|
||||||
|
else if (InternalOffset != 0)
|
||||||
|
{
|
||||||
|
ExFreePool(BaseAddress);
|
||||||
|
}
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
VfatReadCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
PVFATFCB Fcb,
|
||||||
|
ULONG StartOffset,
|
||||||
|
ULONG FirstCluster,
|
||||||
|
PULONG CurrentCluster,
|
||||||
|
PVOID Destination,
|
||||||
|
ULONG NoCache,
|
||||||
|
ULONG InternalOffset,
|
||||||
|
ULONG InternalLength)
|
||||||
|
{
|
||||||
|
if (DeviceExt->BytesPerCluster >= PAGESIZE)
|
||||||
|
{
|
||||||
|
return(VfatReadBigCluster(DeviceExt,
|
||||||
|
Fcb,
|
||||||
|
StartOffset,
|
||||||
|
FirstCluster,
|
||||||
|
CurrentCluster,
|
||||||
|
Destination,
|
||||||
|
NoCache,
|
||||||
|
InternalOffset,
|
||||||
|
InternalLength));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(VfatReadSmallCluster(DeviceExt,
|
||||||
|
Fcb,
|
||||||
|
StartOffset,
|
||||||
|
FirstCluster,
|
||||||
|
CurrentCluster,
|
||||||
|
Destination,
|
||||||
|
NoCache,
|
||||||
|
InternalOffset,
|
||||||
|
InternalLength));
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -283,6 +384,9 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select an appropiate size for reads
|
||||||
|
*/
|
||||||
if (DeviceExt->BytesPerCluster >= PAGESIZE)
|
if (DeviceExt->BytesPerCluster >= PAGESIZE)
|
||||||
{
|
{
|
||||||
ChunkSize = DeviceExt->BytesPerCluster;
|
ChunkSize = DeviceExt->BytesPerCluster;
|
||||||
|
@ -302,21 +406,21 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Status = OffsetToCluster(DeviceExt,
|
Status = OffsetToCluster(DeviceExt,
|
||||||
FirstCluster,
|
FirstCluster,
|
||||||
ROUND_DOWN(ReadOffset, ChunkSize),
|
ROUND_DOWN(ReadOffset, ChunkSize),
|
||||||
&CurrentCluster);
|
&CurrentCluster,
|
||||||
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the read doesn't begin on a cluster boundary then read a full
|
* If the read doesn't begin on a chunk boundary then we need special
|
||||||
* cluster and copy it.
|
* handling
|
||||||
*/
|
*/
|
||||||
if ((ReadOffset % ChunkSize) != 0)
|
if ((ReadOffset % ChunkSize) != 0)
|
||||||
{
|
{
|
||||||
TempLength = min (Length, ChunkSize - (ReadOffset % ChunkSize));
|
TempLength = min (Length, ChunkSize - (ReadOffset % ChunkSize));
|
||||||
VfatReadCluster(DeviceExt, Fcb,
|
VfatReadCluster(DeviceExt, Fcb, ROUND_DOWN(ReadOffset, ChunkSize),
|
||||||
ROUND_DOWN(ReadOffset, ChunkSize),
|
|
||||||
FirstCluster, &CurrentCluster, Buffer, NoCache,
|
FirstCluster, &CurrentCluster, Buffer, NoCache,
|
||||||
ReadOffset % ChunkSize, TempLength);
|
ReadOffset % ChunkSize, TempLength);
|
||||||
|
|
||||||
|
@ -331,10 +435,6 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
|
VfatReadCluster(DeviceExt, Fcb, ReadOffset,
|
||||||
FirstCluster, &CurrentCluster, Buffer, NoCache, 0,
|
FirstCluster, &CurrentCluster, Buffer, NoCache, 0,
|
||||||
ChunkSize);
|
ChunkSize);
|
||||||
if (CurrentCluster == 0xffffffff)
|
|
||||||
{
|
|
||||||
return (STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*LengthRead) = (*LengthRead) + ChunkSize;
|
(*LengthRead) = (*LengthRead) + ChunkSize;
|
||||||
Buffer = Buffer + ChunkSize;
|
Buffer = Buffer + ChunkSize;
|
||||||
|
@ -351,21 +451,324 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
return (STATUS_SUCCESS);
|
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
|
NTSTATUS
|
||||||
VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
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
|
* FUNCTION: Writes data to file
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
ULONG FileOffset;
|
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
PVFATFCB Fcb;
|
PVFATFCB Fcb;
|
||||||
PVFATCCB pCcb;
|
PVFATCCB pCcb;
|
||||||
PVOID Temp;
|
ULONG TempLength;
|
||||||
ULONG TempLength, Length2 = Length;
|
|
||||||
LARGE_INTEGER SystemTime, LocalTime;
|
LARGE_INTEGER SystemTime, LocalTime;
|
||||||
|
ULONG ChunkSize;
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOLEAN Extend;
|
||||||
|
|
||||||
DPRINT1 ("VfatWriteFile(FileObject %x, Buffer %x, Length %x, "
|
DPRINT1 ("VfatWriteFile(FileObject %x, Buffer %x, Length %x, "
|
||||||
"WriteOffset %x\n", FileObject, Buffer, Length, WriteOffset);
|
"WriteOffset %x\n", FileObject, Buffer, Length, WriteOffset);
|
||||||
|
@ -376,6 +779,16 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
assert (pCcb);
|
assert (pCcb);
|
||||||
Fcb = pCcb->pFcb;
|
Fcb = pCcb->pFcb;
|
||||||
assert (Fcb);
|
assert (Fcb);
|
||||||
|
|
||||||
|
if (DeviceExt->BytesPerCluster >= PAGESIZE)
|
||||||
|
{
|
||||||
|
ChunkSize = DeviceExt->BytesPerCluster;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChunkSize = PAGESIZE;
|
||||||
|
}
|
||||||
|
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
CurrentCluster =
|
CurrentCluster =
|
||||||
|
@ -387,45 +800,32 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
FirstCluster = CurrentCluster;
|
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 */
|
/* Find the cluster according to the offset in the file */
|
||||||
if (CurrentCluster == 1)
|
|
||||||
{
|
|
||||||
CurrentCluster = DeviceExt->rootStart + WriteOffset
|
|
||||||
/ DeviceExt->BytesPerCluster * DeviceExt->Boot->SectorsPerCluster;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* File of size zero
|
* File of size zero
|
||||||
*/
|
*/
|
||||||
// CurrentCluster = GetNextWriteCluster (DeviceExt, 0);
|
Status = NextCluster (DeviceExt, FirstCluster, &CurrentCluster,
|
||||||
|
TRUE);
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
Fcb->entry.FirstClusterHigh = CurrentCluster >> 16;
|
Fcb->entry.FirstClusterHigh = CurrentCluster >> 16;
|
||||||
Fcb->entry.FirstCluster = CurrentCluster;
|
Fcb->entry.FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Fcb->entry.FirstCluster = CurrentCluster;
|
Fcb->entry.FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
else
|
FirstCluster = CurrentCluster;
|
||||||
{
|
|
||||||
for (FileOffset = 0;
|
|
||||||
FileOffset < WriteOffset / DeviceExt->BytesPerCluster;
|
|
||||||
FileOffset++)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
CurrentCluster =
|
|
||||||
GetNextWriteCluster (DeviceExt, CurrentCluster);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
Status = OffsetToCluster(DeviceExt, FirstCluster, WriteOffset,
|
||||||
CHECKPOINT;
|
&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
|
* then we have to write only from the specified offset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((WriteOffset % DeviceExt->BytesPerCluster) != 0)
|
if ((WriteOffset % ChunkSize) != 0)
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
TempLength = min (Length, ChunkSize - (WriteOffset % ChunkSize));
|
||||||
TempLength = min (Length, DeviceExt->BytesPerCluster -
|
if ((Length - TempLength) > 0)
|
||||||
(WriteOffset % DeviceExt->BytesPerCluster));
|
|
||||||
/* Read in the existing cluster data */
|
|
||||||
if (FirstCluster == 1)
|
|
||||||
{
|
{
|
||||||
/* FIXME: Check status */
|
Extend = TRUE;
|
||||||
VfatReadSectors (DeviceExt->StorageDevice,
|
|
||||||
CurrentCluster,
|
|
||||||
DeviceExt->Boot->SectorsPerCluster, Temp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VfatRawReadCluster (DeviceExt, FirstCluster, Temp, CurrentCluster);
|
Extend = FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
}
|
}
|
||||||
|
Status = VfatWriteCluster(DeviceExt,
|
||||||
|
Fcb,
|
||||||
|
ROUND_DOWN(WriteOffset, ChunkSize),
|
||||||
|
FirstCluster,
|
||||||
|
&CurrentCluster,
|
||||||
|
Buffer,
|
||||||
|
NoCache,
|
||||||
|
WriteOffset % ChunkSize,
|
||||||
|
TempLength,
|
||||||
|
Extend);
|
||||||
Buffer = Buffer + TempLength;
|
Buffer = Buffer + TempLength;
|
||||||
|
Length = Length - TempLength;
|
||||||
|
WriteOffset = WriteOffset + TempLength;
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
|
||||||
|
|
||||||
/* Write the buffer in chunks of 1 cluster */
|
while (Length >= ChunkSize)
|
||||||
|
|
||||||
while (Length2 >= DeviceExt->BytesPerCluster)
|
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
if ((Length - ChunkSize) > 0)
|
||||||
if (CurrentCluster == 0)
|
|
||||||
{
|
{
|
||||||
ExFreePool (Temp);
|
Extend = TRUE;
|
||||||
return (STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
Length2 -= DeviceExt->BytesPerCluster;
|
|
||||||
if (FirstCluster == 1)
|
|
||||||
{
|
|
||||||
VfatWriteSectors (DeviceExt->StorageDevice,
|
|
||||||
CurrentCluster,
|
|
||||||
DeviceExt->Boot->SectorsPerCluster, Buffer);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VfatWriteCluster (DeviceExt, Buffer, CurrentCluster);
|
Extend = FALSE;
|
||||||
#if 0
|
|
||||||
if (Length2 > 0)
|
|
||||||
CurrentCluster = GetNextWriteCluster (DeviceExt, CurrentCluster);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
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 */
|
/* Write the remainder */
|
||||||
|
if (Length > 0)
|
||||||
if (Length2 > 0)
|
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
Status = VfatWriteCluster(DeviceExt,
|
||||||
if (CurrentCluster == 0)
|
Fcb,
|
||||||
{
|
ROUND_DOWN(WriteOffset, ChunkSize),
|
||||||
ExFreePool (Temp);
|
FirstCluster,
|
||||||
return (STATUS_UNSUCCESSFUL);
|
&CurrentCluster,
|
||||||
}
|
Buffer,
|
||||||
CHECKPOINT;
|
NoCache,
|
||||||
/* Read in the existing cluster data */
|
0,
|
||||||
if (FirstCluster == 1)
|
Length,
|
||||||
{
|
FALSE);
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set dates and times */
|
/* set dates and times */
|
||||||
|
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
KeQuerySystemTime (&SystemTime);
|
KeQuerySystemTime (&SystemTime);
|
||||||
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
|
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
|
||||||
FsdFileTimeToDosDateTime ((TIME *) & LocalTime,
|
FsdFileTimeToDosDateTime ((TIME*)&LocalTime,
|
||||||
&Fcb->entry.UpdateDate, &Fcb->entry.UpdateTime);
|
&Fcb->entry.UpdateDate,
|
||||||
|
&Fcb->entry.UpdateTime);
|
||||||
Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
|
Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
|
||||||
|
updEntry (DeviceExt, FileObject);
|
||||||
if (Fcb->entry.FileSize < WriteOffset + Length
|
|
||||||
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
{
|
|
||||||
Fcb->entry.FileSize = WriteOffset + Length;
|
|
||||||
/*
|
|
||||||
* update entry in directory
|
|
||||||
*/
|
|
||||||
// updEntry (DeviceExt, FileObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExFreePool (Temp);
|
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,6 +928,7 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG NoCache;
|
||||||
|
|
||||||
DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
|
DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
|
@ -587,7 +936,18 @@ VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
|
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.Status = Status;
|
||||||
Irp->IoStatus.Information = Length;
|
Irp->IoStatus.Information = Length;
|
||||||
|
|
|
@ -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 <ddk/ntifs.h>
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ typedef struct
|
||||||
PDEVICE_OBJECT StorageDevice;
|
PDEVICE_OBJECT StorageDevice;
|
||||||
PFILE_OBJECT StreamStorageDevice;
|
PFILE_OBJECT StreamStorageDevice;
|
||||||
PBCB StorageBcb;
|
PBCB StorageBcb;
|
||||||
|
PFILE_OBJECT Fat12StorageDevice;
|
||||||
|
PBCB Fat12StorageBcb;
|
||||||
BootSector *Boot;
|
BootSector *Boot;
|
||||||
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
||||||
int FATEntriesPerSector, FATUnit;
|
int FATEntriesPerSector, FATUnit;
|
||||||
|
@ -153,6 +155,12 @@ NTSTATUS STDCALL
|
||||||
VfatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
VfatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
ULONG FirstCluster,
|
||||||
|
PULONG CurrentCluster,
|
||||||
|
BOOLEAN Extend);
|
||||||
|
|
||||||
/* internal functions in blockdev.c */
|
/* internal functions in blockdev.c */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
VfatReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
|
@ -188,9 +196,11 @@ VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PULONG LengthRead, ULONG NoCache);
|
PULONG LengthRead, ULONG NoCache);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PVOID Buffer, ULONG Length, ULONG WriteOffset);
|
PVOID Buffer, ULONG Length, ULONG WriteOffset, ULONG NoCache);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster,
|
GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
ULONG FirstCluster,
|
||||||
|
ULONG CurrentCluster,
|
||||||
PULONG NextCluster);
|
PULONG NextCluster);
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsDeletedEntry(PVOID Block, ULONG Offset);
|
IsDeletedEntry(PVOID Block, ULONG Offset);
|
||||||
|
@ -199,7 +209,8 @@ IsLastEntry(PVOID Block, ULONG Offset);
|
||||||
wchar_t*
|
wchar_t*
|
||||||
vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
|
VfatRawWriteCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
ULONG FirstCluster, PVOID Buffer, ULONG Cluster);
|
||||||
|
|
||||||
/* internal functions in dirwr.c */
|
/* internal functions in dirwr.c */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -236,7 +247,8 @@ ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
GetNextCluster(PDEVICE_EXTENSION DeviceExt,
|
GetNextCluster(PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG CurrentCluster,
|
ULONG CurrentCluster,
|
||||||
PULONG NextCluster);
|
PULONG NextCluster,
|
||||||
|
BOOLEAN Extend);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
|
VfatRawReadCluster (PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG FirstCluster,
|
ULONG FirstCluster,
|
||||||
|
@ -269,6 +281,9 @@ VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
|
ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
|
||||||
|
NTSTATUS
|
||||||
|
VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
PWSTR FileName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* functions from shutdown.c
|
* functions from shutdown.c
|
||||||
|
|
|
@ -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/vga/display/vgaddi.dll $1/reactos/system32/drivers
|
||||||
cp services/dd/vidport/vidport.sys $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 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/ntdll/ntdll.dll $1/reactos/system32
|
||||||
cp lib/kernel32/kernel32.dll $1/reactos/system32
|
cp lib/kernel32/kernel32.dll $1/reactos/system32
|
||||||
cp lib/crtdll/crtdll.dll $1/reactos/system32
|
cp lib/crtdll/crtdll.dll $1/reactos/system32
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -101,8 +101,6 @@ WINBOOL STDCALL ReadFile(HANDLE hFile,
|
||||||
PIO_STATUS_BLOCK IoStatusBlock;
|
PIO_STATUS_BLOCK IoStatusBlock;
|
||||||
PLARGE_INTEGER ptrOffset;
|
PLARGE_INTEGER ptrOffset;
|
||||||
|
|
||||||
DbgPrint("ReadFile(hFile %x)\n", hFile);
|
|
||||||
|
|
||||||
if (IsConsoleHandle(hFile))
|
if (IsConsoleHandle(hFile))
|
||||||
{
|
{
|
||||||
return(ReadConsoleA(hFile,
|
return(ReadConsoleA(hFile,
|
||||||
|
|
|
@ -101,6 +101,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
MmPageArray[i].SavedSwapEntry = 0;
|
MmPageArray[i].SavedSwapEntry = 0;
|
||||||
InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry);
|
InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry);
|
||||||
}
|
}
|
||||||
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
return((PVOID)(start * 4096));
|
return((PVOID)(start * 4096));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ DIST_DIR = dist
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CC = $(PREFIX)gcc
|
CC = $(PREFIX)gcc
|
||||||
|
CXX = $(PREFIX)g++
|
||||||
HOST_CC = gcc
|
HOST_CC = gcc
|
||||||
HOST_NM = nm
|
HOST_NM = nm
|
||||||
CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe
|
CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe
|
||||||
|
|
Loading…
Reference in a new issue