Fixed several bugs

Commented out code that wouldn't compile in lib/crtdll
Began removed memory and file leaks

svn path=/trunk/; revision=170
This commit is contained in:
David Welch 1999-01-16 21:03:00 +00:00
parent 73d2af04d9
commit c2059de8af
47 changed files with 5307 additions and 5390 deletions

View file

@ -1,10 +1,10 @@
#include <ddk/ntddk.h>
#include <stdarg.h>
#include <string.h>
void main()
{
NtDisplayString("Hello world\n");
ExitProcess(0);
}
#include <ddk/ntddk.h>
#include <stdarg.h>
#include <string.h>
void main()
{
NtDisplayString("Hello world\n");
ExitProcess(0);
}

View file

@ -1,154 +1,154 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/blockdev.c
* PURPOSE: Temporary sector reading support
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
int j;
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
(unsigned long) DiskSector,
(unsigned long) BLOCKSIZE,
(unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
(unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("READ failed!!!\n");
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(%x)\n", status, status);
return FALSE;
}
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);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("WRITE failed!!!\n");
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(%x)\n", status, status);
return FALSE;
}
ExFreePool(mbr);
DPRINT("Block request succeeded\n");
return TRUE;
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/blockdev.c
* PURPOSE: Temporary sector reading support
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer)
{
LARGE_INTEGER sectorNumber;
PIRP irp;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
NTSTATUS status;
ULONG sectorSize;
int j;
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
pDeviceObject,DiskSector,Buffer);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
(unsigned long) DiskSector,
(unsigned long) BLOCKSIZE,
(unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
(unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("READ failed!!!\n");
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(%x)\n", status, status);
return FALSE;
}
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);
SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
KeInitializeEvent(&event, NotificationEvent, FALSE);
sectorSize = BLOCKSIZE*SectorCount;
DPRINT("Building synchronous FSD Request...\n");
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
pDeviceObject,
Buffer,
sectorSize,
&sectorNumber,
&event,
&ioStatus );
if (!irp) {
DbgPrint("WRITE failed!!!\n");
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(%x)\n", status, status);
return FALSE;
}
ExFreePool(mbr);
DPRINT("Block request succeeded\n");
return TRUE;
}

View file

@ -1,300 +1,300 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#include <wstring.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS *****************************************************************/
VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
{
ULONG i;
for (i=0; i<Len; i++)
{
*Out = *In;
Out++;
In++;
}
*Out = 0;
}
PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,
struct ext2_dir_entry* dir_entry,
PIO_STACK_LOCATION IoStack,
PVOID Buffer,
ULONG FileIndex)
{
PFILE_DIRECTORY_INFORMATION FDI;
PFILE_NAMES_INFORMATION FNI;
ULONG i;
PWSTR FileName;
struct ext2_inode inode;
Ext2ReadInode(DeviceExt,
dir_entry->inode,
&inode);
switch (IoStack->Parameters.QueryDirectory.FileInformationClass)
{
case FileNamesInformation:
FNI = (PFILE_NAMES_INFORMATION)Buffer;
FNI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FNI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FNI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FNI->NextEntryOffset;
break;
case FileDirectoryInformation:
FDI = (PFILE_DIRECTORY_INFORMATION)Buffer;
FDI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FDI->FileIndex = FileIndex;
// FDI->CreationTime = 0;
// FDI->LastAccessTime = 0;
// FDI->LastWriteTime = 0;
// FDI->ChangeTime = 0;
FDI->AllocationSize = FDI->EndOfFile = inode.i_size;
FDI->FileAttributes = 0;
FDI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FDI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FDI->NextEntryOffset;
break;
default:
UNIMPLEMENTED;
}
return(Buffer);
}
NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,
PEXT2_FCB Fcb,
PIRP Irp,
PIO_STACK_LOCATION IoStack)
{
ULONG Max;
ULONG i;
ULONG StartIndex;
PVOID Buffer;
struct ext2_dir_entry dir_entry;
ULONG CurrentIndex;
Buffer = Irp->UserBuffer;
if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)
{
Max = 1;
}
else
{
UNIMPLEMENTED;
}
if (IoStack->Flags & SL_INDEX_SPECIFIED)
{
StartIndex = ((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex;
}
else
{
StartIndex = 0;
}
if (IoStack->Flags & SL_RESTART_SCAN)
{
StartIndex = 0;
}
for (i=0; i<Max ;i++)
{
if (!Ext2ScanDir(DeviceExt,&Fcb->inode,"*",&dir_entry,&StartIndex))
{
((PFILE_DIRECTORY_INFORMATION)Buffer)->NextEntryOffset = 0;
return(STATUS_NO_MORE_FILES);
}
Buffer = Ext2ProcessDirEntry(DeviceExt,
&dir_entry,
IoStack,
Buffer,
StartIndex);
}
}
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PEXT2_FCB Fcb = (PVOID)FileObject->FsContext;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2DirectoryControl(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
switch (Stack->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
Status = Ext2QueryDirectory(DeviceExt, Fcb, Irp, Stack);
break;
default:
Status = STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* dir,
PCH filename,
struct ext2_dir_entry* ret,
PULONG StartIndex)
{
ULONG i;
char* buffer;
ULONG offset;
char name[255];
struct ext2_dir_entry* current;
ULONG block;
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);
for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
{
DPRINT("block %d\n",block);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
buffer);
offset = (*StartIndex)%BLOCKSIZE;
while (offset < BLOCKSIZE)
{
current = &buffer[offset];
strncpy(name,current->name,current->name_len);
name[current->name_len]=0;
DPRINT("Scanning offset %d inode %d name %s\n",
offset,current->inode,name);
DPRINT("Comparing %s %s\n",name,filename);
if (strcmp(name,filename)==0 || strcmp(filename,"*")==0)
{
DPRINT("Match found\n");
*StartIndex = (i*BLOCKSIZE) + offset + current->rec_len;
memcpy(ret,current,sizeof(struct ext2_dir_entry));
ExFreePool(buffer);
return(TRUE);
}
offset = offset + current->rec_len;
assert(current->rec_len != 0);
DPRINT("offset %d\n",offset);
}
DPRINT("Onto next block\n");
}
DPRINT("No match\n");
ExFreePool(buffer);
return(FALSE);
}
void unicode_to_ansi(PCH StringA, PWSTR StringW)
{
while((*StringW)!=0)
{
*StringA = *StringW;
StringA++;
StringW++;
}
*StringA = 0;
}
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
{
struct ext2_inode parent_inode;
struct ext2_dir_entry entry;
char name[255];
ULONG current_inode = 2;
char* current_segment;
PEXT2_FCB Fcb;
ULONG StartIndex = 0;
DPRINT("Ext2OpenFile(DeviceExt %x, FileObject %x, FileName %w)\n",
DeviceExt,FileObject,FileName);
Fcb = ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
unicode_to_ansi(name,FileName);
DbgPrint("name %s\n",name);
current_segment = strtok(name,"\\");
do
{
Ext2ReadInode(DeviceExt,
current_inode,
&parent_inode);
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
&StartIndex))
{
ExFreePool(Fcb);
return(STATUS_UNSUCCESSFUL);
}
current_inode = entry.inode;
current_segment = strtok(NULL,"\\");
} while(current_segment!=NULL);
DPRINT("Found file\n");
Ext2ReadInode(DeviceExt,
current_inode,
&Fcb->inode);
FileObject->FsContext = Fcb;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2Create(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
Status = Ext2OpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#include <wstring.h>
#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* FUNCTIONS *****************************************************************/
VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
{
ULONG i;
for (i=0; i<Len; i++)
{
*Out = *In;
Out++;
In++;
}
*Out = 0;
}
PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,
struct ext2_dir_entry* dir_entry,
PIO_STACK_LOCATION IoStack,
PVOID Buffer,
ULONG FileIndex)
{
PFILE_DIRECTORY_INFORMATION FDI;
PFILE_NAMES_INFORMATION FNI;
ULONG i;
PWSTR FileName;
struct ext2_inode inode;
Ext2ReadInode(DeviceExt,
dir_entry->inode,
&inode);
switch (IoStack->Parameters.QueryDirectory.FileInformationClass)
{
case FileNamesInformation:
FNI = (PFILE_NAMES_INFORMATION)Buffer;
FNI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FNI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FNI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FNI->NextEntryOffset;
break;
case FileDirectoryInformation:
FDI = (PFILE_DIRECTORY_INFORMATION)Buffer;
FDI->NextEntryOffset = sizeof(FileDirectoryInformation) +
dir_entry->name_len + 1;
FDI->FileIndex = FileIndex;
// FDI->CreationTime = 0;
// FDI->LastAccessTime = 0;
// FDI->LastWriteTime = 0;
// FDI->ChangeTime = 0;
FDI->AllocationSize = FDI->EndOfFile = inode.i_size;
FDI->FileAttributes = 0;
FDI->FileNameLength = dir_entry->name_len;
Ext2ConvertName(FDI->FileName, dir_entry->name, dir_entry->name_len);
Buffer = Buffer + FDI->NextEntryOffset;
break;
default:
UNIMPLEMENTED;
}
return(Buffer);
}
NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,
PEXT2_FCB Fcb,
PIRP Irp,
PIO_STACK_LOCATION IoStack)
{
ULONG Max;
ULONG i;
ULONG StartIndex;
PVOID Buffer;
struct ext2_dir_entry dir_entry;
ULONG CurrentIndex;
Buffer = Irp->UserBuffer;
if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)
{
Max = 1;
}
else
{
UNIMPLEMENTED;
}
if (IoStack->Flags & SL_INDEX_SPECIFIED)
{
StartIndex = ((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex;
}
else
{
StartIndex = 0;
}
if (IoStack->Flags & SL_RESTART_SCAN)
{
StartIndex = 0;
}
for (i=0; i<Max ;i++)
{
if (!Ext2ScanDir(DeviceExt,&Fcb->inode,"*",&dir_entry,&StartIndex))
{
((PFILE_DIRECTORY_INFORMATION)Buffer)->NextEntryOffset = 0;
return(STATUS_NO_MORE_FILES);
}
Buffer = Ext2ProcessDirEntry(DeviceExt,
&dir_entry,
IoStack,
Buffer,
StartIndex);
}
}
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PEXT2_FCB Fcb = (PVOID)FileObject->FsContext;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2DirectoryControl(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
switch (Stack->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
Status = Ext2QueryDirectory(DeviceExt, Fcb, Irp, Stack);
break;
default:
Status = STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* dir,
PCH filename,
struct ext2_dir_entry* ret,
PULONG StartIndex)
{
ULONG i;
char* buffer;
ULONG offset;
char name[255];
struct ext2_dir_entry* current;
ULONG block;
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);
for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
{
DPRINT("block %d\n",block);
Ext2ReadSectors(DeviceExt->StorageDevice,
block,
1,
buffer);
offset = (*StartIndex)%BLOCKSIZE;
while (offset < BLOCKSIZE)
{
current = &buffer[offset];
strncpy(name,current->name,current->name_len);
name[current->name_len]=0;
DPRINT("Scanning offset %d inode %d name %s\n",
offset,current->inode,name);
DPRINT("Comparing %s %s\n",name,filename);
if (strcmp(name,filename)==0 || strcmp(filename,"*")==0)
{
DPRINT("Match found\n");
*StartIndex = (i*BLOCKSIZE) + offset + current->rec_len;
memcpy(ret,current,sizeof(struct ext2_dir_entry));
ExFreePool(buffer);
return(TRUE);
}
offset = offset + current->rec_len;
assert(current->rec_len != 0);
DPRINT("offset %d\n",offset);
}
DPRINT("Onto next block\n");
}
DPRINT("No match\n");
ExFreePool(buffer);
return(FALSE);
}
void unicode_to_ansi(PCH StringA, PWSTR StringW)
{
while((*StringW)!=0)
{
*StringA = *StringW;
StringA++;
StringW++;
}
*StringA = 0;
}
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
{
struct ext2_inode parent_inode;
struct ext2_dir_entry entry;
char name[255];
ULONG current_inode = 2;
char* current_segment;
PEXT2_FCB Fcb;
ULONG StartIndex = 0;
DPRINT("Ext2OpenFile(DeviceExt %x, FileObject %x, FileName %w)\n",
DeviceExt,FileObject,FileName);
Fcb = ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
unicode_to_ansi(name,FileName);
DbgPrint("name %s\n",name);
current_segment = strtok(name,"\\");
do
{
Ext2ReadInode(DeviceExt,
current_inode,
&parent_inode);
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
&StartIndex))
{
ExFreePool(Fcb);
return(STATUS_UNSUCCESSFUL);
}
current_inode = entry.inode;
current_segment = strtok(NULL,"\\");
} while(current_segment!=NULL);
DPRINT("Found file\n");
Ext2ReadInode(DeviceExt,
current_inode,
&Fcb->inode);
FileObject->FsContext = Fcb;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DPRINT("Ext2Create(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
Status = Ext2OpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}

View file

@ -1,242 +1,242 @@
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer);
#define BLOCKSIZE (1024)
struct ext2_super_block {
ULONG s_inodes_count; /* Inodes count */
ULONG s_blocks_count; /* Blocks count */
ULONG s_r_blocks_count; /* Reserved blocks count */
ULONG s_free_blocks_count; /* Free blocks count */
ULONG s_free_inodes_count; /* Free inodes count */
ULONG s_first_data_block; /* First Data Block */
ULONG s_log_block_size; /* Block size */
LONG s_log_frag_size; /* Fragment size */
ULONG s_blocks_per_group; /* # Blocks per group */
ULONG s_frags_per_group; /* # Fragments per group */
ULONG s_inodes_per_group; /* # Inodes per group */
ULONG s_mtime; /* Mount time */
ULONG s_wtime; /* Write time */
USHORT s_mnt_count; /* Mount count */
SHORT s_max_mnt_count; /* Maximal mount count */
USHORT s_magic; /* Magic signature */
USHORT s_state; /* File system state */
USHORT s_errors; /* Behaviour when detecting errors */
USHORT s_minor_rev_level; /* minor revision level */
ULONG s_lastcheck; /* time of last check */
ULONG s_checkinterval; /* max. time between checks */
ULONG s_creator_os; /* OS */
ULONG s_rev_level; /* Revision level */
USHORT s_def_resuid; /* Default uid for reserved blocks */
USHORT s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
ULONG s_first_ino; /* First non-reserved inode */
USHORT s_inode_size; /* size of inode structure */
USHORT s_block_group_nr; /* block group # of this superblock */
ULONG s_feature_compat; /* compatible feature set */
ULONG s_feature_incompat; /* incompatible feature set */
ULONG s_feature_ro_compat; /* readonly-compatible feature set */
ULONG s_reserved[230]; /* Padding to the end of the block */
};
/*
* Codes for operating systems
*/
#define EXT2_OS_LINUX 0
#define EXT2_OS_HURD 1
#define EXT2_OS_MASIX 2
#define EXT2_OS_FREEBSD 3
#define EXT2_OS_LITES 4
/*
* Revision levels
*/
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
/*
* The second extended file system magic number
*/
#define EXT2_SUPER_MAGIC 0xEF53
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
USHORT i_mode; /* File mode */
USHORT i_uid; /* Owner Uid */
ULONG i_size; /* Size in bytes */
ULONG i_atime; /* Access time */
ULONG i_ctime; /* Creation time */
ULONG i_mtime; /* Modification time */
ULONG i_dtime; /* Deletion Time */
USHORT i_gid; /* Group Id */
USHORT i_links_count; /* Links count */
ULONG i_blocks; /* Blocks count */
ULONG i_flags; /* File flags */
union {
struct {
ULONG l_i_reserved1;
} linux1;
struct {
ULONG h_i_translator;
} hurd1;
struct {
ULONG m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
ULONG i_version; /* File version (for NFS) */
ULONG i_file_acl; /* File ACL */
ULONG i_dir_acl; /* Directory ACL */
ULONG i_faddr; /* Fragment address */
union {
struct {
UCHAR l_i_frag; /* Fragment number */
UCHAR l_i_fsize; /* Fragment size */
USHORT i_pad1;
ULONG l_i_reserved2[2];
} linux2;
struct {
UCHAR h_i_frag; /* Fragment number */
UCHAR h_i_fsize; /* Fragment size */
USHORT h_i_mode_high;
USHORT h_i_uid_high;
USHORT h_i_gid_high;
ULONG h_i_author;
} hurd2;
struct {
UCHAR m_i_frag; /* Fragment number */
UCHAR m_i_fsize; /* Fragment size */
USHORT m_pad1;
ULONG m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
#define i_fsize osd2.linux2.l_i_fsize
#define i_reserved2 osd2.linux2.l_i_reserved2
#endif
#ifdef __hurd__
#define i_translator osd1.hurd1.h_i_translator
#define i_frag osd2.hurd2.h_i_frag;
#define i_fsize osd2.hurd2.h_i_fsize;
#define i_uid_high osd2.hurd2.h_i_uid_high
#define i_gid_high osd2.hurd2.h_i_gid_high
#define i_author osd2.hurd2.h_i_author
#endif
#ifdef __masix__
#define i_reserved1 osd1.masix1.m_i_reserved1
#define i_frag osd2.masix2.m_i_frag
#define i_fsize osd2.masix2.m_i_fsize
#define i_reserved2 osd2.masix2.m_i_reserved2
#endif
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Inode flags
*/
#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
#define EXT2_UNRM_FL 0x00000002 /* Undelete */
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
/*
* Structure of a blocks group descriptor
*/
struct ext2_group_desc
{
ULONG bg_block_bitmap; /* Blocks bitmap block */
ULONG bg_inode_bitmap; /* Inodes bitmap block */
ULONG bg_inode_table; /* Inodes table block */
USHORT bg_free_blocks_count; /* Free blocks count */
USHORT bg_free_inodes_count; /* Free inodes count */
USHORT bg_used_dirs_count; /* Directories count */
USHORT bg_pad;
ULONG bg_reserved[3];
};
#define EXT2_NAME_LEN 255
struct ext2_dir_entry {
ULONG inode; /* Inode number */
USHORT rec_len; /* Directory entry length */
USHORT name_len; /* Name length */
char name[EXT2_NAME_LEN]; /* File name */
};
typedef struct
{
PDEVICE_OBJECT StorageDevice;
struct ext2_super_block* superblock;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode);
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group);
typedef struct _EXT2_FCB
{
struct ext2_inode inode;
} EXT2_FCB, *PEXT2_FCB;
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* inode,
ULONG offset);
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName);
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
LARGE_INTEGER Offset);
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN PVOID Buffer);
#define BLOCKSIZE (1024)
struct ext2_super_block {
ULONG s_inodes_count; /* Inodes count */
ULONG s_blocks_count; /* Blocks count */
ULONG s_r_blocks_count; /* Reserved blocks count */
ULONG s_free_blocks_count; /* Free blocks count */
ULONG s_free_inodes_count; /* Free inodes count */
ULONG s_first_data_block; /* First Data Block */
ULONG s_log_block_size; /* Block size */
LONG s_log_frag_size; /* Fragment size */
ULONG s_blocks_per_group; /* # Blocks per group */
ULONG s_frags_per_group; /* # Fragments per group */
ULONG s_inodes_per_group; /* # Inodes per group */
ULONG s_mtime; /* Mount time */
ULONG s_wtime; /* Write time */
USHORT s_mnt_count; /* Mount count */
SHORT s_max_mnt_count; /* Maximal mount count */
USHORT s_magic; /* Magic signature */
USHORT s_state; /* File system state */
USHORT s_errors; /* Behaviour when detecting errors */
USHORT s_minor_rev_level; /* minor revision level */
ULONG s_lastcheck; /* time of last check */
ULONG s_checkinterval; /* max. time between checks */
ULONG s_creator_os; /* OS */
ULONG s_rev_level; /* Revision level */
USHORT s_def_resuid; /* Default uid for reserved blocks */
USHORT s_def_resgid; /* Default gid for reserved blocks */
/*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
ULONG s_first_ino; /* First non-reserved inode */
USHORT s_inode_size; /* size of inode structure */
USHORT s_block_group_nr; /* block group # of this superblock */
ULONG s_feature_compat; /* compatible feature set */
ULONG s_feature_incompat; /* incompatible feature set */
ULONG s_feature_ro_compat; /* readonly-compatible feature set */
ULONG s_reserved[230]; /* Padding to the end of the block */
};
/*
* Codes for operating systems
*/
#define EXT2_OS_LINUX 0
#define EXT2_OS_HURD 1
#define EXT2_OS_MASIX 2
#define EXT2_OS_FREEBSD 3
#define EXT2_OS_LITES 4
/*
* Revision levels
*/
#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
/*
* The second extended file system magic number
*/
#define EXT2_SUPER_MAGIC 0xEF53
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
USHORT i_mode; /* File mode */
USHORT i_uid; /* Owner Uid */
ULONG i_size; /* Size in bytes */
ULONG i_atime; /* Access time */
ULONG i_ctime; /* Creation time */
ULONG i_mtime; /* Modification time */
ULONG i_dtime; /* Deletion Time */
USHORT i_gid; /* Group Id */
USHORT i_links_count; /* Links count */
ULONG i_blocks; /* Blocks count */
ULONG i_flags; /* File flags */
union {
struct {
ULONG l_i_reserved1;
} linux1;
struct {
ULONG h_i_translator;
} hurd1;
struct {
ULONG m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
ULONG i_version; /* File version (for NFS) */
ULONG i_file_acl; /* File ACL */
ULONG i_dir_acl; /* Directory ACL */
ULONG i_faddr; /* Fragment address */
union {
struct {
UCHAR l_i_frag; /* Fragment number */
UCHAR l_i_fsize; /* Fragment size */
USHORT i_pad1;
ULONG l_i_reserved2[2];
} linux2;
struct {
UCHAR h_i_frag; /* Fragment number */
UCHAR h_i_fsize; /* Fragment size */
USHORT h_i_mode_high;
USHORT h_i_uid_high;
USHORT h_i_gid_high;
ULONG h_i_author;
} hurd2;
struct {
UCHAR m_i_frag; /* Fragment number */
UCHAR m_i_fsize; /* Fragment size */
USHORT m_pad1;
ULONG m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
#define i_frag osd2.linux2.l_i_frag
#define i_fsize osd2.linux2.l_i_fsize
#define i_reserved2 osd2.linux2.l_i_reserved2
#endif
#ifdef __hurd__
#define i_translator osd1.hurd1.h_i_translator
#define i_frag osd2.hurd2.h_i_frag;
#define i_fsize osd2.hurd2.h_i_fsize;
#define i_uid_high osd2.hurd2.h_i_uid_high
#define i_gid_high osd2.hurd2.h_i_gid_high
#define i_author osd2.hurd2.h_i_author
#endif
#ifdef __masix__
#define i_reserved1 osd1.masix1.m_i_reserved1
#define i_frag osd2.masix2.m_i_frag
#define i_fsize osd2.masix2.m_i_fsize
#define i_reserved2 osd2.masix2.m_i_reserved2
#endif
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
/*
* Inode flags
*/
#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
#define EXT2_UNRM_FL 0x00000002 /* Undelete */
#define EXT2_COMPR_FL 0x00000004 /* Compress file */
#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
/*
* Structure of a blocks group descriptor
*/
struct ext2_group_desc
{
ULONG bg_block_bitmap; /* Blocks bitmap block */
ULONG bg_inode_bitmap; /* Inodes bitmap block */
ULONG bg_inode_table; /* Inodes table block */
USHORT bg_free_blocks_count; /* Free blocks count */
USHORT bg_free_inodes_count; /* Free inodes count */
USHORT bg_used_dirs_count; /* Directories count */
USHORT bg_pad;
ULONG bg_reserved[3];
};
#define EXT2_NAME_LEN 255
struct ext2_dir_entry {
ULONG inode; /* Inode number */
USHORT rec_len; /* Directory entry length */
USHORT name_len; /* Name length */
char name[EXT2_NAME_LEN]; /* File name */
};
typedef struct
{
PDEVICE_OBJECT StorageDevice;
struct ext2_super_block* superblock;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode);
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group);
typedef struct _EXT2_FCB
{
struct ext2_inode inode;
} EXT2_FCB, *PEXT2_FCB;
ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
struct ext2_inode* inode,
ULONG offset);
NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
PWSTR FileName);
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
LARGE_INTEGER Offset);
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);

View file

@ -1,78 +1,78 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/inode.c
* PURPOSE: Manipulating inodes
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 26/12/98: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/debug.h>
#include <string.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group)
{
struct ext2_group_desc* buffer;
ULONG block;
struct ext2_group_desc* gdp;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
block = block_group / (BLOCKSIZE / sizeof(struct ext2_group_desc));
Ext2ReadSectors(DeviceExt->StorageDevice,
2 + block,
1,
buffer);
gdp = &buffer[block_group % (BLOCKSIZE / sizeof(struct ext2_group_desc))];
DPRINT("gdp->bg_free_blocks_count %d\n",gdp->bg_free_blocks_count);
DPRINT("gdp->bg_inode_table %d\n",gdp->bg_inode_table);
return(gdp);
}
#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode)
{
ULONG block_group;
struct ext2_group_desc* gdp;
ULONG offset;
struct ext2_inode* buffer;
DPRINT("Ext2ReadInode(DeviceExt %x, ino %d, inode %x)\n",
DeviceExt,ino,inode);
block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;
gdp = Ext2LoadGroupDesc(DeviceExt, block_group);
offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
Ext2ReadSectors(DeviceExt->StorageDevice,
gdp->bg_inode_table + (offset / INODES_PER_BLOCK),
1,
buffer);
memcpy(inode,&buffer[offset % INODES_PER_BLOCK],sizeof(struct ext2_inode));
DPRINT("inode->i_uid %d\n",inode->i_uid);
DPRINT("inode->i_links_count %d\n",inode->i_links_count);
DPRINT("inode->i_blocks %d\n",inode->i_blocks);
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/inode.c
* PURPOSE: Manipulating inodes
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* 26/12/98: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/debug.h>
#include <string.h>
#include "ext2fs.h"
/* FUNCTIONS ***************************************************************/
struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
ULONG block_group)
{
struct ext2_group_desc* buffer;
ULONG block;
struct ext2_group_desc* gdp;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
block = block_group / (BLOCKSIZE / sizeof(struct ext2_group_desc));
Ext2ReadSectors(DeviceExt->StorageDevice,
2 + block,
1,
buffer);
gdp = &buffer[block_group % (BLOCKSIZE / sizeof(struct ext2_group_desc))];
DPRINT("gdp->bg_free_blocks_count %d\n",gdp->bg_free_blocks_count);
DPRINT("gdp->bg_inode_table %d\n",gdp->bg_inode_table);
return(gdp);
}
#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))
VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
ULONG ino,
struct ext2_inode* inode)
{
ULONG block_group;
struct ext2_group_desc* gdp;
ULONG offset;
struct ext2_inode* buffer;
DPRINT("Ext2ReadInode(DeviceExt %x, ino %d, inode %x)\n",
DeviceExt,ino,inode);
block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;
gdp = Ext2LoadGroupDesc(DeviceExt, block_group);
offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
Ext2ReadSectors(DeviceExt->StorageDevice,
gdp->bg_inode_table + (offset / INODES_PER_BLOCK),
1,
buffer);
memcpy(inode,&buffer[offset % INODES_PER_BLOCK],sizeof(struct ext2_inode));
DPRINT("inode->i_uid %d\n",inode->i_uid);
DPRINT("inode->i_links_count %d\n",inode->i_links_count);
DPRINT("inode->i_blocks %d\n",inode->i_blocks);
}

View file

@ -1,195 +1,195 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#include <wstring.h>
//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* GLOBALS *****************************************************************/
static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
NTSTATUS Ext2CloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
{
}
NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
Status = Ext2CloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP 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;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset;
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_EXTENSION DeviceExt;
PVOID BlockBuffer;
struct ext2_super_block* superblock;
DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);
BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
Ext2ReadSectors(DeviceToMount,
1,
1,
BlockBuffer);
superblock = BlockBuffer;
if (superblock->s_magic != EXT2_SUPER_MAGIC)
{
ExFreePool(BlockBuffer);
return(STATUS_UNRECOGNIZED_VOLUME);
}
DPRINT("Volume recognized\n");
DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);
DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);
IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
DeviceToMount);
DeviceExt->superblock = superblock;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PVPB vpb = Stack->Parameters.Mount.Vpb;
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
NTSTATUS Status;
Status = Ext2Mount(DeviceToMount);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
UNICODE_STRING DeviceNameU;
ANSI_STRING DeviceNameA;
DbgPrint("Ext2 FSD 0.0.1\n");
DriverObject = _DriverObject;
RtlInitAnsiString(&DeviceNameA,"\\Device\\Ext2Fsd");
RtlAnsiStringToUnicodeString(&DeviceNameU,&DeviceNameA,TRUE);
ret = IoCreateDevice(DriverObject,
0,
&DeviceNameU,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;
DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;
DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
Ext2FileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=
Ext2DirectoryControl;
DriverObject->DriverUnload = NULL;
DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n",
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]);
DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL);
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/ext2/super.c
* PURPOSE: ext2 filesystem
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/string.h>
#include <wstring.h>
//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
/* GLOBALS *****************************************************************/
static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
NTSTATUS Ext2CloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
{
}
NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
Status = Ext2CloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP 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;
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset;
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_EXTENSION DeviceExt;
PVOID BlockBuffer;
struct ext2_super_block* superblock;
DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);
BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
Ext2ReadSectors(DeviceToMount,
1,
1,
BlockBuffer);
superblock = BlockBuffer;
if (superblock->s_magic != EXT2_SUPER_MAGIC)
{
ExFreePool(BlockBuffer);
return(STATUS_UNRECOGNIZED_VOLUME);
}
DPRINT("Volume recognized\n");
DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);
DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);
IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
DeviceToMount);
DeviceExt->superblock = superblock;
return(STATUS_SUCCESS);
}
NTSTATUS Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PVPB vpb = Stack->Parameters.Mount.Vpb;
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
NTSTATUS Status;
Status = Ext2Mount(DeviceToMount);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS ret;
UNICODE_STRING DeviceNameU;
ANSI_STRING DeviceNameA;
DbgPrint("Ext2 FSD 0.0.1\n");
DriverObject = _DriverObject;
RtlInitAnsiString(&DeviceNameA,"\\Device\\Ext2Fsd");
RtlAnsiStringToUnicodeString(&DeviceNameU,&DeviceNameA,TRUE);
ret = IoCreateDevice(DriverObject,
0,
&DeviceNameU,
FILE_DEVICE_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (ret!=STATUS_SUCCESS)
{
return(ret);
}
DeviceObject->Flags=0;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;
DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;
DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;
DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
Ext2FileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=
Ext2DirectoryControl;
DriverObject->DriverUnload = NULL;
DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n",
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]);
DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL);
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
}

View file

@ -1274,8 +1274,8 @@ NTSTATUS FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Stack = IoGetCurrentIrpStackLocation(Irp);
RequestedDisposition = ((Stack->Parameters.Create.Options>>24)&0xff);
RequestedOptions=Stack->Parameters.Create.Options&FILE_VALID_OPTION_FLAGS;
DbgPrint("CROptions=%x\n",Stack->Parameters.Create.Options);
DbgPrint("REquestedOptions=%x\n",RequestedOptions);
DPRINT("CROptions=%x\n",Stack->Parameters.Create.Options);
DPRINT("REquestedOptions=%x\n",RequestedOptions);
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
@ -1285,7 +1285,7 @@ DbgPrint("REquestedOptions=%x\n",RequestedOptions);
||RequestedDisposition==FILE_OPEN_IF
||RequestedDisposition==FILE_OVERWRITE_IF)
{
DbgPrint("try to create file\n");
DPRINT("try to create file\n");
Status=addEntry(DeviceExt,FileObject,RequestedOptions);
}
}

View file

@ -62,7 +62,7 @@ typedef struct _OBJECT_TYPE
/*
* PURPOSE: Called to close an object if OkayToClose returns true
*/
VOID (*Close)(VOID);
VOID (*Close)(PVOID ObjectBody);
/*
* PURPOSE: Called to close an object if OkayToClose returns true
@ -91,15 +91,15 @@ typedef struct _OBJECT_TYPE
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT
typedef struct _OBJECT_HEADER
/*
* PURPOSE: Header for every object managed by the object manager
*/
{
UNICODE_STRING Name;
LIST_ENTRY Entry;
ULONG RefCount;
ULONG HandleCount;
LONG RefCount;
LONG HandleCount;
BOOLEAN Permanent;
struct _DIRECTORY_OBJECT* Parent;
POBJECT_TYPE ObjectType;

View file

@ -1,274 +1,274 @@
#ifndef __INCLUDE_DDK_PSTYPES_H
#define __INCLUDE_DDK_PSTYPES_H
#undef WIN32_LEAN_AND_MEAN
#include <windows.h> // might be redundant
#include <kernel32/heap.h>
#include <kernel32/atom.h>
#include <internal/hal.h>
#ifndef TLS_MINIMUM_AVAILABLE
#define TLS_MINIMUM_AVAILABLE (64)
#endif
#ifndef MAX_PATH
#define MAX_PATH (260)
#endif
typedef NTSTATUS (*PKSTART_ROUTINE)(PVOID StartContext);
typedef struct _STACK_INFORMATION
{
PVOID BaseAddress;
PVOID UpperAddress;
} STACK_INFORMATION, *PSTACK_INFORMATION;
typedef struct linux_sigcontext {
int sc_gs;
int sc_fs;
int sc_es;
int sc_ds;
int sc_edi;
int sc_esi;
int sc_ebp;
int sc_esp;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_trapno;
int sc_err;
int sc_eip;
int sc_cs;
int sc_eflags;
int sc_esp_at_signal;
int sc_ss;
int sc_387;
int sc_mask;
int sc_cr2;
} TRAP_FRAME, *PTRAP_FRAME;
typedef ULONG THREADINFOCLASS;
typedef struct _STARTUPINFOW {
DWORD cb;
WCHAR WindowTitle[MAX_PATH];
WCHAR ImageFile[MAX_PATH];
WCHAR CommandLine[MAX_PATH];
WCHAR DllPath[MAX_PATH];
LPWSTR Reserved[MAX_PATH];
LPWSTR Desktop[MAX_PATH];
LPWSTR Title[MAX_PATH];
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
unsigned char * lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} PROCESSINFOW, *PPROCESSINFOW;
typedef struct _LDR {
UCHAR Initialized;
UCHAR InInitializationOrderModuleList;
PVOID InLoadOrderModuleList;
PVOID InMemoryOrderModuleList;
} LDR, *PLDR;
typedef struct _NT_PEB
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
LONG ImageBaseAddress;
LDR Ldr;
WORD NumberOfProcessors;
WORD NtGlobalFlag;
PPROCESSINFOW StartupInfo;
PHEAP ProcessHeap;
ATOMTABLE LocalAtomTable;
LPCRITICAL_SECTION CriticalSection;
DWORD CriticalSectionTimeout;
WORD MajorVersion;
WORD MinorVersion;
WORD BuildNumber;
WORD PlatformId;
} NT_PEB, *PNT_PEB;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
PVOID StackLimit;
PVOID SubSystemTib;
union {
PVOID FiberData;
ULONG Version;
} Fib;
PVOID ArbitraryUserPointer;
struct _NT_TIB *Self;
} NT_TIB, *PNT_TIB;
typedef struct _NT_TEB
{
NT_TIB Tib;
CLIENT_ID Cid;
HANDLE RPCHandle;
PVOID TlsData[TLS_MINIMUM_AVAILABLE];
DWORD dwTlsIndex;
NT_PEB *Peb;
DWORD LastErrorCode;
NTSTATUS LastStatusValue;
DWORD LockCount;
UCHAR HardErrorMode;
} NT_TEB;
typedef struct _KTHREAD
{
DISPATCHER_HEADER DispatcherHeader;
TIME ElapsedTime;
TIME KernelTime;
TIME UserTime;
STACK_INFORMATION StackInformation;
PVOID ServiceDescriptorTable; // points to KeServiceDescriptorTable
KAFFINITY Affinity;
KPRIORITY CurrentPriority;
KPRIORITY BasePriority;
ULONG Quantum;
UCHAR ThreadState; //Thread state is a typeless enum, otherwise it should be const integer
ULONG FreezeCount;
LONG SuspendCount;
PTRAP_FRAME TrapFrame;
PVOID *Tls;
KWAIT_BLOCK WaitBlock[4];
struct _KMUTANT* MutantList;
PLIST_ENTRY ApcList;
UCHAR KernelApcDisable;
KTIMER TimerBlock;
KDEVICE_QUEUE DeviceQueue;
NT_TEB* Teb;
/*
* PURPOSE: CPU state
* NOTE: I have temporarily added this to give somewhere to store
* cpu state when the thread isn't running
*/
hal_thread_state Context;
LIST_ENTRY Entry;
ULONG LastTick;
} KTHREAD, *PKTHREAD;
// According to documentation the stack should have a commited [ 1 page ] and
// a reserved part [ 1 M ] but can be specified otherwise in the image file.
typedef struct _INITIAL_TEB {
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
} INITIAL_TEB, *PINITIAL_TEB;
// TopLevelIrp can be one of the following values:
// FIXME I belong somewhere else
#define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
typedef struct _TOP_LEVEL_IRP
{
PIRP TopLevelIrp;
ULONG TopLevelIrpConst;
} TOP_LEVEL_IRP;
typedef struct _ETHREAD {
KTHREAD Tcb;
TIME CreateTime;
TIME ExitTime;
NTSTATUS ExitStatus;
LIST_ENTRY PostBlockList;
LIST_ENTRY TerminationPortList;
ULONG ActiveTimerListLock;
PVOID ActiveTimerListHead;
CLIENT_ID Cid;
PLARGE_INTEGER LpcReplySemaphore;
PVOID LpcReplyMessage;
PLARGE_INTEGER LpcReplyMessageId;
PVOID ImpersonationInfo;
LIST_ENTRY IrpList; //
TOP_LEVEL_IRP TopLevelIrp;
ULONG ReadClusterSize;
UCHAR ForwardClusterOnly;
UCHAR DisablePageFaultClustering;
UCHAR DeadThread;
UCHAR HasTerminated;
ACCESS_MASK GrantedAccess;
struct _EPROCESS* ThreadsProcess;
PKSTART_ROUTINE StartAddress;
LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func
UCHAR LpcExitThreadCalled;
UCHAR HardErrorsAreDisabled;
} ETHREAD, *PETHREAD;
typedef struct _KPROCESS
{
DISPATCHER_HEADER DispatcherHeader;
PVOID PageTableDirectory; // FIXME: I shoud point to a PTD
TIME ElapsedTime;
TIME KernelTime;
TIME UserTime;
LIST_ENTRY InMemoryList;
LIST_ENTRY SwappedOutList;
KSPIN_LOCK SpinLock;
KAFFINITY Affinity;
ULONG StackCount;
KPRIORITY BasePriority;
ULONG DefaultThreadQuantum;
UCHAR ProcessState;
ULONG ThreadSeed;
UCHAR DisableBoost;
/*
* Added by David Welch (welch@mcmail.com)
*/
LIST_ENTRY MemoryAreaList;
HANDLE_TABLE HandleTable;
} KPROCESS, *PKPROCESS;
typedef struct _EPROCESS
{
KPROCESS Pcb;
} EPROCESS, *PEPROCESS;
#define PROCESS_STATE_TERMINATED (1)
#define PROCESS_STATE_ACTIVE (2)
#endif /* __INCLUDE_DDK_PSTYPES_H */
#ifndef __INCLUDE_DDK_PSTYPES_H
#define __INCLUDE_DDK_PSTYPES_H
#undef WIN32_LEAN_AND_MEAN
#include <windows.h> // might be redundant
#include <kernel32/heap.h>
#include <kernel32/atom.h>
#include <internal/hal.h>
#ifndef TLS_MINIMUM_AVAILABLE
#define TLS_MINIMUM_AVAILABLE (64)
#endif
#ifndef MAX_PATH
#define MAX_PATH (260)
#endif
typedef NTSTATUS (*PKSTART_ROUTINE)(PVOID StartContext);
typedef struct _STACK_INFORMATION
{
PVOID BaseAddress;
PVOID UpperAddress;
} STACK_INFORMATION, *PSTACK_INFORMATION;
typedef struct linux_sigcontext {
int sc_gs;
int sc_fs;
int sc_es;
int sc_ds;
int sc_edi;
int sc_esi;
int sc_ebp;
int sc_esp;
int sc_ebx;
int sc_edx;
int sc_ecx;
int sc_eax;
int sc_trapno;
int sc_err;
int sc_eip;
int sc_cs;
int sc_eflags;
int sc_esp_at_signal;
int sc_ss;
int sc_387;
int sc_mask;
int sc_cr2;
} TRAP_FRAME, *PTRAP_FRAME;
typedef ULONG THREADINFOCLASS;
typedef struct _STARTUPINFOW {
DWORD cb;
WCHAR WindowTitle[MAX_PATH];
WCHAR ImageFile[MAX_PATH];
WCHAR CommandLine[MAX_PATH];
WCHAR DllPath[MAX_PATH];
LPWSTR Reserved[MAX_PATH];
LPWSTR Desktop[MAX_PATH];
LPWSTR Title[MAX_PATH];
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
unsigned char * lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} PROCESSINFOW, *PPROCESSINFOW;
typedef struct _LDR {
UCHAR Initialized;
UCHAR InInitializationOrderModuleList;
PVOID InLoadOrderModuleList;
PVOID InMemoryOrderModuleList;
} LDR, *PLDR;
typedef struct _NT_PEB
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
LONG ImageBaseAddress;
LDR Ldr;
WORD NumberOfProcessors;
WORD NtGlobalFlag;
PPROCESSINFOW StartupInfo;
PHEAP ProcessHeap;
ATOMTABLE LocalAtomTable;
LPCRITICAL_SECTION CriticalSection;
DWORD CriticalSectionTimeout;
WORD MajorVersion;
WORD MinorVersion;
WORD BuildNumber;
WORD PlatformId;
} NT_PEB, *PNT_PEB;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
PVOID StackLimit;
PVOID SubSystemTib;
union {
PVOID FiberData;
ULONG Version;
} Fib;
PVOID ArbitraryUserPointer;
struct _NT_TIB *Self;
} NT_TIB, *PNT_TIB;
typedef struct _NT_TEB
{
NT_TIB Tib;
CLIENT_ID Cid;
HANDLE RPCHandle;
PVOID TlsData[TLS_MINIMUM_AVAILABLE];
DWORD dwTlsIndex;
NT_PEB *Peb;
DWORD LastErrorCode;
NTSTATUS LastStatusValue;
DWORD LockCount;
UCHAR HardErrorMode;
} NT_TEB;
typedef struct _KTHREAD
{
DISPATCHER_HEADER DispatcherHeader;
TIME ElapsedTime;
TIME KernelTime;
TIME UserTime;
STACK_INFORMATION StackInformation;
PVOID ServiceDescriptorTable; // points to KeServiceDescriptorTable
KAFFINITY Affinity;
KPRIORITY CurrentPriority;
KPRIORITY BasePriority;
ULONG Quantum;
UCHAR ThreadState; //Thread state is a typeless enum, otherwise it should be const integer
ULONG FreezeCount;
LONG SuspendCount;
PTRAP_FRAME TrapFrame;
PVOID *Tls;
KWAIT_BLOCK WaitBlock[4];
struct _KMUTANT* MutantList;
PLIST_ENTRY ApcList;
UCHAR KernelApcDisable;
KTIMER TimerBlock;
KDEVICE_QUEUE DeviceQueue;
NT_TEB* Teb;
/*
* PURPOSE: CPU state
* NOTE: I have temporarily added this to give somewhere to store
* cpu state when the thread isn't running
*/
hal_thread_state Context;
LIST_ENTRY Entry;
ULONG LastTick;
} KTHREAD, *PKTHREAD;
// According to documentation the stack should have a commited [ 1 page ] and
// a reserved part [ 1 M ] but can be specified otherwise in the image file.
typedef struct _INITIAL_TEB {
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
} INITIAL_TEB, *PINITIAL_TEB;
// TopLevelIrp can be one of the following values:
// FIXME I belong somewhere else
#define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
typedef struct _TOP_LEVEL_IRP
{
PIRP TopLevelIrp;
ULONG TopLevelIrpConst;
} TOP_LEVEL_IRP;
typedef struct _ETHREAD {
KTHREAD Tcb;
TIME CreateTime;
TIME ExitTime;
NTSTATUS ExitStatus;
LIST_ENTRY PostBlockList;
LIST_ENTRY TerminationPortList;
ULONG ActiveTimerListLock;
PVOID ActiveTimerListHead;
CLIENT_ID Cid;
PLARGE_INTEGER LpcReplySemaphore;
PVOID LpcReplyMessage;
PLARGE_INTEGER LpcReplyMessageId;
PVOID ImpersonationInfo;
LIST_ENTRY IrpList; //
TOP_LEVEL_IRP TopLevelIrp;
ULONG ReadClusterSize;
UCHAR ForwardClusterOnly;
UCHAR DisablePageFaultClustering;
UCHAR DeadThread;
UCHAR HasTerminated;
ACCESS_MASK GrantedAccess;
struct _EPROCESS* ThreadsProcess;
PKSTART_ROUTINE StartAddress;
LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func
UCHAR LpcExitThreadCalled;
UCHAR HardErrorsAreDisabled;
} ETHREAD, *PETHREAD;
typedef struct _KPROCESS
{
DISPATCHER_HEADER DispatcherHeader;
PVOID PageTableDirectory; // FIXME: I shoud point to a PTD
TIME ElapsedTime;
TIME KernelTime;
TIME UserTime;
LIST_ENTRY InMemoryList;
LIST_ENTRY SwappedOutList;
KSPIN_LOCK SpinLock;
KAFFINITY Affinity;
ULONG StackCount;
KPRIORITY BasePriority;
ULONG DefaultThreadQuantum;
UCHAR ProcessState;
ULONG ThreadSeed;
UCHAR DisableBoost;
/*
* Added by David Welch (welch@mcmail.com)
*/
LIST_ENTRY MemoryAreaList;
HANDLE_TABLE HandleTable;
} KPROCESS, *PKPROCESS;
typedef struct _EPROCESS
{
KPROCESS Pcb;
} EPROCESS, *PEPROCESS;
#define PROCESS_STATE_TERMINATED (1)
#define PROCESS_STATE_ACTIVE (2)
#endif /* __INCLUDE_DDK_PSTYPES_H */

View file

@ -45,8 +45,11 @@ typedef struct
unsigned short reserved11;
unsigned short trap;
unsigned short iomap_base;
unsigned short nr;
PVOID KernelStackBase;
PVOID SavedKernelEsp;
PVOID SavedKernelStackBase;
unsigned char io_bitmap[1];
} hal_thread_state;

View file

@ -1,58 +1,58 @@
#ifndef __INCLUDE_INTERNAL_PSMGR_H
#define __INCLUDE_INTERNAL_PSMGR_H
#include <internal/hal.h>
extern PEPROCESS SystemProcess;
extern HANDLE SystemProcessHandle;
extern POBJECT_TYPE PsThreadType;
extern POBJECT_TYPE PsProcessType;
void PsInitThreadManagment(void);
VOID PsInitProcessManagment(VOID);
VOID PsInitIdleThread(VOID);
VOID PsDispatchThread(VOID);
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
/*
* PURPOSE: Thread states
*/
enum
{
/*
* PURPOSE: Don't touch
*/
THREAD_STATE_INVALID,
/*
* PURPOSE: Waiting to be dispatched
*/
THREAD_STATE_RUNNABLE,
/*
* PURPOSE: Currently running
*/
THREAD_STATE_RUNNING,
/*
* PURPOSE: Doesn't want to run
*/
THREAD_STATE_SUSPENDED,
/*
* Waiting to be freed
*/
THREAD_STATE_TERMINATED,
};
/*
* Functions the HAL must provide
*/
void HalInitFirstTask(PETHREAD thread);
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
void HalTaskSwitch(PKTHREAD thread);
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
#endif
#ifndef __INCLUDE_INTERNAL_PSMGR_H
#define __INCLUDE_INTERNAL_PSMGR_H
#include <internal/hal.h>
extern PEPROCESS SystemProcess;
extern HANDLE SystemProcessHandle;
extern POBJECT_TYPE PsThreadType;
extern POBJECT_TYPE PsProcessType;
void PsInitThreadManagment(void);
VOID PsInitProcessManagment(VOID);
VOID PsInitIdleThread(VOID);
VOID PsDispatchThread(VOID);
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
/*
* PURPOSE: Thread states
*/
enum
{
/*
* PURPOSE: Don't touch
*/
THREAD_STATE_INVALID,
/*
* PURPOSE: Waiting to be dispatched
*/
THREAD_STATE_RUNNABLE,
/*
* PURPOSE: Currently running
*/
THREAD_STATE_RUNNING,
/*
* PURPOSE: Doesn't want to run
*/
THREAD_STATE_SUSPENDED,
/*
* Waiting to be freed
*/
THREAD_STATE_TERMINATED,
};
/*
* Functions the HAL must provide
*/
void HalInitFirstTask(PETHREAD thread);
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
void HalTaskSwitch(PKTHREAD thread);
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
#endif

View file

@ -50,7 +50,7 @@ typedef unsigned long long u64;
#endif
typedef unsigned int size_t;
typedef int size_t;
typedef size_t __kernel_size_t;
#endif /* _LINUX_TYPES_H */

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#include <io.h>
#include <windows.h>
#include <libc/file.h>
//#include <libc/file.h>
int close(int _fd)
@ -13,4 +13,4 @@ int _close(int _fd)
CloseHandle(filehnd(_fd));
return __fileno_close(_fd);
}
}

View file

@ -1,7 +1,8 @@
#include <windows.h>
#include <io.h>
#include <string.h>
#include <libc/file.h>
#if 0
//UnixTimeToFileTime
//FileTimeToUnixTime
@ -251,3 +252,4 @@ time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
}
#endif

View file

@ -1,6 +1,6 @@
#include <windows.h>
#include <io.h>
#include <libc/file.h>
//#include <libc/file.h>
#undef lseek
long lseek(int _fildes, long _offset, int _whence)

View file

@ -12,10 +12,12 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <libc/file.h>
//#include <libc/file.h>
#include <string.h>
#include <share.h>
#if 0
typedef struct _fileno_modes_type
{
HANDLE hFile;
@ -252,3 +254,4 @@ int _open_osfhandle (void *osfhandle, int flags )
{
return __fileno_alloc((HANDLE)osfhandle, flags);
}
#endif

View file

@ -9,7 +9,6 @@
*/
#include <io.h>
#include <windows.h>
#include <libc/file.h>
int write(int _fd, const void *_buf,int _nbyte)
{
@ -24,4 +23,4 @@ size_t _write(int _fd, const void *_buf, size_t _nbyte)
return -1;
}
return _wbyte;
}
}

View file

@ -3,7 +3,7 @@
#include <fcntl.h>
#include <string.h>
#include <windows.h>
#include <libc/file.h>
//#include <libc/file.h>
void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder );
time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );

View file

@ -18,6 +18,9 @@
#include <ddk/li.h>
#include <ddk/rtl.h>
#define NDEBUG
#include <kernel32/kernel32.h>
HANDLE STDCALL CreateFileA(LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
@ -141,7 +144,7 @@ HANDLE STDCALL CreateFileW(LPCWSTR lpFileName,
NULL,
0);
dprintf("After create file");
DPRINT("After create file\n");
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
@ -228,4 +231,4 @@ HANDLE STDCALL CreateFileW(LPCWSTR lpFileName,
return(FileHandle);
}
#endif
#endif

View file

@ -13,14 +13,15 @@
#include <windows.h>
#define NDEBUG
#include <kernel32/kernel32.h>
/* GLOBALS *******************************************************************/
WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
WCHAR SystemDirectoryW[MAX_PATH];
WCHAR WindowsDirectoryW[MAX_PATH];
static WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
static WCHAR SystemDirectoryW[MAX_PATH];
static WCHAR WindowsDirectoryW[MAX_PATH];
/* FUNCTIONS *****************************************************************/
@ -46,7 +47,7 @@ DWORD STDCALL GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
{
UINT uSize;
dprintf("CurrentDirectoryW %w\n",CurrentDirectoryW);
DPRINT("CurrentDirectoryW %w\n",CurrentDirectoryW);
if ( lpBuffer == NULL )
return 0;
@ -54,7 +55,7 @@ DWORD STDCALL GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
if ( nBufferLength > uSize )
lstrcpynW(lpBuffer,CurrentDirectoryW,uSize);
dprintf("GetCurrentDirectoryW() = %w\n",lpBuffer);
DPRINT("GetCurrentDirectoryW() = %w\n",lpBuffer);
return uSize;
}
@ -63,7 +64,7 @@ BOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName)
{
UINT i;
dprintf("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
DPRINT("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
if ( lpPathName == NULL )
return FALSE;
@ -77,7 +78,7 @@ BOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName)
}
CurrentDirectoryW[i] = 0;
dprintf("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
DPRINT("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
return(TRUE);
}

View file

@ -1,450 +1,450 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/
#include <windows.h>
#include <wstring.h>
#include <ddk/ntddk.h>
typedef enum _FINDEX_INFO_LEVELS
{
FindExSearchNameMatch,
FindExSearchLimitToDirectories,
FindExSearchLimitToDevices,
} FINDEX_INFO_LEVELS ;
typedef enum _FINDEX_SEARCH_OPS
{
FindExInfoStandard
} FINDEX_SEARCH_OPS;
int wcharicmp ( WCHAR char1, WCHAR char2 );
WINBOOL
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);
HANDLE
STDCALL
FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
);
WINBOOL
STDCALL
FindNextFileW(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
);
HANDLE
STDCALL
FindFirstFileExA(
LPCSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
);
HANDLE
STDCALL
FindFirstFileExW(
LPCWSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
);
typedef struct _FIND_FILE_INFO
{
ULONG Offset;
PVOID SearchFilter;
WCHAR FileName[MAX_PATH];
WCHAR PathName[MAX_PATH];
FILE_DIRECTORY_INFORMATION *FileDirectory;
} FIND_FILE_INFO;
typedef struct _WIN32_FIND_DATAW {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
WCHAR cFileName[ MAX_PATH ];
WCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
WINBOOL
STDCALL
FindClose(
HANDLE hFind
)
{
if ( hFind == NULL)
return FALSE;
HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
HeapFree(GetProcessHeap(),0,hFind);
return TRUE;
}
HANDLE
STDCALL
FindFirstFileA(
LPCSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
WIN32_FIND_DATA FindFileDataW;
WCHAR FileNameW[MAX_PATH];
ULONG i;
i = 0;
while ((*lpFileName)!=0 && i < MAX_PATH)
{
FileNameW[i] = *lpFileName;
lpFileName++;
i++;
}
FileNameW[i] = 0;
FindFirstFileW(FileNameW,&FindFileDataW);
// converteer FindFileDataW
}
HANDLE
STDCALL
FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);
}
WINBOOL
STDCALL
FindNextFileA(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
{
WIN32_FIND_DATA FindFileDataW;
FindNextFileW(hFind,&FindFileDataW);
// converteer FindFileDataW
}
WINBOOL
STDCALL
FindNextFileW(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
{
int i;
WCHAR *pNameRead;
WCHAR FileName[MAX_PATH];
FIND_FILE_INFO *FindPtr = hFind;
FILE_DIRECTORY_INFORMATION *FileDirectory;
if ( FindPtr == NULL )
return FALSE;
/* Try to find a file */
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
while ( FileDirectory->NextEntryOffset != 0 ) {
pNameRead = FileDirectory->FileName;
FindPtr->Offset += FileDirectory->NextEntryOffset;
for(i=0;i<FileDirectory->FileNameLength;i++)
dprintf("%c\n",(char)pNameRead[i]);
if (mfs_regexp(pNameRead, FindPtr->FileName))
{
/* We found one! */
if (FindPtr->PathName[0] != L'\0')
{
lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);
lstrcatW(lpFindFileData->cFileName, L"/");
lstrcatW(lpFindFileData->cFileName, pNameRead);
}
else
lstrcpyW(lpFindFileData->cFileName, pNameRead);
lstrcpyW(lpFindFileData->cAlternateFileName, L"");
lpFindFileData->dwReserved0 = 0;
lpFindFileData->dwReserved1 = 0;
return TRUE;
}
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
}
return FALSE;
}
HANDLE
STDCALL
FindFirstFileExA(
LPCSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
)
{
WCHAR FileNameW[MAX_PATH];
WIN32_FIND_DATAW FindFileDataW;
FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);
// conerteer FindFileDataW
}
HANDLE
STDCALL
FindFirstFileExW(
LPCWSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle = NULL;
FIND_FILE_INFO *hFind;
WCHAR *FilePart;
UNICODE_STRING FileNameString, PathNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
ACCESS_MASK DesiredAccess=FILE_READ_DATA;
ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ULONG CreateDisposition=FILE_OPEN;
ULONG CreateOptions=FILE_DIRECTORY_FILE;
hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
/* Try to find a path and a filename in the passed filename */
lstrcpyW(hFind->PathName, lpFileName);
FilePart = wcsrchr(hFind->PathName, '\\');
if (FilePart == NULL){
GetCurrentDirectory(MAX_PATH, hFind->PathName);
lstrcpyW(hFind->FileName, lpFileName);
}
else {
FilePart[0] = L'\0';
lstrcpyW(hFind->FileName, &FilePart[1]);
}
hFind->Offset = 0;
PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
PathNameString.Buffer = hFind->PathName;
PathNameString.MaximumLength = FileNameString.Length;
FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
FileNameString.Buffer = hFind->FileName;
FileNameString.MaximumLength = FileNameString.Length;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = &PathNameString;
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
errCode = NtCreateFile(
&FileHandle,
DesiredAccess,
&ObjectAttributes,
&IoStatusBlock,
NULL, // AllocationSize
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
NULL, // EaBuffer
0); //
if ( !NT_SUCCESS(errCode) ) {
printf("%x\n",errCode);
return NULL;
}
errCode = NtQueryDirectoryFile(
FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
hFind->FileDirectory,
8192,
FileDirectoryInformation,
FALSE,
&FileNameString,
FALSE
);
if ( !NT_SUCCESS(errCode) ) {
printf("%x\n",errCode);
return NULL;
}
if ( FindNextFileW(hFind,lpFindFileData) )
return hFind;
else {
FindClose(hFind);
return NULL;
}
return NULL;
}
/************************************************************************/
WINBOOL
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)
{
/* The following code is provided by Tarang and I trust him...
*/
LPWSTR lpTempFileName = (LPWSTR)lpFileName;
LPWSTR lpTempFilter = (LPWSTR)lpFilter;
WCHAR TempToken [ 2 ];
WCHAR TempFilter [ 2 ];
WINBOOL Matched = FALSE;
if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||
( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )
return 0L;
if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )
{
wsprintf ( TempFilter, "*" );
lpTempFilter = TempFilter;
lpFilter = TempFilter;
}
while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )
{
memset ( TempToken, 0, sizeof ( TempToken ) );
switch ( *lpTempFilter )
{
default:
if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )
{
lpTempFileName = (LPWSTR)lpFileName;
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
if ( lpTempFilter )
lpTempFilter+=sizeof(WCHAR);
}
else
{
lpTempFilter+=sizeof(WCHAR);
lpTempFileName+=sizeof(WCHAR);
switch ( *lpTempFilter )
{
default:
break;
case L'\0':
case L' ':
case L',':
case L';':
if ( ! *lpTempFileName )
Matched = TRUE;
break;
}
}
break;
case L'?':
lpTempFilter+=sizeof(WCHAR);
lpTempFileName+=sizeof(WCHAR);
break;
case L'*':
lpTempFilter += sizeof(WCHAR);
if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )
Matched = TRUE;
else
{
lpTempFilter+=sizeof(WCHAR);
while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&
( ! Matched ) ) {
lpTempFileName+= sizeof(WCHAR);
Matched = mfs_regexp ( lpTempFileName, lpTempFilter );
}
if ( ( ! lpTempFileName ) && ( ! Matched ) )
{
lpTempFileName = (LPWSTR)lpFileName;
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
if ( lpTempFilter )
lpTempFilter+=sizeof(WCHAR);
}
}
break;
case L'\0':
case L' ':
case L',':
case L';':
Matched = TRUE;
break;
}
}
return (DWORD)Matched;
}
int wcharicmp ( WCHAR char1, WCHAR char2 )
{
WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ?
char1 - L'a' + L'A' : char1;
WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ?
char2 - L'a' + L'A' : char2;
return ( Char2 - Char1 );
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/
#include <windows.h>
#include <wstring.h>
#include <ddk/ntddk.h>
typedef enum _FINDEX_INFO_LEVELS
{
FindExSearchNameMatch,
FindExSearchLimitToDirectories,
FindExSearchLimitToDevices,
} FINDEX_INFO_LEVELS ;
typedef enum _FINDEX_SEARCH_OPS
{
FindExInfoStandard
} FINDEX_SEARCH_OPS;
int wcharicmp ( WCHAR char1, WCHAR char2 );
WINBOOL
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);
HANDLE
STDCALL
FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
);
WINBOOL
STDCALL
FindNextFileW(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
);
HANDLE
STDCALL
FindFirstFileExA(
LPCSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
);
HANDLE
STDCALL
FindFirstFileExW(
LPCWSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
);
typedef struct _FIND_FILE_INFO
{
ULONG Offset;
PVOID SearchFilter;
WCHAR FileName[MAX_PATH];
WCHAR PathName[MAX_PATH];
FILE_DIRECTORY_INFORMATION *FileDirectory;
} FIND_FILE_INFO;
typedef struct _WIN32_FIND_DATAW {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
WCHAR cFileName[ MAX_PATH ];
WCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
WINBOOL
STDCALL
FindClose(
HANDLE hFind
)
{
if ( hFind == NULL)
return FALSE;
HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
HeapFree(GetProcessHeap(),0,hFind);
return TRUE;
}
HANDLE
STDCALL
FindFirstFileA(
LPCSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
WIN32_FIND_DATA FindFileDataW;
WCHAR FileNameW[MAX_PATH];
ULONG i;
i = 0;
while ((*lpFileName)!=0 && i < MAX_PATH)
{
FileNameW[i] = *lpFileName;
lpFileName++;
i++;
}
FileNameW[i] = 0;
FindFirstFileW(FileNameW,&FindFileDataW);
// converteer FindFileDataW
}
HANDLE
STDCALL
FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);
}
WINBOOL
STDCALL
FindNextFileA(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
{
WIN32_FIND_DATA FindFileDataW;
FindNextFileW(hFind,&FindFileDataW);
// converteer FindFileDataW
}
WINBOOL
STDCALL
FindNextFileW(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
{
int i;
WCHAR *pNameRead;
WCHAR FileName[MAX_PATH];
FIND_FILE_INFO *FindPtr = hFind;
FILE_DIRECTORY_INFORMATION *FileDirectory;
if ( FindPtr == NULL )
return FALSE;
/* Try to find a file */
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
while ( FileDirectory->NextEntryOffset != 0 ) {
pNameRead = FileDirectory->FileName;
FindPtr->Offset += FileDirectory->NextEntryOffset;
for(i=0;i<FileDirectory->FileNameLength;i++)
dprintf("%c\n",(char)pNameRead[i]);
if (mfs_regexp(pNameRead, FindPtr->FileName))
{
/* We found one! */
if (FindPtr->PathName[0] != L'\0')
{
lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);
lstrcatW(lpFindFileData->cFileName, L"/");
lstrcatW(lpFindFileData->cFileName, pNameRead);
}
else
lstrcpyW(lpFindFileData->cFileName, pNameRead);
lstrcpyW(lpFindFileData->cAlternateFileName, L"");
lpFindFileData->dwReserved0 = 0;
lpFindFileData->dwReserved1 = 0;
return TRUE;
}
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
}
return FALSE;
}
HANDLE
STDCALL
FindFirstFileExA(
LPCSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
)
{
WCHAR FileNameW[MAX_PATH];
WIN32_FIND_DATAW FindFileDataW;
FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);
// conerteer FindFileDataW
}
HANDLE
STDCALL
FindFirstFileExW(
LPCWSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle = NULL;
FIND_FILE_INFO *hFind;
WCHAR *FilePart;
UNICODE_STRING FileNameString, PathNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
ACCESS_MASK DesiredAccess=FILE_READ_DATA;
ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ULONG CreateDisposition=FILE_OPEN;
ULONG CreateOptions=FILE_DIRECTORY_FILE;
hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
/* Try to find a path and a filename in the passed filename */
lstrcpyW(hFind->PathName, lpFileName);
FilePart = wcsrchr(hFind->PathName, '\\');
if (FilePart == NULL){
GetCurrentDirectory(MAX_PATH, hFind->PathName);
lstrcpyW(hFind->FileName, lpFileName);
}
else {
FilePart[0] = L'\0';
lstrcpyW(hFind->FileName, &FilePart[1]);
}
hFind->Offset = 0;
PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
PathNameString.Buffer = hFind->PathName;
PathNameString.MaximumLength = FileNameString.Length;
FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
FileNameString.Buffer = hFind->FileName;
FileNameString.MaximumLength = FileNameString.Length;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = &PathNameString;
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
errCode = NtCreateFile(
&FileHandle,
DesiredAccess,
&ObjectAttributes,
&IoStatusBlock,
NULL, // AllocationSize
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
NULL, // EaBuffer
0); //
if ( !NT_SUCCESS(errCode) ) {
printf("%x\n",errCode);
return NULL;
}
errCode = NtQueryDirectoryFile(
FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
hFind->FileDirectory,
8192,
FileDirectoryInformation,
FALSE,
&FileNameString,
FALSE
);
if ( !NT_SUCCESS(errCode) ) {
printf("%x\n",errCode);
return NULL;
}
if ( FindNextFileW(hFind,lpFindFileData) )
return hFind;
else {
FindClose(hFind);
return NULL;
}
return NULL;
}
/************************************************************************/
WINBOOL
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)
{
/* The following code is provided by Tarang and I trust him...
*/
LPWSTR lpTempFileName = (LPWSTR)lpFileName;
LPWSTR lpTempFilter = (LPWSTR)lpFilter;
WCHAR TempToken [ 2 ];
WCHAR TempFilter [ 2 ];
WINBOOL Matched = FALSE;
if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||
( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )
return 0L;
if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )
{
wsprintf ( TempFilter, "*" );
lpTempFilter = TempFilter;
lpFilter = TempFilter;
}
while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )
{
memset ( TempToken, 0, sizeof ( TempToken ) );
switch ( *lpTempFilter )
{
default:
if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )
{
lpTempFileName = (LPWSTR)lpFileName;
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
if ( lpTempFilter )
lpTempFilter+=sizeof(WCHAR);
}
else
{
lpTempFilter+=sizeof(WCHAR);
lpTempFileName+=sizeof(WCHAR);
switch ( *lpTempFilter )
{
default:
break;
case L'\0':
case L' ':
case L',':
case L';':
if ( ! *lpTempFileName )
Matched = TRUE;
break;
}
}
break;
case L'?':
lpTempFilter+=sizeof(WCHAR);
lpTempFileName+=sizeof(WCHAR);
break;
case L'*':
lpTempFilter += sizeof(WCHAR);
if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )
Matched = TRUE;
else
{
lpTempFilter+=sizeof(WCHAR);
while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&
( ! Matched ) ) {
lpTempFileName+= sizeof(WCHAR);
Matched = mfs_regexp ( lpTempFileName, lpTempFilter );
}
if ( ( ! lpTempFileName ) && ( ! Matched ) )
{
lpTempFileName = (LPWSTR)lpFileName;
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
if ( lpTempFilter )
lpTempFilter+=sizeof(WCHAR);
}
}
break;
case L'\0':
case L' ':
case L',':
case L';':
Matched = TRUE;
break;
}
}
return (DWORD)Matched;
}
int wcharicmp ( WCHAR char1, WCHAR char2 )
{
WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ?
char1 - L'a' + L'A' : char1;
WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ?
char2 - L'a' + L'A' : char2;
return ( Char2 - Char1 );
}

View file

@ -7,38 +7,27 @@
* UPDATE HISTORY:
* Created 01/11/98
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#include <wstring.h>
#include <string.h>
#include <ddk/ntddk.h>
#define NDEBUG
#include <kernel32/kernel32.h>
/* TYPES ********************************************************************/
typedef struct _FIND_FILE_INFO
typedef struct _KERNEL32_FIND_FILE_DATA
{
ULONG Offset;
WCHAR PathName[MAX_PATH];
WCHAR FileName[MAX_PATH];
FILE_DIRECTORY_INFORMATION *FileDirectory;
} FIND_FILE_INFO;
HANDLE DirectoryHandle;
FILE_DIRECTORY_INFORMATION FileInfo;
WCHAR FileNameExtra[MAX_PATH];
UNICODE_STRING PatternStr;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
typedef struct _NOTIFY_INFO
{
HANDLE Event;
HANDLE FileHandle;
DWORD dwNotifyFilter;
WINBOOL bWatchSubtree;
} NOTIFY_INFO;
typedef struct _WIN32_FIND_DATAW {
typedef struct _WIN32_FIND_DATA_UNICODE {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
@ -49,415 +38,239 @@ typedef struct _WIN32_FIND_DATAW {
DWORD dwReserved1;
WCHAR cFileName[ MAX_PATH ];
WCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
} WIN32_FIND_DATA_UNICODE, *PWIN32_FIND_DATA_UNICODE;
typedef struct _WIN32_FIND_DATA_ASCII {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
CHAR cFileName[ MAX_PATH ];
CHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATA_ASCII, *PWIN32_FIND_DATA_ASCII;
WINBOOL
STDCALL
FindClose(
HANDLE hFind
)
/* FUNCTIONS *****************************************************************/
WINBOOL STDCALL InternalFindNextFile(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
if ( hFind == NULL)
return FALSE;
if ( hFind == (HANDLE)-1)
return FALSE;
HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
HeapFree(GetProcessHeap(),0,hFind);
return TRUE;
}
HANDLE
STDCALL
FindFirstFileA(
LPCSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
WIN32_FIND_DATAW FindFileDataW;
WCHAR FileNameW[MAX_PATH];
ULONG i;
HANDLE hFind;
i = 0;
while ((*lpFileName)!=0 && i < MAX_PATH)
{
FileNameW[i] = *lpFileName;
lpFileName++;
i++;
}
FileNameW[i] = 0;
hFind = FindFirstFileW(FileNameW,(WIN32_FIND_DATA *)&FindFileDataW);
lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
i = 0;
while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
{
lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
i++;
}
lpFindFileData->cFileName[i] = 0;
i = 0;
while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
{
lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
i++;
}
lpFindFileData->cAlternateFileName[i] = 0;
return hFind;
}
HANDLE
STDCALL
FindFirstFileW(
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE FileHandle = NULL;
FIND_FILE_INFO *hFind;
WCHAR *FilePart;
UNICODE_STRING FileNameString, PathNameString;
OBJECT_ATTRIBUTES ObjectAttributes;
ACCESS_MASK DesiredAccess=FILE_READ_DATA;
ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
ULONG CreateDisposition=FILE_OPEN;
ULONG CreateOptions=FILE_DIRECTORY_FILE;
hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
/* Try to find a path and a filename in the passed filename */
lstrcpyW(hFind->PathName, lpFileName);
FilePart = wcsrchr(hFind->PathName, '\\');
if (FilePart == NULL){
GetCurrentDirectoryW(MAX_PATH, hFind->PathName);
lstrcpyW(hFind->FileName, lpFileName);
}
else {
lstrcpyW(hFind->FileName, &FilePart[1]);
}
hFind->Offset = 0;
PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
PathNameString.Buffer = hFind->PathName;
PathNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
PKERNEL32_FIND_FILE_DATA IData;
FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
FileNameString.Buffer = hFind->FileName;
FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = &PathNameString;
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
errCode = NtCreateFile(
&FileHandle,
DesiredAccess,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
NULL,
0); //
if ( !NT_SUCCESS(errCode) ) {
return NULL;
}
errCode = NtQueryDirectoryFile(
FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
hFind->FileDirectory,
8192,
FileDirectoryInformation,
FALSE,
&FileNameString,
FALSE
);
if ( !NT_SUCCESS(errCode) ) {
// printf("%x\n",errCode);
return NULL;
}
if ( FindNextFileW(hFind,lpFindFileData) )
return hFind;
else {
FindClose(hFind);
return NULL;
}
return NULL;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
Status = NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
DPRINT("Found %w\n",IData->FileInfo.FileName);
lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
if (Status != STATUS_SUCCESS)
{
return(FALSE);
}
return(TRUE);
}
WINBOOL
STDCALL
FindNextFileA(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
HANDLE STDCALL InternalFindFirstFile(LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
{
WIN32_FIND_DATAW FindFileDataW;
ULONG i;
hFind = FindNextFileW(hFind,(WIN32_FIND_DATA *)&FindFileDataW);
lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
i = 0;
while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
{
lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
i++;
}
lpFindFileData->cFileName[i] = 0;
i = 0;
while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
{
lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
i++;
}
lpFindFileData->cAlternateFileName[i] = 0;
return hFind;
WCHAR CurrentDirectory[MAX_PATH];
WCHAR Pattern[MAX_PATH];
WCHAR Directory[MAX_PATH];
PWSTR End;
PKERNEL32_FIND_FILE_DATA IData;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameStr;
IO_STATUS_BLOCK IoStatusBlock;
DPRINT("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
lpFileName, lpFindFileData);
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
Directory[0] = '\\';
Directory[1] = '?';
Directory[2] = '?';
Directory[3] = '\\';
Directory[4] = 0;
DPRINT("Directory %w\n",Directory);
wcscat(Directory, CurrentDirectory);
DPRINT("Directory %w\n",Directory);
wcscat(Directory, lpFileName);
DPRINT("Directory %w\n",Directory);
End = wcsrchr(Directory, '\\');
*End = 0;
wcscpy(Pattern, End+1);
*(End+1) = 0;
*End = '\\';
DPRINT("Directory %w Pattern %w\n",Directory,Pattern);
IData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(KERNEL32_FIND_FILE_DATA));
RtlInitUnicodeString(&DirectoryNameStr, Directory);
InitializeObjectAttributes(&ObjectAttributes,
&DirectoryNameStr,
0,
NULL,
NULL);
if (ZwOpenFile(&IData->DirectoryHandle,
FILE_LIST_DIRECTORY,
&ObjectAttributes,
&IoStatusBlock,
FILE_OPEN_IF,
OPEN_EXISTING)!=STATUS_SUCCESS)
{
return(NULL);
}
RtlInitUnicodeString(&(IData->PatternStr), Pattern);
NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
DPRINT("Found %w\n",IData->FileInfo.FileName);
lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
return(IData);
}
WINBOOL
STDCALL
FindNextFileW(
HANDLE hFind,
LPWIN32_FIND_DATA lpFindFileData
)
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR lpFileNameW[MAX_PATH];
ULONG i;
PKERNEL32_FIND_FILE_DATA IData;
PWIN32_FIND_DATA_ASCII Ret;
DPRINT("FindFirstFileA(lpFileName %s, lpFindFileData %x)\n",
lpFileName,lpFindFileData);
i = 0;
while (lpFileName[i]!=0)
{
lpFileNameW[i] = lpFileName[i];
i++;
}
lpFileNameW[i] = 0;
IData = InternalFindFirstFile(lpFileNameW,lpFindFileData);
if (IData == NULL)
{
DPRINT("Failing request\n");
return(NULL);
}
Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
LPWIN32_FIND_DATAW lpFindFileDataW = (LPWIN32_FIND_DATAW)lpFindFileData;
FIND_FILE_INFO *FindPtr = hFind;
FILE_DIRECTORY_INFORMATION *FileDirectory=NULL;
if ( FindPtr == NULL )
return FALSE;
if ( FileDirectory->NextEntryOffset == 0 )
return FALSE;
/* Try to find a file */
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
FindPtr->Offset += FileDirectory->NextEntryOffset;
/* We found one! */
if (FindPtr->PathName[0] != L'\0')
{
wcscpy(lpFindFileDataW->cFileName, FindPtr->PathName);
wcscat(lpFindFileDataW->cFileName, L"\\");
wcscat(lpFindFileDataW->cFileName, FileDirectory->FileName);
}
else
wcscpy(lpFindFileDataW->cFileName, FileDirectory->FileName);
wcscpy(lpFindFileDataW->cAlternateFileName, L"");
lpFindFileData->dwReserved0 = 0;
lpFindFileData->dwReserved1 = 0;
return TRUE;
for (i=0; i<IData->FileInfo.FileNameLength; i++)
{
Ret->cFileName[i] = IData->FileInfo.FileName[i];
}
Ret->cFileName[i] = 0;
return(IData);
}
HANDLE
STDCALL
FindFirstChangeNotificationA(
LPCSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
ULONG i;
PWIN32_FIND_DATA_ASCII Ret;
PKERNEL32_FIND_FILE_DATA IData;
ULONG i;
WCHAR PathNameW[MAX_PATH];
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (IData == NULL)
{
return(FALSE);
}
if (!InternalFindNextFile(hFindFile, lpFindFileData))
{
return(FALSE);
}
i = 0;
while ((*lpPathName)!=0 && i < MAX_PATH)
{
PathNameW[i] = *lpPathName;
lpPathName++;
i++;
}
PathNameW[i] = 0;
return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
for (i=0; i<IData->FileInfo.FileNameLength; i++)
{
Ret->cFileName[i] = IData->FileInfo.FileName[i];
}
Ret->cFileName[i] = 0;
return(TRUE);
}
HANDLE
STDCALL
FindFirstChangeNotificationW(
LPCWSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
BOOL FindClose(HANDLE hFindFile)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
NOTIFY_INFO *NotifyHandle;
WCHAR Buffer[100];
ULONG BufferSize = 100;
NotifyHandle = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFY_INFO));
NotifyHandle->Event = CreateEventW(NULL,FALSE,FALSE,NULL);
NotifyHandle->FileHandle = CreateFileW(lpPathName,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
NotifyHandle->dwNotifyFilter = dwNotifyFilter;
NotifyHandle->bWatchSubtree = bWatchSubtree;
errCode = NtNotifyChangeDirectoryFile(
NotifyHandle->FileHandle,
NotifyHandle->Event,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BufferSize,
NotifyHandle->dwNotifyFilter,
NotifyHandle->bWatchSubtree
);
return NotifyHandle;
PKERNEL32_FIND_FILE_DATA IData;
dprintf("FindClose(hFindFile %x)\n",hFindFile);
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
NtClose(IData->DirectoryHandle);
HeapFree(GetProcessHeap(), 0, IData);
return(TRUE);
}
WINBOOL
STDCALL
FindNextChangeNotification(
HANDLE hChangeHandle
)
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
{
NTSTATUS errCode;
PWIN32_FIND_DATA_UNICODE Ret;
PKERNEL32_FIND_FILE_DATA IData;
IData = InternalFindFirstFile(lpFileName,lpFindFileData);
Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
IO_STATUS_BLOCK IoStatusBlock;
NOTIFY_INFO *NotifyHandle = hChangeHandle;
memcpy(Ret->cFileName, IData->FileInfo.FileName,
IData->FileInfo.FileNameLength);
memset(Ret->cAlternateFileName, 0, 14);
WCHAR Buffer[100];
ULONG BufferSize = 100;
EVENT_BASIC_INFORMATION EventBasic;
ULONG ReturnLength;
NtQueryEvent(NotifyHandle->Event,EventBasicInformation,&EventBasic,sizeof(EVENT_BASIC_INFORMATION),&ReturnLength);
if ( EventBasic.Signaled == TRUE ) {
ResetEvent(NotifyHandle->Event);
return TRUE;
}
errCode = NtNotifyChangeDirectoryFile(
NotifyHandle->FileHandle,
NotifyHandle->Event,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BufferSize,
NotifyHandle->dwNotifyFilter,
(BOOLEAN)NotifyHandle->bWatchSubtree
);
return FALSE;
return(IData);
}
WINBOOL
STDCALL
FindCloseChangeNotification(
HANDLE hChangeHandle
)
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
HeapFree(GetProcessHeap(),0,hChangeHandle);
return TRUE;
PWIN32_FIND_DATA_UNICODE Ret;
PKERNEL32_FIND_FILE_DATA IData;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (!InternalFindNextFile(hFindFile, lpFindFileData))
{
return(FALSE);
}
Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
memcpy(Ret->cFileName, IData->FileInfo.FileName,
IData->FileInfo.FileNameLength);
memset(Ret->cAlternateFileName, 0, 14);
return(TRUE);
}

View file

@ -1,124 +1,124 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#include <wstring.h>
#include <ddk/ntddk.h>
/* TYPES ********************************************************************/
typedef struct _KERNEL32_FIND_FILE_DATA;
{
HANDLE DirectoryHandle;
FILE_DIRECTORY_INFORMATION FileInfo;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
/* FUNCTIONS *****************************************************************/
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR lpFileNameW[MAX_PATH];
ULONG i;
i = 0;
while (lpFileName[i]!=0)
{
lpFileName[i] = lpFileName[i];
i++;
}
return(FindFirstFileW(lpFileName,lpFindFileData));
}
BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
return(FindNextFileW(hFindFile, lpFindFileData));
}
BOOL FindClose(HANDLE hFindFile)
{
PKERNEL32_FIND_FILE_DATA IData;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
NtClose(IData->DirectoryHandle);
HeapFree(IData);
}
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR CurrentDirectory[MAX_PATH];
WCHAR Pattern[MAX_PATH];
WCHAR Directory[MAX_PATH];
PWSTR End;
PKERNEL32_FIND_FILE_DATA IData;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameStr;
IO_STATUS_BLOCK IoStatusBlock;
dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
lpFileName, lpFindFileData);
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
Directory[0] = '\\';
Directory[1] = '?';
Directory[2] = '?';
Directory[3] = '\\';
Directory[4] = 0;
wstrcat(Directory, CurrentDirectory);
wstrcat(Directory, lpFileName);
End = wstrchr(Directory, '\\');
*End = 0;
wstrcpy(Pattern, End+1);
dprintf("Directory %w End %w\n",Directory,End);
IData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(KERNEL32_FIND_FILE_DATA));
RtlInitUnicodeString(&DirectoryNameStr, Directory);
InitializeObjectAttributes(&ObjectAttributes,
&DirectoryNameStr,
0,
NULL,
NULL);
if (ZwOpenFile(&IData->DirectoryHandle,
FILE_TRAVERSE,
&ObjectAttributes,
0,
OPEN_EXISTING)!=STATUS_SUCCESS)
{
return(NULL);
}
NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
&IData->FileInfo,
sizeof(IData->FileInfo),
FileDirectoryInformation,
TRUE,
Pattern,
FALSE);
return(IData);
}
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#include <wstring.h>
#include <ddk/ntddk.h>
/* TYPES ********************************************************************/
typedef struct _KERNEL32_FIND_FILE_DATA;
{
HANDLE DirectoryHandle;
FILE_DIRECTORY_INFORMATION FileInfo;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
/* FUNCTIONS *****************************************************************/
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR lpFileNameW[MAX_PATH];
ULONG i;
i = 0;
while (lpFileName[i]!=0)
{
lpFileName[i] = lpFileName[i];
i++;
}
return(FindFirstFileW(lpFileName,lpFindFileData));
}
BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
return(FindNextFileW(hFindFile, lpFindFileData));
}
BOOL FindClose(HANDLE hFindFile)
{
PKERNEL32_FIND_FILE_DATA IData;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
NtClose(IData->DirectoryHandle);
HeapFree(IData);
}
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR CurrentDirectory[MAX_PATH];
WCHAR Pattern[MAX_PATH];
WCHAR Directory[MAX_PATH];
PWSTR End;
PKERNEL32_FIND_FILE_DATA IData;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameStr;
IO_STATUS_BLOCK IoStatusBlock;
dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
lpFileName, lpFindFileData);
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
Directory[0] = '\\';
Directory[1] = '?';
Directory[2] = '?';
Directory[3] = '\\';
Directory[4] = 0;
wstrcat(Directory, CurrentDirectory);
wstrcat(Directory, lpFileName);
End = wstrchr(Directory, '\\');
*End = 0;
wstrcpy(Pattern, End+1);
dprintf("Directory %w End %w\n",Directory,End);
IData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(KERNEL32_FIND_FILE_DATA));
RtlInitUnicodeString(&DirectoryNameStr, Directory);
InitializeObjectAttributes(&ObjectAttributes,
&DirectoryNameStr,
0,
NULL,
NULL);
if (ZwOpenFile(&IData->DirectoryHandle,
FILE_TRAVERSE,
&ObjectAttributes,
0,
OPEN_EXISTING)!=STATUS_SUCCESS)
{
return(NULL);
}
NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
&IData->FileInfo,
sizeof(IData->FileInfo),
FileDirectoryInformation,
TRUE,
Pattern,
FALSE);
return(IData);
}
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
}

View file

@ -28,7 +28,7 @@ OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
kernel32.a: $(OBJECTS)
$(AR) vrcs kernel32.a $(OBJECTS)
$(AR) rcs kernel32.a $(OBJECTS)
dummy:

View file

