mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
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:
parent
2d14c3e110
commit
20ef31f3cc
21 changed files with 882 additions and 521 deletions
|
@ -5,6 +5,6 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
NtDisplayString("Shell Starting...\n");
|
||||
NtDisplayString("Hello world\n");
|
||||
ExitThread(0);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
#define VALIDATE_POOL validate_kernel_pool()
|
||||
#else
|
||||
#define VALIDATE_POOL
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue