mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:43:04 +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 <ddk/ntddk.h>
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
|
#include <wstring.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG DiskSector,
|
IN ULONG DiskSector,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN UCHAR* Buffer)
|
IN UCHAR* Buffer)
|
||||||
{
|
{
|
||||||
|
@ -31,20 +32,14 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG sectorSize;
|
ULONG sectorSize;
|
||||||
PULONG mbr;
|
PULONG mbr;
|
||||||
int j;
|
|
||||||
|
|
||||||
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||||
pDeviceObject,DiskSector,Buffer);
|
pDeviceObject,DiskSector,Buffer);
|
||||||
|
|
||||||
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
|
// sectorNumber.HighPart = 0;
|
||||||
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
|
// sectorNumber.LowPart = DiskSector * BLOCKSIZE;
|
||||||
|
sectorNumber.LowPart=DiskSector<<9;
|
||||||
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
sectorNumber.HighPart=DiskSector>>23;
|
||||||
(unsigned long) DiskSector,
|
|
||||||
(unsigned long) BLOCKSIZE,
|
|
||||||
(unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
|
|
||||||
(unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
|
|
||||||
|
|
||||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
sectorSize = BLOCKSIZE*SectorCount;
|
sectorSize = BLOCKSIZE*SectorCount;
|
||||||
|
@ -87,7 +82,9 @@ DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
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);
|
ExFreePool(mbr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +98,7 @@ DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG DiskSector,
|
IN ULONG DiskSector,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN UCHAR* Buffer)
|
IN UCHAR* Buffer)
|
||||||
{
|
{
|
||||||
|
@ -112,13 +109,12 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG sectorSize;
|
ULONG sectorSize;
|
||||||
PULONG mbr;
|
PULONG mbr;
|
||||||
int j;
|
|
||||||
|
|
||||||
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||||
pDeviceObject,DiskSector,Buffer);
|
pDeviceObject,DiskSector,Buffer);
|
||||||
|
|
||||||
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
|
sectorNumber.HighPart = 0;
|
||||||
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
|
sectorNumber.LowPart = DiskSector * BLOCKSIZE;
|
||||||
|
|
||||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
|
@ -162,7 +158,7 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
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);
|
ExFreePool(mbr);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,27 +31,6 @@
|
||||||
|
|
||||||
#include "vfat.h"
|
#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 *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
||||||
|
@ -60,6 +39,10 @@ static PDRIVER_OBJECT DriverObject;
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
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 FATsector;
|
||||||
ULONG FATeis;
|
ULONG FATeis;
|
||||||
|
@ -67,8 +50,8 @@ ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
Block = ExAllocatePool(NonPagedPool,1024);
|
Block = ExAllocatePool(NonPagedPool,1024);
|
||||||
FATsector=CurrentCluster/(512/sizeof(ULONG));
|
FATsector=CurrentCluster/(512/sizeof(ULONG));
|
||||||
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
|
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
|
VFATReadSectors(DeviceExt->StorageDevice
|
||||||
Block);
|
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
|
||||||
CurrentCluster = Block[FATeis];
|
CurrentCluster = Block[FATeis];
|
||||||
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
||||||
CurrentCluster = 0;
|
CurrentCluster = 0;
|
||||||
|
@ -77,43 +60,39 @@ ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG Fat16GetNextCluster(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 FATsector;
|
||||||
ULONG FATeis;
|
ULONG FATeis;
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
|
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
FATsector=CurrentCluster/(512/sizeof(USHORT));
|
FATsector=CurrentCluster/(512/sizeof(USHORT));
|
||||||
FATeis=CurrentCluster-(FATsector*256);
|
FATeis=CurrentCluster-(FATsector*256);
|
||||||
|
memcpy(Block,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||||
|
|
||||||
// VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
|
|
||||||
// (UCHAR *)Block);
|
|
||||||
|
|
||||||
Block = (PUSHORT)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
|
||||||
|
|
||||||
CurrentCluster = Block[FATeis];
|
CurrentCluster = Block[FATeis];
|
||||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||||
CurrentCluster = 0;
|
CurrentCluster = 0;
|
||||||
|
ExFreePool(Block);
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG 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;
|
unsigned char* CBlock;
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
CBlock = ExAllocatePool(NonPagedPool,1024);
|
||||||
|
|
||||||
FATsector = (CurrentCluster * 12) / (512 * 8);
|
FATsector = (CurrentCluster * 12) / (512 * 8);
|
||||||
|
memcpy(CBlock,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||||
// VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart
|
|
||||||
// +FATsector,1,CBlock);
|
|
||||||
|
|
||||||
CBlock = (unsigned char *)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
|
||||||
|
|
||||||
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
||||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||||
if ((CurrentCluster % 2) == 0)
|
if ((CurrentCluster % 2) == 0)
|
||||||
|
@ -130,12 +109,15 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
CurrentCluster = Entry;
|
CurrentCluster = Entry;
|
||||||
|
ExFreePool(CBlock);
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG 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",
|
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||||
|
@ -155,6 +137,9 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Finds the first available cluster in a FAT16 table
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG sector;
|
ULONG sector;
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
|
@ -184,6 +169,9 @@ ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
|
|
||||||
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
ULONG FATeis;
|
ULONG FATeis;
|
||||||
|
@ -208,51 +196,21 @@ void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ExFreePool(Block);
|
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,
|
void WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Write a changed FAT entry
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
if (DeviceExt->FatType == FAT16) {
|
if (DeviceExt->FatType == FAT16) {
|
||||||
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||||
} else {
|
|
||||||
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Determines the next cluster to be written
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG LastCluster, NewCluster;
|
ULONG LastCluster, NewCluster;
|
||||||
BOOLEAN EOF = FALSE;
|
BOOLEAN EOF = FALSE;
|
||||||
|
@ -290,7 +248,7 @@ ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
if(DeviceExt->FatType == FAT16) {
|
if(DeviceExt->FatType == FAT16) {
|
||||||
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
|
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
|
||||||
} else {
|
} else {
|
||||||
FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
//FIXME FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, write the AU of the LastCluster with the value of the newly
|
/* 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)
|
unsigned long Cluster)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Converts the cluster number to a sector number for this physical
|
||||||
|
* device
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Convert an ANSI string to it's Unicode equivalent
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -326,6 +291,10 @@ void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtlCatAnsiToUnicode(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;
|
ULONG i;
|
||||||
|
|
||||||
|
@ -341,6 +310,9 @@ void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length)
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfat_initstr(wchar_t *wstr, ULONG wsize)
|
void vfat_initstr(wchar_t *wstr, ULONG wsize)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Initialize a string for use with a long file name
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
wchar_t nc=0;
|
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)
|
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;
|
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)
|
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;
|
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,
|
wchar_t * vfat_movstr(wchar_t * dest, const wchar_t *src, ULONG dpos,
|
||||||
ULONG spos, ULONG len)
|
ULONG spos, ULONG len)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Move the characters in a string to a new position in the same
|
||||||
|
* string
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
int i;
|
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)
|
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Determine if the given directory entry is the last
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
return(((FATDirEntry *)Block)[Offset].Filename[0] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset)
|
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) */
|
/* 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,
|
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;
|
FATDirEntry* test;
|
||||||
slot* test2;
|
slot* test2;
|
||||||
|
@ -490,8 +481,11 @@ BOOLEAN GetEntryName(PVOID Block, PULONG _Offset, PWSTR Name, PULONG _jloop,
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
|
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))
|
while (wtolower(*s1)==wtolower(*s2))
|
||||||
{
|
{
|
||||||
if ((*s1)==0 && (*s2)==0)
|
if ((*s1)==0 && (*s2)==0)
|
||||||
|
@ -504,100 +498,143 @@ BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2)
|
||||||
}
|
}
|
||||||
return(FALSE);
|
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,
|
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 i, j;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
char* block;
|
char* block;
|
||||||
WCHAR name[256];
|
WCHAR name[256];
|
||||||
ULONG StartingSector;
|
ULONG StartingSector;
|
||||||
ULONG NextCluster;
|
ULONG NextCluster;
|
||||||
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||||
|
|
||||||
if (Parent == NULL)
|
if (Parent == NULL)
|
||||||
{
|
{
|
||||||
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||||
StartingSector = DeviceExt->rootStart;
|
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],
|
Size = ULONG_MAX;
|
||||||
sizeof(FATDirEntry));
|
if (DeviceExt->FatType == FAT32)
|
||||||
|
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
|
||||||
ExFreePool(block);
|
else
|
||||||
return(STATUS_SUCCESS);
|
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
|
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
|
with 0xffff. This theory is still not 100% certain, so the following
|
||||||
lines are commented and not removed */
|
lines are commented and not removed */
|
||||||
|
|
||||||
StartingSector++;
|
StartingSector++;
|
||||||
/* if (Parent == NULL)
|
/* if (Parent == NULL)
|
||||||
{
|
{
|
||||||
StartingSector++;
|
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);
|
ExFreePool(block);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
@ -609,6 +646,7 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* NOP */
|
/* NOP */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
@ -640,7 +678,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
*next=0;
|
*next=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = FindFile(DeviceExt,Fcb,ParentFcb,current);
|
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
|
||||||
if (Status != STATUS_SUCCESS)
|
if (Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -649,15 +687,15 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
if (ParentFcb == NULL)
|
if (ParentFcb == NULL)
|
||||||
{
|
{
|
||||||
Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
Fcb = ExAllocatePool(NonPagedPool,sizeof(FCB));
|
||||||
ParentFcb = Temp;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Fcb = ParentFcb;
|
Fcb = ParentFcb;
|
||||||
ParentFcb = Temp;
|
|
||||||
}
|
}
|
||||||
|
ParentFcb = Temp;
|
||||||
}
|
}
|
||||||
FileObject->FsContext = ParentFcb;
|
FileObject->FsContext = ParentFcb;
|
||||||
|
DPRINT("file opn, fcb=%x\n",ParentFcb);
|
||||||
DPRINT("ParentFcb->entry.FileSize %d\n",ParentFcb->entry.FileSize);
|
DPRINT("ParentFcb->entry.FileSize %d\n",ParentFcb->entry.FileSize);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -666,7 +704,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||||
* by this fsd
|
* by this fsd
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
BootSector* Boot;
|
BootSector* Boot;
|
||||||
|
@ -692,8 +730,6 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
* FUNCTION: Mounts the device
|
* FUNCTION: Mounts the device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
DPRINT("Mounting VFAT device...");
|
DPRINT("Mounting VFAT device...");
|
||||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||||
|
|
||||||
|
@ -738,9 +774,13 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
||||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
||||||
}
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Load a cluster from the physical device
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG Sector;
|
ULONG Sector;
|
||||||
|
|
||||||
|
@ -756,6 +796,9 @@ void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
void VFATWriteCluster(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;
|
ULONG Sector;
|
||||||
|
|
||||||
|
@ -794,6 +837,9 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||||
else
|
else
|
||||||
CurrentCluster = Fcb->entry.FirstCluster;
|
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)
|
if (ReadOffset >= Fcb->entry.FileSize)
|
||||||
{
|
{
|
||||||
|
@ -804,15 +850,11 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
Length = Fcb->entry.FileSize - ReadOffset;
|
Length = Fcb->entry.FileSize - ReadOffset;
|
||||||
}
|
}
|
||||||
*LengthRead = 0;
|
*LengthRead = 0;
|
||||||
|
|
||||||
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
|
||||||
|
|
||||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||||
|
|
||||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
||||||
{
|
{
|
||||||
|
@ -949,6 +991,9 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Close a file
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
@ -965,6 +1010,9 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Create or open a file
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
|
@ -985,6 +1033,9 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Write to a file
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
|
@ -998,7 +1049,7 @@ NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
Length = Stack->Parameters.Write.Length;
|
Length = Stack->Parameters.Write.Length;
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
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);
|
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)
|
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Read from a file
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
|
@ -1024,14 +1078,13 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
Length = Stack->Parameters.Read.Length;
|
Length = Stack->Parameters.Read.Length;
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
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,
|
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset,
|
||||||
&LengthRead);
|
&LengthRead);
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = LengthRead;
|
Irp->IoStatus.Information = LengthRead;
|
||||||
|
|
||||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -1039,6 +1092,9 @@ NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Mount the filesystem
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
@ -1052,15 +1108,19 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||||
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
||||||
|
// use same vpb as device disk
|
||||||
|
DeviceObject->Vpb=DeviceToMount->Vpb;
|
||||||
FsdMountDevice(DeviceExt,DeviceToMount);
|
FsdMountDevice(DeviceExt,DeviceToMount);
|
||||||
|
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
||||||
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
||||||
DeviceToMount);
|
DeviceToMount);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: File system control
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||||
|
@ -1088,7 +1148,10 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
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;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
unsigned long AllocSize;
|
unsigned long AllocSize;
|
||||||
|
@ -1096,10 +1159,9 @@ NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
||||||
|
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = 0;
|
AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
|
||||||
while(AllocSize<FCB->entry.FileSize) {
|
DeviceExtension->BytesPerCluster) *
|
||||||
AllocSize+=DeviceExtension->BytesPerCluster;
|
DeviceExtension->BytesPerCluster;
|
||||||
}
|
|
||||||
|
|
||||||
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
|
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
|
||||||
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
|
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
|
||||||
|
@ -1115,20 +1177,24 @@ NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Retrieve the specified file information
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass =
|
FILE_INFORMATION_CLASS FileInformationClass =
|
||||||
Stack->Parameters.QueryFile.FileInformationClass;
|
Stack->Parameters.QueryFile.FileInformationClass;
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PFCB FCB = NULL;
|
PFCB FCB = NULL;
|
||||||
PCCB CCB = NULL;
|
// PCCB CCB = NULL;
|
||||||
|
|
||||||
NTSTATUS RC = STATUS_SUCCESS;
|
NTSTATUS RC = STATUS_SUCCESS;
|
||||||
void *SystemBuffer;
|
void *SystemBuffer;
|
||||||
|
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
CCB = (PCCB)(FileObject->FsContext2);
|
// CCB = (PCCB)(FileObject->FsContext2);
|
||||||
FCB = CCB->Buffer; // Should be CCB->FCB???
|
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||||
|
FCB=(PFCB)(FileObject->FsContext);
|
||||||
|
|
||||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
|
@ -1136,9 +1202,6 @@ NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
RC = STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RC;
|
return RC;
|
||||||
|
@ -1159,7 +1222,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
UNICODE_STRING ustr;
|
UNICODE_STRING ustr;
|
||||||
ANSI_STRING astr;
|
ANSI_STRING astr;
|
||||||
|
|
||||||
DbgPrint("VFAT 0.0.4\n");
|
DbgPrint("VFAT 0.0.5\n");
|
||||||
|
|
||||||
DriverObject = _DriverObject;
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
|
@ -1181,6 +1244,9 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
FsdFileSystemControl;
|
FsdFileSystemControl;
|
||||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||||
FsdQueryInformation;
|
FsdQueryInformation;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||||
|
FsdDirectoryControl;
|
||||||
|
|
||||||
DriverObject->DriverUnload = NULL;
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
IoRegisterFileSystem(DeviceObject);
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
%.o: %.asm
|
%.o: %.asm
|
||||||
$(NASM) $(NFLAGS) $< -o $@
|
$(NASM) $(NFLAGS) $< -o $@
|
||||||
|
|
||||||
all: blockdev.o iface.o
|
OBJECTS= blockdev.o iface.o dir.o
|
||||||
$(LD) iface.o blockdev.o -r -o vfatfsd.o
|
|
||||||
|
all: $(OBJECTS)
|
||||||
|
$(LD) $(OBJECTS) -r -o vfatfsd.o
|
||||||
|
$(NM) --numeric-sort vfatfsd.o > vfatfsd.sym
|
||||||
|
|
||||||
include ../../../rules.mak
|
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 {
|
struct _BootSector {
|
||||||
unsigned char magic0, res0, magic1;
|
unsigned char magic0, res0, magic1;
|
||||||
|
@ -45,9 +38,11 @@ struct _BootSector32 {
|
||||||
typedef struct _BootSector BootSector;
|
typedef struct _BootSector BootSector;
|
||||||
|
|
||||||
struct _FATDirEntry {
|
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 short FirstClusterHigh;// higher
|
||||||
unsigned char Res2[4];
|
unsigned short UpdateTime;//time create/update
|
||||||
|
unsigned short UpdateDate;//date create/update
|
||||||
unsigned short FirstCluster;
|
unsigned short FirstCluster;
|
||||||
unsigned long FileSize;
|
unsigned long FileSize;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -108,3 +103,59 @@ typedef struct _SFsdFileControlBlock {
|
||||||
} SFsdFCB, *PtrSFsdFCB;
|
} 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;
|
} u;
|
||||||
} SetFile;
|
} SetFile;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a guess
|
||||||
|
*/
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
ULONG Length;
|
|
||||||
PUNICODE_STRING FileName;
|
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass;
|
||||||
ULONG FileIndex;
|
BOOLEAN ReturnSingleEntry;
|
||||||
|
PUNICODE_STRING FileName;
|
||||||
|
BOOLEAN RestartScan;
|
||||||
|
ULONG BufferLength;
|
||||||
|
ULONG FileIndex;
|
||||||
} QueryDirectory;
|
} QueryDirectory;
|
||||||
} Parameters;
|
} Parameters;
|
||||||
|
|
||||||
|
|
|
@ -164,4 +164,124 @@ __OUTS(l)
|
||||||
__inlc_p(port) : \
|
__inlc_p(port) : \
|
||||||
__inl_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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/io/dir.c
|
* FILE: ntoskrnl/io/dir.c
|
||||||
* PURPOSE: Directory functions
|
* PURPOSE: Directory functions
|
||||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* Created 22/05/98
|
* Created 22/05/98
|
||||||
*/
|
*/
|
||||||
|
@ -13,22 +13,25 @@
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/io.h>
|
#include <internal/io.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS STDCALL NtQueryDirectoryFile(IN HANDLE FileHandle,
|
NTSTATUS STDCALL
|
||||||
IN HANDLE Event OPTIONAL,
|
NtQueryDirectoryFile(
|
||||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
IN HANDLE FileHandle,
|
||||||
IN PVOID ApcContext OPTIONAL,
|
IN HANDLE Event OPTIONAL,
|
||||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||||
OUT PVOID FileInformation,
|
IN PVOID ApcContext OPTIONAL,
|
||||||
IN ULONG Length,
|
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||||
IN FILE_INFORMATION_CLASS
|
OUT PVOID FileInformation,
|
||||||
FileInformationClass,
|
IN ULONG Length,
|
||||||
IN BOOLEAN ReturnSingleEntry,
|
IN FILE_INFORMATION_CLASS FileInformationClass,
|
||||||
IN PUNICODE_STRING FileName OPTIONAL,
|
IN BOOLEAN ReturnSingleEntry,
|
||||||
IN BOOLEAN RestartScan)
|
IN PUNICODE_STRING FileName OPTIONAL,
|
||||||
|
IN BOOLEAN RestartScan
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return(ZwQueryDirectoryFile(FileHandle,
|
return(ZwQueryDirectoryFile(FileHandle,
|
||||||
Event,
|
Event,
|
||||||
|
@ -131,96 +134,46 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
BOOLEAN IndexSpecified;
|
|
||||||
ULONG Idx;
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_LIST_DIRECTORY,
|
FILE_LIST_DIRECTORY,
|
||||||
IoFileType,
|
IoFileType,
|
||||||
UserMode,
|
UserMode,
|
||||||
&FileObject,
|
(PVOID *)&FileObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (Status != STATUS_SUCCESS)
|
if (Status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||||
DeviceObject = FileObject->DeviceObject;
|
DeviceObject = FileObject->DeviceObject;
|
||||||
|
|
||||||
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||||
|
if (Irp==NULL)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
|
||||||
|
|
||||||
Irp->UserIosb = IoStatusBlock;
|
Irp->UserIosb = IoStatusBlock;
|
||||||
Irp->UserEvent = &Event;
|
Irp->UserEvent = &Event;
|
||||||
|
Irp->UserBuffer=FileInformation;
|
||||||
|
|
||||||
IoStack = IoGetNextIrpStackLocation(Irp);
|
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->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
|
||||||
IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
|
IoStack->MinorFunction = IRP_MN_QUERY_DIRECTORY;
|
||||||
|
IoStack->Flags = 0;
|
||||||
IoStack->Control = 0;
|
IoStack->Control = 0;
|
||||||
IoStack->DeviceObject = DeviceObject;
|
IoStack->DeviceObject = DeviceObject;
|
||||||
IoStack->FileObject = FileObject;
|
IoStack->FileObject = FileObject;
|
||||||
|
|
||||||
IoStack->Parameters.QueryDirectory.FileInformationClass =
|
IoStack->Parameters.QueryDirectory.FileInformationClass =
|
||||||
FileInformationClass;
|
FileInformationClass;
|
||||||
|
IoStack->Parameters.QueryDirectory.ReturnSingleEntry =
|
||||||
|
ReturnSingleEntry;
|
||||||
IoStack->Parameters.QueryDirectory.FileName = FileName;
|
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);
|
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
||||||
if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||||
|
|
|
@ -107,7 +107,10 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
Status = ZwOpenFile(&FileHandle, 0, &FileObjectAttributes, NULL, 0, 0);
|
Status = ZwOpenFile(&FileHandle,
|
||||||
|
FILE_ALL_ACCESS,
|
||||||
|
&FileObjectAttributes,
|
||||||
|
NULL, 0, 0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -28,7 +28,9 @@ static unsigned char TstReadLineReadChar(VOID)
|
||||||
KEY_EVENT_RECORD key[2];
|
KEY_EVENT_RECORD key[2];
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
|
||||||
ZwReadFile(KeyboardHandle,
|
key[0].AsciiChar=0;
|
||||||
|
while(!key[0].AsciiChar)
|
||||||
|
ZwReadFile(KeyboardHandle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -37,7 +39,6 @@ static unsigned char TstReadLineReadChar(VOID)
|
||||||
sizeof(KEY_EVENT_RECORD)*2,
|
sizeof(KEY_EVENT_RECORD)*2,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
// DbgPrint("%c",key[0].AsciiChar);
|
|
||||||
return(key[0].AsciiChar);
|
return(key[0].AsciiChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +51,6 @@ VOID TstReadLine(ULONG Length, PCHAR Buffer)
|
||||||
for (i=0;i<Length;i++)
|
for (i=0;i<Length;i++)
|
||||||
{
|
{
|
||||||
tmp = TstReadLineReadChar();
|
tmp = TstReadLineReadChar();
|
||||||
// DbgPrint("%x %x ",tmp,'\n');
|
|
||||||
switch (tmp)
|
switch (tmp)
|
||||||
{
|
{
|
||||||
case 0xd:
|
case 0xd:
|
||||||
|
|
|
@ -19,16 +19,21 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
int ShellChangeDir(char* args);
|
int ShellChangeDirOb(char* args);
|
||||||
int ShellListDir(char* args);
|
int ShellListDirOb(char* args);
|
||||||
|
int ShellChangeDirFile(char* args);
|
||||||
|
int ShellListDirFile(char* args);
|
||||||
VOID TstReadLineInit(VOID);
|
VOID TstReadLineInit(VOID);
|
||||||
VOID TstReadLine(ULONG Length, PCHAR Buffer);
|
VOID TstReadLine(ULONG Length, PCHAR Buffer);
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
static HANDLE CurrentDirHandle = NULL;
|
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 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
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -38,8 +43,10 @@ typedef struct
|
||||||
|
|
||||||
command commands[]=
|
command commands[]=
|
||||||
{
|
{
|
||||||
{"cd",ShellChangeDir},
|
{"fcd",ShellChangeDirFile},
|
||||||
{"dir",ShellListDir},
|
{"fdir",ShellListDirFile},
|
||||||
|
{"ocd",ShellChangeDirOb},
|
||||||
|
{"odir",ShellListDirOb},
|
||||||
{NULL,NULL},
|
{NULL,NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,11 +61,12 @@ char* eat_white_space(char* s)
|
||||||
return(s);
|
return(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShellChangeDir(char* args)
|
int ShellChangeDirOb(char* args)
|
||||||
{
|
{
|
||||||
char* end;
|
char* end;
|
||||||
ANSI_STRING astr;
|
ANSI_STRING astr;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("ShellChangeDir(args %s)\n",args);
|
DPRINT("ShellChangeDir(args %s)\n",args);
|
||||||
|
|
||||||
|
@ -68,7 +76,8 @@ int ShellChangeDir(char* args)
|
||||||
{
|
{
|
||||||
*end=0;
|
*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);
|
DPRINT("current_dir_name %s\n",current_dir_name);
|
||||||
|
|
||||||
|
@ -76,33 +85,130 @@ int ShellChangeDir(char* args)
|
||||||
RtlAnsiStringToUnicodeString(&CurrentDirName,&astr,TRUE);
|
RtlAnsiStringToUnicodeString(&CurrentDirName,&astr,TRUE);
|
||||||
InitializeObjectAttributes(&attr,&CurrentDirName,0,NULL,NULL);
|
InitializeObjectAttributes(&attr,&CurrentDirName,0,NULL,NULL);
|
||||||
ZwClose(CurrentDirHandle);
|
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];
|
OBJDIR_INFORMATION DirObj[50];
|
||||||
ULONG Idx;
|
ULONG Idx=0;
|
||||||
ULONG Length;
|
ULONG Length=0;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
|
if (args) args = eat_white_space(args);
|
||||||
DbgPrint("ShellListDir(args %s)\n",args);
|
DbgPrint("ShellListDir(args %s)\n",args);
|
||||||
|
|
||||||
ZwQueryDirectoryObject(CurrentDirHandle,
|
ZwQueryDirectoryObject(CurrentDirHandle,
|
||||||
&(DirObj[0]),
|
&(DirObj[0]),
|
||||||
sizeof(DirObj),
|
sizeof(DirObj),
|
||||||
TRUE,
|
TRUE,
|
||||||
TRUE,
|
TRUE,
|
||||||
&Idx,
|
&Idx,
|
||||||
&Length);
|
&Length);
|
||||||
|
DbgPrint("read %d bytes,Idx=%d\n",Length,Idx);
|
||||||
for (i=0;i<(Length/sizeof(OBJDIR_INFORMATION));i++)
|
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);
|
printk("%w# ",CurrentDirName.Buffer);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +216,7 @@ VOID ShellDisplayPrompt()
|
||||||
VOID ShellProcessCommand(char* cmd)
|
VOID ShellProcessCommand(char* cmd)
|
||||||
{
|
{
|
||||||
unsigned int i=0;
|
unsigned int i=0;
|
||||||
DbgPrint("Processing cmd '%s'\n",cmd);
|
DbgPrint("Processing cmd :%s.\n",cmd);
|
||||||
while (commands[i].name!=NULL)
|
while (commands[i].name!=NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("Scanning %s i %d\n",commands[i].name,i);
|
DbgPrint("Scanning %s i %d\n",commands[i].name,i);
|
||||||
|
@ -142,6 +248,7 @@ NTSTATUS TstShell(VOID)
|
||||||
InitializeObjectAttributes(&attr,&ufilename,0,NULL,NULL);
|
InitializeObjectAttributes(&attr,&ufilename,0,NULL,NULL);
|
||||||
ZwOpenDirectoryObject(&CurrentDirHandle,0,&attr);
|
ZwOpenDirectoryObject(&CurrentDirHandle,0,&attr);
|
||||||
|
|
||||||
|
ShellChangeDirFile("\\??\\C:\\");
|
||||||
|
|
||||||
TstReadLineInit();
|
TstReadLineInit();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue