Various changes to support the executable/driver loader

svn path=/trunk/; revision=130
This commit is contained in:
Rex Jolliff 1998-12-20 19:41:39 +00:00
parent a9ce8c6379
commit 6cd2bc16b8
35 changed files with 1461 additions and 323 deletions

View file

@ -93,3 +93,80 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
DPRINT("Block request succeeded\n");
return TRUE;
}
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN UCHAR* Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
PULONG mbr;
int j;
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
sectorNumber.HighPart = 0;
sectorNumber.LowPart = DiskSector * BLOCKSIZE;
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
mbr = ExAllocatePool(NonPagedPool, sectorSize);
if (!mbr) {
return FALSE;
}
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
pDeviceObject,
mbr,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("WRITE failed!!!\n");
ExFreePool(mbr);
return FALSE;
}
DPRINT("Calling IO Driver...\n");
status = IoCallDriver(pDeviceObject,
irp);
DPRINT("Waiting for IO Operation...\n");
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Suspended,
KernelMode,
FALSE,
NULL);
DPRINT("Getting IO Status...\n");
status = ioStatus.Status;
}
if (!NT_SUCCESS(status)) {
DbgPrint("IO failed!!! Error code: %d\n", status);
ExFreePool(mbr);
return FALSE;
}
DPRINT("Copying memory...\n");
RtlCopyMemory(Buffer,mbr,sectorSize);
ExFreePool(mbr);
DPRINT("Block request succeeded\n");
return TRUE;
}

View file

@ -12,6 +12,10 @@
28-10-1998 Reads entire FAT into memory
VFatReadSector modified to read in more than one sector at a time
7-11-1998 Fixed bug that assumed that directory data could be fragmented
8-12-1998 Added FAT32 support
Added initial writability functions
WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
12-12-1998 Added basic support for FILE_STANDARD_INFORMATION request
*/
@ -20,6 +24,7 @@
#include <ddk/ntddk.h>
#include <internal/string.h>
#include <wstring.h>
#include <ddk/cctypes.h>
#define NDEBUG
#include <internal/debug.h>
@ -28,6 +33,7 @@
#define FAT16 (1)
#define FAT12 (2)
#define FAT32 (3)
typedef struct
{
@ -53,6 +59,23 @@ static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
{
ULONG FATsector;
ULONG FATeis;
PULONG Block;
Block = ExAllocatePool(NonPagedPool,1024);
FATsector=CurrentCluster/(512/sizeof(ULONG));
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
Block);
CurrentCluster = Block[FATeis];
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
CurrentCluster = 0;
ExFreePool(Block);
return(CurrentCluster);
}
ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
{
ULONG FATsector;
@ -69,14 +92,10 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
Block = (PUSHORT)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
CurrentCluster = Block[FATeis];
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
{
CurrentCluster = 0;
}
DPRINT("Returning %x\n",CurrentCluster);
return(CurrentCluster);
}
@ -96,9 +115,7 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
CBlock = (unsigned char *)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
FATOffset = (CurrentCluster * 12) % (512 * 8);
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
if ((CurrentCluster % 2) == 0)
{
Entry = CBlock[((FATOffset / 24)*3)];
@ -109,18 +126,12 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
}
DPRINT("Entry %x\n",Entry);
if (Entry >= 0xff8 && Entry <= 0xfff)
{
Entry = 0;
}
CurrentCluster = Entry;
DPRINT("Returning %x\n",CurrentCluster);
return(CurrentCluster);
}
@ -133,12 +144,170 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
{
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
}
else if (DeviceExt->FatType == FAT32)
{
return(Fat32GetNextCluster(DeviceExt, CurrentCluster));
}
else
{
{
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
}
}
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
{
ULONG sector;
PUSHORT Block;
int i;
sector = 0;
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
while(sector<DeviceExt->Boot->FATSectors) {
memcpy(Block, DeviceExt->FAT+sector*BLOCKSIZE, BLOCKSIZE);
for(i=0; i<512; i++) {
if(Block[i]==0) {
ExFreePool(Block);
return i;
}
}
sector++;
}
/* Give an error message (out of disk space) if we reach here) */
ExFreePool(Block);
return 0;
}
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
ULONG NewValue)
{
ULONG FATsector;
ULONG FATeis;
PUSHORT Block;
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
FATsector=ClusterToWrite/(512/sizeof(USHORT));
FATeis=ClusterToWrite-(FATsector*256);
/* Update the in-memory FAT */
memcpy(Block, DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
Block[FATeis] = NewValue;
memcpy(DeviceExt->FAT+FATsector*BLOCKSIZE, Block, BLOCKSIZE);
/* Write the changed FAT sector to disk */
VFATWriteSectors(DeviceExt->StorageDevice,
DeviceExt->FATStart+FATsector,
DeviceExt->Boot->SectorsPerCluster,
(UCHAR *)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,
ULONG NewValue)
{
if (DeviceExt->FatType == FAT16) {
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
} else {
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
}
}
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
{
ULONG LastCluster, NewCluster;
BOOLEAN EOF = FALSE;
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
DeviceExt,CurrentCluster);
/* Find out what was happening in the last cluster's AU */
if (DeviceExt->FatType == FAT16)
{
LastCluster = Fat16GetNextCluster(DeviceExt, CurrentCluster);
if(LastCluster == 0xFFFF) {
EOF = TRUE;
}
}
else
{
LastCluster = Fat12GetNextCluster(DeviceExt, CurrentCluster);
if(LastCluster == 0xFFF) {
EOF = TRUE;
}
}
/* Check to see if we must append or overwrite */
if (EOF == TRUE) {
/* Append */
/* Firstly, find the next available open allocation unit */
NewCluster = FAT16FindAvailableCluster(DeviceExt);
/* Mark the new AU as the EOF */
if(DeviceExt->FatType == FAT16) {
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
} else {
FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
}
/* Now, write the AU of the LastCluster with the value of the newly
found AU */
WriteCluster(DeviceExt, LastCluster, NewCluster);
/* Return NewCluster as CurrentCluster */
return NewCluster;
} else {
/* Overwrite: Return LastCluster as CurrentCluster */
return LastCluster;
}
}
unsigned long ClusterToSector(PDEVICE_EXTENSION DeviceExt,
unsigned long Cluster)
{
@ -345,12 +514,11 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
WCHAR name[256];
ULONG StartingSector;
ULONG NextCluster;
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
if (Parent == NULL)
{
Size = DeviceExt->rootDirectorySectors;
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
StartingSector = DeviceExt->rootStart;
}
else
@ -358,10 +526,12 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
Size = ULONG_MAX;
StartingSector = ClusterToSector(DeviceExt, Parent->entry.FirstCluster);
NextCluster = Parent->entry.FirstCluster;
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++)
@ -381,12 +551,20 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
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;
}
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
sizeof(FATDirEntry));
@ -492,13 +670,14 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
*/
{
BootSector* Boot;
Boot = ExAllocatePool(NonPagedPool,512);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
if (strncmp(Boot->SysType,"FAT12",5)==0 ||
strncmp(Boot->SysType,"FAT16",5)==0)
strncmp(Boot->SysType,"FAT16",5)==0 ||
strncmp(((struct _BootSector32 *)(Boot))->SysType,"FAT32",5)==0)
{
ExFreePool(Boot);
return(TRUE);
@ -507,7 +686,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
return(FALSE);
}
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Mounts the device
@ -517,7 +696,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
DPRINT("Mounting VFAT device...");
DPRINT("DeviceExt %x\n",DeviceExt);
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
@ -538,29 +717,57 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
{
DeviceExt->FatType = FAT12;
}
else if (strncmp(((struct _BootSector32 *)(DeviceExt->Boot))->SysType,"FAT32",5)==0)
{
DeviceExt->FatType = FAT32;
DeviceExt->rootDirectorySectors=DeviceExt->Boot->SectorsPerCluster;
DeviceExt->rootStart=
DeviceExt->FATStart+DeviceExt->Boot->FATCount
* ((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
DeviceExt->dataStart=DeviceExt->rootStart;
}
else
{
DeviceExt->FatType = FAT16;
}
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
// with FAT32 it's not a good idea to load always fat in memory
// because on a 8GB partition with 2 KO clusters, the fat = 8 MO
if(DeviceExt->FatType!=FAT32)
{
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
}
}
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
{
ULONG Sector;
ULONG i;
DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster);
VFATReadSectors(DeviceExt->StorageDevice,
Sector,
DeviceExt->Boot->SectorsPerCluster,
Buffer);
}
void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
{
ULONG Sector;
// DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
// DeviceExt,Buffer,Cluster);
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
DeviceExt,Buffer,Cluster);
Sector = ClusterToSector(DeviceExt, Cluster);
Sector = ClusterToSector(DeviceExt, Cluster);
VFATReadSectors(DeviceExt->StorageDevice,
Sector,
DeviceExt->Boot->SectorsPerCluster,
Buffer);
VFATWriteSectors(DeviceExt->StorageDevice,
Sector,
DeviceExt->Boot->SectorsPerCluster,
Buffer);
}
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
@ -573,7 +780,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
ULONG CurrentCluster;
ULONG FileOffset;
ULONG FirstCluster;
PFCB Fcb;
PFCB Fcb;
PVOID Temp;
ULONG TempLength;
@ -583,7 +790,10 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
Fcb = FileObject->FsContext;
CurrentCluster = Fcb->entry.FirstCluster;
if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
else
CurrentCluster = Fcb->entry.FirstCluster;
if (ReadOffset >= Fcb->entry.FileSize)
{
@ -627,7 +837,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
if (CurrentCluster == 0)
{
ExFreePool(Temp);
ExFreePool(Temp);
return(STATUS_SUCCESS);
}
@ -646,6 +856,97 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return(STATUS_SUCCESS);
}
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PVOID Buffer, ULONG Length, ULONG WriteOffset)
/*
* FUNCTION: Writes data to file
*/
{
ULONG CurrentCluster;
ULONG FileOffset;
ULONG FirstCluster;
PFCB Fcb;
PVOID Temp;
ULONG TempLength;
/* Locate the first cluster of the file */
FirstCluster = WriteOffset / DeviceExt->BytesPerCluster;
Fcb = FileObject->FsContext;
if (DeviceExt->FatType == FAT32)
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
else
CurrentCluster = Fcb->entry.FirstCluster;
/* Allocate a buffer to hold 1 cluster of data */
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
/* Find the cluster according to the offset in the file */
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
{
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
}
CHECKPOINT;
/*
If the offset in the cluster doesn't fall on the cluster boundary then
we have to write only from the specified offset
*/
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
{
TempLength = min(Length,DeviceExt->BytesPerCluster -
(WriteOffset % DeviceExt->BytesPerCluster));
/* Read in the existing cluster data */
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
/* Overwrite the last parts of the data as necessary */
memcpy(Temp + WriteOffset % DeviceExt->BytesPerCluster, Buffer,
TempLength);
/* Write the cluster back */
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
/* Next write cluster */
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
Length = Length - TempLength;
Buffer = Buffer + TempLength;
}
CHECKPOINT;
/* Write the buffer in chunks of 1 cluster */
while (Length > DeviceExt->BytesPerCluster)
{
VFATWriteCluster(DeviceExt, Buffer, CurrentCluster);
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
if (CurrentCluster == 0)
{
ExFreePool(Temp);
return(STATUS_SUCCESS);
}
Buffer = Buffer + DeviceExt->BytesPerCluster;
Length = Length - DeviceExt->BytesPerCluster;
}
CHECKPOINT;
/* Write the remainder */
if (Length > 0)
{
memcpy(Temp, Buffer, Length);
VFATWriteCluster(DeviceExt, Temp, CurrentCluster);
}
ExFreePool(Temp);
return(STATUS_SUCCESS);
}
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
@ -653,7 +954,7 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
Status = FsdCloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status;
@ -685,11 +986,27 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Write.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Write.ByteOffset.LowPart;
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
@ -746,10 +1063,10 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PVPB vpb = Stack->Parameters.Mount.Vpb;
// PVPB vpb = Stack->Parameters.Mount.Vpb;
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
NTSTATUS Status;
DPRINT("VFAT FSC\n");
if (FsdHasFileSystem(DeviceToMount))
@ -762,7 +1079,7 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Status = STATUS_UNRECOGNIZED_VOLUME;
}
DPRINT("VFAT File system successfully mounted\n");
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
@ -770,6 +1087,60 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
return(Status);
}
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
PFILE_STANDARD_INFORMATION StandardInfo)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
unsigned long AllocSize;
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
/* Make allocsize a rounded up multiple of BytesPerCluster */
AllocSize = 0;
while(AllocSize<FCB->entry.FileSize) {
AllocSize+=DeviceExtension->BytesPerCluster;
}
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
StandardInfo->NumberOfLinks = 0;
StandardInfo->DeletePending = FALSE;
if((FCB->entry.Attrib & 0x10)>0) {
StandardInfo->Directory = TRUE;
} else {
StandardInfo->Directory = FALSE;
}
return STATUS_SUCCESS;
}
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
FILE_INFORMATION_CLASS FileInformationClass =
Stack->Parameters.QueryFile.FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PFCB FCB = NULL;
PCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS;
void *SystemBuffer;
FileObject = Stack->FileObject;
CCB = (PCCB)(FileObject->FsContext2);
FCB = CCB->Buffer; // Should be CCB->FCB???
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
switch(FileInformationClass) {
case FileStandardInformation:
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
break;
}
return RC;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
@ -785,7 +1156,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
UNICODE_STRING ustr;
ANSI_STRING astr;
DbgPrint("VFAT 0.0.3\n");
DbgPrint("VFAT 0.0.4\n");
DriverObject = _DriverObject;
@ -805,6 +1176,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
FsdFileSystemControl;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
FsdQueryInformation;
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);

View file

@ -3,6 +3,11 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
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;
unsigned char OEMName[8];
@ -20,10 +25,29 @@ struct _BootSector {
unsigned char Res2[450];
} __attribute__((packed));
struct _BootSector32 {
unsigned char magic0, res0, magic1;
unsigned char OEMName[8];
unsigned short BytesPerSector;
unsigned char SectorsPerCluster;
unsigned short ReservedSectors;
unsigned char FATCount;
unsigned short RootEntries, Sectors;
unsigned char Media;
unsigned short FATSectors, SectorsPerTrack, Heads;
unsigned long HiddenSectors, SectorsHuge;
unsigned long FATSectors32;
unsigned char x[31];
unsigned char VolumeLabel[11], SysType[8];
unsigned char Res2[422];
} __attribute__((packed));
typedef struct _BootSector BootSector;
struct _FATDirEntry {
unsigned char Filename[8], Ext[3], Attrib, Res[14];
unsigned char Filename[8], Ext[3], Attrib, Res[8];
unsigned short FirstClusterHigh;// higher
unsigned char Res2[4];
unsigned short FirstCluster;
unsigned long FileSize;
} __attribute__((packed));
@ -46,3 +70,41 @@ struct _slot
typedef struct _slot slot;
#define BLOCKSIZE 512
// Put the rest in struct.h
/*
typedef unsigned int uint32;
typedef struct _SFsdIdentifier {
uint32 NodeType;
uint32 NodeSize;
} SFsdIdentifier, *PtrSFsdIdentifier;
typedef struct _SFsdNTRequiredFCB {
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
SECTION_OBJECT_POINTERS SectionObject;
ERESOURCE MainResource;
ERESOURCE PagingIoResource;
} SFsdNTRequiredFCB, *PtrSFsdNTRequiredFCB;
typedef struct _SFsdFileControlBlock {
SFsdIdentifier NodeIdentifier;
SFsdNTRequiredFCB NTRequiredFCB;
SFsdDiskDependentFCB DiskDependentFCB;
struct _SFsdVolumeControlBlock *PtrVCB;
LIST_ENTRY NextFCB;
uint32 FCBFlags;
LIST_ENTRY NextCCB;
SHARE_ACCESS FCBShareAccess;
uint32 LazyWriterThreadID;
uint32 ReferenceCount;
uint32 OpenHandleCount;
PtrSFsdObjectName FCBName;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
SFsdFileLockAnchorFCB ByteRangeLock;
OPLOCK FCBOplock;
} SFsdFCB, *PtrSFsdFCB;
*/

