From 88454ea69a8ca032fbdd882c3f71a81a4ac79033 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 30 Dec 2004 18:30:05 +0000 Subject: [PATCH] Implemented: ExSetResourceOwnerPointer, FsRtlDissectDbcs, FsRtlDoesDbcsContainWildCards, FsRtlAcquireFileExclusive, FsRtlReleaseFile, FsRtlGetNextMcbEntry, FsRtlLookupLastMcbEntry, FsRtlLookupMcbEntry, FsRtlRemoveMcbEntry, FsRtlIncrementCcFastReadResourceMiss, FsRtlIncrementCcFastReadNotPossible, FsRtlIncrementCcFastReadWait, FsRtlIncrementCcFastReadNoWait , FsRtlAreNamesEqual, FsRtlDoesNameContainWildCards, IoCreateDriver, IoDeleteDriver Thanks to Filip for reviewing some of these. svn path=/trunk/; revision=12408 --- reactos/include/ddk/fsfuncs.h | 50 ++++++++++++++- reactos/include/ddk/iotypes.h | 23 ++++++- reactos/include/ntos/rtl.h | 3 +- reactos/ntoskrnl/cc/copy.c | 5 +- reactos/ntoskrnl/ex/resource.c | 58 +++++++++++++++-- reactos/ntoskrnl/fs/dbcsname.c | 60 ++++++++++++++++-- reactos/ntoskrnl/fs/filelock.c | 66 ++++++++++++++++++-- reactos/ntoskrnl/fs/mcb.c | 93 +++++++++++++++++++-------- reactos/ntoskrnl/fs/mdl.c | 21 ++++--- reactos/ntoskrnl/fs/name.c | 95 +++++++++++++++++++++------- reactos/ntoskrnl/io/driver.c | 111 +++++++++++++++++++++++++++++++-- 11 files changed, 498 insertions(+), 87 deletions(-) diff --git a/reactos/include/ddk/fsfuncs.h b/reactos/include/ddk/fsfuncs.h index 38b289cc5c7..1a1d1b01787 100644 --- a/reactos/include/ddk/fsfuncs.h +++ b/reactos/include/ddk/fsfuncs.h @@ -1,6 +1,6 @@ #ifndef __INCLUDE_DDK_FSFUNCS_H #define __INCLUDE_DDK_FSFUNCS_H -/* $Id: fsfuncs.h,v 1.30 2004/11/21 17:47:22 navaraf Exp $ */ +/* $Id: fsfuncs.h,v 1.31 2004/12/30 18:30:04 ion Exp $ */ #define FlagOn(x,f) ((x) & (f)) #include @@ -60,6 +60,7 @@ extern PUCHAR IMPORTED FsRtlLegalAnsiCharacterArray; #define FSRTL_WILD_CHARACTER 0x08 +typedef signed char SCHAR; VOID STDCALL @@ -414,9 +415,54 @@ FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus); #define FsRtlIsUnicodeCharacterWild(C) ( \ (((C) >= 0x40) ? \ FALSE : \ - FlagOn((*FsRtlLegalAnsiCharacterArray)[(C)], FSRTL_WILD_CHARACTER )) \ + FlagOn((FsRtlLegalAnsiCharacterArray)[(C)], FSRTL_WILD_CHARACTER )) \ ) +#define FSRTL_FAT_LEGAL 0x01 +#define FSRTL_HPFS_LEGAL 0x02 +#define FSRTL_NTFS_LEGAL 0x04 +#define FSRTL_WILD_CHARACTER 0x08 +#define FSRTL_OLE_LEGAL 0x10 +#define FSRTL_NTFS_STREAM_LEGAL (FSRTL_NTFS_LEGAL | FSRTL_OLE_LEGAL) + +#define FsRtlIsAnsiCharacterWild(C) ( \ + FsRtlTestAnsiCharacter((C), FALSE, FALSE, FSRTL_WILD_CHARACTER) \ + ) + +#define FsRtlIsAnsiCharacterLegalFat(C,WILD_OK) ( \ + FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_FAT_LEGAL) \ + ) + +#define FsRtlIsAnsiCharacterLegalHpfs(C,WILD_OK) ( \ + FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_HPFS_LEGAL) \ + ) + +#define FsRtlIsAnsiCharacterLegalNtfs(C,WILD_OK) ( \ + FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_LEGAL) \ + ) + +#define FsRtlIsAnsiCharacterLegalNtfsStream(C,WILD_OK) ( \ + FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_STREAM_LEGAL) \ + ) + +#define FsRtlIsAnsiCharacterLegal(C,FLAGS) ( \ + FsRtlTestAnsiCharacter((C), TRUE, FALSE, (FLAGS)) \ + ) + +#define FsRtlTestAnsiCharacter(C, DEFAULT_RET, WILD_OK, FLAGS) ( \ + ((SCHAR)(C) < 0) ? DEFAULT_RET : \ + FlagOn(FsRtlLegalAnsiCharacterArray[(int)(C)], \ + (FLAGS) | \ + ((WILD_OK) ? FSRTL_WILD_CHARACTER : 0) ) \ + ) + +#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR) ( \ + (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ + (NLS_MB_CODE_PAGE_TAG && \ + (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ + ) + + BOOLEAN STDCALL FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, diff --git a/reactos/include/ddk/iotypes.h b/reactos/include/ddk/iotypes.h index ab96d718012..b7bbe995812 100644 --- a/reactos/include/ddk/iotypes.h +++ b/reactos/include/ddk/iotypes.h @@ -1,4 +1,4 @@ -/* $Id: iotypes.h,v 1.72 2004/12/23 12:28:31 ekohl Exp $ +/* $Id: iotypes.h,v 1.73 2004/12/30 18:30:04 ion Exp $ * */ @@ -801,6 +801,14 @@ typedef BOOLEAN STDCALL_FUNC OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject); +typedef VOID +(*PFAST_IO_ACQUIRE_FILE) ( + IN struct _FILE_OBJECT *FileObject); + +typedef VOID +(*PFAST_IO_RELEASE_FILE) ( + IN struct _FILE_OBJECT *FileObject); + typedef struct _FAST_IO_DISPATCH { ULONG SizeOfFastIoDispatch; PFAST_IO_ROUTINE FastIoCheckIfPossible; @@ -813,8 +821,8 @@ typedef struct _FAST_IO_DISPATCH { PFAST_IO_ROUTINE FastIoUnlockAll; PFAST_IO_ROUTINE FastIoUnlockAllByKey; PFAST_IO_ROUTINE FastIoDeviceControl; - PFAST_IO_ROUTINE AcquireFileForNtCreateSection; - PFAST_IO_ROUTINE ReleaseFileForNtCreateSection; + PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection; + PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection; PFAST_IO_ROUTINE FastIoDetachDevice; PFAST_IO_ROUTINE FastIoQueryNetworkOpenInfo; PFAST_IO_ROUTINE AcquireForModWrite; @@ -878,6 +886,15 @@ struct _FAST_IO_DISPATCH_TABLE } FAST_IO_DISPATCH_TABLE, * PFAST_IO_DISPATCH_TABLE; #endif +#define IO_DRIVER_OBJECT 4L +#define DRVO_UNLOAD_INVOKED 0x1L +#define DRVO_LEGACY_DRIVER 0x2L +#define DRVO_BUILTIN_DRIVER 0x4L +#define DRVO_REINIT_REGISTERED 0x8L +#define DRVO_INITIALIZED 0x10L +#define DRVO_BOOTREINIT_REGISTERED 0x20L +#define DRVO_LEGACY_RESOURCES 0x40L + typedef struct _DRIVER_OBJECT { CSHORT Type; diff --git a/reactos/include/ntos/rtl.h b/reactos/include/ntos/rtl.h index 179622b1ea2..4d88682e054 100755 --- a/reactos/include/ntos/rtl.h +++ b/reactos/include/ntos/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.40 2004/12/16 15:10:00 gdalsnes Exp $ +/* $Id: rtl.h,v 1.41 2004/12/30 18:30:03 ion Exp $ * */ #ifndef __DDK_RTL_H @@ -375,6 +375,7 @@ RemoveTailList( #define IsLastEntry(ListHead, Entry) ((ListHead)->Blink == Entry) +#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination), (Source), (Length))) NTSTATUS STDCALL diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index 6db9c17f10f..816db20b42e 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -1,4 +1,4 @@ -/* $Id: copy.c,v 1.31 2004/08/25 15:08:28 navaraf Exp $ +/* $Id: copy.c,v 1.32 2004/12/30 18:30:05 ion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -35,6 +35,9 @@ void* _alloca(size_t size); ULONG EXPORTED CcFastMdlReadWait; ULONG EXPORTED CcFastReadNotPossible; ULONG EXPORTED CcFastReadWait; +ULONG CcFastReadNoWait; +ULONG CcFastReadResourceMiss; + /* FUNCTIONS *****************************************************************/ diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c index d785851679d..00a72479b7b 100644 --- a/reactos/ntoskrnl/ex/resource.c +++ b/reactos/ntoskrnl/ex/resource.c @@ -1,4 +1,4 @@ -/* $Id: resource.c,v 1.30 2004/11/21 18:38:51 gdalsnes Exp $ +/* $Id: resource.c,v 1.31 2004/12/30 18:30:05 ion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -809,7 +809,7 @@ ExReleaseResourceForThread ( /* - * @unimplemented + * @implemented */ VOID STDCALL @@ -898,7 +898,7 @@ ExReleaseResourceForThreadLite ( /* - * @unimplemented + * @implemented */ VOID STDCALL @@ -907,7 +907,57 @@ ExSetResourceOwnerPointer ( IN PVOID OwnerPointer ) { - + PKTHREAD CurrentThread; + KIRQL OldIrql; + POWNER_ENTRY OwnerEntry; + + CurrentThread = KeGetCurrentThread(); + + /* Lock the resource */ + KeAcquireSpinLock(&Resource->SpinLock, &OldIrql); + + /* Check if it's exclusive */ + if (Resource->Flag & ResourceOwnedExclusive) { + + /* If it's exclusive, set the first entry no matter what */ + Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer; + + } else { + + /* Check both entries and see which one matches the current thread */ + if (Resource->OwnerThreads[0].OwnerThread == (ULONG_PTR)CurrentThread) { + + Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer; + + } else if (Resource->OwnerThreads[1].OwnerThread == (ULONG_PTR)CurrentThread) { + + Resource->OwnerThreads[1].OwnerThread = (ULONG_PTR)OwnerPointer; + + } else { /* None of the entries match, so we need to do a lookup */ + + /* Get the first Entry */ + OwnerEntry = Resource->OwnerTable; + + /* Check if the Current Thread is in the Resource Table Entry */ + if ((CurrentThread->ResourceIndex >= OwnerEntry->TableSize) || + (OwnerEntry[CurrentThread->ResourceIndex].OwnerThread != (ULONG_PTR)CurrentThread)) { + + /* Loop until we find the current thread in an entry */ + for (;OwnerEntry->OwnerThread == (ULONG_PTR)CurrentThread;OwnerEntry++); + + } else { + + /* It's in the current RTE, so set it */ + OwnerEntry = &OwnerEntry[CurrentThread->ResourceIndex]; + } + + /* Now that we went to the right entry, set the Owner Pointer */ + OwnerEntry->OwnerThread = (ULONG_PTR)OwnerPointer; + } + } + + /* Release the resource */ + KeReleaseSpinLock(&Resource->SpinLock, OldIrql); } /* EOF */ diff --git a/reactos/ntoskrnl/fs/dbcsname.c b/reactos/ntoskrnl/fs/dbcsname.c index fac26b799e2..263e97ee7c4 100644 --- a/reactos/ntoskrnl/fs/dbcsname.c +++ b/reactos/ntoskrnl/fs/dbcsname.c @@ -1,4 +1,4 @@ -/* $Id: dbcsname.c,v 1.6 2004/09/11 14:48:13 ekohl Exp $ +/* $Id: dbcsname.c,v 1.7 2004/12/30 18:30:05 ion Exp $ * * reactos/ntoskrnl/fs/dbcsname.c * @@ -171,13 +171,49 @@ PUCHAR EXPORTED FsRtlLegalAnsiCharacterArray = LegalAnsiCharacterArray; * FirstPart: test1 * RemainingPart: test2\test3 * - * @unimplemented + * @implemented */ VOID STDCALL FsRtlDissectDbcs(IN ANSI_STRING Name, OUT PANSI_STRING FirstPart, OUT PANSI_STRING RemainingPart) { + ULONG i; + ULONG FirstLoop; + + /* Initialize the Outputs */ + RtlZeroMemory(&FirstPart, sizeof(ANSI_STRING)); + RtlZeroMemory(&RemainingPart, sizeof(ANSI_STRING)); + + /* Bail out if empty */ + if (!Name.Length) return; + + /* Ignore backslash */ + if (Name.Buffer[0] == '\\') { + i = 1; + } else { + i = 0; + } + + /* Loop until we find a backslash */ + for (FirstLoop = i;i < Name.Length;i++) { + if (Name.Buffer[i] != '\\') break; + if (FsRtlIsLeadDbcsCharacter(Name.Buffer[i])) i++; + } + + /* Now we have the First Part */ + FirstPart->Length = (i-FirstLoop); + FirstPart->MaximumLength = FirstPart->Length; /* +2?? */ + FirstPart->Buffer = &Name.Buffer[FirstLoop]; + + /* Make the second part if something is still left */ + if (iLength = (Name.Length - (i+1)); + RemainingPart->MaximumLength = RemainingPart->Length; /* +2?? */ + RemainingPart->Buffer = &Name.Buffer[i+1]; + } + + return; } @@ -191,15 +227,29 @@ FsRtlDissectDbcs(IN ANSI_STRING Name, * * RETURN VALUE * - * @unimplemented + * @implemented */ BOOLEAN STDCALL FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name) { - return FALSE; + ULONG i; + + /* Check every character */ + for (i=0;i < Name->Length;i++) { + + /* First make sure it's not the Lead DBCS */ + if (FsRtlIsLeadDbcsCharacter(Name->Buffer[i])) { + i++; + } else if (FsRtlIsAnsiCharacterWild(Name->Buffer[i])) { + /* Now return if it has a Wilcard */ + return TRUE; + } + } + + /* We didn't return above...so none found */ + return FALSE; } - /********************************************************************** * NAME EXPORTED * FsRtlIsDbcsInExpression@8 diff --git a/reactos/ntoskrnl/fs/filelock.c b/reactos/ntoskrnl/fs/filelock.c index f4e4fd871be..3ab65402de4 100644 --- a/reactos/ntoskrnl/fs/filelock.c +++ b/reactos/ntoskrnl/fs/filelock.c @@ -1,4 +1,4 @@ -/* $Id: filelock.c,v 1.17 2004/12/30 02:30:40 gdalsnes Exp $ +/* $Id: filelock.c,v 1.18 2004/12/30 18:30:05 ion Exp $ * * reactos/ntoskrnl/fs/filelock.c * @@ -1298,7 +1298,7 @@ FsRtlFreeFileLock( } /* - * @unimplemented + * @implemented */ VOID STDCALL @@ -1306,11 +1306,39 @@ FsRtlAcquireFileExclusive( IN PFILE_OBJECT FileObject ) { - UNIMPLEMENTED; + PFAST_IO_DISPATCH FastDispatch; + PDEVICE_OBJECT DeviceObject; + PFSRTL_COMMON_FCB_HEADER FcbHeader; + + /* Get the Device Object */ + DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); + + /* Check if we have to do a Fast I/O Dispatch */ + if ((FastDispatch = DeviceObject->DriverObject->FastIoDispatch)) { + + /* Call the Fast I/O Routine */ + if (FastDispatch->AcquireFileForNtCreateSection) { + FastDispatch->AcquireFileForNtCreateSection(FileObject); + } + + return; + } + + /* Do a normal acquire */ + if ((FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)) { + + /* Use a Resource Acquire */ + ExAcquireResourceExclusive(FcbHeader->Resource, TRUE); + + return; + } + + /* Return...is there some kind of failure we should raise?? */ + return; } /* - * @unimplemented + * @implemented */ VOID STDCALL @@ -1318,7 +1346,35 @@ FsRtlReleaseFile( IN PFILE_OBJECT FileObject ) { - UNIMPLEMENTED; + PFAST_IO_DISPATCH FastDispatch; + PDEVICE_OBJECT DeviceObject; + PFSRTL_COMMON_FCB_HEADER FcbHeader; + + /* Get the Device Object */ + DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); + + /* Check if we have to do a Fast I/O Dispatch */ + if ((FastDispatch = DeviceObject->DriverObject->FastIoDispatch)) { + + /* Use Fast I/O */ + if (FastDispatch->ReleaseFileForNtCreateSection) { + FastDispatch->ReleaseFileForNtCreateSection(FileObject); + } + + return; + } + + /* Do a normal acquire */ + if ((FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)) { + + /* Use a Resource Release */ + ExReleaseResource(FcbHeader->Resource); + + return; + } + + /* Return...is there some kind of failure we should raise?? */ + return; } diff --git a/reactos/ntoskrnl/fs/mcb.c b/reactos/ntoskrnl/fs/mcb.c index 9376320b565..79771a4494d 100644 --- a/reactos/ntoskrnl/fs/mcb.c +++ b/reactos/ntoskrnl/fs/mcb.c @@ -1,4 +1,4 @@ -/* $Id: mcb.c,v 1.16 2004/11/21 17:47:22 navaraf Exp $ +/* $Id: mcb.c,v 1.17 2004/12/30 18:30:05 ion Exp $ * * reactos/ntoskrnl/fs/mcb.c * @@ -63,7 +63,7 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, /* - * @unimplemented + * @implemented */ BOOLEAN STDCALL FsRtlGetNextMcbEntry (IN PMCB Mcb, @@ -72,19 +72,25 @@ FsRtlGetNextMcbEntry (IN PMCB Mcb, OUT PLBN Lbn, OUT PULONG SectorCount) { - BOOLEAN rc=FALSE; + BOOLEAN Return = FALSE; LONGLONG llVbn; LONGLONG llLbn; LONGLONG llSectorCount; - // FIXME: how should conversion be done - // FIXME: between 32 and 64 bits? - rc=FsRtlGetNextLargeMcbEntry (& Mcb->LargeMcb, - RunIndex, - & llVbn, - & llLbn, - & llSectorCount); - return(rc); + /* Call the Large version */ + Return = FsRtlGetNextLargeMcbEntry(&Mcb->LargeMcb, + RunIndex, + &llVbn, + &llLbn, + &llSectorCount); + + /* Return everything typecasted */ + *Vbn = (ULONG)llVbn; + *Lbn = (ULONG)llLbn; + *SectorCount = (ULONG)llSectorCount; + + /* And return the original value */ + return(Return); } @@ -187,30 +193,60 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, /* - * @unimplemented + * @implemented */ BOOLEAN STDCALL -FsRtlLookupLastMcbEntry (IN PMCB Mcb, - OUT PVBN Vbn, - OUT PLBN Lbn) +FsRtlLookupLastMcbEntry(IN PMCB Mcb, + OUT PVBN Vbn, + OUT PLBN Lbn) { - UNIMPLEMENTED; - return(FALSE); + BOOLEAN Return = FALSE; + LONGLONG llVbn; + LONGLONG llLbn; + + /* Call the Large version */ + Return = FsRtlLookupLastLargeMcbEntry(&Mcb->LargeMcb, + &llVbn, + &llLbn); + + /* Return everything typecasted */ + *Vbn = (ULONG)llVbn; + *Lbn = (ULONG)llLbn; + + /* And return the original value */ + return(Return); } /* - * @unimplemented + * @implemented */ BOOLEAN STDCALL -FsRtlLookupMcbEntry (IN PMCB Mcb, - IN VBN Vbn, - OUT PLBN Lbn, - OUT PULONG SectorCount OPTIONAL, - OUT PULONG Index) +FsRtlLookupMcbEntry(IN PMCB Mcb, + IN VBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount OPTIONAL, + OUT PULONG Index) { - UNIMPLEMENTED; - return(FALSE); + BOOLEAN Return = FALSE; + LONGLONG llLbn; + LONGLONG llSectorCount; + + /* Call the Large version */ + Return = FsRtlLookupLargeMcbEntry(&Mcb->LargeMcb, + (LONGLONG)Vbn, + &llLbn, + &llSectorCount, + NULL, + NULL, + Index); + + /* Return everything typecasted */ + *Lbn = (ULONG)llLbn; + if (SectorCount) *SectorCount = (ULONG)llSectorCount; + + /* And return the original value */ + return(Return); } @@ -253,14 +289,17 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, /* - * @unimplemented + * @implemented */ VOID STDCALL FsRtlRemoveMcbEntry (IN PMCB Mcb, IN VBN Vbn, IN ULONG SectorCount) { - UNIMPLEMENTED; + /* Call the large function */ + return FsRtlRemoveLargeMcbEntry(&Mcb->LargeMcb, + (LONGLONG)Vbn, + (LONGLONG)SectorCount); } diff --git a/reactos/ntoskrnl/fs/mdl.c b/reactos/ntoskrnl/fs/mdl.c index 9bfab285e7d..dfb0cedcd9b 100644 --- a/reactos/ntoskrnl/fs/mdl.c +++ b/reactos/ntoskrnl/fs/mdl.c @@ -1,4 +1,4 @@ -/* $Id: mdl.c,v 1.8 2004/08/15 16:39:02 chorns Exp $ +/* $Id: mdl.c,v 1.9 2004/12/30 18:30:05 ion Exp $ * * reactos/ntoskrnl/fs/mdl.c * @@ -7,44 +7,47 @@ #include #include +extern ULONG CcFastReadResourceMiss; +extern ULONG CcFastReadNoWait; + /* - * @unimplemented + * @implemented */ VOID STDCALL FsRtlIncrementCcFastReadResourceMiss( VOID ) { - UNIMPLEMENTED; + CcFastReadResourceMiss++; } /* - * @unimplemented + * @implemented */ VOID STDCALL FsRtlIncrementCcFastReadNotPossible( VOID ) { - UNIMPLEMENTED; + CcFastReadNotPossible++; } /* - * @unimplemented + * @implemented */ VOID STDCALL FsRtlIncrementCcFastReadWait( VOID ) { - UNIMPLEMENTED; + CcFastReadWait++; } /* - * @unimplemented + * @implemented */ VOID STDCALL FsRtlIncrementCcFastReadNoWait( VOID ) { - UNIMPLEMENTED; + CcFastReadNoWait++; } diff --git a/reactos/ntoskrnl/fs/name.c b/reactos/ntoskrnl/fs/name.c index 8c390cfd4d1..bb03a2da7e1 100644 --- a/reactos/ntoskrnl/fs/name.c +++ b/reactos/ntoskrnl/fs/name.c @@ -1,4 +1,4 @@ -/* $Id: name.c,v 1.12 2004/09/11 14:48:13 ekohl Exp $ +/* $Id: name.c,v 1.13 2004/12/30 18:30:05 ion Exp $ * * reactos/ntoskrnl/fs/name.c * @@ -21,7 +21,7 @@ * NOTE * From Bo Branten's ntifs.h v25. * - * @unimplemented + * @implemented */ BOOLEAN STDCALL FsRtlAreNamesEqual (IN PUNICODE_STRING Name1, @@ -29,7 +29,63 @@ FsRtlAreNamesEqual (IN PUNICODE_STRING Name1, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL) { - return FALSE; + + UNICODE_STRING UpcaseName1; + UNICODE_STRING UpcaseName2; + BOOLEAN StringsAreEqual; + + /* Well, first check their size */ + if (Name1->Length != Name2->Length) { + /* Not equal! */ + return FALSE; + } + + /* Turn them into Upcase if we don't have a table */ + if (IgnoreCase && !UpcaseTable) { + RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE); + RtlUpcaseUnicodeString(&UpcaseName2, Name2, TRUE); + Name1 = &UpcaseName1; + Name2 = &UpcaseName2; + + goto ManualCase; + } + + /* Do a case-sensitive search */ + if (!IgnoreCase) { + +ManualCase: + /* Use a raw memory compare */ + StringsAreEqual = RtlEqualMemory(Name1->Buffer, + Name2->Buffer, + Name1->Length); + + /* Clear the strings if we need to */ + if (IgnoreCase) { + RtlFreeUnicodeString(&UpcaseName1); + RtlFreeUnicodeString(&UpcaseName2); + } + + /* Return the equality */ + return StringsAreEqual; + + } else { + + /* Case in-sensitive search */ + + LONG i; + + for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) { + + if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) { + + /* Non-match found! */ + return FALSE; + } + } + + /* We finished the loop so we are equal */ + return TRUE; + } } @@ -127,31 +183,22 @@ FsRtlDissectName (IN UNICODE_STRING Name, BOOLEAN STDCALL FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name) { - PWCHAR Ptr; + PWCHAR Ptr; - if (Name->Length == 0) - return FALSE; + /* Loop through every character */ + if (Name->Length) { + for (Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR))-1; + Ptr >= Name->Buffer && *Ptr != L'\\';Ptr--) { - /* Set pointer to last character of the string */ - Ptr = Name->Buffer + (Name->Length / sizeof(WCHAR)); - - while (Ptr >= Name->Buffer) - { - /* Stop at backslash */ - if (*Ptr == L'\\') - return FALSE; - - /* Check for wildcards */ - if ((*Ptr < L'@') && - (*Ptr == L'\"' || *Ptr == L'*' || *Ptr == L'<' || - *Ptr == L'>' || *Ptr == L'?')) - return TRUE; - - /* Move to previous character */ - Ptr--; + /* Check for Wildcard */ + if (FsRtlIsUnicodeCharacterWild(*Ptr)) { + return TRUE; + } + } } - return FALSE; + /* Nothing Found */ + return FALSE; } diff --git a/reactos/ntoskrnl/io/driver.c b/reactos/ntoskrnl/io/driver.c index 0136fdacc84..3442179d001 100644 --- a/reactos/ntoskrnl/io/driver.c +++ b/reactos/ntoskrnl/io/driver.c @@ -1,4 +1,4 @@ -/* $Id: driver.c,v 1.57 2004/12/23 23:33:54 navaraf Exp $ +/* $Id: driver.c,v 1.58 2004/12/30 18:30:05 ion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -18,6 +18,7 @@ /* ke/main.c */ extern LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock; +extern ULONG KeTickCount; NTSTATUS LdrProcessModule(PVOID ModuleLoadBase, @@ -1584,7 +1585,7 @@ IopReinitializeDrivers(VOID) /* - * @unimplemented + * @implemented */ NTSTATUS STDCALL @@ -1593,12 +1594,109 @@ IoCreateDriver ( IN PDRIVER_INITIALIZE InitializationFunction ) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + WCHAR NameBuffer[100]; + USHORT NameLength; + UNICODE_STRING LocalDriverName; /* To reduce code if no name given */ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG ObjectSize; + PDRIVER_OBJECT DriverObject; + UNICODE_STRING ServiceKeyName; + HANDLE hDriver; + + /* First, create a unique name for the driver if we don't have one */ + if (!DriverName) { + + /* Create a random name and set up the string*/ + NameLength = swprintf(NameBuffer, L"\\Driver\\%08u", KeTickCount); + LocalDriverName.Length = NameLength * sizeof(WCHAR); + LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL); + LocalDriverName.Buffer = NameBuffer; + + } else { + + /* So we can avoid another code path, use a local var */ + LocalDriverName = *DriverName; + } + + /* Initialize the Attributes */ + ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION); + InitializeObjectAttributes(&ObjectAttributes, + &LocalDriverName, + OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Create the Object */ + Status = ObCreateObject(KernelMode, + IoDriverObjectType, + &ObjectAttributes, + KernelMode, + NULL, + ObjectSize, + 0, + 0, + (PVOID*)&DriverObject); + + /* Return on failure */ + if (!NT_SUCCESS(Status)) return Status; + + /* Set up the Object */ + RtlZeroMemory(DriverObject, ObjectSize); + DriverObject->Type = IO_DRIVER_OBJECT; + DriverObject->Size = sizeof(DRIVER_OBJECT); + DriverObject->Flags = DRVO_BUILTIN_DRIVER; + DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1); + DriverObject->DriverExtension->DriverObject = DriverObject; + DriverObject->DriverInit = InitializationFunction; + /* FIXME: Invalidate all Major Functions b/c now they are NULL and might crash */ + + /* Set up the Service Key Name */ + ServiceKeyName.Buffer = ExAllocatePool(PagedPool, LocalDriverName.Length + sizeof(WCHAR)); + ServiceKeyName.Length = LocalDriverName.Length; + ServiceKeyName.MaximumLength = LocalDriverName.MaximumLength; + RtlMoveMemory(ServiceKeyName.Buffer, LocalDriverName.Buffer, LocalDriverName.Length); + ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = L'\0'; + DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName; + + /* Also store it in the Driver Object. This is a bit of a hack. */ + RtlMoveMemory(&DriverObject->DriverName, &ServiceKeyName, sizeof(UNICODE_STRING)); + + /* Add the Object and get its handle */ + Status = ObInsertObject(DriverObject, + NULL, + FILE_READ_DATA, + 0, + NULL, + &hDriver); + + /* Return on Failure */ + if (!NT_SUCCESS(Status)) return Status; + + /* Now reference it */ + Status = ObReferenceObjectByHandle(hDriver, + 0, + IoDriverObjectType, + KernelMode, + (PVOID*)&DriverObject, + NULL); + ZwClose(hDriver); + + /* Finally, call its init function */ + Status = (*InitializationFunction)(DriverObject, NULL); + + if (!NT_SUCCESS(Status)) { + /* If it didn't work, then kill the object */ + ObMakeTemporaryObject(DriverObject); + ObDereferenceObject(DriverObject); + } + + /* Return the Status */ + return Status; } /* - * @unimplemented + * @implemented */ VOID STDCALL @@ -1606,7 +1704,8 @@ IoDeleteDriver ( IN PDRIVER_OBJECT DriverObject ) { - UNIMPLEMENTED; + /* Simply derefence the Object */ + ObDereferenceObject(DriverObject); }