Added directory listing support for the shell

Correctec bug that prevented listing the root directory in the vfat fsd
Corrected mistake where the SL_xxx constants were too long

svn path=/trunk/; revision=145
This commit is contained in:
David Welch 1999-01-03 16:18:19 +00:00
parent 2d14c3e110
commit 20ef31f3cc
21 changed files with 882 additions and 521 deletions

View file

@ -5,6 +5,6 @@
void main()
{
NtDisplayString("Shell Starting...\n");
NtDisplayString("Hello world\n");
ExitThread(0);
}

View file

@ -53,7 +53,7 @@ void ExecuteDir(char* cmdline)
HANDLE shandle;
WIN32_FIND_DATA FindData;
shandle = FindFirstFile("*.*",&FindData);
shandle = FindFirstFile("*",&FindData);
if (shandle==INVALID_HANDLE_VALUE)
{
@ -94,12 +94,13 @@ int ExecuteProcess(char* name, char* cmdline)
PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo;
char arguments;
BOOL ret;
memset(&StartupInfo,0,sizeof(StartupInfo));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpTitle = name;
return(CreateProcessA(name,
ret = CreateProcessA(name,
cmdline,
NULL,
NULL,
@ -108,7 +109,12 @@ int ExecuteProcess(char* name, char* cmdline)
NULL,
NULL,
&StartupInfo,
&ProcessInformation));
&ProcessInformation);
if (ret)
{
WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
}
return(ret);
}
void ExecuteCommand(char* line)

View file

@ -13,17 +13,162 @@
#include <internal/string.h>
#include <wstring.h>
//#define NDEBUG
#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)
struct ext2_dir_entry* ret,
PULONG StartIndex)
{
ULONG i;
char* buffer;
@ -35,8 +180,9 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
for (i=0; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);
for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
{
DPRINT("block %d\n",block);
Ext2ReadSectors(DeviceExt->StorageDevice,
@ -44,7 +190,7 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
1,
buffer);
offset = 0;
offset = (*StartIndex)%BLOCKSIZE;
while (offset < BLOCKSIZE)
{
current = &buffer[offset];
@ -56,9 +202,10 @@ BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
offset,current->inode,name);
DPRINT("Comparing %s %s\n",name,filename);
if (strcmp(name,filename)==0)
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);
@ -98,6 +245,7 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
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);
@ -113,7 +261,8 @@ NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Ext2ReadInode(DeviceExt,
current_inode,
&parent_inode);
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry))
if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
&StartIndex))
{
ExFreePool(Fcb);
return(STATUS_UNSUCCESSFUL);

View file

@ -239,4 +239,4 @@ NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
ULONG Length,
LARGE_INTEGER Offset);
NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);

View file

@ -13,7 +13,7 @@
#include <internal/string.h>
#include <wstring.h>
#define NDEBUG
//#define NDEBUG
#include <internal/debug.h>
#include "ext2fs.h"
@ -180,8 +180,14 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,
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

