mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +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");
|
||||
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
|
||||
VFatReadSector modified to read in more than one sector at a time
|
||||
7-11-1998 Fixed bug that assumed that directory data could be fragmented
|
||||
8-12-1998 Added FAT32 support
|
||||
Added initial writability functions
|
||||
WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
|
||||
12-12-1998 Added basic support for FILE_STANDARD_INFORMATION request
|
||||
|
||||
*/
|
||||
|
||||
|
@ -20,6 +24,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/string.h>
|
||||
#include <wstring.h>
|
||||
#include <ddk/cctypes.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -28,6 +33,7 @@
|
|||
|
||||
#define FAT16 (1)
|
||||
#define FAT12 (2)
|
||||
#define FAT32 (3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -53,6 +59,23 @@ static PDRIVER_OBJECT DriverObject;
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
ULONG Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||
{
|
||||
ULONG FATsector;
|
||||
ULONG FATeis;
|
||||
PULONG Block;
|
||||
Block = ExAllocatePool(NonPagedPool,1024);
|
||||
FATsector=CurrentCluster/(512/sizeof(ULONG));
|
||||
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
|
||||
VFATReadSectors(DeviceExt->StorageDevice,DeviceExt->FATStart+FATsector, 1,
|
||||
Block);
|
||||
CurrentCluster = Block[FATeis];
|
||||
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
||||
CurrentCluster = 0;
|
||||
ExFreePool(Block);
|
||||
return(CurrentCluster);
|
||||
}
|
||||
|
||||
ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||
{
|
||||
ULONG FATsector;
|
||||
|
@ -69,14 +92,10 @@ ULONG Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
Block = (PUSHORT)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
||||
|
||||
CurrentCluster = Block[FATeis];
|
||||
|
||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||
{
|
||||
CurrentCluster = 0;
|
||||
}
|
||||
|
||||
DPRINT("Returning %x\n",CurrentCluster);
|
||||
|
||||
return(CurrentCluster);
|
||||
}
|
||||
|
||||
|
@ -96,9 +115,7 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
CBlock = (unsigned char *)(DeviceExt->FAT + (FATsector * BLOCKSIZE));
|
||||
|
||||
FATOffset = (CurrentCluster * 12) % (512 * 8);
|
||||
|
||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||
|
||||
if ((CurrentCluster % 2) == 0)
|
||||
{
|
||||
Entry = CBlock[((FATOffset / 24)*3)];
|
||||
|
@ -109,18 +126,12 @@ ULONG Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
|
||||
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
||||
}
|
||||
|
||||
DPRINT("Entry %x\n",Entry);
|
||||
|
||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||
{
|
||||
Entry = 0;
|
||||
}
|
||||
|
||||
CurrentCluster = Entry;
|
||||
|
||||
DPRINT("Returning %x\n",CurrentCluster);
|
||||
|
||||
return(CurrentCluster);
|
||||
}
|
||||
|
||||
|
@ -133,12 +144,170 @@ ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|||
{
|
||||
return(Fat16GetNextCluster(DeviceExt, CurrentCluster));
|
||||
}
|
||||
else if (DeviceExt->FatType == FAT32)
|
||||
{
|
||||
return(Fat32GetNextCluster(DeviceExt, CurrentCluster));
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
return(Fat12GetNextCluster(DeviceExt, CurrentCluster));
|
||||
}
|
||||
}
|
||||
|
||||
ULONG FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||
{
|
||||
ULONG sector;
|
||||
PUSHORT Block;
|
||||
int i;
|
||||
|
||||
sector = 0;
|
||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
|
||||
while(sector<DeviceExt->Boot->FATSectors) {
|
||||
memcpy(Block, DeviceExt->FAT+sector*BLOCKSIZE, BLOCKSIZE);
|
||||
|
||||
for(i=0; i<512; i++) {
|
||||
if(Block[i]==0) {
|
||||
ExFreePool(Block);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
sector++;
|
||||
}
|
||||
|
||||
/* Give an error message (out of disk space) if we reach here) */
|
||||
|
||||
ExFreePool(Block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
{
|
||||
ULONG FATsector;
|
||||
ULONG FATeis;
|
||||
PUSHORT Block;
|
||||
|
||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
|
||||
FATsector=ClusterToWrite/(512/sizeof(USHORT));
|
||||
FATeis=ClusterToWrite-(FATsector*256);
|
||||
|
||||
/* Update the in-memory FAT */
|
||||
memcpy(Block, DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||
Block[FATeis] = NewValue;
|
||||
memcpy(DeviceExt->FAT+FATsector*BLOCKSIZE, Block, BLOCKSIZE);
|
||||
|
||||
/* Write the changed FAT sector to disk */
|
||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||
DeviceExt->FATStart+FATsector,
|
||||
DeviceExt->Boot->SectorsPerCluster,
|
||||
(UCHAR *)Block);
|
||||
|
||||
ExFreePool(Block);
|
||||
}
|
||||
|
||||
void FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
{
|
||||
unsigned char* CBlock;
|
||||
ULONG FATsector;
|
||||
ULONG FATOffset;
|
||||
ULONG Entry;
|
||||
|
||||
CBlock = ExAllocatePool(NonPagedPool,1024);
|
||||
FATsector = (ClusterToWrite * 12) / (512 * 8);
|
||||
|
||||
memcpy(CBlock,DeviceExt->FAT+FATsector*BLOCKSIZE, BLOCKSIZE);
|
||||
FATOffset = (ClusterToWrite * 12) % (512 * 8);
|
||||
|
||||
DPRINT("FATSector %d FATOffset %d\n",FATsector,FATOffset);
|
||||
|
||||
/*
|
||||
|
||||
Write 12-bit entry
|
||||
|
||||
if ((CurrentCluster % 2) == 0)
|
||||
{
|
||||
Entry = CBlock[((FATOffset / 24)*3)];
|
||||
Entry |= (CBlock[((FATOffset / 24)*3) + 1] & 0xf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Entry = (CBlock[((FATOffset / 24)*3) + 1] >> 4);
|
||||
Entry |= (CBlock[((FATOffset / 24)*3) + 2] << 4);
|
||||
} */
|
||||
|
||||
ExFreePool(CBlock);
|
||||
}
|
||||
|
||||
void WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||
ULONG NewValue)
|
||||
{
|
||||
if (DeviceExt->FatType == FAT16) {
|
||||
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||
} else {
|
||||
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||
{
|
||||
ULONG LastCluster, NewCluster;
|
||||
BOOLEAN EOF = FALSE;
|
||||
|
||||
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||
DeviceExt,CurrentCluster);
|
||||
|
||||
/* Find out what was happening in the last cluster's AU */
|
||||
|
||||
if (DeviceExt->FatType == FAT16)
|
||||
{
|
||||
LastCluster = Fat16GetNextCluster(DeviceExt, CurrentCluster);
|
||||
if(LastCluster == 0xFFFF) {
|
||||
EOF = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LastCluster = Fat12GetNextCluster(DeviceExt, CurrentCluster);
|
||||
if(LastCluster == 0xFFF) {
|
||||
EOF = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if we must append or overwrite */
|
||||
|
||||
if (EOF == TRUE) {
|
||||
|
||||
/* Append */
|
||||
|
||||
/* Firstly, find the next available open allocation unit */
|
||||
NewCluster = FAT16FindAvailableCluster(DeviceExt);
|
||||
|
||||
/* Mark the new AU as the EOF */
|
||||
if(DeviceExt->FatType == FAT16) {
|
||||
FAT16WriteCluster(DeviceExt, NewCluster, 0xFFFF);
|
||||
} else {
|
||||
FAT12WriteCluster(DeviceExt, NewCluster, 0xFFF);
|
||||
}
|
||||
|
||||
/* Now, write the AU of the LastCluster with the value of the newly
|
||||
found AU */
|
||||
WriteCluster(DeviceExt, LastCluster, NewCluster);
|
||||
|
||||
/* Return NewCluster as CurrentCluster */
|
||||
return NewCluster;
|
||||
|
||||
} else {
|
||||
|
||||
/* Overwrite: Return LastCluster as CurrentCluster */
|
||||
return LastCluster;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
||||
unsigned long Cluster)
|
||||
{
|
||||
|
@ -345,12 +514,11 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
|||
WCHAR name[256];
|
||||
ULONG StartingSector;
|
||||
ULONG NextCluster;
|
||||
|
||||
DPRINT("FileFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
|
||||
|
||||
if (Parent == NULL)
|
||||
{
|
||||
Size = DeviceExt->rootDirectorySectors;
|
||||
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
|
||||
StartingSector = DeviceExt->rootStart;
|
||||
}
|
||||
else
|
||||
|
@ -358,10 +526,12 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
|||
DPRINT("Parent->entry.FileSize %x\n",Parent->entry.FileSize);
|
||||
|
||||
Size = ULONG_MAX;
|
||||
StartingSector = ClusterToSector(DeviceExt, Parent->entry.FirstCluster);
|
||||
NextCluster = Parent->entry.FirstCluster;
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
|
||||
else
|
||||
NextCluster = Parent->entry.FirstCluster;
|
||||
StartingSector = ClusterToSector(DeviceExt, NextCluster);
|
||||
}
|
||||
|
||||
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
|
||||
for (j=0; j<Size; j++)
|
||||
|
@ -381,12 +551,20 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
|
|||
DPRINT("Comparing %w %w\n",name,FileToFind);
|
||||
if (wstrcmpi(name,FileToFind))
|
||||
{
|
||||
|
||||
/* In the case of a long filename, the firstcluster is stored in
|
||||
the next record -- where it's short name is */
|
||||
if(DeviceExt->FatType==FAT32)
|
||||
if(((FATDirEntry *)block)[i].FirstCluster==0
|
||||
&&((FATDirEntry *)block)[i].FirstClusterHigh==0
|
||||
) i++;
|
||||
else
|
||||
if(((FATDirEntry *)block)[i].FirstCluster==0) i++;
|
||||
|
||||
DPRINT("Found it at cluster %u\n", ((FATDirEntry *)block)[i].FirstCluster);
|
||||
if( i==ENTRIES_PER_SECTOR)
|
||||
{
|
||||
VFATReadSectors(DeviceExt->StorageDevice,StartingSector+1,1,block);
|
||||
i=0;
|
||||
}
|
||||
|
||||
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
|
||||
sizeof(FATDirEntry));
|
||||
|
@ -492,13 +670,14 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
|||
*/
|
||||
{
|
||||
BootSector* Boot;
|
||||
|
||||
|
||||
Boot = ExAllocatePool(NonPagedPool,512);
|
||||
|
||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
|
||||
|
||||
if (strncmp(Boot->SysType,"FAT12",5)==0 ||
|
||||
strncmp(Boot->SysType,"FAT16",5)==0)
|
||||
strncmp(Boot->SysType,"FAT16",5)==0 ||
|
||||
strncmp(((struct _BootSector32 *)(Boot))->SysType,"FAT32",5)==0)
|
||||
{
|
||||
ExFreePool(Boot);
|
||||
return(TRUE);
|
||||
|
@ -507,7 +686,7 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||
PDEVICE_OBJECT DeviceToMount)
|
||||
/*
|
||||
* FUNCTION: Mounts the device
|
||||
|
@ -517,7 +696,7 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
|||
|
||||
DPRINT("Mounting VFAT device...");
|
||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
||||
|
||||
|
||||
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
|
||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
|
||||
|
||||
|
@ -538,29 +717,57 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
|||
{
|
||||
DeviceExt->FatType = FAT12;
|
||||
}
|
||||
else if (strncmp(((struct _BootSector32 *)(DeviceExt->Boot))->SysType,"FAT32",5)==0)
|
||||
{
|
||||
DeviceExt->FatType = FAT32;
|
||||
DeviceExt->rootDirectorySectors=DeviceExt->Boot->SectorsPerCluster;
|
||||
DeviceExt->rootStart=
|
||||
DeviceExt->FATStart+DeviceExt->Boot->FATCount
|
||||
* ((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
|
||||
DeviceExt->dataStart=DeviceExt->rootStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceExt->FatType = FAT16;
|
||||
}
|
||||
|
||||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
||||
// with FAT32 it's not a good idea to load always fat in memory
|
||||
// because on a 8GB partition with 2 KO clusters, the fat = 8 MO
|
||||
if(DeviceExt->FatType!=FAT32)
|
||||
{
|
||||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
||||
}
|
||||
}
|
||||
|
||||
void VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||
{
|
||||
ULONG Sector;
|
||||
ULONG i;
|
||||
|
||||
DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||
DeviceExt,Buffer,Cluster);
|
||||
|
||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
||||
|
||||
VFATReadSectors(DeviceExt->StorageDevice,
|
||||
Sector,
|
||||
DeviceExt->Boot->SectorsPerCluster,
|
||||
Buffer);
|
||||
}
|
||||
|
||||
void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||
{
|
||||
ULONG Sector;
|
||||
|
||||
// DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||
// DeviceExt,Buffer,Cluster);
|
||||
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||
DeviceExt,Buffer,Cluster);
|
||||
|
||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
||||
|
||||
VFATReadSectors(DeviceExt->StorageDevice,
|
||||
Sector,
|
||||
DeviceExt->Boot->SectorsPerCluster,
|
||||
Buffer);
|
||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
||||
Sector,
|
||||
DeviceExt->Boot->SectorsPerCluster,
|
||||
Buffer);
|
||||
}
|
||||
|
||||
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
|
@ -573,7 +780,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
ULONG CurrentCluster;
|
||||
ULONG FileOffset;
|
||||
ULONG FirstCluster;
|
||||
PFCB Fcb;
|
||||
PFCB Fcb;
|
||||
PVOID Temp;
|
||||
ULONG TempLength;
|
||||
|
||||
|
@ -583,7 +790,10 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
|
||||
FirstCluster = ReadOffset / DeviceExt->BytesPerCluster;
|
||||
Fcb = FileObject->FsContext;
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||
else
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
|
||||
if (ReadOffset >= Fcb->entry.FileSize)
|
||||
{
|
||||
|
@ -627,7 +837,7 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
|
||||
if (CurrentCluster == 0)
|
||||
{
|
||||
ExFreePool(Temp);
|
||||
ExFreePool(Temp);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -646,6 +856,97 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||
PVOID Buffer, ULONG Length, ULONG WriteOffset)
|
||||
/*
|
||||
* FUNCTION: Writes data to file
|
||||
*/
|
||||
{
|
||||
ULONG CurrentCluster;
|
||||
ULONG FileOffset;
|
||||
ULONG FirstCluster;
|
||||
PFCB Fcb;
|
||||
PVOID Temp;
|
||||
ULONG TempLength;
|
||||
|
||||
/* Locate the first cluster of the file */
|
||||
|
||||
FirstCluster = WriteOffset / DeviceExt->BytesPerCluster;
|
||||
Fcb = FileObject->FsContext;
|
||||
if (DeviceExt->FatType == FAT32)
|
||||
CurrentCluster = Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
||||
else
|
||||
CurrentCluster = Fcb->entry.FirstCluster;
|
||||
|
||||
/* Allocate a buffer to hold 1 cluster of data */
|
||||
|
||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
||||
|
||||
/* Find the cluster according to the offset in the file */
|
||||
|
||||
for (FileOffset=0; FileOffset < FirstCluster; FileOffset++)
|
||||
{
|
||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/*
|
||||
If the offset in the cluster doesn't fall on the cluster boundary then
|
||||
we have to write only from the specified offset
|
||||
*/
|
||||
|
||||
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
|
||||
{
|
||||
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
||||
(WriteOffset % DeviceExt->BytesPerCluster));
|
||||
|
||||
/* Read in the existing cluster data */
|
||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
||||
|
||||
/* Overwrite the last parts of the data as necessary */
|
||||
memcpy(Temp + WriteOffset % DeviceExt->BytesPerCluster, Buffer,
|
||||
TempLength);
|
||||
|
||||
/* Write the cluster back */
|
||||
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
||||
|
||||
/* Next write cluster */
|
||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
||||
|
||||
Length = Length - TempLength;
|
||||
Buffer = Buffer + TempLength;
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/* Write the buffer in chunks of 1 cluster */
|
||||
|
||||
while (Length > DeviceExt->BytesPerCluster)
|
||||
{
|
||||
VFATWriteCluster(DeviceExt, Buffer, CurrentCluster);
|
||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
||||
|
||||
if (CurrentCluster == 0)
|
||||
{
|
||||
ExFreePool(Temp);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||
Length = Length - DeviceExt->BytesPerCluster;
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/* Write the remainder */
|
||||
|
||||
if (Length > 0)
|
||||
{
|
||||
memcpy(Temp, Buffer, Length);
|
||||
VFATWriteCluster(DeviceExt, Temp, CurrentCluster);
|
||||
}
|
||||
|
||||
ExFreePool(Temp);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
|
@ -653,7 +954,7 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
Status = FsdCloseFile(DeviceExtension,FileObject);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
|
@ -685,11 +986,27 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
|
||||
NTSTATUS FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Length = Stack->Parameters.Write.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = Stack->Parameters.Write.ByteOffset.LowPart;
|
||||
|
||||
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
|
@ -746,10 +1063,10 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
|||
NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
DPRINT("VFAT FSC\n");
|
||||
|
||||
if (FsdHasFileSystem(DeviceToMount))
|
||||
|
@ -762,7 +1079,7 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||
}
|
||||
DPRINT("VFAT File system successfully mounted\n");
|
||||
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
|
@ -770,6 +1087,60 @@ NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS FsdGetStandardInformation(PFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||
PFILE_STANDARD_INFORMATION StandardInfo)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
unsigned long AllocSize;
|
||||
|
||||
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
||||
|
||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||
AllocSize = 0;
|
||||
while(AllocSize<FCB->entry.FileSize) {
|
||||
AllocSize+=DeviceExtension->BytesPerCluster;
|
||||
}
|
||||
|
||||
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
|
||||
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
|
||||
StandardInfo->NumberOfLinks = 0;
|
||||
StandardInfo->DeletePending = FALSE;
|
||||
if((FCB->entry.Attrib & 0x10)>0) {
|
||||
StandardInfo->Directory = TRUE;
|
||||
} else {
|
||||
StandardInfo->Directory = FALSE;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FILE_INFORMATION_CLASS FileInformationClass =
|
||||
Stack->Parameters.QueryFile.FileInformationClass;
|
||||
PFILE_OBJECT FileObject = NULL;
|
||||
PFCB FCB = NULL;
|
||||
PCCB CCB = NULL;
|
||||
|
||||
NTSTATUS RC = STATUS_SUCCESS;
|
||||
void *SystemBuffer;
|
||||
|
||||
FileObject = Stack->FileObject;
|
||||
CCB = (PCCB)(FileObject->FsContext2);
|
||||
FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||
|
||||
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
switch(FileInformationClass) {
|
||||
case FileStandardInformation:
|
||||
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
return RC;
|
||||
}
|
||||
|
||||
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
|
@ -785,7 +1156,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|||
UNICODE_STRING ustr;
|
||||
ANSI_STRING astr;
|
||||
|
||||
DbgPrint("VFAT 0.0.3\n");
|
||||
DbgPrint("VFAT 0.0.4\n");
|
||||
|
||||
DriverObject = _DriverObject;
|
||||
|
||||
|
@ -805,6 +1176,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||
FsdFileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||
FsdQueryInformation;
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
IoRegisterFileSystem(DeviceObject);
|
||||
|
|
|
@ -3,6 +3,11 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
|||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN ULONG SectorCount,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
struct _BootSector {
|
||||
unsigned char magic0, res0, magic1;
|
||||
unsigned char OEMName[8];
|
||||
|
@ -20,10 +25,29 @@ struct _BootSector {
|
|||
unsigned char Res2[450];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct _BootSector32 {
|
||||
unsigned char magic0, res0, magic1;
|
||||
unsigned char OEMName[8];
|
||||
unsigned short BytesPerSector;
|
||||
unsigned char SectorsPerCluster;
|
||||
unsigned short ReservedSectors;
|
||||
unsigned char FATCount;
|
||||
unsigned short RootEntries, Sectors;
|
||||
unsigned char Media;
|
||||
unsigned short FATSectors, SectorsPerTrack, Heads;
|
||||
unsigned long HiddenSectors, SectorsHuge;
|
||||
unsigned long FATSectors32;
|
||||
unsigned char x[31];
|
||||
unsigned char VolumeLabel[11], SysType[8];
|
||||
unsigned char Res2[422];
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _BootSector BootSector;
|
||||
|
||||
struct _FATDirEntry {
|
||||
unsigned char Filename[8], Ext[3], Attrib, Res[14];
|
||||
unsigned char Filename[8], Ext[3], Attrib, Res[8];
|
||||
unsigned short FirstClusterHigh;// higher
|
||||
unsigned char Res2[4];
|
||||
unsigned short FirstCluster;
|
||||
unsigned long FileSize;
|
||||
} __attribute__((packed));
|
||||
|
@ -46,3 +70,41 @@ struct _slot
|
|||
typedef struct _slot slot;
|
||||
|
||||
#define BLOCKSIZE 512
|
||||
|
||||
// Put the rest in struct.h
|
||||
/*
|
||||
typedef unsigned int uint32;
|
||||
|
||||
typedef struct _SFsdIdentifier {
|
||||
uint32 NodeType;
|
||||
uint32 NodeSize;
|
||||
} SFsdIdentifier, *PtrSFsdIdentifier;
|
||||
|
||||
typedef struct _SFsdNTRequiredFCB {
|
||||
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
|
||||
SECTION_OBJECT_POINTERS SectionObject;
|
||||
ERESOURCE MainResource;
|
||||
ERESOURCE PagingIoResource;
|
||||
} SFsdNTRequiredFCB, *PtrSFsdNTRequiredFCB;
|
||||
|
||||
typedef struct _SFsdFileControlBlock {
|
||||
SFsdIdentifier NodeIdentifier;
|
||||
SFsdNTRequiredFCB NTRequiredFCB;
|
||||
SFsdDiskDependentFCB DiskDependentFCB;
|
||||
struct _SFsdVolumeControlBlock *PtrVCB;
|
||||
LIST_ENTRY NextFCB;
|
||||
uint32 FCBFlags;
|
||||
LIST_ENTRY NextCCB;
|
||||
SHARE_ACCESS FCBShareAccess;
|
||||
uint32 LazyWriterThreadID;
|
||||
uint32 ReferenceCount;
|
||||
uint32 OpenHandleCount;
|
||||
PtrSFsdObjectName FCBName;
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
SFsdFileLockAnchorFCB ByteRangeLock;
|
||||
OPLOCK FCBOplock;
|
||||
} SFsdFCB, *PtrSFsdFCB;
|
||||
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
|
||||
#ifndef __DDK_LI_H
|
||||
#define __DDK_LI_H
|
||||
|
||||
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
|
||||
|
||||
#ifdef COMPILER_LARGE_INTEGERS
|
||||
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >> 32) )
|
||||
|
@ -7,14 +12,19 @@
|
|||
( LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
|
||||
( LargeInteger |= Unsigned_Long )
|
||||
#define LARGE_INTEGER_QUAD_PART(LargeInteger) (LargeInteger)
|
||||
|
||||
#else
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (LargeInteger.HighPart) )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger.LowPart) )
|
||||
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (LargeInteger).HighPart )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger).LowPart )
|
||||
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) \
|
||||
( LargeInteger.HighPart= Signed_Long )
|
||||
((LargeInteger).HighPart = (Signed_Long))
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) \
|
||||
( LargeInteger.LowPart = Unsigned_Long )
|
||||
((LargeInteger).LowPart = (Unsigned_Long))
|
||||
#define LARGE_INTEGER_QUAD_PART(LI) (*(LONGLONG *)(&(LI)))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ extern "C"
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#define QUAD_PART(LI) (*(LONGLONG *)(&LI))
|
||||
#include <ddk/li.h>
|
||||
|
||||
#include <ddk/status.h>
|
||||
#include <ddk/ntdef.h>
|
||||
|
|
|
@ -39,6 +39,11 @@ typedef struct _UNICODE_STRING
|
|||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
#define INIT_UNICODE_STRING(us, str) \
|
||||
((us).Length = strlen((str)), \
|
||||
(us).MaximumLength = (us).Length, \
|
||||
(us).Buffer = (str), (us))
|
||||
|
||||
typedef enum _SECTION_INHERIT {
|
||||
ViewShare = 1,
|
||||
ViewUnmap = 2
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
#define __MODULE_H
|
||||
|
||||
#include <coff.h>
|
||||
#include <pe.h>
|
||||
|
||||
typedef struct
|
||||
/*
|
||||
*
|
||||
*/
|
||||
/* FIXME: replace this struct with struct below in all code */
|
||||
typedef struct _module
|
||||
{
|
||||
unsigned int nsyms;
|
||||
unsigned int text_base;
|
||||
|
@ -29,6 +28,45 @@ typedef struct
|
|||
unsigned int raw_data_off;
|
||||
} module;
|
||||
|
||||
typedef SCNHDR COFF_SECTION_HEADER, *PCOFF_SECTION_HEADER;
|
||||
|
||||
typedef struct _MODULE
|
||||
{
|
||||
PVOID Base;
|
||||
unsigned int Size;
|
||||
unsigned int Flags;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int NumberOfSyms;
|
||||
PVOID TextBase;
|
||||
PVOID DataBase;
|
||||
PVOID BSSBase;
|
||||
SCNHDR *SectionList;
|
||||
char *StringTable;
|
||||
SYMENT *SymbolList;
|
||||
} COFF;
|
||||
struct
|
||||
{
|
||||
PIMAGE_FILE_HEADER FileHeader;
|
||||
PIMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
PCOFF_SECTION_HEADER SectionList;
|
||||
} PE;
|
||||
} Image;
|
||||
} MODULE, *PMODULE;
|
||||
|
||||
#define MODULE_FLAG_BIN 0x0001
|
||||
#define MODULE_FLAG_MZ 0x0002
|
||||
#define MODULE_FLAG_NE 0x0004
|
||||
#define MODULE_FLAG_PE 0x0008
|
||||
#define MODULE_FLAG_COFF 0x0010
|
||||
|
||||
typedef struct _INSTANCE
|
||||
{
|
||||
HANDLE ModuleHandle;
|
||||
} INSTANCE, *PINSTANCE;
|
||||
|
||||
BOOLEAN process_boot_module(unsigned int start);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,7 @@ typedef DWORD *PDWORD;
|
|||
#endif
|
||||
|
||||
#define IMAGE_DOS_MAGIC 0x54ad
|
||||
#define IMAGE_NT_MAGIC 0x00004550
|
||||
#define IMAGE_PE_MAGIC 0x00004550
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||
WORD e_magic; // Magic number
|
||||
|
@ -613,12 +613,10 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
|
|||
#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
|
||||
// old checksum didn't match.
|
||||
|
||||
|
||||
//
|
||||
// End Image Format
|
||||
//
|
||||
|
||||
|
||||
#define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
|
||||
#define MAXRESOURCENAME 13
|
||||
|
||||
|
@ -646,13 +644,34 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
|
|||
sizeof (IMAGE_FILE_HEADER) + \
|
||||
sizeof (IMAGE_OPTIONAL_HEADER)))
|
||||
|
||||
typedef struct _IMAGE_IMPORT_MODULE_DIRECTORY
|
||||
{
|
||||
DWORD dwRVAFunctionNameList;
|
||||
DWORD dwUseless1;
|
||||
DWORD dwUseless2;
|
||||
DWORD dwRVAModuleName;
|
||||
DWORD dwRVAFunctionAddressList;
|
||||
} IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
|
||||
|
||||
typedef struct tagImportDirectory
|
||||
{
|
||||
DWORD dwRVAFunctionNameList;
|
||||
DWORD dwUseless1;
|
||||
DWORD dwUseless2;
|
||||
DWORD dwRVAModuleName;
|
||||
DWORD dwRVAFunctionAddressList;
|
||||
}IMAGE_IMPORT_MODULE_DIRECTORY, * PIMAGE_IMPORT_MODULE_DIRECTORY;
|
||||
typedef struct _RELOCATION_DIRECTORY
|
||||
{
|
||||
DWORD VirtualAddress; /* adresse virtuelle du bloc ou se font les relocations */
|
||||
DWORD SizeOfBlock; // taille de cette structure + des structures
|
||||
// relocation_entry qui suivent (ces dernieres sont
|
||||
// donc au nombre de (SizeOfBlock-8)/2
|
||||
} RELOCATION_DIRECTORY, *PRELOCATION_DIRECTORY;
|
||||
|
||||
typedef struct _RELOCATION_ENTRY
|
||||
{
|
||||
WORD TypeOffset;
|
||||
// (TypeOffset >> 12) est le type
|
||||
// (TypeOffset&0xfff) est l'offset dans le bloc
|
||||
} RELOCATION_ENTRY, *PRELOCATION_ENTRY;
|
||||
|
||||
#define TYPE_RELOC_ABSOLUTE 0
|
||||
#define TYPE_RELOC_HIGH 1
|
||||
#define TYPE_RELOC_LOW 2
|
||||
#define TYPE_RELOC_HIGHLOW 3
|
||||
#define TYPE_RELOC_HIGHADJ 4
|
||||
#define TYPE_RELOC_MIPS_JMPADDR 5
|
||||
|
|
@ -32,11 +32,25 @@
|
|||
#ifndef _GNU_H_WINDOWS32_STRUCTURES
|
||||
#define _GNU_H_WINDOWS32_STRUCTURES
|
||||
|
||||
#ifdef COMPILER_LARGE_INTEGERS
|
||||
|
||||
typedef long long int LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
typedef unsigned long long int ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct _LARGE_INTEGER {
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
} LARGE_INTEGER, *PLARGE_INTEGER;
|
||||
|
||||
typedef struct _ULARGE_INTEGER {
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct _LIST_ENTRY {
|
||||
struct _LIST_ENTRY *Flink;
|
||||
struct _LIST_ENTRY *Blink;
|
||||
|
@ -129,11 +143,6 @@ typedef struct _CRITICAL_SECTION {
|
|||
DWORD Reserved;
|
||||
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
|
||||
|
||||
typedef struct _ULARGE_INTEGER {
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
||||
|
||||
typedef struct _GENERIC_MAPPING {
|
||||
ACCESS_MASK GenericRead;
|
||||
ACCESS_MASK GenericWrite;
|
||||
|
|
|
@ -390,6 +390,7 @@ rostitle db '',0
|
|||
;
|
||||
;
|
||||
loading_msg db 'Loading: ',0
|
||||
death_msg: db 'death', 0
|
||||
|
||||
filelength_lo dw 0
|
||||
filelength_hi dw 0
|
||||
|
|
|
@ -31,7 +31,7 @@ LOADERS = dos
|
|||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
|
||||
minix vfat ext2fs
|
||||
minix vfat # ext2fs
|
||||
|
||||
APPS = hello shell
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ static NTSTATUS CbReadBlock(PDCCB Dccb, PCCB Ccb)
|
|||
Ccb->Buffer=ExAllocatePool(NonPagedPool,Dccb->SectorSize);
|
||||
}
|
||||
|
||||
Offset.HighPart = 0;
|
||||
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
|
||||
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||
Dccb->DeviceObject,
|
||||
|
@ -206,8 +206,8 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
|
|||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
|
||||
Offset.HighPart = 0;
|
||||
Offset.LowPart = Ccb->BlockNr * Dccb->SectorSize;
|
||||
SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(Offset, Ccb->BlockNr * Dccb->SectorSize);
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
||||
Dccb->DeviceObject,
|
||||
|
@ -231,7 +231,7 @@ static NTSTATUS CbWriteBlock(PDCCB Dccb, PCCB Ccb)
|
|||
|
||||
PCCB CbFindModifiedCcb(PDCCB Dccb, PCCB Start)
|
||||
{
|
||||
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
static VOID CbDeleteAllCcbs(PDCCB Dccb)
|
||||
|
|
|
@ -122,10 +122,14 @@ VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,
|
|||
BOOLEAN ExTryToAcquireResourceExclusiveLite(PERESOURCE Resource)
|
||||
{
|
||||
LARGE_INTEGER timeout;
|
||||
timeout.HighPart = 0;
|
||||
timeout.LowPart = 0;
|
||||
KeWaitForSingleObject(&Resource->ExclusiveWaiters,Executive,KernelMode,
|
||||
FALSE,&timeout);
|
||||
|
||||
SET_LARGE_INTEGER_HIGH_PART(timeout, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(timeout, 0);
|
||||
return KeWaitForSingleObject(&Resource->ExclusiveWaiters,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
&timeout) == STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -201,11 +201,14 @@ PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr)
|
|||
* FUNCTION: Returns the physical address corresponding to a virtual address
|
||||
*/
|
||||
{
|
||||
PHYSICAL_ADDRESS p;
|
||||
DPRINT("get_page_physical_address(vaddr %x)\n",vaddr);
|
||||
p.HighPart = 0;
|
||||
p.LowPart = PAGE_MASK(*get_page_entry((unsigned int)vaddr));
|
||||
return(p);
|
||||
PHYSICAL_ADDRESS p;
|
||||
|
||||
DPRINT("get_page_physical_address(vaddr %x)\n", vaddr);
|
||||
SET_LARGE_INTEGER_HIGH_PART(p, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(
|
||||
*get_page_entry((unsigned int) vaddr)));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
BOOL is_page_present(unsigned int vaddr)
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#define SERIAL_PORT 0x03f8
|
||||
#define SERIAL_BAUD_RATE 19200
|
||||
#define SERIAL_LINE_CONTROL (SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO)
|
||||
//#define NDEBUG
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
|
|
@ -170,15 +170,12 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
|||
}
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
||||
StartingOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
||||
StartingOffset->HighPart;
|
||||
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,34 +279,29 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
|
|||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (MajorFunction == IRP_MJ_READ)
|
||||
{
|
||||
if (StartingOffset!=NULL)
|
||||
if (StartingOffset != NULL)
|
||||
{
|
||||
StackPtr->Parameters.Read.ByteOffset.LowPart =
|
||||
StartingOffset->LowPart;
|
||||
StackPtr->Parameters.Read.ByteOffset.HighPart =
|
||||
StartingOffset->HighPart;
|
||||
StackPtr->Parameters.Read.ByteOffset = *StartingOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
|
||||
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
||||
StartingOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
||||
StartingOffset->HighPart;
|
||||
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Write.ByteOffset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return(Irp);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,9 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
if (FileObject != NULL)
|
||||
{
|
||||
FileObject->CurrentByteOffset.LowPart =
|
||||
FileObject->CurrentByteOffset.LowPart + Irp->IoStatus.Information;
|
||||
SET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset,
|
||||
GET_LARGE_INTEGER_LOW_PART(FileObject->CurrentByteOffset) +
|
||||
Irp->IoStatus.Information);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,13 +93,12 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
|||
StackPtr->Parameters.Read.Length = Length;
|
||||
if (ByteOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Read.ByteOffset.LowPart = ByteOffset->LowPart;
|
||||
StackPtr->Parameters.Read.ByteOffset.HighPart = ByteOffset->HighPart;
|
||||
StackPtr->Parameters.Read.ByteOffset = *ByteOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Read.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Read.ByteOffset.HighPart = 0;
|
||||
SET_LARGE_INTEGER_LOW_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||
SET_LARGE_INTEGER_HIGH_PART(StackPtr->Parameters.Read.ByteOffset, 0);
|
||||
}
|
||||
if (Key!=NULL)
|
||||
{
|
||||
|
|
|
@ -127,10 +127,10 @@ asmlinkage void _main(boot_param* _bp)
|
|||
/*
|
||||
* Initalize the console (before printing anything)
|
||||
*/
|
||||
HalInitConsole(&bp);
|
||||
HalInitConsole(&_bp);
|
||||
|
||||
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
|
||||
|
||||
|
||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||
if (start < ((int)&end))
|
||||
{
|
||||
|
|
|
@ -65,11 +65,11 @@ static unsigned int loops_per_microsecond = 100;
|
|||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
void KeCalibrateTimerLoop()
|
||||
VOID KeCalibrateTimerLoop(VOID)
|
||||
{
|
||||
unsigned int start_tick;
|
||||
unsigned int end_tick;
|
||||
unsigned int nr_ticks;
|
||||
// unsigned int end_tick;
|
||||
// unsigned int nr_ticks;
|
||||
unsigned int i;
|
||||
unsigned int microseconds;
|
||||
|
||||
|
@ -146,10 +146,16 @@ NTSTATUS STDCALL ZwQueryPerformanceCounter(IN PLARGE_INTEGER Counter,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
|
||||
NTSTATUS
|
||||
KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
|
||||
{
|
||||
KeInitializeTimer(&(Thread->TimerBlock));
|
||||
KeSetTimer(&(Thread->TimerBlock),*Interval,NULL);
|
||||
assert(Thread != NULL);
|
||||
assert(Interval != NULL);
|
||||
|
||||
KeInitializeTimer(&(Thread->TimerBlock));
|
||||
KeSetTimer(&(Thread->TimerBlock),*Interval,NULL);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -193,6 +199,7 @@ VOID KeStallExecutionProcessor(ULONG MicroSeconds)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void ULLToLargeInteger(unsigned long long src,
|
||||
PLARGE_INTEGER dest)
|
||||
{
|
||||
|
@ -233,6 +240,8 @@ static inline signed long long LargeIntegerToSLL(PLARGE_INTEGER src)
|
|||
return(r);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
|
||||
/*
|
||||
|
@ -244,10 +253,12 @@ LARGE_INTEGER KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
|
|||
* NOTE: Returns the system tick count or the time-stamp on the pentium
|
||||
*/
|
||||
{
|
||||
PerformanceFreq->HighPart=0;
|
||||
PerformanceFreq->LowPart=0;
|
||||
if (PerformanceFreq != NULL)
|
||||
{
|
||||
LARGE_INTEGER_QUAD_PART(*PerformanceFreq) = 0;
|
||||
}
|
||||
|
||||
return *PerformanceFreq;
|
||||
return *PerformanceFreq;
|
||||
}
|
||||
|
||||
ULONG KeQueryTimeIncrement(VOID)
|
||||
|
@ -269,7 +280,7 @@ VOID KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
|
|||
* 1st of January, 1601.
|
||||
*/
|
||||
{
|
||||
ULLToLargeInteger(system_time,CurrentTime);
|
||||
LARGE_INTEGER_QUAD_PART(*CurrentTime) = system_time;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtGetTickCount(PULONG UpTime)
|
||||
|
@ -407,7 +418,7 @@ VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
|
|||
* TickCount (OUT) = Points to storage for the number of ticks
|
||||
*/
|
||||
{
|
||||
ULLToLargeInteger(ticks,TickCount);
|
||||
LARGE_INTEGER_QUAD_PART(*TickCount) = ticks;
|
||||
}
|
||||
|
||||
static void HandleExpiredTimer(PKTIMER current)
|
||||
|
@ -464,7 +475,7 @@ extern unsigned int nr_used_blocks;
|
|||
extern unsigned int EiFreeNonPagedPool;
|
||||
extern unsigned int EiUsedNonPagedPool;
|
||||
|
||||
VOID KiTimerInterrupt(VOID)
|
||||
BOOLEAN KiTimerInterrupt(VOID)
|
||||
/*
|
||||
* FUNCTION: Handles a timer interrupt
|
||||
*/
|
||||
|
@ -506,8 +517,8 @@ VOID KiTimerInterrupt(VOID)
|
|||
*vidmem=0x7;
|
||||
vidmem++;
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ldr/loader.c
|
||||
* PURPOSE: Loaders for PE executables
|
||||
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
|
||||
* PROGRAMMERS: Jean Michault
|
||||
* Rex Jolliff (rex@lvcablemodem.com)
|
||||
* UPDATE HISTORY:
|
||||
* DW 22/05/98 Created
|
||||
* RJJ 10/12/98 Completed loader function and added hooks for MZ/PE
|
||||
* RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE
|
||||
* RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF
|
||||
* RJJ 10/12/98 Rolled in David's code to load COFF drivers
|
||||
* JM 14/12/98 Built initail PE user module loader
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -16,24 +19,29 @@
|
|||
#include <internal/kernel.h>
|
||||
#include <internal/linkage.h>
|
||||
#include <internal/module.h>
|
||||
#include <internal/ob.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/symbol.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/li.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "pe.h"
|
||||
/* MACROS ********************************************************************/
|
||||
|
||||
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
POBJECT_TYPE ObModuleType = NULL;
|
||||
|
||||
/* FORWARD DECLARATIONS ******************************************************/
|
||||
|
||||
NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
|
||||
NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
|
||||
|
||||
/* COFF Driver load support **************************************************/
|
||||
|
||||
/* COFF Driver load support */
|
||||
static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
|
||||
static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
||||
static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
|
||||
|
@ -42,8 +50,37 @@ static unsigned int LdrCOFFGetSymbolValue(module *Module, unsigned int Idx);
|
|||
static unsigned int LdrCOFFGetKernelSymbolAddr(char *Name);
|
||||
static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName, unsigned int Idx);
|
||||
|
||||
/* Image loader forward delcarations */
|
||||
static NTSTATUS LdrProcessMZImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
|
||||
static NTSTATUS LdrProcessPEImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
|
||||
static NTSTATUS LdrProcessBinImage(HANDLE ProcessHandle, HANDLE ModuleHandle, HANDLE FileHandle);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID LdrInitModuleManagment(VOID)
|
||||
{
|
||||
ANSI_STRING AnsiString;
|
||||
|
||||
/* Register the process object type */
|
||||
ObModuleType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
ObModuleType->TotalObjects = 0;
|
||||
ObModuleType->TotalHandles = 0;
|
||||
ObModuleType->MaxObjects = ULONG_MAX;
|
||||
ObModuleType->MaxHandles = ULONG_MAX;
|
||||
ObModuleType->PagedPoolCharge = 0;
|
||||
ObModuleType->NonpagedPoolCharge = sizeof(MODULE);
|
||||
ObModuleType->Dump = NULL;
|
||||
ObModuleType->Open = NULL;
|
||||
ObModuleType->Close = NULL;
|
||||
ObModuleType->Delete = NULL;
|
||||
ObModuleType->Parse = NULL;
|
||||
ObModuleType->Security = NULL;
|
||||
ObModuleType->QueryName = NULL;
|
||||
ObModuleType->OkayToClose = NULL;
|
||||
RtlInitAnsiString(&AnsiString, "Module");
|
||||
RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Loads a kernel driver
|
||||
* ARGUMENTS:
|
||||
|
@ -62,6 +99,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
|||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
|
||||
DbgPrint("Loading Driver %W...\n", Filename);
|
||||
|
||||
/* Open the Driver */
|
||||
InitializeObjectAttributes(&FileObjectAttributes,
|
||||
Filename,
|
||||
|
@ -155,11 +194,15 @@ LdrLoadDriver(PUNICODE_STRING Filename)
|
|||
NTSTATUS
|
||||
LdrPEProcessDriver(PVOID ModuleLoadBase)
|
||||
{
|
||||
PULONG NTMagic;
|
||||
unsigned int DriverSize;
|
||||
PVOID DriverBase, CodeBase, InitializedDataBase, UninitializedDataBase;
|
||||
PULONG PEMagic;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
PIMAGE_FILE_HEADER PEFileHeader;
|
||||
PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
|
||||
|
||||
DbgPrint("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
|
||||
|
||||
/* Get header pointers */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
|
||||
PEMagic = (PULONG) ((unsigned int) ModuleLoadBase +
|
||||
|
@ -168,18 +211,76 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
|
|||
PEDosHeader->e_lfanew + sizeof(ULONG));
|
||||
PEOptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((unsigned int) ModuleLoadBase +
|
||||
PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
|
||||
CHECKPOINT;
|
||||
|
||||
/* Check file magic numbers */
|
||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
||||
PEDosHeader->e_lfanew == 0 ||
|
||||
*PEMagic != IMAGE_NT_MAGIC ||
|
||||
*PEMagic != IMAGE_PE_MAGIC ||
|
||||
PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
#if 0
|
||||
/* FIXME: if image is fixed-address load, then fail */
|
||||
|
||||
/* FIXME: check/verify OS version number */
|
||||
|
||||
DbgPrint("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
|
||||
PEOptionalHeader->Magic,
|
||||
PEOptionalHeader->MajorLinkerVersion,
|
||||
PEOptionalHeader->MinorLinkerVersion);
|
||||
DbgPrint("Size: CODE:%08lx(%d) DATA:%08lx(%d) BSS:%08lx(%d)\n",
|
||||
PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SizeOfUninitializedData,
|
||||
PEOptionalHeader->SizeOfUninitializedData);
|
||||
DbgPrint("Entry Point:%08lx\n", PEOptionalHeader->AddressOfEntryPoint);
|
||||
CHECKPOINT;
|
||||
|
||||
/* Determine the size of the module */
|
||||
DriverSize = ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SectionAlignment) +
|
||||
ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SectionAlignment) +
|
||||
ROUND_UP(PEOptionalHeader->SizeOfUninitializedData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
CHECKPOINT;
|
||||
|
||||
/* Allocate a virtual section for the module */
|
||||
DriverBase = MmAllocateSection(DriverSize);
|
||||
if (DriverBase == 0)
|
||||
{
|
||||
DbgPrint("Failed to allocate a virtual section for driver\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
CHECKPOINT;
|
||||
|
||||
/* Compute addresses for driver sections */
|
||||
CodeBase = DriverBase;
|
||||
InitializedDataBase = (PUCHAR) DriverBase +
|
||||
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
UninitializedDataBase = (PUCHAR) InitializedDataBase +
|
||||
(PUCHAR) ROUND_UP(PEOptionalHeader->SizeOfInitializedData,
|
||||
PEOptionalHeader->SectionAlignment);
|
||||
|
||||
/* FIXME: Copy code section into virtual section */
|
||||
memcpy(CodeBase,
|
||||
(PVOID)(ModuleLoadBase + ???),
|
||||
ROUND_UP(PEOptionalHeader->SizeOfCode,
|
||||
PEOptionalHeader->FileAlignment));
|
||||
#endif
|
||||
|
||||
/* FIXME: Copy initialized data section into virtual section */
|
||||
/* FIXME: Perform relocations fixups */
|
||||
/* FIXME: compute address of entry point */
|
||||
|
||||
/* return InitializeLoadedDriver(EntryPoint); */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -568,59 +669,91 @@ LdrCOFFGetSymbolValueByName(module *Module,
|
|||
return 0L;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
LdrProcessMZImage(HANDLE ProcessHandle,
|
||||
HANDLE FileHandle,
|
||||
PIMAGE_DOS_HEADER DosHeader)
|
||||
NTSTATUS LdrLoadLibrary(HANDLE ProcessHandle,
|
||||
PHANDLE ModuleHandle,
|
||||
PCHAR Name)
|
||||
{
|
||||
#if 0
|
||||
NTSTATUS Status;
|
||||
ANSI_STRING afilename;
|
||||
UNICODE_STRING ufilename,umodName;
|
||||
PMODULE *Library, *Module;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
PWSTR Ignored;
|
||||
char name2[512];
|
||||
|
||||
/* FIXME: map VDM into low memory */
|
||||
/* FIXME: Build/Load image sections */
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* FIXME: this is broke */
|
||||
/* FIXME: check for module already loaded */
|
||||
/* FIXME: otherwise load module */
|
||||
/* FIXME: we need to fix how modules are loaded so that they can
|
||||
be shared... :( */
|
||||
|
||||
/* If module is already loaded, get a reference and return it */
|
||||
strcpy(name2, "\\modules\\");
|
||||
strcat(name2, Name);
|
||||
RtlInitAnsiString(&afilename, name2);
|
||||
RtlAnsiStringToUnicodeString(&umodName, &afilename, TRUE);
|
||||
InitializeObjectAttributes(&attr, &umodName, 0, NULL, NULL);
|
||||
Status = ObOpenObjectByName(&attr, (PVOID *) &Library, &Ignored);
|
||||
DPRINT("LoadLibrary : Status=%x,pLibrary=%x\n",Status, Library);
|
||||
if (!NT_SUCCESS(Status) || Library == NULL)
|
||||
{
|
||||
strcpy(name2, "\\??\\C:\\reactos\\system\\");
|
||||
strcat(name2, name);
|
||||
RtlInitAnsiString(&afilename, name2);
|
||||
RtlAnsiStringToUnicodeString(&ufilename, &afilename, TRUE);
|
||||
DPRINT("LoadLibrary,load %s\n", name2);
|
||||
Library = LdrLoadImage(&ufilename);
|
||||
/* FIXME: execute start code ? */
|
||||
Module = ObGenericCreateObject(NULL, PROCESS_ALL_ACCESS, &attr, ObModuleType);
|
||||
if (Module)
|
||||
{
|
||||
memcpy(Module, Library, PMODULE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("library object not created\n");
|
||||
}
|
||||
RtlFreeUnicodeString(&ufilename);
|
||||
Status = ObOpenObjectByName(&attr, (PVOID *)&Library, &Ignored);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("Library already loaded\n");
|
||||
*Module = Library
|
||||
}
|
||||
RtlFreeUnicodeString(&umodName);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
#endif
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
LdrProcessPEImage(HANDLE ProcessHandle,
|
||||
HANDLE FileHandle,
|
||||
PIMAGE_DOS_HEADER DosHeader)
|
||||
{
|
||||
// PIMAGE_NT_HEADERS PEHeader;
|
||||
// PIMAGE_SECTION_HEADER Sections;
|
||||
|
||||
// FIXME: Check architechture
|
||||
// FIXME: Build/Load image sections
|
||||
// FIXME: do relocations code sections
|
||||
// FIXME: resolve imports
|
||||
// FIXME: do fixups
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Loads a PE executable into the specified process
|
||||
/* LdrLoadImage
|
||||
* FUNCTION:
|
||||
* Loads a module into the specified process
|
||||
* ARGUMENTS:
|
||||
* Filename = File to load
|
||||
* ProcessHandle = handle
|
||||
* RETURNS: Status
|
||||
* HANDLE ProcessHandle handle of the process to load the module into
|
||||
* PHANDLE ModuleHandle handle of the loaded module
|
||||
* PUNICODE_STRING Filename name of the module to load
|
||||
* RETURNS:
|
||||
* NTSTATUS
|
||||
*/
|
||||
|
||||
NTSTATUS
|
||||
LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
|
||||
LdrLoadImage(HANDLE ProcessHandle,
|
||||
PHANDLE ModuleHandle,
|
||||
PUNICODE_STRING Filename)
|
||||
{
|
||||
char BlockBuffer[512];
|
||||
#if 0
|
||||
char BlockBuffer[1024];
|
||||
NTSTATUS Status;
|
||||
ULONG SectionSize;
|
||||
HANDLE FileHandle;
|
||||
HANDLE ThreadHandle;
|
||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||
HANDLE FileHandle;
|
||||
PMODULE Module;
|
||||
PIMAGE_DOS_HEADER PEDosHeader;
|
||||
CONTEXT Context;
|
||||
HANDLE SectionHandle;
|
||||
PVOID BaseAddress;
|
||||
|
||||
/* FIXME: should DLLs be named sections? */
|
||||
|
||||
|
@ -636,135 +769,490 @@ LdrLoadImage(PUNICODE_STRING Filename, HANDLE ProcessHandle)
|
|||
return Status;
|
||||
}
|
||||
|
||||
/* Read first block of image to determine type */
|
||||
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 512, 0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Build a module structure for the image */
|
||||
Module = ObGenericCreateObject(ModuleHandle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
NULL,
|
||||
ObModuleType);
|
||||
if (Module == NULL)
|
||||
{
|
||||
ZwClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read first block of image to determine type */
|
||||
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(*ModuleHandle);
|
||||
*ModuleHandle = NULL;
|
||||
ZwClose(FileHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
|
||||
if (PEDosHeader->e_magic == 0x54AD && PEDosHeader->e_lfanew != 0L)
|
||||
if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC &&
|
||||
PEDosHeader->e_lfanew != 0L &&
|
||||
*(PULONG)((PUCHAR)BlockBuffer + PEDosHeader->e_lfanew) == IMAGE_PE_MAGIC)
|
||||
{
|
||||
Status = LdrProcessPEImage(ProcessHandle,
|
||||
FileHandle,
|
||||
PEDosHeader);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
ModuleHandle,
|
||||
FileHandle);
|
||||
}
|
||||
else if (PEDosHeader->e_magic == 0x54AD)
|
||||
{
|
||||
Status = LdrProcessMZImage(ProcessHandle,
|
||||
FileHandle,
|
||||
PEDosHeader);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
ModuleHandle,
|
||||
FileHandle);
|
||||
}
|
||||
else /* Assume bin format and load */
|
||||
{
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
|
||||
/* Get the size of the file for the section */
|
||||
Status = ZwQueryInformationFile(FileHandle,
|
||||
NULL,
|
||||
&FileStdInfo,
|
||||
sizeof(FileStdInfo),
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwClose(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the section for the code */
|
||||
Status = ZwCreateSection(&SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
MEM_COMMIT,
|
||||
FileHandle);
|
||||
ZwClose(FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map a view of the section into the desired process */
|
||||
BaseAddress = (PVOID)0x10000;
|
||||
SectionSize = GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize);
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
SectionSize,
|
||||
NULL,
|
||||
&SectionSize,
|
||||
0,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: destroy the section here */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Setup the context for the initial thread */
|
||||
memset(&Context,0,sizeof(CONTEXT));
|
||||
Context.SegSs = USER_DS;
|
||||
Context.Esp = 0x2000;
|
||||
Context.EFlags = 0x202;
|
||||
Context.SegCs = USER_CS;
|
||||
Context.Eip = 0x10000;
|
||||
Context.SegDs = USER_DS;
|
||||
Context.SegEs = USER_DS;
|
||||
Context.SegFs = USER_DS;
|
||||
Context.SegGs = USER_DS;
|
||||
|
||||
/* Create the stack for the process */
|
||||
BaseAddress = (PVOID) 0x1000;
|
||||
SectionSize = 0x1000;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&SectionSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: unmap the section here */
|
||||
/* FIXME: destroy the section here */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the initial thread */
|
||||
Status = ZwCreateThread(&ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
ProcessHandle,
|
||||
NULL,
|
||||
&Context,
|
||||
NULL,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: destroy the stack memory block here */
|
||||
/* FIXME: unmap the section here */
|
||||
/* FIXME: destroy the section here */
|
||||
|
||||
return Status;
|
||||
}
|
||||
Status = LdrProcessBinImage(ProcessHandle,
|
||||
ModuleHandle,
|
||||
FileHandle);
|
||||
}
|
||||
/* FIXME: {else} could check for a.out, ELF, COFF, etc. images here... */
|
||||
|
||||
/* FIXME: should we unconditionally dereference the module handle here? */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(*ModuleHandle);
|
||||
*ModuleHandle = NULL;
|
||||
}
|
||||
ZwClose(FileHandle);
|
||||
|
||||
return Status;
|
||||
#endif
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static NTSTATUS
|
||||
LdrProcessMZImage(HANDLE ProcessHandle,
|
||||
HANDLE ModuleHandle,
|
||||
HANDLE FileHandle)
|
||||
{
|
||||
|
||||
/* FIXME: map VDM into low memory */
|
||||
/* FIXME: Build/Load image sections */
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
LdrProcessPEImage(HANDLE ProcessHandle,
|
||||
HANDLE ModuleHandle,
|
||||
HANDLE FileHandle)
|
||||
{
|
||||
int i;
|
||||
NTSTATUS Status;
|
||||
PVOID BaseSection;
|
||||
PIMAGE_DOS_HEADER DosHeader;
|
||||
PIMAGE_NT_HEADERS NTHeaders;
|
||||
PMODULE Module;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
|
||||
/* Allocate memory for headers */
|
||||
Module = HEADER_TO_BODY(ModuleHandle);
|
||||
if (Module == NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
DosHeader = (PIMAGE_DOS_HEADER)ExAllocatePool(NonPagedPool,
|
||||
sizeof(IMAGE_DOS_HEADER) +
|
||||
sizeof(IMAGE_NT_HEADERS));
|
||||
if (DosHeader == NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
NTHeaders = (PIMAGE_NT_HEADERS)((PUCHAR) DosHeader + sizeof(IMAGE_DOS_HEADER));
|
||||
|
||||
/* Read the headers into memory */
|
||||
memset(Module, '\0', sizeof(PMODULE));
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL, NULL, NULL, NULL,
|
||||
DosHeader,
|
||||
sizeof(IMAGE_DOS_HEADER),
|
||||
0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(DosHeader);
|
||||
return Status;
|
||||
}
|
||||
SET_LARGE_INTEGER_HIGH_PART(SectionOffset, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(SectionOffset, DosHeader->e_lfanew);
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NTHeaders,
|
||||
sizeof(IMAGE_NT_HEADERS),
|
||||
&SectionOffset,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(DosHeader);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory in process for image */
|
||||
Module->Flags = MODULE_FLAG_PE;
|
||||
Module->Base = (PVOID) NTHeaders->OptionalHeader.ImageBase;
|
||||
Module->Size = NTHeaders->OptionalHeader.SizeOfImage;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&Module->Base,
|
||||
0,
|
||||
NULL,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(DosHeader);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load headers into virtual memory */
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL, NULL, NULL, NULL,
|
||||
Module->Base,
|
||||
NTHeaders->OptionalHeader.SizeOfHeaders,
|
||||
0, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwFreeVirtualMemory(ProcessHandle,
|
||||
Module->Base,
|
||||
0,
|
||||
MEM_RELEASE);
|
||||
ExFreePool(DosHeader);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Adjust module pointers into virtual memory */
|
||||
DosHeader = (PIMAGE_DOS_HEADER) Module->Base;
|
||||
NTHeaders = (PIMAGE_NT_HEADERS) ((PUCHAR)Module->Base +
|
||||
DosHeader->e_lfanew);
|
||||
Module->Image.PE.FileHeader = (PIMAGE_FILE_HEADER) ((PUCHAR)NTHeaders +
|
||||
sizeof(DWORD));
|
||||
Module->Image.PE.OptionalHeader = (PIMAGE_OPTIONAL_HEADER)
|
||||
((PUCHAR)Module->Image.PE.FileHeader + sizeof(IMAGE_FILE_HEADER));
|
||||
Module->Image.PE.SectionList = (PCOFF_SECTION_HEADER) ((PUCHAR)NTHeaders +
|
||||
sizeof(IMAGE_NT_HEADERS));
|
||||
|
||||
/* Build Image Sections */
|
||||
/* FIXME: should probably use image directory to load sections. */
|
||||
for (i = 0; i < Module->Image.PE.FileHeader->NumberOfSections; i++)
|
||||
{
|
||||
DPRINT("section %d\n", i);
|
||||
BaseSection = (PVOID)((PCHAR) Module->Base +
|
||||
Module->Image.PE.SectionList[i].s_vaddr);
|
||||
|
||||
/* Load code and initialized data sections from disk */
|
||||
if ((Module->Image.PE.SectionList[i].s_flags & STYP_TEXT) ||
|
||||
(Module->Image.PE.SectionList[i].s_flags & STYP_DATA))
|
||||
{
|
||||
SET_LARGE_INTEGER_HIGH_PART(SectionOffset, 0);
|
||||
SET_LARGE_INTEGER_LOW_PART(SectionOffset,
|
||||
Module->Image.PE.SectionList[i].s_scnptr);
|
||||
|
||||
/* FIXME: should probably map sections into sections */
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL, NULL, NULL, NULL,
|
||||
Module->Base + Module->Image.PE.SectionList[i].s_vaddr,
|
||||
min(Module->Image.PE.SectionList[i].s_size,
|
||||
Module->Image.PE.SectionList[i].s_paddr),
|
||||
&SectionOffset, 0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ZwFreeVirtualMemory(ProcessHandle,
|
||||
Module->Base,
|
||||
0,
|
||||
MEM_RELEASE);
|
||||
ExFreePool(DosHeader);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else if (Module->Image.PE.SectionList[i].s_flags & STYP_BSS)
|
||||
{
|
||||
memset((PVOID)(Module->Base +
|
||||
Module->Image.PE.SectionList[i].s_vaddr),
|
||||
0,
|
||||
Module->Image.PE.SectionList[i].s_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolve Import Library references */
|
||||
if (Module->Image.PE.OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
{
|
||||
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
|
||||
|
||||
/* Process each import module */
|
||||
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
|
||||
((PUCHAR)Module->Base + Module->Image.PE.OptionalHeader->
|
||||
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
while (ImportModuleDirectory->dwRVAModuleName)
|
||||
{
|
||||
PMODULE Library;
|
||||
PVOID *LibraryExports;
|
||||
PVOID *ImportAddressList; // was pImpAddr
|
||||
PULONG FunctionNameList;
|
||||
DWORD pName;
|
||||
PWORD pHint;
|
||||
|
||||
/* Load the library module into the process */
|
||||
/* FIXME: this should take a UNICODE string */
|
||||
Status = LdrLoadLibrary(ProcessHandle,
|
||||
&Library,
|
||||
(PCHAR)(Module->Base +
|
||||
ImportModuleDirectory->dwRVAModuleName));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Dereference all loaded modules */
|
||||
ZwFreeVirtualMemory(ProcessHandle,
|
||||
Module->Base,
|
||||
0,
|
||||
MEM_RELEASE);
|
||||
ExFreePool(DosHeader);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get the address of the export list for the library */
|
||||
LibraryExports = (PVOID *)(Library->Base +
|
||||
Library->Image.PE.OptionalHeader->
|
||||
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress +
|
||||
sizeof(IMAGE_EXPORT_DIRECTORY));
|
||||
|
||||
/* Get the import address list */
|
||||
ImportAddressList = (PVOID *)
|
||||
((PCHAR)Module->Image.PE.OptionalHeader->ImageBase +
|
||||
ImportModuleDirectory->dwRVAFunctionAddressList);
|
||||
|
||||
/* Get the list of functions to import */
|
||||
if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
|
||||
{
|
||||
FunctionNameList = (PULONG) ((PCHAR)Module->Base +
|
||||
ImportModuleDirectory->dwRVAFunctionNameList);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionNameList = (PULONG) ((PCHAR)Module->Base +
|
||||
ImportModuleDirectory->dwRVAFunctionAddressList);
|
||||
}
|
||||
|
||||
/* Walk through function list and fixup addresses */
|
||||
while(*FunctionNameList != 0L)
|
||||
{
|
||||
if ((*FunctionNameList) & 0x80000000) // hint
|
||||
{
|
||||
*ImportAddressList = LibraryExports[(*FunctionNameList) & 0x7fffffff];
|
||||
}
|
||||
else // hint-name
|
||||
{
|
||||
pName = (DWORD)((PCHAR)Module->Base + *FunctionNameList + 2);
|
||||
pHint = (PWORD)((PCHAR)Module->Base + *FunctionNameList);
|
||||
|
||||
/* FIXME: verify name */
|
||||
|
||||
*ImportAddressList = LibraryExports[*pHint];
|
||||
}
|
||||
|
||||
/* FIXME: verify value of hint */
|
||||
|
||||
ImportAddressList++;
|
||||
FunctionNameList++;
|
||||
}
|
||||
ImportModuleDirectory++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do fixups */
|
||||
if (Module->Base != (PVOID)Module->Image.PE.OptionalHeader->ImageBase)
|
||||
{
|
||||
USHORT NumberOfEntries;
|
||||
PUSHORT pValue16;
|
||||
ULONG RelocationRVA;
|
||||
ULONG Delta32, Offset;
|
||||
PULONG pValue32;
|
||||
PRELOCATION_DIRECTORY RelocationDir;
|
||||
PRELOCATION_ENTRY RelocationBlock;
|
||||
|
||||
RelocationRVA = NTHeaders->OptionalHeader.DataDirectory[
|
||||
IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||
if (RelocationRVA)
|
||||
{
|
||||
RelocationDir = (PRELOCATION_DIRECTORY)
|
||||
((PCHAR)Module->Base + RelocationRVA);
|
||||
while (RelocationDir->SizeOfBlock)
|
||||
{
|
||||
Delta32 = (unsigned long)(Module->Base - NTHeaders->OptionalHeader.ImageBase);
|
||||
RelocationBlock = (PRELOCATION_ENTRY)
|
||||
(RelocationRVA + Module->Base + sizeof(RELOCATION_DIRECTORY));
|
||||
NumberOfEntries =
|
||||
(RelocationDir->SizeOfBlock - sizeof(RELOCATION_DIRECTORY)) /
|
||||
sizeof(RELOCATION_ENTRY);
|
||||
for (i = 0; i < NumberOfEntries; i++)
|
||||
{
|
||||
Offset = (RelocationBlock[i].TypeOffset & 0xfff) + RelocationDir->VirtualAddress;
|
||||
switch (RelocationBlock[i].TypeOffset >> 12)
|
||||
{
|
||||
case TYPE_RELOC_ABSOLUTE:
|
||||
break;
|
||||
|
||||
case TYPE_RELOC_HIGH:
|
||||
pValue16 = (PUSHORT) (Module->Base + Offset);
|
||||
*pValue16 += Delta32 >> 16;
|
||||
break;
|
||||
|
||||
case TYPE_RELOC_LOW:
|
||||
pValue16 = (PUSHORT)(Module->Base + Offset);
|
||||
*pValue16 += Delta32 & 0xffff;
|
||||
break;
|
||||
|
||||
case TYPE_RELOC_HIGHLOW:
|
||||
pValue32 = (PULONG) (Module->Base + Offset);
|
||||
*pValue32 += Delta32;
|
||||
break;
|
||||
|
||||
case TYPE_RELOC_HIGHADJ:
|
||||
/* FIXME: do the highadjust fixup */
|
||||
DbgPrint("TYPE_RELOC_HIGHADJ fixup not implemented, sorry\n");
|
||||
// break;
|
||||
|
||||
default:
|
||||
DbgPrint("unexpected fixup type\n");
|
||||
|
||||
/* FIXME: Dereference all loaded modules */
|
||||
|
||||
ZwFreeVirtualMemory(ProcessHandle,
|
||||
Module->Base,
|
||||
0,
|
||||
MEM_RELEASE);
|
||||
ExFreePool(DosHeader);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
RelocationRVA += RelocationDir->SizeOfBlock;
|
||||
RelocationDir = (PRELOCATION_DIRECTORY)((PCHAR)Module->Base +
|
||||
RelocationRVA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Create the stack for the process */
|
||||
/* FIXME: Setup the context for the initial thread */
|
||||
/* FIXME: Create the initial thread */
|
||||
|
||||
// fail: ZwFreeVirtualMemory(ProcessHandle, Module->ImageBase, 0, MEM_RELEASE);
|
||||
ExFreePool(DosHeader);
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
LdrProcessBinImage(HANDLE ProcessHandle,
|
||||
HANDLE ModuleHandle,
|
||||
HANDLE FileHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
ULONG SectionSize;
|
||||
HANDLE ThreadHandle;
|
||||
CONTEXT Context;
|
||||
HANDLE SectionHandle;
|
||||
PVOID BaseAddress;
|
||||
|
||||
/* FIXME: should set module pointers */
|
||||
|
||||
/* Get the size of the file for the section */
|
||||
Status = ZwQueryInformationFile(FileHandle,
|
||||
NULL,
|
||||
&FileStdInfo,
|
||||
sizeof(FileStdInfo),
|
||||
FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the section for the code */
|
||||
Status = ZwCreateSection(&SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
MEM_COMMIT,
|
||||
FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map a view of the section into the desired process */
|
||||
BaseAddress = (PVOID)0x10000;
|
||||
SectionSize = GET_LARGE_INTEGER_LOW_PART(FileStdInfo.AllocationSize);
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
SectionSize,
|
||||
NULL,
|
||||
&SectionSize,
|
||||
0,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: destroy the section here */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Setup the context for the initial thread */
|
||||
memset(&Context,0,sizeof(CONTEXT));
|
||||
Context.SegSs = USER_DS;
|
||||
Context.Esp = 0x2000;
|
||||
Context.EFlags = 0x202;
|
||||
Context.SegCs = USER_CS;
|
||||
Context.Eip = 0x10000;
|
||||
Context.SegDs = USER_DS;
|
||||
Context.SegEs = USER_DS;
|
||||
Context.SegFs = USER_DS;
|
||||
Context.SegGs = USER_DS;
|
||||
|
||||
/* Create the stack for the process */
|
||||
BaseAddress = (PVOID) 0x1000;
|
||||
SectionSize = 0x1000;
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&SectionSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: unmap the section here */
|
||||
/* FIXME: destroy the section here */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create the initial thread */
|
||||
Status = ZwCreateThread(&ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
ProcessHandle,
|
||||
NULL,
|
||||
&Context,
|
||||
NULL,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: destroy the stack memory block here */
|
||||
/* FIXME: unmap the section here */
|
||||
/* FIXME: destroy the section here */
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -89,6 +89,9 @@ objects/tst.o: $(TST_OBJECTS)
|
|||
objects/dbg.o: $(DBG_OBJECTS)
|
||||
$(LD) -r $(DBG_OBJECTS) -o objects/dbg.o
|
||||
|
||||
objects/ldr.o: $(LDR_OBJECTS)
|
||||
$(LD) -r $(LDR_OBJECTS) -o objects/ldr.o
|
||||
|
||||
objects/nt.o: $(NT_OBJECTS)
|
||||
$(LD) -r $(NT_OBJECTS) -o objects/nt.o
|
||||
|
||||
|
@ -98,8 +101,7 @@ objects/cc.o: $(CC_OBJECTS)
|
|||
OBJECTS = objects/hal.o objects/ke.o objects/rtl.o objects/mm.o \
|
||||
objects/io.o objects/ob.o objects/ps.o objects/ex.o \
|
||||
objects/se.o objects/cm.o objects/tst.o objects/dbg.o\
|
||||
objects/nt.o objects/cc.o
|
||||
|
||||
objects/nt.o objects/cc.o objects/ldr.o
|
||||
|
||||
utils/export/export$(EXE_POSTFIX): utils/export/export.c
|
||||
$(NATIVE_CC) -g utils/export/export.c -o utils/export/export$(EXE_POSTFIX)
|
||||
|
|
|
@ -411,8 +411,9 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process,
|
|||
{
|
||||
for (i=0;i<=(MemoryArea->Length/PAGESIZE);i++)
|
||||
{
|
||||
free_page(MmGetPhysicalAddress(MemoryArea->BaseAddress+
|
||||
(i*PAGESIZE)).LowPart,1);
|
||||
free_page(GET_LARGE_INTEGER_LOW_PART(
|
||||
MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE))),
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
|||
{
|
||||
DPRINT("Writing %x with physical address %x\n",
|
||||
base+(i*PAGESIZE),mdl_pages[i]);
|
||||
set_page(base+(i*PAGESIZE),PA_READ + PA_SYSTEM,mdl_pages[i]);
|
||||
set_page((DWORD)base+(i*PAGESIZE),PA_READ + PA_SYSTEM,mdl_pages[i]);
|
||||
}
|
||||
DPRINT("base %x\n",base);
|
||||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
||||
|
@ -143,7 +143,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
|||
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
|
||||
{
|
||||
Address = Mdl->StartVa + (i*PAGESIZE);
|
||||
mdl_pages[i]=MmGetPhysicalAddress(Address).LowPart;
|
||||
mdl_pages[i] = GET_LARGE_INTEGER_LOW_PART(MmGetPhysicalAddress(Address));
|
||||
DPRINT("mdl_pages[i] %x\n",mdl_pages[i]);
|
||||
}
|
||||
}
|
||||
|
@ -220,8 +220,8 @@ VOID MmBuildMdlForNonPagedPool(PMDL Mdl)
|
|||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_SOURCE_IS_NONPAGED_POOL;
|
||||
for (va=0; va<Mdl->Size; va++)
|
||||
{
|
||||
((PULONG)(Mdl + 1))[va] = MmGetPhysicalAddress(
|
||||
Mdl->StartVa+ (va * PAGESIZE)).LowPart;
|
||||
((PULONG)(Mdl + 1))[va] = GET_LARGE_INTEGER_LOW_PART(
|
||||
MmGetPhysicalAddress(Mdl->StartVa + (va * PAGESIZE)));
|
||||
}
|
||||
Mdl->MappedSystemVa = Mdl->StartVa;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/pool.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
|
|
@ -117,8 +117,7 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle,
|
|||
}
|
||||
else
|
||||
{
|
||||
Section->MaximumSize.HighPart = 0;
|
||||
Section->MaximumSize.LowPart = 0xffffffff;
|
||||
LARGE_INTEGER_QUAD_PART(Section->MaximumSize) = 0xffffffff;
|
||||
}
|
||||
Section->SectionPageProtection = SectionPageProtection;
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
|
@ -258,9 +257,9 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
|
|||
return(Status);
|
||||
}
|
||||
|
||||
if ((*ViewSize) > Section->MaximumSize.LowPart)
|
||||
if ((*ViewSize) > GET_LARGE_INTEGER_LOW_PART(Section->MaximumSize))
|
||||
{
|
||||
(*ViewSize) = Section->MaximumSize.LowPart;
|
||||
(*ViewSize) = GET_LARGE_INTEGER_LOW_PART(Section->MaximumSize);
|
||||
}
|
||||
|
||||
MmCreateMemoryArea(UserMode,
|
||||
|
@ -271,7 +270,7 @@ NTSTATUS ZwMapViewOfSection(HANDLE SectionHandle,
|
|||
Protect,
|
||||
&Result);
|
||||
Result->Data.SectionData.Section = Section;
|
||||
Result->Data.SectionData.ViewOffset = SectionOffset->LowPart;
|
||||
Result->Data.SectionData.ViewOffset = GET_LARGE_INTEGER_LOW_PART(*SectionOffset);
|
||||
|
||||
DPRINT("*BaseAddress %x\n",*BaseAddress);
|
||||
DPRINT("Result->Data.SectionData.Section->FileObject %x\n",
|
||||
|
|
|
@ -89,7 +89,9 @@ PVOID MmMapIoSpace(PHYSICAL_ADDRESS PhysicalAddress,
|
|||
}
|
||||
for (i=0;i<=(NumberOfBytes/PAGESIZE);i++)
|
||||
{
|
||||
set_page(Result+(i*PAGESIZE),Attributes,PhysicalAddress.LowPart);
|
||||
set_page(Result + (i * PAGESIZE),
|
||||
Attributes,
|
||||
GET_LARGE_INTEGER_LOW_PART(PhysicalAddress));
|
||||
}
|
||||
return((PVOID)Result);
|
||||
}
|
||||
|
|
|
@ -107,9 +107,9 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
|
|||
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
|
||||
MemoryArea,Address);
|
||||
|
||||
set_page(Address,0x7,get_free_page());
|
||||
set_page((DWORD)Address,0x7,get_free_page());
|
||||
|
||||
Offset.LowPart = (Address - MemoryArea->BaseAddress) +
|
||||
LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) +
|
||||
MemoryArea->Data.SectionData.ViewOffset;
|
||||
|
||||
DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
|
||||
|
@ -193,7 +193,7 @@ asmlinkage int page_fault_handler(unsigned int cs,
|
|||
break;
|
||||
|
||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||
if (MmSectionHandleFault(MemoryArea,cr2)==STATUS_SUCCESS)
|
||||
if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
|
||||
{
|
||||
stat=1;
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
|
|||
|
||||
for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
|
||||
{
|
||||
CurrentEntry = MmGetPageEntry(Process, BaseAddress + (i*PAGESIZE));
|
||||
CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
|
||||
RtlCopyMemory(Buffer + (i*PAGESIZE),
|
||||
(PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
|
||||
PAGESIZE);
|
||||
|
@ -735,7 +735,7 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
|
||||
for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)
|
||||
{
|
||||
CurrentEntry = MmGetPageEntry(Process, BaseAddress + (i*PAGESIZE));
|
||||
CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
|
||||
RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
|
||||
Buffer + (i*PAGESIZE),
|
||||
PAGESIZE);
|
||||
|
|
|
@ -162,7 +162,7 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
|
|||
}
|
||||
|
||||
ObLookupObject(ObjectAttributes->RootDirectory,path,
|
||||
&hdr->Parent,&Ignored);
|
||||
&hdr->Parent,&Ignored, 0L);
|
||||
|
||||
/*
|
||||
* Initialize the object header
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <internal/mm.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
|
|
@ -131,7 +131,7 @@ VOID PsDispatchThread(VOID)
|
|||
{
|
||||
DPRINT("Scheduling current thread\n");
|
||||
KeQueryTickCount(&TickCount);
|
||||
CurrentThread->Tcb.LastTick = TickCount.LowPart;
|
||||
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
|
||||
CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||
KeReleaseSpinLock(&ThreadListLock,irql);
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
|
@ -144,7 +144,7 @@ VOID PsDispatchThread(VOID)
|
|||
Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
|
||||
|
||||
KeQueryTickCount(&TickCount);
|
||||
CurrentThread->Tcb.LastTick = TickCount.LowPart;
|
||||
CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
|
||||
|
||||
CurrentThread = Candidate;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <internal/ctype.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
unsigned long result = 0,value;
|
||||
|
@ -117,13 +119,14 @@ static char * number(char * str, long num, int base, int size, int precision
|
|||
*str++ = ' ';
|
||||
if (sign)
|
||||
*str++ = sign;
|
||||
if (type & SPECIAL)
|
||||
if (base==8)
|
||||
if (type & SPECIAL) {
|
||||
if (base==8) {
|
||||
*str++ = '0';
|
||||
else if (base==16) {
|
||||
} else if (base==16) {
|
||||
*str++ = '0';
|
||||
*str++ = digits[33];
|
||||
}
|
||||
}
|
||||
if (!(type & LEFT))
|
||||
while (size-- > 0)
|
||||
*str++ = c;
|
||||
|
@ -143,7 +146,8 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
|||
int i, base;
|
||||
char * str;
|
||||
const char *s;
|
||||
const short int* sw;
|
||||
const short int *sw;
|
||||
PUNICODE_STRING pus;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
|
@ -243,6 +247,25 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
|||
// CHECKPOINT;
|
||||
continue;
|
||||
|
||||
case 'W':
|
||||
pus = va_arg(args, PUNICODE_STRING);
|
||||
if (pus == NULL || pus->Length > pus->MaximumLength)
|
||||
{
|
||||
s = "<NULL>";
|
||||
while ((*s) != 0)
|
||||
{
|
||||
*str++ = *s++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < pus->Length; i++)
|
||||
{
|
||||
*str++ = (char)(pus->Buffer[i]);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
|
@ -310,17 +333,19 @@ int vsprintf(char *buf, const char *fmt, va_list args)
|
|||
--fmt;
|
||||
continue;
|
||||
}
|
||||
if (qualifier == 'l')
|
||||
if (qualifier == 'l') {
|
||||
num = va_arg(args, unsigned long);
|
||||
else if (qualifier == 'h')
|
||||
if (flags & SIGN)
|
||||
} else if (qualifier == 'h') {
|
||||
if (flags & SIGN) {
|
||||
num = va_arg(args, short);
|
||||
else
|
||||
} else {
|
||||
num = va_arg(args, unsigned short);
|
||||
else if (flags & SIGN)
|
||||
}
|
||||
} else if (flags & SIGN) {
|
||||
num = va_arg(args, int);
|
||||
else
|
||||
} else {
|
||||
num = va_arg(args, unsigned int);
|
||||
}
|
||||
str = number(str, num, base, field_width, precision, flags);
|
||||
}
|
||||
*str = '\0';
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <internal/string.h>
|
||||
#include <internal/ctype.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
int ShellChangeDir(char* args);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <internal/i386/segment.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include <in.h>
|
||||
|
@ -531,8 +531,24 @@ TstTimer(void)
|
|||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void TstDriverLoad(void)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DriverName;
|
||||
|
||||
INIT_UNICODE_STRING(DriverName, "C:\\reactos\\system\\keyboard.o");
|
||||
Status = LdrLoadDriver(DriverName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("driver load failed, status;%d(%x)\n", Status, Status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void TstBegin()
|
||||
{
|
||||
// TstDriverLoad();
|
||||
ExExecuteShell();
|
||||
// TstFileRead();
|
||||
// TstGeneralWrite();
|
||||
|
|
|
@ -63,7 +63,7 @@ else
|
|||
DEBUGGING_CFLAGS =
|
||||
endif
|
||||
|
||||
DEFINES = -DDBG -DCHECKED
|
||||
DEFINES = -DDBG -DCHECKED # -DCOMPILER_LARGE_INTEGERS
|
||||
|
||||
ifeq ($(WIN32_LEAN_AND_MEAN),yes)
|
||||
LEAN_AND_MEAN_DEFINE = -DWIN32_LEAN_AND_MEAN
|
||||
|
|
Loading…
Reference in a new issue