View file

@ -1,4 +1,9 @@
#ifndef __DDK_LI_H
#define __DDK_LI_H
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
#ifdef COMPILER_LARGE_INTEGERS
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >> 32) )
@ -7,14 +12,19 @@
( LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
( LargeInteger |= Unsigned_Long )
#define LARGE_INTEGER_QUAD_PART(LargeInteger) (LargeInteger)
#else
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (LargeInteger.HighPart) )
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger.LowPart) )
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (LargeInteger).HighPart )
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger).LowPart )
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) \
( LargeInteger.HighPart= Signed_Long )
((LargeInteger).HighPart = (Signed_Long))
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
( LargeInteger.LowPart = Unsigned_Long )
((LargeInteger).LowPart = (Unsigned_Long))
#define LARGE_INTEGER_QUAD_PART(LI) (*(LONGLONG *)(&(LI)))
#endif
#endif

View file

@ -20,7 +20,7 @@ extern "C"
#include <windows.h>
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
#include <ddk/li.h>
#include <ddk/status.h>
#include <ddk/ntdef.h>

View file

@ -39,6 +39,11 @@ typedef struct _UNICODE_STRING
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
#define INIT_UNICODE_STRING(us, str) \
((us).Length = strlen((str)), \
(us).MaximumLength = (us).Length, \
(us).Buffer = (str), (us))
typedef enum _SECTION_INHERIT {
ViewShare = 1,
ViewUnmap = 2

View file

@ -3,11 +3,10 @@
#define __MODULE_H
#include <coff.h>
#include <pe.h>
typedef struct
/*
*
*/
/* FIXME: replace this struct with struct below in all code */
typedef struct _module
{
unsigned int nsyms;
unsigned int text_base;
@ -29,6 +28,45 @@ typedef struct
unsigned int raw_data_off;
} module;
typedef SCNHDR COFF_SECTION_HEADER, *PCOFF_SECTION_HEADER;
typedef struct _MODULE
{
PVOID Base;
unsigned int Size;
unsigned int Flags;
union
{
struct
{
unsigned int NumberOfSyms;
PVOID TextBase;
PVOID DataBase;
PVOID BSSBase;
SCNHDR *SectionList;
char *StringTable;
SYMENT *SymbolList;
} COFF;
struct
{
PIMAGE_FILE_HEADER FileHeader;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
PCOFF_SECTION_HEADER SectionList;
} PE;
} Image;
} MODULE, *PMODULE;
#define MODULE_FLAG_BIN 0x0001
#define MODULE_FLAG_MZ 0x0002
#define MODULE_FLAG_NE 0x0004
#define MODULE_FLAG_PE 0x0008
#define MODULE_FLAG_COFF 0x0010
typedef struct _INSTANCE
{
HANDLE ModuleHandle;
} INSTANCE, *PINSTANCE;
BOOLEAN process_boot_module(unsigned int start);
#endif

View file

@ -8,7 +8,7 @@ typedef DWORD *PDWORD;
#endif
#define IMAGE_DOS_MAGIC 0x54ad
#define IMAGE_NT_MAGIC 0x00004550
#define IMAGE_PE_MAGIC 0x00004550
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
@ -613,12 +613,10 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
// old checksum didn't match.
//
// End Image Format
//
#define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
#define MAXRESOURCENAME 13
@ -646,13 +644,34 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
sizeof (IMAGE_FILE_HEADER) + \
sizeof (IMAGE_OPTIONAL_HEADER)))
typedef struct _IMAGE_IMPORT_MODULE_DIRECTORY
{
DWORD dwRVAFunctionNameList;
DWORD dwUseless1;
DWORD dwUseless2;
DWORD dwRVAModuleName;
DWORD dwRVAFunctionAddressList;
} IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
typedef struct tagImportDirectory
{
DWORD dwRVAFunctionNameList;
DWORD dwUseless1;
DWORD dwUseless2;
DWORD dwRVAModuleName;
DWORD dwRVAFunctionAddressList;
}IMAGE_IMPORT_MODULE_DIRECTORY, * PIMAGE_IMPORT_MODULE_DIRECTORY;
typedef struct _RELOCATION_DIRECTORY
{
DWORD VirtualAddress; /* adresse virtuelle du bloc ou se font les relocations */
DWORD SizeOfBlock; // taille de cette structure + des structures
// relocation_entry qui suivent (ces dernieres sont
// donc au nombre de (SizeOfBlock-8)/2
} RELOCATION_DIRECTORY, *PRELOCATION_DIRECTORY;
typedef struct _RELOCATION_ENTRY
{
WORD TypeOffset;
// (TypeOffset >> 12) est le type
// (TypeOffset&0xfff) est l'offset dans le bloc
} RELOCATION_ENTRY, *PRELOCATION_ENTRY;
#define TYPE_RELOC_ABSOLUTE 0
#define TYPE_RELOC_HIGH 1
#define TYPE_RELOC_LOW 2
#define TYPE_RELOC_HIGHLOW 3
#define TYPE_RELOC_HIGHADJ 4
#define TYPE_RELOC_MIPS_JMPADDR 5

View file

@ -32,11 +32,25 @@
#ifndef _GNU_H_WINDOWS32_STRUCTURES
#define _GNU_H_WINDOWS32_STRUCTURES
#ifdef COMPILER_LARGE_INTEGERS
typedef long long int LARGE_INTEGER, *PLARGE_INTEGER;
typedef unsigned long long int ULARGE_INTEGER, *PULARGE_INTEGER;
#else
typedef struct _LARGE_INTEGER {
DWORD LowPart;
LONG HighPart;
} LARGE_INTEGER, *PLARGE_INTEGER;
typedef struct _ULARGE_INTEGER {
DWORD LowPart;
DWORD HighPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;
#endif
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
@ -129,11 +143,6 @@ typedef struct _CRITICAL_SECTION {
DWORD Reserved;
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
typedef struct _ULARGE_INTEGER {
DWORD LowPart;
DWORD HighPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;
typedef struct _GENERIC_MAPPING {
ACCESS_MASK GenericRead;
ACCESS_MASK GenericWrite;

View file

@ -390,6 +390,7 @@ rostitle db '',0
;
;
loading_msg db 'Loading: ',0
death_msg: db 'death', 0
filelength_lo dw 0
filelength_hi dw 0

View file

@ -31,7 +31,7 @@ LOADERS = dos
# Select the device drivers and filesystems you want
#
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
minix vfat ext2fs
minix vfat # ext2fs
APPS = hello shell

View file

@ -165,8 +165,8 @@ static NTSTATUS CbReadBlock(PDCCB Dccb, PCCB Ccb)
Ccb->Buffer=ExAllocatePool(NonPagedPool,Dccb->SectorSize);
}
Offset.HighPart = 0;
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
KeInitializeEvent(&Event,NotificationEvent,FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
Dccb->DeviceObject,
@ -206,8 +206,8 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
NTSTATUS Status;
KEVENT Event;
Offset.HighPart = 0;
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
KeInitializeEvent(&Event,NotificationEvent,FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
Dccb->DeviceObject,
@ -231,7 +231,7 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
PCCB CbFindModifiedCcb(PDCCB Dccb, PCCB Start)
{
UNIMPLEMENTED;
}
static VOID CbDeleteAllCcbs(PDCCB Dccb)

View file

@ -122,10 +122,14 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
{
LARGE_INTEGER timeout;
timeout.HighPart = 0;
timeout.LowPart = 0;
KeWaitForSingleObject(&Resource->ExclusiveWaiters,Executive,KernelMode,
FALSE,&timeout);
SET_LARGE_INTEGER_HIGH_PART(timeout, 0);
SET_LARGE_INTEGER_LOW_PART(timeout, 0);
return KeWaitForSingleObject(&Resource->ExclusiveWaiters,
Executive,
KernelMode,
FALSE,
&timeout) == STATUS_SUCCESS;
}

View file

@ -201,11 +201,14 @@ PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
* FUNCTION: Returns the physical address corresponding to a virtual address
*/
{
PHYSICAL_ADDRESS p;
DPRINT("get_page_physical_address(vaddr %x)\n",vaddr);
p.HighPart = 0;
p.LowPart = PAGE_MASK(*get_page_entry((unsigned int)vaddr));
return(p);
PHYSICAL_ADDRESS p;
DPRINT("get_page_physical_address(vaddr %x)\n", vaddr);
SET_LARGE_INTEGER_HIGH_PART(p, 0);
SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(
*get_page_entry((unsigned int) vaddr)));
return p;
}
BOOL is_page_present(unsigned int vaddr)

View file

@ -21,7 +21,8 @@
#define SERIAL_PORT 0x03f8
#define SERIAL_BAUD_RATE 19200
#define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/

View file

@ -170,15 +170,12 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
}
if (StartingOffset!=NULL)
{
StackPtr->Parameters.Write.ByteOffset.LowPart =
StartingOffset->LowPart;
StackPtr->Parameters.Write.ByteOffset.HighPart =
StartingOffset->HighPart;
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
}
else
{
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
}
}
@ -282,34 +279,29 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
StackPtr->Parameters.Write.Length = Length;
if (MajorFunction == IRP_MJ_READ)
{
if (StartingOffset!=NULL)
if (StartingOffset != NULL)
{
StackPtr->Parameters.Read.ByteOffset.LowPart =
StartingOffset->LowPart;
StackPtr->Parameters.Read.ByteOffset.HighPart =
StartingOffset->HighPart;
StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
}
else
{
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
}
}
else
{
if (StartingOffset!=NULL)
{
StackPtr->Parameters.Write.ByteOffset.LowPart =
StartingOffset->LowPart;
StackPtr->Parameters.Write.ByteOffset.HighPart =
StartingOffset->HighPart;
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
}
else
{
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
}
}
return(Irp);
}

View file

@ -52,8 +52,9 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
}
if (FileObject != NULL)
{
FileObject->CurrentByteOffset.LowPart =
FileObject->CurrentByteOffset.LowPart + Irp->IoStatus.Information;
SET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset,
GET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset) +
Irp->IoStatus.Information);
}
}

