Put in updated version of bitops header

Corrected bug in loader with mapping sections with zero VirtualSize
Corrected bug in the vfat driver that accessed freed memory
General cleanup of the vfat driver

svn path=/trunk/; revision=857
This commit is contained in:
David Welch 1999-12-11 21:14:49 +00:00
parent 14ac854378
commit 910f27a570
17 changed files with 2503 additions and 2151 deletions

View file

@ -0,0 +1,658 @@
/* $Id: create.c,v 1.1 1999/12/11 21:14:48 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/create.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset)
/*
* FUNCTION: Determine if the given directory entry is the last
*/
{
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
}
BOOLEAN IsVolEntry(PVOID Block, ULONG Offset)
/*
* FUNCTION: Determine if the given directory entry is a vol entry
*/
{
if( (((FATDirEntry *)Block)[Offset].Attrib)==0x28 ) return TRUE;
else return FALSE;
}
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
/*
* FUNCTION: Determines if the given entry is a deleted one
*/
{
/* Checks special character */
return ((((FATDirEntry *)Block)[Offset].Filename[0] == 0xe5));
}
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector)
/*
* FUNCTION: Retrieves the file name, be it in short or long file name format
*/
{
FATDirEntry* test;
slot* test2;
ULONG Offset = *_Offset;
ULONG StartingSector = *_StartingSector;
ULONG jloop = *_jloop;
ULONG cpos;
test = (FATDirEntry *)Block;
test2 = (slot *)Block;
*Name = 0;
if (IsDeletedEntry(Block,Offset))
{
return(FALSE);
}
if(test2[Offset].attr == 0x0f)
{
vfat_initstr(Name, 256);
vfat_wcsncpy(Name,test2[Offset].name0_4,5);
vfat_wcsncat(Name,test2[Offset].name5_10,5,6);
vfat_wcsncat(Name,test2[Offset].name11_12,11,2);
cpos=0;
while((test2[Offset].id!=0x41) && (test2[Offset].id!=0x01) &&
(test2[Offset].attr>0))
{
Offset++;
if(Offset==ENTRIES_PER_SECTOR) {
Offset=0;
StartingSector++;//FIXME : nor always the next sector
jloop++;
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,Block);
test2 = (slot *)Block;
}
cpos++;
vfat_movstr(Name, 13, 0, cpos*13);
vfat_wcsncpy(Name, test2[Offset].name0_4, 5);
vfat_wcsncat(Name,test2[Offset].name5_10,5,6);
vfat_wcsncat(Name,test2[Offset].name11_12,11,2);
}
if (IsDeletedEntry(Block,Offset+1))
{
Offset++;
*_Offset = Offset;
*_jloop = jloop;
*_StartingSector = StartingSector;
return(FALSE);
}
*_Offset = Offset;
*_jloop = jloop;
*_StartingSector = StartingSector;
return(TRUE);
}
RtlAnsiToUnicode(Name,test[Offset].Filename,8);
if (test[Offset].Ext[0]!=' ')
{
RtlCatAnsiToUnicode(Name,".",1);
}
RtlCatAnsiToUnicode(Name,test[Offset].Ext,3);
*_Offset = Offset;
return(TRUE);
}
NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb)
/*
* FUNCTION: Read the volume label
*/
{
ULONG i = 0;
ULONG j;
ULONG Size;
char* block;
ULONG StartingSector;
ULONG NextCluster;
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
StartingSector = DeviceExt->rootStart;
NextCluster=0;
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
DPRINT("FindFile : start at sector %lx, entry %ld\n",StartingSector,i);
for (j=0; j<Size; j++)
{
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
for (i=0; i<ENTRIES_PER_SECTOR; i++)
{
if (IsVolEntry((PVOID)block,i))
{
FATDirEntry *test = (FATDirEntry *)block;
/* copy volume label */
RtlAnsiToUnicode(Vpb->VolumeLabel,test[i].Filename,8);
RtlCatAnsiToUnicode(Vpb->VolumeLabel,test[i].Ext,3);
Vpb->VolumeLabelLength = wcslen(Vpb->VolumeLabel);
ExFreePool(block);
return(STATUS_SUCCESS);
}
if (IsLastEntry((PVOID)block,i))
{
*(Vpb->VolumeLabel) = 0;
Vpb->VolumeLabelLength = 0;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
}
// not found in this sector, try next :
/* directory can be fragmented although it is best to keep them
unfragmented */
StartingSector++;
if (DeviceExt->FatType ==FAT32)
{
if(StartingSector==ClusterToSector(DeviceExt,NextCluster+1))
{
NextCluster = GetNextCluster(DeviceExt,NextCluster);
if (NextCluster == 0||NextCluster==0xffffffff)
{
*(Vpb->VolumeLabel) = 0;
Vpb->VolumeLabelLength = 0;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
StartingSector = ClusterToSector(DeviceExt,NextCluster);
}
}
}
*(Vpb->VolumeLabel) = 0;
Vpb->VolumeLabelLength = 0;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry)
/*
* FUNCTION: Find a file
*/
{
ULONG i, j;
ULONG Size;
char* block;
WCHAR name[256];
ULONG StartingSector;
ULONG NextCluster;
WCHAR TempStr[2];
DPRINT("FindFile(Parent %x, FileToFind '%w')\n",Parent,FileToFind);
if (wcslen(FileToFind)==0)
{
CHECKPOINT;
TempStr[0] = (WCHAR)'.';
TempStr[1] = 0;
FileToFind=(PWSTR)&TempStr;
}
if (Parent != NULL)
{
DPRINT("Parent->entry.FirstCluster %d\n",Parent->entry.FirstCluster);
}
DPRINT("FindFile '%w'\n", FileToFind);
if (Parent == NULL||Parent->entry.FirstCluster==1)
{
CHECKPOINT;
Size = DeviceExt->rootDirectorySectors; /* FIXME : in fat32, no limit */
StartingSector = DeviceExt->rootStart;
NextCluster=0;
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0) ||
(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;
Fcb->entry.Attrib=FILE_ATTRIBUTE_DIRECTORY;
if (DeviceExt->FatType == FAT32)
Fcb->entry.FirstCluster=2;
else
Fcb->entry.FirstCluster=1; /* FIXME : is 1 the good value for mark root? */
if(StartSector)
*StartSector=StartingSector;
if(Entry)
*Entry=0;
return(STATUS_SUCCESS);
}
}
else
{
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
Size = ULONG_MAX;
if (DeviceExt->FatType == FAT32)
NextCluster = Parent->entry.FirstCluster
+Parent->entry.FirstClusterHigh*65536;
else
NextCluster = Parent->entry.FirstCluster;
StartingSector = ClusterToSector(DeviceExt, NextCluster);
if(Parent->entry.FirstCluster==1 && DeviceExt->FatType!=FAT32)
{
/* read of root directory in FAT16 or FAT12 */
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++)
{
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
for (i=(Entry)?(*Entry):0; i<ENTRIES_PER_SECTOR; i++)
{
if (IsVolEntry((PVOID)block,i))
continue;
if (IsLastEntry((PVOID)block,i))
{
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
{
DPRINT("Comparing '%w' '%w'\n",name,FileToFind);
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 */
if(((FATDirEntry *)block)[i].Attrib==0x0f) i++;
if( i==(ENTRIES_PER_SECTOR))
{
/* entry is in next sector */
StartingSector++;
/* FIXME : treat case of next sector fragmented */
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
i=0;
}
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
sizeof(FATDirEntry));
vfat_wcsncpy(Fcb->ObjectName,name,MAX_PATH);
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_SUCCESS);
}
}
}
/* not found in this sector, try next : */
/* directory can be fragmented although it is best to keep them
unfragmented */
if(Entry) *Entry=0;
StartingSector++;
if ((Parent != NULL && Parent->entry.FirstCluster!=1)
|| DeviceExt->FatType ==FAT32)
{
if(StartingSector==ClusterToSector(DeviceExt,NextCluster+1))
{
NextCluster = GetNextCluster(DeviceExt,NextCluster);
if (NextCluster == 0||NextCluster==0xffffffff)
{
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
StartingSector = ClusterToSector(DeviceExt,NextCluster);
}
}
}
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
{
PVFATFCB pFcb;
PVFATCCB pCcb;
KIRQL oldIrql;
DPRINT("FsdCloseFile(DeviceExt %x, FileObject %x)\n",
DeviceExt,FileObject);
//FIXME : update entry in directory ?
pCcb = (PVFATCCB)(FileObject->FsContext2);
DPRINT("pCcb %x\n",pCcb);
if (pCcb == NULL)
{
return(STATUS_SUCCESS);
}
pFcb = pCcb->pFcb;
pFcb->RefCount--;
if(pFcb->RefCount<=0)
{
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
RemoveEntryList(&pFcb->FcbListEntry);
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
ExFreePool(pFcb);
}
ExFreePool(pCcb);
return STATUS_SUCCESS;
}
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
{
PWSTR current = NULL;
PWSTR next;
PWSTR string;
PVFATFCB ParentFcb;
PVFATFCB Fcb,pRelFcb;
PVFATFCB Temp;
PVFATCCB newCCB,pRelCcb;
NTSTATUS Status;
PFILE_OBJECT pRelFileObject;
PWSTR AbsFileName=NULL;
short i,j;
PLIST_ENTRY current_entry;
KIRQL oldIrql;
DPRINT("FsdOpenFile(%08lx, %08lx, %w)\n",
DeviceExt,
FileObject,
FileName);
/* FIXME : treat relative name */
if(FileObject->RelatedFileObject)
{
DbgPrint("try related for %w\n",FileName);
pRelFileObject=FileObject->RelatedFileObject;
pRelCcb=pRelFileObject->FsContext2;
assert(pRelCcb);
pRelFcb=pRelCcb->pFcb;
assert(pRelFcb);
/*
* verify related object is a directory and target name don't start with \.
*/
if( !(pRelFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|| (FileName[0]!= '\\') )
{
Status=STATUS_INVALID_PARAMETER;
return Status;
}
/* construct absolute path name */
AbsFileName=ExAllocatePool(NonPagedPool,MAX_PATH);
for (i=0;pRelFcb->PathName[i];i++)
AbsFileName[i]=pRelFcb->PathName[i];
AbsFileName[i++]='\\';
for (j=0;FileName[j]&&i<MAX_PATH;j++)
AbsFileName[i++]=FileName[j];
assert(i<MAX_PATH);
AbsFileName[i]=0;
FileName=AbsFileName;
}
/*
* try first to find an existing FCB in memory
*/
CHECKPOINT;
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
current_entry = DeviceExt->FcbListHead.Flink;
while (current_entry != &DeviceExt->FcbListHead)
{
Fcb = CONTAINING_RECORD(current_entry, VFATFCB, FcbListEntry);
DPRINT("Scanning %x\n", Fcb);
DPRINT("Scanning %w\n", Fcb->PathName);
if (DeviceExt==Fcb->pDevExt
&& wstrcmpi(FileName,Fcb->PathName))
{
Fcb->RefCount++;
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
FileObject->FsContext =(PVOID) &Fcb->NTRequiredFCB;
newCCB = ExAllocatePool(NonPagedPool,sizeof(VFATCCB));
memset(newCCB,0,sizeof(VFATCCB));
FileObject->FsContext2 = newCCB;
newCCB->pFcb=Fcb;
newCCB->PtrFileObject=FileObject;
if(AbsFileName)ExFreePool(AbsFileName);
return(STATUS_SUCCESS);
}
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
CHECKPOINT;
string = FileName;
ParentFcb = NULL;
Fcb = ExAllocatePool(NonPagedPool, sizeof(VFATFCB));
memset(Fcb,0,sizeof(VFATFCB));
Fcb->ObjectName=Fcb->PathName;
next = &string[0];
CHECKPOINT;
while (next!=NULL)
{
CHECKPOINT;
*next = '\\';
current = next+1;
next = wcschr(next+1,'\\');
if (next!=NULL)
{
*next=0;
}
DPRINT("current '%w'\n",current);
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
if (Status != STATUS_SUCCESS)
{
CHECKPOINT;
if (Fcb != NULL)
ExFreePool(Fcb);
if (ParentFcb != NULL)
ExFreePool(ParentFcb);
if(AbsFileName)
ExFreePool(AbsFileName);
return(Status);
}
Temp = Fcb;
CHECKPOINT;
if (ParentFcb == NULL)
{
CHECKPOINT;
Fcb = ExAllocatePool(NonPagedPool,sizeof(VFATFCB));
memset(Fcb,0,sizeof(VFATFCB));
Fcb->ObjectName=Fcb->PathName;
}
else
Fcb = ParentFcb;
CHECKPOINT;
ParentFcb = Temp;
}
CHECKPOINT;
FileObject->FsContext =(PVOID) &ParentFcb->NTRequiredFCB;
newCCB = ExAllocatePool(NonPagedPool,sizeof(VFATCCB));
memset(newCCB,0,sizeof(VFATCCB));
FileObject->FsContext2 = newCCB;
newCCB->pFcb=ParentFcb;
newCCB->PtrFileObject=FileObject;
ParentFcb->RefCount++;
//FIXME : initialize all fields in FCB and CCB
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
InsertTailList(&DeviceExt->FcbListHead, &ParentFcb->FcbListEntry);
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
vfat_wcsncpy(ParentFcb->PathName,FileName,MAX_PATH);
ParentFcb->ObjectName=ParentFcb->PathName+(current-FileName);
ParentFcb->pDevExt=DeviceExt;
DPRINT("file open, fcb=%x\n",ParentFcb);
DPRINT("FileSize %d\n",ParentFcb->entry.FileSize);
if(Fcb) ExFreePool(Fcb);
if(AbsFileName)ExFreePool(AbsFileName);
CHECKPOINT;
return(STATUS_SUCCESS);
}
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Close a file
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT("FsdClose(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
Status = FsdCloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Create or open a file
*/
{
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
NTSTATUS Status=STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExt;
ULONG RequestedDisposition,RequestedOptions;
PVFATCCB pCcb;
PVFATFCB pFcb;
assert(DeviceObject);
assert(Irp);
if (DeviceObject->Size==sizeof(DEVICE_OBJECT))
{
/* DeviceObject represent FileSystem instead of logical volume */
DbgPrint("FsdCreate called with file system\n");
Irp->IoStatus.Status=Status;
Irp->IoStatus.Information=FILE_OPENED;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
Stack = IoGetCurrentIrpStackLocation(Irp);
assert(Stack);
RequestedDisposition = ((Stack->Parameters.Create.Options>>24)&0xff);
RequestedOptions=Stack->Parameters.Create.Options&FILE_VALID_OPTION_FLAGS;
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
assert(DeviceExt);
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
CHECKPOINT;
Irp->IoStatus.Information = 0;
if(!NT_SUCCESS(Status))
{
if(RequestedDisposition==FILE_CREATE
||RequestedDisposition==FILE_OPEN_IF
||RequestedDisposition==FILE_OVERWRITE_IF)
{
CHECKPOINT;
Status=addEntry(DeviceExt,FileObject,RequestedOptions
,(Stack->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_VALID_FLAGS));
if(NT_SUCCESS(Status))
Irp->IoStatus.Information = FILE_CREATED;
// FIXME set size if AllocationSize requested
// FIXME set extended attributes ?
// FIXME set share access
// IoSetShareAccess(DesiredAccess,ShareAccess,FileObject
// ,((PVfatCCB)(FileObject->FsContext2))->pFcb->FCBShareAccess);
}
}
else
{
if(RequestedDisposition==FILE_CREATE)
{
Irp->IoStatus.Information = FILE_EXISTS;
Status=STATUS_OBJECT_NAME_COLLISION;
}
pCcb=FileObject->FsContext2;
pFcb=pCcb->pFcb;
if( (RequestedOptions&FILE_NON_DIRECTORY_FILE)
&& (pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
Status=STATUS_FILE_IS_A_DIRECTORY;
}
if( (RequestedOptions&FILE_DIRECTORY_FILE)
&& !(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
Status=STATUS_NOT_A_DIRECTORY;
}
// FIXME : test share access
// FIXME : test write access if requested
if(!NT_SUCCESS(Status))
FsdCloseFile(DeviceExt,FileObject);
else Irp->IoStatus.Information = FILE_OPENED;
// FIXME : make supersed or overwrite if requested
}
CHECKPOINT;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
ExReleaseResourceLite(&DeviceExt->DirResource);
return Status;
}

View file

@ -62,7 +62,7 @@ unsigned long vfat_wstrlen(PWSTR s)
}
#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) )
NTSTATUS FsdGetFileNameInformation(PVfatFCB pFcb,
NTSTATUS FsdGetFileNameInformation(PVFATFCB pFcb,
PFILE_NAMES_INFORMATION pInfo,ULONG BufferLength)
{
ULONG Length;
@ -76,7 +76,7 @@ NTSTATUS FsdGetFileNameInformation(PVfatFCB pFcb,
return STATUS_SUCCESS;
}
NTSTATUS FsdGetFileDirectoryInformation(PVfatFCB pFcb,
NTSTATUS FsdGetFileDirectoryInformation(PVFATFCB pFcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
{
@ -109,7 +109,7 @@ NTSTATUS FsdGetFileDirectoryInformation(PVfatFCB pFcb,
return STATUS_SUCCESS;
}
NTSTATUS FsdGetFileFullDirectoryInformation(PVfatFCB pFcb,
NTSTATUS FsdGetFileFullDirectoryInformation(PVFATFCB pFcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_FULL_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
{
@ -142,7 +142,7 @@ NTSTATUS FsdGetFileFullDirectoryInformation(PVfatFCB pFcb,
return STATUS_SUCCESS;
}
NTSTATUS FsdGetFileBothInformation(PVfatFCB pFcb,
NTSTATUS FsdGetFileBothInformation(PVFATFCB pFcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_BOTH_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
{
@ -193,9 +193,9 @@ NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION Stack)
unsigned char *Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
PFILE_OBJECT pFileObject = NULL;
PVfatFCB pFcb;
VfatFCB tmpFcb;
PVfatCCB pCcb;
PVFATFCB pFcb;
VFATFCB tmpFcb;
PVFATCCB pCcb;
PDEVICE_EXTENSION DeviceExt;
WCHAR star[5],*pCharPattern;
unsigned long OldEntry,OldSector;
@ -206,7 +206,7 @@ NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION Stack)
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
pFileObject = Stack->FileObject;
pCcb =(PVfatCCB)pFileObject->FsContext2;
pCcb =(PVFATCCB)pFileObject->FsContext2;
pFcb = pCcb->pFcb;
if(Stack->Flags & SL_RESTART_SCAN)
{//FIXME : what is really use of RestartScan ?

View file

@ -25,17 +25,17 @@ NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject)
*/
{
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
VfatFCB FileFcb;
VFATFCB FileFcb;
ULONG Sector=0,Entry=0;
PUCHAR Buffer;
FATDirEntry * pEntries;
NTSTATUS status;
FILE_OBJECT FileObject;
PVfatCCB pDirCcb;
PVfatFCB pDirFcb,pFcb;
PVFATCCB pDirCcb;
PVFATFCB pDirFcb,pFcb;
short i,posCar,NameLen;
PathFileName=pFileObject->FileName.Buffer;
pFcb=((PVfatCCB)pFileObject->FsContext2)->pFcb;
pFcb=((PVFATCCB)pFileObject->FsContext2)->pFcb;
//find last \ in PathFileName
posCar=-1;
for(i=0;PathFileName[i];i++)
@ -52,7 +52,7 @@ NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject)
memset(&FileObject,0,sizeof(FILE_OBJECT));
DPRINT("open directory %w for update of entry %w\n",DirName,FileName);
status=FsdOpenFile(DeviceExt,&FileObject,DirName);
pDirCcb=(PVfatCCB)FileObject.FsContext2;
pDirCcb=(PVFATCCB)FileObject.FsContext2;
assert(pDirCcb);
pDirFcb=pDirCcb->pFcb;
assert(pDirFcb);
@ -79,7 +79,7 @@ NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt
*/
{
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
VfatFCB DirFcb,FileFcb;
VFATFCB DirFcb,FileFcb;
FATDirEntry FatEntry;
NTSTATUS status;
FILE_OBJECT FileObject;
@ -89,9 +89,11 @@ NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt
short nbSlots=0,nbFree=0,i,j,posCar,NameLen;
PUCHAR Buffer,Buffer2;
BOOLEAN needTilde=FALSE,needLong=FALSE;
PVfatFCB newFCB;
PVfatCCB newCCB;
PVFATFCB newFCB;
PVFATCCB newCCB;
ULONG CurrentCluster;
KIRQL oldIrql;
PathFileName=pFileObject->FileName.Buffer;
DPRINT("addEntry: Pathname=%w\n",PathFileName);
//find last \ in PathFileName
@ -297,19 +299,25 @@ DPRINT("i=%d,j=%d,%d,%d\n",i,j,pEntry->Filename[i],FileName[i]);
,sizeof(FATDirEntry)*(nbSlots+1),Offset);
}
DPRINT("write entry offset %d status=%x\n",Offset,status);
newCCB = ExAllocatePool(NonPagedPool,sizeof(VfatCCB));
newFCB = ExAllocatePool(NonPagedPool,sizeof(VfatFCB));
memset(newCCB,0,sizeof(VfatCCB));
memset(newFCB,0,sizeof(VfatFCB));
newCCB = ExAllocatePool(NonPagedPool,sizeof(VFATCCB));
newFCB = ExAllocatePool(NonPagedPool,sizeof(VFATFCB));
memset(newCCB,0,sizeof(VFATCCB));
memset(newFCB,0,sizeof(VFATFCB));
newCCB->pFcb=newFCB;
newCCB->PtrFileObject=pFileObject;
newFCB->RefCount++;
//FIXME : initialize all fields in FCB and CCB
newFCB->nextFcb=pFirstFcb;
/*
* FIXME : initialize all fields in FCB and CCB
*/
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
InsertTailList(&DeviceExt->FcbListHead, &newFCB->FcbListEntry);
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
memcpy(&newFCB->entry,pEntry,sizeof(FATDirEntry));
DPRINT("new : entry=%11.11s\n",newFCB->entry.Filename);
DPRINT("new : entry=%11.11s\n",pEntry->Filename);
pFirstFcb=newFCB;
vfat_wcsncpy(newFCB->PathName,PathFileName,MAX_PATH);
newFCB->ObjectName=newFCB->PathName+(PathFileName-FileName);
newFCB->pDevExt=DeviceExt;
@ -322,9 +330,9 @@ DPRINT("new : entry=%11.11s\n",pEntry->Filename);
status=FsdWriteFile(DeviceExt,pFileObject,pEntry
,sizeof(FATDirEntry),0L);
pEntry->FirstCluster
=((VfatCCB *)(FileObject.FsContext2))->pFcb->entry.FirstCluster;
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstCluster;
pEntry->FirstClusterHigh
=((VfatCCB *)(FileObject.FsContext2))->pFcb->entry.FirstClusterHigh;
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstClusterHigh;
memcpy(pEntry->Filename,".. ",11);
if(pEntry->FirstCluster==1 && DeviceExt->FatType!=FAT32)
pEntry->FirstCluster=0;

View file

@ -0,0 +1,478 @@
/*
* $Id: fat.c,v 1.1 1999/12/11 21:14:48 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/fat.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
/*
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
* disk read
*/
{
ULONG FATsector;
ULONG FATeis;
PULONG Block;
Block = ExAllocatePool(NonPagedPool,1024);
FATsector=CurrentCluster/(512/sizeof(ULONG));
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
VFATReadSectors(DeviceExt->StorageDevice
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
CurrentCluster = Block[FATeis];
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0xffffffff;
ExFreePool(Block);
return(CurrentCluster);
}
ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
/*
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table from the
* in-memory FAT
*/
{
PUSHORT Block;
Block=(PUSHORT)DeviceExt->FAT;
CurrentCluster = Block[CurrentCluster];
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
CurrentCluster = 0xffffffff;
DPRINT("Returning %x\n",CurrentCluster);
return(CurrentCluster);
}
ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
/*
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table from the
* in-memory FAT
*/
{
unsigned char* CBlock;
ULONG FATOffset;
ULONG Entry;
CBlock = DeviceExt->FAT;
FATOffset = (CurrentCluster * 12)/ 8;//first byte containing value
if ((CurrentCluster % 2) == 0)
{
Entry = CBlock[FATOffset];
Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
}
else
{
Entry = (CBlock[FATOffset] >> 4);
Entry |= (CBlock[FATOffset+1] << 4);
}
DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
Entry = 0xffffffff;
DPRINT("Returning %x\n",Entry);
return(Entry);
}
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
/*
* FUNCTION: Retrieve the next cluster depending on the FAT type
*/
{
ULONG NextCluster;
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
DeviceExt,CurrentCluster);
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
if (DeviceExt->FatType == FAT16)
{
NextCluster = Fat16GetNextCluster(DeviceExt, CurrentCluster);
}
else if (DeviceExt->FatType == FAT32)
{
NextCluster = Fat32GetNextCluster(DeviceExt, CurrentCluster);
}
else
{
NextCluster = Fat12GetNextCluster(DeviceExt, CurrentCluster);
}
ExReleaseResourceLite(&DeviceExt->FatResource);
return(NextCluster);
}
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Finds the first available cluster in a FAT16 table
*/
{
PUSHORT Block;
int i;
Block=(PUSHORT)DeviceExt->FAT;
for(i=2;i<(DeviceExt->Boot->FATSectors*256) ;i++)
if(Block[i]==0)
return (i);
/* Give an error message (out of disk space) if we reach here) */
return 0;
}
ULONG FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Finds the first available cluster in a FAT12 table
*/
{
ULONG FATOffset;
ULONG Entry;
PUCHAR CBlock=DeviceExt->FAT;
ULONG i;
for(i=2;i<((DeviceExt->Boot->FATSectors*512*8)/12) ;i++)
{
FATOffset = (i * 12)/8;
if ((i % 2) == 0)
{
Entry = CBlock[FATOffset];
Entry |= ((CBlock[FATOffset + 1] & 0xf)<<8);
}
else
{
Entry = (CBlock[FATOffset] >> 4);
Entry |= (CBlock[FATOffset + 1] << 4);
}
if(Entry==0)
return (i);
}
/* Give an error message (out of disk space) if we reach here) */
DbgPrint("Disk full, %d clusters used\n",i);
return 0;
}
ULONG FAT32FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Finds the first available cluster in a FAT32 table
*/
{
ULONG sector;
PULONG Block;
int i;
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
for(sector=0
;sector< ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32
;sector++)
{
VFATReadSectors(DeviceExt->StorageDevice
,(ULONG)(DeviceExt->FATStart+sector), 1,(UCHAR*) Block);
for(i=0; i<512; i++)
{
if(Block[i]==0)
{
ExFreePool(Block);
return (i+sector*128);
}
}
}
/* Give an error message (out of disk space) if we reach here) */
ExFreePool(Block);
return 0;
}
ULONG FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free cluster in a FAT12 table
*/
{
ULONG FATOffset;
ULONG Entry;
PUCHAR CBlock=DeviceExt->FAT;
ULONG ulCount = 0;
ULONG i;
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
for(i=2;i<((DeviceExt->Boot->FATSectors*512*8)/12) ;i++)
{
FATOffset = (i * 12)/8;
if ((i % 2) == 0)
{
Entry = CBlock[FATOffset];
Entry |= ((CBlock[FATOffset + 1] & 0xf)<<8);
}
else
{
Entry = (CBlock[FATOffset] >> 4);
Entry |= (CBlock[FATOffset + 1] << 4);
}
if(Entry==0)
ulCount++;
}
ExReleaseResourceLite(&DeviceExt->FatResource);
return ulCount;
}
ULONG FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT16 table
*/
{
PUSHORT Block;
ULONG ulCount = 0;
ULONG i;
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
Block=(PUSHORT)DeviceExt->FAT;
for(i=2;i<(DeviceExt->Boot->FATSectors*256);i++)
{
if(Block[i]==0)
ulCount++;
}
ExReleaseResourceLite(&DeviceExt->FatResource);
return ulCount;
}
ULONG FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
/*
* FUNCTION: Counts free clusters in a FAT32 table
*/
{
ULONG sector;
PULONG Block;
ULONG ulCount = 0;
ULONG i;
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
for(sector=0
;sector< ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32
;sector++)
{
VFATReadSectors(DeviceExt->StorageDevice
,(ULONG)(DeviceExt->FATStart+sector), 1,(UCHAR*) Block);
for(i=0; i<512; i++)
{
if(Block[i]==0)
ulCount++;
}
}
/* Give an error message (out of disk space) if we reach here) */
ExFreePool(Block);
ExReleaseResourceLite(&DeviceExt->FatResource);
return ulCount;
}
void FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
ULONG NewValue)
/*
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
*/
{
ULONG FATsector;
ULONG FATOffset;
PUCHAR CBlock=DeviceExt->FAT;
int i;
FATOffset = (ClusterToWrite * 12)/8;
if ((ClusterToWrite % 2) == 0)
{
CBlock[FATOffset]=NewValue;
CBlock[FATOffset + 1] &=0xf0;
CBlock[FATOffset + 1]
|= (NewValue&0xf00)>>8;
}
else
{
CBlock[FATOffset] &=0x0f;
CBlock[FATOffset]
|= (NewValue&0xf)<<4;
CBlock[FATOffset+1]=NewValue>>4;
}
/* Write the changed FAT sector(s) to disk */
FATsector=FATOffset/BLOCKSIZE;
for(i=0;i<DeviceExt->Boot->FATCount;i++)
{
if( (FATOffset%BLOCKSIZE)==(BLOCKSIZE-1))//entry is on 2 sectors
{
VFATWriteSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector
+i*DeviceExt->Boot->FATSectors,
2,
CBlock+FATsector*512);
}
else
{
VFATWriteSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector
+i*DeviceExt->Boot->FATSectors,
1,
CBlock+FATsector*512);
}
}
}
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
ULONG NewValue)
/*
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
*/
{
ULONG FATsector;
PUSHORT Block;
DbgPrint("FAT16WriteCluster %u : %u\n",ClusterToWrite,NewValue);
Block=(PUSHORT)DeviceExt->FAT;
FATsector=ClusterToWrite/(512/sizeof(USHORT));
/* Update the in-memory FAT */
Block[ClusterToWrite] = NewValue;
/* Write the changed FAT sector to disk */
VFATWriteSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector,
1,
(UCHAR *)Block);
}
void FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
ULONG NewValue)
/*
* FUNCTION: Writes a cluster to the FAT32 physical tables
*/
{
ULONG FATsector;
ULONG FATeis;
PUSHORT Block;
DbgPrint("FAT32WriteCluster %u : %u\n",ClusterToWrite,NewValue);
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
FATsector=ClusterToWrite/128;
FATeis=ClusterToWrite-(FATsector*128);
/* load sector, change value, then rewrite sector */
VFATReadSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector,
1,
(UCHAR *)Block);
Block[FATeis] = NewValue;
VFATWriteSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector,
1,
(UCHAR *)Block);
ExFreePool(Block);
}
void WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
ULONG NewValue)
/*
* FUNCTION: Write a changed FAT entry
*/
{
if(DeviceExt->FatType==FAT16)
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
else if(DeviceExt->FatType==FAT32)
FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue);
else
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
}
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
/*
* FUNCTION: Determines the next cluster to be written
*/
{
ULONG LastCluster, NewCluster;
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
DeviceExt,CurrentCluster);
/* Find out what was happening in the last cluster's AU */
LastCluster=GetNextCluster(DeviceExt,CurrentCluster);
/* 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)
NewCluster = FAT16FindAvailableCluster(DeviceExt);
else if(DeviceExt->FatType == FAT32)
NewCluster = FAT32FindAvailableCluster(DeviceExt);
else
NewCluster = FAT12FindAvailableCluster(DeviceExt);
/* 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 */
if(CurrentCluster)
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
/* Return NewCluster as CurrentCluster */
return NewCluster;
}
else
{
/* Overwrite: Return LastCluster as CurrentCluster */
return LastCluster;
}
}
ULONG ClusterToSector(PDEVICE_EXTENSION DeviceExt,
unsigned long Cluster)
/*
* FUNCTION: Converts the cluster number to a sector number for this physical
* device
*/
{
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
}
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
/*
* FUNCTION: Load a cluster from the physical device
*/
{
ULONG Sector;
DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster);
VFATReadSectors(DeviceExt->StorageDevice,
Sector,
DeviceExt->Boot->SectorsPerCluster,
Buffer);
DPRINT("Finished VFATReadSectors\n");
}
void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
/*
* FUNCTION: Write a cluster to the physical device
*/
{
ULONG Sector;
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster);
VFATWriteSectors(DeviceExt->StorageDevice,
Sector,
DeviceExt->Boot->SectorsPerCluster,
Buffer);
}

View file

@ -0,0 +1,249 @@
/* $Id: finfo.c,v 1.1 1999/12/11 21:14:48 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/finfo.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS FsdGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
PFILE_STANDARD_INFORMATION StandardInfo)
/*
* FUNCTION: Retrieve the standard file information
*/
{
PDEVICE_EXTENSION DeviceExtension;
unsigned long AllocSize;
DeviceExtension = DeviceObject->DeviceExtension;
/* PRECONDITION */
assert(DeviceExtension != NULL);
assert(DeviceExtension->BytesPerCluster != 0);
assert(StandardInfo != NULL);
assert(FCB != NULL);
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
/* Make allocsize a rounded up multiple of BytesPerCluster */
AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
DeviceExtension->BytesPerCluster) *
DeviceExtension->BytesPerCluster;
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
StandardInfo->NumberOfLinks = 0;
StandardInfo->DeletePending = FALSE;
if((FCB->entry.Attrib & 0x10)>0) {
StandardInfo->Directory = TRUE;
} else {
StandardInfo->Directory = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS FsdSetPositionInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_POSITION_INFORMATION PositionInfo)
{
DPRINT("FsdSetPositionInformation()\n");
DPRINT("PositionInfo %x\n", PositionInfo);
DPRINT("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
memcpy(&FileObject->CurrentByteOffset,&PositionInfo->CurrentByteOffset,
sizeof(LARGE_INTEGER));
return(STATUS_SUCCESS);
}
NTSTATUS FsdGetPositionInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_POSITION_INFORMATION PositionInfo)
{
DPRINT("FsdGetPositionInformation()\n");
memcpy(&PositionInfo->CurrentByteOffset, &FileObject->CurrentByteOffset,
sizeof(LARGE_INTEGER));
DPRINT("Getting position %x\n", PositionInfo->CurrentByteOffset.u.LowPart);
return(STATUS_SUCCESS);
}
NTSTATUS FsdGetBasicInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_BASIC_INFORMATION BasicInfo)
{
DPRINT("FsdGetBasicInformation()\n");
FsdDosDateTimeToFileTime(FCB->entry.CreationDate,FCB->entry.CreationTime,
&BasicInfo->CreationTime);
FsdDosDateTimeToFileTime(FCB->entry.AccessDate,0,
&BasicInfo->LastAccessTime);
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,FCB->entry.UpdateTime,
&BasicInfo->LastWriteTime);
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,FCB->entry.UpdateTime,
&BasicInfo->ChangeTime);
BasicInfo->FileAttributes = FCB->entry.Attrib;
DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
return(STATUS_SUCCESS);
}
NTSTATUS FsdSetDispositionInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_DISPOSITION_INFORMATION DispositionInfo)
{
DPRINT("FsdSetDispositionInformation()\n");
FileObject->DeletePending = DispositionInfo->DeleteFile;
return(STATUS_SUCCESS);
}
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Retrieve the specified file information
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
FILE_INFORMATION_CLASS FileInformationClass =
Stack->Parameters.QueryFile.FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
void *SystemBuffer;
/* PRECONDITION */
assert(DeviceObject != NULL);
assert(Irp != NULL);
/* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
FileObject = Stack->FileObject;
// CCB = (PVFATCCB)(FileObject->FsContext2);
// FCB = CCB->Buffer; // Should be CCB->FCB???
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
// FIXME : determine Buffer for result :
if (Irp->MdlAddress)
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
SystemBuffer = Irp->UserBuffer;
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
switch(FileInformationClass) {
case FileStandardInformation:
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
break;
case FilePositionInformation:
RC = FsdGetPositionInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer);
break;
case FileBasicInformation:
RC = FsdGetBasicInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer);
break;
default:
RC=STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return RC;
}
NTSTATUS VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Retrieve the specified file information
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer;
/* PRECONDITION */
assert(DeviceObject != NULL);
assert(Irp != NULL);
DPRINT("FsdSetInformation(DeviceObject %x, Irp %x)\n",
DeviceObject,Irp);
/* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
FileObject = Stack->FileObject;
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
// FIXME : determine Buffer for result :
if (Irp->MdlAddress)
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
SystemBuffer = Irp->UserBuffer;
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FileInformationClass %d\n",FileInformationClass);
DPRINT("SystemBuffer %x\n",SystemBuffer);
switch(FileInformationClass)
{
case FilePositionInformation:
RC = FsdSetPositionInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer);
break;
case FileDispositionInformation:
RC = FsdSetDispositionInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer);
break;
default:
RC = STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return RC;
}

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,11 @@
# $Id: makefile,v 1.11 1999/12/04 20:58:44 ea Exp $
# $Id: makefile,v 1.12 1999/12/11 21:14:49 dwelch Exp $
#
#
TARGET=vfatfs
#OBJECTS = blockdev.o dir.o dirwr.o iface.o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
OBJECTS = blockdev.o dir.o dirwr.o iface.o ../../../ntoskrnl/ntoskrnl.a
OBJECTS = blockdev.o dir.o dirwr.o iface.o string.o fat.o rw.o finfo.o \
volume.o create.o
LIBS = ../../../ntoskrnl/ntoskrnl.a
BASE_CFLAGS = -I../../../include
@ -24,7 +25,7 @@ ifeq ($(DOSCLI),yes)
- $(RM) temp.exp
- $(RM) $(TARGET).sys
else
- $(RM) blockdev.o dir.o dirwr.o iface.o $(TARGET).coff junk.tmp base.tmp temp.exp $(TARGET).sys
- $(RM) $(OBJECTS) $(TARGET).coff junk.tmp base.tmp temp.exp $(TARGET).sys
endif
.phony: clean
@ -47,7 +48,7 @@ else
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
endif
$(TARGET).sys: $(OBJECTS)
$(TARGET).sys: $(OBJECTS) $(LIBS)
$(CC) \
-specs=../../svc_specs \
-mdll \
@ -57,7 +58,7 @@ $(TARGET).sys: $(OBJECTS)
-Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp \
-Wl,"-h vfatfs.sys" \
$(OBJECTS)
$(OBJECTS) $(LIBS)
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGET).sys \
@ -74,8 +75,9 @@ $(TARGET).sys: $(OBJECTS)
-specs=../../svc_specs \
-mdll \
-o $(TARGET).sys \
$(OBJECTS)
$(OBJECTS) $(LIBS)
- $(RM) temp.exp
WARNINGS_ARE_ERRORS = yes
include ../../../rules.mak

View file

@ -0,0 +1,385 @@
/* $Id: rw.c,v 1.1 1999/12/11 21:14:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/rw.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG ReadOffset,
PULONG LengthRead)
/*
* FUNCTION: Reads data from a file
*/
{
ULONG CurrentCluster;
ULONG FileOffset;
ULONG FirstCluster;
PVFATFCB Fcb;
PVOID Temp;
ULONG TempLength;
/* PRECONDITION */
assert(DeviceExt != NULL);
assert(DeviceExt->BytesPerCluster != 0);
assert(FileObject != NULL);
assert(FileObject->FsContext != NULL);
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
Length,ReadOffset);
Fcb = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster
+Fcb->entry.FirstClusterHigh*65536;
else
CurrentCluster = Fcb->entry.FirstCluster;
FirstCluster=CurrentCluster;
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
{
return(STATUS_FILE_IS_A_DIRECTORY);
}
if (ReadOffset >= Fcb->entry.FileSize
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
return(STATUS_END_OF_FILE);
}
if ((ReadOffset + Length) > Fcb->entry.FileSize
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
{
Length = Fcb->entry.FileSize - ReadOffset;
}
*LengthRead = 0;
/* FIXME: optimize by remembering the last cluster read and using if possible */
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
if(!Temp) return STATUS_UNSUCCESSFUL;
if (FirstCluster==1)
{ //root of FAT16 or FAT12
CurrentCluster=DeviceExt->rootStart+ReadOffset
/(DeviceExt->BytesPerCluster)*DeviceExt->Boot->SectorsPerCluster;
}
else
for (FileOffset=0; FileOffset < ReadOffset / DeviceExt->BytesPerCluster
; FileOffset++)
{
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
}
CHECKPOINT;
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
{
if (FirstCluster==1)
{
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
}
TempLength = min(Length,DeviceExt->BytesPerCluster -
(ReadOffset % DeviceExt->BytesPerCluster));
memcpy(Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
TempLength);
(*LengthRead) = (*LengthRead) + TempLength;
Length = Length - TempLength;
Buffer = Buffer + TempLength;
}
CHECKPOINT;
while (Length >= DeviceExt->BytesPerCluster)
{
if (FirstCluster==1)
{
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Buffer);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATLoadCluster(DeviceExt,Buffer,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
}
if (CurrentCluster == 0xffffffff)
{
ExFreePool(Temp);
return(STATUS_SUCCESS);
}
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
Buffer = Buffer + DeviceExt->BytesPerCluster;
Length = Length - DeviceExt->BytesPerCluster;
}
CHECKPOINT;
if (Length > 0)
{
(*LengthRead) = (*LengthRead) + Length;
if (FirstCluster==1)
{
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
}
memcpy(Buffer, Temp, Length);
}
ExFreePool(Temp);
return(STATUS_SUCCESS);
}
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG WriteOffset)
/*
* FUNCTION: Writes data to file
*/
{
ULONG CurrentCluster;
ULONG FileOffset;
ULONG FirstCluster;
PVFATFCB Fcb;
PVFATCCB pCcb;
PVOID Temp;
ULONG TempLength,Length2=Length;
/* Locate the first cluster of the file */
assert(FileObject);
pCcb=(PVFATCCB)(FileObject->FsContext2);
assert(pCcb);
Fcb = pCcb->pFcb;
assert(Fcb);
if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
else
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)
{ //root of FAT16 or FAT12
CurrentCluster=DeviceExt->rootStart+WriteOffset
/DeviceExt->BytesPerCluster*DeviceExt->Boot->SectorsPerCluster;
}
else
if (CurrentCluster==0)
{// file of size 0 : allocate first cluster
CurrentCluster=GetNextWriteCluster(DeviceExt,0);
if (DeviceExt->FatType == FAT32)
{
Fcb->entry.FirstClusterHigh=CurrentCluster>>16;
Fcb->entry.FirstCluster=CurrentCluster;
}
else
Fcb->entry.FirstCluster=CurrentCluster;
}
else
for (FileOffset=0; FileOffset < WriteOffset / DeviceExt->BytesPerCluster; FileOffset++)
{
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
}
CHECKPOINT;
/*
If the offset in the cluster doesn't fall on the cluster boundary then
we have to write only from the specified offset
*/
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
{
CHECKPOINT;
TempLength = min(Length,DeviceExt->BytesPerCluster -
(WriteOffset % DeviceExt->BytesPerCluster));
/* Read in the existing cluster data */
if (FirstCluster==1)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp);
else
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
/* Overwrite the last parts of the data as necessary */
memcpy(Temp + (WriteOffset % DeviceExt->BytesPerCluster), Buffer,
TempLength);
/* Write the cluster back */
if (FirstCluster==1)
{
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
}
Length2 -= TempLength;
Buffer = Buffer + TempLength;
}
CHECKPOINT;
/* Write the buffer in chunks of 1 cluster */
while (Length2 >= DeviceExt->BytesPerCluster)
{
CHECKPOINT;
if (CurrentCluster == 0)
{
ExFreePool(Temp);
return(STATUS_UNSUCCESSFUL);
}
if (FirstCluster==1)
{
VFATWriteSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Buffer);
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
}
else
{
VFATWriteCluster(DeviceExt,Buffer,CurrentCluster);
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
}
Buffer = Buffer + DeviceExt->BytesPerCluster;
Length2 -= DeviceExt->BytesPerCluster;
}
CHECKPOINT;
/* Write the remainder */
if (Length2 > 0)
{
CHECKPOINT;
if (CurrentCluster == 0)
{
ExFreePool(Temp);
return(STATUS_UNSUCCESSFUL);
}
CHECKPOINT;
/* Read in the existing cluster data */
if (FirstCluster==1)
VFATReadSectors(DeviceExt->StorageDevice,CurrentCluster
,DeviceExt->Boot->SectorsPerCluster,Temp);
else
VFATLoadCluster(DeviceExt,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;
//FIXME : set last write time and date
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);
}
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Write to a file
*/
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Write.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Read from a file
*/
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status;
ULONG LengthRead;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
/* Precondition / Initialization */
assert(Irp != NULL);
Stack = IoGetCurrentIrpStackLocation(Irp);
assert(Stack != NULL);
FileObject = Stack->FileObject;
assert(FileObject != NULL);
DeviceExt = DeviceObject->DeviceExtension;
assert(DeviceExt != NULL);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset,
&LengthRead);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = LengthRead;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}

View file

@ -0,0 +1,178 @@
/* $Id: string.c,v 1.1 1999/12/11 21:14:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/string.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
/*
* FUNCTION: Convert an ANSI string to it's Unicode equivalent
*/
{
int i;
for (i=0; (i<Length && Source[i] != ' '); i++)
{
Dest[i] = Source[i];
}
Dest[i]=0;
}
void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
/*
* FUNCTION: Appends a converted ANSI to Unicode string to the end of an
* existing Unicode string
*/
{
ULONG i;
while((*Dest)!=0)
{
Dest++;
}
for (i=0; (i<Length && Source[i] != ' '); i++)
{
Dest[i] = Source[i];
}
Dest[i]=0;
}
void vfat_initstr(wchar_t *wstr, ULONG wsize)
/*
* FUNCTION: Initialize a string for use with a long file name
*/
{
int i;
wchar_t nc=0;
for(i=0; i<wsize; i++)
{
*wstr=nc;
wstr++;
}
wstr=wstr-wsize;
}
wchar_t * vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount)
/*
* FUNCTION: Append a string for use with a long file name
*/
{
int i;
dest+=wstart;
for(i=0; i<wcount; i++)
{
*dest=src[i];
dest++;
}
dest=dest-(wcount+wstart);
return dest;
}
wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount)
/*
* FUNCTION: Copy a string for use with long file names
*/
{
int i;
for (i=0;i<wcount;i++)
{
dest[i]=src[i];
if(!dest[i]) break;
}
return(dest);
}
wchar_t * vfat_movstr(wchar_t *src, ULONG dpos,
ULONG spos, ULONG len)
/*
* FUNCTION: Move the characters in a string to a new position in the same
* string
*/
{
int i;
if(dpos<=spos)
{
for(i=0; i<len; i++)
{
src[dpos++]=src[spos++];
}
}
else
{
dpos+=len-1;
spos+=len-1;
for(i=0; i<len; i++)
{
src[dpos--]=src[spos--];
}
}
return(src);
}
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
/*
* FUNCTION: Compare to wide character strings
* return TRUE if s1==s2
*/
{
while (towlower(*s1)==towlower(*s2))
{
if ((*s1)==0 && (*s2)==0)
{
return(TRUE);
}
s1++;
s2++;
}
return(FALSE);
}
BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2)
/*
* FUNCTION: Compare to wide character strings, s2 with jokers (* or ?)
* return TRUE if s1 like s2
*/
{
while ((*s2=='?')||(towlower(*s1)==towlower(*s2)))
{
if ((*s1)==0 && (*s2)==0)
return(TRUE);
s1++;
s2++;
}
if(*s2=='*')
{
s2++;
while (*s1)
if (wstrcmpjoki(s1,s2)) return TRUE;
else s1++;
}
if ((*s1)==0 && (*s2)==0)
return(TRUE);
return(FALSE);
}