@ -82,15 +82,19 @@ NTSTATUS FsdGetFileDirectoryInformation(PFCB pFcb,
PDEVICE_EXTENSION DeviceExt,
PFILE_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
{
unsigned long long AllocSize;
ULONG Length;
Length=vfat_wstrlen(pFcb->ObjectName);
if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
unsigned long long AllocSize;
ULONG Length;
DPRINT("BufferLength %d\n",BufferLength);
Length=vfat_wstrlen(pFcb->ObjectName);
if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
return STATUS_BUFFER_OVERFLOW;
pInfo->FileNameLength=Length;
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
memcpy(pInfo->FileName,pFcb->ObjectName
,sizeof(WCHAR)*(pInfo->FileNameLength));
pInfo->FileNameLength=Length;
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
memcpy(pInfo->FileName,pFcb->ObjectName
,sizeof(WCHAR)*(pInfo->FileNameLength));
DPRINT("pInfo->FileName %w\n",pInfo->FileName);
// pInfo->FileIndex=;
DosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
,&pInfo->CreationTime);
@ -188,74 +192,90 @@ DPRINT("sizeof %d,Length %d, BufLength %d, Next %d\n"
return STATUS_SUCCESS;
}
NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION Stack)
NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PIO_STACK_LOCATION Stack)
{
NTSTATUS RC=STATUS_SUCCESS;
long BufferLength = 0;
PUNICODE_STRING pSearchPattern = NULL;
FILE_INFORMATION_CLASS FileInformationClass;
unsigned long FileIndex = 0;
unsigned char *Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
PFILE_OBJECT pFileObject = NULL;
PFCB pFcb;
FCB tmpFcb;
PDEVICE_EXTENSION DeviceExt;
WCHAR star[5],*pCharPattern;
unsigned long OldEntry,OldSector;
DeviceExt = DeviceObject->DeviceExtension;
// Obtain the callers parameters
BufferLength = Stack->Parameters.QueryDirectory.BufferLength;
pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
pFileObject = Stack->FileObject;
pFcb=(PFCB)(pFileObject->FsContext);
if(Stack->Parameters.QueryDirectory.RestartScan)
{
pFcb->StartEntry=pFcb->StartSector=0;
}
// determine Buffer for result :
if (Irp->MdlAddress)
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
Buffer = Irp->UserBuffer;
if (pSearchPattern==NULL)
{
star[0]='*';
star[1]=0;
pCharPattern=star;
}
else pCharPattern=pSearchPattern->Buffer;
NTSTATUS RC=STATUS_SUCCESS;
long BufferLength = 0;
PUNICODE_STRING pSearchPattern = NULL;
FILE_INFORMATION_CLASS FileInformationClass;
unsigned long FileIndex = 0;
unsigned char *Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
PFILE_OBJECT pFileObject = NULL;
PFCB pFcb;
FCB tmpFcb;
PDEVICE_EXTENSION DeviceExt;
WCHAR star[5],*pCharPattern;
unsigned long OldEntry,OldSector;
BOOLEAN RestartScan;
DeviceExt = DeviceObject->DeviceExtension;
// Obtain the callers parameters
BufferLength = Stack->Parameters.QueryDirectory.Length;
pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
pFileObject = Stack->FileObject;
pFcb=(PFCB)(pFileObject->FsContext);
if(Stack->Flags & SL_RESTART_SCAN)
{
pFcb->StartEntry=pFcb->StartSector=0;
}
// determine Buffer for result :
if (Irp->MdlAddress)
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
else
Buffer = Irp->UserBuffer;
if (pSearchPattern==NULL)
{
star[0]='*';
star[1]=0;
pCharPattern=star;
}
else pCharPattern=pSearchPattern->Buffer;
while(RC==STATUS_SUCCESS && BufferLength >0)
{
OldSector=pFcb->StartSector;
OldEntry=pFcb->StartEntry;
if(OldSector)pFcb->StartEntry++;
RC=FindFile(DeviceExt,&tmpFcb,pFcb,pCharPattern,&pFcb->StartSector,&pFcb->StartEntry);
DPRINT("Found %w\n",tmpFcb.ObjectName);
if (NT_SUCCESS(RC))
{
switch(FileInformationClass)
{
case FileNameInformation:
RC=FsdGetFileNameInformation(&tmpFcb
,(PFILE_NAMES_INFORMATION)Buffer,BufferLength);
break;
case FileDirectoryInformation:
RC= FsdGetFileDirectoryInformation(&tmpFcb
,DeviceExt,(PFILE_DIRECTORY_INFORMATION)Buffer,BufferLength);
break;
case FileFullDirectoryInformation :
RC= FsdGetFileFullDirectoryInformation(&tmpFcb
,DeviceExt,(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,BufferLength);
break;
case FileBothDirectoryInformation :
RC=FsdGetFileBothInformation(&tmpFcb
,DeviceExt,(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,BufferLength);
break;
default:
RC=STATUS_INVALID_INFO_CLASS;
OldSector=pFcb->StartSector;
OldEntry=pFcb->StartEntry;
if(OldSector)pFcb->StartEntry++;
RC=FindFile(DeviceExt,
&tmpFcb,
pFcb,
pCharPattern,
&pFcb->StartSector,
&pFcb->StartEntry);
DPRINT("Found %w\n",tmpFcb.ObjectName);
if (NT_SUCCESS(RC))
{
switch(FileInformationClass)
{
case FileNameInformation:
RC=FsdGetFileNameInformation(&tmpFcb
,(PFILE_NAMES_INFORMATION)Buffer,BufferLength);
break;
case FileDirectoryInformation:
RC= FsdGetFileDirectoryInformation(&tmpFcb,
DeviceExt,
(PFILE_DIRECTORY_INFORMATION)Buffer,
BufferLength);
break;
case FileFullDirectoryInformation :
RC= FsdGetFileFullDirectoryInformation(&tmpFcb
,DeviceExt,(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,BufferLength);
break;
case FileBothDirectoryInformation :
RC=FsdGetFileBothInformation(&tmpFcb
,DeviceExt,(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,BufferLength);
break;
default:
RC=STATUS_INVALID_INFO_CLASS;
}
}
else
@ -272,7 +292,8 @@ DPRINT("Found %w\n",tmpFcb.ObjectName);
}
Buffer0=(PFILE_NAMES_INFORMATION)Buffer;
Buffer0->FileIndex=FileIndex++;
if(Stack->Parameters.QueryDirectory.ReturnSingleEntry) break;
DPRINT("Stack->Flags %x\n",Stack->Flags);
if(Stack->Flags & SL_RETURN_SINGLE_ENTRY) break;
BufferLength -= Buffer0->NextEntryOffset;
Buffer += Buffer0->NextEntryOffset;
}
@ -287,12 +308,16 @@ NTSTATUS FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
* FUNCTION: directory control : read/write directory informations
*/
{
NTSTATUS RC = STATUS_SUCCESS;
PFILE_OBJECT FileObject = NULL;
PIO_STACK_LOCATION Stack;
NTSTATUS RC = STATUS_SUCCESS;
PFILE_OBJECT FileObject = NULL;
PIO_STACK_LOCATION Stack;
DPRINT("FsdDirectoryControl(DeviceObject %x, Irp %x)\n",
DeviceObject,Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
CHECKPOINT;
FileObject = Stack->FileObject;
switch (Stack->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:

View file

@ -273,6 +273,11 @@ ULONG ClusterToSector(PDEVICE_EXTENSION DeviceExt,
* device
*/
{
DPRINT("ClusterToSector(Cluster %d)\n",Cluster);
DPRINT("DeviceExt->Boot->SectorsPerCluster %d\n",
DeviceExt->Boot->SectorsPerCluster);
DPRINT("Returning %d\n",DeviceExt->dataStart+
((Cluster-2)*DeviceExt->Boot->SectorsPerCluster));
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
}
@ -537,7 +542,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
ULONG NextCluster;
DPRINT("FindFile(Parent %x, FileToFind %w)\n",Parent,FileToFind);
if (Parent == NULL)
if (Parent == NULL || Parent->entry.FirstCluster == 1)
{
Size = DeviceExt->rootDirectorySectors;//FIXME : in fat32, no limit
StartingSector = DeviceExt->rootStart;
@ -545,6 +550,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
{// it's root !
memset(Fcb,0,sizeof(FCB));
memset(Fcb->entry.Filename,' ',11);
Fcb->entry.FileSize = DeviceExt->rootDirectorySectors * BLOCKSIZE;
if (DeviceExt->FatType == FAT32)
Fcb->entry.FirstCluster=2;
else Fcb->entry.FirstCluster=1;
@ -559,15 +565,20 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
Size = ULONG_MAX;
if (DeviceExt->FatType == FAT32)
NextCluster = Parent->entry.FirstCluster+Parent->entry.FirstClusterHigh*65536;
NextCluster = Parent->entry.FirstCluster
+Parent->entry.FirstClusterHigh*65536;
else
NextCluster = Parent->entry.FirstCluster;
StartingSector = ClusterToSector(DeviceExt, NextCluster);
}
if (Parent != NULL)
{
DPRINT("Parent->entry.FirstCluster %x\n",Parent->entry.FirstCluster);
}
block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
if (StartSector && (*StartSector)) StartingSector=*StartSector;
i=(Entry)?(*Entry):0;
DPRINT("FindFile : start at sector %lx, entry %ld\n",StartingSector,i);
DbgPrint("FindFile : start at sector %lx, entry %ld\n",StartingSector,i);
for (j=0; j<Size; j++)
{
VFATReadSectors(DeviceExt->StorageDevice,StartingSector,1,block);
@ -576,12 +587,13 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
{
if (IsLastEntry((PVOID)block,i))
{
DPRINT("Is last entry\n");
ExFreePool(block);
return(STATUS_UNSUCCESSFUL);
}
if (GetEntryName((PVOID)block,&i,name,&j,DeviceExt,&StartingSector))
{
// DPRINT("Comparing %w %w\n",name,FileToFind);
DPRINT("Comparing %w %w\n",name,FileToFind);
if (wstrcmpjoki(name,FileToFind))
{
/* In the case of a long filename, the firstcluster is stored in
@ -604,6 +616,7 @@ NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PFCB Fcb,
memcpy(&Fcb->entry,&((FATDirEntry *)block)[i],
sizeof(FATDirEntry));
vfat_wcsncpy(Fcb->ObjectName,name,251);
DPRINT("Fcb->ObjectName %w name %w\n",Fcb->ObjectName,name);
ExFreePool(block);
if(StartSector) *StartSector=StartingSector;
if(Entry) *Entry=i;
@ -686,7 +699,7 @@ NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
*next=0;
}
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
Status = FindFile(DeviceExt,Fcb,ParentFcb,current,NULL,NULL);
if (Status != STATUS_SUCCESS)
{
/* FIXME: should the FCB be freed here? */
@ -716,8 +729,8 @@ BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
* by this fsd
*/
{
BootSector *Boot;
DPRINT("FsdHasFileSystem(DeviceToMount %x)\n",DeviceToMount);
Boot = ExAllocatePool(NonPagedPool,512);
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);

View file

@ -82,13 +82,14 @@ enum
SL_FT_SEQUENTIAL_WRITE = 0x80,
SL_FAIL_IMMEDIATELY = 0x100,
SL_EXCLUSIVE_LOCK = 0x200,
SL_RESTART_SCAN = 0x400,
SL_RETURN_SINGLE_ENTRY = 0x800,
SL_INDEX_SPECIFIED = 0x1000,
SL_WATCH_TREE = 0x2000,
SL_ALLOW_RAW_MOUNT = 0x4000,
};
#define SL_RESTART_SCAN (0x1)
#define SL_RETURN_SINGLE_ENTRY (0x2)
#define SL_INDEX_SPECIFIED (0x3)
#define SL_PENDING_RETURNED 0x01
#define SL_INVOKE_ON_CANCEL 0x20
#define SL_INVOKE_ON_SUCCESS 0x40

View file

@ -158,12 +158,10 @@ typedef struct _IO_STACK_LOCATION
*/
struct
{
FILE_INFORMATION_CLASS FileInformationClass;
BOOLEAN ReturnSingleEntry;
ULONG Length;
PUNICODE_STRING FileName;
BOOLEAN RestartScan;
ULONG BufferLength;
ULONG FileIndex;
FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex;
} QueryDirectory;
} Parameters;

View file

@ -17,19 +17,8 @@ typedef struct _CONTROLLER_OBJECT
typedef struct _STRING
{
/*
* Length in bytes of the string stored in buffer
*/
USHORT Length;
/*
* Maximum length of the string
*/
USHORT MaximumLength;
/*
* String
*/
PCHAR Buffer;
} STRING, *PSTRING;

View file

@ -386,7 +386,8 @@ typedef struct _FILE_NAME_INFORMATION {
WCHAR FileName[0];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef struct _FILE_NAMES_INFORMATION {
typedef struct _FILE_NAMES_INFORMATION
{
ULONG NextEntryOffset;
ULONG FileIndex;
ULONG FileNameLength;

View file

@ -20,28 +20,191 @@ typedef struct _KERNEL32_FIND_FILE_DATA
{
HANDLE DirectoryHandle;
FILE_DIRECTORY_INFORMATION FileInfo;
WCHAR FileNameExtra[MAX_PATH];
UNICODE_STRING PatternStr;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
typedef struct _WIN32_FIND_DATA_UNICODE {
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_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;
/* FUNCTIONS *****************************************************************/
WINBOOL STDCALL InternalFindNextFile(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
PKERNEL32_FIND_FILE_DATA IData;
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);
dprintf("Found %w\n",IData->FileInfo.FileName);
lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
if (Status != STATUS_SUCCESS)
{
return(FALSE);
}
return(TRUE);
}
HANDLE STDCALL InternalFindFirstFile(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;
dprintf("Directory %w\n",Directory);
wcscat(Directory, CurrentDirectory);
dprintf("Directory %w\n",Directory);
wcscat(Directory, lpFileName);
dprintf("Directory %w\n",Directory);
End = wcsrchr(Directory, '\\');
*End = 0;
wcscpy(Pattern, End+1);
dprintf("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,
0,
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);
dprintf("Found %w\n",IData->FileInfo.FileName);
lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
return(IData);
}
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR lpFileNameW[MAX_PATH];
ULONG i;
PKERNEL32_FIND_FILE_DATA IData;
PWIN32_FIND_DATA_ASCII Ret;
i = 0;
while (lpFileName[i]!=0)
{
lpFileNameW[i] = lpFileName[i];
i++;
}
lpFileNameW[i] = 0;
return(FindFirstFileW(lpFileNameW,lpFindFileData));
IData = InternalFindFirstFile(lpFileNameW,lpFindFileData);
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(IData);
}
WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
return(FindNextFileW(hFindFile, lpFindFileData));
PWIN32_FIND_DATA_ASCII Ret;
PKERNEL32_FIND_FILE_DATA IData;
ULONG i;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (!InternalFindNextFile(hFindFile, lpFindFileData))
{
return(FALSE);
}
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);
}
BOOL FindClose(HANDLE hFindFile)
@ -57,73 +220,36 @@ BOOL FindClose(HANDLE hFindFile)
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR CurrentDirectory[MAX_PATH];
WCHAR Pattern[MAX_PATH];
WCHAR Directory[MAX_PATH];
PWSTR End;
PWIN32_FIND_DATA_UNICODE Ret;
PKERNEL32_FIND_FILE_DATA IData;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameStr;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING PatternStr;
dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
lpFileName, lpFindFileData);
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
Directory[0] = '\\';
Directory[1] = '?';
Directory[2] = '?';
Directory[3] = '\\';
Directory[4] = 0;
wcscat(Directory, CurrentDirectory);
wcscat(Directory, lpFileName);
End = wcschr(Directory, '\\');
*End = 0;
wcscpy(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,
&IoStatusBlock,
0,
OPEN_EXISTING)!=STATUS_SUCCESS)
{
return(NULL);
}
RtlInitUnicodeString(&PatternStr, Pattern);
NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo),
FileDirectoryInformation,
TRUE,
&PatternStr,
FALSE);
IData = InternalFindFirstFile(lpFileName,lpFindFileData);
Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
memcpy(Ret->cFileName, IData->FileInfo.FileName,
IData->FileInfo.FileNameLength);
memset(Ret->cAlternateFileName, 0, 14);
return(IData);
}
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData)
{
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

@ -110,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

@ -135,6 +135,8 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
KEVENT Event;
PIO_STACK_LOCATION IoStack;
DPRINT("ZwQueryDirectoryFile()\n");
Status = ObReferenceObjectByHandle(FileHandle,
FILE_LIST_DIRECTORY,
IoFileType,
@ -167,13 +169,26 @@ NTSTATUS STDCALL ZwQueryDirectoryFile(
IoStack->DeviceObject = DeviceObject;
IoStack->FileObject = FileObject;
if (RestartScan)
{
IoStack->Flags = IoStack->Flags | SL_RESTART_SCAN;
}
if (ReturnSingleEntry)
{
DPRINT("Setting ReturingSingleEntry flag\n");
IoStack->Flags = IoStack->Flags | SL_RETURN_SINGLE_ENTRY;
DPRINT("SL_RETURN_SINGLE_ENTRY %x\n",SL_RETURN_SINGLE_ENTRY);
DPRINT("IoStack->Flags %x\n",IoStack->Flags);
}
if (((PFILE_DIRECTORY_INFORMATION)FileInformation)->FileIndex != 0)
{
IoStack->Flags = IoStack->Flags | SL_INDEX_SPECIFIED;
}
IoStack->Parameters.QueryDirectory.FileInformationClass =
FileInformationClass;
IoStack->Parameters.QueryDirectory.ReturnSingleEntry =
ReturnSingleEntry;
IoStack->Parameters.QueryDirectory.FileName = FileName;
IoStack->Parameters.QueryDirectory.RestartScan = RestartScan;
IoStack->Parameters.QueryDirectory.BufferLength = Length;
IoStack->Parameters.QueryDirectory.Length = Length;
Status = IoCallDriver(FileObject->DeviceObject,Irp);
if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))

View file

@ -1,313 +1,312 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/irp.c
* PURPOSE: Handle IRPs
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* 24/05/98: Created
*/
/* NOTES *******************************************************************
*
* Layout of an IRP
*
* ################
* # Headers #
* ################
* # #
* # Variable #
* # length list #
* # of io stack #
* # locations #
* # #
* ################
*
*
*
*/
/* INCLUDES ****************************************************************/
#include <internal/string.h>
#include <internal/io.h>
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
/*
* FUNCTION: Returns a pointer to the device, representing a removable-media
* device, that is the target of the given thread's I/O request
*/
{
UNIMPLEMENTED;
}
VOID IoFreeIrp(PIRP Irp)
/*
* FUNCTION: Releases a caller allocated irp
* ARGUMENTS:
* Irp = Irp to free
*/
{
ExFreePool(Irp);
}
PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
/*
* FUNCTION: Allocates and initializes an irp to associated with a master irp
* ARGUMENTS:
* Irp = Master irp
* StackSize = Number of stack locations to be allocated in the irp
* RETURNS: The irp allocated
*/
{
PIRP AssocIrp;
AssocIrp = IoAllocateIrp(StackSize,FALSE);
UNIMPLEMENTED;
}
VOID IoMarkIrpPending(PIRP Irp)
/*
* FUNCTION: Marks the specified irp, indicating further processing will
* be required by other driver routines
* ARGUMENTS:
* Irp = Irp to mark
*/
{
DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
IoGetCurrentIrpStackLocation(Irp));
IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
Irp->Tail.Overlay.Thread = KeGetCurrentThread();
DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
IoGetCurrentIrpStackLocation(Irp)->Control);
DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
}
USHORT IoSizeOfIrp(CCHAR StackSize)
/*
* FUNCTION: Determines the size of an IRP
* ARGUMENTS:
* StackSize = number of stack locations in the IRP
* RETURNS: The size of the IRP in bytes
*/
{
return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
}
VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
/*
* FUNCTION: Initalizes an irp allocated by the caller
* ARGUMENTS:
* Irp = IRP to initalize
* PacketSize = Size in bytes of the IRP
* StackSize = Number of stack locations in the IRP
*/
{
assert(Irp != NULL);
memset(Irp,0,PacketSize);
Irp->StackCount=StackSize;
Irp->CurrentLocation=StackSize;
Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
}
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
/*
* FUNCTION: Gets a pointer to the callers location in the I/O stack in
* the given IRP
* ARGUMENTS:
* Irp = Points to the IRP
* RETURNS: A pointer to the stack location
*/
{
DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
Irp,
Irp->CurrentLocation,
Irp->StackCount);
return &Irp->Stack[Irp->CurrentLocation];
}
VOID IoSetNextIrpStackLocation(PIRP Irp)
{
Irp->CurrentLocation--;
Irp->Tail.Overlay.CurrentStackLocation--;
}
PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
/*
* FUNCTION: Gives a higher level driver access to the next lower driver's
* I/O stack location
* ARGUMENTS:
* Irp = points to the irp
* RETURNS: A pointer to the stack location
*/
{
DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
Irp,
Irp->CurrentLocation,
Irp->StackCount);
assert(Irp!=NULL);
DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
return(&Irp->Stack[Irp->CurrentLocation-1]);
}
NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
/*
* FUNCTION: Sends an IRP to the next lower driver
*/
{
NTSTATUS Status;
PDRIVER_OBJECT drv = DevObject->DriverObject;
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
DPRINT("Deviceobject %x\n",DevObject);
DPRINT("Irp %x\n",irp);
irp->Tail.Overlay.CurrentStackLocation--;
irp->CurrentLocation--;
DPRINT("Io stack address %x\n",param);
DPRINT("Function %d Routine %x\n",param->MajorFunction,
drv->MajorFunction[param->MajorFunction]);
Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);
return Status;
}
PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
/*
* FUNCTION: Allocates an IRP
* ARGUMENTS:
* StackSize = the size of the stack required for the irp
* ChargeQuota = Charge allocation to current threads quota
* RETURNS: Irp allocated
*/
{
PIRP Irp;
DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
StackSize,
ChargeQuota);
if (ChargeQuota)
{
Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
}
else
{
Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
}
if (Irp==NULL)
{
return(NULL);
}
IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize);
DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
return Irp;
}
VOID IoSetCompletionRoutine(PIRP Irp,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID Context,
BOOLEAN InvokeOnSuccess,
BOOLEAN InvokeOnError,
BOOLEAN InvokeOnCancel)
{
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);
param->CompletionRoutine=CompletionRoutine;
param->CompletionContext=Context;
if (InvokeOnSuccess)
{
param->Control = param->Control | SL_INVOKE_ON_SUCCESS;
}
if (InvokeOnError)
{
param->Control = param->Control | SL_INVOKE_ON_ERROR;
}
if (InvokeOnCancel)
{
param->Control = param->Control | SL_INVOKE_ON_CANCEL;
}
}
VOID IopCompleteRequest(struct _KAPC* Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{
IoSecondStageCompletion((PIRP)(*NormalContext),
IO_NO_INCREMENT);
}
VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
/*
* FUNCTION: Indicates the caller has finished all processing for a given
* I/O request and is returning the given IRP to the I/O manager
* ARGUMENTS:
* Irp = Irp to be cancelled
* PriorityBoost = Increment by which to boost the priority of the
* thread making the request
*/
{
unsigned int i;
NTSTATUS Status;
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
Irp,PriorityBoost);
for (i=0;i<Irp->StackCount;i++)
{
DPRINT("&Irp->Stack[%d].CompletionRoutine %08lx\n",
i,
Irp->Stack[i].CompletionRoutine);
if (Irp->Stack[i].CompletionRoutine != NULL)
{
Status = Irp->Stack[i].CompletionRoutine(
Irp->Stack[i].DeviceObject,
Irp,
Irp->Stack[i].CompletionContext);
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
{
return;
}
}
DPRINT("Irp->Stack[%d].Control %08lx\n", i, Irp->Stack[i].Control);
if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
{
DPRINT("Setting PendingReturned flag\n");
Irp->PendingReturned = TRUE;
}
}
if (Irp->PendingReturned)
{
KeInitializeApc(&Irp->Tail.Apc,
&Irp->Tail.Overlay.Thread->Tcb,
0,
IopCompleteRequest,
NULL,
NULL,
0,
Irp);
KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
}
else
{
IoSecondStageCompletion(Irp,PriorityBoost);
}
}
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/irp.c
* PURPOSE: Handle IRPs
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* 24/05/98: Created
*/
/* NOTES *******************************************************************
*
* Layout of an IRP
*
* ################
* # Headers #
* ################
* # #
* # Variable #
* # length list #
* # of io stack #
* # locations #
* # #
* ################
*
*
*
*/
/* INCLUDES ****************************************************************/
#include <internal/string.h>
#include <internal/io.h>
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
/*
* FUNCTION: Returns a pointer to the device, representing a removable-media
* device, that is the target of the given thread's I/O request
*/
{
UNIMPLEMENTED;
}
VOID IoFreeIrp(PIRP Irp)
/*
* FUNCTION: Releases a caller allocated irp
* ARGUMENTS:
* Irp = Irp to free
*/
{
ExFreePool(Irp);
}
PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
/*
* FUNCTION: Allocates and initializes an irp to associated with a master irp
* ARGUMENTS:
* Irp = Master irp
* StackSize = Number of stack locations to be allocated in the irp
* RETURNS: The irp allocated
*/
{
PIRP AssocIrp;
AssocIrp = IoAllocateIrp(StackSize,FALSE);
UNIMPLEMENTED;
}
VOID IoMarkIrpPending(PIRP Irp)
/*
* FUNCTION: Marks the specified irp, indicating further processing will
* be required by other driver routines
* ARGUMENTS:
* Irp = Irp to mark
*/
{
DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
IoGetCurrentIrpStackLocation(Irp));
IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
Irp->Tail.Overlay.Thread = KeGetCurrentThread();
DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
IoGetCurrentIrpStackLocation(Irp)->Control);
DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
}
USHORT IoSizeOfIrp(CCHAR StackSize)
/*
* FUNCTION: Determines the size of an IRP
* ARGUMENTS:
* StackSize = number of stack locations in the IRP
* RETURNS: The size of the IRP in bytes
*/
{
return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
}
VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
/*
* FUNCTION: Initalizes an irp allocated by the caller
* ARGUMENTS:
* Irp = IRP to initalize
* PacketSize = Size in bytes of the IRP
* StackSize = Number of stack locations in the IRP
*/
{
assert(Irp != NULL);
memset(Irp,0,PacketSize);
Irp->StackCount=StackSize;
Irp->CurrentLocation=StackSize;
Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
}
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
/*
* FUNCTION: Gets a pointer to the callers location in the I/O stack in
* the given IRP
* ARGUMENTS:
* Irp = Points to the IRP
* RETURNS: A pointer to the stack location
*/
{
DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
Irp,
Irp->CurrentLocation,
Irp->StackCount);
return &Irp->Stack[Irp->CurrentLocation];
}
VOID IoSetNextIrpStackLocation(PIRP Irp)
{
Irp->CurrentLocation--;
Irp->Tail.Overlay.CurrentStackLocation--;
}
PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
/*
* FUNCTION: Gives a higher level driver access to the next lower driver's
* I/O stack location
* ARGUMENTS:
* Irp = points to the irp
* RETURNS: A pointer to the stack location
*/
{
DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
Irp,
Irp->CurrentLocation,
Irp->StackCount);
assert(Irp!=NULL);
DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
return(&Irp->Stack[Irp->CurrentLocation-1]);
}
NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
/*
* FUNCTION: Sends an IRP to the next lower driver
*/
{
NTSTATUS Status;
PDRIVER_OBJECT drv = DevObject->DriverObject;
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
DPRINT("Deviceobject %x\n",DevObject);
DPRINT("Irp %x\n",irp);
irp->Tail.Overlay.CurrentStackLocation--;
irp->CurrentLocation--;
DPRINT("Io stack address %x\n",param);
DPRINT("Function %d Routine %x\n",param->MajorFunction,
drv->MajorFunction[param->MajorFunction]);
Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);
return Status;
}
PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
/*
* FUNCTION: Allocates an IRP
* ARGUMENTS:
* StackSize = the size of the stack required for the irp
* ChargeQuota = Charge allocation to current threads quota
* RETURNS: Irp allocated
*/
{
PIRP Irp;
DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
StackSize,
ChargeQuota);
if (ChargeQuota)
{
Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
}
else
{
Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
}
if (Irp==NULL)
{
return(NULL);
}
IoInitializeIrp(Irp, IoSizeOfIrp(StackSize), StackSize);
DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
return Irp;
}
VOID IoSetCompletionRoutine(PIRP Irp,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID Context,
BOOLEAN InvokeOnSuccess,
BOOLEAN InvokeOnError,
BOOLEAN InvokeOnCancel)
{
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);
param->CompletionRoutine=CompletionRoutine;
param->CompletionContext=Context;
if (InvokeOnSuccess)
{
param->Control = param->Control | SL_INVOKE_ON_SUCCESS;
}
if (InvokeOnError)
{
param->Control = param->Control | SL_INVOKE_ON_ERROR;
}
if (InvokeOnCancel)
{
param->Control = param->Control | SL_INVOKE_ON_CANCEL;
}
}
VOID IopCompleteRequest(struct _KAPC* Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* NormalContext,
PVOID* SystemArgument1,
PVOID* SystemArgument2)
{
IoSecondStageCompletion((PIRP)(*NormalContext),
IO_NO_INCREMENT);
}
VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
/*
* FUNCTION: Indicates the caller has finished all processing for a given
* I/O request and is returning the given IRP to the I/O manager
* ARGUMENTS:
* Irp = Irp to be cancelled
* PriorityBoost = Increment by which to boost the priority of the
* thread making the request
*/
{
unsigned int i;
NTSTATUS Status;
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
Irp,PriorityBoost);
for (i=0;i<Irp->StackCount;i++)
{
DPRINT("&Irp->Stack[%d].CompletionRoutine %08lx\n",
i,
Irp->Stack[i].CompletionRoutine);
if (Irp->Stack[i].CompletionRoutine != NULL)
{
Status = Irp->Stack[i].CompletionRoutine(
Irp->Stack[i].DeviceObject,
Irp,
Irp->Stack[i].CompletionContext);
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
{
return;
}
}
DPRINT("Irp->Stack[%d].Control %08lx\n", i, Irp->Stack[i].Control);
if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
{
DPRINT("Setting PendingReturned flag\n");
Irp->PendingReturned = TRUE;
}
}
if (Irp->PendingReturned)
{
KeInitializeApc(&Irp->Tail.Apc,
&Irp->Tail.Overlay.Thread->Tcb,
0,
IopCompleteRequest,
NULL,
NULL,
0,
Irp);
KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
}
else
{
IoSecondStageCompletion(Irp,PriorityBoost);
}
}