View file

@ -93,13 +93,12 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
StackPtr->Parameters.Read.Length = Length;
if (ByteOffset!=NULL)
{
StackPtr->Parameters.Read.ByteOffset.LowPart = ByteOffset->LowPart;
StackPtr->Parameters.Read.ByteOffset.HighPart = ByteOffset->HighPart;
StackPtr->Parameters.Read.ByteOffset = *ByteOffset;
}
else
{
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
}
if (Key!=NULL)
{

View file

@ -127,10 +127,10 @@ asmlinkage void _main(boot_param* _bp)
/*
* Initalize the console (before printing anything)
*/
HalInitConsole(&bp);
HalInitConsole(&_bp);
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
if (start < ((int)&end))
{

View file

@ -65,11 +65,11 @@ static unsigned int loops_per_microsecond = 100;
/* FUNCTIONS **************************************************************/
void KeCalibrateTimerLoop()
VOID KeCalibrateTimerLoop(VOID)
{
unsigned int start_tick;
unsigned int end_tick;
unsigned int nr_ticks;
// unsigned int end_tick;
// unsigned int nr_ticks;
unsigned int i;
unsigned int microseconds;
@ -146,10 +146,16 @@ NTSTATUS STDCALL ZwQueryPerformanceCounter(IN PLARGE_INTEGER Counter,
}
NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
NTSTATUS
KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
{
KeInitializeTimer(&(Thread->TimerBlock));
KeSetTimer(&(Thread->TimerBlock),*Interval,NULL);
assert(Thread != NULL);
assert(Interval != NULL);
KeInitializeTimer(&(Thread->TimerBlock));
KeSetTimer(&(Thread->TimerBlock),*Interval,NULL);
return STATUS_SUCCESS;
}
@ -193,6 +199,7 @@ VOID KeStallExecutionProcessor(ULONG MicroSeconds)
}
}
#if 0
static inline void ULLToLargeInteger(unsigned long long src,
PLARGE_INTEGER dest)
{
@ -233,6 +240,8 @@ static inline signed long long LargeIntegerToSLL(PLARGE_INTEGER src)
return(r);
}
#endif
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
/*
@ -244,10 +253,12 @@ LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
* NOTE: Returns the system tick count or the time-stamp on the pentium
*/
{
PerformanceFreq->HighPart=0;
PerformanceFreq->LowPart=0;
if (PerformanceFreq != NULL)
{
LARGE_INTEGER_QUAD_PART(*PerformanceFreq) = 0;
}
return *PerformanceFreq;
return *PerformanceFreq;
}
ULONG KeQueryTimeIncrement(VOID)
@ -269,7 +280,7 @@ VOID KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
* 1st of January, 1601.
*/
{
ULLToLargeInteger(system_time,CurrentTime);
LARGE_INTEGER_QUAD_PART(*CurrentTime) = system_time;
}
NTSTATUS STDCALL NtGetTickCount(PULONG UpTime)
@ -407,7 +418,7 @@ VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
* TickCount (OUT) = Points to storage for the number of ticks
*/
{
ULLToLargeInteger(ticks,TickCount);
LARGE_INTEGER_QUAD_PART(*TickCount) = ticks;
}
static void HandleExpiredTimer(PKTIMER current)
@ -464,7 +475,7 @@ extern unsigned int nr_used_blocks;
extern unsigned int EiFreeNonPagedPool;
extern unsigned int EiUsedNonPagedPool;
VOID KiTimerInterrupt(VOID)
BOOLEAN KiTimerInterrupt(VOID)
/*
* FUNCTION: Handles a timer interrupt
*/
@ -506,8 +517,8 @@ VOID KiTimerInterrupt(VOID)
*vidmem=0x7;
vidmem++;
}
return(TRUE);
return TRUE;
}

View file

