From 20ef31f3ccbf71727f209bbbf113ed2fdf832959 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 3 Jan 1999 16:18:19 +0000 Subject: [PATCH] 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 --- reactos/apps/tests/hello/hello.c | 2 +- reactos/apps/utils/shell/shell.c | 12 +- reactos/drivers/fs/ext2/dir.c | 163 ++++++- reactos/drivers/fs/ext2/ext2fs.h | 2 +- reactos/drivers/fs/ext2/super.c | 8 +- reactos/drivers/fs/vfat/dir.c | 181 ++++---- reactos/drivers/fs/vfat/iface.c | 27 +- reactos/include/ddk/iodef.h | 7 +- reactos/include/ddk/iotypes.h | 8 +- reactos/include/ddk/rtl.h | 11 - reactos/include/ddk/zwtypes.h | 3 +- reactos/lib/kernel32/file/find.c | 254 ++++++++--- reactos/lib/kernel32/thread/thread.c | 13 +- reactos/ntoskrnl/io/dir.c | 23 +- reactos/ntoskrnl/io/irp.c | 625 +++++++++++++-------------- reactos/ntoskrnl/ke/wait.c | 27 +- reactos/ntoskrnl/mm/npool.c | 2 +- reactos/ntoskrnl/ob/object.c | 12 +- reactos/ntoskrnl/ps/kill.c | 5 +- reactos/ntoskrnl/ps/process.c | 6 +- reactos/ntoskrnl/ps/thread.c | 12 +- 21 files changed, 882 insertions(+), 521 deletions(-) diff --git a/reactos/apps/tests/hello/hello.c b/reactos/apps/tests/hello/hello.c index 528184c51fe..ec06d8c0b78 100644 --- a/reactos/apps/tests/hello/hello.c +++ b/reactos/apps/tests/hello/hello.c @@ -5,6 +5,6 @@ void main() { - NtDisplayString("Shell Starting...\n"); + NtDisplayString("Hello world\n"); ExitThread(0); } diff --git a/reactos/apps/utils/shell/shell.c b/reactos/apps/utils/shell/shell.c index 44869213b83..8a8c4c99e79 100644 --- a/reactos/apps/utils/shell/shell.c +++ b/reactos/apps/utils/shell/shell.c @@ -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) diff --git a/reactos/drivers/fs/ext2/dir.c b/reactos/drivers/fs/ext2/dir.c index 22384bd3caa..357c0de7dd4 100644 --- a/reactos/drivers/fs/ext2/dir.c +++ b/reactos/drivers/fs/ext2/dir.c @@ -13,17 +13,162 @@ #include #include -//#define NDEBUG +#define NDEBUG #include #include "ext2fs.h" /* FUNCTIONS *****************************************************************/ +VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len) +{ + ULONG i; + + for (i=0; iinode, + &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; iinode,"*",&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); diff --git a/reactos/drivers/fs/ext2/ext2fs.h b/reactos/drivers/fs/ext2/ext2fs.h index 4e310a6ed6f..8ce5978a42c 100644 --- a/reactos/drivers/fs/ext2/ext2fs.h +++ b/reactos/drivers/fs/ext2/ext2fs.h @@ -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); diff --git a/reactos/drivers/fs/ext2/super.c b/reactos/drivers/fs/ext2/super.c index 1cfef69a752..2f4a21e7cea 100644 --- a/reactos/drivers/fs/ext2/super.c +++ b/reactos/drivers/fs/ext2/super.c @@ -13,7 +13,7 @@ #include #include -#define NDEBUG +//#define NDEBUG #include #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); diff --git a/reactos/drivers/fs/vfat/dir.c b/reactos/drivers/fs/vfat/dir.c index e478c5a566e..b47148465b7 100644 --- a/reactos/drivers/fs/vfat/dir.c +++ b/reactos/drivers/fs/vfat/dir.c @@ -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: diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 969ad86ee3b..8ba6033ca41 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -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; jStorageDevice,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); diff --git a/reactos/include/ddk/iodef.h b/reactos/include/ddk/iodef.h index bbff55a56a4..e6dc309f4fd 100644 --- a/reactos/include/ddk/iodef.h +++ b/reactos/include/ddk/iodef.h @@ -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 diff --git a/reactos/include/ddk/iotypes.h b/reactos/include/ddk/iotypes.h index 8049ebe4d81..f899bc278d2 100644 --- a/reactos/include/ddk/iotypes.h +++ b/reactos/include/ddk/iotypes.h @@ -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; diff --git a/reactos/include/ddk/rtl.h b/reactos/include/ddk/rtl.h index 926ba8ae835..b9ff79f87aa 100644 --- a/reactos/include/ddk/rtl.h +++ b/reactos/include/ddk/rtl.h @@ -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; diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index b3712ab3c2c..5d31882a028 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -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; diff --git a/reactos/lib/kernel32/file/find.c b/reactos/lib/kernel32/file/find.c index 61b0b5b88ef..083f912e39e 100644 --- a/reactos/lib/kernel32/file/find.c +++ b/reactos/lib/kernel32/file/find.c @@ -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; iFileInfo.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; iFileInfo.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); } diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 6595b603867..68e44d7b633 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -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; diff --git a/reactos/ntoskrnl/io/dir.c b/reactos/ntoskrnl/io/dir.c index 33661c574a1..5752065637a 100644 --- a/reactos/ntoskrnl/io/dir.c +++ b/reactos/ntoskrnl/io/dir.c @@ -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)) diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index 3c8f2f32196..dc7a779f12d 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -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 -#include -#include - -#define NDEBUG -#include - -/* 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;iStackCount;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 +#include +#include + +#define NDEBUG +#include + +/* 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;iStackCount;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); + } +} diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 6a0d2b4c046..474b292c5ff 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -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); } diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index bafde82e98e..e28f306b463 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -28,7 +28,7 @@ #include -#if 0 +#if 1 #define VALIDATE_POOL validate_kernel_pool() #else #define VALIDATE_POOL diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 02f60cd505e..ff0cd3846d8 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -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 diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 40870f97810..7e021da8836 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -13,7 +13,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include /* 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(); diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 0b02183b360..b4ebf11a1ec 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -15,7 +15,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include /* 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)); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 0975fc2a9af..6602e3bba44 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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,