From 5ba4cc87c5389d5fa94eeb13a88df20733c7a91c Mon Sep 17 00:00:00 2001 From: David Welch Date: Mon, 1 Feb 1999 20:58:37 +0000 Subject: [PATCH] Extensive changes to the objmgr Some bug fixes svn path=/trunk/; revision=200 --- reactos/apps/utils/shell/shell.c | 41 +- reactos/drivers/dd/ide/ide.c | 1 - reactos/drivers/fs/ext2/super.c | 17 +- reactos/drivers/fs/vfat/iface.c | 14 + reactos/include/ddk/obfuncs.h | 15 +- reactos/include/ddk/obtypes.h | 21 +- reactos/include/ddk/zw.h | 54 +-- reactos/include/internal/io.h | 10 + reactos/include/internal/ntoskrnl.h | 14 +- reactos/include/internal/ob.h | 9 +- reactos/lib/kernel32/file/create.c | 22 + reactos/lib/kernel32/file/curdir.c | 50 ++- reactos/lib/kernel32/file/dir.c | 150 ++++--- reactos/lib/ntdll/makefile | 2 +- reactos/lib/ntdll/string/ctype.c | 42 ++ reactos/lib/ntdll/stubs/stubs.c | 7 - reactos/ntoskrnl/cc/view.c | 142 +++--- reactos/ntoskrnl/cm/registry.c | 36 +- reactos/ntoskrnl/ex/power.c | 39 +- reactos/ntoskrnl/hal/x86/bios32.c | 5 +- reactos/ntoskrnl/hal/x86/halinit.c | 2 +- reactos/ntoskrnl/hal/x86/isa.c | 2 +- reactos/ntoskrnl/hal/x86/mbr.c | 4 +- reactos/ntoskrnl/hal/x86/mp.c | 4 +- reactos/ntoskrnl/hal/x86/spinlock.c | 5 +- reactos/ntoskrnl/io/buildirp.c | 15 +- reactos/ntoskrnl/io/cleanup.c | 12 +- reactos/ntoskrnl/io/create.c | 174 ++++---- reactos/ntoskrnl/io/device.c | 45 +- reactos/ntoskrnl/io/dir.c | 1 - reactos/ntoskrnl/io/errlog.c | 2 +- reactos/ntoskrnl/io/file.c | 119 +++-- reactos/ntoskrnl/io/flush.c | 2 +- reactos/ntoskrnl/io/iomgr.c | 59 ++- reactos/ntoskrnl/io/irp.c | 20 +- reactos/ntoskrnl/io/page.c | 7 +- reactos/ntoskrnl/io/rw.c | 3 - reactos/ntoskrnl/io/symlink.c | 72 +++- reactos/ntoskrnl/ke/catch.c | 2 +- reactos/ntoskrnl/ke/main.c | 4 +- reactos/ntoskrnl/ldr/loader.c | 10 +- reactos/ntoskrnl/makefile_rex | 6 +- reactos/ntoskrnl/mm/cont.c | 6 +- reactos/ntoskrnl/mm/mdl.c | 2 +- reactos/ntoskrnl/mm/ncache.c | 6 +- reactos/ntoskrnl/mm/section.c | 103 +++-- reactos/ntoskrnl/nt/nt.c | 22 + reactos/ntoskrnl/nt/ntevent.c | 19 +- reactos/ntoskrnl/nt/port.c | 2 +- reactos/ntoskrnl/ob/dirobj.c | 267 ++++++++++++ reactos/ntoskrnl/ob/handle.c | 6 +- reactos/ntoskrnl/ob/namespc.c | 647 +++++++--------------------- reactos/ntoskrnl/ob/ntobj.c | 148 +++++++ reactos/ntoskrnl/ob/object.c | 404 +++++++---------- reactos/ntoskrnl/ps/process.c | 10 +- reactos/ntoskrnl/ps/thread.c | 8 +- reactos/ntoskrnl/rtl/seqlist.c | 6 +- reactos/ntoskrnl/rtl/time.c | 2 - reactos/ntoskrnl/tst/test.c | 159 +------ 59 files changed, 1596 insertions(+), 1482 deletions(-) create mode 100644 reactos/lib/ntdll/string/ctype.c create mode 100644 reactos/ntoskrnl/nt/nt.c create mode 100644 reactos/ntoskrnl/ob/dirobj.c create mode 100644 reactos/ntoskrnl/ob/ntobj.c diff --git a/reactos/apps/utils/shell/shell.c b/reactos/apps/utils/shell/shell.c index 3f2749aa424..851b1745f62 100644 --- a/reactos/apps/utils/shell/shell.c +++ b/reactos/apps/utils/shell/shell.c @@ -18,33 +18,11 @@ void debug_printf(char* fmt, ...) } void ExecuteCd(char* cmdline) -{ - UCHAR Buffer[255]; - - debug_printf("ExecuteCd(cmdline %s)\n",cmdline); - - if (cmdline[0] != '\\' && - cmdline[1] != ':') +{ + if (!SetCurrentDirectoryA(cmdline)) { - GetCurrentDirectoryA(255,Buffer); + debug_printf("Invalid directory\n"); } - else - { - Buffer[0] = 0; - } - debug_printf("Buffer %s\n",Buffer); - - lstrcatA(Buffer,cmdline); - - debug_printf("Buffer %s\n",Buffer); - - if (Buffer[lstrlenA(Buffer)-1] != '\\') - { - lstrcatA(Buffer,"\\"); - } - debug_printf("Buffer %s\n",Buffer); - - SetCurrentDirectoryA(Buffer); } void ExecuteDir(char* cmdline) @@ -136,7 +114,7 @@ void ExecuteCommand(char* line) char* cmd; char* tail; - if (line[1] == ':' && line[2] == 0) + if (isalpha(line[0]) && line[1] == ':' && line[2] == 0) { line[2] = '\\'; line[3] = 0; @@ -155,8 +133,7 @@ void ExecuteCommand(char* line) tail++; } cmd = line; - -// debug_printf("cmd '%s' tail '%s'\n",cmd,tail); + if (cmd==NULL) { @@ -196,11 +173,15 @@ void ReadLine(char* line) do { - ReadConsoleA(InputHandle, + if (!ReadConsoleA(InputHandle, &KeyEvent, sizeof(KEY_EVENT_RECORD), &Result, - NULL); + NULL)) + { + debug_printf("Failed to read from console\n"); + for(;;); + } if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0) { debug_printf("%c", KeyEvent.AsciiChar); diff --git a/reactos/drivers/dd/ide/ide.c b/reactos/drivers/dd/ide/ide.c index 7dfe9c3eefe..1fde5d6416f 100644 --- a/reactos/drivers/dd/ide/ide.c +++ b/reactos/drivers/dd/ide/ide.c @@ -71,7 +71,6 @@ typedef DISK_GEOMETRY *PDISK_GEOMETRY; // ------------------------------------------------------------------------- -#include #include #include diff --git a/reactos/drivers/fs/ext2/super.c b/reactos/drivers/fs/ext2/super.c index acf736263a6..b1cf9d6095b 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" @@ -29,15 +29,24 @@ NTSTATUS Ext2CloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) * FUNCTION: Closes a file */ { + DPRINT("Ext2CloseFile(DeviceExt %x, FileObject %x)\n", + DeviceExt,FileObject); + return(STATUS_SUCCESS); } NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp) { - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); - PFILE_OBJECT FileObject = Stack->FileObject; - PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + PIO_STACK_LOCATION Stack; + PFILE_OBJECT FileObject; + PDEVICE_EXTENSION DeviceExtension; NTSTATUS Status; + DPRINT("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); + + Stack = IoGetCurrentIrpStackLocation(Irp); + FileObject = Stack->FileObject; + DeviceExtension = DeviceObject->DeviceExtension; + Status = Ext2CloseFile(DeviceExtension,FileObject); Irp->IoStatus.Status = Status; diff --git a/reactos/drivers/fs/vfat/iface.c b/reactos/drivers/fs/vfat/iface.c index 26262a0a17c..cb4421806a2 100644 --- a/reactos/drivers/fs/vfat/iface.c +++ b/reactos/drivers/fs/vfat/iface.c @@ -758,9 +758,21 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) { PVfatFCB pFcb; PVfatCCB pCcb; + + DPRINT("FsdCloseFile(DeviceExt %x, FileObject %x)\n", + DeviceExt,FileObject); + //FIXME : update entry in directory ? pCcb = (PVfatCCB)(FileObject->FsContext2); + + DPRINT("pCcb %x\n",pCcb); + if (pCcb == NULL) + { + return(STATUS_SUCCESS); + } + pFcb = pCcb->pFcb; + pFcb->RefCount--; if(pFcb->RefCount<=0) { @@ -1310,6 +1322,8 @@ NTSTATUS FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; NTSTATUS Status; + DPRINT("FsdClose(DeviceObject %x, Irp %x)\n",DeviceObject, Irp); + Status = FsdCloseFile(DeviceExtension,FileObject); Irp->IoStatus.Status = Status; diff --git a/reactos/include/ddk/obfuncs.h b/reactos/include/ddk/obfuncs.h index a405072a271..835f9fd6e5b 100644 --- a/reactos/include/ddk/obfuncs.h +++ b/reactos/include/ddk/obfuncs.h @@ -43,5 +43,16 @@ NTSTATUS ObReferenceObjectByPointer(PVOID Object, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode); -NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes, - PVOID* Object, PWSTR* UnparsedSection); +NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath, + ULONG Attributes, + PACCESS_STATE PassedAccessState, + ACCESS_MASK DesiredAccess, + POBJECT_TYPE ObjectType, + KPROCESSOR_MODE AccessMode, + PVOID ParseContext, + PVOID* ObjectPtr); + +PVOID ObCreateObject(PHANDLE Handle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + POBJECT_TYPE Type); diff --git a/reactos/include/ddk/obtypes.h b/reactos/include/ddk/obtypes.h index fbb04790a04..0bf1ce69e0e 100644 --- a/reactos/include/ddk/obtypes.h +++ b/reactos/include/ddk/obtypes.h @@ -1,4 +1,5 @@ struct _DIRECTORY_OBJECT; +struct _OBJECT_ATTRIBUTES; typedef ULONG ACCESS_STATE, *PACCESS_STATE; @@ -7,9 +8,6 @@ typedef struct _OBJECT_HANDLE_INFORMATION { ACCESS_MASK GrantedAccess; } OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION; -struct _OBJECT; - - typedef struct _OBJECT_TYPE { /* @@ -62,18 +60,18 @@ typedef struct _OBJECT_TYPE /* * PURPOSE: Called to close an object if OkayToClose returns true */ - VOID (*Close)(PVOID ObjectBody); + VOID (*Close)(PVOID ObjectBody, ULONG HandleCount); /* - * PURPOSE: Called to close an object if OkayToClose returns true + * PURPOSE: Called to delete an object when the last reference is removed */ - VOID (*Delete)(VOID); + VOID (*Delete)(PVOID ObjectBody); /* * PURPOSE: Called when an open attempts to open a file apparently * residing within the object */ - PVOID (*Parse)(struct _OBJECT *ParsedObject, PWSTR UnparsedSection); + PVOID (*Parse)(PVOID ParsedObject, PWSTR* Path); /* */ @@ -87,7 +85,12 @@ typedef struct _OBJECT_TYPE * PURPOSE: Called when a process asks to close the object */ VOID (*OkayToClose)(VOID); - + + NTSTATUS (*Create)(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + } OBJECT_TYPE, *POBJECT_TYPE; @@ -133,3 +136,5 @@ typedef struct _HANDLE_TABLE LIST_ENTRY ListHead; KSPIN_LOCK ListLock; } HANDLE_TABLE, *PHANDLE_TABLE; + +extern POBJECT_TYPE ObDirectoryType; diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index 897af889579..f62d7852bb6 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -1558,47 +1558,35 @@ ZwFlushVirtualMemory( IN ULONG NumberOfBytesToFlush, OUT PULONG NumberOfBytesFlushed OPTIONAL ); + /* * FUNCTION: Flushes the dirty pages to file - * RETURNS: Status + * RETURNS: Status + * FIXME: Not sure this does (how is the file specified) */ -NTSTATUS -STDCALL -NtFlushWriteBuffer ( - VOID - ); -NTSTATUS -STDCALL -ZwFlushWriteBuffer ( - VOID - ); -/* +NTSTATUS STDCALL NtFlushWriteBuffer(VOID); +NTSTATUS STDCALL ZwFlushWriteBuffer(VOID); + + /* * FUNCTION: Frees a range of virtual memory * ARGUMENTS: - * ProcessHandle = Points to the process that allocated the virtual memory - * BaseAddress = Points to the memory address, rounded down to a multiple of the pagesize - * RegionSize = Limits the range to free, rounded up to a multiple of the paging size + * ProcessHandle = Points to the process that allocated the virtual + * memory + * BaseAddress = Points to the memory address, rounded down to a + * multiple of the pagesize + * RegionSize = Limits the range to free, rounded up to a multiple of + * the paging size * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE * RETURNS: Status */ - -NTSTATUS -STDCALL -NtFreeVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID *BaseAddress, - IN PULONG RegionSize, - IN ULONG FreeType - ); - -NTSTATUS -STDCALL -ZwFreeVirtualMemory( - IN HANDLE ProcessHandle, - IN PVOID *BaseAddress, - IN PULONG RegionSize, - IN ULONG FreeType - ); +NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID *BaseAddress, + IN PULONG RegionSize, + IN ULONG FreeType); +NTSTATUS STDCALL ZwFreeVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID *BaseAddress, + IN PULONG RegionSize, + IN ULONG FreeType); /* * FUNCTION: Sends FSCTL to the filesystem diff --git a/reactos/include/internal/io.h b/reactos/include/internal/io.h index 2a86cbedcc9..0e37fdf0566 100644 --- a/reactos/include/internal/io.h +++ b/reactos/include/internal/io.h @@ -45,4 +45,14 @@ NTSTATUS IoPageRead(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, PIO_STATUS_BLOCK StatusBlock); VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost); + +NTSTATUS IopCreateFile(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes); +NTSTATUS IopCreateDevice(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes); + #endif diff --git a/reactos/include/internal/ntoskrnl.h b/reactos/include/internal/ntoskrnl.h index 850fda90779..a4d04c28cdc 100644 --- a/reactos/include/internal/ntoskrnl.h +++ b/reactos/include/internal/ntoskrnl.h @@ -78,16 +78,18 @@ typedef struct unsigned int module_length[64]; } boot_param; +VOID NtInitializeEventImplementation(VOID); +VOID NtInit(VOID); /* * Initalization functions (called once by main()) */ -void MmInitialize(boot_param* bp); -void HalInit(boot_param* bp); -void IoInit(void); -void ObInit(void); -void PsInit(void); -void TstBegin(void); +VOID MmInitialize(boot_param* bp); +VOID HalInit(boot_param* bp); +VOID IoInit(VOID); +VOID ObInit(VOID); +VOID PsInit(VOID); +VOID TstBegin(VOID); VOID KeInit(VOID); VOID HalInitConsole(boot_param* bp); diff --git a/reactos/include/internal/ob.h b/reactos/include/internal/ob.h index f2f9bf72b26..a328ced9510 100644 --- a/reactos/include/internal/ob.h +++ b/reactos/include/internal/ob.h @@ -61,10 +61,10 @@ VOID ObDeleteHandle(HANDLE Handle); NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object, PWSTR* UnparsedSection, ULONG Attributes); -PVOID ObGenericCreateObject(PHANDLE Handle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - POBJECT_TYPE Type); +PVOID ObCreateObject(PHANDLE Handle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + POBJECT_TYPE Type); VOID ObInitializeHandleTable(PKPROCESS Parent, BOOLEAN Inherit, PKPROCESS Process); VOID ObRemoveEntry(POBJECT_HEADER Header); @@ -101,5 +101,6 @@ typedef struct } HANDLE_REP, *PHANDLE_REP; PHANDLE_REP ObTranslateHandle(PKPROCESS Process, HANDLE h); +extern PDIRECTORY_OBJECT NameSpaceRoot; #endif /* __INCLUDE_INTERNAL_OBJMGR_H */ diff --git a/reactos/lib/kernel32/file/create.c b/reactos/lib/kernel32/file/create.c index 7a8954ddaf3..368c18ef10b 100644 --- a/reactos/lib/kernel32/file/create.c +++ b/reactos/lib/kernel32/file/create.c @@ -79,6 +79,28 @@ HANDLE STDCALL CreateFileW(LPCWSTR lpFileName, WCHAR *FilePart; UINT Len = 0; + switch (dwCreationDisposition) + { + case CREATE_NEW: + dwCreationDisposition = FILE_CREATE; + break; + + case CREATE_ALWAYS: + dwCreationDisposition = FILE_OVERWRITE_IF; + break; + + case OPEN_EXISTING: + dwCreationDisposition = FILE_OPEN; + break; + + case OPEN_ALWAYS: + dwCreationDisposition = OPEN_ALWAYS; + break; + + case TRUNCATE_EXISTING: + dwCreationDisposition = FILE_OVERWRITE; + } + DPRINT("CreateFileW(lpFileName %w)\n",lpFileName); if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)) diff --git a/reactos/lib/kernel32/file/curdir.c b/reactos/lib/kernel32/file/curdir.c index d12b1eb99ac..da5be7587b5 100644 --- a/reactos/lib/kernel32/file/curdir.c +++ b/reactos/lib/kernel32/file/curdir.c @@ -63,7 +63,8 @@ DWORD STDCALL GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer) BOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName) { UINT i; - + WCHAR TempStr[MAX_PATH]; + DPRINT("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName); if ( lpPathName == NULL ) @@ -73,24 +74,59 @@ BOOL STDCALL SetCurrentDirectoryA(LPCSTR lpPathName) i = 0; while ((lpPathName[i])!=0 && i < MAX_PATH) { - CurrentDirectoryW[i] = (unsigned short)lpPathName[i]; + TempStr[i] = (unsigned short)lpPathName[i]; i++; } - CurrentDirectoryW[i] = 0; + TempStr[i] = 0; - DPRINT("CurrentDirectoryW = '%w'\n",CurrentDirectoryW); - - return(TRUE); + return(SetCurrentDirectoryW(TempStr)); } WINBOOL STDCALL SetCurrentDirectoryW(LPCWSTR lpPathName) { + WCHAR TempDir[MAX_PATH]; + HANDLE TempHandle; + ULONG Len; + + DPRINT("SetCurrentDirectoryW(lpPathName %w)\n",lpPathName); + if ( lpPathName == NULL ) return FALSE; if ( lstrlenW(lpPathName) > MAX_PATH ) return FALSE; - lstrcpyW(CurrentDirectoryW,lpPathName); + + lstrcpyW(TempDir, CurrentDirectoryW); + GetFullPathNameW(lpPathName, + MAX_PATH, + TempDir, + NULL); + + Len = lstrlenW(TempDir); + if (TempDir[Len-1] != '\\') + { + TempDir[Len] = '\\'; + TempDir[Len+1] = 0; + } + + DPRINT("TempDir %w\n",TempDir); + + TempHandle = CreateFileW(TempDir, + FILE_TRAVERSE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_DIRECTORY, + NULL); + if (TempHandle == NULL) + { + return(FALSE); + } + CloseHandle(TempHandle); + lstrcpyW(CurrentDirectoryW, TempDir); + + DPRINT("CurrentDirectoryW %w\n",CurrentDirectoryW); + return(TRUE); } diff --git a/reactos/lib/kernel32/file/dir.c b/reactos/lib/kernel32/file/dir.c index 573cb531461..edb30aa0194 100644 --- a/reactos/lib/kernel32/file/dir.c +++ b/reactos/lib/kernel32/file/dir.c @@ -171,84 +171,80 @@ DWORD STDCALL GetFullPathNameA(LPCSTR lpFileName, } -#define IS_END_OF_NAME(ch) (!(ch) || ((ch) == L'/') || ((ch) == L'\\')) - - -DWORD -STDCALL -GetFullPathNameW( - LPCWSTR lpFileName, - DWORD nBufferLength, - LPWSTR lpBuffer, - LPWSTR *lpFilePart - ) +DWORD STDCALL GetFullPathNameW(LPCWSTR lpFileName, + DWORD nBufferLength, + LPWSTR lpBuffer, + LPWSTR *lpFilePart) { - - WCHAR buffer[MAX_PATH]; - WCHAR *p; - - if (!lpFileName || !lpBuffer) return 0; - - p = buffer; - - if (IS_END_OF_NAME(*lpFileName) && (*lpFileName)) /* Absolute path */ - { - while (*lpFileName == L'\\') - lpFileName++; - } - else /* Relative path or empty path */ - { - if ( GetCurrentDirectoryW(MAX_PATH,p) == 0 ) - wcscpy( p, L"C:"); - if (*p) - p += wcslen(p); - } - if (!*lpFileName) /* empty path */ - *p++ = '\\'; - *p = '\0'; - - while (*lpFileName) - { - if (*lpFileName == '.') - { - if (IS_END_OF_NAME(lpFileName[1])) - { - lpFileName++; - while (*lpFileName == L'\\' ) lpFileName++; - continue; - } - else if ((lpFileName[1] == L'.') && IS_END_OF_NAME(lpFileName[2])) - { - lpFileName += 2; - while ((*lpFileName == '\\') ) lpFileName++; - while ((p > buffer + 2) && (*p != '\\')) p--; - *p = '\0'; /* Remove trailing separator */ - continue; - } - } - if (p >= buffer + sizeof(buffer) - 1) - { - //DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk); - return 0; - } - *p++ = '\\'; - while (!IS_END_OF_NAME(*lpFileName) && (p < buffer + sizeof(buffer) -1)) - *p++ = *lpFileName++; - *p = '\0'; - while ((*lpFileName == '\\') ) lpFileName++; - } - - if (!buffer[2]) - { - buffer[2] = '\\'; - buffer[3] = '\0'; - } - - - wcsncpy( lpBuffer, buffer, nBufferLength); - - //TRACE(dosfs, "returning %s\n", buffer ); - return wcslen(buffer); + PWSTR p; + PWSTR prev = NULL; + + DPRINT("GetFullPathNameW(lpFileName %w, nBufferLength %d, lpBuffer %w, " + "lpFilePart %x)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart); + + if (!lpFileName || !lpBuffer) return 0; + + if (isalpha(lpFileName[0]) && lpFileName[1] == ':') + { + lstrcpyW(lpBuffer, lpFileName); + } + else if (lpFileName[0] == '\\') + { + lstrcpyW(&lpBuffer[2], lpFileName); + } + else + { + lstrcatW(lpBuffer, lpFileName); + } + + DPRINT("lpBuffer %w\n",lpBuffer); + + p = lpBuffer + 2; + + while ((*p) != 0) + { + DPRINT("prev %w p %w\n",prev,p); + if (p[1] == '.' && (p[2] == '\\' || p[2] == 0)) + { + lstrcpyW(p, p+2); + } + else if (p[1] == '.' && p[2] == '.' && (p[3] == '\\' || p[3] == 0) && + prev != NULL) + { + lstrcpyW(prev, p+3); + p = prev; + if (prev == (lpBuffer+2)) + { + prev = NULL; + } + else + { + prev--; + while ((*prev) != '\\') + { + prev--; + } + } + } + else + { + prev = p; + do + { + p++; + } + while ((*p) != 0 && (*p) != '\\'); + } + } + + if (lpFilePart != NULL) + { + (*lpFilePart) = prev; + } + + DPRINT("lpBuffer %w\n",lpBuffer); + + return wcslen(lpBuffer); } diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index 4100b9ee3b1..444aef689a8 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,7 +1,7 @@ all: ntdll.a OBJECTS = napi.o stubs/stubs.o string/wstring.o stdio/vsprintf.o \ - rtl/unicode.o rtl/namespc.o + rtl/unicode.o rtl/namespc.o string/ctype.o ntdll.a: $(OBJECTS) $(AR) vcsr ntdll.a $(OBJECTS) diff --git a/reactos/lib/ntdll/string/ctype.c b/reactos/lib/ntdll/string/ctype.c new file mode 100644 index 00000000000..44ca6963d3f --- /dev/null +++ b/reactos/lib/ntdll/string/ctype.c @@ -0,0 +1,42 @@ + +#define upalpha ('A' - 'a') + +int isalpha(char c) +{ + return(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))); +} + +int isspace(char c) +{ + return(c==' '||c=='\t'); +} + +char toupper(char c) +{ + if ((c>='a') && (c<='z')) return (c+upalpha); + return(c); +} + +int islower(char c) +{ + if ((c>='a') && (c<='z')) return 1; + return 0; +} + +int isdigit(char c) +{ + if ((c>='0') && (c<='9')) return 1; + return 0; +} + +int isxdigit(char c) +{ + if (((c>='0') && (c<='9')) || ((toupper(c)>='A') && (toupper(c)<='Z'))) + { + return 1; + } + return 0; +} + + + diff --git a/reactos/lib/ntdll/stubs/stubs.c b/reactos/lib/ntdll/stubs/stubs.c index 3df7a08baa8..354bbd475d7 100644 --- a/reactos/lib/ntdll/stubs/stubs.c +++ b/reactos/lib/ntdll/stubs/stubs.c @@ -543,18 +543,13 @@ STUB(cos) STUB(fabs) STUB(floor) STUB(isalnum) -STUB(isalpha) STUB(iscntrl) -STUB(isdigit) STUB(isgraph) -STUB(islower) STUB(isprint) STUB(ispunct) -STUB(isspace) STUB(isupper) STUB(iswalpha) STUB(iswctype) -STUB(isxdigit) STUB(labs) STUB(log) STUB(mbstowcs) @@ -585,6 +580,4 @@ STUB(strtol) STUB(strtoul) STUB(swprintf) STUB(tan) -STUB(tolower) -STUB(toupper) STUB(towlower) diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 1181f0b4033..f9c49c2a316 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -12,127 +12,97 @@ #include #include +#include #define NDEBUG #include /* TYPES *********************************************************************/ -#define CACHE_SEGMENT_SIZE (0x10000) - -#define CACHE_SEGMENT_INVALID (0) // Isn't valid -#define CACHE_SEGMENT_WRITTEN (1) // Written -#define CACHE_SEGMENT_READ (2) +#define CACHE_SEGMENT_SIZE (0x10000) typedef struct _CACHE_SEGMENT { - ULONG Type; // Debugging - ULONG Size; - LIST_ENTRY ListEntry; // Entry in the per-open list of segments - PVOID BaseAddress; // Base address of the mapping - ULONG ValidLength; // Length of the mapping - ULONG State; // Information - MEMORY_AREA* MemoryArea; // Memory area for the mapping - ULONG FileOffset; // Offset within the file of the mapping - KEVENT Event; - BOOLEAN Dirty; // Contains dirty data + PVOID BaseAddress; + PMEMORY_AREA MemoryArea; + ULONG ValidPages; + ULONG AllocatedPages; + LIST_ENTRY ListEntry; + ULONG FileOffset; } CACHE_SEGMENT, *PCACHE_SEGMENT; -typedef struct _CC1_CCB +typedef struct _BCB { - ULONG Type; - ULONG Size; LIST_ENTRY CacheSegmentListHead; - KSPIN_LOCK CacheSegmentListLock; - LIST_ENTRY ListEntry; -} CC1_CCB, PCC1_CCB; + PFILE_OBJECT FileObject; + KSPIN_LOCK BcbLock; +} BCB, *PBCB; /* FUNCTIONS *****************************************************************/ -PVOID Cc1FlushView(PCC1_CCB CacheDesc, - ULONG FileOffset, - ULONG Length) -{ -} - -PVOID Cc1PurgeView(PCC1_CCB CacheDesc, - ULONG FileOffset, - ULONG Length) -{ -} - - - -NTSTATUS Cc1RequestView(PCC1_CCB CacheDesc, - ULONG FileOffset, - ULONG Length, - PCACHE_SEGMENT ReturnedSegments[], - PULONG NrSegments) -/* - * FUNCTION: Request a view for caching data - */ +NTSTATUS CcRequestCachePage(PBCB Bcb, + ULONG FileOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate) { + KIRQL oldirql; PLIST_ENTRY current_entry; PCACHE_SEGMENT current; - PCACHE_SEGMENT new_segment; - ULONG MaxSegments; - ULONG LengthDelta; + ULONG InternalOffset; - MaxSegments = *NrSegments; - (*NrSegments) = 0; + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - KeAcquireSpinLock(&CacheDesc->CacheSegmentListLock); - - current_entry = CacheDesc->CacheSegmentListHead.Flink; - while (current_entry != &(CacheDesc->CacheSegmentListHead)) + current_entry = Bcb->CacheSegmentListHead.Flink; + while (current_entry != &Bcb->CacheSegmentListHead) { - current = CONTAING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); - + current = CONTAING_RECORD(current, CACHE_SEGMENT, ListEntry); if (current->FileOffset <= FileOffset && - (current->FileOffset + current->ValidLength) > FileOffset) + (current->FileOffset + CACHE_SEGMENT_SIZE) > FileOffset) { - ReturnedSegments[(*NrSegments)] = current; - (*NrSegments)++; - FileOffset = current->FileOffset + current->ValidLength; - LengthDelta = (FileOffset - current->FileOffset); - if (Length <= LengthDelta) + InternalOffset = (FileOffset - current->FileOffset); + + if (!test_bit(InternalOffset / PAGESIZE, + current->AllocatedPages)) { - KeReleaseSpinLock(&CacheDesc->CacheSegmentListLock); - return(STATUS_SUCCESS); + MmSetPageEntry(PsGetCurrentProcess(), + current->BaseAddress + InternalOffset, + PAGE_READWRITE, + get_free_page()); } - Length = Length - LengthDelta; + if (!test_bit(InternalOffset / PAGESIZE, + current->ValidPages)) + { + UptoDate = False; + } + else + { + UptoDate = True; + } + (*BaseAddress) = current->BaseAddress + InternalOffset; + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + return(STATUS_SUCCESS); } - else if (current->FileOffset <= (FileOffset + Length) && - (current->FileOffset + current->ValidLength) > - (FileOffset + Length)) - { - ReturnedSegments[(*NrSegments)] = current; - (*NrSegments)++; - Length = Length - ((FileOffset + Length) - current->FileOffset); - } - current_entry = current_entry->Flink; } - KeReleaseSpinLock(&CacheDesc->CacheSegmentListLock); + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); } -PCC1_CCB Cc1InitializeFileCache(PFILE_OBJECT FileObject) -/* - * FUNCTION: Initialize caching for a file - */ +NTSTATUS CcInitializeFileCache(PFILE_OBJECT FileObject, + PBCB* Bcb) { - PCC1_CCB CacheDesc; - - CacheDesc = ExAllocatePool(NonPagedPool, sizeof(CC1_CCB)); - if (CacheDesc == NULL) + (*Bcb) = ExAllocatePool(NonPagedPool, sizeof(BCB)); + if ((*Bcb) == NULL) { - return(NULL); + return(STATUS_OUT_OF_MEMORY); } - CacheDesc->Type = CC1_CCB_ID; - InitializeListHead(&CacheDesc->CacheSegmentListHead); - KeInitializeSpinLock(&CacheDesc->CacheSegmentListLock); + (*Bcb)->FileObject = FileObject; + InitializeListHead(&(*Bcb)->CacheSegmentListHead); + KeInitializeSpinLock(&(*Bcb)->BcbLock); - return(CacheDesc); + return(STATUS_SUCCESS); } + + + diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 80a4508146c..0b6955acdcc 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -619,46 +619,32 @@ NtSetInformationKey( KeyInformationLength); } -NTSTATUS -STDCALL -ZwSetInformationKey( - IN HANDLE KeyHandle, - IN CINT KeyInformationClass, - IN PVOID KeyInformation, - IN ULONG KeyInformationLength - ) +NTSTATUS STDCALL ZwSetInformationKey(IN HANDLE KeyHandle, + IN CINT KeyInformationClass, + IN PVOID KeyInformation, + IN ULONG KeyInformationLength) { - UNIMPLEMENTED; + UNIMPLEMENTED; } -NTSTATUS -STDCALL -NtUnloadKey( - HANDLE KeyHandle - ) +NTSTATUS STDCALL NtUnloadKey(HANDLE KeyHandle) { return ZwUnloadKey(KeyHandle); } -NTSTATUS -STDCALL -ZwUnloadKey( - HANDLE KeyHandle - ) +NTSTATUS STDCALL ZwUnloadKey(HANDLE KeyHandle) { - UNIMPLEMENTED; + UNIMPLEMENTED; } -NTSTATUS STDCALL -NtInitializeRegistry(BOOLEAN SetUpBoot) +NTSTATUS STDCALL NtInitializeRegistry(BOOLEAN SetUpBoot) { return ZwInitializeRegistry(SetUpBoot); } -NTSTATUS STDCALL -ZwInitializeRegistry(BOOLEAN SetUpBoot) +NTSTATUS STDCALL ZwInitializeRegistry(BOOLEAN SetUpBoot) { - UNIMPLEMENTED; + UNIMPLEMENTED; } NTSTATUS RtlCheckRegistryKey(ULONG RelativeTo, PWSTR Path) diff --git a/reactos/ntoskrnl/ex/power.c b/reactos/ntoskrnl/ex/power.c index a1783a1d3d8..125a2ce06b1 100644 --- a/reactos/ntoskrnl/ex/power.c +++ b/reactos/ntoskrnl/ex/power.c @@ -1,16 +1,18 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/bug.c - * PURPOSE: Graceful system shutdown if a bug is detected - * PROGRAMMER: David Welch (welch@mcmail.com) + * FILE: ntoskrnl/ex/power.c + * PURPOSE: Power managment + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 + * Added reboot support 30/01/99 */ /* INCLUDES *****************************************************************/ #include +#include #include @@ -26,7 +28,34 @@ NTSTATUS STDCALL NtShutdownSystem(IN SHUTDOWN_ACTION Action) return(ZwShutdownSystem(Action)); } -NTSTATUS STDCALL ZwShutdownSystem(IN SHUTDOWN_ACTION Action) +static void kb_wait(void) { - UNIMPLEMENTED; + int i; + + for (i=0; i<10000; i++) + { + if ((inb_p(0x64) & 0x02) == 0) + { + return; + } + } +} + +NTSTATUS STDCALL ZwShutdownSystem(IN SHUTDOWN_ACTION Action) +/* + * FIXME: Does a reboot only + */ +{ + int i, j; + + for (;;) + { + for (i=0; i<100; i++) + { + kb_wait(); + for (j=0; j<500; j++); + outb(0xfe, 0x64); + for (j=0; j<500; j++); + } + } } diff --git a/reactos/ntoskrnl/hal/x86/bios32.c b/reactos/ntoskrnl/hal/x86/bios32.c index 55c91865952..49d67034129 100644 --- a/reactos/ntoskrnl/hal/x86/bios32.c +++ b/reactos/ntoskrnl/hal/x86/bios32.c @@ -1,8 +1,8 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: mkernel/hal/eisa.c - * PURPOSE: Interfaces to the PCI bus + * FILE: ntoskrnl/hal/pci + * PURPOSE: Interfaces to BIOS32 interface * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * 05/06/98: Created @@ -14,7 +14,6 @@ /* INCLUDES ***************************************************************/ -#include #include #include #include diff --git a/reactos/ntoskrnl/hal/x86/halinit.c b/reactos/ntoskrnl/hal/x86/halinit.c index 8b06db7aa5d..3176ea6d86a 100644 --- a/reactos/ntoskrnl/hal/x86/halinit.c +++ b/reactos/ntoskrnl/hal/x86/halinit.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: mkernel/hal/x86/halinit.c + * FILE: ntoskrnl/hal/x86/halinit.c * PURPOSE: Initalize the uniprocessor, x86 hal * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: diff --git a/reactos/ntoskrnl/hal/x86/isa.c b/reactos/ntoskrnl/hal/x86/isa.c index 4a738a848d6..d92fe992e5f 100644 --- a/reactos/ntoskrnl/hal/x86/isa.c +++ b/reactos/ntoskrnl/hal/x86/isa.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: mkernel/hal/eisa.c + * FILE: ntoskrnl/hal/isa.c * PURPOSE: Interfaces to the ISA bus * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: diff --git a/reactos/ntoskrnl/hal/x86/mbr.c b/reactos/ntoskrnl/hal/x86/mbr.c index 27fa2ee3c63..5dc30a9e203 100644 --- a/reactos/ntoskrnl/hal/x86/mbr.c +++ b/reactos/ntoskrnl/hal/x86/mbr.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/hal/x86/mbr.c + * FILE: ntoskrnl/hal/x86/mbr.c * PURPOSE: Functions for reading the master boot record (MBR) - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ diff --git a/reactos/ntoskrnl/hal/x86/mp.c b/reactos/ntoskrnl/hal/x86/mp.c index 2efc20575b6..22ad8465336 100644 --- a/reactos/ntoskrnl/hal/x86/mp.c +++ b/reactos/ntoskrnl/hal/x86/mp.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/hal/x86/mp.c + * FILE: ntoskrnl/hal/x86/mp.c * PURPOSE: Multiprocessor stubs - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ diff --git a/reactos/ntoskrnl/hal/x86/spinlock.c b/reactos/ntoskrnl/hal/x86/spinlock.c index efc26eaee1f..435d7229dbb 100644 --- a/reactos/ntoskrnl/hal/x86/spinlock.c +++ b/reactos/ntoskrnl/hal/x86/spinlock.c @@ -1,9 +1,9 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/hal/x86/spinlock.c + * FILE: ntoskrnl/hal/x86/spinlock.c * PURPOSE: Implements spinlocks - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 3/6/98: Created */ @@ -15,7 +15,6 @@ /* INCLUDES ****************************************************************/ -#include #include #include diff --git a/reactos/ntoskrnl/io/buildirp.c b/reactos/ntoskrnl/io/buildirp.c index 0da2c8debaf..cafa0b34a75 100644 --- a/reactos/ntoskrnl/io/buildirp.c +++ b/reactos/ntoskrnl/io/buildirp.c @@ -35,7 +35,7 @@ NTSTATUS IoPrepareIrpBuffer(PIRP Irp, if (Irp->AssociatedIrp.SystemBuffer==NULL) { IoFreeIrp(Irp); - return(NULL); + return(STATUS_NOT_IMPLEMENTED); } /* FIXME: should copy buffer in on other ops */ if (MajorFunction == IRP_MJ_WRITE) @@ -262,11 +262,14 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction, StackPtr->FileObject = NULL; StackPtr->CompletionRoutine = NULL; - IoPrepareIrpBuffer(Irp, - DeviceObject, - Buffer, - Length, - MajorFunction); + if (Buffer != NULL) + { + IoPrepareIrpBuffer(Irp, + DeviceObject, + Buffer, + Length, + MajorFunction); + } if (MajorFunction == IRP_MJ_READ) { diff --git a/reactos/ntoskrnl/io/cleanup.c b/reactos/ntoskrnl/io/cleanup.c index 856d4f7ccb5..1dfab951679 100644 --- a/reactos/ntoskrnl/io/cleanup.c +++ b/reactos/ntoskrnl/io/cleanup.c @@ -24,13 +24,11 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IoStack) -{ +{ PFILE_OBJECT FileObject; FileObject = IoStack->FileObject; - DPRINT("FileObject %x\n",FileObject); - if (DeviceObject->Flags & DO_BUFFERED_IO) { if (IoStack->MajorFunction == IRP_MJ_READ) @@ -70,6 +68,7 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost) { PIO_STACK_LOCATION IoStack; PDEVICE_OBJECT DeviceObject; + PFILE_OBJECT FileObject; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -97,6 +96,13 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost) { KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE); } + + FileObject = IoStack->FileObject; + + if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE) + { + ObDereferenceObject(FileObject); + } IoFreeIrp(Irp); } diff --git a/reactos/ntoskrnl/io/create.c b/reactos/ntoskrnl/io/create.c index dab472d5150..73a29ccc092 100644 --- a/reactos/ntoskrnl/io/create.c +++ b/reactos/ntoskrnl/io/create.c @@ -57,6 +57,68 @@ NTSTATUS NtCreateFile(PHANDLE FileHandle, EaLength)); } +NTSTATUS IopCreateFile(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parent; + PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody; + NTSTATUS Status; + + DPRINT("IopCreateFile(ObjectBody %x, Parent %x, RemainingPath %w)\n", + ObjectBody,Parent,RemainingPath); + + Status = ObReferenceObjectByPointer(DeviceObject, + STANDARD_RIGHTS_REQUIRED, + IoDeviceType, + UserMode); + if (Status != STATUS_SUCCESS) + { + CHECKPOINT; + return(Status); + } + + DeviceObject = IoGetAttachedDevice(DeviceObject); + + DPRINT("DeviceObject %x\n",DeviceObject); + + if (RemainingPath == NULL) + { + FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN; + FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool, + (ObjectAttributes->ObjectName->Length+1)*2); + FileObject->FileName.Length = ObjectAttributes->ObjectName->Length; + FileObject->FileName.MaximumLength = + ObjectAttributes->ObjectName->MaximumLength; + RtlCopyUnicodeString(&(FileObject->FileName), + ObjectAttributes->ObjectName); + } + else + { + if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM && + DeviceObject->DeviceType != FILE_DEVICE_DISK) + { + return(STATUS_UNSUCCESSFUL); + } + if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED)) + { + Status = IoTryToMountStorageDevice(DeviceObject); + if (Status!=STATUS_SUCCESS) + { + return(Status); + } + DeviceObject = IoGetAttachedDevice(DeviceObject); + } + RtlInitUnicodeString(&(FileObject->FileName),wstrdup(RemainingPath)); + } + DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer); + FileObject->DeviceObject=DeviceObject; + FileObject->Vpb=DeviceObject->Vpb; + + return(STATUS_SUCCESS); +} + NTSTATUS ZwCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, @@ -91,14 +153,11 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle, * RETURNS: Status */ { - PVOID Object; + PFILE_OBJECT FileObject; NTSTATUS Status; PIRP Irp; KEVENT Event; - PDEVICE_OBJECT DeviceObject; - PFILE_OBJECT FileObject; PIO_STACK_LOCATION StackLoc; - PWSTR Remainder; DPRINT("ZwCreateFile(FileHandle %x, DesiredAccess %x, " "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %w)\n", @@ -109,76 +168,15 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle, *FileHandle=0; - FileObject = ObGenericCreateObject(FileHandle, - DesiredAccess, - NULL, - IoFileType); - memset(FileObject,0,sizeof(FILE_OBJECT)); - - Status = ObOpenObjectByName(ObjectAttributes,&Object,&Remainder); - - if (Status != STATUS_SUCCESS && Status != STATUS_FS_QUERY_REQUIRED) + FileObject = ObCreateObject(FileHandle, + DesiredAccess, + ObjectAttributes, + IoFileType); + if (FileObject == NULL) { - DPRINT("%s() = Failed to find object\n",__FUNCTION__); - ObDereferenceObject(FileObject); - ZwClose(*FileHandle); - *FileHandle=0; return(STATUS_UNSUCCESSFUL); } - - DeviceObject = (PDEVICE_OBJECT)Object; - DeviceObject = IoGetAttachedDevice(DeviceObject); - - if (Status == STATUS_SUCCESS) - { - CHECKPOINT; - FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN; - FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool, - (ObjectAttributes->ObjectName->Length+1)*2); - FileObject->FileName.Length = ObjectAttributes->ObjectName->Length; - FileObject->FileName.MaximumLength = - ObjectAttributes->ObjectName->MaximumLength; - RtlCopyUnicodeString(&(FileObject->FileName), - ObjectAttributes->ObjectName); - } - else - { - CHECKPOINT; - DPRINT("DeviceObject %x\n",DeviceObject); - DPRINT("FileHandle %x\n",FileHandle); - if (DeviceObject->DeviceType != FILE_DEVICE_FILE_SYSTEM && - DeviceObject->DeviceType != FILE_DEVICE_DISK) - { - ObDereferenceObject(FileObject); - ZwClose(*FileHandle); - *FileHandle=0; - return(STATUS_UNSUCCESSFUL); - } - DPRINT("DeviceObject->Vpb %x\n",DeviceObject->Vpb); - if (!(DeviceObject->Vpb->Flags & VPB_MOUNTED)) - { - CHECKPOINT; - Status = IoTryToMountStorageDevice(DeviceObject); - if (Status!=STATUS_SUCCESS) - { - ObDereferenceObject(FileObject); - ZwClose(*FileHandle); - *FileHandle=0; - return(Status); - } - DeviceObject = IoGetAttachedDevice(DeviceObject); - } - DPRINT("Remainder %x\n",Remainder); - DPRINT("Remainder %w\n",Remainder); - DPRINT("FileObject->FileName.Buffer %w\n",FileObject->FileName.Buffer); - RtlInitUnicodeString(&(FileObject->FileName),wstrdup(Remainder)); - DPRINT("FileObject->FileName.Buffer %x %w\n", - FileObject->FileName.Buffer,FileObject->FileName.Buffer); - } - CHECKPOINT; - DPRINT("FileObject->FileName.Buffer %x\n",FileObject->FileName.Buffer); - if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) { FileObject->Flags = FileObject->Flags | FO_ALERTABLE_IO; @@ -188,19 +186,12 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle, { FileObject->Flags = FileObject->Flags | FO_SYNCHRONOUS_IO; } - - FileObject->DeviceObject=DeviceObject; - FileObject->Vpb=DeviceObject->Vpb; - + KeInitializeEvent(&Event,NotificationEvent,FALSE); - DPRINT("DevObj StackSize %d\n", DeviceObject->StackSize); - Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE); if (Irp==NULL) { - ObDereferenceObject(FileObject); - ZwClose(*FileHandle); - *FileHandle=0; return(STATUS_UNSUCCESSFUL); } @@ -209,31 +200,26 @@ NTSTATUS ZwCreateFile(PHANDLE FileHandle, StackLoc->MinorFunction = 0; StackLoc->Flags = 0; StackLoc->Control = 0; - StackLoc->DeviceObject = DeviceObject; - StackLoc->FileObject=FileObject; - StackLoc->Parameters.Create.Options=CreateOptions&FILE_VALID_OPTION_FLAGS; - StackLoc->Parameters.Create.Options|=CreateDisposition<<24; - Status = IoCallDriver(DeviceObject,Irp); - if (Status==STATUS_PENDING) + StackLoc->DeviceObject = FileObject->DeviceObject; + StackLoc->FileObject = FileObject; + StackLoc->Parameters.Create.Options = CreateOptions&FILE_VALID_OPTION_FLAGS; + StackLoc->Parameters.Create.Options |= CreateDisposition<<24; + + Status = IoCallDriver(FileObject->DeviceObject,Irp); + if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock->Status; } - if (Status!=STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { - DPRINT("FileObject->FileName.Buffer %x\n",FileObject->FileName.Buffer); - ObDereferenceObject(FileObject); ZwClose(*FileHandle); - *FileHandle=0; - return(Status); + (*FileHandle) = 0; } - DPRINT("*FileHandle %x\n",*FileHandle); - ObDereferenceObject(FileObject); - + DPRINT("Finished ZwCreateFile()\n"); return(Status); - } NTSTATUS NtOpenFile(PHANDLE FileHandle, diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index 24fe0718b3f..5676478566f 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -112,6 +112,15 @@ VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject, UNIMPLEMENTED; } +NTSTATUS IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return(STATUS_NOT_IMPLEMENTED); +} NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry) /* @@ -121,6 +130,7 @@ NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry) { NTSTATUS ret; PDRIVER_OBJECT DriverObject; + ULONG i; /* * Allocate memory for a driver object @@ -133,8 +143,12 @@ NTSTATUS InitializeLoadedDriver(PDRIVER_INITIALIZE entry) DbgPrint("%s:%d\n",__FILE__,__LINE__); return STATUS_INSUFFICIENT_RESOURCES; } - memset(DriverObject, '\0', sizeof(DRIVER_OBJECT)); - CHECKPOINT; + memset(DriverObject, 0, sizeof(DRIVER_OBJECT)); + + for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) + { + DriverObject->MajorFunction[i] = IopDefaultDispatchFunction; + } /* * Initalize the driver @@ -166,6 +180,29 @@ NTSTATUS IoAttachDevice(PDEVICE_OBJECT SourceDevice, UNIMPLEMENTED; } +NTSTATUS IopCreateDevice(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ObjectBody; + + DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %w)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) + { + return(STATUS_UNSUCCESSFUL); + } + + if (Parent != NULL && RemainingPath != NULL) + { + ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1); + } + return(STATUS_SUCCESS); +} + + NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject, ULONG DeviceExtensionSize, PUNICODE_STRING DeviceName, @@ -209,11 +246,11 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject, if (DeviceName!=NULL) { InitializeObjectAttributes(&dev_attr,DeviceName,0,NULL,NULL); - dev = ObGenericCreateObject(&devh,0,&dev_attr,IoDeviceType); + dev = ObCreateObject(&devh,0,&dev_attr,IoDeviceType); } else { - dev = ObGenericCreateObject(&devh,0,NULL,IoDeviceType); + dev = ObCreateObject(&devh,0,NULL,IoDeviceType); } *DeviceObject=NULL; diff --git a/reactos/ntoskrnl/io/dir.c b/reactos/ntoskrnl/io/dir.c index a7e9cad13a6..8cb5f070f57 100644 --- a/reactos/ntoskrnl/io/dir.c +++ b/reactos/ntoskrnl/io/dir.c @@ -204,7 +204,6 @@ NTSTATUS STDCALL ZwQueryDirectoryFile( } Status = IoStatusBlock->Status; } - ObDereferenceObject(FileObject); return(Status); } diff --git a/reactos/ntoskrnl/io/errlog.c b/reactos/ntoskrnl/io/errlog.c index 920bf278607..55013004fa2 100644 --- a/reactos/ntoskrnl/io/errlog.c +++ b/reactos/ntoskrnl/io/errlog.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/io/errlog.c * PURPOSE: Error logging - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ diff --git a/reactos/ntoskrnl/io/file.c b/reactos/ntoskrnl/io/file.c index 677d91a41f7..1064b463433 100644 --- a/reactos/ntoskrnl/io/file.c +++ b/reactos/ntoskrnl/io/file.c @@ -17,12 +17,11 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS -NtQueryInformationFile(HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass) +NTSTATUS NtQueryInformationFile(HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass) { return ZwQueryInformationFile(FileHandle, IoStatusBlock, @@ -31,12 +30,11 @@ NtQueryInformationFile(HANDLE FileHandle, FileInformationClass); } -NTSTATUS -ZwQueryInformationFile(HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass) +NTSTATUS ZwQueryInformationFile(HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass) { NTSTATUS Status; PFILE_OBJECT FileObject; @@ -92,12 +90,11 @@ ZwQueryInformationFile(HANDLE FileHandle, return Status; } -NTSTATUS -NtSetInformationFile(HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass) +NTSTATUS NtSetInformationFile(HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass) { return ZwSetInformationFile(FileHandle, IoStatusBlock, @@ -106,57 +103,52 @@ NtSetInformationFile(HANDLE FileHandle, FileInformationClass); } -NTSTATUS -ZwSetInformationFile(HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass) +NTSTATUS ZwSetInformationFile(HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass) { UNIMPLEMENTED; } -PGENERIC_MAPPING -IoGetFileObjectGenericMapping(VOID) +PGENERIC_MAPPING IoGetFileObjectGenericMapping(VOID) { UNIMPLEMENTED; } -NTSTATUS STDCALL -NtQueryAttributesFile(IN HANDLE FileHandle, - IN PVOID Buffer) +NTSTATUS STDCALL NtQueryAttributesFile(IN HANDLE FileHandle, + IN PVOID Buffer) { return ZwQueryAttributesFile(FileHandle, Buffer); } -NTSTATUS STDCALL -ZwQueryAttributesFile(IN HANDLE FileHandle, IN PVOID Buffer) +NTSTATUS STDCALL ZwQueryAttributesFile(IN HANDLE FileHandle, IN PVOID Buffer) { UNIMPLEMENTED; } -NTSTATUS STDCALL -NtQueryFullAttributesFile(IN HANDLE FileHandle, IN PVOID Attributes) +NTSTATUS STDCALL NtQueryFullAttributesFile(IN HANDLE FileHandle, + IN PVOID Attributes) { return ZwQueryFullAttributesFile(FileHandle, Attributes); } -NTSTATUS STDCALL -ZwQueryFullAttributesFile(IN HANDLE FileHandle, IN PVOID Attributes) +NTSTATUS STDCALL ZwQueryFullAttributesFile(IN HANDLE FileHandle, + IN PVOID Attributes) { UNIMPLEMENTED; } -NTSTATUS STDCALL -NtQueryEaFile(IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID Buffer, - IN ULONG Length, - IN BOOLEAN ReturnSingleEntry, - IN PVOID EaList OPTIONAL, - IN ULONG EaListLength, - IN PULONG EaIndex OPTIONAL, - IN BOOLEAN RestartScan) +NTSTATUS STDCALL NtQueryEaFile(IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN ReturnSingleEntry, + IN PVOID EaList OPTIONAL, + IN ULONG EaListLength, + IN PULONG EaIndex OPTIONAL, + IN BOOLEAN RestartScan) { return NtQueryEaFile(FileHandle, IoStatusBlock, @@ -169,25 +161,23 @@ NtQueryEaFile(IN HANDLE FileHandle, RestartScan); } -NTSTATUS STDCALL -ZwQueryEaFile(IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID Buffer, - IN ULONG Length, - IN BOOLEAN ReturnSingleEntry, - IN PVOID EaList OPTIONAL, - IN ULONG EaListLength, - IN PULONG EaIndex OPTIONAL, - IN BOOLEAN RestartScan) +NTSTATUS STDCALL ZwQueryEaFile(IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN ReturnSingleEntry, + IN PVOID EaList OPTIONAL, + IN ULONG EaListLength, + IN PULONG EaIndex OPTIONAL, + IN BOOLEAN RestartScan) { UNIMPLEMENTED; } -NTSTATUS STDCALL -NtSetEaFile(IN HANDLE FileHandle, - IN PIO_STATUS_BLOCK IoStatusBlock, - PVOID EaBuffer, - ULONG EaBufferSize) +NTSTATUS STDCALL NtSetEaFile(IN HANDLE FileHandle, + IN PIO_STATUS_BLOCK IoStatusBlock, + PVOID EaBuffer, + ULONG EaBufferSize) { return ZwSetEaFile(FileHandle, IoStatusBlock, @@ -195,11 +185,10 @@ NtSetEaFile(IN HANDLE FileHandle, EaBufferSize); } -NTSTATUS STDCALL -ZwSetEaFile(IN HANDLE FileHandle, - IN PIO_STATUS_BLOCK IoStatusBlock, - PVOID EaBuffer, - ULONG EaBufferSize) +NTSTATUS STDCALL ZwSetEaFile(IN HANDLE FileHandle, + IN PIO_STATUS_BLOCK IoStatusBlock, + PVOID EaBuffer, + ULONG EaBufferSize) { UNIMPLEMENTED; } diff --git a/reactos/ntoskrnl/io/flush.c b/reactos/ntoskrnl/io/flush.c index 4e6e48a52dd..2793457364f 100644 --- a/reactos/ntoskrnl/io/flush.c +++ b/reactos/ntoskrnl/io/flush.c @@ -45,7 +45,7 @@ NTSTATUS STDCALL ZwFlushBuffersFile(IN HANDLE FileHandle, * the flush buffers operation. The information field is * set to number of bytes flushed to disk. * RETURNS: Status - * REMARKS: This funciton maps to the win32 FlushFileBuffers + * REMARKS: This function maps to the win32 FlushFileBuffers */ { PFILE_OBJECT FileObject = NULL; diff --git a/reactos/ntoskrnl/io/iomgr.c b/reactos/ntoskrnl/io/iomgr.c index 74d2033859a..bd9e1952229 100644 --- a/reactos/ntoskrnl/io/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr.c @@ -23,13 +23,62 @@ POBJECT_TYPE IoDeviceType = NULL; POBJECT_TYPE IoFileType = NULL; - /* FUNCTIONS ****************************************************************/ -VOID IopCloseFile(PVOID ObjectBody) +VOID IopCloseFile(PVOID ObjectBody, ULONG HandleCount) { PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody; - + PIRP Irp; + PIO_STACK_LOCATION StackPtr; + NTSTATUS Status; + + if (HandleCount > 0) + { + return; + } + + ObReferenceObjectByPointer(FileObject, + STANDARD_RIGHTS_REQUIRED, + IoFileType, + UserMode); + + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP, + FileObject->DeviceObject, + NULL, + 0, + NULL, + NULL, + NULL); + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + + Status = IoCallDriver(FileObject->DeviceObject, Irp); +} + +VOID IopDeleteFile(PVOID ObjectBody) +{ + PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody; + PIRP Irp; + PIO_STACK_LOCATION StackPtr; + NTSTATUS Status; + + ObReferenceObjectByPointer(ObjectBody, + STANDARD_RIGHTS_REQUIRED, + IoFileType, + UserMode); + + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE, + FileObject->DeviceObject, + NULL, + 0, + NULL, + NULL, + NULL); + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = FileObject; + + Status = IoCallDriver(FileObject->DeviceObject, Irp); + if (FileObject->FileName.Buffer != NULL) { ExFreePool(FileObject->FileName.Buffer); @@ -62,6 +111,7 @@ VOID IoInit(VOID) IoDeviceType->Security = NULL; IoDeviceType->QueryName = NULL; IoDeviceType->OkayToClose = NULL; + IoDeviceType->Create = IopCreateDevice; RtlInitAnsiString(&AnsiString,"Device"); RtlAnsiStringToUnicodeString(&IoDeviceType->TypeName,&AnsiString,TRUE); @@ -77,11 +127,12 @@ VOID IoInit(VOID) IoFileType->Dump = NULL; IoFileType->Open = NULL; IoFileType->Close = IopCloseFile; - IoFileType->Delete = NULL; + IoFileType->Delete = IopDeleteFile; IoFileType->Parse = NULL; IoFileType->Security = NULL; IoFileType->QueryName = NULL; IoFileType->OkayToClose = NULL; + IoFileType->Create = IopCreateFile; RtlInitAnsiString(&AnsiString,"File"); RtlAnsiStringToUnicodeString(&IoFileType->TypeName,&AnsiString,TRUE); diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index 0006187aa1f..b7a5267af37 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -150,10 +150,7 @@ PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp) * RETURNS: A pointer to the stack location */ { - DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", - Irp, - Irp->CurrentLocation, - Irp->StackCount); + DPRINT("IoGetNextIrpStackLocation(Irp %x)\n",Irp); assert(Irp!=NULL); DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation); @@ -166,12 +163,19 @@ NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp) */ { NTSTATUS Status; - PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject; - PIO_STACK_LOCATION param = IoGetNextIrpStackLocation(Irp); - + PDRIVER_OBJECT DriverObject; + PIO_STACK_LOCATION param; + + DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp); + + DriverObject = DeviceObject->DriverObject; + param = IoGetNextIrpStackLocation(Irp); + Irp->Tail.Overlay.CurrentStackLocation--; Irp->CurrentLocation--; - + + DPRINT("DriverObject->MajorFunction[param->MajorFunction] %x\n", + DriverObject->MajorFunction[param->MajorFunction]); Status = DriverObject->MajorFunction[param->MajorFunction](DeviceObject, Irp); return Status; diff --git a/reactos/ntoskrnl/io/page.c b/reactos/ntoskrnl/io/page.c index 2f6b2fc8173..b8fcd893f63 100644 --- a/reactos/ntoskrnl/io/page.c +++ b/reactos/ntoskrnl/io/page.c @@ -30,7 +30,12 @@ NTSTATUS IoPageRead(PFILE_OBJECT FileObject, DPRINT("IoPageRead(FileObject %x, Address %x)\n", FileObject,Address); - + + ObReferenceObjectByPointer(FileObject, + STANDARD_RIGHTS_REQUIRED, + IoFileType, + UserMode); + KeInitializeEvent(&Event,NotificationEvent,FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, FileObject->DeviceObject, diff --git a/reactos/ntoskrnl/io/rw.c b/reactos/ntoskrnl/io/rw.c index 4e963a3780d..bca4944c0c9 100644 --- a/reactos/ntoskrnl/io/rw.c +++ b/reactos/ntoskrnl/io/rw.c @@ -107,7 +107,6 @@ NTSTATUS ZwReadFile(HANDLE FileHandle, KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); return(IoStatusBlock->Status); } - ObDereferenceObject(FileObject); return(Status); } @@ -188,8 +187,6 @@ NTSTATUS ZwWriteFile(HANDLE FileHandle, KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = Irp->IoStatus.Status; } - ObDereferenceObject(FileObject); - return(Status); } diff --git a/reactos/ntoskrnl/io/symlink.c b/reactos/ntoskrnl/io/symlink.c index 19f2e9682fd..d31ab708e3a 100644 --- a/reactos/ntoskrnl/io/symlink.c +++ b/reactos/ntoskrnl/io/symlink.c @@ -30,6 +30,40 @@ POBJECT_TYPE IoSymbolicLinkType = NULL; /* FUNCTIONS *****************************************************************/ +NTSTATUS IopCreateSymbolicLink(PVOID Object, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + if (Parent != NULL && RemainingPath != NULL) + { + ObAddEntryDirectory(Parent, Object, RemainingPath+1); + } + return(STATUS_SUCCESS); +} + +PVOID IopParseSymbolicLink(PVOID Object, + PWSTR* RemainingPath) +{ + NTSTATUS Status; + PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT)Object; + PVOID ReturnedObject; + + Status = ObReferenceObjectByName(SymlinkObject->Target.ObjectName, + 0, + NULL, + STANDARD_RIGHTS_REQUIRED, + NULL, + UserMode, + NULL, + &ReturnedObject); + if (NT_SUCCESS(Status)) + { + return(ReturnedObject); + } + return(NULL); +} + VOID IoInitSymbolicLinkImplementation(VOID) { ANSI_STRING AnsiString; @@ -46,10 +80,11 @@ VOID IoInitSymbolicLinkImplementation(VOID) IoSymbolicLinkType->Open = NULL; IoSymbolicLinkType->Close = NULL; IoSymbolicLinkType->Delete = NULL; - IoSymbolicLinkType->Parse = NULL; + IoSymbolicLinkType->Parse = IopParseSymbolicLink; IoSymbolicLinkType->Security = NULL; IoSymbolicLinkType->QueryName = NULL; IoSymbolicLinkType->OkayToClose = NULL; + IoSymbolicLinkType->Create = IopCreateSymbolicLink; RtlInitAnsiString(&AnsiString,"Symbolic Link"); RtlAnsiStringToUnicodeString(&IoSymbolicLinkType->TypeName, @@ -72,9 +107,15 @@ NTSTATUS ZwOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, { NTSTATUS Status; PVOID Object; - PWSTR Ignored; - Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored); + Status = ObReferenceObjectByName(ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, + NULL, + DesiredAccess, + NULL, + UserMode, + NULL, + &Object); if (!NT_SUCCESS(Status)) { return(Status); @@ -117,21 +158,6 @@ NTSTATUS ZwQuerySymbolicLinkObject(IN HANDLE LinkHandle, return(STATUS_SUCCESS); } - -POBJECT IoOpenSymlink(POBJECT _Symlink) -{ - PVOID Result; - PSYMLNK_OBJECT Symlink = (PSYMLNK_OBJECT)_Symlink; - PWSTR Ignored; - - DPRINT("IoOpenSymlink(_Symlink %x)\n",Symlink); - - DPRINT("Target %w\n",Symlink->Target.ObjectName->Buffer); - - ObOpenObjectByName(&(Symlink->Target),&Result,&Ignored); - return(Result); -} - NTSTATUS IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName, PUNICODE_STRING DeviceName) { @@ -150,10 +176,10 @@ NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, SymbolicLinkName->Buffer,DeviceName->Buffer); InitializeObjectAttributes(&ObjectAttributes,SymbolicLinkName,0,NULL,NULL); - SymbolicLink = ObGenericCreateObject(&SymbolicLinkHandle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes, - IoSymbolicLinkType); + SymbolicLink = ObCreateObject(&SymbolicLinkHandle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + IoSymbolicLinkType); if (SymbolicLink == NULL) { return(STATUS_UNSUCCESSFUL); @@ -163,7 +189,7 @@ NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, SymbolicLink->TargetName.MaximumLength = ((wstrlen(DeviceName->Buffer) + 1) * sizeof(WCHAR)); SymbolicLink->TargetName.Buffer = ExAllocatePool(NonPagedPool, - SymbolicLink->TargetName.MaximumLength); + SymbolicLink->TargetName.MaximumLength); RtlCopyUnicodeString(&(SymbolicLink->TargetName), DeviceName); DPRINT("DeviceName %w\n", SymbolicLink->TargetName.Buffer); InitializeObjectAttributes(&(SymbolicLink->Target), diff --git a/reactos/ntoskrnl/ke/catch.c b/reactos/ntoskrnl/ke/catch.c index f6ffd166195..68e3f3b5134 100644 --- a/reactos/ntoskrnl/ke/catch.c +++ b/reactos/ntoskrnl/ke/catch.c @@ -17,7 +17,7 @@ VOID ExRaiseStatus(NTSTATUS Status) { - DbgPrint("ExRaiseStatus(%d)\n",Status); + DbgPrint("ExRaiseStatus(%x)\n",Status); for(;;); } diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index ce99a6073ea..1cd29ba5d34 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -150,7 +150,7 @@ asmlinkage void _main(boot_param* _bp) KeInit(); ObInit(); PsInit(); - IoInit(); + IoInit(); LdrInitModuleManagement(); /* @@ -165,7 +165,7 @@ asmlinkage void _main(boot_param* _bp) LdrProcessDriver(start); start=start+PAGE_ROUND_UP(bp.module_length[i]); } - + /* * Load Auto configured drivers */ diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 35a31139e53..2bc949ad0c6 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -16,7 +16,7 @@ /* INCLUDES *****************************************************************/ #include -#include +#include #include #include #include @@ -957,10 +957,10 @@ LdrLoadImage(HANDLE ProcessHandle, } /* Build a module structure for the image */ - Module = ObGenericCreateObject(ModuleHandle, - PROCESS_ALL_ACCESS, - NULL, - ObModuleType); + Module = ObCreateObject(ModuleHandle, + PROCESS_ALL_ACCESS, + NULL, + ObModuleType); if (Module == NULL) { ZwClose(FileHandle); diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 5e3f0ea0374..39d75cfb241 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -7,7 +7,7 @@ include hal/x86/sources NT_OBJECTS = nt/port.o nt/channel.o nt/ntevent.o nt/nttimer.o nt/atom.o \ nt/evtpair.o nt/ntsem.o nt/mutant.o nt/misc.o nt/plugplay.o \ - nt/profile.o + nt/profile.o nt/nt.o RTL_OBJECTS = rtl/vsprintf.o rtl/lookas.o rtl/unicode.o rtl/strtok.o \ rtl/time.o rtl/unalign.o rtl/mem.o rtl/largeint.o rtl/ctype.o \ @@ -32,7 +32,7 @@ IO_OBJECTS = io/iomgr.o io/create.o io/irp.o io/device.o io/rw.o \ io/fs.o io/vpb.o io/buildirp.o io/flush.o io/dir.o io/iocomp.o \ io/mailslot.o io/npipe.o io/lock.o io/page.o io/cleanup.o -OB_OBJECTS = ob/object.o ob/handle.o ob/namespc.o +OB_OBJECTS = ob/object.o ob/handle.o ob/namespc.o ob/ntobj.o ob/dirobj.o PS_OBJECTS = ps/psmgr.o ps/thread.o ps/process.o ps/idle.o ps/kill.o \ ps/tinfo.o @@ -45,7 +45,7 @@ SE_OBJECTS = se/semgr.o CM_OBJECTS = cm/registry.o -TST_OBJECTS = tst/test.o tst/sshell.o tst/readline.o +TST_OBJECTS = tst/test.o DBG_OBJECTS = dbg/brkpoint.o dbg/errinfo.o diff --git a/reactos/ntoskrnl/mm/cont.c b/reactos/ntoskrnl/mm/cont.c index 202955f88ae..1a7357bed6e 100644 --- a/reactos/ntoskrnl/mm/cont.c +++ b/reactos/ntoskrnl/mm/cont.c @@ -1,17 +1,15 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/mm/cont.c + * FILE: ntoskrnl/mm/cont.c * PURPOSE: Manages continuous memory - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ /* INCLUDES *****************************************************************/ -#include -#include #include #include diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 25576b182c7..424b3d1347f 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -125,7 +125,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode, */ if (marea==NULL ) { - printk("Area is invalid\n"); + DbgPrint("(%s:%d) Area is invalid\n",__FILE__,__LINE__); ExRaiseStatus(STATUS_INVALID_PARAMETER); } diff --git a/reactos/ntoskrnl/mm/ncache.c b/reactos/ntoskrnl/mm/ncache.c index 0be71ed1916..cbf182be92e 100644 --- a/reactos/ntoskrnl/mm/ncache.c +++ b/reactos/ntoskrnl/mm/ncache.c @@ -1,17 +1,15 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: kernel/mm/cont.c + * FILE: ntoskrnl/mm/cont.c * PURPOSE: Manages non-cached memory - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ /* INCLUDES *****************************************************************/ -#include -#include #include #include diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 006b97a1843..da4931c1c31 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -25,6 +25,44 @@ POBJECT_TYPE MmSectionType = NULL; /* FUNCTIONS *****************************************************************/ +VOID MmpDeleteSection(PVOID ObjectBody) +{ +} + +NTSTATUS MmpCreateSection(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath) +{ + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ObjectBody; + NTSTATUS Status; + + DPRINT("MmpCreateDevice(ObjectBody %x, Parent %x, RemainingPath %w)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath == NULL) + { + return(STATUS_SUCCESS); + } + + if (wcschr(RemainingPath+1, '\\') != NULL) + { + return(STATUS_UNSUCCESSFUL); + } + + Status = ObReferenceObjectByPointer(Parent, + STANDARD_RIGHTS_REQUIRED, + ObDirectoryType, + UserMode); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1); + + return(STATUS_SUCCESS); +} + NTSTATUS MmInitSectionImplementation(VOID) { ANSI_STRING AnsiString; @@ -40,11 +78,12 @@ NTSTATUS MmInitSectionImplementation(VOID) MmSectionType->Dump = NULL; MmSectionType->Open = NULL; MmSectionType->Close = NULL; - MmSectionType->Delete = NULL; + MmSectionType->Delete = MmpDeleteSection; MmSectionType->Parse = NULL; MmSectionType->Security = NULL; MmSectionType->QueryName = NULL; MmSectionType->OkayToClose = NULL; + MmSectionType->Create = MmpCreateSection; RtlInitAnsiString(&AnsiString,"Section"); RtlAnsiStringToUnicodeString(&MmSectionType->TypeName, @@ -106,10 +145,10 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle, DbgPrint("ZwCreateSection()\n"); - Section = ObGenericCreateObject(SectionHandle, - DesiredAccess, - ObjectAttributes, - MmSectionType); + Section = ObCreateObject(SectionHandle, + DesiredAccess, + ObjectAttributes, + MmSectionType); if (MaximumSize != NULL) { @@ -120,20 +159,27 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle, LARGE_INTEGER_QUAD_PART(Section->MaximumSize) = 0xffffffff; } Section->SectionPageProtection = SectionPageProtection; - Status = ObReferenceObjectByHandle(FileHandle, - FILE_READ_DATA, - IoFileType, - UserMode, - (PVOID*)&Section->FileObject, - NULL); - if (Status != STATUS_SUCCESS) - { - DPRINT("ZwCreateSection() = %x\n",Status); - return(Status); - } - Section->AllocateAttributes = AllocationAttributes; + if (FileHandle != NULL) + { + Status = ObReferenceObjectByHandle(FileHandle, + FILE_READ_DATA, + IoFileType, + UserMode, + (PVOID*)&Section->FileObject, + NULL); + if (Status != STATUS_SUCCESS) + { + DPRINT("ZwCreateSection() = %x\n",Status); + return(Status); + } + } + else + { + Section->FileObject = NULL; + } + DPRINT("ZwCreateSection() = STATUS_SUCCESS\n"); return(STATUS_SUCCESS); } @@ -153,23 +199,26 @@ NTSTATUS ZwOpenSection(PHANDLE SectionHandle, { PVOID Object; NTSTATUS Status; - PWSTR Ignored; *SectionHandle = 0; - - Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored); + + Status = ObReferenceObjectByName(ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, + NULL, + DesiredAccess, + MmSectionType, + UserMode, + NULL, + &Object); if (!NT_SUCCESS(Status)) { return(Status); } - if (BODY_TO_HEADER(Object)->ObjectType!=MmSectionType) - { - return(STATUS_UNSUCCESSFUL); - } - - *SectionHandle = ObInsertHandle(KeGetCurrentProcess(),Object, - DesiredAccess,FALSE); + *SectionHandle = ObInsertHandle(KeGetCurrentProcess(), + Object, + DesiredAccess, + FALSE); return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/nt/nt.c b/reactos/ntoskrnl/nt/nt.c new file mode 100644 index 00000000000..8a1a8734830 --- /dev/null +++ b/reactos/ntoskrnl/nt/nt.c @@ -0,0 +1,22 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/nt/nt.c + * PURPOSE: Initialization of system call interfaces + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include + +#include + +/* FUNCTIONS *****************************************************************/ + +VOID NtInit(VOID) +{ + NtInitializeEventImplementation(); +} diff --git a/reactos/ntoskrnl/nt/ntevent.c b/reactos/ntoskrnl/nt/ntevent.c index 4089fc801b9..7bb4bc9128f 100644 --- a/reactos/ntoskrnl/nt/ntevent.c +++ b/reactos/ntoskrnl/nt/ntevent.c @@ -92,10 +92,10 @@ NTSTATUS STDCALL ZwCreateEvent(OUT PHANDLE EventHandle, { PKEVENT Event; - Event = ObGenericCreateObject(EventHandle, - DesiredAccess, - ObjectAttributes, - ExEventType); + Event = ObCreateObject(EventHandle, + DesiredAccess, + ObjectAttributes, + ExEventType); if (ManualReset == TRUE) { KeInitializeEvent(Event,NotificationEvent,InitialState); @@ -121,9 +121,16 @@ NTSTATUS STDCALL ZwOpenEvent(OUT PHANDLE EventHandle, { NTSTATUS Status; PKEVENT Event; - PWSTR Ignored; + - Status = ObOpenObjectByName(ObjectAttributes,(PVOID*)Event,&Ignored); + Status = ObReferenceObjectByName(ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, + NULL, + DesiredAccess, + ExEventType, + UserMode, + NULL, + (PVOID*)&Event); if (Status != STATUS_SUCCESS) { return(Status); diff --git a/reactos/ntoskrnl/nt/port.c b/reactos/ntoskrnl/nt/port.c index 16d35a19205..9a57d8f9bb2 100644 --- a/reactos/ntoskrnl/nt/port.c +++ b/reactos/ntoskrnl/nt/port.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/nt/port.c * PURPOSE: Communication mechanism (like Mach?) - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * Created 22/05/98 */ diff --git a/reactos/ntoskrnl/ob/dirobj.c b/reactos/ntoskrnl/ob/dirobj.c new file mode 100644 index 00000000000..09c1fd973fe --- /dev/null +++ b/reactos/ntoskrnl/ob/dirobj.c @@ -0,0 +1,267 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ob/dirobj.c + * PURPOSE: Interface functions to directory object + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * 22/05/98: Created + */ + +/* INCLUDES ***************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + + +/* FUNCTIONS **************************************************************/ + +NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + return(ZwOpenDirectoryObject(DirectoryHandle, + DesiredAccess, + ObjectAttributes)); +} + +NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) +/* + * FUNCTION: Opens a namespace directory object + * ARGUMENTS: + * DirectoryHandle (OUT) = Variable which receives the directory handle + * DesiredAccess = Desired access to the directory + * ObjectAttributes = Structure describing the directory + * RETURNS: Status + * NOTES: Undocumented + */ +{ + PVOID Object; + NTSTATUS Status; + + *DirectoryHandle = 0; + + Status = ObReferenceObjectByName(ObjectAttributes->ObjectName, + ObjectAttributes->Attributes, + NULL, + DesiredAccess, + ObDirectoryType, + UserMode, + NULL, + &Object); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object, + DesiredAccess,FALSE); + return(STATUS_SUCCESS); +} + +NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle, + OUT POBJDIR_INFORMATION DirObjInformation, + IN ULONG BufferLength, + IN BOOLEAN GetNextIndex, + IN BOOLEAN IgnoreInputIndex, + IN OUT PULONG ObjectIndex, + OUT PULONG DataWritten OPTIONAL) +{ + return(ZwQueryDirectoryObject(DirObjHandle, + DirObjInformation, + BufferLength, + GetNextIndex, + IgnoreInputIndex, + ObjectIndex, + DataWritten)); +} + +NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle, + OUT POBJDIR_INFORMATION DirObjInformation, + IN ULONG BufferLength, + IN BOOLEAN GetNextIndex, + IN BOOLEAN IgnoreInputIndex, + IN OUT PULONG ObjectIndex, + OUT PULONG DataWritten OPTIONAL) +/* + * FUNCTION: Reads information from a namespace directory + * ARGUMENTS: + * DirObjInformation (OUT) = Buffer to hold the data read + * BufferLength = Size of the buffer in bytes + * GetNextIndex = If TRUE then set ObjectIndex to the index of the + * next object + * If FALSE then set ObjectIndex to the number of + * objects in the directory + * IgnoreInputIndex = If TRUE start reading at index 0 + * If FALSE start reading at the index specified + * by object index + * ObjectIndex = Zero based index into the directory, interpretation + * depends on IgnoreInputIndex and GetNextIndex + * DataWritten (OUT) = Caller supplied storage for the number of bytes + * written (or NULL) + * RETURNS: Status + */ +{ + PDIRECTORY_OBJECT dir = NULL; + ULONG EntriesToRead; + PLIST_ENTRY current_entry; + POBJECT_HEADER current; + ULONG i=0; + ULONG EntriesToSkip; + NTSTATUS Status; + + DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle); + DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr))); + +// assert_irql(PASSIVE_LEVEL); + + Status = ObReferenceObjectByHandle(DirObjHandle, + DIRECTORY_QUERY, + ObDirectoryType, + UserMode, + (PVOID*)&dir, + NULL); + if (Status != STATUS_SUCCESS) + { + return(Status); + } + + EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION); + *DataWritten = 0; + + DPRINT("EntriesToRead %d\n",EntriesToRead); + + current_entry = dir->head.Flink; + + /* + * Optionally, skip over some entries at the start of the directory + */ + if (!IgnoreInputIndex) + { + CHECKPOINT; + + EntriesToSkip = *ObjectIndex; + while ( iFlink; + } + } + + DPRINT("DirObjInformation %x\n",DirObjInformation); + + /* + * Read the maximum entries possible into the buffer + */ + while ( ihead))) + { + current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry); + DPRINT("Scanning %w\n",current->Name.Buffer); + DirObjInformation[i].ObjectName.Buffer = + ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2); + DirObjInformation[i].ObjectName.Length = current->Name.Length; + DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length; + DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n", + DirObjInformation[i].ObjectName.Buffer); + RtlCopyUnicodeString(&DirObjInformation[i].ObjectName, + &(current->Name)); + i++; + current_entry = current_entry->Flink; + (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION); + CHECKPOINT; + } + CHECKPOINT; + + /* + * Optionally, count the number of entries in the directory + */ + if (GetNextIndex) + { + *ObjectIndex=i; + } + else + { + while ( current_entry!=(&(dir->head)) ) + { + current_entry=current_entry->Flink; + i++; + } + *ObjectIndex=i; + } + return(STATUS_SUCCESS); +} + + +NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + return(ZwCreateDirectoryObject(DirectoryHandle, + DesiredAccess, + ObjectAttributes)); +} + +NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) +/* + * FUNCTION: Creates or opens a directory object (a container for other + * objects) + * ARGUMENTS: + * DirectoryHandle (OUT) = Caller supplied storage for the handle + * of the directory + * DesiredAccess = Access desired to the directory + * ObjectAttributes = Object attributes initialized with + * InitializeObjectAttributes + * RETURNS: Status + */ +{ + PDIRECTORY_OBJECT dir; + + dir = ObCreateObject(DirectoryHandle, + DesiredAccess, + ObjectAttributes, + ObDirectoryType); + return(STATUS_SUCCESS); +} + +VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes, + PUNICODE_STRING ObjectName, + ULONG Attributes, + HANDLE RootDirectory, + PSECURITY_DESCRIPTOR SecurityDescriptor) +/* + * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a + * subsequent call to ZwCreateXXX or ZwOpenXXX + * ARGUMENTS: + * InitializedAttributes (OUT) = Caller supplied storage for the + * object attributes + * ObjectName = Full path name for object + * Attributes = Attributes for the object + * RootDirectory = Where the object should be placed or NULL + * SecurityDescriptor = Ignored + * + * NOTE: + * Either ObjectName is a fully qualified pathname or a path relative + * to RootDirectory + */ +{ + DPRINT("InitializeObjectAttributes(InitializedAttributes %x " + "ObjectName %x Attributes %x RootDirectory %x)\n", + InitializedAttributes,ObjectName,Attributes,RootDirectory); + InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES); + InitializedAttributes->RootDirectory=RootDirectory; + InitializedAttributes->ObjectName=ObjectName; + InitializedAttributes->Attributes=Attributes; + InitializedAttributes->SecurityDescriptor=SecurityDescriptor; + InitializedAttributes->SecurityQualityOfService=NULL; +} + diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index 6c31438f45a..aea54358d2e 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -215,8 +215,10 @@ VOID ObDeleteHandle(HANDLE Handle) DPRINT("Finished ObDeleteHandle()\n"); } -HANDLE ObInsertHandle(PKPROCESS Process, PVOID ObjectBody, - ACCESS_MASK GrantedAccess, BOOLEAN Inherit) +HANDLE ObInsertHandle(PKPROCESS Process, + PVOID ObjectBody, + ACCESS_MASK GrantedAccess, + BOOLEAN Inherit) /* * FUNCTION: Add a handle referencing an object * ARGUMENTS: diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index d36cffcbc44..15b29f4068f 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -24,193 +24,10 @@ POBJECT_TYPE ObDirectoryType = NULL; -static struct -{ - OBJECT_HEADER hdr; -// DIRECTORY_OBJECT directory; - LIST_ENTRY head; - KSPIN_LOCK Lock; -} namespc_root = {{0,},}; +PDIRECTORY_OBJECT NameSpaceRoot = NULL; /* FUNCTIONS **************************************************************/ -NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) -{ - return(ZwOpenDirectoryObject(DirectoryHandle, - DesiredAccess, - ObjectAttributes)); -} - -NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) -/* - * FUNCTION: Opens a namespace directory object - * ARGUMENTS: - * DirectoryHandle (OUT) = Variable which receives the directory handle - * DesiredAccess = Desired access to the directory - * ObjectAttributes = Structure describing the directory - * RETURNS: Status - * NOTES: Undocumented - */ -{ - PVOID Object; - NTSTATUS Status; - PWSTR Ignored; - - *DirectoryHandle = 0; - - Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY) - { - return(STATUS_UNSUCCESSFUL); - } - - *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object, - DesiredAccess,FALSE); - CHECKPOINT; - return(STATUS_SUCCESS); -} - -NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle, - OUT POBJDIR_INFORMATION DirObjInformation, - IN ULONG BufferLength, - IN BOOLEAN GetNextIndex, - IN BOOLEAN IgnoreInputIndex, - IN OUT PULONG ObjectIndex, - OUT PULONG DataWritten OPTIONAL) -{ - return(ZwQueryDirectoryObject(DirObjHandle, - DirObjInformation, - BufferLength, - GetNextIndex, - IgnoreInputIndex, - ObjectIndex, - DataWritten)); -} - -NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle, - OUT POBJDIR_INFORMATION DirObjInformation, - IN ULONG BufferLength, - IN BOOLEAN GetNextIndex, - IN BOOLEAN IgnoreInputIndex, - IN OUT PULONG ObjectIndex, - OUT PULONG DataWritten OPTIONAL) -/* - * FUNCTION: Reads information from a namespace directory - * ARGUMENTS: - * DirObjInformation (OUT) = Buffer to hold the data read - * BufferLength = Size of the buffer in bytes - * GetNextIndex = If TRUE then set ObjectIndex to the index of the - * next object - * If FALSE then set ObjectIndex to the number of - * objects in the directory - * IgnoreInputIndex = If TRUE start reading at index 0 - * If FALSE start reading at the index specified - * by object index - * ObjectIndex = Zero based index into the directory, interpretation - * depends on IgnoreInputIndex and GetNextIndex - * DataWritten (OUT) = Caller supplied storage for the number of bytes - * written (or NULL) - * RETURNS: Status - */ -{ - PDIRECTORY_OBJECT dir = NULL; - ULONG EntriesToRead; - PLIST_ENTRY current_entry; - POBJECT_HEADER current; - ULONG i=0; - ULONG EntriesToSkip; - NTSTATUS Status; - - DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle); - DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr))); - -// assert_irql(PASSIVE_LEVEL); - - Status = ObReferenceObjectByHandle(DirObjHandle, - DIRECTORY_QUERY, - ObDirectoryType, - UserMode, - (PVOID*)&dir, - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION); - *DataWritten = 0; - - DPRINT("EntriesToRead %d\n",EntriesToRead); - - current_entry = dir->head.Flink; - - /* - * Optionally, skip over some entries at the start of the directory - */ - if (!IgnoreInputIndex) - { - CHECKPOINT; - - EntriesToSkip = *ObjectIndex; - while ( iFlink; - } - } - - DPRINT("DirObjInformation %x\n",DirObjInformation); - - /* - * Read the maximum entries possible into the buffer - */ - while ( ihead))) - { - current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry); - DPRINT("Scanning %w\n",current->Name.Buffer); - DirObjInformation[i].ObjectName.Buffer = - ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2); - DirObjInformation[i].ObjectName.Length = current->Name.Length; - DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length; - DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n", - DirObjInformation[i].ObjectName.Buffer); - RtlCopyUnicodeString(&DirObjInformation[i].ObjectName, - &(current->Name)); - i++; - current_entry = current_entry->Flink; - (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION); - CHECKPOINT; - } - CHECKPOINT; - - /* - * Optionally, count the number of entries in the directory - */ - if (GetNextIndex) - { - *ObjectIndex=i; - } - else - { - while ( current_entry!=(&(dir->head)) ) - { - current_entry=current_entry->Flink; - i++; - } - *ObjectIndex=i; - } - return(STATUS_SUCCESS); -} - - NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath, ULONG Attributes, PACCESS_STATE PassedAccessState, @@ -220,34 +37,173 @@ NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath, PVOID ParseContext, PVOID* ObjectPtr) { - UNIMPLEMENTED; + PVOID Object; + PWSTR RemainingPath; + OBJECT_ATTRIBUTES ObjectAttributes; + + InitializeObjectAttributes(&ObjectAttributes, + ObjectPath, + 0, + NULL, + NULL); + ObFindObject(&ObjectAttributes, + &Object, + &RemainingPath); + + if (RemainingPath != NULL || + Object == NULL) + { + *ObjectPtr = NULL; + return(STATUS_UNSUCCESSFUL); + } + *ObjectPtr = Object; + return(STATUS_SUCCESS); } -NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes, - PVOID* Object, PWSTR* UnparsedSection) +VOID ObAddEntryDirectory(PDIRECTORY_OBJECT Parent, + POBJECT Object, + PWSTR Name) +/* + * FUNCTION: Add an entry to a namespace directory + * ARGUMENTS: + * parent = directory to add in + * name = Name to give the entry + * Object = Header of the object to add the entry for + */ { + KIRQL oldlvl; + POBJECT_HEADER Header = BODY_TO_HEADER(Object); + + RtlInitUnicodeString(&Header->Name, wstrdup(Name)); + Header->Parent = Parent; + + KeAcquireSpinLock(&Parent->Lock, &oldlvl); + InsertTailList(&Parent->head, &Header->Entry); + KeReleaseSpinLock(&Parent->Lock, oldlvl); +} + +PVOID ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject, + PWSTR Name, + ULONG Attributes) +{ + PLIST_ENTRY current = DirectoryObject->head.Flink; + POBJECT_HEADER current_obj; + + DPRINT("ObDirLookup(dir %x, name %w)\n",DirectoryObject, Name); + + if (Name[0]==0) + { + return(DirectoryObject); + } + if (Name[0]=='.' && Name[1]==0) + { + return(DirectoryObject); + } + if (Name[0]=='.' && Name[1]=='.' && Name[2]==0) + { + return(BODY_TO_HEADER(DirectoryObject)->Parent); + } + while (current!=(&(DirectoryObject->head))) + { + current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry); + DPRINT("Scanning %w %w\n",current_obj->Name.Buffer, Name); + if (Attributes & OBJ_CASE_INSENSITIVE) + { + if (wcsicmp(current_obj->Name.Buffer, Name)==0) + { + DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); + return(HEADER_TO_BODY(current_obj)); + } + } + else + { + if ( wcscmp(current_obj->Name.Buffer, Name)==0) + { + DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); + return(HEADER_TO_BODY(current_obj)); + } + } + current = current->Flink; + } + DPRINT("%s() = NULL\n",__FUNCTION__); + return(NULL); + +} + +PVOID ObpParseDirectory(PVOID Object, PWSTR* Path) +{ + PWSTR end; + PVOID FoundObject; NTSTATUS Status; - DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n", - ObjectAttributes,Object); - DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n", - ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer); - DPRINT("ObjectAttributes->ObjectName->Length %d\n", - ObjectAttributes->ObjectName->Length); + DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %w)\n", + Object,Path,*Path); - *Object = NULL; - Status = ObLookupObject(ObjectAttributes->RootDirectory, - ObjectAttributes->ObjectName->Buffer, - Object, - UnparsedSection, - ObjectAttributes->Attributes); - DPRINT("*Object %x\n",*Object); - DPRINT("ObjectAttributes->ObjectName->Length %d\n", - ObjectAttributes->ObjectName->Length); - return(Status); + if ((*Path) == NULL) + { + return(NULL); + } + + end = wcschr((*Path)+1, '\\'); + if (end != NULL) + { + *end = 0; + } + + FoundObject = ObpFindEntryDirectory(Object, (*Path)+1, 0); + + if (FoundObject == NULL) + { + if (end != NULL) + { + *end = '\\'; + } + return(NULL); + } + + ObReferenceObjectByPointer(FoundObject, + STANDARD_RIGHTS_REQUIRED, + NULL, + UserMode); + + if (end != NULL) + { + *end = '\\'; + *Path = end; + } + else + { + *Path = NULL; + } + + return(FoundObject); } -void ObInit(void) +NTSTATUS ObpCreateDirectory(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + PDIRECTORY_OBJECT DirectoryObject = (PDIRECTORY_OBJECT)ObjectBody; + + DPRINT("ObpCreateDirectory(ObjectBody %x, Parent %x, RemainingPath %w)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) + { + return(STATUS_UNSUCCESSFUL); + } + + if (Parent != NULL && RemainingPath != NULL) + { + ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1); + } + InitializeListHead(&DirectoryObject->head); + KeInitializeSpinLock(&DirectoryObject->Lock); + return(STATUS_SUCCESS); +} + +VOID ObInit(VOID) /* * FUNCTION: Initialize the object manager namespace */ @@ -266,141 +222,20 @@ void ObInit(void) ObDirectoryType->Open = NULL; ObDirectoryType->Close = NULL; ObDirectoryType->Delete = NULL; - ObDirectoryType->Parse = NULL; + ObDirectoryType->Parse = ObpParseDirectory; ObDirectoryType->Security = NULL; ObDirectoryType->QueryName = NULL; ObDirectoryType->OkayToClose = NULL; + ObDirectoryType->Create = ObpCreateDirectory; RtlInitAnsiString(&AnsiString,"Directory"); RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName, &AnsiString,TRUE); - ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr); - InitializeListHead(&namespc_root.head); -} - -NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) -{ - return(ZwCreateDirectoryObject(DirectoryHandle, - DesiredAccess, - ObjectAttributes)); -} - -NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) -/* - * FUNCTION: Creates or opens a directory object (a container for other - * objects) - * ARGUMENTS: - * DirectoryHandle (OUT) = Caller supplied storage for the handle - * of the directory - * DesiredAccess = Access desired to the directory - * ObjectAttributes = Object attributes initialized with - * InitializeObjectAttributes - * RETURNS: Status - */ -{ - PDIRECTORY_OBJECT dir; - - dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes, - ObDirectoryType); - - /* - * Initialize the object body - */ - InitializeListHead(&dir->head); - KeInitializeSpinLock(&(dir->Lock)); - - return(STATUS_SUCCESS); -} - -VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes, - PUNICODE_STRING ObjectName, - ULONG Attributes, - HANDLE RootDirectory, - PSECURITY_DESCRIPTOR SecurityDescriptor) -/* - * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a - * subsequent call to ZwCreateXXX or ZwOpenXXX - * ARGUMENTS: - * InitializedAttributes (OUT) = Caller supplied storage for the - * object attributes - * ObjectName = Full path name for object - * Attributes = Attributes for the object - * RootDirectory = Where the object should be placed or NULL - * SecurityDescriptor = Ignored - * - * NOTE: - * Either ObjectName is a fully qualified pathname or a path relative - * to RootDirectory - */ -{ - DPRINT("InitializeObjectAttributes(InitializedAttributes %x " - "ObjectName %x Attributes %x RootDirectory %x)\n", - InitializedAttributes,ObjectName,Attributes,RootDirectory); - InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES); - InitializedAttributes->RootDirectory=RootDirectory; - InitializedAttributes->ObjectName=ObjectName; - InitializedAttributes->Attributes=Attributes; - InitializedAttributes->SecurityDescriptor=SecurityDescriptor; - InitializedAttributes->SecurityQualityOfService=NULL; -} - -static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name, - ULONG Attributes) -/* - * FUNCTION: Looks up an entry within a namespace directory - * ARGUMENTS: - * dir = Directory to lookup in - * name = Entry name to find - * RETURNS: A pointer to the object body if found - * NULL otherwise - */ -{ - LIST_ENTRY* current = dir->head.Flink; - POBJECT_HEADER current_obj; - - DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name); - - if (name[0]==0) - { - return(dir); - } - if (name[0]=='.'&&name[1]==0) - { - return(dir); - } - if (name[0]=='.'&&name[1]=='.'&&name[2]==0) - { - return(BODY_TO_HEADER(dir)->Parent); - } - while (current!=(&(dir->head))) - { - current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry); - DPRINT("Scanning %w\n",current_obj->Name.Buffer); - if (Attributes & OBJ_CASE_INSENSITIVE) - { - if (wcsicmp(current_obj->Name.Buffer, name)==0) - { - DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); - return(HEADER_TO_BODY(current_obj)); - } - } - else - { - if ( wcscmp(current_obj->Name.Buffer, name)==0) - { - DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj)); - return(HEADER_TO_BODY(current_obj)); - } - } - current = current->Flink; - } - DPRINT("%s() = NULL\n",__FUNCTION__); - return(NULL); + NameSpaceRoot = ObCreateObject(NULL, + STANDARD_RIGHTS_REQUIRED, + NULL, + ObDirectoryType); } VOID ObRemoveEntry(POBJECT_HEADER Header) @@ -414,153 +249,3 @@ VOID ObRemoveEntry(POBJECT_HEADER Header) KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl); } -VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object) -/* - * FUNCTION: Add an entry to a namespace directory - * ARGUMENTS: - * parent = directory to add in - * name = Name to give the entry - * Object = Header of the object to add the entry for - */ -{ - DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer, - Object->Name.Buffer); - - /* - * Insert ourselves in our parents list - */ - InsertTailList(&parent->head,&Object->Entry); -} - -NTSTATUS ObLookupObject(HANDLE rootdir, - PWSTR string, - PVOID* Object, - PWSTR* UnparsedSection, - ULONG Attributes) -/* - * FUNCTION: Lookup an object within the system namespc - * ARGUMENTS: - * root = Directory to start lookup from - * _string = Pathname to lookup - * RETURNS: On success a pointer to the object body - * On failure NULL - */ -{ - PWSTR current; - PWSTR next; - PDIRECTORY_OBJECT current_dir = NULL; - NTSTATUS Status; - - DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, " - "UnparsedSection %x)\n",rootdir,string,string,Object, - UnparsedSection); - *UnparsedSection = NULL; - *Object = NULL; - - if (rootdir == NULL) - { - current_dir = HEADER_TO_BODY(&(namespc_root.hdr)); - } - else - { - ObReferenceObjectByHandle(rootdir, - DIRECTORY_TRAVERSE, - NULL, - UserMode, - (PVOID*)¤t_dir, - NULL); - } - - /* - * Bit of a hack this - */ - if (string[0] == 0) - { - *Object = current_dir; - return STATUS_SUCCESS; - } - - if (string[0] != '\\') - { - DbgPrint("Non absolute pathname passed\n"); - return STATUS_UNSUCCESSFUL; - } - - next = string; - current = next + 1; - - while (next != NULL && - BODY_TO_HEADER(current_dir)->ObjectType == ObDirectoryType) - { - *next = '\\'; - current = next + 1; - next = wcschr(next + 1,'\\'); - if (next != NULL) - { - *next = 0; - } - - DPRINT("current %w current[5] %x next %x ", current, current[5], next); - if (next != NULL) - { - DPRINT("(next+1) %w", next + 1); - } - DPRINT("\n",0); - - current_dir = (PDIRECTORY_OBJECT)ObDirLookup(current_dir, - current, - Attributes); - if (current_dir == NULL) - { - DbgPrint("Path component %w not found\n", current); - return STATUS_UNSUCCESSFUL; - } - - if (BODY_TO_HEADER(current_dir)->ObjectType == IoSymbolicLinkType) - { - current_dir = IoOpenSymlink(current_dir); - } - - } - DPRINT("next %x\n",next); - DPRINT("current %x current %w\n",current,current); - if (next == NULL) - { - if (current_dir == NULL) - { - Status = STATUS_UNSUCCESSFUL; - } - else - { - Status = STATUS_SUCCESS; - } - } - else - { - CHECKPOINT; - *next = '\\'; - *UnparsedSection = next; - if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType) - { - Status = STATUS_FS_QUERY_REQUIRED; - } - else if (BODY_TO_HEADER(current_dir)->ObjectType->Parse != NULL) - { - current_dir = BODY_TO_HEADER(current_dir)->ObjectType-> - Parse(current_dir, - UnparsedSection); - Status = (current_dir != NULL) ? STATUS_SUCCESS : - STATUS_UNSUCCESSFUL; - } - else - { - Status = STATUS_UNSUCCESSFUL; - } - } - CHECKPOINT; - *Object = current_dir; - DPRINT("current_dir %x\n", current_dir); - - return Status; -} - diff --git a/reactos/ntoskrnl/ob/ntobj.c b/reactos/ntoskrnl/ob/ntobj.c new file mode 100644 index 00000000000..3db3fbb52b1 --- /dev/null +++ b/reactos/ntoskrnl/ob/ntobj.c @@ -0,0 +1,148 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ob/ntobj.c + * PURPOSE: User mode interface to object manager + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * 10/06/98: Created + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include +#include + +#define NDEBUG +#include + +/* FUNCTIONS ************************************************************/ + +NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length) +{ + return(ZwSetInformationObject(ObjectHandle, + ObjectInformationClass, + ObjectInformation, + Length)); +} + +NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length) +{ + UNIMPLEMENTED; +} + +NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + return(ZwQueryObject(ObjectHandle, + ObjectInformationClass, + ObjectInformation, + Length, + ResultLength)); +} + +NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle, + IN CINT ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength) +{ + UNIMPLEMENTED +} + +VOID ObMakeTemporaryObject(PVOID ObjectBody) +{ + POBJECT_HEADER ObjectHeader; + + ObjectHeader = BODY_TO_HEADER(ObjectBody); + ObjectHeader->Permanent = FALSE; +} + +NTSTATUS NtMakeTemporaryObject(HANDLE Handle) +{ + return(ZwMakeTemporaryObject(Handle)); +} + +NTSTATUS ZwMakeTemporaryObject(HANDLE Handle) +{ + PVOID Object; + NTSTATUS Status; + POBJECT_HEADER ObjectHeader; + + Status = ObReferenceObjectByHandle(Handle, + 0, + NULL, + KernelMode, + &Object, + NULL); + if (Status != STATUS_SUCCESS) + { + return(Status); + } + + ObjectHeader = BODY_TO_HEADER(Object); + ObjectHeader->Permanent = FALSE; + + ObDereferenceObject(Object); + + return(STATUS_SUCCESS); +} + +NTSTATUS NtClose(HANDLE Handle) +{ + return(ZwClose(Handle)); +} + +NTSTATUS ZwClose(HANDLE Handle) +/* + * FUNCTION: Closes a handle reference to an object + * ARGUMENTS: + * Handle = handle to close + * RETURNS: Status + */ +{ + PVOID ObjectBody; + POBJECT_HEADER Header; + PHANDLE_REP HandleRep; + + assert_irql(PASSIVE_LEVEL); + + DPRINT("ZwClose(Handle %x)\n",Handle); + + HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle); + if (HandleRep == NULL) + { + return(STATUS_INVALID_HANDLE); + } + ObjectBody = HandleRep->ObjectBody; + + HandleRep->ObjectBody = NULL; + + Header = BODY_TO_HEADER(ObjectBody); + + Header->RefCount++; + Header->HandleCount--; + + if (Header->ObjectType != NULL && + Header->ObjectType->Close != NULL) + { + Header->ObjectType->Close(ObjectBody, Header->HandleCount); + } + + Header->RefCount--; + + ObPerformRetentionChecks(Header); + + return(STATUS_SUCCESS); +} diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index df126f5c218..c3abfcad27a 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/ob/object.c * PURPOSE: Implements generic object managment functions - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 10/06/98: Created */ @@ -20,222 +20,150 @@ /* FUNCTIONS ************************************************************/ -NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - IN PVOID ObjectInformation, - IN ULONG Length) +VOID ObInitializeObject(POBJECT_HEADER ObjectHeader, + PHANDLE Handle, + ACCESS_MASK DesiredAccess, + POBJECT_TYPE Type, + POBJECT_ATTRIBUTES ObjectAttributes) { - return(ZwSetInformationObject(ObjectHandle, - ObjectInformationClass, - ObjectInformation, - Length)); -} - -NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - IN PVOID ObjectInformation, - IN ULONG Length) -{ - UNIMPLEMENTED; -} - -NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - return(ZwQueryObject(ObjectHandle, - ObjectInformationClass, - ObjectInformation, - Length, - ResultLength)); -} - -NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle, - IN CINT ObjectInformationClass, - OUT PVOID ObjectInformation, - IN ULONG Length, - OUT PULONG ResultLength) -{ - UNIMPLEMENTED -} - -VOID ObMakeTemporaryObject(PVOID ObjectBody) -{ - POBJECT_HEADER ObjectHeader; - - ObjectHeader = BODY_TO_HEADER(ObjectBody); - ObjectHeader->Permanent = FALSE; -} - -NTSTATUS NtMakeTemporaryObject(HANDLE Handle) -{ - return(ZwMakeTemporaryObject(Handle)); -} - -NTSTATUS ZwMakeTemporaryObject(HANDLE Handle) -{ - PVOID Object; - NTSTATUS Status; - POBJECT_HEADER ObjectHeader; - - Status = ObReferenceObjectByHandle(Handle, - 0, - NULL, - KernelMode, - &Object, - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - ObjectHeader = BODY_TO_HEADER(Object); - ObjectHeader->Permanent = FALSE; - - ObDereferenceObject(Object); - - return(STATUS_SUCCESS); -} - -PVOID ObGenericCreateObject(PHANDLE Handle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - POBJECT_TYPE Type) -/* - * FUNCTION: Creates a new object - */ -{ - POBJECT_HEADER hdr = NULL; - PWSTR path; - PWSTR name; - PWSTR Ignored; - PULONG addr; - PWSTR Buffer; - - DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x," - "ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess, - ObjectAttributes,Type); - - /* - * Allocate the object body and header - */ - hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type)); - DPRINT("OBJECT_ALLOC_SIZE(Type) %d\n",OBJECT_ALLOC_SIZE(Type)); - if (hdr==NULL) - { - return(NULL); - } - DPRINT("hdr %x\n",hdr); - - - /* - * If unnamed then initalize - */ - if (ObjectAttributes==NULL || ObjectAttributes->ObjectName==NULL) - { - ObInitializeObjectHeader(Type,NULL,hdr); - if (Handle != NULL) - { - *Handle = ObInsertHandle(KeGetCurrentProcess(), - HEADER_TO_BODY(hdr), - DesiredAccess, - FALSE); - } - return(HEADER_TO_BODY(hdr)); - } - - - /* - * Copy the object name into a buffer - */ -// DbgPrint("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName); -// DbgPrint("ObjectAttributes->ObjectName->Length %d\n", -// ObjectAttributes->ObjectName->Length); -// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n", -// ObjectAttributes->ObjectName->MaximumLength); - Buffer = ExAllocatePool(NonPagedPool, - ((ObjectAttributes->ObjectName->Length+1)*2)); - if (Buffer==NULL) - { - return(NULL); - } - memcpy(Buffer, ObjectAttributes->ObjectName->Buffer, - (ObjectAttributes->ObjectName->Length+1)*2); - - /* - * Seperate the name into a path and name - */ - name = wcsrchr(Buffer,'\\'); - if (name==NULL) - { - name=Buffer; - path=NULL; - } - else - { - path=Buffer; - *name=0; - name=name+1; - } - DPRINT("name %w path %w\n",name,path); - - ObLookupObject(ObjectAttributes->RootDirectory, - path, - &hdr->Parent, - &Ignored, - 0L); - - /* - * Initialize the object header - */ - ObInitializeObjectHeader(Type,name,hdr); - - - ObCreateEntry(hdr->Parent,hdr); - - DPRINT("Handle %x\n",Handle); - if (Handle != NULL) - { - *Handle = ObInsertHandle(KeGetCurrentProcess(), - HEADER_TO_BODY(hdr), - DesiredAccess, - FALSE); - } - - return(HEADER_TO_BODY(hdr)); -} - -VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name, - POBJECT_HEADER ObjectHeader) -/* - * FUNCTION: Creates a new object - * ARGUMENT: - * id = Identifier for the type of object - * obj = Pointer to the header of the object - */ -{ - PWSTR temp_name; - - DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type, - name,ObjectHeader); - ObjectHeader->HandleCount = 1; ObjectHeader->RefCount = 1; ObjectHeader->ObjectType = Type; ObjectHeader->Permanent = FALSE; - if (name==NULL) + RtlInitUnicodeString(&(ObjectHeader->Name),NULL); + if (Handle != NULL) { - ObjectHeader->Name.Length=0; - ObjectHeader->Name.Buffer=NULL; - } - else - { - RtlInitUnicodeString(&(ObjectHeader->Name),name); + *Handle = ObInsertHandle(KeGetCurrentProcess(), + HEADER_TO_BODY(ObjectHeader), + DesiredAccess, + FALSE); } } +NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, + PVOID* ReturnedObject, + PWSTR* RemainingPath) +{ + PVOID NextObject; + PVOID CurrentObject; + POBJECT_HEADER CurrentHeader; + NTSTATUS Status; + PWSTR Path; + PWSTR current; + + DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, " + "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath); + DPRINT("ObjectAttributes->ObjectName->Buffer %x\n", + ObjectAttributes->ObjectName->Buffer); + + if (ObjectAttributes->RootDirectory == NULL) + { + ObReferenceObjectByPointer(NameSpaceRoot, + DIRECTORY_TRAVERSE, + NULL, + UserMode); + CurrentObject = NameSpaceRoot; + } + else + { + Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory, + DIRECTORY_TRAVERSE, + NULL, + UserMode, + &CurrentObject, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + + Path = ObjectAttributes->ObjectName->Buffer; + + if (Path[0] == 0) + { + *ReturnedObject = CurrentObject; + return(STATUS_SUCCESS); + } + + if (Path[0] != '\\') + { + return(STATUS_UNSUCCESSFUL); + } + + current = Path; + + while (TRUE) + { + DPRINT("current %w\n",current); + CurrentHeader = BODY_TO_HEADER(CurrentObject); + if (CurrentHeader->ObjectType->Parse == NULL) + { + break; + } + NextObject = CurrentHeader->ObjectType->Parse(CurrentObject, + ¤t); + if (NextObject == NULL) + { + break; + } + ObDereferenceObject(CurrentObject); + CurrentObject = NextObject; + } + + *RemainingPath = current; + *ReturnedObject = CurrentObject; + + return(STATUS_SUCCESS); +} + +PVOID ObCreateObject(PHANDLE Handle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + POBJECT_TYPE Type) +{ + PVOID Parent = NULL; + PWSTR RemainingPath = NULL; + POBJECT_HEADER Header; + NTSTATUS Status; + + DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n"); + if (ObjectAttributes != NULL && + ObjectAttributes->ObjectName != NULL) + { + DPRINT("ObjectAttributes->ObjectName->Buffer %w\n", + ObjectAttributes->ObjectName->Buffer); + } + + if (ObjectAttributes != NULL && + ObjectAttributes->ObjectName != NULL) + { + ObFindObject(ObjectAttributes, + &Parent, + &RemainingPath); + } + + Header = (POBJECT_HEADER)ExAllocatePool(NonPagedPool, + OBJECT_ALLOC_SIZE(Type)); + ObInitializeObject(Header, + Handle, + DesiredAccess, + Type, + ObjectAttributes); + if (Header->ObjectType != NULL && + Header->ObjectType->Create != NULL) + { + Status = Header->ObjectType->Create(HEADER_TO_BODY(Header), + Parent, + RemainingPath, + ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + return(NULL); + } + } + return(HEADER_TO_BODY(Header)); +} NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody, ACCESS_MASK DesiredAccess, @@ -251,12 +179,21 @@ NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody, * RETURNS: Status */ { - POBJECT_HEADER Object; + POBJECT_HEADER ObjectHeader; - DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody); + DPRINT("ObReferenceObjectByPointer(ObjectBody %x, ObjectType %x)\n", + ObjectBody,ObjectType); - Object = BODY_TO_HEADER(ObjectBody); - Object->RefCount++; + ObjectHeader = BODY_TO_HEADER(ObjectBody); + + if (ObjectType != NULL && ObjectHeader->ObjectType != ObjectType) + { + DPRINT("Failed (type was %x %w)\n",ObjectHeader->ObjectType, + ObjectHeader->ObjectType->TypeName.Buffer); + return(STATUS_UNSUCCESSFUL); + } + + ObjectHeader->RefCount++; return(STATUS_SUCCESS); } @@ -274,9 +211,9 @@ NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header) !Header->Permanent) { if (Header->ObjectType != NULL && - Header->ObjectType->Close != NULL) + Header->ObjectType->Delete != NULL) { - Header->ObjectType->Close(HEADER_TO_BODY(Header)); + Header->ObjectType->Delete(HEADER_TO_BODY(Header)); } if (Header->Name.Buffer != NULL) { @@ -305,45 +242,6 @@ VOID ObDereferenceObject(PVOID ObjectBody) ObPerformRetentionChecks(Header); } - -NTSTATUS NtClose(HANDLE Handle) -{ - return(ZwClose(Handle)); -} - -NTSTATUS ZwClose(HANDLE Handle) -/* - * FUNCTION: Closes a handle reference to an object - * ARGUMENTS: - * Handle = handle to close - * RETURNS: Status - */ -{ - PVOID ObjectBody; - POBJECT_HEADER Header; - PHANDLE_REP HandleRep; - - assert_irql(PASSIVE_LEVEL); - - DPRINT("ZwClose(Handle %x)\n",Handle); - - HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle); - if (HandleRep == NULL) - { - return(STATUS_INVALID_HANDLE); - } - ObjectBody = HandleRep->ObjectBody; - - HandleRep->ObjectBody = NULL; - - Header = BODY_TO_HEADER(ObjectBody); - - Header->HandleCount--; - ObPerformRetentionChecks(Header); - - return(STATUS_SUCCESS); -} - NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index b44ce1f9a3c..3b6ee2f67c3 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -59,7 +59,7 @@ VOID PsInitProcessManagment(VOID) /* * Initialize the system process */ - SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL, + SystemProcess = ObCreateObject(NULL,PROCESS_ALL_ACCESS,NULL, PsProcessType); KProcess = &SystemProcess->Pcb; @@ -172,10 +172,10 @@ NTSTATUS STDCALL ZwCreateProcess( return(Status); } - Process = ObGenericCreateObject(ProcessHandle, - DesiredAccess, - ObjectAttributes, - PsProcessType); + Process = ObCreateObject(ProcessHandle, + DesiredAccess, + ObjectAttributes, + PsProcessType); KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader, 0, sizeof(EPROCESS), diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 006b3efe332..eb6838a348e 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -216,10 +216,10 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle, PiNrThreads++; - Thread = ObGenericCreateObject(ThreadHandle, - DesiredAccess, - ThreadAttributes, - PsThreadType); + Thread = ObCreateObject(ThreadHandle, + DesiredAccess, + ThreadAttributes, + PsThreadType); DPRINT("Thread = %x\n",Thread); Thread->Tcb.LastTick = 0; Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED; diff --git a/reactos/ntoskrnl/rtl/seqlist.c b/reactos/ntoskrnl/rtl/seqlist.c index d67ea727676..20a809dbf2a 100644 --- a/reactos/ntoskrnl/rtl/seqlist.c +++ b/reactos/ntoskrnl/rtl/seqlist.c @@ -1,18 +1,16 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: mkernel/rtl/seqlist.c + * FILE: ntoskrnl/rtl/seqlist.c * PURPOSE: Implementing sequenced lists - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * REVISION HISTORY: * 28/06/98: Created */ /* INCLUDES ***************************************************************/ -#include #include -#include /* TYPES ********************************************************************/ diff --git a/reactos/ntoskrnl/rtl/time.c b/reactos/ntoskrnl/rtl/time.c index 96b8a852136..7fdab2cf7d2 100644 --- a/reactos/ntoskrnl/rtl/time.c +++ b/reactos/ntoskrnl/rtl/time.c @@ -11,8 +11,6 @@ /* INCLUDES *****************************************************************/ -#include -#include #include #include diff --git a/reactos/ntoskrnl/tst/test.c b/reactos/ntoskrnl/tst/test.c index f2384face15..d430bcc66ee 100644 --- a/reactos/ntoskrnl/tst/test.c +++ b/reactos/ntoskrnl/tst/test.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/tst/test.c * PURPOSE: Kernel regression tests - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 28/05/98: Created */ @@ -25,66 +25,8 @@ #define IDE_SECTOR_SZ 512 -/* GLOBALS ******************************************************************/ - -static KEVENT event = {}; -//static KEVENT event2; -NTSTATUS TstShell(VOID); - /* FUNCTIONS ****************************************************************/ -NTSTATUS TstPlaySound(VOID) -{ - HANDLE hfile; - -// * Open the parallel port - printk("Opening Waveout\n"); -// hfile = CreateFile("\\Device\\WaveOut",0,0,0,0,0,0); - if (hfile == NULL) - { - printk("File open failed\n"); - } - else - { -// WriteFile(hfile,wave,wavelength,NULL,NULL); - } -} -NTSTATUS TstFirstThread(PVOID start) -{ - int i; - - printk("Beginning Thread A\n"); - for (;;) - { - KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); - printk("AAA "); - KeSetEvent(&event,IO_NO_INCREMENT,FALSE); - } -} - -NTSTATUS TstSecondThread(PVOID start) -{ - int i; - - printk("Beginning Thread B\n"); - for(;;) - { - KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); - printk("BBB "); - KeSetEvent(&event,IO_NO_INCREMENT,FALSE); - } -} - -NTSTATUS TstThreadSupport() -{ - HANDLE th1, th2; - - KeInitializeEvent(&event,SynchronizationEvent,TRUE); - PsCreateSystemThread(&th1,0,NULL,NULL,NULL,TstFirstThread,NULL); - PsCreateSystemThread(&th2,0,NULL,NULL,NULL,TstSecondThread,NULL); - printk("Ending main thread\n"); - for(;;); -} VOID ExExecuteShell(VOID) { @@ -99,6 +41,7 @@ VOID ExExecuteShell(VOID) LARGE_INTEGER SectionOffset; ULONG Size, StackSize; CONTEXT Context; + NTSTATUS Status; ZwCreateProcess(&ShellHandle, PROCESS_ALL_ACCESS, @@ -112,8 +55,8 @@ VOID ExExecuteShell(VOID) RtlInitAnsiString(&afilename,"\\??\\C:\\reactos\\system\\shell.bin"); RtlAnsiStringToUnicodeString(&ufilename,&afilename,TRUE); InitializeObjectAttributes(&attr,&ufilename,0,NULL,NULL); - ZwOpenFile(&hfile,FILE_ALL_ACCESS,&attr,NULL,0,0); - if (hfile==NULL) + Status = ZwOpenFile(&hfile,FILE_ALL_ACCESS,&attr,NULL,0,0); + if (!NT_SUCCESS(Status)) { DbgPrint("Failed to open file\n"); return; @@ -443,102 +386,8 @@ void TstIDERead(void) } } -void -TstKeyboard(void) -{ - NTSTATUS Status; - HANDLE FileHandle; - ANSI_STRING AnsiDeviceName; - UNICODE_STRING UnicodeDeviceName; - OBJECT_ATTRIBUTES ObjectAttributes; - KEY_EVENT_RECORD KeyEvent[2]; - - DbgPrint("Testing keyboard driver...\n"); - - DbgPrint("Opening Keyboard device\n"); - RtlInitAnsiString(&AnsiDeviceName, "\\Device\\Keyboard"); - RtlAnsiStringToUnicodeString(&UnicodeDeviceName, &AnsiDeviceName, TRUE); - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeDeviceName, - 0, - NULL, - NULL); - Status = ZwOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes, NULL, 0, 0); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to open keyboard\n"); - return; - } - - DbgPrint(">"); - for(;;) - { - Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - NULL, - &KeyEvent, - sizeof(KeyEvent), - 0, - 0); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to read key event, status %08x\n", Status); - return; - } - DbgPrint("%c",KeyEvent[0].AsciiChar); - } -} - -static int TTcnt = 0; - -VOID TstTimerDpc(struct _KDPC* Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - TTcnt++; - - DPRINT("Timer DPC cnt:%d\n", TTcnt); - -} - -void -TstTimer(void) -{ - PIO_TIMER Timer = ExAllocatePool(NonPagedPool,sizeof(IO_TIMER)); - long long int lli = -10000000; - LARGE_INTEGER li = *(LARGE_INTEGER *)&lli; - - CHECKPOINT; - KeInitializeTimer(&Timer->timer); - CHECKPOINT; - KeInitializeDpc(&Timer->dpc, TstTimerDpc, NULL); - CHECKPOINT; - KeSetTimerEx(&Timer->timer, - li, - 1000, - &Timer->dpc); - CHECKPOINT; - while (TTcnt < 100) - ; - CHECKPOINT; - KeCancelTimer(&Timer->timer); - CHECKPOINT; - -} - void TstBegin() { ExExecuteShell(); -// TstFileRead(); -// TstGeneralWrite(); -// TstThreadSupport(); -// TstKeyboard(); -// TstIDERead(); -// TstKeyboardRead(); -// TstShell(); -// TstTimer(); }