mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Various changes to support the executable/driver loader
svn path=/trunk/; revision=130
This commit is contained in:
parent
a9ce8c6379
commit
6cd2bc16b8
35 changed files with 1461 additions and 323 deletions
|
@ -93,3 +93,80 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
DPRINT("Block request succeeded\n");
|
DPRINT("Block request succeeded\n");
|
||||||
return TRUE;
|
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,
|
||||||
|
§orNumber,
|
||||||
|
&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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
28-10-1998 Reads entire FAT into memory
|
28-10-1998 Reads entire FAT into memory
|
||||||
VFatReadSector modified to read in more than one sector at a time
|
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
|
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 <ddk/ntddk.h>
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
#include <wstring.h>
|
#include <wstring.h>
|
||||||
|
#include <ddk/cctypes.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -28,6 +33,7 @@
|
||||||
|
|
||||||
#define FAT16 (1)
|
#define FAT16 (1)
|
||||||
#define FAT12 (2)
|
#define FAT12 (2)
|
||||||
|
#define FAT32 (3)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -53,6 +59,23 @@ static PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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 Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
{
|
{
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
|
@ -69,14 +92,10 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
Block = (PUSHORT)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
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;
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
|
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +115,7 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
CBlock = (unsigned char *)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
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)
|
||||||
{
|
{
|
||||||
Entry = CBlock[((FATOffset / 24)*3)];
|
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) + 1] >> 4);
|
||||||
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Entry %x\n",Entry);
|
DPRINT("Entry %x\n",Entry);
|
||||||
|
|
||||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
{
|
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
}
|
|
||||||
|
|
||||||
CurrentCluster = Entry;
|
CurrentCluster = Entry;
|
||||||
|
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT("Returning %x\n",CurrentCluster);
|
||||||
|
|
||||||
return(CurrentCluster);
|
return(CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,12 +144,170 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
{
|
{
|
||||||
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
}
|
}
|
||||||
|
else if (DeviceExt->FatType == FAT32)
|
||||||
|
{
|
||||||
|
return(Fat32GetNextCluster(DeviceExt, CurrentCluster));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
|
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 ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||||
unsigned long Cluster)
|
unsigned long Cluster)
|
||||||
{
|
{
|
||||||
|
@ -345,12 +514,11 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
WCHAR name[256];
|
WCHAR name[256];
|
||||||
ULONG StartingSector;
|
ULONG StartingSector;
|
||||||
ULONG NextCluster;
|
ULONG NextCluster;
|
||||||
|
|
||||||
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||||
|
|
||||||
if (Parent == NULL)
|
if (Parent == NULL)
|
||||||
{
|
{
|
||||||
Size = DeviceExt->rootDirectorySectors;
|
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||||
StartingSector = DeviceExt->rootStart;
|
StartingSector = DeviceExt->rootStart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -358,10 +526,12 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
|
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
|
||||||
|
|
||||||
Size = ULONG_MAX;
|
Size = ULONG_MAX;
|
||||||
StartingSector = ClusterToSector(DeviceExt, Parent->entry.FirstCluster);
|
if (DeviceExt->FatType == FAT32)
|
||||||
NextCluster = Parent->entry.FirstCluster;
|
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
|
||||||
|
else
|
||||||
|
NextCluster = Parent->entry.FirstCluster;
|
||||||
|
StartingSector = ClusterToSector(DeviceExt, NextCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||||
|
|
||||||
for (j=0; j<Size; j++)
|
for (j=0; j<Size; j++)
|
||||||
|
@ -381,12 +551,20 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
||||||
DPRINT("Comparing %w %w\n",name,FileToFind);
|
DPRINT("Comparing %w %w\n",name,FileToFind);
|
||||||
if (wstrcmpi(name,FileToFind))
|
if (wstrcmpi(name,FileToFind))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* In the case of a long filename, the firstcluster is stored in
|
/* In the case of a long filename, the firstcluster is stored in
|
||||||
the next record -- where it's short name is */
|
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++;
|
if(((FATDirEntry *)block)[i].FirstCluster==0) i++;
|
||||||
|
|
||||||
DPRINT("Found it at cluster %u\n", ((FATDirEntry *)block)[i].FirstCluster);
|
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],
|
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||||
sizeof(FATDirEntry));
|
sizeof(FATDirEntry));
|
||||||
|
@ -492,13 +670,14 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
BootSector* Boot;
|
BootSector* Boot;
|
||||||
|
|
||||||
Boot = ExAllocatePool(NonPagedPool,512);
|
Boot = ExAllocatePool(NonPagedPool,512);
|
||||||
|
|
||||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
|
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
|
||||||
|
|
||||||
if (strncmp(Boot->SysType,"FAT12",5)==0 ||
|
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);
|
ExFreePool(Boot);
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
|
@ -507,7 +686,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
PDEVICE_OBJECT DeviceToMount)
|
PDEVICE_OBJECT DeviceToMount)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Mounts the device
|
* FUNCTION: Mounts the device
|
||||||
|
@ -517,7 +696,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
DPRINT("Mounting VFAT device...");
|
DPRINT("Mounting VFAT device...");
|
||||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||||
|
|
||||||
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
|
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
|
||||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
|
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
|
||||||
|
|
||||||
|
@ -538,29 +717,57 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
{
|
{
|
||||||
DeviceExt->FatType = FAT12;
|
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
|
else
|
||||||
{
|
{
|
||||||
DeviceExt->FatType = FAT16;
|
DeviceExt->FatType = FAT16;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
// with FAT32 it's not a good idea to load always fat in memory
|
||||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
// 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)
|
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
{
|
{
|
||||||
ULONG Sector;
|
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",
|
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
// DeviceExt,Buffer,Cluster);
|
DeviceExt,Buffer,Cluster);
|
||||||
|
|
||||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
Sector = ClusterToSector(DeviceExt, Cluster);
|
||||||
|
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||||
Sector,
|
Sector,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster,
|
||||||
Buffer);
|
Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
@ -573,7 +780,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
ULONG FileOffset;
|
ULONG FileOffset;
|
||||||
ULONG FirstCluster;
|
ULONG FirstCluster;
|
||||||
PFCB Fcb;
|
PFCB Fcb;
|
||||||
PVOID Temp;
|
PVOID Temp;
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
|
|
||||||
|
@ -583,7 +790,10 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
||||||
Fcb = FileObject->FsContext;
|
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)
|
if (ReadOffset >= Fcb->entry.FileSize)
|
||||||
{
|
{
|
||||||
|
@ -627,7 +837,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool(Temp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,6 +856,97 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
return(STATUS_SUCCESS);
|
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)
|
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
|
@ -653,7 +954,7 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = FsdCloseFile(DeviceExtension,FileObject);
|
Status = FsdCloseFile(DeviceExtension,FileObject);
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
|
@ -685,11 +986,27 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
NTSTATUS FsdWrite(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;
|
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
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)
|
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
@ -746,10 +1063,10 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(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;
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("VFAT FSC\n");
|
DPRINT("VFAT FSC\n");
|
||||||
|
|
||||||
if (FsdHasFileSystem(DeviceToMount))
|
if (FsdHasFileSystem(DeviceToMount))
|
||||||
|
@ -762,7 +1079,7 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
}
|
}
|
||||||
DPRINT("VFAT File system successfully mounted\n");
|
DPRINT("VFAT File system successfully mounted\n");
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
@ -770,6 +1087,60 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return(Status);
|
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,
|
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
PUNICODE_STRING RegistryPath)
|
PUNICODE_STRING RegistryPath)
|
||||||
/*
|
/*
|
||||||
|
@ -785,7 +1156,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
UNICODE_STRING ustr;
|
UNICODE_STRING ustr;
|
||||||
ANSI_STRING astr;
|
ANSI_STRING astr;
|
||||||
|
|
||||||
DbgPrint("VFAT 0.0.3\n");
|
DbgPrint("VFAT 0.0.4\n");
|
||||||
|
|
||||||
DriverObject = _DriverObject;
|
DriverObject = _DriverObject;
|
||||||
|
|
||||||
|
@ -805,6 +1176,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
||||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
FsdFileSystemControl;
|
FsdFileSystemControl;
|
||||||
|
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||||
|
FsdQueryInformation;
|
||||||
DriverObject->DriverUnload = NULL;
|
DriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
IoRegisterFileSystem(DeviceObject);
|
IoRegisterFileSystem(DeviceObject);
|
||||||
|
|
|
@ -3,6 +3,11 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN UCHAR* Buffer);
|
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;
|
||||||
unsigned char OEMName[8];
|
unsigned char OEMName[8];
|
||||||
|
@ -20,10 +25,29 @@ struct _BootSector {
|
||||||
unsigned char Res2[450];
|
unsigned char Res2[450];
|
||||||
} __attribute__((packed));
|
} __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;
|
typedef struct _BootSector BootSector;
|
||||||
|
|
||||||
struct _FATDirEntry {
|
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 short FirstCluster;
|
||||||
unsigned long FileSize;
|
unsigned long FileSize;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
@ -46,3 +70,41 @@ struct _slot
|
||||||
typedef struct _slot slot;
|
typedef struct _slot slot;
|
||||||
|
|
||||||
#define BLOCKSIZE 512
|
#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;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
|
|
||||||
|
#ifndef __DDK_LI_H
|
||||||
|
#define __DDK_LI_H
|
||||||
|
|
||||||
|
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
|
||||||
|
|
||||||
#ifdef COMPILER_LARGE_INTEGERS
|
#ifdef COMPILER_LARGE_INTEGERS
|
||||||
|
|
||||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >> 32) )
|
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >> 32) )
|
||||||
|
@ -7,14 +12,19 @@
|
||||||
( LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
|
( LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
|
||||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
|
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
|
||||||
( LargeInteger |= Unsigned_Long )
|
( LargeInteger |= Unsigned_Long )
|
||||||
|
#define LARGE_INTEGER_QUAD_PART(LargeInteger) (LargeInteger)
|
||||||
|
|
||||||
#else
|
#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) \
|
#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) \
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern "C"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
|
#include <ddk/li.h>
|
||||||
|
|
||||||
#include <ddk/status.h>
|
#include <ddk/status.h>
|
||||||
#include <ddk/ntdef.h>
|
#include <ddk/ntdef.h>
|
||||||
|
|
|
@ -39,6 +39,11 @@ typedef struct _UNICODE_STRING
|
||||||
PWSTR Buffer;
|
PWSTR Buffer;
|
||||||
} UNICODE_STRING, *PUNICODE_STRING;
|
} 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 {
|
typedef enum _SECTION_INHERIT {
|
||||||
ViewShare = 1,
|
ViewShare = 1,
|
||||||
ViewUnmap = 2
|
ViewUnmap = 2
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
#define __MODULE_H
|
#define __MODULE_H
|
||||||
|
|
||||||
#include <coff.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 nsyms;
|
||||||
unsigned int text_base;
|
unsigned int text_base;
|
||||||
|
@ -29,6 +28,45 @@ typedef struct
|
||||||
unsigned int raw_data_off;
|
unsigned int raw_data_off;
|
||||||
} module;
|
} 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);
|
BOOLEAN process_boot_module(unsigned int start);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@ typedef DWORD *PDWORD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IMAGE_DOS_MAGIC 0x54ad
|
#define IMAGE_DOS_MAGIC 0x54ad
|
||||||
#define IMAGE_NT_MAGIC 0x00004550
|
#define IMAGE_PE_MAGIC 0x00004550
|
||||||
|
|
||||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||||
WORD e_magic; // Magic number
|
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
|
#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
|
||||||
// old checksum didn't match.
|
// old checksum didn't match.
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// End Image Format
|
// End Image Format
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
|
#define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
|
||||||
#define MAXRESOURCENAME 13
|
#define MAXRESOURCENAME 13
|
||||||
|
|
||||||
|
@ -646,13 +644,34 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
|
||||||
sizeof (IMAGE_FILE_HEADER) + \
|
sizeof (IMAGE_FILE_HEADER) + \
|
||||||
sizeof (IMAGE_OPTIONAL_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
|
typedef struct _RELOCATION_DIRECTORY
|
||||||
{
|
{
|
||||||
DWORD dwRVAFunctionNameList;
|
DWORD VirtualAddress; /* adresse virtuelle du bloc ou se font les relocations */
|
||||||
DWORD dwUseless1;
|
DWORD SizeOfBlock; // taille de cette structure + des structures
|
||||||
DWORD dwUseless2;
|
// relocation_entry qui suivent (ces dernieres sont
|
||||||
DWORD dwRVAModuleName;
|
// donc au nombre de (SizeOfBlock-8)/2
|
||||||
DWORD dwRVAFunctionAddressList;
|
} RELOCATION_DIRECTORY, *PRELOCATION_DIRECTORY;
|
||||||
}IMAGE_IMPORT_MODULE_DIRECTORY, * PIMAGE_IMPORT_MODULE_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
|
||||||
|
|
|
@ -32,11 +32,25 @@
|
||||||
#ifndef _GNU_H_WINDOWS32_STRUCTURES
|
#ifndef _GNU_H_WINDOWS32_STRUCTURES
|
||||||
#define _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 {
|
typedef struct _LARGE_INTEGER {
|
||||||
DWORD LowPart;
|
DWORD LowPart;
|
||||||
LONG HighPart;
|
LONG HighPart;
|
||||||
} LARGE_INTEGER, *PLARGE_INTEGER;
|
} LARGE_INTEGER, *PLARGE_INTEGER;
|
||||||
|
|
||||||
|
typedef struct _ULARGE_INTEGER {
|
||||||
|
DWORD LowPart;
|
||||||
|
DWORD HighPart;
|
||||||
|
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _LIST_ENTRY {
|
typedef struct _LIST_ENTRY {
|
||||||
struct _LIST_ENTRY *Flink;
|
struct _LIST_ENTRY *Flink;
|
||||||
struct _LIST_ENTRY *Blink;
|
struct _LIST_ENTRY *Blink;
|
||||||
|
@ -129,11 +143,6 @@ typedef struct _CRITICAL_SECTION {
|
||||||
DWORD Reserved;
|
DWORD Reserved;
|
||||||
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
|
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
|
||||||
|
|
||||||
typedef struct _ULARGE_INTEGER {
|
|
||||||
DWORD LowPart;
|
|
||||||
DWORD HighPart;
|
|
||||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
|
||||||
|
|
||||||
typedef struct _GENERIC_MAPPING {
|
typedef struct _GENERIC_MAPPING {
|
||||||
ACCESS_MASK GenericRead;
|
ACCESS_MASK GenericRead;
|
||||||
ACCESS_MASK GenericWrite;
|
ACCESS_MASK GenericWrite;
|
||||||
|
|
|
@ -390,6 +390,7 @@ rostitle db '',0
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
loading_msg db 'Loading: ',0
|
loading_msg db 'Loading: ',0
|
||||||
|
death_msg: db 'death', 0
|
||||||
|
|
||||||
filelength_lo dw 0
|
filelength_lo dw 0
|
||||||
filelength_hi dw 0
|
filelength_hi dw 0
|
||||||
|
|
|
@ -31,7 +31,7 @@ LOADERS = dos
|
||||||
# Select the device drivers and filesystems you want
|
# Select the device drivers and filesystems you want
|
||||||
#
|
#
|
||||||
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
|
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
|
||||||
minix vfat ext2fs
|
minix vfat # ext2fs
|
||||||
|
|
||||||
APPS = hello shell
|
APPS = hello shell
|
||||||
|
|
||||||
|
|
|
@ -165,8 +165,8 @@ static NTSTATUS CbReadBlock(PDCCB Dccb, PCCB Ccb)
|
||||||
Ccb->Buffer=ExAllocatePool(NonPagedPool,Dccb->SectorSize);
|
Ccb->Buffer=ExAllocatePool(NonPagedPool,Dccb->SectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
|
||||||
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
|
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
|
||||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||||
Dccb->DeviceObject,
|
Dccb->DeviceObject,
|
||||||
|
@ -206,8 +206,8 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
|
|
||||||
Offset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
|
||||||
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
|
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
|
||||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
||||||
Dccb->DeviceObject,
|
Dccb->DeviceObject,
|
||||||
|
@ -231,7 +231,7 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
|
||||||
|
|
||||||
PCCB CbFindModifiedCcb(PDCCB Dccb, PCCB Start)
|
PCCB CbFindModifiedCcb(PDCCB Dccb, PCCB Start)
|
||||||
{
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID CbDeleteAllCcbs(PDCCB Dccb)
|
static VOID CbDeleteAllCcbs(PDCCB Dccb)
|
||||||
|
|
|
@ -122,10 +122,14 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
|
||||||
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
|
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER timeout;
|
LARGE_INTEGER timeout;
|
||||||
timeout.HighPart = 0;
|
|
||||||
timeout.LowPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(timeout, 0);
|
||||||
KeWaitForSingleObject(&Resource->ExclusiveWaiters,Executive,KernelMode,
|
SET_LARGE_INTEGER_LOW_PART(timeout, 0);
|
||||||
FALSE,&timeout);
|
return KeWaitForSingleObject(&Resource->ExclusiveWaiters,
|
||||||
|
Executive,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
&timeout) == STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -201,11 +201,14 @@ PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
|
||||||
* FUNCTION: Returns the physical address corresponding to a virtual address
|
* FUNCTION: Returns the physical address corresponding to a virtual address
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS p;
|
PHYSICAL_ADDRESS p;
|
||||||
DPRINT("get_page_physical_address(vaddr %x)\n",vaddr);
|
|
||||||
p.HighPart = 0;
|
DPRINT("get_page_physical_address(vaddr %x)\n", vaddr);
|
||||||
p.LowPart = PAGE_MASK(*get_page_entry((unsigned int)vaddr));
|
SET_LARGE_INTEGER_HIGH_PART(p, 0);
|
||||||
return(p);
|
SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(
|
||||||
|
*get_page_entry((unsigned int) vaddr)));
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL is_page_present(unsigned int vaddr)
|
BOOL is_page_present(unsigned int vaddr)
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
#define SERIAL_PORT 0x03f8
|
#define SERIAL_PORT 0x03f8
|
||||||
#define SERIAL_BAUD_RATE 19200
|
#define SERIAL_BAUD_RATE 19200
|
||||||
#define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
|
#define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
|
||||||
//#define NDEBUG
|
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
|
@ -170,15 +170,12 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
||||||
}
|
}
|
||||||
if (StartingOffset!=NULL)
|
if (StartingOffset!=NULL)
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
|
||||||
StartingOffset->LowPart;
|
|
||||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
|
||||||
StartingOffset->HighPart;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,34 +279,29 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
|
||||||
StackPtr->Parameters.Write.Length = Length;
|
StackPtr->Parameters.Write.Length = Length;
|
||||||
if (MajorFunction == IRP_MJ_READ)
|
if (MajorFunction == IRP_MJ_READ)
|
||||||
{
|
{
|
||||||
if (StartingOffset!=NULL)
|
if (StartingOffset != NULL)
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Read.ByteOffset.LowPart =
|
StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
|
||||||
StartingOffset->LowPart;
|
|
||||||
StackPtr->Parameters.Read.ByteOffset.HighPart =
|
|
||||||
StartingOffset->HighPart;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
|
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||||
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (StartingOffset!=NULL)
|
if (StartingOffset!=NULL)
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
|
||||||
StartingOffset->LowPart;
|
|
||||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
|
||||||
StartingOffset->HighPart;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(Irp);
|
return(Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,9 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
if (FileObject != NULL)
|
if (FileObject != NULL)
|
||||||
{
|
{
|
||||||
FileObject->CurrentByteOffset.LowPart =
|
SET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset,
|
||||||
FileObject->CurrentByteOffset.LowPart + Irp->IoStatus.Information;
|
GET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset) +
|
||||||
|
Irp->IoStatus.Information);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,13 +93,12 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
||||||
StackPtr->Parameters.Read.Length = Length;
|
StackPtr->Parameters.Read.Length = Length;
|
||||||
if (ByteOffset!=NULL)
|
if (ByteOffset!=NULL)
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Read.ByteOffset.LowPart = ByteOffset->LowPart;
|
StackPtr->Parameters.Read.ByteOffset = *ByteOffset;
|
||||||
StackPtr->Parameters.Read.ByteOffset.HighPart = ByteOffset->HighPart;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
|
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||||
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
|
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||||
}
|
}
|
||||||
if (Key!=NULL)
|
if (Key!=NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,10 +127,10 @@ asmlinkage void _main(boot_param* _bp)
|
||||||
/*
|
/*
|
||||||
* Initalize the console (before printing anything)
|
* Initalize the console (before printing anything)
|
||||||
*/
|
*/
|
||||||
HalInitConsole(&bp);
|
HalInitConsole(&_bp);
|
||||||
|
|
||||||
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
|
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
|
||||||
|
|
||||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||||
if (start < ((int)&end))
|
if (start < ((int)&end))
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,11 +65,11 @@ static unsigned int loops_per_microsecond = 100;
|
||||||
|
|
||||||
/* FUNCTIONS **************************************************************/
|
/* FUNCTIONS **************************************************************/
|
||||||
|
|
||||||
void KeCalibrateTimerLoop()
|
VOID KeCalibrateTimerLoop(VOID)
|
||||||
{
|
{
|
||||||
unsigned int start_tick;
|
unsigned int start_tick;
|
||||||
unsigned int end_tick;
|
// unsigned int end_tick;
|
||||||
unsigned int nr_ticks;
|
// unsigned int nr_ticks;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int microseconds;
|
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));
|
assert(Thread != NULL);
|
||||||
KeSetTimer(&(Thread->TimerBlock),*Interval,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,
|
static inline void ULLToLargeInteger(unsigned long long src,
|
||||||
PLARGE_INTEGER dest)
|
PLARGE_INTEGER dest)
|
||||||
{
|
{
|
||||||
|
@ -233,6 +240,8 @@ static inline signed long long LargeIntegerToSLL(PLARGE_INTEGER src)
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
|
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
|
* NOTE: Returns the system tick count or the time-stamp on the pentium
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PerformanceFreq->HighPart=0;
|
if (PerformanceFreq != NULL)
|
||||||
PerformanceFreq->LowPart=0;
|
{
|
||||||
|
LARGE_INTEGER_QUAD_PART(*PerformanceFreq) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return *PerformanceFreq;
|
return *PerformanceFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG KeQueryTimeIncrement(VOID)
|
ULONG KeQueryTimeIncrement(VOID)
|
||||||
|
@ -269,7 +280,7 @@ VOID KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
|
||||||
* 1st of January, 1601.
|
* 1st of January, 1601.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULLToLargeInteger(system_time,CurrentTime);
|
LARGE_INTEGER_QUAD_PART(*CurrentTime) = system_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL NtGetTickCount(PULONG UpTime)
|
NTSTATUS STDCALL NtGetTickCount(PULONG UpTime)
|
||||||
|
@ -407,7 +418,7 @@ VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
|
||||||
* TickCount (OUT) = Points to storage for the number of ticks
|
* TickCount (OUT) = Points to storage for the number of ticks
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULLToLargeInteger(ticks,TickCount);
|
LARGE_INTEGER_QUAD_PART(*TickCount) = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleExpiredTimer(PKTIMER current)
|
static void HandleExpiredTimer(PKTIMER current)
|
||||||
|
@ -464,7 +475,7 @@ extern unsigned int nr_used_blocks;
|
||||||
extern unsigned int EiFreeNonPagedPool;
|
extern unsigned int EiFreeNonPagedPool;
|
||||||
extern unsigned int EiUsedNonPagedPool;
|
extern unsigned int EiUsedNonPagedPool;
|
||||||
|
|
||||||
VOID KiTimerInterrupt(VOID)
|
BOOLEAN KiTimerInterrupt(VOID)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Handles a timer interrupt
|
* FUNCTION: Handles a timer interrupt
|
||||||
*/
|
*/
|
||||||
|
@ -506,8 +517,8 @@ VOID KiTimerInterrupt(VOID)
|
||||||
*vidmem=0x7;
|
*vidmem=0x7;
|
||||||
vidmem++;
|
vidmem++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(TRUE);
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ldr/loader.c
|
* FILE: ntoskrnl/ldr/loader.c
|
||||||
* PURPOSE: Loaders for PE executables
|
* PURPOSE: Loaders for PE executables
|
||||||
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
|
* PROGRAMMERS: Jean Michault
|
||||||
|
* Rex Jolliff (rex@lvcablemodem.com)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* DW 22/05/98 Created
|
* 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
|
* RJJ 10/12/98 Rolled in David's code to load COFF drivers
|
||||||
|
* JM 14/12/98 Built initail PE user module loader
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -16,24 +19,29 @@
|
||||||
#include <internal/kernel.h>
|
#include <internal/kernel.h>
|
||||||
#include <internal/linkage.h>
|
#include <internal/linkage.h>
|
||||||
#include <internal/module.h>
|
#include <internal/module.h>
|
||||||
|
#include <internal/ob.h>
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
#include <internal/symbol.h>
|
#include <internal/symbol.h>
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <ddk/li.h>
|
|
||||||
|
|
||||||
//#define NDEBUG
|
//#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#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 ******************************************************/
|
/* FORWARD DECLARATIONS ******************************************************/
|
||||||
|
|
||||||
NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
|
NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
|
||||||
NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
|
NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
|
||||||
|
|
||||||
/* COFF Driver load support **************************************************/
|
/* COFF Driver load support */
|
||||||
|
|
||||||
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
|
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
|
||||||
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
||||||
static BOOLEAN LdrCOFFDoReloc32Reloc(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 LdrCOFFGetKernelSymbolAddr(char *Name);
|
||||||
static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName, unsigned int Idx);
|
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 *****************************************************************/
|
/* 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
|
* FUNCTION: Loads a kernel driver
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -62,6 +99,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||||
PIMAGE_DOS_HEADER PEDosHeader;
|
PIMAGE_DOS_HEADER PEDosHeader;
|
||||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||||
|
|
||||||
|
DbgPrint("Loading Driver %W...\n", Filename);
|
||||||
|
|
||||||
/* Open the Driver */
|
/* Open the Driver */
|
||||||
InitializeObjectAttributes(&FileObjectAttributes,
|
InitializeObjectAttributes(&FileObjectAttributes,
|
||||||
Filename,
|
Filename,
|
||||||
|
@ -155,11 +194,15 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
LdrPEProcessDriver(PVOID ModuleLoadBase)
|
LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||||
{
|
{
|
||||||
PULONG NTMagic;
|
unsigned int DriverSize;
|
||||||
|
PVOID DriverBase, CodeBase, InitializedDataBase, UninitializedDataBase;
|
||||||
|
PULONG PEMagic;
|
||||||
PIMAGE_DOS_HEADER PEDosHeader;
|
PIMAGE_DOS_HEADER PEDosHeader;
|
||||||
PIMAGE_FILE_HEADER PEFileHeader;
|
PIMAGE_FILE_HEADER PEFileHeader;
|
||||||
PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
|
PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
|
||||||
|
|
||||||
|
DbgPrint("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
|
||||||
|
|
||||||
/* Get header pointers */
|
/* Get header pointers */
|
||||||
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
||||||
PEMagic = (PULONG) ((unsigned int) ModuleLoadBase +
|
PEMagic = (PULONG) ((unsigned int) ModuleLoadBase +
|
||||||
|
@ -168,18 +211,76 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||||
PEDosHeader->e_lfanew + sizeof(ULONG));
|
PEDosHeader->e_lfanew + sizeof(ULONG));
|
||||||
PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) ModuleLoadBase +
|
PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) ModuleLoadBase +
|
||||||
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
|
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
|
||||||
|
CHECKPOINT;
|
||||||
|
|
||||||
/* Check file magic numbers */
|
/* Check file magic numbers */
|
||||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
||||||
PEDosHeader->e_lfanew == 0 ||
|
PEDosHeader->e_lfanew == 0 ||
|
||||||
*PEMagic != IMAGE_NT_MAGIC ||
|
*PEMagic != IMAGE_PE_MAGIC ||
|
||||||
PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
|
PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
|
||||||
{
|
{
|
||||||
return STATUS_UNSUCCESSFUL;
|
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;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,59 +669,91 @@ LdrCOFFGetSymbolValueByName(module *Module,
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS LdrLoadLibrary(HANDLE ProcessHandle,
|
||||||
|
PHANDLE ModuleHandle,
|
||||||
|
PCHAR Name)
|
||||||
static NTSTATUS
|
|
||||||
LdrProcessMZImage(HANDLE ProcessHandle,
|
|
||||||
HANDLE FileHandle,
|
|
||||||
PIMAGE_DOS_HEADER DosHeader)
|
|
||||||
{
|
{
|
||||||
|
#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: this is broke */
|
||||||
/* FIXME: Build/Load image sections */
|
/* FIXME: check for module already loaded */
|
||||||
|
/* FIXME: otherwise load module */
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* LdrLoadImage
|
||||||
* FUNCTION: Loads a PE executable into the specified process
|
* FUNCTION:
|
||||||
|
* Loads a module into the specified process
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* Filename = File to load
|
* HANDLE ProcessHandle handle of the process to load the module into
|
||||||
* ProcessHandle = handle
|
* PHANDLE ModuleHandle handle of the loaded module
|
||||||
* RETURNS: Status
|
* PUNICODE_STRING Filename name of the module to load
|
||||||
|
* RETURNS:
|
||||||
|
* NTSTATUS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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;
|
NTSTATUS Status;
|
||||||
ULONG SectionSize;
|
|
||||||
HANDLE FileHandle;
|
|
||||||
HANDLE ThreadHandle;
|
|
||||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
PMODULE Module;
|
||||||
PIMAGE_DOS_HEADER PEDosHeader;
|
PIMAGE_DOS_HEADER PEDosHeader;
|
||||||
CONTEXT Context;
|
|
||||||
HANDLE SectionHandle;
|
|
||||||
PVOID BaseAddress;
|
|
||||||
|
|
||||||
/* FIXME: should DLLs be named sections? */
|
/* FIXME: should DLLs be named sections? */
|
||||||
|
|
||||||
|
@ -636,135 +769,490 @@ LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read first block of image to determine type */
|
/* Build a module structure for the image */
|
||||||
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 512, 0, 0);
|
Module = ObGenericCreateObject(ModuleHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
PROCESS_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
ObModuleType);
|
||||||
|
if (Module == NULL)
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If MZ header exists */
|
/* If MZ header exists */
|
||||||
PEDosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
|
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,
|
Status = LdrProcessPEImage(ProcessHandle,
|
||||||
FileHandle,
|
ModuleHandle,
|
||||||
PEDosHeader);
|
FileHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (PEDosHeader->e_magic == 0x54AD)
|
else if (PEDosHeader->e_magic == 0x54AD)
|
||||||
{
|
{
|
||||||
Status = LdrProcessMZImage(ProcessHandle,
|
Status = LdrProcessMZImage(ProcessHandle,
|
||||||
FileHandle,
|
ModuleHandle,
|
||||||
PEDosHeader);
|
FileHandle);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* Assume bin format and load */
|
else /* Assume bin format and load */
|
||||||
{
|
{
|
||||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
Status = LdrProcessBinImage(ProcessHandle,
|
||||||
|
ModuleHandle,
|
||||||
/* Get the size of the file for the section */
|
FileHandle);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* FIXME: {else} could check for a.out, ELF, COFF, etc. images here... */
|
/* 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;
|
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
|
||||||
|
|
|
@ -89,6 +89,9 @@ objects/tst.o: $(TST_OBJECTS)
|
||||||
objects/dbg.o: $(DBG_OBJECTS)
|
objects/dbg.o: $(DBG_OBJECTS)
|
||||||
$(LD) -r $(DBG_OBJECTS) -o objects/dbg.o
|
$(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)
|
objects/nt.o: $(NT_OBJECTS)
|
||||||
$(LD) -r $(NT_OBJECTS) -o objects/nt.o
|
$(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 = 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/io.o objects/ob.o objects/ps.o objects/ex.o \
|
||||||
objects/se.o objects/cm.o objects/tst.o objects/dbg.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
|
utils/export/export$(EXE_POSTFIX): utils/export/export.c
|
||||||
$(NATIVE_CC) -g utils/export/export.c -o utils/export/export$(EXE_POSTFIX)
|
$(NATIVE_CC) -g utils/export/export.c -o utils/export/export$(EXE_POSTFIX)
|
||||||
|
|
|
@ -411,8 +411,9 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
|
||||||
{
|
{
|
||||||
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
|
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
|
||||||
{
|
{
|
||||||
free_page(MmGetPhysicalAddress(MemoryArea->BaseAddress+
|
free_page(GET_LARGE_INTEGER_LOW_PART(
|
||||||
(i*PAGESIZE)).LowPart,1);
|
MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE))),
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
{
|
{
|
||||||
DPRINT("Writing %x with physical address %x\n",
|
DPRINT("Writing %x with physical address %x\n",
|
||||||
base+(i*PAGESIZE),mdl_pages[i]);
|
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);
|
DPRINT("base %x\n",base);
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
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++)
|
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
|
||||||
{
|
{
|
||||||
Address = Mdl->StartVa + (i*PAGESIZE);
|
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]);
|
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;
|
Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
|
||||||
for (va=0; va<Mdl->Size; va++)
|
for (va=0; va<Mdl->Size; va++)
|
||||||
{
|
{
|
||||||
((PULONG)(Mdl + 1))[va] = MmGetPhysicalAddress(
|
((PULONG)(Mdl + 1))[va] = GET_LARGE_INTEGER_LOW_PART(
|
||||||
Mdl->StartVa+ (va * PAGESIZE)).LowPart;
|
MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE)));
|
||||||
}
|
}
|
||||||
Mdl->MappedSystemVa = Mdl->StartVa;
|
Mdl->MappedSystemVa = Mdl->StartVa;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/pool.h>
|
#include <internal/pool.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS *****************************************************************/
|
/* GLOBALS *****************************************************************/
|
||||||
|
|
|
@ -117,8 +117,7 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Section->MaximumSize.HighPart = 0;
|
LARGE_INTEGER_QUAD_PART(Section->MaximumSize) = 0xffffffff;
|
||||||
Section->MaximumSize.LowPart = 0xffffffff;
|
|
||||||
}
|
}
|
||||||
Section->SectionPageProtection = SectionPageProtection;
|
Section->SectionPageProtection = SectionPageProtection;
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -258,9 +257,9 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
|
||||||
return(Status);
|
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,
|
MmCreateMemoryArea(UserMode,
|
||||||
|
@ -271,7 +270,7 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
|
||||||
Protect,
|
Protect,
|
||||||
&Result);
|
&Result);
|
||||||
Result->Data.SectionData.Section = Section;
|
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("*BaseAddress %x\n",*BaseAddress);
|
||||||
DPRINT("Result->Data.SectionData.Section->FileObject %x\n",
|
DPRINT("Result->Data.SectionData.Section->FileObject %x\n",
|
||||||
|
|
|
@ -89,7 +89,9 @@ PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress,
|
||||||
}
|
}
|
||||||
for (i=0;i<=(NumberOfBytes/PAGESIZE);i++)
|
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);
|
return((PVOID)Result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,9 +107,9 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
|
||||||
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
|
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
|
||||||
MemoryArea,Address);
|
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;
|
MemoryArea->Data.SectionData.ViewOffset;
|
||||||
|
|
||||||
DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
|
DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
|
||||||
|
@ -193,7 +193,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||||
if (MmSectionHandleFault(MemoryArea,cr2)==STATUS_SUCCESS)
|
if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
stat=1;
|
stat=1;
|
||||||
}
|
}
|
||||||
|
@ -656,7 +656,7 @@ NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
|
for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
|
||||||
{
|
{
|
||||||
CurrentEntry = MmGetPageEntry(Process, BaseAddress + (i*PAGESIZE));
|
CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
|
||||||
RtlCopyMemory(Buffer + (i*PAGESIZE),
|
RtlCopyMemory(Buffer + (i*PAGESIZE),
|
||||||
(PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
|
(PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
|
||||||
PAGESIZE);
|
PAGESIZE);
|
||||||
|
@ -735,7 +735,7 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)
|
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)),
|
RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
|
||||||
Buffer + (i*PAGESIZE),
|
Buffer + (i*PAGESIZE),
|
||||||
PAGESIZE);
|
PAGESIZE);
|
||||||
|
|
|
@ -162,7 +162,7 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
ObLookupObject(ObjectAttributes->RootDirectory,path,
|
ObLookupObject(ObjectAttributes->RootDirectory,path,
|
||||||
&hdr->Parent,&Ignored);
|
&hdr->Parent,&Ignored, 0L);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the object header
|
* Initialize the object header
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <internal/mm.h>
|
#include <internal/mm.h>
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
|
@ -131,7 +131,7 @@ VOID PsDispatchThread(VOID)
|
||||||
{
|
{
|
||||||
DPRINT("Scheduling current thread\n");
|
DPRINT("Scheduling current thread\n");
|
||||||
KeQueryTickCount(&TickCount);
|
KeQueryTickCount(&TickCount);
|
||||||
CurrentThread->Tcb.LastTick = TickCount.LowPart;
|
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
|
||||||
CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||||
KeReleaseSpinLock(&ThreadListLock,irql);
|
KeReleaseSpinLock(&ThreadListLock,irql);
|
||||||
KeLowerIrql(PASSIVE_LEVEL);
|
KeLowerIrql(PASSIVE_LEVEL);
|
||||||
|
@ -144,7 +144,7 @@ VOID PsDispatchThread(VOID)
|
||||||
Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||||
|
|
||||||
KeQueryTickCount(&TickCount);
|
KeQueryTickCount(&TickCount);
|
||||||
CurrentThread->Tcb.LastTick = TickCount.LowPart;
|
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
|
||||||
|
|
||||||
CurrentThread = Candidate;
|
CurrentThread = Candidate;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include <internal/ctype.h>
|
#include <internal/ctype.h>
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
|
||||||
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||||
{
|
{
|
||||||
unsigned long result = 0,value;
|
unsigned long result = 0,value;
|
||||||
|
@ -117,13 +119,14 @@ static char * number(char * str, long num, int base, int size, int precision
|
||||||
*str++ = ' ';
|
*str++ = ' ';
|
||||||
if (sign)
|
if (sign)
|
||||||
*str++ = sign;
|
*str++ = sign;
|
||||||
if (type & SPECIAL)
|
if (type & SPECIAL) {
|
||||||
if (base==8)
|
if (base==8) {
|
||||||
*str++ = '0';
|
*str++ = '0';
|
||||||
else if (base==16) {
|
} else if (base==16) {
|
||||||
*str++ = '0';
|
*str++ = '0';
|
||||||
*str++ = digits[33];
|
*str++ = digits[33];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!(type & LEFT))
|
if (!(type & LEFT))
|
||||||
while (size-- > 0)
|
while (size-- > 0)
|
||||||
*str++ = c;
|
*str++ = c;
|
||||||
|
@ -143,7 +146,8 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
int i, base;
|
int i, base;
|
||||||
char * str;
|
char * str;
|
||||||
const char *s;
|
const char *s;
|
||||||
const short int* sw;
|
const short int *sw;
|
||||||
|
PUNICODE_STRING pus;
|
||||||
|
|
||||||
int flags; /* flags to number() */
|
int flags; /* flags to number() */
|
||||||
|
|
||||||
|
@ -243,6 +247,25 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
// CHECKPOINT;
|
// CHECKPOINT;
|
||||||
continue;
|
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':
|
case 's':
|
||||||
s = va_arg(args, char *);
|
s = va_arg(args, char *);
|
||||||
if (!s)
|
if (!s)
|
||||||
|
@ -310,17 +333,19 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
||||||
--fmt;
|
--fmt;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (qualifier == 'l')
|
if (qualifier == 'l') {
|
||||||
num = va_arg(args, unsigned long);
|
num = va_arg(args, unsigned long);
|
||||||
else if (qualifier == 'h')
|
} else if (qualifier == 'h') {
|
||||||
if (flags & SIGN)
|
if (flags & SIGN) {
|
||||||
num = va_arg(args, short);
|
num = va_arg(args, short);
|
||||||
else
|
} else {
|
||||||
num = va_arg(args, unsigned short);
|
num = va_arg(args, unsigned short);
|
||||||
else if (flags & SIGN)
|
}
|
||||||
|
} else if (flags & SIGN) {
|
||||||
num = va_arg(args, int);
|
num = va_arg(args, int);
|
||||||
else
|
} else {
|
||||||
num = va_arg(args, unsigned int);
|
num = va_arg(args, unsigned int);
|
||||||
|
}
|
||||||
str = number(str, num, base, field_width, precision, flags);
|
str = number(str, num, base, field_width, precision, flags);
|
||||||
}
|
}
|
||||||
*str = '\0';
|
*str = '\0';
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <internal/string.h>
|
#include <internal/string.h>
|
||||||
#include <internal/ctype.h>
|
#include <internal/ctype.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
int ShellChangeDir(char* args);
|
int ShellChangeDir(char* args);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <internal/i386/segment.h>
|
#include <internal/i386/segment.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
#include <in.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()
|
void TstBegin()
|
||||||
{
|
{
|
||||||
|
// TstDriverLoad();
|
||||||
ExExecuteShell();
|
ExExecuteShell();
|
||||||
// TstFileRead();
|
// TstFileRead();
|
||||||
// TstGeneralWrite();
|
// TstGeneralWrite();
|
||||||
|
|
|
@ -63,7 +63,7 @@ else
|
||||||
DEBUGGING_CFLAGS =
|
DEBUGGING_CFLAGS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DEFINES = -DDBG -DCHECKED
|
DEFINES = -DDBG -DCHECKED # -DCOMPILER_LARGE_INTEGERS
|
||||||
|
|
||||||
ifeq ($(WIN32_LEAN_AND_MEAN),yes)
|
ifeq ($(WIN32_LEAN_AND_MEAN),yes)
|
||||||
LEAN_AND_MEAN_DEFINE = -DWIN32_LEAN_AND_MEAN
|
LEAN_AND_MEAN_DEFINE = -DWIN32_LEAN_AND_MEAN
|
||||||
|
|
Loading…
Reference in a new issue