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
This commit is contained in:
Alex Ionescu 2004-12-30 18:30:05 +00:00
parent b3ba03af69
commit 88454ea69a
11 changed files with 498 additions and 87 deletions

View file

@ -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 <ntos/fstypes.h>
@ -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,

View file

@ -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;

View file

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

View file

@ -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 *****************************************************************/

View file

@ -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 */

View file

@ -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 (i<Name.Length) {
RemainingPart->Length = (Name.Length - (i+1));
RemainingPart->MaximumLength = RemainingPart->Length; /* +2?? */
RemainingPart->Buffer = &Name.Buffer[i+1];
}
return;
}
@ -191,14 +227,28 @@ 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

View file

@ -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;
}

View file

@ -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,
/* Call the Large version */
Return = FsRtlGetNextLargeMcbEntry(&Mcb->LargeMcb,
RunIndex,
&llVbn,
&llLbn,
&llSectorCount);
return(rc);
/* Return everything typecasted */
*Vbn = (ULONG)llVbn;
*Lbn = (ULONG)llLbn;
*SectorCount = (ULONG)llSectorCount;
/* And return the original value */
return(Return);
}
@ -187,20 +193,33 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb,
/*
* @unimplemented
* @implemented
*/
BOOLEAN STDCALL
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,
@ -209,8 +228,25 @@ FsRtlLookupMcbEntry (IN PMCB Mcb,
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);
}

View file

@ -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 <ntoskrnl.h>
#include <internal/debug.h>
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++;
}

View file

@ -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,9 +29,65 @@ FsRtlAreNamesEqual (IN PUNICODE_STRING Name1,
IN BOOLEAN IgnoreCase,
IN PWCHAR UpcaseTable OPTIONAL)
{
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;
}
}
/**********************************************************************
* NAME EXPORTED
@ -129,28 +185,19 @@ FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name)
{
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'?'))
/* Check for Wildcard */
if (FsRtlIsUnicodeCharacterWild(*Ptr)) {
return TRUE;
/* Move to previous character */
Ptr--;
}
}
}
/* Nothing Found */
return FALSE;
}

View file

@ -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);
}