@ -3,11 +3,14 @@
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/loader.c
* PURPOSE: Loaders for PE executables
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
* UPDATE HISTORY:
* DW 22/05/98 Created
* RJJ 10/12/98 Completed loader function and added hooks for MZ/PE
* RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE
* RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF
* RJJ 10/12/98 Rolled in David's code to load COFF drivers
* JM 14/12/98 Built initail PE user module loader
*/
/* INCLUDES *****************************************************************/
@ -16,24 +19,29 @@
#include <internal/kernel.h>
#include <internal/linkage.h>
#include <internal/module.h>
#include <internal/ob.h>
#include <internal/string.h>
#include <internal/symbol.h>
#include <ddk/ntddk.h>
#include <ddk/li.h>
//#define NDEBUG
#include <internal/debug.h>
#include "pe.h"
/* MACROS ********************************************************************/
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
/* GLOBALS *******************************************************************/
POBJECT_TYPE ObModuleType = NULL;
/* FORWARD DECLARATIONS ******************************************************/
NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
/* COFF Driver load support **************************************************/
/* COFF Driver load support */
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
@ -42,8 +50,37 @@ static unsigned int LdrCOFFGetSymbolValue(module *Module, unsigned int Idx);
static unsigned int LdrCOFFGetKernelSymbolAddr(char *Name);
static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName, unsigned int Idx);
/* Image loader forward delcarations */
static NTSTATUS LdrProcessMZImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
static NTSTATUS LdrProcessPEImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
static NTSTATUS LdrProcessBinImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
/* FUNCTIONS *****************************************************************/
VOID LdrInitModuleManagment(VOID)
{
ANSI_STRING AnsiString;
/* Register the process object type */
ObModuleType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
ObModuleType->TotalObjects = 0;
ObModuleType->TotalHandles = 0;
ObModuleType->MaxObjects = ULONG_MAX;
ObModuleType->MaxHandles = ULONG_MAX;
ObModuleType->PagedPoolCharge = 0;
ObModuleType->NonpagedPoolCharge = sizeof(MODULE);
ObModuleType->Dump = NULL;
ObModuleType->Open = NULL;
ObModuleType->Close = NULL;
ObModuleType->Delete = NULL;
ObModuleType->Parse = NULL;
ObModuleType->Security = NULL;
ObModuleType->QueryName = NULL;
ObModuleType->OkayToClose = NULL;
RtlInitAnsiString(&AnsiString, "Module");
RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE);
}
/*
* FUNCTION: Loads a kernel driver
* ARGUMENTS:
@ -62,6 +99,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
PIMAGE_DOS_HEADER PEDosHeader;
FILE_STANDARD_INFORMATION FileStdInfo;
DbgPrint("Loading Driver %W...\n", Filename);
/* Open the Driver */
InitializeObjectAttributes(&FileObjectAttributes,
Filename,
@ -155,11 +194,15 @@ LdrLoadDriver(PUNICODE_STRING Filename)
NTSTATUS
LdrPEProcessDriver(PVOID ModuleLoadBase)
{
PULONG NTMagic;
unsigned int DriverSize;
PVOID DriverBase, CodeBase, InitializedDataBase, UninitializedDataBase;
PULONG PEMagic;
PIMAGE_DOS_HEADER PEDosHeader;
PIMAGE_FILE_HEADER PEFileHeader;
PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
DbgPrint("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
/* Get header pointers */
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
PEMagic = (PULONG) ((unsigned int) ModuleLoadBase +
@ -168,18 +211,76 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
PEDosHeader->e_lfanew + sizeof(ULONG));
PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) ModuleLoadBase +
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
CHECKPOINT;
/* Check file magic numbers */
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
PEDosHeader->e_lfanew == 0 ||
*PEMagic != IMAGE_NT_MAGIC ||
*PEMagic != IMAGE_PE_MAGIC ||
PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
{
return STATUS_UNSUCCESSFUL;
}
CHECKPOINT;
#if 0
/* FIXME: if image is fixed-address load, then fail */
/* FIXME: check/verify OS version number */
DbgPrint("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
PEOptionalHeader->Magic,
PEOptionalHeader->MajorLinkerVersion,
PEOptionalHeader->MinorLinkerVersion);
DbgPrint("Size: CODE:%08lx(%d) DATA:%08lx(%d) BSS:%08lx(%d)\n",
PEOptionalHeader->SizeOfCode,
PEOptionalHeader->SizeOfCode,
PEOptionalHeader->SizeOfInitializedData,
PEOptionalHeader->SizeOfInitializedData,
PEOptionalHeader->SizeOfUninitializedData,
PEOptionalHeader->SizeOfUninitializedData);
DbgPrint("Entry Point:%08lx\n", PEOptionalHeader->AddressOfEntryPoint);
CHECKPOINT;
/* Determine the size of the module */
DriverSize = ROUND_UP(PEOptionalHeader->SizeOfCode,
PEOptionalHeader->SectionAlignment) +
ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
PEOptionalHeader->SectionAlignment) +
ROUND_UP(PEOptionalHeader->SizeOfUninitializedData,
PEOptionalHeader->SectionAlignment);
CHECKPOINT;
/* Allocate a virtual section for the module */
DriverBase = MmAllocateSection(DriverSize);
if (DriverBase == 0)
{
DbgPrint("Failed to allocate a virtual section for driver\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
CHECKPOINT;
/* Compute addresses for driver sections */
CodeBase = DriverBase;
InitializedDataBase = (PUCHAR) DriverBase +
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfCode,
PEOptionalHeader->SectionAlignment);
UninitializedDataBase = (PUCHAR) InitializedDataBase +
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
PEOptionalHeader->SectionAlignment);
/* FIXME: Copy code section into virtual section */
memcpy(CodeBase,
(PVOID)(ModuleLoadBase + ???),
ROUND_UP(PEOptionalHeader->SizeOfCode,
PEOptionalHeader->FileAlignment));
#endif
/* FIXME: Copy initialized data section into virtual section */
/* FIXME: Perform relocations fixups */
/* FIXME: compute address of entry point */
/* return InitializeLoadedDriver(EntryPoint); */
return STATUS_NOT_IMPLEMENTED;
}
@ -568,59 +669,91 @@ LdrCOFFGetSymbolValueByName(module *Module,
return 0L;
}
static NTSTATUS
LdrProcessMZImage(HANDLE ProcessHandle,
HANDLE FileHandle,
PIMAGE_DOS_HEADER DosHeader)
NTSTATUS LdrLoadLibrary(HANDLE ProcessHandle,
PHANDLE ModuleHandle,
PCHAR Name)
{
#if 0
NTSTATUS Status;
ANSI_STRING afilename;
UNICODE_STRING ufilename,umodName;
PMODULE *Library, *Module;
OBJECT_ATTRIBUTES attr;
PWSTR Ignored;
char name2[512];
/* FIXME: map VDM into low memory */
/* FIXME: Build/Load image sections */
return STATUS_NOT_IMPLEMENTED;
/* FIXME: this is broke */
/* FIXME: check for module already loaded */
/* FIXME: otherwise load module */
/* FIXME: we need to fix how modules are loaded so that they can
be shared... :( */
/* If module is already loaded, get a reference and return it */
strcpy(name2, "\\modules\\");
strcat(name2, Name);
RtlInitAnsiString(&afilename, name2);
RtlAnsiStringToUnicodeString(&umodName, &afilename, TRUE);
InitializeObjectAttributes(&attr, &umodName, 0, NULL, NULL);
Status = ObOpenObjectByName(&attr, (PVOID *) &Library, &Ignored);
DPRINT("LoadLibrary : Status=%x,pLibrary=%x\n",Status, Library);
if (!NT_SUCCESS(Status) || Library == NULL)
{
strcpy(name2, "\\??\\C:\\reactos\\system\\");
strcat(name2, name);
RtlInitAnsiString(&afilename, name2);
RtlAnsiStringToUnicodeString(&ufilename, &afilename, TRUE);
DPRINT("LoadLibrary,load %s\n", name2);
Library = LdrLoadImage(&ufilename);
/* FIXME: execute start code ? */
Module = ObGenericCreateObject(NULL, PROCESS_ALL_ACCESS, &attr, ObModuleType);
if (Module)
{
memcpy(Module, Library, PMODULE);
}
else
{
DbgPrint("library object not created\n");
}
RtlFreeUnicodeString(&ufilename);
Status = ObOpenObjectByName(&attr, (PVOID *)&Library, &Ignored);
}
else
{
DbgPrint("Library already loaded\n");
*Module = Library
}
RtlFreeUnicodeString(&umodName);
return STATUS_SUCCESS;
#endif
UNIMPLEMENTED;
}
static NTSTATUS
LdrProcessPEImage(HANDLE ProcessHandle,
HANDLE FileHandle,
PIMAGE_DOS_HEADER DosHeader)
{
// PIMAGE_NT_HEADERS PEHeader;
// PIMAGE_SECTION_HEADER Sections;
// FIXME: Check architechture
// FIXME: Build/Load image sections
// FIXME: do relocations code sections
// FIXME: resolve imports
// FIXME: do fixups
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Loads a PE executable into the specified process
/* LdrLoadImage
* FUNCTION:
* Loads a module into the specified process
* ARGUMENTS:
* Filename = File to load
* ProcessHandle = handle
* RETURNS: Status
* HANDLE ProcessHandle handle of the process to load the module into
* PHANDLE ModuleHandle handle of the loaded module
* PUNICODE_STRING Filename name of the module to load
* RETURNS:
* NTSTATUS
*/
NTSTATUS
LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
LdrLoadImage(HANDLE ProcessHandle,
PHANDLE ModuleHandle,
PUNICODE_STRING Filename)
{
char BlockBuffer[512];
#if 0
char BlockBuffer[1024];
NTSTATUS Status;
ULONG SectionSize;
HANDLE FileHandle;
HANDLE ThreadHandle;
OBJECT_ATTRIBUTES FileObjectAttributes;
HANDLE FileHandle;
PMODULE Module;
PIMAGE_DOS_HEADER PEDosHeader;
CONTEXT Context;
HANDLE SectionHandle;
PVOID BaseAddress;
/* FIXME: should DLLs be named sections? */
@ -636,135 +769,490 @@ LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
return Status;
}
/* Read first block of image to determine type */
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 512, 0, 0);
if (!NT_SUCCESS(Status))
/* Build a module structure for the image */
Module = ObGenericCreateObject(ModuleHandle,
PROCESS_ALL_ACCESS,
NULL,
ObModuleType);
if (Module == NULL)
{
ZwClose(FileHandle);
return Status;
}
/* Read first block of image to determine type */
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(*ModuleHandle);
*ModuleHandle = NULL;
ZwClose(FileHandle);
return Status;
}
/* If MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
if (PEDosHeader->e_magic == 0x54AD && PEDosHeader->e_lfanew != 0L)
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC &&
PEDosHeader->e_lfanew != 0L &&
*(PULONG)((PUCHAR)BlockBuffer + PEDosHeader->e_lfanew) == IMAGE_PE_MAGIC)
{
Status = LdrProcessPEImage(ProcessHandle,
FileHandle,
PEDosHeader);
if (!NT_SUCCESS(Status))
{
return Status;
}
ModuleHandle,
FileHandle);
}
else if (PEDosHeader->e_magic == 0x54AD)
{
Status = LdrProcessMZImage(ProcessHandle,
FileHandle,
PEDosHeader);
if (!NT_SUCCESS(Status))
{
return Status;
}
ModuleHandle,
FileHandle);
}
else /* Assume bin format and load */
{
FILE_STANDARD_INFORMATION FileStdInfo;
/* Get the size of the file for the section */
Status = ZwQueryInformationFile(FileHandle,
NULL,
&FileStdInfo,
sizeof(FileStdInfo),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
return Status;
}
/* Create the section for the code */
Status = ZwCreateSection(&SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
ZwClose(FileHandle);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Map a view of the section into the desired process */
BaseAddress = (PVOID)0x10000;
SectionSize = GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize);
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
&BaseAddress,
0,
SectionSize,
NULL,
&SectionSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* FIXME: destroy the section here */
return Status;
}
/* Setup the context for the initial thread */
memset(&Context,0,sizeof(CONTEXT));
Context.SegSs = USER_DS;
Context.Esp = 0x2000;
Context.EFlags = 0x202;
Context.SegCs = USER_CS;
Context.Eip = 0x10000;
Context.SegDs = USER_DS;
Context.SegEs = USER_DS;
Context.SegFs = USER_DS;
Context.SegGs = USER_DS;
/* Create the stack for the process */
BaseAddress = (PVOID) 0x1000;
SectionSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&BaseAddress,
0,
&SectionSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
/* Create the initial thread */
Status = ZwCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
ProcessHandle,
NULL,
&Context,
NULL,
FALSE);
if (!NT_SUCCESS(Status))
{
/* FIXME: destroy the stack memory block here */
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
Status = LdrProcessBinImage(ProcessHandle,
ModuleHandle,
FileHandle);
}
/* FIXME: {else} could check for a.out, ELF, COFF, etc. images here... */
/* FIXME: should we unconditionally dereference the module handle here? */
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(*ModuleHandle);
*ModuleHandle = NULL;
}
ZwClose(FileHandle);
return Status;
#endif
UNIMPLEMENTED;
}
#if 0
static NTSTATUS
LdrProcessMZImage(HANDLE ProcessHandle,
HANDLE ModuleHandle,
HANDLE FileHandle)
{
/* FIXME: map VDM into low memory */
/* FIXME: Build/Load image sections */
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS
LdrProcessPEImage(HANDLE ProcessHandle,
HANDLE ModuleHandle,
HANDLE FileHandle)
{
int i;
NTSTATUS Status;
PVOID BaseSection;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
PMODULE Module;
LARGE_INTEGER SectionOffset;
/* Allocate memory for headers */
Module = HEADER_TO_BODY(ModuleHandle);
if (Module == NULL)
{
return STATUS_UNSUCCESSFUL;
}
DosHeader = (PIMAGE_DOS_HEADER)ExAllocatePool(NonPagedPool,
sizeof(IMAGE_DOS_HEADER) +
sizeof(IMAGE_NT_HEADERS));
if (DosHeader == NULL)
{
return STATUS_UNSUCCESSFUL;
}
NTHeaders = (PIMAGE_NT_HEADERS)((PUCHAR) DosHeader + sizeof(IMAGE_DOS_HEADER));
/* Read the headers into memory */
memset(Module, '\0', sizeof(PMODULE));
Status = ZwReadFile(FileHandle,
NULL, NULL, NULL, NULL,
DosHeader,
sizeof(IMAGE_DOS_HEADER),
0, 0);
if (!NT_SUCCESS(Status))
{
ExFreePool(DosHeader);
return Status;
}
SET_LARGE_INTEGER_HIGH_PART(SectionOffset, 0);
SET_LARGE_INTEGER_LOW_PART(SectionOffset, DosHeader->e_lfanew);
Status = ZwReadFile(FileHandle,
NULL, NULL, NULL, NULL,
NTHeaders,
sizeof(IMAGE_NT_HEADERS),
&SectionOffset,
0);
if (!NT_SUCCESS(Status))
{
ExFreePool(DosHeader);
return Status;
}
/* Allocate memory in process for image */
Module->Flags = MODULE_FLAG_PE;
Module->Base = (PVOID) NTHeaders->OptionalHeader.ImageBase;
Module->Size = NTHeaders->OptionalHeader.SizeOfImage;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&Module->Base,
0,
NULL,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
ExFreePool(DosHeader);
return Status;
}
/* Load headers into virtual memory */
Status = ZwReadFile(FileHandle,
NULL, NULL, NULL, NULL,
Module->Base,
NTHeaders->OptionalHeader.SizeOfHeaders,
0, 0);
if (!NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(ProcessHandle,
Module->Base,
0,
MEM_RELEASE);
ExFreePool(DosHeader);
return Status;
}
/* Adjust module pointers into virtual memory */
DosHeader = (PIMAGE_DOS_HEADER) Module->Base;
NTHeaders = (PIMAGE_NT_HEADERS) ((PUCHAR)Module->Base +
DosHeader->e_lfanew);
Module->Image.PE.FileHeader = (PIMAGE_FILE_HEADER) ((PUCHAR)NTHeaders +
sizeof(DWORD));
Module->Image.PE.OptionalHeader = (PIMAGE_OPTIONAL_HEADER)
((PUCHAR)Module->Image.PE.FileHeader + sizeof(IMAGE_FILE_HEADER));
Module->Image.PE.SectionList = (PCOFF_SECTION_HEADER) ((PUCHAR)NTHeaders +
sizeof(IMAGE_NT_HEADERS));
/* Build Image Sections */
/* FIXME: should probably use image directory to load sections. */
for (i = 0; i < Module->Image.PE.FileHeader->NumberOfSections; i++)
{
DPRINT("section %d\n", i);
BaseSection = (PVOID)((PCHAR) Module->Base +
Module->Image.PE.SectionList[i].s_vaddr);
/* Load code and initialized data sections from disk */
if ((Module->Image.PE.SectionList[i].s_flags & STYP_TEXT) ||
(Module->Image.PE.SectionList[i].s_flags & STYP_DATA))
{
SET_LARGE_INTEGER_HIGH_PART(SectionOffset, 0);
SET_LARGE_INTEGER_LOW_PART(SectionOffset,
Module->Image.PE.SectionList[i].s_scnptr);
/* FIXME: should probably map sections into sections */
Status = ZwReadFile(FileHandle,
NULL, NULL, NULL, NULL,
Module->Base + Module->Image.PE.SectionList[i].s_vaddr,
min(Module->Image.PE.SectionList[i].s_size,
Module->Image.PE.SectionList[i].s_paddr),
&SectionOffset, 0);
if (!NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(ProcessHandle,
Module->Base,
0,
MEM_RELEASE);
ExFreePool(DosHeader);
return Status;
}
}
else if (Module->Image.PE.SectionList[i].s_flags & STYP_BSS)
{
memset((PVOID)(Module->Base +
Module->Image.PE.SectionList[i].s_vaddr),
0,
Module->Image.PE.SectionList[i].s_size);
}
}
/* Resolve Import Library references */
if (Module->Image.PE.OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
{
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
((PUCHAR)Module->Base + Module->Image.PE.OptionalHeader->
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (ImportModuleDirectory->dwRVAModuleName)
{
PMODULE Library;
PVOID *LibraryExports;
PVOID *ImportAddressList; // was pImpAddr
PULONG FunctionNameList;
DWORD pName;
PWORD pHint;
/* Load the library module into the process */
/* FIXME: this should take a UNICODE string */
Status = LdrLoadLibrary(ProcessHandle,
&Library,
(PCHAR)(Module->Base +
ImportModuleDirectory->dwRVAModuleName));
if (!NT_SUCCESS(Status))
{
/* FIXME: Dereference all loaded modules */
ZwFreeVirtualMemory(ProcessHandle,
Module->Base,
0,
MEM_RELEASE);
ExFreePool(DosHeader);
return Status;
}
/* Get the address of the export list for the library */
LibraryExports = (PVOID *)(Library->Base +
Library->Image.PE.OptionalHeader->
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress +
sizeof(IMAGE_EXPORT_DIRECTORY));
/* Get the import address list */
ImportAddressList = (PVOID *)
((PCHAR)Module->Image.PE.OptionalHeader->ImageBase +
ImportModuleDirectory->dwRVAFunctionAddressList);
/* Get the list of functions to import */
if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
{
FunctionNameList = (PULONG) ((PCHAR)Module->Base +
ImportModuleDirectory->dwRVAFunctionNameList);
}
else
{
FunctionNameList = (PULONG) ((PCHAR)Module->Base +
ImportModuleDirectory->dwRVAFunctionAddressList);
}
/* Walk through function list and fixup addresses */
while(*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000) // hint
{
*ImportAddressList = LibraryExports[(*FunctionNameList) & 0x7fffffff];
}
else // hint-name
{
pName = (DWORD)((PCHAR)Module->Base + *FunctionNameList + 2);
pHint = (PWORD)((PCHAR)Module->Base + *FunctionNameList);
/* FIXME: verify name */
*ImportAddressList = LibraryExports[*pHint];
}
/* FIXME: verify value of hint */
ImportAddressList++;
FunctionNameList++;
}
ImportModuleDirectory++;
}
}
/* Do fixups */
if (Module->Base != (PVOID)Module->Image.PE.OptionalHeader->ImageBase)
{
USHORT NumberOfEntries;
PUSHORT pValue16;
ULONG RelocationRVA;
ULONG Delta32, Offset;
PULONG pValue32;
PRELOCATION_DIRECTORY RelocationDir;
PRELOCATION_ENTRY RelocationBlock;
RelocationRVA = NTHeaders->OptionalHeader.DataDirectory[
IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
if (RelocationRVA)
{
RelocationDir = (PRELOCATION_DIRECTORY)
((PCHAR)Module->Base + RelocationRVA);
while (RelocationDir->SizeOfBlock)
{
Delta32 = (unsigned long)(Module->Base - NTHeaders->OptionalHeader.ImageBase);
RelocationBlock = (PRELOCATION_ENTRY)
(RelocationRVA + Module->Base + sizeof(RELOCATION_DIRECTORY));
NumberOfEntries =
(RelocationDir->SizeOfBlock - sizeof(RELOCATION_DIRECTORY)) /
sizeof(RELOCATION_ENTRY);
for (i = 0; i < NumberOfEntries; i++)
{
Offset = (RelocationBlock[i].TypeOffset & 0xfff) + RelocationDir->VirtualAddress;
switch (RelocationBlock[i].TypeOffset >> 12)
{
case TYPE_RELOC_ABSOLUTE:
break;
case TYPE_RELOC_HIGH:
pValue16 = (PUSHORT) (Module->Base + Offset);
*pValue16 += Delta32 >> 16;
break;
case TYPE_RELOC_LOW:
pValue16 = (PUSHORT)(Module->Base + Offset);
*pValue16 += Delta32 & 0xffff;
break;
case TYPE_RELOC_HIGHLOW:
pValue32 = (PULONG) (Module->Base + Offset);
*pValue32 += Delta32;
break;
case TYPE_RELOC_HIGHADJ:
/* FIXME: do the highadjust fixup */
DbgPrint("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
// break;
default:
DbgPrint("unexpected fixup type\n");
/* FIXME: Dereference all loaded modules */
ZwFreeVirtualMemory(ProcessHandle,
Module->Base,
0,
MEM_RELEASE);
ExFreePool(DosHeader);
return STATUS_UNSUCCESSFUL;
}
}
RelocationRVA += RelocationDir->SizeOfBlock;
RelocationDir = (PRELOCATION_DIRECTORY)((PCHAR)Module->Base +
RelocationRVA);
}
}
}
/* FIXME: Create the stack for the process */
/* FIXME: Setup the context for the initial thread */
/* FIXME: Create the initial thread */
// fail: ZwFreeVirtualMemory(ProcessHandle, Module->ImageBase, 0, MEM_RELEASE);
ExFreePool(DosHeader);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
LdrProcessBinImage(HANDLE ProcessHandle,
HANDLE ModuleHandle,
HANDLE FileHandle)
{
NTSTATUS Status;
FILE_STANDARD_INFORMATION FileStdInfo;
ULONG SectionSize;
HANDLE ThreadHandle;
CONTEXT Context;
HANDLE SectionHandle;
PVOID BaseAddress;
/* FIXME: should set module pointers */
/* Get the size of the file for the section */
Status = ZwQueryInformationFile(FileHandle,
NULL,
&FileStdInfo,
sizeof(FileStdInfo),
FileStandardInformation);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Create the section for the code */
Status = ZwCreateSection(&SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Map a view of the section into the desired process */
BaseAddress = (PVOID)0x10000;
SectionSize = GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize);
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
&BaseAddress,
0,
SectionSize,
NULL,
&SectionSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* FIXME: destroy the section here */
return Status;
}
/* Setup the context for the initial thread */
memset(&Context,0,sizeof(CONTEXT));
Context.SegSs = USER_DS;
Context.Esp = 0x2000;
Context.EFlags = 0x202;
Context.SegCs = USER_CS;
Context.Eip = 0x10000;
Context.SegDs = USER_DS;
Context.SegEs = USER_DS;
Context.SegFs = USER_DS;
Context.SegGs = USER_DS;
/* Create the stack for the process */
BaseAddress = (PVOID) 0x1000;
SectionSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&BaseAddress,
0,
&SectionSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
/* Create the initial thread */
Status = ZwCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
ProcessHandle,
NULL,
&Context,
NULL,
FALSE);
if (!NT_SUCCESS(Status))
{
/* FIXME: destroy the stack memory block here */
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
return STATUS_SUCCESS;
}
#endif

View file

@ -89,6 +89,9 @@ objects/tst.o: $(TST_OBJECTS)
objects/dbg.o: $(DBG_OBJECTS)
$(LD) -r $(DBG_OBJECTS) -o objects/dbg.o
objects/ldr.o: $(LDR_OBJECTS)
$(LD) -r $(LDR_OBJECTS) -o objects/ldr.o
objects/nt.o: $(NT_OBJECTS)
$(LD) -r $(NT_OBJECTS) -o objects/nt.o
@ -98,8 +101,7 @@ objects/cc.o: $(CC_OBJECTS)
OBJECTS = objects/hal.o objects/ke.o objects/rtl.o objects/mm.o \
objects/io.o objects/ob.o objects/ps.o objects/ex.o \
objects/se.o objects/cm.o objects/tst.o objects/dbg.o\
objects/nt.o objects/cc.o
objects/nt.o objects/cc.o objects/ldr.o
utils/export/export$(EXE_POSTFIX): utils/export/export.c
$(NATIVE_CC) -g utils/export/export.c -o utils/export/export$(EXE_POSTFIX)

View file

@ -411,8 +411,9 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
{
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
{
free_page(MmGetPhysicalAddress(MemoryArea->BaseAddress+
(i*PAGESIZE)).LowPart,1);
free_page(GET_LARGE_INTEGER_LOW_PART(
MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE))),
1);
}
}

View file

@ -66,7 +66,7 @@ PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
{
DPRINT("Writing %x with physical address %x\n",
base+(i*PAGESIZE),mdl_pages[i]);
set_page(base+(i*PAGESIZE),PA_READ + PA_SYSTEM,mdl_pages[i]);
set_page((DWORD)base+(i*PAGESIZE),PA_READ + PA_SYSTEM,mdl_pages[i]);
}
DPRINT("base %x\n",base);
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
@ -143,7 +143,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
{
Address = Mdl->StartVa + (i*PAGESIZE);
mdl_pages[i]=MmGetPhysicalAddress(Address).LowPart;
mdl_pages[i] = GET_LARGE_INTEGER_LOW_PART(MmGetPhysicalAddress(Address));
DPRINT("mdl_pages[i] %x\n",mdl_pages[i]);
}
}
@ -220,8 +220,8 @@ VOID MmBuildMdlForNonPagedPool(PMDL Mdl)
Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
for (va=0; va<Mdl->Size; va++)
{
((PULONG)(Mdl + 1))[va] = MmGetPhysicalAddress(
Mdl->StartVa+ (va * PAGESIZE)).LowPart;
((PULONG)(Mdl + 1))[va] = GET_LARGE_INTEGER_LOW_PART(
MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE)));
}
Mdl->MappedSystemVa = Mdl->StartVa;
}