View file

@ -231,7 +231,32 @@ NTSTATUS STDCALL ZwWaitForSingleObject (IN HANDLE Object,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Time)
{
UNIMPLEMENTED;
PVOID ObjectPtr;
NTSTATUS Status;
DPRINT("ZwWaitForSingleObject(Object %x, Alertable %d, Time %x)\n",
Object,Alertable,Time);
Status = ObReferenceObjectByHandle(Object,
SYNCHRONIZE,
NULL,
UserMode,
&ObjectPtr,
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
Status = KeWaitForSingleObject(ObjectPtr,
UserMode,
UserMode,
Alertable,
Time);
ObDereferenceObject(ObjectPtr);
return(Status);
}

View file

@ -28,7 +28,7 @@
#include <ddk/ntddk.h>
#if 0
#if 1
#define VALIDATE_POOL validate_kernel_pool()
#else
#define VALIDATE_POOL

View file

@ -255,7 +255,10 @@ NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
if (Header->RefCount == 0 && Header->HandleCount == 0 &&
!Header->Permanent)
{
ObRemoveEntry(Header);
if (Header->Name.Buffer != NULL)
{
ObRemoveEntry(Header);
}
ExFreePool(Header);
}
return(STATUS_SUCCESS);
@ -270,6 +273,10 @@ VOID ObDereferenceObject(PVOID ObjectBody)
*/
{
POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
DPRINT("ObDeferenceObject(ObjectBody %x) RefCount %d\n",ObjectBody,
Header->RefCount);
Header->RefCount--;
ObPerformRetentionChecks(Header);
}
@ -317,8 +324,7 @@ NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
KPROCESSOR_MODE AccessMode,
PVOID* Object,
POBJECT_HANDLE_INFORMATION
HandleInformationPtr
)
HandleInformationPtr)
/*
* FUNCTION: Increments the reference count for an object and returns a
* pointer to its body

View file

@ -13,7 +13,7 @@
#include <ddk/ntddk.h>
#include <internal/ps.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
@ -60,7 +60,7 @@ VOID PsReleaseThread(PETHREAD Thread)
DPRINT("PsReleaseThread(Thread %x)\n",Thread);
RemoveEntryList(&Thread->Tcb.Entry);
ExFreePool(Thread);
ObDereferenceObject(Thread);
}
@ -82,6 +82,7 @@ NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
CurrentThread->ExitStatus = ExitStatus;
DPRINT("terminating %x\n",CurrentThread);
ObDereferenceObject(CurrentThread->ThreadsProcess);
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
ZwYieldExecution();

View file

@ -15,7 +15,7 @@
#include <internal/mm.h>
#include <internal/string.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
@ -176,6 +176,10 @@ NTSTATUS STDCALL ZwCreateProcess(
DesiredAccess,
ObjectAttributes,
PsProcessType);
KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
0,
sizeof(EPROCESS),
FALSE);
KProcess = &(Process->Pcb);
InitializeListHead(&(KProcess->MemoryAreaList));

View file

@ -99,13 +99,13 @@ static PETHREAD PsScanThreadList(KPRIORITY Priority)
while (current_entry != &PriorityListHead[THREAD_PRIORITY_MAX+Priority])
{
current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);
#if 0
if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED &&
current != CurrentThread)
{
PsReleaseThread(CurrentThread);
PsReleaseThread(current);
}
#endif
if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)
{
if (oldest == NULL || oldest_time > current->Tcb.LastTick)
@ -225,6 +225,10 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
InitializeListHead(Thread->Tcb.ApcList);
InitializeListHead(&(Thread->IrpList));
Thread->Cid.UniqueThread=InterlockedIncrement(&NextThreadUniqueId);
ObReferenceObjectByPointer(Thread,
THREAD_ALL_ACCESS,
PsThreadType,
UserMode);
PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);
*ThreadPtr = Thread;
@ -344,7 +348,7 @@ NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,
PETHREAD Thread;
NTSTATUS Status;
DbgPrint("ZwCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
DPRINT("ZwCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
ThreadHandle,ThreadContext);
Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,