@ -26,8 +26,10 @@
* Put the type definitions of the heap in a seperate header. Boudewijn Dekker
*/
#include <kernel32/proc.h>
#define NDEBUG
#include <kernel32/kernel32.h>
#include <kernel32/proc.h>
#include <kernel32/heap.h>
#include <internal/string.h>
@ -72,7 +74,7 @@ static PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize,
*********************************************************************/
static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end)
{
dprintf("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
DPRINT("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
(ULONG) pheap, (ULONG) start, (ULONG) end);
if(end >= pheap->LastBlock)
@ -91,7 +93,7 @@ static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end)
*********************************************************************/
static BOOL __HeapDecommit(PHEAP pheap, LPVOID start, LPVOID end)
{
dprintf("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
DPRINT("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
(ULONG) pheap, (ULONG) start, (ULONG) end);
#ifdef NOT
__VirtualDump();
@ -117,7 +119,7 @@ static LPVOID __HeapAlloc(PHEAP pheap, ULONG flags, ULONG size, ULONG tag)
ULONG freesize;
ULONG allocsize;
dprintf("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
DPRINT("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
pheap,flags,size,tag);
pfree=&(pheap->Start);
@ -239,7 +241,7 @@ static LPVOID __HeapReAlloc(PHEAP pheap, ULONG flags, LPVOID pold, DWORD size)
*/
if(size==0)
{
dprintf("__HeapReAlloc: freeing memory\n");
DPRINT("__HeapReAlloc: freeing memory\n");
__HeapFree(pheap, flags, pold);
return NULL;
}
@ -255,7 +257,7 @@ static LPVOID __HeapReAlloc(PHEAP pheap, ULONG flags, LPVOID pold, DWORD size)
#endif
else if(newsize < allocsize )
{
dprintf("__HeapReAlloc: shrinking memory\n");
DPRINT("__HeapReAlloc: shrinking memory\n");
/* free remaining region of memory */
prealloc->Size=size | HEAP_NORMAL_TAG;
pnext=HEAP_NEXT(prealloc);
@ -271,7 +273,7 @@ static LPVOID __HeapReAlloc(PHEAP pheap, ULONG flags, LPVOID pold, DWORD size)
}
else if(newsize == allocsize )
{
dprintf("__HeapReAlloc: no changes\n");
DPRINT("__HeapReAlloc: no changes\n");
/* nothing to do */
prealloc->Size= size | HEAP_NORMAL_TAG;
return pold;
@ -284,7 +286,7 @@ static LPVOID __HeapReAlloc(PHEAP pheap, ULONG flags, LPVOID pold, DWORD size)
if(((LPVOID) pnext< pheap->End)&& HEAP_ISFREE(pnext) &&
(HEAP_SIZE(pnext) + HEAP_ADMIN_SIZE >=newsize-allocsize))
{
dprintf("__HeapReAlloc: joining memory\n");
DPRINT("__HeapReAlloc: joining memory\n");
oldsize=HEAP_SIZE(prealloc);
prealloc->Size=size | HEAP_NORMAL_TAG;
@ -308,7 +310,7 @@ static LPVOID __HeapReAlloc(PHEAP pheap, ULONG flags, LPVOID pold, DWORD size)
{
if((flags&HEAP_REALLOC_IN_PLACE_ONLY)==0)
{
dprintf("__HeapReAlloc: allocating new memory\n");
DPRINT("__HeapReAlloc: allocating new memory\n");
/* alloc a new piece of memory */
oldsize=HEAP_SIZE(prealloc);
pmem=__HeapAlloc(pheap, flags, size, HEAP_NORMAL_TAG);
@ -595,7 +597,7 @@ PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize, ULONG flags)
{
PHEAP pheap=(PHEAP) base;
dprintf("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
DPRINT("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
base,minsize,maxsize,flags);
pheap->Magic=MAGIC_HEAP;
@ -641,7 +643,7 @@ HANDLE STDCALL HeapCreate(DWORD flags, DWORD minsize, DWORD maxsize)
{
PHEAP pheap;
aprintf("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, minsize, maxsize);
DPRINT("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, minsize, maxsize);
pheap = VirtualAlloc(NULL, minsize, MEM_TOP_DOWN, PAGE_READWRITE);
VirtualAlloc(pheap, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);
@ -655,7 +657,7 @@ BOOL WINAPI HeapDestroy(HANDLE hheap)
{
PHEAP pheap=(PHEAP) hheap;
aprintf("HeapDestroy( 0x%lX )\n", (ULONG) hheap );
DPRINT("HeapDestroy( 0x%lX )\n", (ULONG) hheap );
if(pheap->Magic!=MAGIC_HEAP)
return __ErrorReturnFalse(ERROR_INVALID_PARAMETER);
@ -675,7 +677,7 @@ LPVOID STDCALL HeapAlloc(HANDLE hheap, DWORD flags, DWORD size)
PHEAP pheap=hheap;
LPVOID retval;
aprintf("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
DPRINT("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
@ -691,7 +693,7 @@ LPVOID STDCALL HeapAlloc(HANDLE hheap, DWORD flags, DWORD size)
if( (flags | pheap->Flags) & HEAP_NO_SERIALIZE )
LeaveCriticalSection(&(pheap->Synchronize));
aprintf("HeapAlloc returns 0x%lX\n", (ULONG) retval);
DPRINT("HeapAlloc returns 0x%lX\n", (ULONG) retval);
return retval;
@ -707,7 +709,7 @@ LPVOID STDCALL HeapReAlloc(HANDLE hheap, DWORD flags, LPVOID ptr, DWORD size)
PHEAP_BLOCK pfree=((PHEAP_BLOCK)ptr-1);
LPVOID retval;
aprintf("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
DPRINT("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr, size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
@ -740,8 +742,8 @@ WINBOOL STDCALL HeapFree(HANDLE hheap, DWORD flags, LPVOID ptr)
PHEAP_BLOCK pfree=(PHEAP_BLOCK)((DWORD)ptr-HEAP_ADMIN_SIZE);
BOOL retval;
aprintf("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr );
DPRINT("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr );
#ifdef NOT
HeapValidate(hheap, 0, 0);
#endif
@ -773,7 +775,7 @@ WINBOOL STDCALL HeapFree(HANDLE hheap, DWORD flags, LPVOID ptr)
*********************************************************************/
HANDLE WINAPI GetProcessHeap(VOID)
{
aprintf("GetProcessHeap()\n");
DPRINT("GetProcessHeap()\n");
return (HANDLE) __ProcessHeap;
}
@ -788,7 +790,7 @@ DWORD WINAPI GetProcessHeaps(DWORD maxheaps, PHANDLE phandles )
DWORD retval;
PHEAP pheap;
aprintf("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
DPRINT("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
pheap= __ProcessHeap;
retval=0;
@ -818,7 +820,7 @@ BOOL WINAPI HeapLock(HANDLE hheap)
{
PHEAP pheap=hheap;
aprintf("HeapLock( 0x%lX )\n", (ULONG) hheap );
DPRINT("HeapLock( 0x%lX )\n", (ULONG) hheap );
EnterCriticalSection(&(pheap->Synchronize));
return TRUE;
@ -832,7 +834,7 @@ BOOL WINAPI HeapUnlock(HANDLE hheap)
{
PHEAP pheap=hheap;
aprintf("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
DPRINT("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
LeaveCriticalSection(&(pheap->Synchronize));
return TRUE;
@ -883,7 +885,7 @@ DWORD WINAPI HeapSize(HANDLE hheap, DWORD flags, LPCVOID pmem)
PHEAP_BLOCK palloc=((PHEAP_BLOCK)pmem-1);
DWORD retval=0;
aprintf("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
DPRINT("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) pmem );
if(pheap->Magic!=MAGIC_HEAP)
@ -941,7 +943,7 @@ BOOL WINAPI HeapValidate(HANDLE hheap, DWORD flags, LPCVOID pmem)
pnext=HEAP_NEXT(pcheck);
if((pprev)&&(HEAP_PREV(pcheck)!=pprev))
{
dprintf("HeapValidate: linked list invalid, region 0x%lX,"
DPRINT("HeapValidate: linked list invalid, region 0x%lX,"
" previous region 0x%lX, list says 0x%lX\n",
(ULONG)pcheck, (ULONG)pprev, (ULONG) HEAP_PREV(pcheck));
return FALSE;

View file

@ -5,9 +5,6 @@ VOID CopyMemory(PVOID Destination, CONST VOID* Source, DWORD Length)
{
DWORD i;
dprintf("CopyMemory(Destination %x, Source %x, Length %d)\n",
Destination,Source,Length);
for (i=0; i<Length; i++)
{
((PCH)Destination)[i] = ((PCH)Source)[i];

View file

@ -7,6 +7,9 @@
* UPDATE HISTORY:
* Created 01/11/98
*/
/* INCLUDES ****************************************************************/
#define UNICODE
#include <windows.h>
#include <kernel32/proc.h>
@ -16,27 +19,28 @@
#include <ddk/rtl.h>
#include <ddk/li.h>
NT_PEB CurrentPeb;
#define NDEBUG
#include <kernel32/kernel32.h>
/* GLOBALS *****************************************************************/
static NT_PEB *CurrentPeb;
static NT_PEB Peb;
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs );
WINBOOL
STDCALL
GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
/* FUNCTIONS ****************************************************************/
WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
NT_PEB *GetCurrentPeb(VOID)
{
return &CurrentPeb;
if ( CurrentPeb != NULL )
return CurrentPeb;
else // hack to be able to return a process environment any time.
return &Peb;
}
HANDLE STDCALL GetCurrentProcess(VOID)
@ -49,310 +53,334 @@ HANDLE STDCALL GetCurrentThread(VOID)
return (HANDLE)NtCurrentThread();
}
DWORD
STDCALL
GetCurrentProcessId(VOID)
{
return (DWORD)(GetTeb()->Cid).UniqueProcess;
DWORD STDCALL GetCurrentProcessId(VOID)
{
return (DWORD)(GetTeb()->Cid).UniqueProcess;
}
unsigned char CommandLineA[MAX_PATH];
LPSTR
STDCALL
GetCommandLineA(
VOID
)
WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
{
WCHAR *CommandLineW;
ULONG i = 0;
CommandLineW = GetCommandLineW();
while ((CommandLineW[i])!=0 && i < MAX_PATH)
{
CommandLineA[i] = (unsigned char)CommandLineW[i];
i++;
}
CommandLineA[i] = 0;
return CommandLineA;
}
LPWSTR
STDCALL
GetCommandLineW(
VOID
)
{
return GetCurrentPeb()->StartupInfo->CommandLine;
}
wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs )
{
return NULL;
}
WINBOOL
STDCALL
GetExitCodeProcess(
HANDLE hProcess,
LPDWORD lpExitCode
)
{
NTSTATUS errCode;
PROCESS_BASIC_INFORMATION ProcessBasic;
ULONG BytesWritten;
errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
return TRUE;
}
WINBOOL
STDCALL
GetProcessId(
HANDLE hProcess,
LPDWORD lpProcessId
)
{
NTSTATUS errCode;
PROCESS_BASIC_INFORMATION ProcessBasic;
ULONG BytesWritten;
errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
return TRUE;
}
WINBOOL
STDCALL
CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
WINBOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
WCHAR ApplicationNameW[MAX_PATH];
WCHAR CommandLineW[MAX_PATH];
WCHAR CurrentDirectoryW[MAX_PATH];
ULONG i;
i = 0;
while ((*lpApplicationName)!=0 && i < MAX_PATH)
{
ApplicationNameW[i] = *lpApplicationName;
lpApplicationName++;
i++;
}
ApplicationNameW[i] = 0;
i = 0;
while ((*lpCommandLine)!=0 && i < MAX_PATH)
{
CommandLineW[i] = *lpCommandLine;
lpCommandLine++;
i++;
}
CommandLineW[i] = 0;
i = 0;
while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
{
CurrentDirectoryW[i] = *lpCurrentDirectory;
lpCurrentDirectory++;
i++;
}
CurrentDirectoryW[i] = 0;
return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
lpProcessInformation);
}
WINBOOL
STDCALL
CreateProcessW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
WINBOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
HANDLE hFile, hSection, hProcess, hThread;
KPRIORITY PriorityClass;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
BOOLEAN CreateSuspended;
NTSTATUS errCode;
UNICODE_STRING ApplicationNameString;
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
LPVOID lpParameter = NULL;
hFile = NULL;
ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
NTSTATUS errCode;
PROCESS_BASIC_INFORMATION ProcessBasic;
ULONG BytesWritten;
ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
ApplicationNameString.MaximumLength = ApplicationNameString.Length+sizeof(WCHAR);
errCode = NtQueryInformationProcess(hProcess,
ProcessBasicInformation,
&ProcessBasic,
sizeof(PROCESS_BASIC_INFORMATION),
&BytesWritten);
if (!NT_SUCCESS(errCode))
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
return TRUE;
}
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
if ( lpProcessAttributes != NULL ) {
if ( lpProcessAttributes->bInheritHandle )
ObjectAttributes.Attributes = OBJ_INHERIT;
else
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
}
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
&IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
NtClose(hFile);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
if ( lpProcessAttributes != NULL ) {
if ( lpProcessAttributes->bInheritHandle )
ObjectAttributes.Attributes = OBJ_INHERIT;
else
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
}
errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
NtClose(hSection);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
PriorityClass = NORMAL_PRIORITY_CLASS;
NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED)
CreateSuspended = TRUE;
else
CreateSuspended = FALSE;
hThread = CreateRemoteThread(
hProcess,
lpThreadAttributes,
4096, // 1 page ??
lpStartAddress,
lpParameter,
CREATE_SUSPENDED,
&lpProcessInformation->dwThreadId
);
if ( hThread == NULL )
return FALSE;
lpProcessInformation->hProcess = hProcess;
lpProcessInformation->hThread = hThread;
GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
return TRUE;
}
HANDLE
STDCALL
OpenProcess(
DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
DWORD dwProcessId
)
WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId )
{
NTSTATUS errCode;
PROCESS_BASIC_INFORMATION ProcessBasic;
ULONG BytesWritten;
errCode = NtQueryInformationProcess(hProcess,
ProcessBasicInformation,
&ProcessBasic,
sizeof(PROCESS_BASIC_INFORMATION),
&BytesWritten);
if (!NT_SUCCESS(errCode))
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
return TRUE;
}
PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
{
ULONG i;
if (In == NULL)
{
return(NULL);
}
else
{
i = 0;
while ((*In)!=0 && i < MaxLength)
{
Out[i] = *In;
In++;
i++;
}
Out[i] = 0;
return(Out);
}
}
WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
WINBOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
/*
* FUNCTION: The CreateProcess function creates a new process and its
* primary thread. The new process executes the specified executable file
* ARGUMENTS:
*
* lpApplicationName = Pointer to name of executable module
* lpCommandLine = Pointer to command line string
* lpProcessAttributes = Process security attributes
* lpThreadAttributes = Thread security attributes
* bInheritHandles = Handle inheritance flag
* dwCreationFlags = Creation flags
* lpEnvironment = Pointer to new environment block
* lpCurrentDirectory = Pointer to current directory name
* lpStartupInfo = Pointer to startup info
* lpProcessInformation = Pointer to process information
*/
{
WCHAR ApplicationNameW[MAX_PATH];
WCHAR CommandLineW[MAX_PATH];
WCHAR CurrentDirectoryW[MAX_PATH];
PWSTR PApplicationNameW;
PWSTR PCommandLineW;
PWSTR PCurrentDirectoryW;
ULONG i;
DPRINT("CreateProcessA\n");
PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
lpApplicationName,
MAX_PATH);
PCommandLineW = InternalAnsiToUnicode(CommandLineW,
lpCommandLine,
MAX_PATH);
PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
lpCurrentDirectory,
MAX_PATH);
return CreateProcessW(PApplicationNameW,
PCommandLineW,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
PCurrentDirectoryW,
lpStartupInfo,
lpProcessInformation);
}
NTSTATUS errCode;
HANDLE ProcessHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId ;
ClientId.UniqueProcess = (HANDLE)dwProcessId;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = (HANDLE)NULL;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
WINBOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
HANDLE hFile, hSection, hProcess, hThread;
KPRIORITY PriorityClass;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
BOOLEAN CreateSuspended;
NTSTATUS errCode;
UNICODE_STRING ApplicationNameString;
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
LPVOID lpParameter = NULL;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
WCHAR TempApplicationName[255];
WCHAR TempFileName[255];
WCHAR TempDirectoryName[255];
ULONG i;
ULONG BaseAddress;
ULONG Size;
LARGE_INTEGER SectionOffset;
DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
lpApplicationName,lpCommandLine);
hFile = NULL;
/*
* Find the application name
*/
TempApplicationName[0] = '\\';
TempApplicationName[1] = '?';
TempApplicationName[2] = '?';
TempApplicationName[3] = '\\';
TempApplicationName[4] = 0;
DPRINT("TempApplicationName '%w'\n",TempApplicationName);
if (lpApplicationName != NULL)
{
wcscpy(TempFileName, lpApplicationName);
if ( bInheritHandle == TRUE )
ObjectAttributes.Attributes = OBJ_INHERIT;
else
ObjectAttributes.Attributes = 0;
DPRINT("TempFileName '%w'\n",TempFileName);
}
else
{
wcscpy(TempFileName, lpCommandLine);
DPRINT("TempFileName '%w'\n",TempFileName);
for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
TempFileName[i]=0;
}
if (TempFileName[1] != ':')
{
GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
wcscat(TempApplicationName,TempDirectoryName);
}
wcscat(TempApplicationName,TempFileName);
RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
DPRINT("ApplicationName %w\n",ApplicationNameString.Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&ApplicationNameString,
OBJ_CASE_INSENSITIVE,
NULL,
SecurityDescriptor);
errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return NULL;
}
return ProcessHandle;
/*
* Try to open the executable
*/
errCode = NtOpenFile(&hFile,
SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_DELETE|FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
if ( !NT_SUCCESS(errCode) )
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
errCode = NtCreateSection(&hSection,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_EXECUTE,
SEC_IMAGE,
hFile);
NtClose(hFile);
if ( !NT_SUCCESS(errCode) )
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
errCode = NtCreateProcess(&hProcess,
PROCESS_ALL_ACCESS,
NULL,
NtCurrentProcess(),
bInheritHandles,
NULL,
NULL,
NULL);
BaseAddress = (PVOID)0x10000;
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
Size = 0x10000;
NtMapViewOfSection(hSection,
hProcess,
&BaseAddress,
0,
Size,
&SectionOffset,
&Size,
0,
MEM_COMMIT,
PAGE_READWRITE);
NtClose(hSection);
if ( !NT_SUCCESS(errCode) )
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
#if 0
PriorityClass = NORMAL_PRIORITY_CLASS;
NtSetInformationProcess(hProcess,
ProcessBasePriority,
&PriorityClass,
sizeof(KPRIORITY));
#endif
DPRINT("Creating thread for process\n");
lpStartAddress = BaseAddress;
hThread = CreateRemoteThread(hProcess,
lpThreadAttributes,
4096, // 1 page ??
lpStartAddress,
lpParameter,
dwCreationFlags,
&lpProcessInformation->dwThreadId);
if ( hThread == NULL )
return FALSE;
lpProcessInformation->hProcess = hProcess;
lpProcessInformation->hThread = hThread;
GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
return TRUE;
}
HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
WINBOOL bInheritHandle,
DWORD dwProcessId)
{
NTSTATUS errCode;
HANDLE ProcessHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId ;
ClientId.UniqueProcess = (HANDLE)dwProcessId;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = (HANDLE)NULL;
ObjectAttributes.SecurityDescriptor = NULL;
ObjectAttributes.SecurityQualityOfService = NULL;
if ( bInheritHandle == TRUE )
ObjectAttributes.Attributes = OBJ_INHERIT;
else
ObjectAttributes.Attributes = 0;
errCode = NtOpenProcess(&ProcessHandle,
dwDesiredAccess,
&ObjectAttributes,
&ClientId);
if (!NT_SUCCESS(errCode))
{
SetLastError(RtlNtStatusToDosError(errCode));
return NULL;
}
return ProcessHandle;
}
@ -367,48 +395,51 @@ OpenProcess(
UINT WinExec ( LPCSTR lpCmdLine, UINT uCmdShow )
UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
HINSTANCE hInst;
DWORD dosErr;
HINSTANCE hInst;
DWORD dosErr;
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.wShowWindow = uCmdShow ;
StartupInfo.dwFlags = 0;
hInst = (HINSTANCE)CreateProcessA(NULL,(PVOID)lpCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo, &ProcessInformation);
if ( hInst == NULL ) {
dosErr = GetLastError();
return dosErr;
}
if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
NtClose(ProcessInformation.hProcess);
NtClose(ProcessInformation.hThread);
return 0;
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.wShowWindow = uCmdShow ;
StartupInfo.dwFlags = 0;
hInst = (HINSTANCE)CreateProcessA(NULL,
(PVOID)lpCmdLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&StartupInfo,
&ProcessInformation);
if ( hInst == NULL )
{
dosErr = GetLastError();
return dosErr;
}
if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
NtClose(ProcessInformation.hProcess);
NtClose(ProcessInformation.hThread);
return 0;
}
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
{
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
return;
}
DWORD
STDCALL
WaitForInputIdle(
HANDLE hProcess,
DWORD dwMilliseconds
)
DWORD STDCALL WaitForInputIdle(HANDLE hProcess,
DWORD dwMilliseconds)
{
return 0;
return 0;
}
VOID
@ -428,10 +459,11 @@ SleepEx(
BOOL bAlertable
)
{
LARGE_INTEGER Interval;
TIME Interval;
NTSTATUS errCode;
SET_LARGE_INTEGER_LOW_PART(Interval,dwMilliseconds*1000);
Interval.LowPart = dwMilliseconds * 1000;
Interval.HighPart = 0;
errCode = NtDelayExecution(bAlertable,&Interval);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
@ -458,8 +490,8 @@ GetStartupInfoW(
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
lstrcpyW(lpStartupInfo->lpDesktop,(WCHAR *) pPeb->StartupInfo->Desktop);
lstrcpyW(lpStartupInfo->lpTitle, (WCHAR *)pPeb->StartupInfo->Title);
lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
@ -505,7 +537,7 @@ GetStartupInfoA(
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpDesktop[i] = (char)pPeb->StartupInfo->Desktop[i];
lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
i++;
}
lpStartupInfo->lpDesktop[i] = 0;
@ -513,7 +545,7 @@ GetStartupInfoA(
i = 0;
while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpTitle[i] = (char)pPeb->StartupInfo->Title[i];
lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
i++;
}
lpStartupInfo->lpTitle[i] = 0;
@ -557,18 +589,9 @@ FlushInstructionCache(
return TRUE;
}
VOID
STDCALL
ExitProcess(
UINT uExitCode
)
{
NtTerminateProcess(
NtCurrentProcess() ,
uExitCode
);
VOID STDCALL ExitProcess(UINT uExitCode)
{
NtTerminateProcess(NtCurrentProcess() ,uExitCode);
}
VOID
@ -594,44 +617,9 @@ FatalAppExitA(
VOID
STDCALL
FatalAppExitW(
UINT uAction,
LPCWSTR lpMessageText
)
VOID STDCALL FatalAppExitW(UINT uAction, LPCWSTR lpMessageText)
{
return;
return;
}
HMODULE
STDCALL
GetModuleHandleA(
LPCSTR lpModuleName
)
{
if ( lpModuleName == NULL )
return 0x00010000; // starting address of current module
else
return NULL; // should return the address of the specified module
return NULL;
}
HMODULE
STDCALL
GetModuleHandleW(
LPCWSTR lpModuleName
)
{
if ( lpModuleName == NULL )
return 0x00010000; // starting address of current module
else
return NULL; // should return the address of the specified module
return NULL;
}

View file

@ -13,7 +13,7 @@
#include <kernel32/thread.h>
#include <ddk/ntddk.h>
#include <string.h>
#include <internal/i386/segment.h>
HANDLE
STDCALL
@ -45,47 +45,64 @@ CreateRemoteThread(
LPDWORD lpThreadId
)
{
NTSTATUS errCode;
HANDLE ThreadHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId;
CONTEXT ThreadContext;
INITIAL_TEB InitialTeb;
BOOLEAN CreateSuspended = FALSE;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
ObjectAttributes.Attributes = 0;
if ( lpThreadAttributes != NULL ) {
if ( lpThreadAttributes->bInheritHandle )
ObjectAttributes.Attributes = OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
}
ObjectAttributes.SecurityQualityOfService = NULL;
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
NTSTATUS errCode;
HANDLE ThreadHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId;
CONTEXT ThreadContext;
INITIAL_TEB InitialTeb;
BOOLEAN CreateSuspended = FALSE;
ULONG BaseAddress;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
ObjectAttributes.ObjectName = NULL;
ObjectAttributes.Attributes = 0;
if ( lpThreadAttributes != NULL ) {
if ( lpThreadAttributes->bInheritHandle )
ObjectAttributes.Attributes = OBJ_INHERIT;
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
}
ObjectAttributes.SecurityQualityOfService = NULL;
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
CreateSuspended = TRUE;
else
CreateSuspended = FALSE;
// fix context
GetThreadContext(NtCurrentThread(),&ThreadContext);
// fix teb [ stack context ] --> check the image file
else
CreateSuspended = FALSE;
errCode = NtCreateThread(
&ThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
hProcess,
&ClientId,
&ThreadContext,
&InitialTeb,
CreateSuspended
);
if ( lpThreadId != NULL )
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
BaseAddress = 0;
ZwAllocateVirtualMemory(hProcess,
&BaseAddress,
0,
&dwStackSize,
MEM_COMMIT,
PAGE_READWRITE);
return ThreadHandle;
memset(&ThreadContext,0,sizeof(CONTEXT));
ThreadContext.Eip = lpStartAddress;
ThreadContext.SegGs = USER_DS;
ThreadContext.SegFs = USER_DS;
ThreadContext.SegEs = USER_DS;
ThreadContext.SegDs = USER_DS;
ThreadContext.SegCs = USER_CS;
ThreadContext.SegSs = USER_DS;
ThreadContext.Esp = BaseAddress + dwStackSize;
ThreadContext.EFlags = (1<<1) + (1<<9);
errCode = NtCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
hProcess,
&ClientId,
&ThreadContext,
&InitialTeb,
CreateSuspended);
if ( lpThreadId != NULL )
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
return ThreadHandle;
}
NT_TEB *GetTeb(VOID)
@ -93,27 +110,20 @@ NT_TEB *GetTeb(VOID)
return NULL;
}
WINBOOL STDCALL
SwitchToThread(VOID )
WINBOOL STDCALL SwitchToThread(VOID )
{
NTSTATUS errCode;
errCode = NtYieldExecution();
return TRUE;
}
DWORD
STDCALL
GetCurrentThreadId()
DWORD STDCALL GetCurrentThreadId()
{
return (DWORD)(GetTeb()->Cid).UniqueThread;
}
VOID
STDCALL
ExitThread(
UINT uExitCode
)
VOID STDCALL ExitThread(UINT uExitCode)
{
NTSTATUS errCode;

View file

@ -18,17 +18,22 @@
/* TYPES *********************************************************************/
#define CACHE_SEGMENT_INVALID (0) // Isn't valid
#define CACHE_SEGMENT_WRITTEN (1) // Written
#define CACHE_SEGMENT_READ (2)
typedef struct _CACHE_SEGMENT
{
ULONG Type;
ULONG Type; // Debugging
ULONG Size;
LIST_ENTRY ListEntry;
PVOID BaseAddress;
ULONG Length;
ULONG State;
MEMORY_AREA* MemoryArea;
ULONG FileOffset;
ULONG InternalOffset;
LIST_ENTRY ListEntry; // Entry in the per-open list of segments
PVOID BaseAddress; // Base address of the mapping
ULONG Length; // Length of the mapping
ULONG State; // Information
MEMORY_AREA* MemoryArea; // Memory area for the mapping
ULONG FileOffset; // Offset within the file of the mapping
KEVENT Event;
BOOLEAN Dirty; // Contains dirty data
} CACHE_SEGMENT, *PCACHE_SEGMENT;
typedef struct _CC1_CCB
@ -36,35 +41,36 @@ typedef struct _CC1_CCB
ULONG Type;
ULONG Size;
LIST_ENTRY CacheSegmentListHead;
KSPIN_LOCK CacheSegmentListLock;
LIST_ENTRY ListEntry;
} CC1_CCB, PCC1_CCB;
/* FUNCTIONS *****************************************************************/
PVOID Cc1FlushView(PFILE_OBJECT FileObject,
PVOID Cc1FlushView(PCC1_CCB CacheDesc,
ULONG FileOffset,
ULONG Length)
{
}
PVOID Cc1PurgeView(PFILE_OBJECT FileObject,
PVOID Cc1PurgeView(PCC1_CCB CacheDesc,
ULONG FileOffset,
ULONG Length)
{
}
VOID Cc1ViewIsUpdated(PFILE_OBJECT FileObject,
ULONG FileOffset)
BOOLEAN Cc1AcquireCacheSegment(PCACHE_SEGMENT CacheSegment,
BOOLEAN AcquireForWrite,
BOOLEAN Wait)
{
}
typedef
BOOLEAN Cc1RequestView(PFILE_OBJECT FileObject,
ULONG FileOffset,
ULONG Length,
BOOLEAN Wait,
BOOLEAN AcquireForWrite)
PVOID Cc1RequestView(PCC1_CCB CacheDesc,
ULONG FileOffset,
ULONG Length,
BOOLEAN Wait,
BOOLEAN AcquireForWrite)
/*
* FUNCTION: Request a view for caching data
* ARGUMENTS:
@ -79,11 +85,41 @@ BOOLEAN Cc1RequestView(PFILE_OBJECT FileObject,
* False otherwise
*/
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
KeAcquireSpinLock(&CacheDesc->CacheSegmentListLock);
current_entry = CacheDesc->CacheSegmentListHead.Flink;
while (current_entry != &CacheDesc->CacheSegmentListHead)
{
current = CONTAING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
if (current->FileOffset <= FileOffset &&
(current->FileOffset + current->length) >= (FileOffset + Length))
{
if (!Cc1AcquireCacheSegment(AcquireForWrite, Wait))
{
return(NULL);
}
return(current->BaseAddress + (FileOffset - current->FileOffset));
}
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&CacheDesc->CacheSegmentListLock);
}
BOOLEAN Cc1InitializeFileCache(PFILE_OBJECT FileObject)
PCC1_CCB Cc1InitializeFileCache(PFILE_OBJECT FileObject)
/*
* FUNCTION: Initialize caching for a file
*/
{
PCC1_CCB CacheDesc;
CacheDesc = ExAllocatePool(NonPagedPool, sizeof(CC1_CCB));
InitializeListHead(&CacheDesc->CacheSegmentListHead);
KeAcquireSpinLock(&CacheDesc->CacheSegmentListLock);
return(CacheDesc);
}

View file

@ -263,7 +263,7 @@ VOID KeDumpStackFrames(ULONG DummyArg)
Stack = (PVOID)(((ULONG)Stack) & (~0x3));
DbgPrint("Frames:\n");
for (i=0; i<1024; i++)
for (i=0; i<32; i++)
{
if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
{

View file

@ -1,330 +1,351 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/thread.c
* PURPOSE: HAL multitasking functions
* PROGRAMMER: David Welch (welch@mcmail.com)
* REVISION HISTORY:
* 27/06/98: Created
*/
/* INCLUDES ****************************************************************/
#include <windows.h>
#include <ddk/ntddk.h>
#include <internal/ntoskrnl.h>
#include <internal/ps.h>
#include <internal/string.h>
#include <internal/hal.h>
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ***************************************************************/
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
VOID PsBeginThreadWithContextInternal(VOID);
#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
static char null_ldt[8]={0,};
static unsigned int null_ldt_sel=0;
static PETHREAD FirstThread=NULL;
/* FUNCTIONS **************************************************************/
void HalTaskSwitch(PKTHREAD thread)
/*
* FUNCTION: Switch tasks
* ARGUMENTS:
* thread = Thread to switch to
* NOTE: This function will not return until the current thread is scheduled
* again
*/
{
DPRINT("Scheduling thread %x\n",thread);
DPRINT("Scheduling thread %x\n",thread->Context.nr);
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
thread->Context.previous_task,thread->Context.reserved1,
thread->Context.esp0,thread->Context.ss0);
DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
thread->Context.eflags,thread->Context.eax);
DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
thread->Context.esp,thread->Context.ebp,thread->Context.esi);
DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
thread->Context.edi,thread->Context.es,thread->Context.reserved5,
thread->Context.cs,thread->Context.reserved6);
DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
thread->Context.reserved8,thread->Context.fs);
DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
thread->Context.reserved9,thread->Context.gs,
thread->Context.reserved10,thread->Context.ldt,
thread->Context.reserved11);
DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
thread->Context.trap,thread->Context.iomap_base,
thread->Context.nr,thread->Context.io_bitmap[0]);
DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",
&(gdt[thread->Context.nr/8].a),
gdt[thread->Context.nr/8].a,
gdt[thread->Context.nr/8].b);
__asm__("pushfl\n\t"
"cli\n\t"
"ljmp %0\n\t"
"popfl\n\t"
: /* No outputs */
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
: "ax","dx");
}
static unsigned int allocate_tss_descriptor(void)
/*
* FUNCTION: Allocates a slot within the GDT to describe a TSS
* RETURNS: The offset within the GDT of the slot allocated on succcess
* Zero on failure
*/
{
unsigned int i;
for (i=0;i<16;i++)
{
if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
gdt[FIRST_TSS_OFFSET + i].b==0)
{
return(FIRST_TSS_OFFSET + i);
}
}
return(0);
}
#define FLAG_NT (1<<14)
#define FLAG_VM (1<<17)
#define FLAG_IF (1<<9)
#define FLAG_IOPL ((1<<12)+(1<<13))
NTSTATUS KeValidateUserContext(PCONTEXT Context)
/*
* FUNCTION: Validates a processor context
* ARGUMENTS:
* Context = Context to validate
* RETURNS: Status
* NOTE: This only validates the context as not violating system security, it
* doesn't guararantee the thread won't crash at some point
* NOTE2: This relies on there only being two selectors which can access
* system space
*/
{
if (Context->Eip >= KERNEL_BASE)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegCs == KERNEL_CS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegDs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegEs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegFs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegGs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if ((Context->EFlags & FLAG_IOPL) != 0 ||
(Context->EFlags & FLAG_NT) ||
(Context->EFlags & FLAG_VM) ||
(!(Context->EFlags & FLAG_IF)))
{
return(STATUS_UNSUCCESSFUL);
}
return(STATUS_SUCCESS);
}
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
/*
* FUNCTION: Initialize a task with a user mode context
* ARGUMENTS:
* Thread = Thread to initialize
* Context = Processor context to initialize it with
* RETURNS: Status
*/
{
unsigned int desc;
unsigned int length;
unsigned int base;
PVOID kernel_stack;
NTSTATUS Status;
PVOID stack_start;
DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
Thread,Context);
assert(sizeof(hal_thread_state)>=0x68);
if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
{
return(Status);
}
desc = allocate_tss_descriptor();
length = sizeof(hal_thread_state) - 1;
base = (unsigned int)(&(Thread->Tcb.Context));
kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
/*
* Setup a TSS descriptor
*/
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
memcpy(stack_start, Context, sizeof(CONTEXT));
/*
* Initialize the thread context
*/
memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
Thread->Tcb.Context.ldt = null_ldt_sel;
Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
Thread->Tcb.Context.esp0 = stack_start;
Thread->Tcb.Context.ss0 = KERNEL_DS;
Thread->Tcb.Context.esp = stack_start;
Thread->Tcb.Context.ss = KERNEL_DS;
Thread->Tcb.Context.cs = KERNEL_CS;
Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;
Thread->Tcb.Context.io_bitmap[0] = 0xff;
Thread->Tcb.Context.cr3 =
linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
Thread->Tcb.Context.ds = KERNEL_DS;
Thread->Tcb.Context.es = KERNEL_DS;
Thread->Tcb.Context.fs = KERNEL_DS;
Thread->Tcb.Context.gs = KERNEL_DS;
Thread->Tcb.Context.nr = desc * 8;
DPRINT("Allocated %x\n",desc*8);
return(STATUS_SUCCESS);
}
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
/*
* FUNCTION: Initializes the HAL portion of a thread object
* ARGUMENTS:
* thread = Object describes the thread
* fn = Entrypoint for the thread
* StartContext = parameter to pass to the thread entrypoint
* RETURNS: True if the function succeeded
*/
{
unsigned int desc = allocate_tss_descriptor();
unsigned int length = sizeof(hal_thread_state) - 1;
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
thread,fn,StartContext);
DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
/*
* Make sure
*/
assert(sizeof(hal_thread_state)>=0x68);
/*
* Setup a TSS descriptor
*/
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
// DPRINT("desc %d\n",desc);
DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",
&(gdt[desc].a),
gdt[desc].a,
gdt[desc].b);
/*
* Initialize the stack for the thread (including the two arguments to
* the general start routine).
*/
kernel_stack[1023] = (unsigned int)StartContext;
kernel_stack[1022] = (unsigned int)fn;
kernel_stack[1021] = NULL;
/*
* Initialize the thread context
*/
memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
thread->Tcb.Context.ldt = null_ldt_sel;
thread->Tcb.Context.eflags = (1<<1)+(1<<9);
thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
thread->Tcb.Context.esp0 = &kernel_stack[1021];
thread->Tcb.Context.ss0 = KERNEL_DS;
thread->Tcb.Context.esp = &kernel_stack[1021];
thread->Tcb.Context.ss = KERNEL_DS;
thread->Tcb.Context.cs = KERNEL_CS;
thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
thread->Tcb.Context.io_bitmap[0] = 0xff;
thread->Tcb.Context.cr3 =
linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
thread->Tcb.Context.ds = KERNEL_DS;
thread->Tcb.Context.es = KERNEL_DS;
thread->Tcb.Context.fs = KERNEL_DS;
thread->Tcb.Context.gs = KERNEL_DS;
thread->Tcb.Context.nr = desc * 8;
DPRINT("Allocated %x\n",desc*8);
return(TRUE);
}
void HalInitFirstTask(PETHREAD thread)
/*
* FUNCTION: Called to setup the HAL portion of a thread object for the
* initial thread
*/
{
unsigned int base;
unsigned int length;
unsigned int desc;
memset(null_ldt,0,sizeof(null_ldt));
desc = allocate_tss_descriptor();
base = (unsigned int)&null_ldt;
length = sizeof(null_ldt) - 1;
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
| (base & 0xff000000);
null_ldt_sel = desc*8;
/*
* Initialize the thread context
*/
HalInitTask(thread,NULL,NULL);
/*
* Load the task register
*/
__asm__("ltr %%ax"
: /* no output */
: "a" (thread->Tcb.Context.nr));
FirstThread = thread;
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/thread.c
* PURPOSE: HAL multitasking functions
* PROGRAMMER: David Welch (welch@mcmail.com)
* REVISION HISTORY:
* 27/06/98: Created
*/
/* INCLUDES ****************************************************************/
#include <windows.h>
#include <ddk/ntddk.h>
#include <internal/ntoskrnl.h>
#include <internal/ps.h>
#include <internal/string.h>
#include <internal/hal.h>
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ***************************************************************/
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
VOID PsBeginThreadWithContextInternal(VOID);
#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
static char null_ldt[8]={0,};
static unsigned int null_ldt_sel=0;
static PETHREAD FirstThread=NULL;
/* FUNCTIONS **************************************************************/
void HalTaskSwitch(PKTHREAD thread)
/*
* FUNCTION: Switch tasks
* ARGUMENTS:
* thread = Thread to switch to
* NOTE: This function will not return until the current thread is scheduled
* again
*/
{
DPRINT("Scheduling thread %x\n",thread);
DPRINT("Scheduling thread %x\n",thread->Context.nr);
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
thread->Context.previous_task,thread->Context.reserved1,
thread->Context.esp0,thread->Context.ss0);
DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
thread->Context.eflags,thread->Context.eax);
DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
thread->Context.esp,thread->Context.ebp,thread->Context.esi);
DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
thread->Context.edi,thread->Context.es,thread->Context.reserved5,
thread->Context.cs,thread->Context.reserved6);
DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
thread->Context.reserved8,thread->Context.fs);
DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
thread->Context.reserved9,thread->Context.gs,
thread->Context.reserved10,thread->Context.ldt,
thread->Context.reserved11);
DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
thread->Context.trap,thread->Context.iomap_base,
thread->Context.nr,thread->Context.io_bitmap[0]);
DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",
&(gdt[thread->Context.nr/8].a),
gdt[thread->Context.nr/8].a,
gdt[thread->Context.nr/8].b);
__asm__("pushfl\n\t"
"cli\n\t"
"ljmp %0\n\t"
"popfl\n\t"
: /* No outputs */
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
: "ax","dx");
}
static unsigned int allocate_tss_descriptor(void)
/*
* FUNCTION: Allocates a slot within the GDT to describe a TSS
* RETURNS: The offset within the GDT of the slot allocated on succcess
* Zero on failure
*/
{
unsigned int i;
for (i=0;i<16;i++)
{
if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
gdt[FIRST_TSS_OFFSET + i].b==0)
{
return(FIRST_TSS_OFFSET + i);
}
}
return(0);
}
#define FLAG_NT (1<<14)
#define FLAG_VM (1<<17)
#define FLAG_IF (1<<9)
#define FLAG_IOPL ((1<<12)+(1<<13))
NTSTATUS KeValidateUserContext(PCONTEXT Context)
/*
* FUNCTION: Validates a processor context
* ARGUMENTS:
* Context = Context to validate
* RETURNS: Status
* NOTE: This only validates the context as not violating system security, it
* doesn't guararantee the thread won't crash at some point
* NOTE2: This relies on there only being two selectors which can access
* system space
*/
{
if (Context->Eip >= KERNEL_BASE)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegCs == KERNEL_CS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegDs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegEs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegFs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if (Context->SegGs == KERNEL_DS)
{
return(STATUS_UNSUCCESSFUL);
}
if ((Context->EFlags & FLAG_IOPL) != 0 ||
(Context->EFlags & FLAG_NT) ||
(Context->EFlags & FLAG_VM) ||
(!(Context->EFlags & FLAG_IF)))
{
return(STATUS_UNSUCCESSFUL);
}
return(STATUS_SUCCESS);
}
NTSTATUS HalReleaseTask(PETHREAD Thread)
{
gdt[Thread->Tcb.Context.nr/8].a=0;
gdt[Thread->Tcb.Context.nr/8].b=0;
ExFreePool(Thread->Tcb.Context.KernelStackBase);
if (Thread->Tcb.Context.SavedKernelStackBase != NULL)
{
ExFreePool(Thread->Tcb.Context.KernelStackBase);
}
}
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
/*
* FUNCTION: Initialize a task with a user mode context
* ARGUMENTS:
* Thread = Thread to initialize
* Context = Processor context to initialize it with
* RETURNS: Status
*/
{
unsigned int desc;
unsigned int length;
unsigned int base;
PVOID kernel_stack;
NTSTATUS Status;
PVOID stack_start;
DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
Thread,Context);
assert(sizeof(hal_thread_state)>=0x68);
if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
{
return(Status);
}
desc = allocate_tss_descriptor();
if (desc == 0)
{
return(STATUS_UNSUCCESSFUL);
}
length = sizeof(hal_thread_state) - 1;
base = (unsigned int)(&(Thread->Tcb.Context));
kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
/*
* Setup a TSS descriptor
*/
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
memcpy(stack_start, Context, sizeof(CONTEXT));
/*
* Initialize the thread context
*/
memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
Thread->Tcb.Context.ldt = null_ldt_sel;
Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
Thread->Tcb.Context.esp0 = (ULONG)stack_start;
Thread->Tcb.Context.ss0 = KERNEL_DS;
Thread->Tcb.Context.esp = stack_start;
Thread->Tcb.Context.ss = KERNEL_DS;
Thread->Tcb.Context.cs = KERNEL_CS;
Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;
Thread->Tcb.Context.io_bitmap[0] = 0xff;
Thread->Tcb.Context.cr3 =
linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
Thread->Tcb.Context.ds = KERNEL_DS;
Thread->Tcb.Context.es = KERNEL_DS;
Thread->Tcb.Context.fs = KERNEL_DS;
Thread->Tcb.Context.gs = KERNEL_DS;
Thread->Tcb.Context.nr = desc * 8;
Thread->Tcb.Context.KernelStackBase = kernel_stack;
Thread->Tcb.Context.SavedKernelEsp = 0;
Thread->Tcb.Context.SavedKernelStackBase = NULL;
return(STATUS_SUCCESS);
}
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
/*
* FUNCTION: Initializes the HAL portion of a thread object
* ARGUMENTS:
* thread = Object describes the thread
* fn = Entrypoint for the thread
* StartContext = parameter to pass to the thread entrypoint
* RETURNS: True if the function succeeded
*/
{
unsigned int desc = allocate_tss_descriptor();
unsigned int length = sizeof(hal_thread_state) - 1;
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
PULONG kernel_stack = ExAllocatePool(NonPagedPool,4096);
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
thread,fn,StartContext);
DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
/*
* Make sure
*/
assert(sizeof(hal_thread_state)>=0x68);
/*
* Setup a TSS descriptor
*/
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
| (base & 0xff000000);
// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
// DPRINT("desc %d\n",desc);
DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",
&(gdt[desc].a),
gdt[desc].a,
gdt[desc].b);
/*
* Initialize the stack for the thread (including the two arguments to
* the general start routine).
*/
kernel_stack[1023] = (unsigned int)StartContext;
kernel_stack[1022] = (unsigned int)fn;
kernel_stack[1021] = NULL;
/*
* Initialize the thread context
*/
memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
thread->Tcb.Context.ldt = null_ldt_sel;
thread->Tcb.Context.eflags = (1<<1)+(1<<9);
thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
thread->Tcb.Context.esp0 = &kernel_stack[1021];
thread->Tcb.Context.ss0 = KERNEL_DS;
thread->Tcb.Context.esp = &kernel_stack[1021];
thread->Tcb.Context.ss = KERNEL_DS;
thread->Tcb.Context.cs = KERNEL_CS;
thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
thread->Tcb.Context.io_bitmap[0] = 0xff;
thread->Tcb.Context.cr3 =
linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
thread->Tcb.Context.ds = KERNEL_DS;
thread->Tcb.Context.es = KERNEL_DS;
thread->Tcb.Context.fs = KERNEL_DS;
thread->Tcb.Context.gs = KERNEL_DS;
thread->Tcb.Context.nr = desc * 8;
thread->Tcb.Context.KernelStackBase = kernel_stack;
thread->Tcb.Context.SavedKernelEsp = 0;
thread->Tcb.Context.SavedKernelStackBase = NULL;
DPRINT("Allocated %x\n",desc*8);
return(TRUE);
}
void HalInitFirstTask(PETHREAD thread)
/*
* FUNCTION: Called to setup the HAL portion of a thread object for the
* initial thread
*/
{
unsigned int base;
unsigned int length;
unsigned int desc;
memset(null_ldt,0,sizeof(null_ldt));
desc = allocate_tss_descriptor();
base = (unsigned int)&null_ldt;
length = sizeof(null_ldt) - 1;
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
| (base & 0xff000000);
null_ldt_sel = desc*8;
/*
* Initialize the thread context
*/
HalInitTask(thread,NULL,NULL);
/*
* Load the task register
*/
__asm__("ltr %%ax"
: /* no output */
: "a" (thread->Tcb.Context.nr));
FirstThread = thread;
}

View file

@ -125,16 +125,14 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle,
DeviceObject = (PDEVICE_OBJECT)Object;
DPRINT("DeviceObject %x\n",DeviceObject);
DeviceObject = IoGetAttachedDevice(DeviceObject);
DPRINT("DeviceObject %x\n",DeviceObject);
if (Status == STATUS_SUCCESS)
{
CHECKPOINT;
FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
ObjectAttributes->ObjectName->Length);
(ObjectAttributes->ObjectName->Length+1)*2);
FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
FileObject->FileName.MaximumLength =
ObjectAttributes->ObjectName->MaximumLength;
@ -197,7 +195,6 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle,
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp==NULL)
{
ExFreePool(FileObject->FileName.Buffer);
ObDereferenceObject(FileObject);
ZwClose(*FileHandle);
*FileHandle=0;
@ -223,13 +220,14 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle,
if (Status!=STATUS_SUCCESS)
{
DPRINT("FileObject->FileName.Buffer %x\n",FileObject->FileName.Buffer);
ExFreePool(FileObject->FileName.Buffer);
ObDereferenceObject(FileObject);
ZwClose(*FileHandle);
*FileHandle=0;
return(Status);
}
DPRINT("*FileHandle %x\n",*FileHandle);
ObDereferenceObject(FileObject);
return(Status);

View file

@ -141,11 +141,12 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
FILE_LIST_DIRECTORY,
IoFileType,
UserMode,
(PVOID *)&FileObject,
(PVOID *)&FileObject,
NULL);
if (Status != STATUS_SUCCESS)
{
ObDereferenceObject(FileObject);
return(Status);
}
KeInitializeEvent(&Event,NotificationEvent,FALSE);
@ -153,7 +154,10 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (Irp==NULL)
return STATUS_UNSUCCESSFUL;
{
ObDereferenceObject(FileObject);
return STATUS_UNSUCCESSFUL;
}
Irp->UserIosb = IoStatusBlock;
@ -203,6 +207,7 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
}
Status = IoStatusBlock->Status;
}
ObDereferenceObject(FileObject);
return(Status);
}

View file

@ -13,7 +13,7 @@
#include <ddk/ntddk.h>
#include <internal/io.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* TYPES *******************************************************************/

View file

@ -26,6 +26,16 @@ POBJECT_TYPE IoFileType = NULL;
/* FUNCTIONS ****************************************************************/
VOID IopCloseFile(PVOID ObjectBody)
{
PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
if (FileObject->FileName.Buffer != NULL)
{
ExFreePool(FileObject->FileName.Buffer);
}
}
VOID IoInit(VOID)
{
OBJECT_ATTRIBUTES attr;
@ -46,7 +56,7 @@ VOID IoInit(VOID)
IoDeviceType->NonpagedPoolCharge = sizeof(DEVICE_OBJECT);
IoDeviceType->Dump = NULL;
IoDeviceType->Open = NULL;
IoDeviceType->Close = NULL;
IoDeviceType->Close = NULL;
IoDeviceType->Delete = NULL;
IoDeviceType->Parse = NULL;
IoDeviceType->Security = NULL;
@ -66,7 +76,7 @@ VOID IoInit(VOID)
IoFileType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
IoFileType->Dump = NULL;
IoFileType->Open = NULL;
IoFileType->Close = NULL;
IoFileType->Close = IopCloseFile;
IoFileType->Delete = NULL;
IoFileType->Parse = NULL;
IoFileType->Security = NULL;

View file

@ -61,7 +61,7 @@ VOID KeDeliverKernelApc(PKAPC Apc)
Stack[1] = TargetThread->Context.eip;
Stack[2] = TargetThread->Context.cs;
Stack[3] = TargetThread->Context.eflags;
TargetThread->Context.eip = KeApcProlog;
TargetThread->Context.eip = (ULONG)KeApcProlog;
TargetThread->Context.eax = (ULONG)Apc;
}
else
@ -78,7 +78,7 @@ VOID KeDeliverKernelApc(PKAPC Apc)
Stack[2] = TargetThread->Context.cs;
Stack[1] = TargetThread->Context.eip;
Stack[0] = TargetThread->Context.eax;
TargetThread->Context.eip = KeApcProlog;
TargetThread->Context.eip = (ULONG)KeApcProlog;
TargetThread->Context.eax = (ULONG)Apc;
}

View file

@ -46,8 +46,7 @@ LONG KeSetEvent(PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait)
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
KeAcquireDispatcherDatabaseLock(Wait);
// ret = InterlockedExchange(&(Event->Header.SignalState),1);
Event->Header.SignalState=1;
ret = InterlockedExchange(&(Event->Header.SignalState),1);
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
KeReleaseDispatcherDatabaseLock(Wait);
}

View file

@ -532,9 +532,9 @@ BOOLEAN KiTimerInterrupt(VOID)
}
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,ticks);
memset(str, 0, sizeof(str));
// sprintf(str,"%.8u %.8u",EiNrUsedBlocks,KiTimerTicks);
sprintf(str,"%.8u %.8u",EiNrUsedBlocks,KiTimerTicks);
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
sprintf(str,"%.8u %.8u",PiNrThreads,KiTimerTicks);
// sprintf(str,"%.8u %.8u",PiNrThreads,KiTimerTicks);
for (i=0;i<17;i++)
{
*vidmem=str[i];

View file

@ -1,118 +1,118 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pool.c
* PURPOSE: Implements the kernel memory pool
* PROGRAMMER: David Welch (welch@mcmail.com)
*/
/* INCLUDES ****************************************************************/
#include <internal/ntoskrnl.h>
#include <ddk/ntddk.h>
#include <internal/pool.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/
#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
/* FUNCTIONS ***************************************************************/
PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)
/*
* FUNCTION: Allocates pool memory of a specified type and returns a pointer
* to the allocated block. This routine is used for general purpose allocation
* of memory
* ARGUMENTS:
* PoolType
* Specifies the type of memory to allocate which can be one
* of the following:
*
* NonPagedPool
* NonPagedPoolMustSucceed
* NonPagedPoolCacheAligned
* NonPagedPoolCacheAlignedMustS
* PagedPool
* PagedPoolCacheAligned
*
* NumberOfBytes
* Specifies the number of bytes to allocate
* RETURNS: The allocated block on success
* NULL on failure
*/
{
PVOID Block;
// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",
// NumberOfBytes,((PULONG)&PoolType)[-1]);
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);
// DbgPrint("ExAllocatePool() = %x\n",Block);
return(Block);
}
PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)
{
PVOID Block;
if (type == NonPagedPoolCacheAligned ||
type == NonPagedPoolCacheAlignedMustS)
{
UNIMPLEMENTED;
}
switch(type)
{
case NonPagedPool:
case NonPagedPoolMustSucceed:
case NonPagedPoolCacheAligned:
case NonPagedPoolCacheAlignedMustS:
Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);
break;
case PagedPool:
case PagedPoolCacheAligned:
Block = ExAllocatePagedPoolWithTag(type,size,Tag);
break;
default:
return(NULL);
};
if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)
&& Block==NULL)
{
KeBugCheck(MUST_SUCCEED_POOL_EMPTY);
}
return(Block);
}
PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,
ULONG Tag)
{
PVOID Block;
PKTHREAD current = KeGetCurrentThread();
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);
switch(PoolType)
{
case NonPagedPool:
case NonPagedPoolMustSucceed:
case NonPagedPoolCacheAligned:
case NonPagedPoolCacheAlignedMustS:
// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;
break;
case PagedPool:
case PagedPoolCacheAligned:
// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;
break;
};
return(Block);
}
PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)
{
return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pool.c
* PURPOSE: Implements the kernel memory pool
* PROGRAMMER: David Welch (welch@mcmail.com)
*/
/* INCLUDES ****************************************************************/
#include <internal/ntoskrnl.h>
#include <ddk/ntddk.h>
#include <internal/pool.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/
#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
/* FUNCTIONS ***************************************************************/
PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)
/*
* FUNCTION: Allocates pool memory of a specified type and returns a pointer
* to the allocated block. This routine is used for general purpose allocation
* of memory
* ARGUMENTS:
* PoolType
* Specifies the type of memory to allocate which can be one
* of the following:
*
* NonPagedPool
* NonPagedPoolMustSucceed
* NonPagedPoolCacheAligned
* NonPagedPoolCacheAlignedMustS
* PagedPool
* PagedPoolCacheAligned
*
* NumberOfBytes
* Specifies the number of bytes to allocate
* RETURNS: The allocated block on success
* NULL on failure
*/
{
PVOID Block;
// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",
// NumberOfBytes,((PULONG)&PoolType)[-1]);
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);
// DbgPrint("ExAllocatePool() = %x\n",Block);
return(Block);
}
PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)
{
PVOID Block;
if (type == NonPagedPoolCacheAligned ||
type == NonPagedPoolCacheAlignedMustS)
{
UNIMPLEMENTED;
}
switch(type)
{
case NonPagedPool:
case NonPagedPoolMustSucceed:
case NonPagedPoolCacheAligned:
case NonPagedPoolCacheAlignedMustS:
Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);
break;
case PagedPool:
case PagedPoolCacheAligned:
Block = ExAllocatePagedPoolWithTag(type,size,Tag);
break;
default:
return(NULL);
};
if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)
&& Block==NULL)
{
KeBugCheck(MUST_SUCCEED_POOL_EMPTY);
}
return(Block);
}
PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,
ULONG Tag)
{
PVOID Block;
PKTHREAD current = KeGetCurrentThread();
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);
switch(PoolType)
{
case NonPagedPool:
case NonPagedPoolMustSucceed:
case NonPagedPoolCacheAligned:
case NonPagedPoolCacheAlignedMustS:
// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;
break;
case PagedPool:
case PagedPoolCacheAligned:
// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;
break;
};
return(Block);
}
PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)
{
return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));
}

View file

@ -177,9 +177,9 @@ NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,
current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
DPRINT("Scanning %w\n",current->Name.Buffer);
DirObjInformation[i].ObjectName.Buffer =
ExAllocatePool(NonPagedPool, current->Name.Length + sizeof(WCHAR));
ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);
DirObjInformation[i].ObjectName.Length = current->Name.Length;
DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length + sizeof(WCHAR);
DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;
DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
DirObjInformation[i].ObjectName.Buffer);
RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
@ -552,4 +552,3 @@ NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,
return(Status);
}

View file

@ -61,6 +61,14 @@ NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,
UNIMPLEMENTED
}
VOID ObMakeTemporaryObject(PVOID ObjectBody)
{
POBJECT_HEADER ObjectHeader;
ObjectHeader = BODY_TO_HEADER(ObjectBody);
ObjectHeader->Permanent = FALSE;
}
NTSTATUS NtMakeTemporaryObject(HANDLE Handle)
{
return(ZwMakeTemporaryObject(Handle));
@ -148,14 +156,13 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",
// ObjectAttributes->ObjectName->MaximumLength);
Buffer = ExAllocatePool(NonPagedPool,
((ObjectAttributes->ObjectName->Length + 1) *
sizeof(WCHAR)));
((ObjectAttributes->ObjectName->Length+1)*2));
if (Buffer==NULL)
{
return(NULL);
}
memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,
(ObjectAttributes->ObjectName->Length + 1) * sizeof(WCHAR));
(ObjectAttributes->ObjectName->Length+1)*2);
/*
* Seperate the name into a path and name
@ -255,13 +262,27 @@ NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
{
DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
Header,Header->RefCount,Header->HandleCount);
if (Header->RefCount < 0 || Header->HandleCount < 0)
{
KeBugCheck(0);
}
if (Header->RefCount == 0 && Header->HandleCount == 0 &&
!Header->Permanent)
{
if (Header->ObjectType != NULL &&
Header->ObjectType->Close != NULL)
{
Header->ObjectType->Close(HEADER_TO_BODY(Header));
}
if (Header->Name.Buffer != NULL)
{
ObRemoveEntry(Header);
}
DPRINT("ObPerformRetentionChecks() = Freeing object\n");
ExFreePool(Header);
}
return(STATUS_SUCCESS);
@ -304,6 +325,8 @@ NTSTATUS ZwClose(HANDLE Handle)
assert_irql(PASSIVE_LEVEL);
DPRINT("ZwClose(Handle %x)\n",Handle);
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
if (HandleRep == NULL)
{
@ -386,4 +409,3 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
return(STATUS_SUCCESS);
}

View file

@ -1,144 +1,151 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/kill.c
* PURPOSE: Terminating a thread
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ps.h>
#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
extern ULONG PiNrThreads;
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
IN NTSTATUS ExitStatus)
{
return(ZwTerminateProcess(ProcessHandle,ExitStatus));
}
NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
PEPROCESS Process;
KIRQL oldlvl;
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
UserMode,
(PVOID*)&Process,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
PiTerminateProcessThreads(Process, ExitStatus);
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader);
Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
if (PsGetCurrentThread()->ThreadsProcess == Process)
{
KeLowerIrql(oldlvl);
PsTerminateSystemThread(ExitStatus);
}
KeLowerIrql(oldlvl);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
return(ZwTerminateThread(ThreadHandle,ExitStatus));
}
NTSTATUS STDCALL ZwTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_TERMINATE,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
PsTerminateThread(Thread);
}
VOID PsTerminateThread(PETHREAD Thread, NTSTATUS ExitStatus)
{
if (Thread == PsGetCurrentThread())
{
PsTerminateSystemThread(ExitStatus);
}
else
{
UNIMPLEMENTED;
}
}
VOID PsReleaseThread(PETHREAD Thread)
{
DPRINT("PsReleaseThread(Thread %x)\n",Thread);
RemoveEntryList(&Thread->Tcb.Entry);
ObDereferenceObject(Thread);
}
NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
/*
* FUNCTION: Terminates the current thread
* ARGUMENTS:
* ExitStatus = Status to pass to the creater
* RETURNS: Doesn't
*/
{
KIRQL oldlvl;
PETHREAD CurrentThread;
PiNrThreads--;
CurrentThread = PsGetCurrentThread();
CurrentThread->ExitStatus = ExitStatus;
DPRINT("terminating %x\n",CurrentThread);
ObDereferenceObject(CurrentThread->ThreadsProcess);
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
ZwYieldExecution();
for(;;);
}
NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)
{
return(ZwRegisterThreadTerminatePort(TerminationPort));
}
NTSTATUS STDCALL ZwRegisterThreadTerminatePort(HANDLE TerminationPort)
{
UNIMPLEMENTED;
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/kill.c
* PURPOSE: Terminating a thread
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ps.h>
#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
extern ULONG PiNrThreads;
/* FUNCTIONS *****************************************************************/
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
{
KIRQL oldlvl;
PETHREAD CurrentThread;
PiNrThreads--;
CurrentThread = PsGetCurrentThread();
CurrentThread->ExitStatus = ExitStatus;
DPRINT("terminating %x\n",CurrentThread);
ObDereferenceObject(CurrentThread->ThreadsProcess);
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
ZwYieldExecution();
for(;;);
}
VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
{
UNIMPLEMENTED;
}
NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
IN NTSTATUS ExitStatus)
{
return(ZwTerminateProcess(ProcessHandle,ExitStatus));
}
NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
PEPROCESS Process;
KIRQL oldlvl;
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
UserMode,
(PVOID*)&Process,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
PiTerminateProcessThreads(Process, ExitStatus);
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader);
Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
if (PsGetCurrentThread()->ThreadsProcess == Process)
{
KeLowerIrql(oldlvl);
PsTerminateCurrentThread(ExitStatus);
}
KeLowerIrql(oldlvl);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
return(ZwTerminateThread(ThreadHandle,ExitStatus));
}
NTSTATUS STDCALL ZwTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_TERMINATE,
PsThreadType,
UserMode,
(PVOID*)&Thread,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
if (Thread == PsGetCurrentThread())
{
PsTerminateCurrentThread(ExitStatus);
}
else
{
PsTerminateOtherThread(Thread, ExitStatus);
}
}
VOID PsReleaseThread(PETHREAD Thread)
{
DPRINT("PsReleaseThread(Thread %x)\n",Thread);
RemoveEntryList(&Thread->Tcb.Entry);
HalReleaseTask(Thread);
ObDereferenceObject(Thread);
}
NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
/*
* FUNCTION: Terminates the current thread
* ARGUMENTS:
* ExitStatus = Status to pass to the creater
* RETURNS: Doesn't
*/
{
PsTerminateCurrentThread(ExitStatus);
}
NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)
{
return(ZwRegisterThreadTerminatePort(TerminationPort));
}
NTSTATUS STDCALL ZwRegisterThreadTerminatePort(HANDLE TerminationPort)
{
UNIMPLEMENTED;
}

View file

@ -310,4 +310,3 @@ NTSTATUS STDCALL ZwSetInformationProcess(IN HANDLE ProcessHandle,
{
UNIMPLEMENTED;
}

File diff suppressed because it is too large Load diff

View file

@ -1,61 +1,61 @@
bits 32
section .text
DECLARE_GLOBAL_SYMBOL InterlockedIncrement
push ebp
mov ebp,esp
push eax
push ebx
mov eax,1
mov ebx,[ebp+8]
xadd [ebx],eax
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DECLARE_GLOBAL_SYMBOL InterlockedDecrement
mov eax,0xffffffff
mov ebx,[esp+4]
xadd [ebx],eax
dec eax
ret
DECLARE_GLOBAL_SYMBOL InterlockedExchange
push ebp
mov ebp,esp
push eax
push ebx
mov eax,[ebp+12]
mov ebx,[ebp+8]
xchg [ebx],eax
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd
mov eax,[esp+8]
mov ebx,[esp+4]
xadd [ebx],eax
ret
DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange
mov eax,[esp+12]
mov edx,[esp+8]
mov ebx,[esp+4]
cmpxchg [ebx],edx
mov eax,edx
ret
bits 32
section .text
DECLARE_GLOBAL_SYMBOL InterlockedIncrement
push ebp
mov ebp,esp
push eax
push ebx
mov eax,1
mov ebx,[ebp+8]
xadd [ebx],eax
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DECLARE_GLOBAL_SYMBOL InterlockedDecrement
mov eax,0xffffffff
mov ebx,[esp+4]
xadd [ebx],eax
dec eax
ret
DECLARE_GLOBAL_SYMBOL InterlockedExchange
push ebp
mov ebp,esp
push eax
push ebx
mov eax,[ebp+12]
mov ebx,[ebp+8]
xchg [ebx],eax
pop ebx
pop eax
mov esp,ebp
pop ebp
ret
DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd
mov eax,[esp+8]
mov ebx,[esp+4]
xadd [ebx],eax
ret
DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange
mov eax,[esp+12]
mov edx,[esp+8]
mov ebx,[esp+4]
cmpxchg [ebx],edx
mov eax,edx
ret

File diff suppressed because it is too large Load diff