View file

@ -12,7 +12,7 @@
#include <ddk/ntddk.h>
#include <internal/pool.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/

View file

@ -117,8 +117,7 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle,
}
else
{
Section->MaximumSize.HighPart = 0;
Section->MaximumSize.LowPart = 0xffffffff;
LARGE_INTEGER_QUAD_PART(Section->MaximumSize) = 0xffffffff;
}
Section->SectionPageProtection = SectionPageProtection;
Status = ObReferenceObjectByHandle(FileHandle,
@ -258,9 +257,9 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
return(Status);
}
if ((*ViewSize) > Section->MaximumSize.LowPart)
if ((*ViewSize) > GET_LARGE_INTEGER_LOW_PART(Section->MaximumSize))
{
(*ViewSize) = Section->MaximumSize.LowPart;
(*ViewSize) = GET_LARGE_INTEGER_LOW_PART(Section->MaximumSize);
}
MmCreateMemoryArea(UserMode,
@ -271,7 +270,7 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
Protect,
&Result);
Result->Data.SectionData.Section = Section;
Result->Data.SectionData.ViewOffset = SectionOffset->LowPart;
Result->Data.SectionData.ViewOffset = GET_LARGE_INTEGER_LOW_PART(*SectionOffset);
DPRINT("*BaseAddress %x\n",*BaseAddress);
DPRINT("Result->Data.SectionData.Section->FileObject %x\n",

View file

@ -89,7 +89,9 @@ PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress,
}
for (i=0;i<=(NumberOfBytes/PAGESIZE);i++)
{
set_page(Result+(i*PAGESIZE),Attributes,PhysicalAddress.LowPart);
set_page(Result + (i * PAGESIZE),
Attributes,
GET_LARGE_INTEGER_LOW_PART(PhysicalAddress));
}
return((PVOID)Result);
}

