mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
more loader changes and new fixes to the VFAT driver from jean
svn path=/trunk/; revision=137
This commit is contained in:
parent
6fd4505b6f
commit
a984573ad4
10 changed files with 622 additions and 318 deletions
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/string.h>
|
||||
#include <wstring.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -20,7 +21,7 @@
|
|||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer)
|
||||
{
|
||||
|
@ -31,20 +32,14 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
NTSTATUS status;
|
||||
ULONG sectorSize;
|
||||
PULONG mbr;
|
||||
int j;
|
||||
|
||||
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||
pDeviceObject,DiskSector,Buffer);
|
||||
|
||||
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
|
||||
|
||||
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
||||
(unsigned long) DiskSector,
|
||||
(unsigned long) BLOCKSIZE,
|
||||
(unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
|
||||
(unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
|
||||
|
||||
// sectorNumber.HighPart = 0;
|
||||
// sectorNumber.LowPart = DiskSector * BLOCKSIZE;
|
||||
sectorNumber.LowPart=DiskSector<<9;
|
||||
sectorNumber.HighPart=DiskSector>>23;
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
|
||||
sectorSize = BLOCKSIZE*SectorCount;
|
||||
|
@ -87,7 +82,9 @@ DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
|||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
|
||||
DbgPrint("IO failed!!! VFATREadSectors : Error code: %x\n", status);
|
||||
DbgPrint("(pDeviceObject %x, DiskSector %x, Buffer %x, offset 0x%x%x)\n",
|
||||
pDeviceObject,DiskSector,Buffer,sectorNumber.HighPart,sectorNumber.LowPart);
|
||||
ExFreePool(mbr);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -101,7 +98,7 @@ DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
|||
}
|
||||
|
||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer)
|
||||
{
|
||||
|
@ -112,13 +109,12 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
NTSTATUS status;
|
||||
ULONG sectorSize;
|
||||
PULONG mbr;
|
||||
int j;
|
||||
|
||||
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||
pDeviceObject,DiskSector,Buffer);
|
||||
|
||||
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
|
||||
sectorNumber.HighPart = 0;
|
||||
sectorNumber.LowPart = DiskSector * BLOCKSIZE;
|
||||
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
|
||||
|
@ -162,7 +158,7 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
|
||||
DbgPrint("IO failed!!! VFATWriteSectors : Error code: %x\n", status);
|
||||
ExFreePool(mbr);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -31,27 +31,6 @@
|
|||
|
||||
#include "vfat.h"
|
||||
|
||||
#define FAT16 (1)
|
||||
#define FAT12 (2)
|
||||
#define FAT32 (3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PDEVICE_OBJECT StorageDevice;
|
||||
BootSector *Boot;
|
||||
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
||||
int FATEntriesPerSector, FATUnit;
|
||||
ULONG BytesPerCluster;
|
||||
ULONG FatType;
|
||||
unsigned char* FAT;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FATDirEntry entry;
|
||||
} FCB, *PFCB;
|
||||
|
||||
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
|
@ -60,6 +39,10 @@ static PDRIVER_OBJECT DriverObject;
|
|||
/* 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;
|
||||
|
@ -67,8 +50,8 @@ ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
Block = ExAllocatePool(NonPagedPool,1024);
|
||||
FATsector=CurrentCluster/(512/sizeof(ULONG));
|
||||
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
|
||||
VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
|
||||
Block);
|
||||
VFATReadSectors(DeviceExt->StorageDevice
|
||||
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
|
||||
CurrentCluster = Block[FATeis];
|
||||
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
||||
CurrentCluster = 0;
|
||||
|
@ -77,43 +60,39 @@ ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
}
|
||||
|
||||
ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||
/*
|
||||
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table from the
|
||||
* in-memory FAT
|
||||
*/
|
||||
{
|
||||
ULONG FATsector;
|
||||
ULONG FATeis;
|
||||
PUSHORT Block;
|
||||
|
||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
FATsector=CurrentCluster/(512/sizeof(USHORT));
|
||||
FATeis=CurrentCluster-(FATsector*256);
|
||||
|
||||
|
||||
// VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
|
||||
// (UCHAR *)Block);
|
||||
|
||||
Block = (PUSHORT)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
||||
|
||||
memcpy(Block,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||
CurrentCluster = Block[FATeis];
|
||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||
CurrentCluster = 0;
|
||||
|
||||
ExFreePool(Block);
|
||||
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 FATsector;
|
||||
ULONG FATOffset;
|
||||
ULONG Entry;
|
||||
|
||||
|
||||
CBlock = ExAllocatePool(NonPagedPool,1024);
|
||||
FATsector = (CurrentCluster * 12) / (512 * 8);
|
||||
|
||||
// VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart
|
||||
// +FATsector,1,CBlock);
|
||||
|
||||
CBlock = (unsigned char *)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
||||
|
||||
memcpy(CBlock,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||
if ((CurrentCluster % 2) == 0)
|
||||
|
@ -130,12 +109,15 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||
Entry = 0;
|
||||
CurrentCluster = Entry;
|
||||
|
||||
ExFreePool(CBlock);
|
||||
DPRINT("Returning %x\n",CurrentCluster);
|
||||
return(CurrentCluster);
|
||||
}
|
||||
|
||||
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||
/*
|
||||
* FUNCTION: Retrieve the next cluster depending on the FAT type
|
||||
*/
|
||||
{
|
||||
|
||||
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||
|
@ -155,6 +137,9 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
}
|
||||
|
||||
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||
/*
|
||||
* FUNCTION: Finds the first available cluster in a FAT16 table
|
||||
*/
|
||||
{
|
||||
ULONG sector;
|
||||
PUSHORT Block;
|
||||
|
@ -184,6 +169,9 @@ ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
|||
|
||||
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
/*
|
||||
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
|
||||
*/
|
||||
{
|
||||
ULONG FATsector;
|
||||
ULONG FATeis;
|
||||
|
@ -208,51 +196,21 @@ void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
|||
ExFreePool(Block);
|
||||
}
|
||||
|
||||
void FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
{
|
||||
unsigned char* CBlock;
|
||||
ULONG FATsector;
|
||||
ULONG FATOffset;
|
||||
ULONG Entry;
|
||||
|
||||
CBlock = ExAllocatePool(NonPagedPool,1024);
|
||||
FATsector = (ClusterToWrite * 12) / (512 * 8);
|
||||
|
||||
memcpy(CBlock,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||
FATOffset = (ClusterToWrite * 12) % (512 * 8);
|
||||
|
||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||
|
||||
/*
|
||||
|
||||
Write 12-bit entry
|
||||
|
||||
if ((CurrentCluster % 2) == 0)
|
||||
{
|
||||
Entry = CBlock[((FATOffset / 24)*3)];
|
||||
Entry |= (CBlock[((FATOffset / 24)*3) + 1] & 0xf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
|
||||
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
||||
} */
|
||||
|
||||
ExFreePool(CBlock);
|
||||
}
|
||||
|
||||
void WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
/*
|
||||
* FUNCTION: Write a changed FAT entry
|
||||
*/
|
||||
{
|
||||
if (DeviceExt->FatType == FAT16) {
|
||||
FAT16WriteCluster(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;
|
||||
BOOLEAN EOF = FALSE;
|
||||
|
@ -290,7 +248,7 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
if(DeviceExt->FatType == FAT16) {
|
||||
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
|
||||
} else {
|
||||
FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
||||
//FIXME FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
||||
}
|
||||
|
||||
/* Now, write the AU of the LastCluster with the value of the newly
|
||||
|
@ -308,13 +266,20 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned long ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||
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 RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||
/*
|
||||
* FUNCTION: Convert an ANSI string to it's Unicode equivalent
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -326,6 +291,10 @@ void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -341,6 +310,9 @@ void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -353,6 +325,9 @@ 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)
|
||||
/*
|
||||
* FUNCTION: Append a string for use with a long file name
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -368,6 +343,9 @@ wchar_t * vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -383,6 +361,10 @@ wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount)
|
|||
|
||||
wchar_t * vfat_movstr(wchar_t * dest, const 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;
|
||||
|
||||
|
@ -398,11 +380,17 @@ wchar_t * vfat_movstr(wchar_t * dest, const wchar_t *src, ULONG dpos,
|
|||
}
|
||||
|
||||
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset)
|
||||
/*
|
||||
* FUNCTION: Determine if the given directory entry is the last
|
||||
*/
|
||||
{
|
||||
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
||||
}
|
||||
|
||||
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
||||
/*
|
||||
* FUNCTION: Determines if the given entry is a deleted one
|
||||
*/
|
||||
{
|
||||
/* Checks special character (short names) or attrib=0 (long names) */
|
||||
|
||||
|
@ -411,7 +399,10 @@ BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
|||
}
|
||||
|
||||
BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
|
||||
PDEVICE_EXTENSION DeviceExt, PULONG _StartingSector)
|
||||
PDEVICE_EXTENSION DeviceExt, ULONG * _StartingSector)
|
||||
/*
|
||||
* FUNCTION: Retrieves the file name, be it in short or long file name format
|
||||
*/
|
||||
{
|
||||
FATDirEntry* test;
|
||||
slot* test2;
|
||||
|
@ -490,8 +481,11 @@ BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
|
|||
}
|
||||
|
||||
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
|
||||
/*
|
||||
* FUNCTION: Compare to wide character strings
|
||||
* return TRUE if s1==s2
|
||||
*/
|
||||
{
|
||||
DPRINT("s1 '%w' s2 '%w'\n",s1,s2);
|
||||
while (wtolower(*s1)==wtolower(*s2))
|
||||
{
|
||||
if ((*s1)==0 && (*s2)==0)
|
||||
|
@ -504,100 +498,143 @@ BOOLEAN wstrcmpi(PWSTR s1, PWSTR 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=='?')||(wtolower(*s1)==wtolower(*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);
|
||||
}
|
||||
|
||||
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||
PFCB Parent, PWSTR FileToFind)
|
||||
PFCB 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;
|
||||
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||
ULONG i, j;
|
||||
ULONG Size;
|
||||
char* block;
|
||||
WCHAR name[256];
|
||||
ULONG StartingSector;
|
||||
ULONG NextCluster;
|
||||
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||
|
||||
if (Parent == NULL)
|
||||
{
|
||||
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||
StartingSector = DeviceExt->rootStart;
|
||||
{
|
||||
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||
StartingSector = DeviceExt->rootStart;
|
||||
if(FileToFind[0]==0 ||(FileToFind[0]=='\\' && FileToFind[1]==0))
|
||||
{// it's root !
|
||||
memset(Fcb,0,sizeof(FCB));
|
||||
memset(Fcb->entry.Filename,' ',11);
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
Fcb->entry.FirstCluster=2;
|
||||
else Fcb->entry.FirstCluster=1;
|
||||
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);
|
||||
}
|
||||
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
|
||||
for (j=0; j<Size; j++)
|
||||
{
|
||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
||||
|
||||
for (i=0; i<ENTRIES_PER_SECTOR; i++)
|
||||
{
|
||||
if (IsLastEntry((PVOID)block,i))
|
||||
{
|
||||
ExFreePool(block);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
|
||||
{
|
||||
DPRINT("Scanning %w\n",name);
|
||||
DPRINT("Comparing %w %w\n",name,FileToFind);
|
||||
if (wstrcmpi(name,FileToFind))
|
||||
{
|
||||
/* In the case of a long filename, the firstcluster is stored in
|
||||
the next record -- where it's short name is */
|
||||
if(DeviceExt->FatType==FAT32)
|
||||
if(((FATDirEntry *)block)[i].FirstCluster==0
|
||||
&&((FATDirEntry *)block)[i].FirstClusterHigh==0
|
||||
) i++;
|
||||
else
|
||||
if(((FATDirEntry *)block)[i].FirstCluster==0) i++;
|
||||
DPRINT("Found it at cluster %u\n", ((FATDirEntry *)block)[i].FirstCluster);
|
||||
if( i==ENTRIES_PER_SECTOR)
|
||||
{
|
||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector+1,1,block);
|
||||
i=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
|
||||
|
||||
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||
sizeof(FATDirEntry));
|
||||
|
||||
ExFreePool(block);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
Size = ULONG_MAX;
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
|
||||
else
|
||||
NextCluster = Parent->entry.FirstCluster;
|
||||
StartingSector = ClusterToSector(DeviceExt, NextCluster);
|
||||
}
|
||||
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
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 (IsLastEntry((PVOID)block,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(DeviceExt->FatType==FAT32)
|
||||
// {
|
||||
// if(((FATDirEntry *)block)[i].FirstCluster==0
|
||||
// &&((FATDirEntry *)block)[i].FirstClusterHigh==0
|
||||
// ) i++;
|
||||
// }
|
||||
// else
|
||||
// if(((FATDirEntry *)block)[i].FirstCluster==0) i++;
|
||||
if( i==(ENTRIES_PER_SECTOR))
|
||||
{// entry is in next sector
|
||||
StartingSector++;
|
||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
|
||||
i=0;
|
||||
}
|
||||
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||
sizeof(FATDirEntry));
|
||||
vfat_wcsncpy(Fcb->ObjectName,name,251);
|
||||
ExFreePool(block);
|
||||
if(StartSector) *StartSector=StartingSector;
|
||||
if(Entry) *Entry=i;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(Entry) *Entry=0;
|
||||
// not found in this sector, try next :
|
||||
|
||||
|
||||
/* It seems that directory sectors cannot be fragmented and therefore,
|
||||
/* It seems that directory sectors cannot be fragmented and therefore,
|
||||
they only have a first cluster, but the one's after it are marked
|
||||
with 0xffff. This theory is still not 100% certain, so the following
|
||||
lines are commented and not removed */
|
||||
|
||||
StartingSector++;
|
||||
/* if (Parent == NULL)
|
||||
{
|
||||
StartingSector++;
|
||||
/* if (Parent == NULL)
|
||||
{
|
||||
StartingSector++;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextCluster = GetNextCluster(DeviceExt,NextCluster);
|
||||
if (NextCluster == 0)
|
||||
{
|
||||
ExFreePool(block);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
StartingSector = ClusterToSector(DeviceExt,NextCluster);
|
||||
} */
|
||||
}
|
||||
else
|
||||
{
|
||||
NextCluster = GetNextCluster(DeviceExt,NextCluster);
|
||||
if (NextCluster == 0)
|
||||
{
|
||||
ExFreePool(block);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
StartingSector = ClusterToSector(DeviceExt,NextCluster);
|
||||
} */
|
||||
}
|
||||
ExFreePool(block);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
@ -609,6 +646,7 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
|||
*/
|
||||
{
|
||||
/* NOP */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
|
@ -640,7 +678,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
*next=0;
|
||||
}
|
||||
|
||||
Status = FindFile(DeviceExt,Fcb,ParentFcb,current);
|
||||
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
|
@ -649,15 +687,15 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
if (ParentFcb == NULL)
|
||||
{
|
||||
Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
||||
ParentFcb = Temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb = ParentFcb;
|
||||
ParentFcb = Temp;
|
||||
}
|
||||
ParentFcb = Temp;
|
||||
}
|
||||
FileObject->FsContext = ParentFcb;
|
||||
DPRINT("file opn, fcb=%x\n",ParentFcb);
|
||||
DPRINT("ParentFcb->entry.FileSize %d\n",ParentFcb->entry.FileSize);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
|
@ -666,7 +704,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||
/*
|
||||
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||
* by this fsd
|
||||
* by this fsd
|
||||
*/
|
||||
{
|
||||
BootSector* Boot;
|
||||
|
@ -692,8 +730,6 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
|||
* FUNCTION: Mounts the device
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
DPRINT("Mounting VFAT device...");
|
||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||
|
||||
|
@ -738,9 +774,13 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
|||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||
/*
|
||||
* FUNCTION: Load a cluster from the physical device
|
||||
*/
|
||||
{
|
||||
ULONG Sector;
|
||||
|
||||
|
@ -756,6 +796,9 @@ void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
|||
}
|
||||
|
||||
void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||
/*
|
||||
* FUNCTION: Write a cluster to the physical device
|
||||
*/
|
||||
{
|
||||
ULONG Sector;
|
||||
|
||||
|
@ -794,6 +837,9 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||
else
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
if (CurrentCluster<2)
|
||||
return STATUS_UNSUCCESSFUL;// FIXME : root of FAT16 ?
|
||||
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
||||
|
||||
if (ReadOffset >= Fcb->entry.FileSize)
|
||||
{
|
||||
|
@ -804,15 +850,11 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
Length = Fcb->entry.FileSize - ReadOffset;
|
||||
}
|
||||
*LengthRead = 0;
|
||||
|
||||
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
||||
|
||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||
|
||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
||||
{
|
||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||
}
|
||||
{
|
||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||
}
|
||||
CHECKPOINT;
|
||||
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
||||
{
|
||||
|
@ -949,6 +991,9 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
}
|
||||
|
||||
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Close a file
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
|
@ -965,6 +1010,9 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
}
|
||||
|
||||
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Create or open a file
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
|
@ -985,6 +1033,9 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|
||||
|
||||
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Write to a file
|
||||
*/
|
||||
{
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
|
@ -998,7 +1049,7 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|
||||
Length = Stack->Parameters.Write.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Write.ByteOffset);
|
||||
Offset = Stack->Parameters.Write.ByteOffset.LowPart;
|
||||
|
||||
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset);
|
||||
|
||||
|
@ -1010,6 +1061,9 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
}
|
||||
|
||||
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Read from a file
|
||||
*/
|
||||
{
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
|
@ -1024,14 +1078,13 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|
||||
Length = Stack->Parameters.Read.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = GET_LARGE_INTEGER_LOW_PART(Stack->Parameters.Read.ByteOffset);
|
||||
Offset = Stack->Parameters.Read.ByteOffset.LowPart;
|
||||
|
||||
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset,
|
||||
&LengthRead);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = LengthRead;
|
||||
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
|
@ -1039,6 +1092,9 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|
||||
|
||||
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||
/*
|
||||
* FUNCTION: Mount the filesystem
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
|
@ -1052,15 +1108,19 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
|||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
||||
|
||||
// use same vpb as device disk
|
||||
DeviceObject->Vpb=DeviceToMount->Vpb;
|
||||
FsdMountDevice(DeviceExt,DeviceToMount);
|
||||
|
||||
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
||||
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||
DeviceToMount);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: File system control
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||
|
@ -1088,7 +1148,10 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
}
|
||||
|
||||
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||
PFILE_STANDARD_INFORMATION StandardInfo)
|
||||
PFILE_STANDARD_INFORMATION StandardInfo)
|
||||
/*
|
||||
* FUNCTION: Retrieve the standard file information
|
||||
*/
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
unsigned long AllocSize;
|
||||
|
@ -1096,10 +1159,9 @@ NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
|||
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
||||
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
AllocSize = 0;
|
||||
while(AllocSize<FCB->entry.FileSize) {
|
||||
AllocSize+=DeviceExtension->BytesPerCluster;
|
||||
}
|
||||
AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
|
||||
DeviceExtension->BytesPerCluster) *
|
||||
DeviceExtension->BytesPerCluster;
|
||||
|
||||
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
|
||||
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
|
||||
|
@ -1115,20 +1177,24 @@ NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
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;
|
||||
PFCB FCB = NULL;
|
||||
PCCB CCB = NULL;
|
||||
// PCCB CCB = NULL;
|
||||
|
||||
NTSTATUS RC = STATUS_SUCCESS;
|
||||
void *SystemBuffer;
|
||||
|
||||
FileObject = Stack->FileObject;
|
||||
CCB = (PCCB)(FileObject->FsContext2);
|
||||
FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||
// CCB = (PCCB)(FileObject->FsContext2);
|
||||
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||
FCB=(PFCB)(FileObject->FsContext);
|
||||
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
|
@ -1136,9 +1202,6 @@ NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
case FileStandardInformation:
|
||||
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
RC = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return RC;
|
||||
|
@ -1159,7 +1222,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|||
UNICODE_STRING ustr;
|
||||
ANSI_STRING astr;
|
||||
|
||||
DbgPrint("VFAT 0.0.4\n");
|
||||
DbgPrint("VFAT 0.0.5\n");
|
||||
|
||||
DriverObject = _DriverObject;
|
||||
|
||||
|
@ -1181,6 +1244,9 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|||
FsdFileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||
FsdQueryInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||
FsdDirectoryControl;
|
||||
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
IoRegisterFileSystem(DeviceObject);
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
%.o: %.asm
|
||||
$(NASM) $(NFLAGS) $< -o $@
|
||||
|
||||
all: blockdev.o iface.o
|
||||
$(LD) iface.o blockdev.o -r -o vfatfsd.o
|
||||
OBJECTS= blockdev.o iface.o dir.o
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(LD) $(OBJECTS) -r -o vfatfsd.o
|
||||
$(NM) --numeric-sort vfatfsd.o > vfatfsd.sym
|
||||
|
||||
include ../../../rules.mak
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
|
||||
struct _BootSector {
|
||||
unsigned char magic0, res0, magic1;
|
||||
|
@ -45,9 +38,11 @@ struct _BootSector32 {
|
|||
typedef struct _BootSector BootSector;
|
||||
|
||||
struct _FATDirEntry {
|
||||
unsigned char Filename[8], Ext[3], Attrib, Res[8];
|
||||
unsigned char Filename[8], Ext[3], Attrib, Res[2];
|
||||
unsigned short CreationTime,CreationDate,AccessDate;
|
||||
unsigned short FirstClusterHigh;// higher
|
||||
unsigned char Res2[4];
|
||||
unsigned short UpdateTime;//time create/update
|
||||
unsigned short UpdateDate;//date create/update
|
||||
unsigned short FirstCluster;
|
||||
unsigned long FileSize;
|
||||
} __attribute__((packed));
|
||||
|
@ -108,3 +103,59 @@ typedef struct _SFsdFileControlBlock {
|
|||
} SFsdFCB, *PtrSFsdFCB;
|
||||
|
||||
*/
|
||||
#define FAT16 (1)
|
||||
#define FAT12 (2)
|
||||
#define FAT32 (3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PDEVICE_OBJECT StorageDevice;
|
||||
BootSector *Boot;
|
||||
int rootDirectorySectors, FATStart, rootStart, dataStart;
|
||||
int FATEntriesPerSector, FATUnit;
|
||||
ULONG BytesPerCluster;
|
||||
ULONG FatType;
|
||||
unsigned char* FAT;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FATDirEntry entry;
|
||||
WCHAR ObjectName[251];// filename has 250 characters max
|
||||
ULONG StartSector;
|
||||
ULONG StartEntry;//for DirectoryControl
|
||||
} FCB, *PFCB;
|
||||
|
||||
|
||||
#define ENTRIES_PER_SECTOR (BLOCKSIZE / sizeof(FATDirEntry))
|
||||
|
||||
|
||||
|
||||
// functions called by i/o manager :
|
||||
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
|
||||
NTSTATUS FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
|
||||
// internal functions in blockdev.c
|
||||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
//internal functions in iface.c :
|
||||
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||
PFILE_STANDARD_INFORMATION StandardInfo);
|
||||
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||
PFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
|
||||
wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
||||
|
|
|
@ -153,12 +153,17 @@ typedef struct _IO_STACK_LOCATION
|
|||
} u;
|
||||
} SetFile;
|
||||
|
||||
/*
|
||||
* This is a guess
|
||||
*/
|
||||
struct
|
||||
{
|
||||
ULONG Length;
|
||||
PUNICODE_STRING FileName;
|
||||
FILE_INFORMATION_CLASS FileInformationClass;
|
||||
ULONG FileIndex;
|
||||
BOOLEAN ReturnSingleEntry;
|
||||
PUNICODE_STRING FileName;
|
||||
BOOLEAN RestartScan;
|
||||
ULONG BufferLength;
|
||||
ULONG FileIndex;
|
||||
} QueryDirectory;
|
||||
} Parameters;
|
||||
|
||||
|
|
|
@ -164,4 +164,124 @@ __OUTS(l)
|
|||
__inlc_p(port) : \
|
||||
__inl_p(port))
|
||||
|
||||
/* HAL port mapped I/O functions */
|
||||
#define READ_PORT_UCHAR(port) inb_p(port)
|
||||
#define READ_PORT_USHORT(port) inw_p(port)
|
||||
#define READ_PORT_ULONG(port) inl_p(port)
|
||||
#define READ_PORT_BUFFER_UCHAR(port, buffer, count) insb(port, buffer, count)
|
||||
#define READ_PORT_BUFFER_USHORT(port, buffer, count) insw(port, buffer, count)
|
||||
#define READ_PORT_BUFFER_ULONG(port, buffer, count) insl(port, buffer, count)
|
||||
#define WRITE_PORT_UCHAR(port, value) outb_p(port, value)
|
||||
#define WRITE_PORT_USHORT(port, value) outw_p(port, value)
|
||||
#define WRITE_PORT_ULONG(port, value) outl_p(port, value)
|
||||
#define WRITE_PORT_BUFFER_UCHAR(port, buffer, count) outsb(port, buffer, count)
|
||||
#define WRITE_PORT_BUFFER_USHORT(port, buffer, count) outsw(port, buffer, count)
|
||||
#define WRITE_PORT_BUFFER_ULONG(port, buffer, count) outsl(port, buffer, count)
|
||||
|
||||
/* HAL Memory mapped I/O functions */
|
||||
/* FIXME: these ops should be 'lock' prefixed */
|
||||
extern inline unsigned char
|
||||
READ_REGISTER_UCHAR(unsigned char *Register)
|
||||
{
|
||||
return *Register;
|
||||
}
|
||||
|
||||
extern inline unsigned short
|
||||
READ_REGISTER_USHORT(unsigned short *Register)
|
||||
{
|
||||
return *Register;
|
||||
}
|
||||
|
||||
extern inline unsigned long
|
||||
READ_REGISTER_ULONG(unsigned long *Register)
|
||||
{
|
||||
return *Register;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
READ_REGISTER_BUFFER_UCHAR(unsigned char *Register,
|
||||
unsigned char *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
extern inline void
|
||||
READ_REGISTER_BUFFER_USHORT(unsigned short *Register,
|
||||
unsigned short *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
extern inline void
|
||||
READ_REGISTER_BUFFER_ULONG(unsigned long *Register,
|
||||
unsigned long *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_UCHAR(unsigned char *Register, unsigned char Value)
|
||||
{
|
||||
*Register = Value;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_USHORT(unsigned short *Register, unsigned short Value)
|
||||
{
|
||||
*Register = Value;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_ULONG(unsigned long *Register, unsigned long Value)
|
||||
{
|
||||
*Register = Value;
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_BUFFER_UCHAR(unsigned char *Register,
|
||||
unsigned char *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_BUFFER_USHORT(unsigned short *Register,
|
||||
unsigned short *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
extern inline void
|
||||
WRITE_REGISTER_BUFFER_ULONG(unsigned long *Register,
|
||||
unsigned long *Buffer,
|
||||
unsigned long Count)
|
||||
{
|
||||
while (Count--)
|
||||
{
|
||||
*Buffer++ = *Register++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/io/dir.c
|
||||
* PURPOSE: Directory functions
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
*/
|
||||
|
@ -13,22 +13,25 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/io.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL NtQueryDirectoryFile(IN HANDLE FileHandle,
|
||||
IN HANDLE Event OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
OUT PVOID FileInformation,
|
||||
IN ULONG Length,
|
||||
IN FILE_INFORMATION_CLASS
|
||||
FileInformationClass,
|
||||
IN BOOLEAN ReturnSingleEntry,
|
||||
IN PUNICODE_STRING FileName OPTIONAL,
|
||||
IN BOOLEAN RestartScan)
|
||||
NTSTATUS STDCALL
|
||||
NtQueryDirectoryFile(
|
||||
IN HANDLE FileHandle,
|
||||
IN HANDLE Event OPTIONAL,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
OUT PVOID FileInformation,
|
||||
IN ULONG Length,
|
||||
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||
IN BOOLEAN ReturnSingleEntry,
|
||||
IN PUNICODE_STRING FileName OPTIONAL,
|
||||
IN BOOLEAN RestartScan
|
||||
)
|
||||
{
|
||||
return(ZwQueryDirectoryFile(FileHandle,
|
||||
Event,
|
||||
|
@ -131,96 +134,46 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
|
|||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
BOOLEAN IndexSpecified;
|
||||
ULONG Idx;
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_LIST_DIRECTORY,
|
||||
IoFileType,
|
||||
UserMode,
|
||||
&FileObject,
|
||||
(PVOID *)&FileObject,
|
||||
NULL);
|
||||
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
DeviceObject = FileObject->DeviceObject;
|
||||
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||
if (Irp==NULL)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->UserEvent = &Event;
|
||||
Irp->UserBuffer=FileInformation;
|
||||
|
||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
|
||||
IoStack->Flags = 0;
|
||||
if (RestartScan)
|
||||
{
|
||||
IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
|
||||
}
|
||||
if (ReturnSingleEntry)
|
||||
{
|
||||
IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
|
||||
}
|
||||
|
||||
switch (FileInformationClass)
|
||||
{
|
||||
case FileNameInformation:
|
||||
Idx = ((PFILE_NAMES_INFORMATION)FileInformation)->FileIndex;
|
||||
if (Idx != 0)
|
||||
{
|
||||
IoStack->Parameters.QueryDirectory.FileIndex = Idx;
|
||||
IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
|
||||
}
|
||||
break;
|
||||
|
||||
case FileDirectoryInformation:
|
||||
Idx = ((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex;
|
||||
if (Idx != 0)
|
||||
{
|
||||
IoStack->Parameters.QueryDirectory.FileIndex = Idx;
|
||||
IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
|
||||
}
|
||||
break;
|
||||
|
||||
case FileFullDirectoryInformation:
|
||||
Idx = ((PFILE_FULL_DIR_INFORMATION)FileInformation)->FileIndex;
|
||||
if (Idx != 0)
|
||||
{
|
||||
IoStack->Parameters.QueryDirectory.FileIndex = Idx;
|
||||
IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
|
||||
}
|
||||
break;
|
||||
|
||||
case FileBothDirectoryInformation:
|
||||
Idx = ((PFILE_BOTH_DIR_INFORMATION)FileInformation)->FileIndex;
|
||||
if (Idx != 0)
|
||||
{
|
||||
IoStack->Parameters.QueryDirectory.FileIndex = Idx;
|
||||
IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
|
||||
IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
|
||||
|
||||
IoStack->Flags = 0;
|
||||
IoStack->Control = 0;
|
||||
IoStack->DeviceObject = DeviceObject;
|
||||
IoStack->FileObject = FileObject;
|
||||
|
||||
IoStack->Parameters.QueryDirectory.FileInformationClass =
|
||||
FileInformationClass;
|
||||
IoStack->Parameters.QueryDirectory.ReturnSingleEntry =
|
||||
ReturnSingleEntry;
|
||||
IoStack->Parameters.QueryDirectory.FileName = FileName;
|
||||
IoStack->Parameters.QueryDirectory.Length = Length;
|
||||
IoStack->Parameters.QueryDirectory.RestartScan = RestartScan;
|
||||
IoStack->Parameters.QueryDirectory.BufferLength = Length;
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||
|
|
|
@ -107,7 +107,10 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
|||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(&FileHandle, 0, &FileObjectAttributes, NULL, 0, 0);
|
||||
Status = ZwOpenFile(&FileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&FileObjectAttributes,
|
||||
NULL, 0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
|
|
|
@ -28,7 +28,9 @@ static unsigned char TstReadLineReadChar(VOID)
|
|||
KEY_EVENT_RECORD key[2];
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
ZwReadFile(KeyboardHandle,
|
||||
key[0].AsciiChar=0;
|
||||
while(!key[0].AsciiChar)
|
||||
ZwReadFile(KeyboardHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -37,7 +39,6 @@ static unsigned char TstReadLineReadChar(VOID)
|
|||
sizeof(KEY_EVENT_RECORD)*2,
|
||||
0,
|
||||
0);
|
||||
// DbgPrint("%c",key[0].AsciiChar);
|
||||
return(key[0].AsciiChar);
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,6 @@ VOID TstReadLine(ULONG Length, PCHAR Buffer)
|
|||
for (i=0;i<Length;i++)
|
||||
{
|
||||
tmp = TstReadLineReadChar();
|
||||
// DbgPrint("%x %x ",tmp,'\n');
|
||||
switch (tmp)
|
||||
{
|
||||
case 0xd:
|
||||
|
|
|
@ -19,16 +19,21 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
int ShellChangeDir(char* args);
|
||||
int ShellListDir(char* args);
|
||||
int ShellChangeDirOb(char* args);
|
||||
int ShellListDirOb(char* args);
|
||||
int ShellChangeDirFile(char* args);
|
||||
int ShellListDirFile(char* args);
|
||||
VOID TstReadLineInit(VOID);
|
||||
VOID TstReadLine(ULONG Length, PCHAR Buffer);
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static HANDLE CurrentDirHandle = NULL;
|
||||
static UNICODE_STRING CurrentDirName = {NULL,0,0};
|
||||
static UNICODE_STRING CurrentDirName = {0,0,NULL};
|
||||
static char current_dir_name[255] = {0,};
|
||||
static HANDLE CurrentDirHandleF = NULL;
|
||||
static UNICODE_STRING CurrentDirNameF = {0,0,NULL};
|
||||
static char current_dir_name_f[255] = {0,};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -38,8 +43,10 @@ typedef struct
|
|||
|
||||
command commands[]=
|
||||
{
|
||||
{"cd",ShellChangeDir},
|
||||
{"dir",ShellListDir},
|
||||
{"fcd",ShellChangeDirFile},
|
||||
{"fdir",ShellListDirFile},
|
||||
{"ocd",ShellChangeDirOb},
|
||||
{"odir",ShellListDirOb},
|
||||
{NULL,NULL},
|
||||
};
|
||||
|
||||
|
@ -54,11 +61,12 @@ char* eat_white_space(char* s)
|
|||
return(s);
|
||||
}
|
||||
|
||||
int ShellChangeDir(char* args)
|
||||
int ShellChangeDirOb(char* args)
|
||||
{
|
||||
char* end;
|
||||
ANSI_STRING astr;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
char* end;
|
||||
ANSI_STRING astr;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("ShellChangeDir(args %s)\n",args);
|
||||
|
||||
|
@ -68,7 +76,8 @@ int ShellChangeDir(char* args)
|
|||
{
|
||||
*end=0;
|
||||
}
|
||||
strcat(current_dir_name,args);
|
||||
if (args[0]=='\\') strcpy(current_dir_name,args);
|
||||
else strcat(current_dir_name,args);
|
||||
|
||||
DPRINT("current_dir_name %s\n",current_dir_name);
|
||||
|
||||
|
@ -76,33 +85,130 @@ int ShellChangeDir(char* args)
|
|||
RtlAnsiStringToUnicodeString(&CurrentDirName,&astr,TRUE);
|
||||
InitializeObjectAttributes(&attr,&CurrentDirName,0,NULL,NULL);
|
||||
ZwClose(CurrentDirHandle);
|
||||
ZwOpenDirectoryObject(&CurrentDirHandle,0,&attr);
|
||||
Status=ZwOpenDirectoryObject(&CurrentDirHandle,0,&attr);
|
||||
DbgPrint("Status=%x,dirhandle=%d\n",Status,CurrentDirHandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShellListDir(char* args)
|
||||
int ShellChangeDirFile(char* args)
|
||||
{
|
||||
char* end;
|
||||
ANSI_STRING astr;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS Status;
|
||||
DPRINT("ShellChangeDir(args %s)\n",args);
|
||||
|
||||
args = eat_white_space(args);
|
||||
end = strchr(args,' ');
|
||||
if (end!=NULL)
|
||||
{
|
||||
*end=0;
|
||||
}
|
||||
if (args[0]=='\\') strcpy(current_dir_name_f,args);
|
||||
else if (args[0])
|
||||
{
|
||||
strcat(current_dir_name_f,"\\");
|
||||
strcat(current_dir_name_f,args);
|
||||
}
|
||||
|
||||
|
||||
DPRINT("current_dir_name_f %s\n",current_dir_name_f);
|
||||
|
||||
RtlInitAnsiString(&astr,current_dir_name_f);
|
||||
RtlAnsiStringToUnicodeString(&CurrentDirNameF,&astr,TRUE);
|
||||
InitializeObjectAttributes(&attr,&CurrentDirNameF,0,NULL,NULL);
|
||||
ZwClose(CurrentDirHandleF);
|
||||
Status=ZwOpenFile(&CurrentDirHandleF,FILE_ALL_ACCESS,&attr,NULL,0,0);
|
||||
DbgPrint("Status=%x,dirhandle=%d\n",Status,CurrentDirHandleF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ShellListDirOb(char* args)
|
||||
{
|
||||
OBJDIR_INFORMATION DirObj[50];
|
||||
ULONG Idx;
|
||||
ULONG Length;
|
||||
ULONG Idx=0;
|
||||
ULONG Length=0;
|
||||
ULONG i;
|
||||
|
||||
if (args) args = eat_white_space(args);
|
||||
DbgPrint("ShellListDir(args %s)\n",args);
|
||||
|
||||
ZwQueryDirectoryObject(CurrentDirHandle,
|
||||
&(DirObj[0]),
|
||||
sizeof(DirObj),
|
||||
TRUE,
|
||||
TRUE,
|
||||
TRUE,
|
||||
&Idx,
|
||||
&Length);
|
||||
|
||||
DbgPrint("read %d bytes,Idx=%d\n",Length,Idx);
|
||||
for (i=0;i<(Length/sizeof(OBJDIR_INFORMATION));i++)
|
||||
{
|
||||
DbgPrint("Scanning %w\n",DirObj[i].ObjectName.Buffer);
|
||||
DbgPrint("i=%d ; ",i);
|
||||
DbgPrint("Scanning %w\n",DirObj[i].ObjectName.Buffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID ShellDisplayPrompt()
|
||||
int ShellListDirFile(char* args)
|
||||
{
|
||||
PFILE_BOTH_DIRECTORY_INFORMATION dirInfo,dirInfo2;
|
||||
NTSTATUS Status;
|
||||
ANSI_STRING afilename;
|
||||
UNICODE_STRING ToFind;
|
||||
WCHAR Name[251];
|
||||
short i;
|
||||
int Length=512;
|
||||
dirInfo=ExAllocatePool(NonPagedPool,Length);
|
||||
if (args) args = eat_white_space(args);
|
||||
if(args && args[0])
|
||||
RtlInitAnsiString(&afilename,args);
|
||||
else
|
||||
RtlInitAnsiString(&afilename,"*");
|
||||
RtlAnsiStringToUnicodeString(&ToFind,&afilename,TRUE);
|
||||
DbgPrint("ShellListDir(args %s)\n",args);
|
||||
DPRINT("before ZwQueryDirectoryFile\n");
|
||||
Status=ZwQueryDirectoryFile(CurrentDirHandleF,NULL,NULL,NULL
|
||||
,NULL
|
||||
, &(dirInfo[0])
|
||||
,Length
|
||||
,FileBothDirectoryInformation
|
||||
,TRUE
|
||||
,&ToFind
|
||||
,TRUE);
|
||||
DPRINT("after ZwQueryDirectoryFile\n");
|
||||
while(NT_SUCCESS(Status))
|
||||
{
|
||||
CHECKPOINT;
|
||||
dirInfo2=dirInfo;
|
||||
while(1)
|
||||
{
|
||||
memcpy(Name,dirInfo2[0].ShortName,12*sizeof(WCHAR));
|
||||
Name[(int)(dirInfo2[0].ShortNameLength)]=0;
|
||||
DbgPrint(" %w",Name);
|
||||
for (i=dirInfo2[0].ShortNameLength; i<14;i++) DbgPrint(" ");
|
||||
memcpy(Name,dirInfo2[0].FileName,dirInfo2[0].FileNameLength*sizeof(WCHAR));
|
||||
Name[dirInfo2[0].FileNameLength]=0;
|
||||
DbgPrint(" %w\n",Name);
|
||||
if(!dirInfo2->NextEntryOffset) break;
|
||||
dirInfo2=(PFILE_BOTH_DIRECTORY_INFORMATION)
|
||||
(((char *)dirInfo2)+dirInfo2->NextEntryOffset);
|
||||
}
|
||||
CHECKPOINT;
|
||||
Status=ZwQueryDirectoryFile(CurrentDirHandleF,NULL,NULL,NULL
|
||||
,NULL
|
||||
, &(dirInfo[0])
|
||||
,Length
|
||||
,FileBothDirectoryInformation
|
||||
, FALSE
|
||||
,&ToFind
|
||||
,FALSE);
|
||||
CHECKPOINT;
|
||||
}
|
||||
ExFreePool(dirInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID ShellDisplayPrompt(VOID)
|
||||
{
|
||||
printk("%w# ",CurrentDirName.Buffer);
|
||||
}
|
||||
|
@ -110,7 +216,7 @@ VOID ShellDisplayPrompt()
|
|||
VOID ShellProcessCommand(char* cmd)
|
||||
{
|
||||
unsigned int i=0;
|
||||
DbgPrint("Processing cmd '%s'\n",cmd);
|
||||
DbgPrint("Processing cmd :%s.\n",cmd);
|
||||
while (commands[i].name!=NULL)
|
||||
{
|
||||
DbgPrint("Scanning %s i %d\n",commands[i].name,i);
|
||||
|
@ -142,6 +248,7 @@ NTSTATUS TstShell(VOID)
|
|||
InitializeObjectAttributes(&attr,&ufilename,0,NULL,NULL);
|
||||
ZwOpenDirectoryObject(&CurrentDirHandle,0,&attr);
|
||||
|
||||
ShellChangeDirFile("\\??\\C:\\");
|
||||
|
||||
TstReadLineInit();
|
||||
|
||||
|
|
Loading…
Reference in a new issue