View file

@ -1,9 +1,4 @@
/* $Id: vfat.h,v 1.14 1999/12/04 20:58:44 ea Exp $ */
#include <wchar.h>
/* $Id: vfat.h,v 1.15 1999/12/11 21:14:49 dwelch Exp $ */
struct _BootSector {
unsigned char magic0, res0, magic1;
@ -77,7 +72,12 @@ typedef struct _slot slot;
typedef struct
{
ERESOURCE Resource;
ERESOURCE DirResource;
ERESOURCE FatResource;
KSPIN_LOCK FcbListLock;
LIST_ENTRY FcbListHead;
PDEVICE_OBJECT StorageDevice;
BootSector *Boot;
int rootDirectorySectors, FATStart, rootStart, dataStart;
@ -85,6 +85,7 @@ typedef struct
ULONG BytesPerCluster;
ULONG FatType;
unsigned char* FAT;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _FSRTL_COMMON_FCB_HEADER{
@ -105,8 +106,7 @@ typedef struct _SFsdNTRequiredFCB {
ERESOURCE PagingIoResource;
} SFsdNTRequiredFCB, *PtrSFsdNTRequiredFCB;
struct _VfatFCB;
typedef struct _VfatFCB
typedef struct _VFATFCB
{
SFsdNTRequiredFCB NTRequiredFCB;
FATDirEntry entry;
@ -114,20 +114,20 @@ typedef struct _VfatFCB
WCHAR PathName[MAX_PATH];// path+filename 260 max
long RefCount;
PDEVICE_EXTENSION pDevExt;
struct _VfatFCB * nextFcb, *prevFcb;
struct _VfatFCB * parentFcb;
} VfatFCB, *PVfatFCB;
LIST_ENTRY FcbListEntry;
struct _VFATFCB * parentFcb;
} VFATFCB, *PVFATFCB;
typedef struct
typedef struct _VFATCCB
{
VfatFCB * pFcb;
VFATFCB * pFcb;
LIST_ENTRY NextCCB;
PFILE_OBJECT PtrFileObject;
LARGE_INTEGER CurrentByteOffset;
ULONG StartSector; // for DirectoryControl
ULONG StartEntry; //for DirectoryControl
// PSTRING DirectorySearchPattern;// for DirectoryControl ?
} VfatCCB, *PVfatCCB;
} VFATCCB, *PVFATCCB;
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
@ -147,9 +147,6 @@ typedef struct __DOSDATE
WORD Year:5;
} DOSDATE, *PDOSDATE;
extern PVfatFCB pFirstFcb;
// functions called by i/o manager :
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
NTSTATUS FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
@ -176,10 +173,10 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
//internal functions in iface.c :
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVfatFCB Fcb,
PVfatFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
NTSTATUS FsdGetStandardInformation(PVfatFCB FCB, PDEVICE_OBJECT DeviceObject,
NTSTATUS FsdGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
PFILE_STANDARD_INFORMATION StandardInfo);
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName);
@ -200,7 +197,41 @@ NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt
NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
//FIXME : following defines must be removed
//FIXME when this functions will work.
#define ExAcquireResourceExclusiveLite(x,y) {}
#define ExReleaseResourceForThreadLite(x,y) {}
/*
* String functions
*/
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
void vfat_initstr(wchar_t *wstr, ULONG wsize);
wchar_t * vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
wchar_t * vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2);
BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2);
/*
* functions from fat.c
*/
ULONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster);
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
VOID VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
ULONG FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
ULONG FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
ULONG FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
/*
* functions from volume.c
*/
NTSTATUS VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
/*
* functions from finfo.c
*/
NTSTATUS VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
/*
* From create.c
*/
NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);

View file

@ -0,0 +1,189 @@
/* $Id: volume.c,v 1.1 1999/12/11 21:14:49 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/volume.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*/
/* INCLUDES *****************************************************************/
#include <wchar.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo)
{
DPRINT("FsdGetFsVolumeInformation()\n");
DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
if (!FsVolumeInfo)
return(STATUS_SUCCESS);
/* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
wcscpy (FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
/* dummy entries */
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
FsVolumeInfo->SupportsObjects = FALSE;
DPRINT("Finished FsdGetFsVolumeInformation()\n");
return(STATUS_SUCCESS);
}
NTSTATUS FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo)
{
DPRINT("FsdGetFsAttributeInformation()\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
if (!FsAttributeInfo)
return(STATUS_SUCCESS);
FsAttributeInfo->FileSystemAttributes = FS_CASE_IS_PRESERVED;
FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 3;
wcscpy (FsAttributeInfo->FileSystemName, L"FAT");
DPRINT("Finished FsdGetFsAttributeInformation()\n");
return(STATUS_SUCCESS);
}
NTSTATUS FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_SIZE_INFORMATION FsSizeInfo)
{
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
DPRINT("FsdGetFsSizeInformation()\n");
DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
if (!FsSizeInfo)
return(STATUS_SUCCESS);
if (DeviceExt->FatType == FAT32)
{
struct _BootSector32 *BootSect = (struct _BootSector32 *)DeviceExt->Boot;
if (BootSect->Sectors)
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
else
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->SectorsHuge;
FsSizeInfo->AvailableAllocationUnits.QuadPart =
FAT32CountAvailableClusters(DeviceExt);
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
}
else
{
struct _BootSector *BootSect = (struct _BootSector *)DeviceExt->Boot;
if (BootSect->Sectors)
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
else
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->SectorsHuge;
if (DeviceExt->FatType == FAT16)
FsSizeInfo->AvailableAllocationUnits.QuadPart =
FAT16CountAvailableClusters(DeviceExt);
else
FsSizeInfo->AvailableAllocationUnits.QuadPart =
FAT12CountAvailableClusters(DeviceExt);
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
}
DPRINT("Finished FsdGetFsSizeInformation()\n");
return(STATUS_SUCCESS);
}
NTSTATUS VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Retrieve the specified file information
*/
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
FILE_INFORMATION_CLASS FileInformationClass =
Stack->Parameters.QueryVolume.FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
// PVfatCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
void *SystemBuffer;
/* PRECONDITION */
assert(DeviceObject != NULL);
assert(Irp != NULL);
DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
DeviceObject,Irp);
/* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryVolume.FileInformationClass;
FileObject = Stack->FileObject;
// CCB = (PVfatCCB)(FileObject->FsContext2);
// FCB = CCB->Buffer; // Should be CCB->FCB???
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
// FIXME : determine Buffer for result :
if (Irp->MdlAddress)
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
SystemBuffer = Irp->UserBuffer;
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FileInformationClass %d\n",FileInformationClass);
DPRINT("SystemBuffer %x\n",SystemBuffer);
switch (FileInformationClass)
{
case FileFsVolumeInformation:
RC = FsdGetFsVolumeInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer);
break;
case FileFsAttributeInformation:
RC = FsdGetFsAttributeInformation(SystemBuffer);
break;
case FileFsSizeInformation:
RC = FsdGetFsSizeInformation(DeviceObject, SystemBuffer);
break;
default:
RC=STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return RC;
}

View file

@ -4,9 +4,6 @@
/*
* Copyright 1992, Linus Torvalds.
*/
/*
* Reused for the ReactOS kernel by David Welch (1998)
*/
/*
* These have to be done with inline assembly: that way the bit-setting
@ -18,65 +15,119 @@
#ifdef __SMP__
#define LOCK_PREFIX "lock ; "
#define SMPVOL volatile
#else
#define LOCK_PREFIX ""
#define SMPVOL
#endif
/*
* Function prototypes to keep gcc -Wall happy
*/
extern void set_bit(int nr, volatile void * addr);
extern void clear_bit(int nr, volatile void * addr);
extern void change_bit(int nr, volatile void * addr);
extern int test_and_set_bit(int nr, volatile void * addr);
extern int test_and_clear_bit(int nr, volatile void * addr);
extern int test_and_change_bit(int nr, volatile void * addr);
extern int __constant_test_bit(int nr, const volatile void * addr);
extern int __test_bit(int nr, volatile void * addr);
extern int find_first_zero_bit(void * addr, unsigned size);
extern int find_next_zero_bit (void * addr, int size, int offset);
extern unsigned long ffz(unsigned long word);
/*
* Some hacks to defeat gcc over-optimizations..
*/
struct __dummy { unsigned long a[100]; };
#define ADDR (*(struct __dummy *) addr)
#define CONST_ADDR (*(const struct __dummy *) addr)
#define ADDR (*(volatile struct __dummy *) addr)
#define CONST_ADDR (*(volatile const struct __dummy *) addr)
extern __inline__ int set_bit(int nr, SMPVOL void * addr)
extern __inline__ void set_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
extern __inline__ void clear_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
extern __inline__ void change_bit(int nr, volatile void * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
:"=m" (ADDR)
:"Ir" (nr));
}
extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"ir" (nr));
:"Ir" (nr));
return oldbit;
}
extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"ir" (nr));
:"Ir" (nr));
return oldbit;
}
extern __inline__ int change_bit(int nr, SMPVOL void * addr)
extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit),"=m" (ADDR)
:"ir" (nr));
:"Ir" (nr));
return oldbit;
}
/*
* This routine doesn't need to be atomic.
*/
extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
{
return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
}
extern __inline__ int __test_bit(int nr, volatile void * addr)
{
int oldbit;
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (ADDR),"Ir" (nr));
return oldbit;
}
#define test_bit(nr,addr) \
(__builtin_constant_p(nr) ? \
__constant_test_bit((nr),(addr)) : \
__test_bit((nr),(addr)))
/*
* Find-bit routines..
*/
extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
int d0, d1, d2;
int res;
if (!size)
@ -92,9 +143,8 @@ extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
:"=d" (res)
:"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
:"ax", "cx", "di");
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
@ -137,4 +187,50 @@ extern __inline__ unsigned long ffz(unsigned long word)
return word;
}
#ifdef __KERNEL__
/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
extern __inline__ int ffs(int x)
{
int r;
__asm__("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "g" (x));
return r+1;
}
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
#endif /* __KERNEL__ */
#ifdef __KERNEL__
#define ext2_set_bit test_and_set_bit
#define ext2_clear_bit test_and_clear_bit
#define ext2_test_bit test_bit
#define ext2_find_first_zero_bit find_first_zero_bit
#define ext2_find_next_zero_bit find_next_zero_bit
/* Bitmap functions for the minix filesystem. */
#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
#define minix_test_bit(nr,addr) test_bit(nr,addr)
#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
#endif /* __KERNEL__ */
#endif /* _I386_BITOPS_H */

View file

@ -8,6 +8,8 @@ extern void dprintf(char* fmt,...);
#define DPRINT(args...) do { dprintf("(NTDLL:%s:%d) ",__FILE__,__LINE__); dprintf(args); } while(0);
#endif
#define DPRINT1(args...) do { dprintf("(NTDLL:%s:%d) ",__FILE__,__LINE__); dprintf(args); } while(0);
#define ROUNDUP(a,b) ((((a)+(b)-1)/(b))*(b))
#define ROUNDDOWN(a,b) (((a)/(b))*(b))

View file

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.18 1999/12/09 19:14:45 ekohl Exp $
/* $Id: utils.c,v 1.19 1999/12/11 21:14:47 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -367,49 +367,50 @@ static NTSTATUS LdrFindDll(PDLL* Dll, PCHAR Name)
* NOTE
*
*/
NTSTATUS
LdrMapSections (
HANDLE ProcessHandle,
PVOID ImageBase,
HANDLE SectionHandle,
PIMAGE_NT_HEADERS NTHeaders
)
NTSTATUS LdrMapSections(HANDLE ProcessHandle,
PVOID ImageBase,
HANDLE SectionHandle,
PIMAGE_NT_HEADERS NTHeaders)
{
ULONG i;
NTSTATUS Status;
for ( i = 0;
(i < NTHeaders->FileHeader.NumberOfSections);
i++
)
{
PIMAGE_SECTION_HEADER Sections;
LARGE_INTEGER Offset;
ULONG Base;
ULONG i;
NTSTATUS Status;
for (i = 0; (i < NTHeaders->FileHeader.NumberOfSections); i++)
{
PIMAGE_SECTION_HEADER Sections;
LARGE_INTEGER Offset;
ULONG Base;
ULONG Size;
Sections = (PIMAGE_SECTION_HEADER) SECHDROFFSET(ImageBase);
Base = (ULONG) (Sections[i].VirtualAddress + ImageBase);
Offset.u.LowPart = Sections[i].PointerToRawData;
Offset.u.HighPart = 0;
Status = ZwMapViewOfSection(
SectionHandle,
ProcessHandle,
(PVOID *) & Base,
0,
Sections[i].Misc.VirtualSize,
& Offset,
(PULONG) & Sections[i].Misc.VirtualSize,
0,
MEM_COMMIT,
PAGE_READWRITE
);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
return STATUS_SUCCESS;
Sections = (PIMAGE_SECTION_HEADER) SECHDROFFSET(ImageBase);
Base = (ULONG) (Sections[i].VirtualAddress + ImageBase);
Offset.u.LowPart = Sections[i].PointerToRawData;
Offset.u.HighPart = 0;
Size = max(Sections[i].Misc.VirtualSize, Sections[i].SizeOfRawData);
DPRINT("Mapping section %d offset %x base %x size %x\n",
i, Offset.u.LowPart, Base, Sections[i].Misc.VirtualSize);
DPRINT("Size %x\n", Sections[i].SizeOfRawData);
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
(PVOID*)&Base,
0,
Size,
&Offset,
(PULONG)&Size,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to map section");
return(Status);
}
}
return STATUS_SUCCESS;
}
@ -697,14 +698,17 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
PDLL Module;
NTSTATUS Status;
DPRINT1("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders,
ImageBase);
/*
* Process each import module.
*/
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)(
ImageBase + NTHeaders->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
ImageBase + NTHeaders->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress);
DPRINT1("ImportModuleDirectory %x\n", ImportModuleDirectory);
while (ImportModuleDirectory->dwRVAModuleName)
{
@ -713,7 +717,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
DWORD pName;
PWORD pHint;
DPRINT("ImportModule->Directory->dwRVAModuleName %s\n",
DPRINT1("ImportModule->Directory->dwRVAModuleName %s\n",
(PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName));
Status = LdrLoadDll(&Module,
@ -734,61 +738,61 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders,
*/
if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
{
FunctionNameList = (PULONG) (
ImageBase
+ ImportModuleDirectory->dwRVAFunctionNameList
);
}
else
{
FunctionNameList = (PULONG) (
ImageBase
+ ImportModuleDirectory->dwRVAFunctionAddressList
);
}
/*
* Walk through function list and fixup addresses.
*/
while (*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000)
{
Ordinal = (*FunctionNameList) & 0x7fffffff;
FunctionNameList = (PULONG) (
ImageBase
+ ImportModuleDirectory->dwRVAFunctionNameList
);
}
else
{
FunctionNameList = (PULONG) (
ImageBase
+ ImportModuleDirectory->dwRVAFunctionAddressList
);
}
/*
* Walk through function list and fixup addresses.
*/
while (*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000)
{
Ordinal = (*FunctionNameList) & 0x7fffffff;
*ImportAddressList =
LdrGetExportByOrdinal(
LdrGetExportByOrdinal(
Module,
Ordinal
);
}
else
{
pName = (DWORD) (
ImageBase
+ *FunctionNameList
+ 2
);
pHint = (PWORD) (
ImageBase
+ *FunctionNameList
);
*ImportAddressList =
LdrGetExportByName(
Module,
Ordinal
);
}
else
{
pName = (DWORD) (
ImageBase
+ *FunctionNameList
+ 2
);
pHint = (PWORD) (
ImageBase
+ *FunctionNameList
);
*ImportAddressList =
LdrGetExportByName(
Module,
(PUCHAR) pName
);
if ((*ImportAddressList) == NULL)
{
(PUCHAR) pName
);
if ((*ImportAddressList) == NULL)
{
dprintf("Failed to import %s\n", pName);
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_UNSUCCESSFUL;
}
}
ImportAddressList++;
FunctionNameList++;
}
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
FunctionNameList++;
}
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
}

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.31 1999/12/02 20:53:52 dwelch Exp $
; $Id: ntoskrnl.def,v 1.32 1999/12/11 21:14:47 dwelch Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -505,4 +505,5 @@ WRITE_PORT_BUFFER_USHORT
WRITE_PORT_UCHAR
WRITE_PORT_ULONG
WRITE_PORT_USHORT
InsertTailList
RemoveEntryList

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.edf,v 1.18 1999/12/02 20:53:53 dwelch Exp $
; $Id: ntoskrnl.edf,v 1.19 1999/12/11 21:14:48 dwelch Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
@ -503,3 +503,5 @@ WRITE_PORT_BUFFER_USHORT
WRITE_PORT_UCHAR
WRITE_PORT_ULONG
WRITE_PORT_USHORT
InsertTailList
RemoveEntryList

View file

@ -1,4 +1,4 @@
/* $Id: interlck.c,v 1.5 1999/12/10 17:04:37 dwelch Exp $
/* $Id: interlck.c,v 1.6 1999/12/11 21:14:48 dwelch Exp $
*
* reactos/ntoskrnl/rtl/interlck.c
*
@ -112,13 +112,11 @@ __asm__(
"_InterlockedExchange@8:\n\t"
"pushl %ebp\n\t"
"movl %esp,%ebp\n\t"
"pushl %eax\n\t"
"pushl %ebx\n\t"
"movl 12(%ebp),%eax\n\t"
"movl 8(%ebp),%ebx\n\t"
"xchgl %eax,(%ebx)\n\t"
"popl %ebx\n\t"
"popl %eax\n\t"
"movl %ebp,%esp\n\t"
"popl %ebp\n\t"
"ret $8\n\t"