View file

@ -107,9 +107,9 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
MemoryArea,Address);
set_page(Address,0x7,get_free_page());
set_page((DWORD)Address,0x7,get_free_page());
Offset.LowPart = (Address - MemoryArea->BaseAddress) +
LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) +
MemoryArea->Data.SectionData.ViewOffset;
DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
@ -193,7 +193,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
break;
case MEMORY_AREA_SECTION_VIEW_COMMIT:
if (MmSectionHandleFault(MemoryArea,cr2)==STATUS_SUCCESS)
if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
{
stat=1;
}
@ -656,7 +656,7 @@ NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
{
CurrentEntry = MmGetPageEntry(Process, BaseAddress + (i*PAGESIZE));
CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
RtlCopyMemory(Buffer + (i*PAGESIZE),
(PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
PAGESIZE);
@ -735,7 +735,7 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)
{
CurrentEntry = MmGetPageEntry(Process, BaseAddress + (i*PAGESIZE));
CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
Buffer + (i*PAGESIZE),
PAGESIZE);

View file

@ -162,7 +162,7 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
}
ObLookupObject(ObjectAttributes->RootDirectory,path,
&hdr->Parent,&Ignored);
&hdr->Parent,&Ignored, 0L);
/*
* Initialize the object header

View file

@ -15,7 +15,7 @@
#include <internal/mm.h>
#include <internal/string.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/

View file

@ -131,7 +131,7 @@ VOID PsDispatchThread(VOID)
{
DPRINT("Scheduling current thread\n");
KeQueryTickCount(&TickCount);
CurrentThread->Tcb.LastTick = TickCount.LowPart;
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
KeReleaseSpinLock(&ThreadListLock,irql);
KeLowerIrql(PASSIVE_LEVEL);
@ -144,7 +144,7 @@ VOID PsDispatchThread(VOID)
Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
KeQueryTickCount(&TickCount);
CurrentThread->Tcb.LastTick = TickCount.LowPart;
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
CurrentThread = Candidate;

View file

@ -19,6 +19,8 @@
#include <internal/ctype.h>
#include <internal/string.h>
#include <ddk/ntddk.h>
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
unsigned long result = 0,value;
@ -117,13 +119,14 @@ static char * number(char * str, long num, int base, int size, int precision
*str++ = ' ';
if (sign)
*str++ = sign;
if (type & SPECIAL)
if (base==8)
if (type & SPECIAL) {
if (base==8) {
*str++ = '0';
else if (base==16) {
} else if (base==16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
@ -143,7 +146,8 @@ int vsprintf(char *buf, const char *fmt, va_list args)
int i, base;
char * str;
const char *s;
const short int* sw;
const short int *sw;
PUNICODE_STRING pus;
int flags; /* flags to number() */
@ -243,6 +247,25 @@ int vsprintf(char *buf, const char *fmt, va_list args)
// CHECKPOINT;
continue;
case 'W':
pus = va_arg(args, PUNICODE_STRING);
if (pus == NULL || pus->Length > pus->MaximumLength)
{
s = "<NULL>";
while ((*s) != 0)
{
*str++ = *s++;
}
}
else
{
for (i = 0; i < pus->Length; i++)
{
*str++ = (char)(pus->Buffer[i]);
}
}
continue;
case 's':
s = va_arg(args, char *);
if (!s)
@ -310,17 +333,19 @@ int vsprintf(char *buf, const char *fmt, va_list args)
--fmt;
continue;
}
if (qualifier == 'l')
if (qualifier == 'l') {
num = va_arg(args, unsigned long);
else if (qualifier == 'h')
if (flags & SIGN)
} else if (qualifier == 'h') {
if (flags & SIGN) {
num = va_arg(args, short);
else
} else {
num = va_arg(args, unsigned short);
else if (flags & SIGN)
}
} else if (flags & SIGN) {
num = va_arg(args, int);
else
} else {
num = va_arg(args, unsigned int);
}
str = number(str, num, base, field_width, precision, flags);
}
*str = '\0';

View file

@ -16,7 +16,7 @@
#include <internal/string.h>
#include <internal/ctype.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
int ShellChangeDir(char* args);

View file

@ -18,7 +18,7 @@
#include <internal/i386/segment.h>
#include <internal/ps.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
#include <in.h>
@ -531,8 +531,24 @@ TstTimer(void)
}
#if 0
void TstDriverLoad(void)
{
NTSTATUS Status;
UNICODE_STRING DriverName;
INIT_UNICODE_STRING(DriverName, "C:\\reactos\\system\\keyboard.o");
Status = LdrLoadDriver(DriverName);
if (!NT_SUCCESS(Status))
{
DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
}
}
#endif
void TstBegin()
{
// TstDriverLoad();
ExExecuteShell();
// TstFileRead();
// TstGeneralWrite();

View file

@ -63,7 +63,7 @@ else
DEBUGGING_CFLAGS =
endif
DEFINES = -DDBG -DCHECKED
DEFINES = -DDBG -DCHECKED # -DCOMPILER_LARGE_INTEGERS
ifeq ($(WIN32_LEAN_AND_MEAN),yes)
LEAN_AND_MEAN_DEFINE = -DWIN32_LEAN_AND_MEAN