mirror of
https://github.com/reactos/reactos
synced 2025-10-07 00:42:44 +02:00
Compare commits
5 Commits
hbelusca/g
...
ReactOS-0.
Author | SHA1 | Date | |
---|---|---|---|
|
cfe5f4afb0 | ||
|
f77c44657c | ||
|
df0328b7cc | ||
|
94c8483b04 | ||
|
fc7e59ce74 |
@@ -39,8 +39,8 @@ enum
|
||||
*/
|
||||
enum
|
||||
{
|
||||
STATUS_SUCCESS,
|
||||
STATUS_INSUFFICIENT_RESOURCES,
|
||||
STATUS_SUCCESS = 0x0,
|
||||
STATUS_INSUFFICIENT_RESOURCES = 0x80000000,
|
||||
STATUS_OBJECT_NAME_EXISTS,
|
||||
STATUS_OBJECT_NAME_COLLISION,
|
||||
// STATUS_DATATYPE_MISALIGNMENT,
|
||||
@@ -179,7 +179,9 @@ enum
|
||||
STATUS_NO_MEDIA_IN_DRIVE,
|
||||
STATUS_VERIFY_REQUIRED,
|
||||
STATUS_UNRECOGNIZED_MEDIA,
|
||||
STATUS_UNRECOGNIZED_VOLUME,
|
||||
// STATUS_WRONG_VOLUME,
|
||||
STATUS_FS_DRIVER_REQUIRED,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -63,6 +63,7 @@ typedef VOID (*PIO_APC_ROUTINE) (PVOID ApcContext,
|
||||
|
||||
/*
|
||||
* PURPOSE: Special timer associated with each device
|
||||
* NOTES: This is a guess
|
||||
*/
|
||||
typedef struct _IO_TIMER
|
||||
{
|
||||
@@ -192,6 +193,27 @@ typedef struct _IO_COMPLETION_CONTEXT
|
||||
ULONG Key;
|
||||
} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
|
||||
|
||||
#define FO_FILE_OPEN 0x00000001
|
||||
#define FO_SYNCHRONOUS_IO 0x00000002
|
||||
#define FO_ALERTABLE_IO 0x00000004
|
||||
#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||
#define FO_WRITE_THROUGH 0x00000010
|
||||
#define FO_SEQUENTIAL_ONLY 0x00000020
|
||||
#define FO_CACHE_SUPPORTED 0x00000040
|
||||
#define FO_NAMED_PIPE 0x00000080
|
||||
#define FO_STREAM_FILE 0x00000100
|
||||
#define FO_MAILSLOT 0x00000200
|
||||
#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400
|
||||
#define FO_DIRECT_DEVICE_OPEN 0x00000800
|
||||
#define FO_FILE_MODIFIED 0x00001000
|
||||
#define FO_FILE_SIZE_CHANGED 0x00002000
|
||||
#define FO_CLEANUP_COMPLETE 0x00004000
|
||||
#define FO_TEMPORARY_FILE 0x00008000
|
||||
#define FO_DELETE_ON_CLOSE 0x00010000
|
||||
#define FO_OPENED_CASE_SENSITIVE 0x00020000
|
||||
#define FO_HANDLE_CREATED 0x00040000
|
||||
#define FO_FILE_FAST_IO_READ 0x00080000
|
||||
|
||||
typedef struct _FILE_OBJECT
|
||||
{
|
||||
CSHORT Type;
|
||||
|
@@ -3,6 +3,12 @@
|
||||
|
||||
/* KERNEL FUNCTIONS ********************************************************/
|
||||
|
||||
VOID KeDrainApcQueue(VOID);
|
||||
VOID KeInitializeApc(PKAPC Apc, PKNORMAL_ROUTINE NormalRoutine,
|
||||
PVOID NormalContext,
|
||||
PKTHREAD TargetThread);
|
||||
BOOLEAN KeInsertQueueApc(PKAPC Apc);
|
||||
|
||||
/*
|
||||
* FUNCTION: Acquires a spinlock so the caller can synchronize access to
|
||||
* data
|
||||
|
@@ -34,7 +34,7 @@ typedef struct
|
||||
USHORT WaitType;
|
||||
} KWAIT_BLOCK, *PKWAIT_BLOCK;
|
||||
|
||||
|
||||
#define _KTHREAD _ETHREAD
|
||||
|
||||
typedef struct _ETHREAD
|
||||
/*
|
||||
@@ -47,7 +47,7 @@ typedef struct _ETHREAD
|
||||
/*
|
||||
* PURPOSE: Head of the queue of apcs
|
||||
*/
|
||||
LIST_ENTRY apc_queue_head;
|
||||
LIST_ENTRY ApcQueueHead;
|
||||
|
||||
/*
|
||||
* PURPOSE: Entry in the linked list of threads
|
||||
|
@@ -1,5 +1,7 @@
|
||||
/* MEMORY MANAGMENT ******************************************************/
|
||||
|
||||
#include <internal/hal/page.h>
|
||||
|
||||
/*
|
||||
* FUNCTION: Determines if the given virtual address is page aligned
|
||||
*/
|
||||
@@ -27,7 +29,16 @@
|
||||
* Size = Size of range
|
||||
* RETURNS: The number of pages
|
||||
*/
|
||||
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(Va, Size)
|
||||
extern inline unsigned int ADDRESS_AND_SIZE_TO_SPAN_PAGES(PVOID Va,
|
||||
ULONG Size)
|
||||
{
|
||||
ULONG HighestAddr;
|
||||
ULONG LowestAddr;
|
||||
|
||||
HighestAddr = PAGE_ROUND_UP(Size + ((ULONG)Va));
|
||||
LowestAddr = PAGE_ROUND_DOWN((ULONG)Va);
|
||||
return((HighestAddr - LowestAddr) / PAGESIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Returns FALSE is the pointer is NULL, TRUE otherwise
|
||||
|
@@ -1,4 +1,25 @@
|
||||
typedef struct _MDL
|
||||
|
||||
enum
|
||||
{
|
||||
MDL_MAPPED_TO_SYSTEM_VA = 0x1,
|
||||
MDL_PAGES_LOCKED = 0x2,
|
||||
MDL_SOURCE_IS_NONPAGED_POOL = 0x4,
|
||||
MDL_ALLOCATED_FIXED_SIZE = 0x8,
|
||||
MDL_PARTIAL = 0x10,
|
||||
MDL_PARTIAL_HAS_BEEN_MAPPED = 0x20,
|
||||
MDL_IO_PAGE_READ = 0x40,
|
||||
MDL_WRITE_OPERATION = 0x80,
|
||||
MDL_PARENT_MAPPED_SYSTEM_VA = 0x100,
|
||||
MDL_LOCK_HELD = 0x200,
|
||||
MDL_SCATTER_GATHER_VA = 0x400,
|
||||
MDL_IO_SPACE = 0x800,
|
||||
MDL_NETWORK_HEADER = 0x1000,
|
||||
MDL_MAPPING_CAN_FAIL = 0x2000,
|
||||
MDL_ALLOCATED_MUST_SUCCEED = 0x4000,
|
||||
MDL_64_BIT_VA = 0x8000,
|
||||
};
|
||||
|
||||
typedef struct _MDL
|
||||
/*
|
||||
* PURPOSE: Describes a user buffer passed to a system API
|
||||
*/
|
||||
|
@@ -64,8 +64,7 @@ enum {
|
||||
#include <ddk/iofuncs.h>
|
||||
#include <ddk/psfuncs.h>
|
||||
#include <ddk/obfuncs.h>
|
||||
|
||||
ULONG DbgPrint(PCH Format,...);
|
||||
#include <ddk/dbgfuncs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
@@ -42,3 +42,6 @@ NTSTATUS ObReferenceObjectByPointer(PVOID Object,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_TYPE ObjectType,
|
||||
KPROCESSOR_MODE AccessMode);
|
||||
|
||||
NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
PVOID* Object);
|
||||
|
@@ -133,17 +133,9 @@ typedef struct _OBJECT
|
||||
typedef struct _OBJECT_ATTRIBUTES
|
||||
{
|
||||
ULONG Length;
|
||||
|
||||
/*
|
||||
* PURPOSE: Attributes of the object
|
||||
*/
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
|
||||
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
// SecurityQualityOfService
|
||||
|
||||
struct _DIRECTORY_OBJECT* parent;
|
||||
UNICODE_STRING name;
|
||||
UNICODE_STRING path;
|
||||
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
|
@@ -226,7 +226,7 @@ VOID RtlStoreUshort(PUSHORT Address, USHORT Value);
|
||||
BOOLEAN RtlTimeFieldsToTime(PTIME_FIELDS TimeFields, PLARGE_INTEGER Time);
|
||||
VOID RtlTimeToTimeFields(PLARGE_INTEGER Time, PTIME_FIELDS TimeFields);
|
||||
PWSTR RtlStrtok(PUNICODE_STRING _string, PWSTR _sep, PWSTR* temp);
|
||||
|
||||
VOID RtlGetCallersAddress(PVOID* CallersAddress);
|
||||
|
||||
typedef struct {
|
||||
ULONG Length;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: dma.h,v 1.3 1998/08/25 04:48:36 rex Exp $
|
||||
/* $Id: dma.h,v 1.1.1.2 1998/08/25 04:27:32 rex Exp $
|
||||
* linux/include/asm/dma.h: Defines for using and allocating dma channels.
|
||||
* Written by Hennus Bergman, 1992.
|
||||
* High DMA channel support & info by Hannu Savolainen
|
||||
|
@@ -22,6 +22,6 @@
|
||||
NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry);
|
||||
|
||||
VOID IoInitCancelHandling(VOID);
|
||||
|
||||
VOID IoInitSymbolicLinkImplementation(VOID);
|
||||
|
||||
#endif
|
||||
|
@@ -40,6 +40,7 @@ enum
|
||||
OBJTYP_SYMLNK,
|
||||
OBJTYP_DEVICE,
|
||||
OBJTYP_THREAD,
|
||||
OBJTYP_FILE,
|
||||
OBJTYP_MAX,
|
||||
};
|
||||
|
||||
@@ -47,7 +48,7 @@ BOOL ObAddObjectToNameSpace(PUNICODE_STRING path, POBJECT_HEADER Object);
|
||||
|
||||
VOID ObRegisterType(CSHORT id, OBJECT_TYPE* type);
|
||||
|
||||
VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
|
||||
VOID ObInitializeObjectHeader(CSHORT id, PWSTR name,
|
||||
POBJECT_HEADER obj);
|
||||
|
||||
/*
|
||||
@@ -58,9 +59,8 @@ VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
|
||||
*/
|
||||
ULONG ObSizeOf(CSHORT Type);
|
||||
HANDLE ObAddHandle(PVOID obj);
|
||||
|
||||
PVOID ObLookupObject(HANDLE rooth, PWSTR _string);
|
||||
PVOID ObGetObjectByHandle(HANDLE h);
|
||||
PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string);
|
||||
PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
|
@@ -9,9 +9,9 @@
|
||||
#ifndef __VERSION_H
|
||||
#define __VERSION_H
|
||||
|
||||
#define KERNEL_VERSION "0.0.8"
|
||||
#define KERNEL_VERSION "0.0.9"
|
||||
#define KERNEL_MAJOR_VERSION 0
|
||||
#define KERNEL_MINOR_VERSION 0
|
||||
#define KERNEL_PATCH_LEVEL 8
|
||||
#define KERNEL_PATCH_LEVEL 9
|
||||
|
||||
#endif
|
||||
|
@@ -38,7 +38,7 @@ extern __kernel_size_t strnlen(const char *,__kernel_size_t);
|
||||
extern __kernel_size_t strspn(const char *,const char *);
|
||||
extern int strcmp(const char *,const char *);
|
||||
extern int strncmp(const char *,const char *,__kernel_size_t);
|
||||
extern int stricmp(const char* cs,const char * ct)
|
||||
extern int stricmp(const char* cs,const char * ct);
|
||||
extern int strnicmp(const char* cs,const char * ct, size_t count);
|
||||
|
||||
extern void * memset(void *,int,__kernel_size_t);
|
||||
|
@@ -27,8 +27,8 @@ extern wchar_t * wcscat(wchar_t *, const wchar_t *);
|
||||
extern wchar_t * wcsncat(wchar_t *, const wchar_t *, __kernel_size_t);
|
||||
extern int wcscmp(const wchar_t *,const wchar_t *);
|
||||
extern int wcsncmp(const wchar_t *,const wchar_t *,__kernel_size_t);
|
||||
extern wchar_t * wcschr(const wchar_t *,int);
|
||||
extern wchar_t * wcsrchr(const wchar_t *,int);
|
||||
wchar_t* wcschr(wchar_t* str, wchar_t ch);
|
||||
extern wchar_t * wcsrchr(const wchar_t *,wchar_t);
|
||||
extern wchar_t * wcspbrk(const wchar_t *,const wchar_t *);
|
||||
extern wchar_t * wcstok(wchar_t *,const wchar_t *);
|
||||
extern wchar_t * wcsstr(const wchar_t *,const wchar_t *);
|
||||
@@ -36,499 +36,6 @@ extern size_t wcsnlen(const wchar_t * s, size_t count);
|
||||
extern int wcsicmp(const wchar_t* cs,const wchar_t * ct);
|
||||
extern int wcsnicmp(const wchar_t* cs,const wchar_t * ct, size_t count);
|
||||
|
||||
|
||||
/*
|
||||
* Include machine specific inline routines
|
||||
*/
|
||||
//#ifndef _I386_STRING_H_
|
||||
//#define _I386_STRING_H_
|
||||
|
||||
/*
|
||||
* On a 486 or Pentium, we are better off not using the
|
||||
* byte string operations. But on a 386 or a PPro the
|
||||
* byte string ops are faster than doing it by hand
|
||||
* (MUCH faster on a Pentium).
|
||||
*
|
||||
* Also, the byte strings actually work correctly. Forget
|
||||
* the i486 routines for now as they may be broken..
|
||||
*/
|
||||
|
||||
#if FIXED_486_STRING && (CPU == 486 || CPU == 586)
|
||||
#include <asm/string-486.h>
|
||||
#else
|
||||
|
||||
/*
|
||||
* This string-include defines all string functions as inline
|
||||
* functions. Use gcc. It also assumes ds=es=data space, this should be
|
||||
* normal. Most of the string-functions are rather heavily hand-optimized,
|
||||
* see especially wcstok,wcsstr,wcs[c]spn. They should work, but are not
|
||||
* very easy to understand. Everything is done entirely within the register
|
||||
* set, making the functions fast and clean. String instructions have been
|
||||
* used through-out, making for "slightly" unclear code :-)
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSCPY
|
||||
extern inline wchar_t * wcscpy(wchar_t * dest,const wchar_t *src)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"stosw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b"
|
||||
: /* no output */
|
||||
:"S" (src),"D" (dest):"esi","edi","eax","memory");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSNCPY
|
||||
inline wchar_t * wcsncpy(wchar_t * dest,const wchar_t *src,size_t count)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\tdecl %2\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsw\n\t"
|
||||
"stosw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b\n\t"
|
||||
"rep\n\t"
|
||||
"stosw\n"
|
||||
"2:"
|
||||
: /* no output */
|
||||
:"S" (src),"D" (dest),"c" (count):"esi","edi","eax","ecx","memory");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSCAT
|
||||
inline wchar_t * wcscat(wchar_t * dest,const wchar_t * src)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"repnz\n\t"
|
||||
"scasw\n\t"
|
||||
"decl %1\n"
|
||||
"decl %1\n\t"
|
||||
"1:\tlodsw\n\t"
|
||||
"stosw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b"
|
||||
: /* no output */
|
||||
:"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"esi","edi","eax","ecx");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSNCAT
|
||||
inline wchar_t * wcsncat(wchar_t * dest,const wchar_t * src,size_t count)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"repnz\n\t"
|
||||
"scasw\n\t"
|
||||
"decl %1\n\t"
|
||||
"movl %4,%3\n"
|
||||
"decl %1\n\t"
|
||||
"1:\tdecl %3\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsw\n\t"
|
||||
"stosw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\txorl %2,%2\n\t"
|
||||
"stosw"
|
||||
: /* no output */
|
||||
:"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
|
||||
:"esi","edi","eax","ecx","memory");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSCMP
|
||||
inline int wcscmp(const wchar_t* cs,const wchar_t * ct)
|
||||
{
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"scasw\n\t"
|
||||
"jne 2f\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\tsbbl %%eax,%%eax\n\t"
|
||||
"orw $1,%%eax\n"
|
||||
"3:"
|
||||
:"=a" (__res):"S" (cs),"D" (ct):"esi","edi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSNCMP
|
||||
inline int wcsncmp(const wchar_t * cs,const wchar_t * ct,size_t count)
|
||||
{
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\tdecl %3\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsw\n\t"
|
||||
"scasw\n\t"
|
||||
"jne 3f\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\txorl %%eax,%%eax\n\t"
|
||||
"jmp 4f\n"
|
||||
"3:\tsbbl %%eax,%%eax\n\t"
|
||||
"orw $1,%%eax\n"
|
||||
"4:"
|
||||
:"=a" (__res):"S" (cs),"D" (ct),"c" (count):"esi","edi","ecx");
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSCHR
|
||||
inline wchar_t * wcschr(const wchar_t * s, int c)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"movw %%eax,%%edx\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"cmpw %%edx,%%eax\n\t"
|
||||
"je 2f\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"jne 1b\n\t"
|
||||
"movl $1,%1\n"
|
||||
"2:\tmovl %1,%0\n\t"
|
||||
"decl %0\n\t"
|
||||
"decl %0\n\t"
|
||||
:"=a" (__res):"S" (s),"0" (c):"esi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSRCHR
|
||||
inline wchar_t * wcsrchr(const wchar_t * s, int c)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"movw %%eax,%%edx\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"cmpw %%edx,%%eax\n\t"
|
||||
"jne 2f\n\t"
|
||||
"leal -2(%%esi),%0\n"
|
||||
"2:\ttestw %%eax,%%eax\n\t"
|
||||
"jne 1b"
|
||||
:"=d" (__res):"0" (0),"S" (s),"a" (c):"eax","esi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSSPN
|
||||
inline size_t wcsspn(const wchar_t * cs, const wchar_t * ct)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne\n\t"
|
||||
"scasb\n\t"
|
||||
"je 1b\n"
|
||||
"2:\tdecl %0"
|
||||
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
|
||||
:"eax","ecx","edx","edi");
|
||||
return __res-cs;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSCSPN
|
||||
inline size_t wcscspn(const wchar_t * cs, const wchar_t * ct)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\tdecl %0"
|
||||
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
|
||||
:"eax","ecx","edx","edi");
|
||||
return __res-cs;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_STRPBRK
|
||||
inline wchar_t * wcspbrk(const wchar_t * cs,const wchar_t * ct)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\tlodsw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"je 2f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"jne 1b\n\t"
|
||||
"decl %0\n\t"
|
||||
"jmp 3f\n"
|
||||
"2:\txorl %0,%0\n"
|
||||
"3:"
|
||||
:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
|
||||
:"eax","ecx","edx","edi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_WCSSTR
|
||||
inline wchar_t * wcsstr(const wchar_t * cs,const wchar_t * ct)
|
||||
{
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t" \
|
||||
"movl %4,%%edi\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
|
||||
"movl %%ecx,%%edx\n"
|
||||
"1:\tmovl %4,%%edi\n\t"
|
||||
"movl %%esi,%%eax\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repe\n\t"
|
||||
"cmpsw\n\t"
|
||||
"je 2f\n\t" /* also works for empty string, see above */
|
||||
"xchgl %%eax,%%esi\n\t"
|
||||
"incl %%esi\n\t"
|
||||
"cmpw $0,-1(%%eax)\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"2:"
|
||||
:"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
|
||||
:"ecx","edx","edi","esi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSLEN
|
||||
inline size_t wcslen(const wchar_t * s)
|
||||
{
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %0\n\t"
|
||||
"decl %0"
|
||||
:"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"edi");
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSTOK
|
||||
|
||||
|
||||
inline wchar_t * wcstok(wchar_t * s,const wchar_t * ct)
|
||||
{
|
||||
|
||||
register wchar_t * __res;
|
||||
__asm__ __volatile__(
|
||||
"testl %1,%1\n\t"
|
||||
"jne 1f\n\t"
|
||||
"testl %0,%0\n\t"
|
||||
"je 8f\n\t"
|
||||
"movl %0,%1\n"
|
||||
"1:\txorl %0,%0\n\t"
|
||||
"movl $-1,%%ecx\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"cld\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"repnz\n\t"
|
||||
"scasw\n\t"
|
||||
"notl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"decl %%ecx\n\t"
|
||||
"je 7f\n\t" /* empty delimiter-string */
|
||||
"movl %%ecx,%%edx\n"
|
||||
"2:\tlodsw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"je 7f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"je 2b\n\t"
|
||||
"decl %1\n\t"
|
||||
"decl %1\n\t"
|
||||
"cmpw $0,(%1)\n\t"
|
||||
"je 7f\n\t"
|
||||
"movl %1,%0\n"
|
||||
"3:\tlodsw\n\t"
|
||||
"testw %%eax,%%eax\n\t"
|
||||
"je 5f\n\t"
|
||||
"movl %4,%%edi\n\t"
|
||||
"movl %%edx,%%ecx\n\t"
|
||||
"repne\n\t"
|
||||
"scasw\n\t"
|
||||
"jne 3b\n\t"
|
||||
"decl %1\n\t"
|
||||
"decl %1\n\t"
|
||||
"decl %1\n\t"
|
||||
"decl %1\n\t"
|
||||
"cmpw $0,(%1)\n\t"
|
||||
"je 5f\n\t"
|
||||
"movw $0,(%1)\n\t"
|
||||
"incl %1\n\t"
|
||||
"incl %1\n\t"
|
||||
"jmp 6f\n"
|
||||
"5:\txorl %1,%1\n"
|
||||
"6:\tcmpw $0,(%0)\n\t"
|
||||
"jne 7f\n\t"
|
||||
"xorl %0,%0\n"
|
||||
"7:\ttestl %0,%0\n\t"
|
||||
"jne 8f\n\t"
|
||||
"movl %0,%1\n"
|
||||
"8:"
|
||||
:"=b" (__res),"=S" (___wcstok)
|
||||
:"0" (___wcstok),"1" (s),"g" (ct)
|
||||
:"eax","ecx","edx","edi","memory");
|
||||
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSNNLEN
|
||||
inline size_t wcsnlen(const wchar_t * s, size_t count)
|
||||
{
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"movl %1,%0\n\t"
|
||||
"jmp 2f\n"
|
||||
"1:\tcmpw $0,(%0)\n\t"
|
||||
"je 3f\n\t"
|
||||
"incl %0\n"
|
||||
"2:\tdecl %2\n\t"
|
||||
"cmpl $-1,%2\n\t"
|
||||
"jne 1b\n"
|
||||
"3:\tsubl %1,%0"
|
||||
:"=a" (__res)
|
||||
:"c" (s),"d" (count)
|
||||
:"edx");
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSICMP
|
||||
inline int wcsicmp(const wchar_t* cs,const wchar_t * ct)
|
||||
{
|
||||
register int __res;
|
||||
|
||||
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\tmovw (%%esi), %%eax\n\t"
|
||||
"movw (%%edi), %%edx \n\t"
|
||||
"cmpw $0x5A, %%eax\n\t"
|
||||
"ja 2f\t\n"
|
||||
"cmpw $0x40, %%eax\t\n"
|
||||
"jbe 2f\t\n"
|
||||
"addw $0x20, %%eax\t\n"
|
||||
"2:\t cmpw $0x5A, %%edx\t\n"
|
||||
"ja 3f\t\n"
|
||||
"cmpw $0x40, %%edx\t\n"
|
||||
"jbe 3f\t\n"
|
||||
"addw $0x20, %%edx\t\n"
|
||||
"3:\t inc %%esi\t\n"
|
||||
"inc %%esi\t\n"
|
||||
"inc %%edi\t\n"
|
||||
"inc %%edi\t\n"
|
||||
"cmpw %%eax, %%edx\t\n"
|
||||
"jne 4f\n\t"
|
||||
"cmpw $00, %%eax\n\t"
|
||||
"jne 1b\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"jmp 5f\n"
|
||||
"4:\tsbbl %%eax,%%eax\n\t"
|
||||
"orw $1,%%eax\n"
|
||||
"5:"
|
||||
:"=a" (__res):"S" (cs),"D" (ct):"esi","edi");
|
||||
|
||||
return __res;
|
||||
}
|
||||
|
||||
|
||||
#define __HAVE_ARCH_WCSNICMP
|
||||
inline int wcsnicmp(const wchar_t* cs,const wchar_t * ct, size_t count)
|
||||
{
|
||||
register int __res;
|
||||
|
||||
|
||||
__asm__ __volatile__(
|
||||
"cld\n"
|
||||
"1:\t decl %3\n\t"
|
||||
"js 6f\n\t"
|
||||
"movw (%%esi), %%eax\n\t"
|
||||
"movw (%%edi), %%edx \n\t"
|
||||
"cmpw $0x5A, %%eax\n\t"
|
||||
"ja 2f\t\n"
|
||||
"cmpw $0x40, %%eax\t\n"
|
||||
"jbe 2f\t\n"
|
||||
"addw $0x20, %%eax\t\n"
|
||||
"2:\t cmpw $0x5A, %%edx\t\n"
|
||||
"ja 3f\t\n"
|
||||
"cmpw $0x40, %%edx\t\n"
|
||||
"jbe 3f\t\n"
|
||||
"addw $0x20, %%edx\t\n"
|
||||
"3:\t inc %%esi\t\n"
|
||||
"inc %%esi\t\n"
|
||||
"inc %%edi\t\n"
|
||||
"inc %%edi\t\n"
|
||||
"cmpw %%eax, %%edx\t\n"
|
||||
"jne 4f\n\t"
|
||||
"cmpw $00, %%eax\n\t"
|
||||
"jne 1b\n\t"
|
||||
"6:xorl %%eax,%%eax\n\t"
|
||||
"jmp 5f\n"
|
||||
"4:\tsbbl %%eax,%%eax\n\t"
|
||||
"orw $1,%%eax\n"
|
||||
"5:"
|
||||
:"=a" (__res):"S" (cs),"D" (ct), "c" (count):"esi","edi", "ecx");
|
||||
|
||||
|
||||
return __res;
|
||||
}
|
||||
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
BIN
reactos/lib/ntdll/genntdll
Normal file
BIN
reactos/lib/ntdll/genntdll
Normal file
Binary file not shown.
@@ -27,12 +27,9 @@
|
||||
;
|
||||
; $Logfile: C:/dos-c/src/boot/boot.asv $
|
||||
;
|
||||
; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.asm,v 1.3 1998/08/25 04:37:43 rex Exp $
|
||||
; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.asm,v 1.1.1.2 1998/08/25 04:27:38 rex Exp $
|
||||
;
|
||||
; $Log: boot.asm,v $
|
||||
; Revision 1.3 1998/08/25 04:37:43 rex
|
||||
; new release cleanup
|
||||
;
|
||||
; Revision 1.1.1.2 1998/08/25 04:27:38 rex
|
||||
; A much Needed Update
|
||||
;
|
||||
@@ -289,3 +286,6 @@ filename db "KERNEL BIN"
|
||||
sign dw 0aa55h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
640
reactos/loaders/boot/boot.lst
Normal file
640
reactos/loaders/boot/boot.lst
Normal file
@@ -0,0 +1,640 @@
|
||||
1 ;
|
||||
2 ; File:
|
||||
3 ; boot.asm
|
||||
4 ; Description:
|
||||
5 ; DOS-C boot
|
||||
6 ;
|
||||
7 ; Copyright (c) 1997;
|
||||
8 ; Svante Frey
|
||||
9 ; All Rights Reserved
|
||||
10 ;
|
||||
11 ; This file is part of DOS-C.
|
||||
12 ;
|
||||
13 ; DOS-C is free software; you can redistribute it and/or
|
||||
14 ; modify it under the terms of the GNU General Public License
|
||||
15 ; as published by the Free Software Foundation; either version
|
||||
16 ; 2, or (at your option) any later version.
|
||||
17 ;
|
||||
18 ; DOS-C is distributed in the hope that it will be useful, but
|
||||
19 ; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
21 ; the GNU General Public License for more details.
|
||||
22 ;
|
||||
23 ; You should have received a copy of the GNU General Public
|
||||
24 ; License along with DOS-C; see the file COPYING. If not,
|
||||
25 ; write to the Free Software Foundation, 675 Mass Ave,
|
||||
26 ; Cambridge, MA 02139, USA.
|
||||
27 ;
|
||||
28 ; $Logfile: C:/dos-c/src/boot/boot.asv $
|
||||
29 ;
|
||||
30 ; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.lst,v 1.1.1.2 1998/08/25 04:27:38 rex Exp $
|
||||
31 ;
|
||||
32 ; $Log: boot.lst,v $
|
||||
32 ; Revision 1.1.1.2 1998/08/25 04:27:38 rex
|
||||
32 ; A much Needed Update
|
||||
32 ;
|
||||
33 ;
|
||||
34 ; Rev 1.5 10 Jan 1997 4:58:06 patv
|
||||
35 ; Corrected copyright
|
||||
36 ;
|
||||
37 ; Rev 1.4 10 Jan 1997 4:52:50 patv
|
||||
38 ; Re-written to support C drive and eliminate restrictions on IPL.SYS
|
||||
39 ;
|
||||
40 ; Rev 1.3 29 Aug 1996 13:06:50 patv
|
||||
41 ; Bug fixes for v0.91b
|
||||
42 ;
|
||||
43 ; Rev 1.2 01 Sep 1995 17:56:44 patv
|
||||
44 ; First GPL release.
|
||||
45 ;
|
||||
46 ; Rev 1.1 30 Jul 1995 20:37:38 patv
|
||||
47 ; Initialized stack before use.
|
||||
48 ;
|
||||
49 ; Rev 1.0 02 Jul 1995 10:57:52 patv
|
||||
50 ; Initial revision.
|
||||
51 ;
|
||||
52
|
||||
53 section .text
|
||||
54
|
||||
55 org 0
|
||||
56 00000000 E93D00 Entry: jmp real_start
|
||||
57
|
||||
58 ; bp is initialized to 7c00h
|
||||
59 %define oem [bp+3]
|
||||
60 %define bytesPerSector [bp+0bh]
|
||||
61 %define sectPerCluster [bp+0dh]
|
||||
62 %define resSectors [bp+0eh]
|
||||
63 %define nFats [bp+10h]
|
||||
64 %define nRootDir [bp+11h]
|
||||
65 %define nSectors [bp+13h]
|
||||
66 %define MID [bp+15h]
|
||||
67 %define sectPerFat [bp+16h]
|
||||
68 %define sectPerTrack [bp+18h]
|
||||
69 %define nHeads [bp+1ah]
|
||||
70 %define nHidden [bp+1ch]
|
||||
71 %define nHidden_hi [bp+1eh]
|
||||
72 %define nSectorHuge [bp+20h]
|
||||
73 %define drive [bp+24h]
|
||||
74 %define extBoot [bp+26h]
|
||||
75 %define volid [bp+27h]
|
||||
76 %define vollabel [bp+2bh]
|
||||
77 %define filesys 36h
|
||||
78
|
||||
79 LOADSEG equ 2000h
|
||||
80
|
||||
81 FATBUF equ 4000h ; offset of temporary buffer for FAT
|
||||
82 ; chain
|
||||
83 RETRYCOUNT equ 5 ; number of retries on disk errors
|
||||
84
|
||||
85 ; Some extra variables that are created on the stack frame
|
||||
86
|
||||
87 %define fat_start [bp-4] ; first FAT sector
|
||||
88 %define fat_start_hi [bp-2]
|
||||
89 %define root_dir_start [bp-8] ; first root directory sector
|
||||
90 %define root_dir_start_hi [bp-6]
|
||||
91 %define data_start [bp-12] ; first data sector
|
||||
92 %define data_start_hi [bp-10]
|
||||
93
|
||||
94 ;
|
||||
95 ; Include macros for filesystem access
|
||||
96 ;
|
||||
97 %include "boot.inc"
|
||||
98 <1> ; To save space, functions that are just called once are
|
||||
99 <1> ; implemented as macros instead. Four bytes are saved by
|
||||
100 <1> ; avoiding the call / ret instructions.
|
||||
101 <1>
|
||||
102 <1>
|
||||
103 <1> ; FINDFILE: Searches for the file in the root directory.
|
||||
104 <1> ;
|
||||
105 <1> ; Returns:
|
||||
106 <1> ;
|
||||
107 <1> ; If file not found: CF set
|
||||
108 <1> ;
|
||||
109 <1> ; If file found: CF clear
|
||||
110 <1> ; AX = first cluster of file
|
||||
111 <1>
|
||||
112 <1>
|
||||
113 <1> %macro FINDFILE 0
|
||||
114 <1> ; First, read the whole root directory
|
||||
115 <1> ; into the temporary buffer.
|
||||
116 <1>
|
||||
117 <1> mov ax, word root_dir_start
|
||||
118 <1> mov dx, word root_dir_start_hi
|
||||
119 <1> mov di, nRootDir
|
||||
120 <1> xor bx, bx
|
||||
121 <1> mov es, tempbuf
|
||||
122 <1> call readDisk
|
||||
123 <1> jc ffDone
|
||||
124 <1>
|
||||
125 <1> xor di, di
|
||||
126 <1>
|
||||
127 <1> next_entry: mov cx, 11
|
||||
128 <1> mov si, filename+7c00h
|
||||
129 <1> push di
|
||||
130 <1> repe cmpsb
|
||||
131 <1> pop di
|
||||
132 <1> mov ax, [es:di+1ah] ; get cluster number from directory entry
|
||||
133 <1> clc
|
||||
134 <1> je ffDone
|
||||
135 <1>
|
||||
136 <1> add di, 20h ; go to next directory entry
|
||||
137 <1> cmp byte [es:di], 0 ; if the first byte of the name is 0,
|
||||
138 <1> jnz next_entry ; there is no more files in the directory
|
||||
139 <1>
|
||||
140 <1> stc
|
||||
141 <1> ffDone:
|
||||
142 <1> %endmacro
|
||||
143 <1>
|
||||
144 <1> ; GETDRIVEPARMS: Calculate start of some disk areas.
|
||||
145 <1>
|
||||
146 <1> %macro GETDRIVEPARMS 0
|
||||
147 <1> mov si, word nHidden
|
||||
148 <1> mov di, word nHidden_hi
|
||||
149 <1> add si, word resSectors
|
||||
150 <1> adc di, 0 ; DI:SI = first FAT sector
|
||||
151 <1>
|
||||
152 <1> mov word fat_start, si
|
||||
153 <1> mov word fat_start_hi, di
|
||||
154 <1>
|
||||
155 <1> mov al, nFats
|
||||
156 <1> xor ah, ah
|
||||
157 <1> mul word sectPerFat ; DX:AX = total number of FAT sectors
|
||||
158 <1>
|
||||
159 <1> add si, ax
|
||||
160 <1> adc di, dx ; DI:SI = first root directory sector
|
||||
161 <1> mov word root_dir_start, si
|
||||
162 <1> mov word root_dir_start_hi, di
|
||||
163 <1>
|
||||
164 <1> ; Calculate how many sectors the root directory occupies.
|
||||
165 <1> mov bx, bytesPerSector
|
||||
166 <1> mov cl, 5 ; divide BX by 32
|
||||
167 <1> shr bx, cl ; BX = directory entries per sector
|
||||
168 <1>
|
||||
169 <1> mov ax, nRootDir
|
||||
170 <1> xor dx, dx
|
||||
171 <1> div bx
|
||||
172 <1>
|
||||
173 <1> mov nRootDir, ax ; AX = sectors per root directory
|
||||
174 <1>
|
||||
175 <1> add si, ax
|
||||
176 <1> adc di, 0 ; DI:SI = first data sector
|
||||
177 <1>
|
||||
178 <1> mov data_start, si
|
||||
179 <1> mov data_start_hi, di
|
||||
180 <1> %endmacro
|
||||
181 <1>
|
||||
182 <1> ; GETFATCHAIN:
|
||||
183 <1> ;
|
||||
184 <1> ; Reads the FAT chain and stores it in a temporary buffer in the first
|
||||
185 <1> ; 64 kb. The FAT chain is stored an array of 16-bit cluster numbers,
|
||||
186 <1> ; ending with 0.
|
||||
187 <1> ;
|
||||
188 <1> ; The file must fit in conventional memory, so it can't be larger than
|
||||
189 <1> ; 640 kb. The sector size must be at least 512 bytes, so the FAT chain
|
||||
190 <1> ; can't be larger than around 3 kb.
|
||||
191 <1> ;
|
||||
192 <1> ; Call with: AX = first cluster in chain
|
||||
193 <1> ;
|
||||
194 <1> ; Returns: CF clear on success, set on error
|
||||
195 <1>
|
||||
196 <1> %macro GETFATCHAIN 0
|
||||
197 <1> push ax ; store first cluster number
|
||||
198 <1>
|
||||
199 <1> ; Load the complete FAT into memory. The FAT can't be larger
|
||||
200 <1> ; than 128 kb, so it should fit in the temporary buffer.
|
||||
201 <1>
|
||||
202 <1> mov es, tempbuf
|
||||
203 <1> xor bx, bx
|
||||
204 <1> mov di, sectPerFat
|
||||
205 <1> mov ax, word fat_start
|
||||
206 <1> mov dx, word fat_start_hi
|
||||
207 <1> call readDisk
|
||||
208 <1> pop ax ; restore first cluster number
|
||||
209 <1> jc boot_error
|
||||
210 <1>
|
||||
211 <1> ; Set ES:DI to the temporary storage for the FAT chain.
|
||||
212 <1> push ds
|
||||
213 <1> push es
|
||||
214 <1> pop ds
|
||||
215 <1> pop es
|
||||
216 <1> mov di, FATBUF
|
||||
217 <1>
|
||||
218 <1> next_clust: stosw ; store cluster number
|
||||
219 <1> mov si, ax ; SI = cluster number
|
||||
220 <1> cmp byte extBoot, 29h
|
||||
221 <1> jne fat_12
|
||||
222 <1> cmp byte [bp+filesys+4], '6' ; check for FAT-16 system
|
||||
223 <1> je fat_16
|
||||
224 <1>
|
||||
225 <1> ; This is a FAT-12 disk.
|
||||
226 <1>
|
||||
227 <1> fat_12: add si, si ; multiply cluster number by 3...
|
||||
228 <1> add si, ax
|
||||
229 <1> shr si, 1 ; ...and divide by 2
|
||||
230 <1> lodsw
|
||||
231 <1>
|
||||
232 <1> ; If the cluster number was even, the cluster value is now in
|
||||
233 <1> ; bits 0-11 of AX. If the cluster number was odd, the cluster
|
||||
234 <1> ; value is in bits 4-15, and must be shifted right 4 bits. If
|
||||
235 <1> ; the number was odd, CF was set in the last shift instruction.
|
||||
236 <1>
|
||||
237 <1> jnc fat_even
|
||||
238 <1> mov cl, 4
|
||||
239 <1> shr ax, cl ; shift the cluster number
|
||||
240 <1>
|
||||
241 <1> fat_even: and ah, 0fh ; mask off the highest 4 bits
|
||||
242 <1> cmp ax, 0fffh ; check for EOF
|
||||
243 <1> jmp short next_test
|
||||
244 <1>
|
||||
245 <1> ; This is a FAT-16 disk. The maximal size of a 16-bit FAT
|
||||
246 <1> ; is 128 kb, so it may not fit within a single 64 kb segment.
|
||||
247 <1>
|
||||
248 <1> fat_16: mov dx, tempbuf
|
||||
249 <1> add si, si ; multiply cluster number by two
|
||||
250 <1> jnc first_half ; if overflow...
|
||||
251 <1> add dh, 10h ; ...add 64 kb to segment value
|
||||
252 <1>
|
||||
253 <1> first_half: mov ds, dx ; DS:SI = pointer to next cluster
|
||||
254 <1> lodsw ; AX = next cluster
|
||||
255 <1>
|
||||
256 <1> cmp ax, 0fff8h ; >= FFF8 = 16-bit EOF
|
||||
257 <1> next_test: jb next_clust ; continue if not EOF
|
||||
258 <1>
|
||||
259 <1> finished: ; Mark end of FAT chain with 0, so we have a single
|
||||
260 <1> ; EOF marker for both FAT-12 and FAT-16 systems.
|
||||
261 <1>
|
||||
262 <1> xor ax, ax
|
||||
263 <1> stosw
|
||||
264 <1> fatError:
|
||||
265 <1> %endmacro
|
||||
266 <1>
|
||||
267 <1>
|
||||
268 <1> ; loadFile: Loads the file into memory, one cluster at a time.
|
||||
269 <1>
|
||||
270 <1> %macro LOADFILE 0
|
||||
271 <1> mov es, tempbuf ; set ES:BX to load address
|
||||
272 <1> xor bx, bx
|
||||
273 <1>
|
||||
274 <1> mov si, FATBUF ; set DS:SI to the FAT chain
|
||||
275 <1> push cs
|
||||
276 <1> pop ds
|
||||
277 <1>
|
||||
278 <1> next_cluster: lodsw ; AX = next cluster to read
|
||||
279 <1> or ax, ax ; if EOF...
|
||||
280 <1> je boot_success ; ...boot was successful
|
||||
281 <1>
|
||||
282 <1> dec ax ; cluster numbers start with 2
|
||||
283 <1> dec ax
|
||||
284 <1>
|
||||
285 <1> mov di, word sectPerCluster
|
||||
286 <1> and di, 0ffh ; DI = sectors per cluster
|
||||
287 <1> mul di
|
||||
288 <1> add ax, data_start
|
||||
289 <1> adc dx, data_start_hi ; DX:AX = first sector to read
|
||||
290 <1> call readDisk
|
||||
291 <1> jnc next_cluster
|
||||
292 <1>
|
||||
293 <1> %endmacro
|
||||
294
|
||||
295 ;
|
||||
296 ;
|
||||
297 ;
|
||||
298 00000003 00<rept> TIMES 3eh-($-$$) DB 0
|
||||
299
|
||||
300 %define tempbuf [bp+3eh]
|
||||
301 0000003E 0020 load_seg dw LOADSEG
|
||||
302
|
||||
303 00000040 FA real_start: cli
|
||||
304 00000041 FC cld
|
||||
305 00000042 8CC8 mov ax, cs
|
||||
306 00000044 8ED0 mov ss, ax ; initialize stack
|
||||
307 00000046 BD007C mov bp, 7c00h
|
||||
308 00000049 8D66E0 lea sp, [bp-20h]
|
||||
309 0000004C FB sti
|
||||
310
|
||||
311 0000004D 8EC0 mov es, ax
|
||||
312 0000004F 8ED8 mov ds, ax
|
||||
313 00000051 885624 mov drive, dl ; BIOS passes drive number in DL
|
||||
314
|
||||
315 GETDRIVEPARMS
|
||||
316 00000054 8B761C <1> mov si, word nHidden
|
||||
317 00000057 8B7E1E <1> mov di, word nHidden_hi
|
||||
318 0000005A 03760E <1> add si, word resSectors
|
||||
319 0000005D 81D70000 <1> adc di, 0
|
||||
320 <1>
|
||||
321 00000061 8976FC <1> mov word fat_start, si
|
||||
322 00000064 897EFE <1> mov word fat_start_hi, di
|
||||
323 <1>
|
||||
324 00000067 8A4610 <1> mov al, nFats
|
||||
325 0000006A 30E4 <1> xor ah, ah
|
||||
326 0000006C F76616 <1> mul word sectPerFat
|
||||
327 <1>
|
||||
328 0000006F 01C6 <1> add si, ax
|
||||
329 00000071 11D7 <1> adc di, dx
|
||||
330 00000073 8976F8 <1> mov word root_dir_start, si
|
||||
331 00000076 897EFA <1> mov word root_dir_start_hi, di
|
||||
332 <1>
|
||||
333 <1>
|
||||
334 00000079 8B5E0B <1> mov bx, bytesPerSector
|
||||
335 0000007C B105 <1> mov cl, 5
|
||||
336 0000007E D3EB <1> shr bx, cl
|
||||
337 <1>
|
||||
338 00000080 8B4611 <1> mov ax, nRootDir
|
||||
339 00000083 31D2 <1> xor dx, dx
|
||||
340 00000085 F7F3 <1> div bx
|
||||
341 <1>
|
||||
342 00000087 894611 <1> mov nRootDir, ax
|
||||
343 <1>
|
||||
344 0000008A 01C6 <1> add si, ax
|
||||
345 0000008C 81D70000 <1> adc di, 0
|
||||
346 <1>
|
||||
347 00000090 8976F4 <1> mov data_start, si
|
||||
348 00000093 897EF6 <1> mov data_start_hi, di
|
||||
349
|
||||
350 FINDFILE ; locate file in root directory
|
||||
351 <1>
|
||||
352 <1>
|
||||
353 <1>
|
||||
354 00000096 8B46F8 <1> mov ax, word root_dir_start
|
||||
355 00000099 8B56FA <1> mov dx, word root_dir_start_hi
|
||||
356 0000009C 8B7E11 <1> mov di, nRootDir
|
||||
357 0000009F 31DB <1> xor bx, bx
|
||||
358 000000A1 8E463E <1> mov es, tempbuf
|
||||
359 000000A4 E8B900 <1> call readDisk
|
||||
360 000000A7 721E <1> jc ffDone
|
||||
361 <1>
|
||||
362 000000A9 31FF <1> xor di, di
|
||||
363 <1>
|
||||
364 000000AB B90B00 <1> next_entry: mov cx, 11
|
||||
365 000000AE BE[F17D] <1> mov si, filename+7c00h
|
||||
366 000000B1 57 <1> push di
|
||||
367 000000B2 F3A6 <1> repe cmpsb
|
||||
368 000000B4 5F <1> pop di
|
||||
369 000000B5 268B451A <1> mov ax, [es:di+1ah]
|
||||
370 000000B9 F8 <1> clc
|
||||
371 000000BA 740B <1> je ffDone
|
||||
372 <1>
|
||||
373 000000BC 81C72000 <1> add di, 20h
|
||||
374 000000C0 26803D00 <1> cmp byte [es:di], 0
|
||||
375 000000C4 75E5 <1> jnz next_entry
|
||||
376 <1>
|
||||
377 000000C6 F9 <1> stc
|
||||
378 <1> ffDone:
|
||||
379 000000C7 727A jc boot_error ; fail if not found
|
||||
380
|
||||
381 GETFATCHAIN ; read FAT chain
|
||||
382 000000C9 50 <1> push ax
|
||||
383 <1>
|
||||
384 <1>
|
||||
385 <1>
|
||||
386 <1>
|
||||
387 000000CA 8E463E <1> mov es, tempbuf
|
||||
388 000000CD 31DB <1> xor bx, bx
|
||||
389 000000CF 8B7E16 <1> mov di, sectPerFat
|
||||
390 000000D2 8B46FC <1> mov ax, word fat_start
|
||||
391 000000D5 8B56FE <1> mov dx, word fat_start_hi
|
||||
392 000000D8 E88500 <1> call readDisk
|
||||
393 000000DB 58 <1> pop ax
|
||||
394 000000DC 7265 <1> jc boot_error
|
||||
395 <1>
|
||||
396 <1>
|
||||
397 000000DE 1E <1> push ds
|
||||
398 000000DF 06 <1> push es
|
||||
399 000000E0 1F <1> pop ds
|
||||
400 000000E1 07 <1> pop es
|
||||
401 000000E2 BF0040 <1> mov di, FATBUF
|
||||
402 <1>
|
||||
403 000000E5 AB <1> next_clust: stosw
|
||||
404 000000E6 89C6 <1> mov si, ax
|
||||
405 000000E8 807E2629 <1> cmp byte extBoot, 29h
|
||||
406 000000EC 7506 <1> jne fat_12
|
||||
407 000000EE 807E3A36 <1> cmp byte [bp+filesys+4], '6'
|
||||
408 000000F2 7415 <1> je fat_16
|
||||
409 <1>
|
||||
410 <1>
|
||||
411 <1>
|
||||
412 000000F4 01F6 <1> fat_12: add si, si
|
||||
413 000000F6 01C6 <1> add si, ax
|
||||
414 000000F8 D1EE <1> shr si, 1
|
||||
415 000000FA AD <1> lodsw
|
||||
416 <1>
|
||||
417 <1>
|
||||
418 <1>
|
||||
419 <1>
|
||||
420 <1>
|
||||
421 <1>
|
||||
422 000000FB 7304 <1> jnc fat_even
|
||||
423 000000FD B104 <1> mov cl, 4
|
||||
424 000000FF D3E8 <1> shr ax, cl
|
||||
425 <1>
|
||||
426 00000101 80E40F <1> fat_even: and ah, 0fh
|
||||
427 00000104 3DFF0F <1> cmp ax, 0fffh
|
||||
428 00000107 EB10 <1> jmp short next_test
|
||||
429 <1>
|
||||
430 <1>
|
||||
431 <1>
|
||||
432 <1>
|
||||
433 00000109 8B563E <1> fat_16: mov dx, tempbuf
|
||||
434 0000010C 01F6 <1> add si, si
|
||||
435 0000010E 7303 <1> jnc first_half
|
||||
436 00000110 80C610 <1> add dh, 10h
|
||||
437 <1>
|
||||
438 00000113 8EDA <1> first_half: mov ds, dx
|
||||
439 00000115 AD <1> lodsw
|
||||
440 <1>
|
||||
441 00000116 3DF8FF <1> cmp ax, 0fff8h
|
||||
442 00000119 72CA <1> next_test: jb next_clust
|
||||
443 <1>
|
||||
444 <1> finished:
|
||||
445 <1>
|
||||
446 <1>
|
||||
447 0000011B 31C0 <1> xor ax, ax
|
||||
448 0000011D AB <1> stosw
|
||||
449 <1> fatError:
|
||||
450 LOADFILE ; load file (jumps to boot_sucess if successful)
|
||||
451 0000011E 8E463E <1> mov es, tempbuf
|
||||
452 00000121 31DB <1> xor bx, bx
|
||||
453 <1>
|
||||
454 00000123 BE0040 <1> mov si, FATBUF
|
||||
455 00000126 0E <1> push cs
|
||||
456 00000127 1F <1> pop ds
|
||||
457 <1>
|
||||
458 00000128 AD <1> next_cluster: lodsw
|
||||
459 00000129 09C0 <1> or ax, ax
|
||||
460 0000012B 742B <1> je boot_success
|
||||
461 <1>
|
||||
462 0000012D 48 <1> dec ax
|
||||
463 0000012E 48 <1> dec ax
|
||||
464 <1>
|
||||
465 0000012F 8B7E0D <1> mov di, word sectPerCluster
|
||||
466 00000132 81E7FF00 <1> and di, 0ffh
|
||||
467 00000136 F7E7 <1> mul di
|
||||
468 00000138 0346F4 <1> add ax, data_start
|
||||
469 0000013B 1356F6 <1> adc dx, data_start_hi
|
||||
470 0000013E E81F00 <1> call readDisk
|
||||
471 00000141 73E5 <1> jnc next_cluster
|
||||
472 <1>
|
||||
473
|
||||
474 00000143 B90A00 boot_error: mov cx, ERRMSGLEN
|
||||
475 00000146 BE[E77D] mov si, errmsg+7c00h
|
||||
476
|
||||
477 00000149 AC next_char: lodsb ; print error message
|
||||
478 0000014A B40E mov ah, 0eh
|
||||
479 0000014C 30FF xor bh, bh
|
||||
480 0000014E CD10 int 10h
|
||||
481 00000150 E2F7 loop next_char
|
||||
482
|
||||
483 00000152 30E4 xor ah, ah
|
||||
484 00000154 CD16 int 16h ; wait for keystroke
|
||||
485 00000156 CD19 int 19h ; invoke bootstrap loader
|
||||
486
|
||||
487 00000158 8A5624 boot_success: mov dl, drive
|
||||
488
|
||||
489 0000015B EA db 0eah ; far jump to LOADSEG:0000
|
||||
490 0000015C 0000 dw 0
|
||||
491 0000015E 0020 dw LOADSEG
|
||||
492
|
||||
493
|
||||
494 ; readDisk: Reads a number of sectors into memory.
|
||||
495 ;
|
||||
496 ; Call with: DX:AX = 32-bit DOS sector number
|
||||
497 ; DI = number of sectors to read
|
||||
498 ; ES:BX = destination buffer
|
||||
499 ; ES must be 64k aligned (1000h, 2000h etc).
|
||||
500 ;
|
||||
501 ; Returns: CF set on error
|
||||
502 ; ES:BX points one byte after the last byte read.
|
||||
503
|
||||
504 readDisk:
|
||||
505 00000160 56 push si
|
||||
506 00000161 52 read_next: push dx
|
||||
507 00000162 50 push ax
|
||||
508
|
||||
509 ;
|
||||
510 ; translate sector number to BIOS parameters
|
||||
511 ;
|
||||
512
|
||||
513 ;
|
||||
514 ; abs = sector offset in track
|
||||
515 ; + head * sectPerTrack offset in cylinder
|
||||
516 ; + track * sectPerTrack * nHeads offset in platter
|
||||
517 ;
|
||||
518 ; t1 = abs / sectPerTrack (ax has t1)
|
||||
519 ; sector = abs mod sectPerTrack (cx has sector)
|
||||
520 ;
|
||||
521 00000163 F77618 div word sectPerTrack
|
||||
522 00000166 89D1 mov cx, dx
|
||||
523
|
||||
524 ;
|
||||
525 ; t1 = head + track * nHeads
|
||||
526 ;
|
||||
527 ; track = t1 / nHeads (ax has track)
|
||||
528 ; head = t1 mod nHeads (dl has head)
|
||||
529 ;
|
||||
530 00000168 31D2 xor dx, dx
|
||||
531 0000016A F7761A div word nHeads
|
||||
532
|
||||
533 ; the following manipulations are necessary in order to
|
||||
534 ; properly place parameters into registers.
|
||||
535 ; ch = cylinder number low 8 bits
|
||||
536 ; cl = 7-6: cylinder high two bits
|
||||
537 ; 5-0: sector
|
||||
538 0000016D 88D6 mov dh, dl ; save head into dh for bios
|
||||
539 0000016F D0CC ror ah, 1 ; move track high bits into
|
||||
540 00000171 D0CC ror ah, 1 ; bits 7-6 (assumes top = 0)
|
||||
541 00000173 86C4 xchg al, ah ; swap for later
|
||||
542 00000175 8A5618 mov dl, byte sectPerTrack
|
||||
543 00000178 28CA sub dl, cl
|
||||
544 0000017A FEC1 inc cl ; sector offset from 1
|
||||
545 0000017C 09C1 or cx, ax ; merge cylinder into sector
|
||||
546 0000017E 88D0 mov al, dl ; al has # of sectors left
|
||||
547
|
||||
548 ; Calculate how many sectors can be transfered in this read
|
||||
549 ; due to dma boundary conditions.
|
||||
550 00000180 52 push dx
|
||||
551
|
||||
552 00000181 89FE mov si, di ; temp register save
|
||||
553 ; this computes remaining bytes because of modulo 65536
|
||||
554 ; nature of dma boundary condition
|
||||
555 00000183 89D8 mov ax, bx ; get offset pointer
|
||||
556 00000185 F7D8 neg ax ; and convert to bytes
|
||||
557 00000187 740B jz ax_min_1 ; started at seg:0, skip ahead
|
||||
558
|
||||
559 00000189 31D2 xor dx, dx ; convert to sectors
|
||||
560 0000018B F7760B div word bytesPerSector
|
||||
561
|
||||
562 0000018E 39F8 cmp ax, di ; check remainder vs. asked
|
||||
563 00000190 7202 jb ax_min_1 ; less, skip ahead
|
||||
564 00000192 89C6 mov si, ax ; transfer only what we can
|
||||
565
|
||||
566 00000194 5A ax_min_1: pop dx
|
||||
567
|
||||
568 ; Check that request sectors do not exceed track boundary
|
||||
569 00000195 8B7618 mov si, sectPerTrack
|
||||
570 00000198 46 inc si
|
||||
571 00000199 89C8 mov ax, cx ; get the sector/cyl byte
|
||||
572 0000019B 253F00 and ax, 03fh ; and mask out sector
|
||||
573 0000019E 29C6 sub si, ax ; si has how many we can read
|
||||
574 000001A0 89F8 mov ax, di
|
||||
575 000001A2 39FE cmp si, di ; see if asked <= available
|
||||
576 000001A4 7D02 jge ax_min_2
|
||||
577 000001A6 89F0 mov ax, si ; get what can be xfered
|
||||
578
|
||||
579 000001A8 BE0500 ax_min_2: mov si, RETRYCOUNT
|
||||
580 000001AB B402 mov ah, 2
|
||||
581 000001AD 8A5624 mov dl, drive
|
||||
582
|
||||
583 000001B0 50 retry: push ax
|
||||
584 000001B1 CD13 int 13h
|
||||
585 000001B3 58 pop ax
|
||||
586 000001B4 7310 jnc read_ok
|
||||
587 000001B6 50 push ax
|
||||
588 000001B7 31C0 xor ax, ax ; reset the drive
|
||||
589 000001B9 CD13 int 13h
|
||||
590 000001BB 58 pop ax
|
||||
591 000001BC 4E dec si
|
||||
592 000001BD 75F1 jnz retry
|
||||
593 000001BF F9 stc
|
||||
594 000001C0 58 pop ax
|
||||
595 000001C1 5A pop dx
|
||||
596 000001C2 5E pop si
|
||||
597 000001C3 C3 ret
|
||||
598
|
||||
599 000001C4 EB9B read_next_jmp: jmp short read_next
|
||||
600 000001C6 30E4 read_ok: xor ah, ah
|
||||
601 000001C8 89C6 mov si, ax ; AX = SI = number of sectors read
|
||||
602 000001CA F7660B mul word bytesPerSector ; AX = number of bytes read
|
||||
603 000001CD 01C3 add bx, ax ; add number of bytes read to BX
|
||||
604 000001CF 7307 jnc no_incr_es ; if overflow...
|
||||
605
|
||||
606 000001D1 8CC0 mov ax, es
|
||||
607 000001D3 80C410 add ah, 10h ; ...add 1000h to ES
|
||||
608 000001D6 8EC0 mov es, ax
|
||||
609
|
||||
610 000001D8 58 no_incr_es: pop ax
|
||||
611 000001D9 5A pop dx ; DX:AX = last sector number
|
||||
612
|
||||
613 000001DA 01F0 add ax, si
|
||||
614 000001DC 81D20000 adc dx, 0 ; DX:AX = next sector to read
|
||||
615 000001E0 29F7 sub di, si ; if there is anything left to read,
|
||||
616 000001E2 7FE0 jg read_next_jmp ; continue
|
||||
617
|
||||
618 000001E4 F8 clc
|
||||
619 000001E5 5E pop si
|
||||
620 000001E6 C3 ret
|
||||
621
|
||||
622 000001E7 426F6F74206572726F- errmsg db "Boot error"
|
||||
623 000001F0 72
|
||||
624 ERRMSGLEN equ $ - errmsg
|
||||
625
|
||||
626
|
||||
627 ;filename db "OSLDR BIN"
|
||||
628 000001F1 4B45524E454C202042- filename db "KERNEL BIN"
|
||||
629 000001FA 494E
|
||||
630
|
||||
631 000001FC 00<rept> TIMES 510-($-$$) DB 0
|
||||
632 000001FE 55AA sign dw 0aa55h
|
||||
633
|
||||
634
|
||||
635
|
||||
636
|
||||
637
|
@@ -1,12 +1,9 @@
|
||||
#
|
||||
# makefile for DOS-C boot
|
||||
#
|
||||
# $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.mak,v 1.3 1998/08/25 04:39:40 rex Exp $
|
||||
# $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/boot.mak,v 1.1.1.2 1998/08/25 04:27:38 rex Exp $
|
||||
#
|
||||
# $Log: boot.mak,v $
|
||||
# Revision 1.3 1998/08/25 04:39:40 rex
|
||||
# Release cleanup
|
||||
#
|
||||
# Revision 1.1.1.2 1998/08/25 04:27:38 rex
|
||||
# A much Needed Update
|
||||
#
|
||||
@@ -56,4 +53,3 @@ clean:
|
||||
del *.las
|
||||
del *.obj
|
||||
del *.exe
|
||||
|
||||
|
@@ -27,12 +27,9 @@
|
||||
;
|
||||
; $Logfile: C:/dos-c/src/boot/boot.asv $
|
||||
;
|
||||
; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/bootbk.asm,v 1.3 1998/08/25 04:40:47 rex Exp $
|
||||
; $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/loaders/boot/Attic/bootbk.asm,v 1.1.1.2 1998/08/25 04:27:38 rex Exp $
|
||||
;
|
||||
; $Log: bootbk.asm,v $
|
||||
; Revision 1.3 1998/08/25 04:40:47 rex
|
||||
; Release cleanup
|
||||
;
|
||||
; Revision 1.1.1.2 1998/08/25 04:27:38 rex
|
||||
; A much Needed Update
|
||||
;
|
||||
@@ -293,3 +290,5 @@ TEXT ENDS
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
reactos/loaders/dos/loadros.com
Normal file
BIN
reactos/loaders/dos/loadros.com
Normal file
Binary file not shown.
@@ -5,9 +5,9 @@
|
||||
#
|
||||
# Select your host
|
||||
#
|
||||
#HOST = djgpp-linux
|
||||
HOST = djgpp-linux
|
||||
#HOST = mingw32-linux
|
||||
HOST = djgpp-msdos
|
||||
#HOST = djgpp-msdos
|
||||
#HOST = mingw32-windows
|
||||
|
||||
include rules.mak
|
||||
@@ -30,15 +30,18 @@ LOADERS = dos
|
||||
#
|
||||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide
|
||||
KERNEL_SERVICES = parallel keyboard null mouse serial sound test
|
||||
|
||||
all: $(COMPONENTS) $(LOADERS) $(KERNEL_SERVICES)
|
||||
|
||||
#
|
||||
# Device driver rules
|
||||
#
|
||||
ide: dummy
|
||||
make -C services/ide
|
||||
test: dummy
|
||||
make -C services/test
|
||||
|
||||
test1: dummy
|
||||
make -C services/test1
|
||||
|
||||
null: dummy
|
||||
make -C services/null
|
||||
|
@@ -7,6 +7,8 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
free_page
|
||||
get_dma_page
|
||||
DbgPrint
|
||||
printk
|
||||
ExAcquireFastMutex
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel v0.0.2
|
||||
* FILE: hal/page.cc
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/page.c
|
||||
* PURPOSE: low level memory managment manipulation
|
||||
* PROGRAMER: David Welch
|
||||
* UPDATE HISTORY:
|
||||
|
@@ -232,7 +232,40 @@ int bad_user_access_length(void)
|
||||
|
||||
ULONG DbgPrint(PCH Format, ...)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
char buffer[256];
|
||||
char* str=buffer;
|
||||
va_list ap;
|
||||
unsigned int eflags;
|
||||
|
||||
/*
|
||||
* Because this is used by alomost every subsystem including irqs it
|
||||
* must be atomic. The following code sequence disables interrupts after
|
||||
* saving the previous state of the interrupt flag
|
||||
*/
|
||||
__asm__("pushf\n\tpop %0\n\tcli\n\t"
|
||||
: "=m" (eflags)
|
||||
: /* */);
|
||||
|
||||
/*
|
||||
* Process the format string into a fixed length buffer using the
|
||||
* standard C RTL function
|
||||
*/
|
||||
va_start(ap,Format);
|
||||
vsprintf(buffer,Format,ap);
|
||||
va_end(ap);
|
||||
|
||||
while ((*str)!=0)
|
||||
{
|
||||
putchar(*str);
|
||||
str++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the interrupt flag
|
||||
*/
|
||||
__asm__("push %0\n\tpopf\n\t"
|
||||
:
|
||||
: "m" (eflags));
|
||||
}
|
||||
|
||||
void InitConsole(boot_param* bp)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: mkernel/iomgr/create.cc
|
||||
* FILE: ntoskrnl/io/create.c
|
||||
* PURPOSE: Handling file create/open apis
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <internal/kernel.h>
|
||||
#include <internal/objmgr.h>
|
||||
#include <internal/iomgr.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
@@ -43,59 +44,54 @@ NTSTATUS ZwOpenFile(PHANDLE FileHandle,
|
||||
ULONG ShareAccess,
|
||||
ULONG OpenOptions)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
HANDLE STDCALL CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess,
|
||||
DWORD dwShareMode,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition,
|
||||
DWORD dwFlagsAndAttributes,
|
||||
HANDLE hTemplateFile)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
HANDLE hfile;
|
||||
UNICODE_STRING filename;
|
||||
ANSI_STRING afilename;
|
||||
KEVENT Event;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION StackLoc;
|
||||
|
||||
RtlInitAnsiString(&afilename,lpFileName);
|
||||
RtlAnsiStringToUnicodeString(&filename,&afilename,TRUE);
|
||||
DeviceObject = ObLookupObject(NULL,&filename);
|
||||
DPRINT("Sending IRP for IRP_MJ_CREATE to %x\n",DeviceObject);
|
||||
if (DeviceObject==NULL)
|
||||
{
|
||||
DPRINT("(%s:%d) Object not found\n",__FILE__,__LINE__);
|
||||
return(NULL);
|
||||
}
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
hfile = ObAddHandle(DeviceObject);
|
||||
*FileHandle=0;
|
||||
|
||||
/*
|
||||
* Tell the device we are openining it
|
||||
*/
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||
if (Irp==NULL)
|
||||
Status = ObOpenObjectByName(ObjectAttributes,&Object);
|
||||
DPRINT("Object %x Status %x\n",Object,Status);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(NULL);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DPRINT("Preparing IRP\n");
|
||||
DeviceObject = (PDEVICE_OBJECT)Object;
|
||||
|
||||
/*
|
||||
* Set up the stack location
|
||||
*/
|
||||
Irp->Stack[Irp->CurrentLocation].MajorFunction = IRP_MJ_CREATE;
|
||||
Irp->Stack[Irp->CurrentLocation].MinorFunction = 0;
|
||||
Irp->Stack[Irp->CurrentLocation].Flags = 0;
|
||||
Irp->Stack[Irp->CurrentLocation].Control = 0;
|
||||
Irp->Stack[Irp->CurrentLocation].DeviceObject = DeviceObject;
|
||||
// Irp->Stack[Irp->StackPtr].FileObject = &files[hfile];
|
||||
FileObject = ObGenericCreateObject(FileHandle,0,NULL,OBJTYP_FILE);
|
||||
DPRINT("FileObject %x DeviceObject %x\n",FileObject,DeviceObject);
|
||||
memset(FileObject,0,sizeof(FILE_OBJECT));
|
||||
FileObject->DeviceObject=DeviceObject;
|
||||
FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
|
||||
|
||||
DPRINT("Sending IRP\n");
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
StackLoc = IoGetNextIrpStackLocation(Irp);
|
||||
DPRINT("StackLoc %x\n",StackLoc);
|
||||
StackLoc->MajorFunction = IRP_MJ_CREATE;
|
||||
StackLoc->MinorFunction = 0;
|
||||
StackLoc->Flags = 0;
|
||||
StackLoc->Control = 0;
|
||||
StackLoc->DeviceObject = DeviceObject;
|
||||
StackLoc->FileObject=FileObject;
|
||||
DPRINT("DeviceObject %x\n",DeviceObject);
|
||||
DPRINT("DeviceObject->DriverObject %x\n",DeviceObject->DriverObject);
|
||||
IoCallDriver(DeviceObject,Irp);
|
||||
|
||||
DPRINT("Returning %x\n",hfile);
|
||||
return(hfile);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: mkernel/iomgr/device.cc
|
||||
* FILE: ntoskrnl/io/device.c
|
||||
* PURPOSE: Manage devices
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
@@ -22,6 +22,16 @@
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
NTSTATUS ZwLoadDriver(PUNICODE_STRING DriverServiceName)
|
||||
/*
|
||||
* FUNCTION: Loads a driver
|
||||
* ARGUMENTS:
|
||||
* DriverServiceName = Name of the service to load (registry key)
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
NTSTATUS IoAttachDeviceByPointer(PDEVICE_OBJECT SourceDevice,
|
||||
PDEVICE_OBJECT TargetDevice)
|
||||
{
|
||||
@@ -144,6 +154,9 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
||||
OBJECT_ATTRIBUTES dev_attr;
|
||||
HANDLE devh;
|
||||
|
||||
DPRINT("IoCreateDevice(DriverObject %x, DeviceName %w)\n",DriverObject,
|
||||
DeviceName->Buffer);
|
||||
|
||||
InitializeObjectAttributes(&dev_attr,DeviceName,0,NULL,NULL);
|
||||
dev = ObGenericCreateObject(&devh,0,&dev_attr,OBJTYP_DEVICE);
|
||||
|
||||
@@ -166,6 +179,9 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
||||
}
|
||||
|
||||
dev->DriverObject = DriverObject;
|
||||
DPRINT("dev %x\n",dev);
|
||||
DPRINT("dev->DriverObject %x\n",dev->DriverObject);
|
||||
|
||||
dev->CurrentIrp=NULL;
|
||||
dev->Flags=0;
|
||||
|
||||
@@ -181,6 +197,7 @@ NTSTATUS IoCreateDevice(PDRIVER_OBJECT DriverObject,
|
||||
dev->AlignmentRequirement=1;
|
||||
|
||||
*DeviceObject=dev;
|
||||
DPRINT("dev->DriverObject %x\n",dev->DriverObject);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
OBJECT_TYPE DeviceObjectType = {{NULL,0,0},
|
||||
OBJECT_TYPE DeviceObjectType = {{0,0,NULL},
|
||||
0,
|
||||
0,
|
||||
ULONG_MAX,
|
||||
@@ -34,6 +34,23 @@ OBJECT_TYPE DeviceObjectType = {{NULL,0,0},
|
||||
NULL,
|
||||
};
|
||||
|
||||
OBJECT_TYPE FileObjectType = {{0,0,NULL},
|
||||
0,
|
||||
0,
|
||||
ULONG_MAX,
|
||||
ULONG_MAX,
|
||||
sizeof(FILE_OBJECT),
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
@@ -44,12 +61,25 @@ VOID IoInit(VOID)
|
||||
UNICODE_STRING string;
|
||||
ANSI_STRING astring;
|
||||
|
||||
/*
|
||||
* Register iomgr types
|
||||
*/
|
||||
RtlInitAnsiString(&astring,"Device");
|
||||
RtlAnsiStringToUnicodeString(&DeviceObjectType.TypeName,&astring,TRUE);
|
||||
ObRegisterType(OBJTYP_DEVICE,&DeviceObjectType);
|
||||
|
||||
RtlInitAnsiString(&astring,"File");
|
||||
RtlAnsiStringToUnicodeString(&FileObjectType.TypeName,&astring,TRUE);
|
||||
ObRegisterType(OBJTYP_FILE,&FileObjectType);
|
||||
|
||||
/*
|
||||
* Create the device directory
|
||||
*/
|
||||
RtlInitAnsiString(&astring,"\\Device");
|
||||
RtlAnsiStringToUnicodeString(&string,&astring,TRUE);
|
||||
InitializeObjectAttributes(&attr,&string,0,NULL,NULL);
|
||||
ZwCreateDirectoryObject(&handle,0,&attr);
|
||||
|
||||
IoInitCancelHandling();
|
||||
IoInitSymbolicLinkImplementation();
|
||||
}
|
||||
|
@@ -89,8 +89,75 @@ PIRP IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
|
||||
ULONG Length,
|
||||
PLARGE_INTEGER StartingOffset,
|
||||
PIO_STATUS_BLOCK IoStatusBlock)
|
||||
/*
|
||||
* FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
|
||||
* ARGUMENTS:
|
||||
* MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
|
||||
* IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
|
||||
* DeviceObject = Device object to send the irp to
|
||||
* Buffer = Buffer into which data will be read or written
|
||||
* Length = Length in bytes of the irp to be allocated
|
||||
* StartingOffset = Starting offset on the device
|
||||
* IoStatusBlock (OUT) = Storage for the result of the operation
|
||||
* RETURNS: The IRP allocated on success, or
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Irp->UserBuffer = (LPVOID)Buffer;
|
||||
if (DeviceObject->Flags&DO_BUFFERED_IO)
|
||||
{
|
||||
DPRINT("Doing buffer i/o\n",0);
|
||||
Irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,Length);
|
||||
if (Irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
Irp->UserBuffer = NULL;
|
||||
}
|
||||
if (DeviceObject->Flags&DO_DIRECT_IO)
|
||||
{
|
||||
DPRINT("Doing direct i/o\n",0);
|
||||
|
||||
Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
|
||||
MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
Irp->UserBuffer = NULL;
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = MajorFunction;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = DeviceObject;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
||||
StartingOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
||||
StartingOffset->HighPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
}
|
||||
|
||||
return(Irp);
|
||||
}
|
||||
|
||||
PIRP IoBuildDeviceIoControlRequest(ULONG IoControlCode,
|
||||
@@ -113,29 +180,78 @@ PIRP IoBuildSynchronousFsdRequest(ULONG MajorFunction,
|
||||
PLARGE_INTEGER StartingOffset,
|
||||
PKEVENT Event,
|
||||
PIO_STATUS_BLOCK IoStatusBlock)
|
||||
/*
|
||||
* FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
|
||||
* level driver(s)
|
||||
* ARGUMENTS:
|
||||
* MajorFunction = Major function code, one of IRP_MJ_READ,
|
||||
* IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_SHUTDOWN
|
||||
* DeviceObject = Target device object
|
||||
* Buffer = Buffer containing data for a read or write
|
||||
* Length = Length in bytes of the information to be transferred
|
||||
* StartingOffset = Offset to begin the read/write from
|
||||
* Event (OUT) = Will be set when the operation is complete
|
||||
* IoStatusBlock (OUT) = Set to the status of the operation
|
||||
* RETURNS: The IRP allocated on success, or
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
|
||||
PIRP irp;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
|
||||
/*
|
||||
* Allocate an IRP for the transfer
|
||||
*/
|
||||
irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
|
||||
if (irp==NULL)
|
||||
Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
|
||||
if (Irp==NULL)
|
||||
{
|
||||
printk("Failed to allocate IRP\n");
|
||||
return(FALSE);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the parameter in the next IO stack location
|
||||
*/
|
||||
StackPtr = IoGetNextIrpStackLocation(irp);
|
||||
Irp->UserBuffer = (LPVOID)Buffer;
|
||||
if (DeviceObject->Flags&DO_BUFFERED_IO)
|
||||
{
|
||||
DPRINT("Doing buffer i/o\n",0);
|
||||
Irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,Length);
|
||||
if (Irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
Irp->UserBuffer = NULL;
|
||||
}
|
||||
if (DeviceObject->Flags&DO_DIRECT_IO)
|
||||
{
|
||||
DPRINT("Doing direct i/o\n",0);
|
||||
|
||||
Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
|
||||
MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
Irp->UserBuffer = NULL;
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Irp->UserEvent = Event;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->MajorFunction = MajorFunction;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = DeviceObject;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (StartingOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart =
|
||||
StartingOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart =
|
||||
StartingOffset->HighPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
}
|
||||
|
||||
return(Irp);
|
||||
}
|
||||
|
||||
USHORT IoSizeOfIrp(CCHAR StackSize)
|
||||
@@ -204,13 +320,15 @@ NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
|
||||
{
|
||||
PDRIVER_OBJECT drv = DevObject->DriverObject;
|
||||
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
|
||||
|
||||
DPRINT("Deviceobject %x\n",DevObject);
|
||||
DPRINT("Irp %x\n",irp);
|
||||
irp->Tail.Overlay.CurrentStackLocation--;
|
||||
irp->CurrentLocation--;
|
||||
DPRINT("Io stack address %x\n",param);
|
||||
DPRINT("Function %d Routine %x\n",param->MajorFunction,
|
||||
drv->MajorFunction[param->MajorFunction]);
|
||||
DPRINT("IRP_MJ_CREATE %d\n",IRP_MJ_CREATE);
|
||||
|
||||
return(drv->MajorFunction[param->MajorFunction](DevObject,irp));
|
||||
}
|
||||
|
||||
@@ -272,7 +390,7 @@ VOID IoSetCompletionRoutine(PIRP Irp,
|
||||
}
|
||||
}
|
||||
|
||||
VOID IoCompleteRequest(IRP* Irp, CCHAR PriorityBoost)
|
||||
VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
|
||||
/*
|
||||
* FUNCTION: Indicates the caller has finished all processing for a given
|
||||
* I/O request and is returning the given IRP to the I/O manager
|
||||
@@ -282,9 +400,15 @@ VOID IoCompleteRequest(IRP* Irp, CCHAR PriorityBoost)
|
||||
* thread making the request
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i=0;
|
||||
unsigned int stack_size;
|
||||
|
||||
for (i=0;i<0;i++)
|
||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
|
||||
Irp,PriorityBoost);
|
||||
DPRINT("Irp->Stack[i].DeviceObject->StackSize %x\n",
|
||||
Irp->Stack[i].DeviceObject->StackSize);
|
||||
stack_size = Irp->Stack[i].DeviceObject->StackSize;
|
||||
for (i=0;i<stack_size;i++)
|
||||
{
|
||||
if (Irp->Stack[i].CompletionRoutine!=NULL)
|
||||
{
|
||||
@@ -292,4 +416,17 @@ VOID IoCompleteRequest(IRP* Irp, CCHAR PriorityBoost)
|
||||
Irp->Stack[i].CompletionContext);
|
||||
}
|
||||
}
|
||||
|
||||
if (Irp->UserEvent!=NULL)
|
||||
{
|
||||
KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE);
|
||||
}
|
||||
if (Irp->UserIosb!=NULL)
|
||||
{
|
||||
*Irp->UserIosb=Irp->IoStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the
|
||||
*/
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/base/bug.c
|
||||
* PURPOSE: Graceful system shutdown if a bug is detected
|
||||
* FILE: ntoskrnl/io/mdl.c
|
||||
* PURPOSE: Io manager mdl functions
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <internal/string.h>
|
||||
#include <internal/objmgr.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -38,191 +38,157 @@ NTSTATUS ZwReadFile(HANDLE FileHandle,
|
||||
PLARGE_INTEGER ByteOffset,
|
||||
PULONG Key)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS ZwWriteFile(HANDLE FileHandle,
|
||||
HANDLE Event,
|
||||
PIO_APC_ROUTINE ApcRoutine,
|
||||
PVOID ApcContext,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
PLARGE_INTEGER ByteOffset,
|
||||
PULONG Key)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
static BOOL WriteDevice(PDEVICE_OBJECT dev, LPVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
PDRIVER_OBJECT drv = dev->DriverObject;
|
||||
PIRP irp;
|
||||
COMMON_BODY_HEADER* hdr = ObGetObjectByHandle(FileHandle);
|
||||
PFILE_OBJECT FileObject = (PFILE_OBJECT)hdr;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
|
||||
DPRINT("dev %x drv %x\n",dev,drv);
|
||||
|
||||
/*
|
||||
* Build an irp for the transfer
|
||||
*/
|
||||
irp = IoAllocateIrp(dev->StackSize,TRUE);
|
||||
if (irp==NULL)
|
||||
if (hdr==NULL)
|
||||
{
|
||||
printk("Failed to allocate IRP\n");
|
||||
return(FALSE);
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the user buffer
|
||||
*/
|
||||
DPRINT1("Preparing user buffer\n");
|
||||
irp->UserBuffer = (LPVOID)lpBuffer; // This handles the 'neither' method
|
||||
if (dev->Flags&DO_BUFFERED_IO)
|
||||
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize,TRUE);
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
Irp->UserBuffer = (LPVOID)Buffer;
|
||||
if (FileObject->DeviceObject->Flags&DO_BUFFERED_IO)
|
||||
{
|
||||
DPRINT1("Doing buffer i/o\n");
|
||||
irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,nNumberOfBytesToWrite);
|
||||
if (irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
Irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,Length);
|
||||
if (Irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(FALSE);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
memcpy(irp->AssociatedIrp.SystemBuffer,lpBuffer,nNumberOfBytesToWrite);
|
||||
irp->UserBuffer = NULL;
|
||||
Irp->UserBuffer = NULL;
|
||||
}
|
||||
if (dev->Flags&DO_DIRECT_IO)
|
||||
if (FileObject->DeviceObject->Flags&DO_DIRECT_IO)
|
||||
{
|
||||
DPRINT1("Doing direct i/o\n");
|
||||
|
||||
irp->MdlAddress = MmCreateMdl(NULL,lpBuffer,nNumberOfBytesToWrite);
|
||||
MmProbeAndLockPages(irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
irp->UserBuffer = NULL;
|
||||
irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
|
||||
MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
Irp->UserBuffer = NULL;
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the stack location
|
||||
*/
|
||||
StackPtr = IoGetNextIrpStackLocation(irp);
|
||||
StackPtr->MajorFunction = IRP_MJ_WRITE;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = dev;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->Parameters.Write.Length = nNumberOfBytesToWrite;
|
||||
|
||||
DPRINT1("Sending IRP\n");
|
||||
IoCallDriver(dev,irp);
|
||||
|
||||
|
||||
/*
|
||||
* Free the above buffer
|
||||
*/
|
||||
}
|
||||
|
||||
WINBOOL STDCALL WriteFile(HANDLE hFile, LPCVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
COMMON_BODY_HEADER* hdr = ObGetObjectByHandle(hFile);
|
||||
|
||||
if (hdr->Type==OBJTYP_DEVICE)
|
||||
{
|
||||
return(WriteDevice(hdr,lpBuffer,nNumberOfBytesToWrite,
|
||||
lpNumberOfBytesWritten,lpOverlapped));
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL ReadDevice(PDEVICE_OBJECT dev, LPVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
PDRIVER_OBJECT drv = dev->DriverObject;
|
||||
PIRP irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
|
||||
DPRINT("dev %x drv %x\n",dev,drv);
|
||||
|
||||
/*
|
||||
* Build an irp for the transfer
|
||||
*/
|
||||
irp = IoAllocateIrp(dev->StackSize,TRUE);
|
||||
if (irp==NULL)
|
||||
{
|
||||
printk("Failed to allocate IRP\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the user buffer
|
||||
*/
|
||||
DPRINT1("Preparing user buffer\n");
|
||||
irp->UserBuffer = (LPVOID)lpBuffer; // This handles the 'neither' method
|
||||
if (dev->Flags&DO_BUFFERED_IO)
|
||||
{
|
||||
DPRINT1("Doing buffer i/o\n");
|
||||
irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,nNumberOfBytesToWrite);
|
||||
if (irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
memcpy(irp->AssociatedIrp.SystemBuffer,lpBuffer,nNumberOfBytesToWrite);
|
||||
irp->UserBuffer = NULL;
|
||||
}
|
||||
if (dev->Flags&DO_DIRECT_IO)
|
||||
{
|
||||
DPRINT1("Doing direct i/o\n");
|
||||
|
||||
irp->MdlAddress = MmCreateMdl(NULL,lpBuffer,nNumberOfBytesToWrite);
|
||||
MmProbeAndLockPages(irp->MdlAddress,UserMode,IoWriteAccess);
|
||||
irp->UserBuffer = NULL;
|
||||
irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the stack location
|
||||
*/
|
||||
StackPtr = IoGetNextIrpStackLocation(irp);
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
DPRINT("StackPtr %x\n",StackPtr);
|
||||
StackPtr->MajorFunction = IRP_MJ_READ;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = dev;
|
||||
StackPtr->FileObject = NULL;
|
||||
StackPtr->Parameters.Write.Length = nNumberOfBytesToWrite;
|
||||
StackPtr->DeviceObject = FileObject->DeviceObject;
|
||||
StackPtr->FileObject = FileObject;
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (ByteOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = ByteOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = ByteOffset->HighPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
}
|
||||
if (Key!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = *Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = 0;
|
||||
}
|
||||
|
||||
DPRINT1("Sending IRP\n");
|
||||
IoCallDriver(dev,irp);
|
||||
|
||||
|
||||
/*
|
||||
* Free the above buffer
|
||||
*/
|
||||
DPRINT1("Finished ReadDevice\n");
|
||||
DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
|
||||
IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
memcpy(Buffer,Irp->AssociatedIrp.SystemBuffer,Length);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
WINBOOL STDCALL ReadFile(HANDLE hFile, LPVOID lpBuffer,
|
||||
DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
NTSTATUS ZwWriteFile(HANDLE FileHandle,
|
||||
HANDLE Event,
|
||||
PIO_APC_ROUTINE ApcRoutine,
|
||||
PVOID ApcContext,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
PLARGE_INTEGER ByteOffset,
|
||||
PULONG Key)
|
||||
{
|
||||
COMMON_BODY_HEADER* hdr = ObGetObjectByHandle(hFile);
|
||||
COMMON_BODY_HEADER* hdr = ObGetObjectByHandle(FileHandle);
|
||||
PFILE_OBJECT FileObject = (PFILE_OBJECT)hdr;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
|
||||
if (hdr->Type==OBJTYP_DEVICE)
|
||||
if (hdr==NULL)
|
||||
{
|
||||
return(ReadDevice((PDEVICE_OBJECT)hdr,lpBuffer,nNumberOfBytesToWrite,
|
||||
lpNumberOfBytesWritten,lpOverlapped));
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
return(FALSE);
|
||||
|
||||
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize,TRUE);
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
Irp->UserBuffer = (LPVOID)Buffer;
|
||||
if (FileObject->DeviceObject->Flags&DO_BUFFERED_IO)
|
||||
{
|
||||
DPRINT1("Doing buffer i/o\n");
|
||||
Irp->AssociatedIrp.SystemBuffer = (PVOID)
|
||||
ExAllocatePool(NonPagedPool,Length);
|
||||
if (Irp->AssociatedIrp.SystemBuffer==NULL)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
memcpy(Irp->AssociatedIrp.SystemBuffer,Buffer,Length);
|
||||
Irp->UserBuffer = NULL;
|
||||
}
|
||||
if (FileObject->DeviceObject->Flags&DO_DIRECT_IO)
|
||||
{
|
||||
DPRINT1("Doing direct i/o\n");
|
||||
|
||||
Irp->MdlAddress = MmCreateMdl(NULL,Buffer,Length);
|
||||
MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
|
||||
Irp->UserBuffer = NULL;
|
||||
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||
}
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
DPRINT("StackPtr %x\n",StackPtr);
|
||||
StackPtr->MajorFunction = IRP_MJ_WRITE;
|
||||
StackPtr->MinorFunction = 0;
|
||||
StackPtr->Flags = 0;
|
||||
StackPtr->Control = 0;
|
||||
StackPtr->DeviceObject = FileObject->DeviceObject;
|
||||
StackPtr->FileObject = FileObject;
|
||||
StackPtr->Parameters.Write.Length = Length;
|
||||
if (ByteOffset!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = ByteOffset->LowPart;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = ByteOffset->HighPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.ByteOffset.LowPart = 0;
|
||||
StackPtr->Parameters.Write.ByteOffset.HighPart = 0;
|
||||
}
|
||||
if (Key!=NULL)
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = *Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
StackPtr->Parameters.Write.Key = 0;
|
||||
}
|
||||
|
||||
DPRINT("FileObject->DeviceObject %x\n",FileObject->DeviceObject);
|
||||
IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/iomgr/symlink.c
|
||||
* FILE: ntoskrnl/io/symlink.c
|
||||
* PURPOSE: Implements symbolic links
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
@@ -16,12 +16,41 @@
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PVOID Target;
|
||||
} SYMBOLIC_LINK_OBJECT;
|
||||
|
||||
OBJECT_TYPE SymlinkObjectType = {{NULL,0,0},
|
||||
0,
|
||||
0,
|
||||
ULONG_MAX,
|
||||
ULONG_MAX,
|
||||
sizeof(SYMBOLIC_LINK_OBJECT),
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID IoInitSymbolicLinkImplementation(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName,
|
||||
PUNICODE_STRING DeviceName)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return(IoCreateSymbolicLink(SymbolicLinkName,DeviceName));
|
||||
}
|
||||
|
||||
NTSTATUS IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/iomgr/timer.c
|
||||
* PURPOSE: IO timers
|
||||
* FILE: ntoskrnl/io/timer.c
|
||||
* PURPOSE: io timers
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
|
@@ -13,8 +13,47 @@
|
||||
#include <internal/kernel.h>
|
||||
#include <internal/linkage.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID KeDrainApcQueue(VOID)
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PKAPC current;
|
||||
|
||||
current_entry = KeGetCurrentThread()->ApcQueueHead.Flink;
|
||||
while (current_entry!=NULL)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry,KAPC,ApcListEntry);
|
||||
current->NormalRoutine(current->NormalContext,
|
||||
current->SystemArgument1,
|
||||
current->SystemArgument2);
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
VOID KeInitializeApc(PKAPC Apc, PKNORMAL_ROUTINE NormalRoutine,
|
||||
PVOID NormalContext,
|
||||
PKTHREAD TargetThread)
|
||||
{
|
||||
memset(Apc,0,sizeof(KAPC));
|
||||
Apc->Thread = TargetThread;
|
||||
Apc->NormalRoutine=NormalRoutine;
|
||||
Apc->NormalContext=NormalContext;
|
||||
Apc->Inserted=FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN KeInsertQueueApc(PKAPC Apc)
|
||||
{
|
||||
if (Apc->Inserted)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
Apc->Inserted=TRUE;
|
||||
InsertTailList(&Apc->Thread->ApcQueueHead,&Apc->ApcListEntry);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/base/bug.c
|
||||
* FILE: ntoskrnl/ke/bug.c
|
||||
* PURPOSE: Graceful system shutdown if a bug is detected
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void free_page(void);
|
||||
void get_dma_page(void);
|
||||
void DbgPrint(void);
|
||||
void printk(void);
|
||||
void ExAcquireFastMutex(void);
|
||||
@@ -378,6 +380,8 @@ void sprintf(void);
|
||||
}
|
||||
#endif
|
||||
export symbol_table[]={
|
||||
{"_free_page",(unsigned int)free_page},
|
||||
{"_get_dma_page",(unsigned int)get_dma_page},
|
||||
{"_DbgPrint",(unsigned int)DbgPrint},
|
||||
{"_printk",(unsigned int)printk},
|
||||
{"_ExAcquireFastMutex",(unsigned int)ExAcquireFastMutex},
|
||||
|
@@ -8,7 +8,8 @@ include hal/x86/sources
|
||||
|
||||
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 \
|
||||
rtl/list.o rtl/slist.o rtl/interlck.o
|
||||
rtl/list.o rtl/slist.o rtl/interlck.o rtl/return.o \
|
||||
rtl/wstring.o
|
||||
|
||||
KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o ke/exports.o \
|
||||
ke/module.o ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \
|
||||
@@ -24,13 +25,15 @@ IO_OBJECTS = io/iomgr.o io/create.o io/irp.o io/device.o io/rw.o \
|
||||
io/queue.o io/drvlck.o io/timer.o io/share.o io/errlog.o \
|
||||
io/shutdown.o io/fdisk.o io/cancel.o io/error.o io/arc.o \
|
||||
io/dpc.o io/symlink.o io/adapter.o io/cntrller.o io/mdl.o \
|
||||
io/resource.o io/event.o io/process.o io/file.o io/ioctrl.o
|
||||
io/resource.o io/event.o io/process.o io/file.o io/ioctrl.o \
|
||||
io/fs.o
|
||||
|
||||
OB_OBJECTS = ob/object.o ob/handle.o ob/namespc.o
|
||||
|
||||
PS_OBJECTS = ps/psmgr.o ps/thread.o ps/process.o
|
||||
|
||||
EX_OBJECTS = ex/work.o ex/fmutex.o ex/resource.o ex/time.o ex/interlck.o
|
||||
EX_OBJECTS = ex/work.o ex/fmutex.o ex/resource.o ex/time.o ex/interlck.o \
|
||||
ex/callback.o
|
||||
|
||||
SE_OBJECTS = se/semgr.o
|
||||
|
||||
@@ -38,9 +41,13 @@ CFG_OBJECTS = cfg/registry.o
|
||||
|
||||
TST_OBJECTS = tst/test.o
|
||||
|
||||
DBG_OBJECTS = dbg/brkpoint.o
|
||||
|
||||
LDR_OBJECTS = ldr/loader.o
|
||||
|
||||
OBJECTS = $(HAL_OBJECTS) $(KE_OBJECTS) $(RTL_OBJECTS) $(MM_OBJECTS) \
|
||||
$(IO_OBJECTS) $(OB_OBJECTS) $(PS_OBJECTS) $(EX_OBJECTS) \
|
||||
$(SE_OBJECTS) $(CFG_OBJECTS) $(TST_OBJECTS)
|
||||
$(SE_OBJECTS) $(CFG_OBJECTS) $(TST_OBJECTS) $(DBG_OBJECTS)
|
||||
|
||||
utils/export/export$(EXE_POSTFIX): utils/export/export.c
|
||||
$(NATIVE_CC) -g utils/export/export.c -o utils/export/export$(EXE_POSTFIX)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: kernel/mm/mdl.cc
|
||||
* FILE: ntoskrnl/mm/mdl.c
|
||||
* PURPOSE: Manipulates MDLs
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
@@ -15,19 +15,45 @@
|
||||
#include <internal/hal/page.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
|
||||
VOID MmUnlockPages(PMDL MemoryDescriptorList)
|
||||
/*
|
||||
* FUNCTION: Unlocks the physical pages described by a given MDL
|
||||
* ARGUMENTS:
|
||||
* MemoryDescriptorList = MDL describing the buffer to be unlocked
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
PVOID MmMapLockedPages(PMDL MemoryDescriptorList, KPROCESSOR_MODE AccessMode)
|
||||
PVOID MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PVOID base;
|
||||
unsigned int i;
|
||||
ULONG* mdl_pages=NULL;
|
||||
|
||||
DPRINT("Mdl->ByteCount %x\n",Mdl->ByteCount);
|
||||
DPRINT("PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE) %x\n",
|
||||
PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE);
|
||||
|
||||
base = VirtualAlloc((LPVOID)0,Mdl->ByteCount,MEM_COMMIT,
|
||||
PAGE_SYSTEM + PAGE_EXECUTE_READWRITE);
|
||||
mdl_pages = (ULONG *)(Mdl + 1);
|
||||
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE); i++)
|
||||
{
|
||||
DPRINT("Writing %x with physical address %x\n",
|
||||
base+(i*PAGESIZE),mdl_pages[i]);
|
||||
DPRINT("&((PULONG)(Mdl+1))[i] %x\n",&mdl_pages[i]);
|
||||
set_page(base+(i*PAGESIZE),PA_READ + PA_SYSTEM,
|
||||
mdl_pages[i]);
|
||||
}
|
||||
DPRINT("base %x\n",base);
|
||||
return(base + Mdl->ByteOffset);
|
||||
}
|
||||
|
||||
VOID MmUnmapLockedPages(PVOID BaseAddress, PMDL MemoryDescriptorList)
|
||||
@@ -56,20 +82,36 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
||||
* Operation = Operation to probe for
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Find the memory area containing the buffer
|
||||
*/
|
||||
ULONG* mdl_pages=NULL;
|
||||
int i;
|
||||
memory_area* marea=find_first_marea(memory_area_list_head,
|
||||
(ULONG)Mdl->StartVa,
|
||||
Mdl->ByteCount);
|
||||
memory_area* marea;
|
||||
|
||||
DPRINT("MmProbeAndLockPages(Mdl %x)\n",Mdl);
|
||||
DPRINT("StartVa %x\n",Mdl->StartVa);
|
||||
|
||||
if (Mdl->StartVa > KERNEL_BASE)
|
||||
{
|
||||
marea=find_first_marea(system_memory_area_list_head,
|
||||
(ULONG)Mdl->StartVa,
|
||||
Mdl->ByteCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
marea=find_first_marea(memory_area_list_head,
|
||||
(ULONG)Mdl->StartVa,
|
||||
Mdl->ByteCount);
|
||||
}
|
||||
|
||||
DPRINT("marea %x\n",marea);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Check the area is valid
|
||||
*/
|
||||
if (marea==NULL || (marea->base+marea->length) < ((ULONG)Mdl->StartVa))
|
||||
{
|
||||
printk("Area is invalid\n");
|
||||
ExRaiseStatus(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
@@ -89,6 +131,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
||||
case IoModifyAccess:
|
||||
if (marea->access&PAGE_GUARD || marea->access&PAGE_READONLY)
|
||||
{
|
||||
printk("Invalid area protections\n");
|
||||
ExRaiseStatus(STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
break;
|
||||
@@ -108,7 +151,7 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
||||
/*
|
||||
* Lock the pages
|
||||
*/
|
||||
mdl_pages = (ULONG *)(Mdl + sizeof(MDL));
|
||||
mdl_pages = (ULONG *)(Mdl + 1);
|
||||
|
||||
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteCount)/PAGESIZE);i++)
|
||||
{
|
||||
@@ -119,6 +162,8 @@ VOID MmProbeAndLockPages(PMDL Mdl, KPROCESSOR_MODE AccessMode,
|
||||
}
|
||||
mdl_pages[i]=MmGetPhysicalAddress((PVOID)(PAGE_ROUND_DOWN(Mdl->StartVa)
|
||||
+(i*PAGESIZE)));
|
||||
DPRINT("mdl_pages[i] %x\n",mdl_pages[i]);
|
||||
DPRINT("&mdl_pages[i] %x\n",&mdl_pages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,13 +196,9 @@ ULONG MmSizeOfMdl(PVOID Base, ULONG Length)
|
||||
* Length = number of bytes to map
|
||||
*/
|
||||
{
|
||||
unsigned int len=PAGE_ROUND_UP(Length)/PAGESIZE;
|
||||
|
||||
if (!IS_PAGE_ALIGNED(Base))
|
||||
{
|
||||
len++;
|
||||
}
|
||||
unsigned int len=ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length);
|
||||
|
||||
DPRINT("MmSizeOfMdl() %x\n",sizeof(MDL)+(len*sizeof(ULONG)));
|
||||
return(sizeof(MDL)+(len*sizeof(ULONG)));
|
||||
}
|
||||
|
||||
@@ -167,12 +208,32 @@ PVOID MmGetMdlVirtualAddress(PMDL Mdl)
|
||||
}
|
||||
|
||||
PVOID MmGetSystemAddressForMdl(PMDL Mdl)
|
||||
/*
|
||||
* FUNCTION: Returns a nonpaged system-space virtual address for the buffer
|
||||
* described by the MDL. It maps the physical pages described by a given
|
||||
* MDL into system space, if they are not already mapped to system space.
|
||||
* ARGUMENTS:
|
||||
* Mdl = Mdl to map
|
||||
* RETURNS: The base system-space virtual address that maps the physical
|
||||
* pages described by the given MDL.
|
||||
*/
|
||||
{
|
||||
Mdl->MappedSystemVa = MmMapLockedPages(Mdl,KernelMode);
|
||||
if (!( (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) ||
|
||||
(Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) ))
|
||||
{
|
||||
Mdl->MappedSystemVa = MmMapLockedPages(Mdl,KernelMode);
|
||||
}
|
||||
return(Mdl->MappedSystemVa);
|
||||
}
|
||||
|
||||
VOID MmBuildMdlForNonPagedPool(PMDL Mdl)
|
||||
/*
|
||||
* FUNCTION: Fills in the corresponding physical page array of a given
|
||||
* MDL for a buffer in nonpaged system space
|
||||
* ARGUMENTS:
|
||||
* Mdl = Points to an MDL that supplies a virtual address,
|
||||
* byte offset and length
|
||||
*/
|
||||
{
|
||||
int va;
|
||||
for (va=0; va<Mdl->Size; va++)
|
||||
@@ -180,21 +241,25 @@ VOID MmBuildMdlForNonPagedPool(PMDL Mdl)
|
||||
((PULONG)(Mdl + 1))[va] = MmGetPhysicalAddress(
|
||||
Mdl->StartVa+ (va * PAGESIZE));
|
||||
}
|
||||
Mdl->MappedSystemVa = Mdl->StartVa;
|
||||
}
|
||||
|
||||
VOID MmInitializeMdl(PMDL MemoryDescriptorList, PVOID Base, ULONG Length)
|
||||
/*
|
||||
* FUNCTION: Initializes the header of an MDL
|
||||
* ARGUMENTS:
|
||||
* MemoryDescriptorList = Points to the MDL to be initialized
|
||||
* BaseVa = Points to the base virtual address of a buffer
|
||||
* Length = Specifies the length (in bytes) of a buffer
|
||||
*/
|
||||
{
|
||||
memset(MemoryDescriptorList,0,sizeof(MDL));
|
||||
MemoryDescriptorList->StartVa = PAGE_ROUND_DOWN(Base);
|
||||
MemoryDescriptorList->ByteOffset = Base - PAGE_ROUND_DOWN(Base);
|
||||
MemoryDescriptorList->MdlFlags = 0;
|
||||
MemoryDescriptorList->ByteCount = Length;
|
||||
MemoryDescriptorList->Size = PAGE_ROUND_UP(Length) / PAGESIZE;
|
||||
if (!IS_PAGE_ALIGNED(Base))
|
||||
{
|
||||
MemoryDescriptorList->Size = MemoryDescriptorList->Size
|
||||
+ sizeof(ULONG);
|
||||
}
|
||||
MemoryDescriptorList->Size = sizeof(MDL) +
|
||||
(ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length) * sizeof(ULONG));
|
||||
MemoryDescriptorList->Process = PsGetCurrentProcess();
|
||||
}
|
||||
|
||||
@@ -211,7 +276,10 @@ PMDL MmCreateMdl(PMDL MemoryDescriptorList, PVOID Base, ULONG Length)
|
||||
{
|
||||
if (MemoryDescriptorList == NULL)
|
||||
{
|
||||
MemoryDescriptorList = (PMDL)ExAllocatePool(NonPagedPool,sizeof(MDL));
|
||||
ULONG Size;
|
||||
|
||||
Size = MmSizeOfMdl(Base,Length);
|
||||
MemoryDescriptorList = (PMDL)ExAllocatePool(NonPagedPool,Size);
|
||||
if (MemoryDescriptorList==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
|
@@ -10,6 +10,7 @@
|
||||
* in take_block (if current bigger than required)
|
||||
* in remove_from_used_list
|
||||
* in ExFreePool
|
||||
* 23/08/98: Fixes from Robert Bergkvist (fragdance@hotmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
@@ -250,15 +251,20 @@ static void remove_from_free_list(block_hdr* current)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current->previous!=NULL)
|
||||
{
|
||||
current->previous->next=current->next;
|
||||
}
|
||||
if (current->next!=NULL)
|
||||
{
|
||||
DPRINT("current->previous %x\n",current->previous);
|
||||
current->next->previous=current->previous;
|
||||
}
|
||||
if (current->next==NULL)
|
||||
{
|
||||
current->previous->next=NULL;
|
||||
}
|
||||
else if (current->previous==NULL)
|
||||
{
|
||||
current->next->previous=NULL;
|
||||
free_list_head=current->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
current->next->previous=current->previous;
|
||||
current->previous->next=current->next;
|
||||
}
|
||||
}
|
||||
nr_free_blocks--;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel v0.0.2
|
||||
* FILE: mm/virtual.cc
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/virtual.c
|
||||
* PURPOSE: implementing the Virtualxxx section of the win32 api
|
||||
* PROGRAMMER: David Welch
|
||||
* UPDATE HISTORY:
|
||||
@@ -22,17 +22,22 @@
|
||||
|
||||
/* TYPES *******************************************************************/
|
||||
|
||||
extern unsigned int etext;
|
||||
extern unsigned int end;
|
||||
|
||||
/*
|
||||
* These two are statically declared because mm is initalized before the
|
||||
* memory pool
|
||||
*/
|
||||
static memory_area kernel_area_desc;
|
||||
static memory_area kernel_text_desc;
|
||||
static memory_area kernel_data_desc;
|
||||
static memory_area kernel_param_desc;
|
||||
static memory_area kernel_pool_desc;
|
||||
|
||||
/*
|
||||
* Head of the list of system memory areas
|
||||
*/
|
||||
memory_area* system_memory_area_list_head=&kernel_area_desc;
|
||||
memory_area* system_memory_area_list_head=&kernel_text_desc;
|
||||
|
||||
/*
|
||||
* Head of the list of user memory areas (this should be per process)
|
||||
@@ -62,16 +67,33 @@ void VirtualInit(boot_param* bp)
|
||||
/*
|
||||
* Setup the system area descriptor list
|
||||
*/
|
||||
kernel_area_desc.base = KERNEL_BASE;
|
||||
kernel_area_desc.length = kernel_len;
|
||||
kernel_area_desc.next = &kernel_pool_desc;
|
||||
kernel_area_desc.load_page=NULL;
|
||||
kernel_text_desc.base = KERNEL_BASE;
|
||||
kernel_text_desc.length = ((ULONG)&etext) - KERNEL_BASE;
|
||||
kernel_text_desc.previous = NULL;
|
||||
kernel_text_desc.next = &kernel_data_desc;
|
||||
kernel_text_desc.load_page=NULL;
|
||||
kernel_text_desc.access = PAGE_EXECUTE_READ;
|
||||
|
||||
kernel_data_desc.base = PAGE_ROUND_UP(((ULONG)&etext));
|
||||
kernel_data_desc.length = ((ULONG)&end) - kernel_text_desc.base;
|
||||
kernel_data_desc.previous = &kernel_text_desc;
|
||||
kernel_data_desc.next = &kernel_param_desc;
|
||||
kernel_data_desc.load_page=NULL;
|
||||
kernel_data_desc.access = PAGE_READWRITE;
|
||||
|
||||
kernel_param_desc.base = PAGE_ROUND_UP(((ULONG)&end));
|
||||
kernel_param_desc.length = kernel_len - (kernel_data_desc.length +
|
||||
kernel_text_desc.length);
|
||||
kernel_param_desc.previous = &kernel_data_desc;
|
||||
kernel_param_desc.next = &kernel_pool_desc;
|
||||
kernel_param_desc.load_page=NULL;
|
||||
|
||||
/*
|
||||
* The kmalloc area starts one page after the kernel area
|
||||
*/
|
||||
kernel_pool_desc.base = KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE;
|
||||
kernel_pool_desc.length = NONPAGED_POOL_SIZE;
|
||||
kernel_pool_desc.previous = &kernel_param_desc;
|
||||
kernel_pool_desc.next = NULL;
|
||||
kernel_pool_desc.load_page=NULL;
|
||||
|
||||
@@ -98,8 +120,10 @@ memory_area* find_first_marea(memory_area* list_head, unsigned int base,
|
||||
{
|
||||
if (current==NULL)
|
||||
{
|
||||
// printk("current is null\n");
|
||||
return(NULL);
|
||||
}
|
||||
// printk("current %x current->base %x\n",current,current->base);
|
||||
if (current->base == base && length==0)
|
||||
{
|
||||
return(current);
|
||||
@@ -210,11 +234,14 @@ static LPVOID allocate_marea(DWORD dwSize, DWORD flAllocationType,
|
||||
*/
|
||||
{
|
||||
memory_area* current=*list_head;
|
||||
memory_area* previous;
|
||||
memory_area* ndesc=NULL;
|
||||
|
||||
previous=current;
|
||||
while (current!=NULL)
|
||||
{
|
||||
last_addr = PAGE_ROUND_UP(current->base + current->length);
|
||||
previous=current;
|
||||
current=current->next;
|
||||
}
|
||||
ndesc = ExAllocatePool(NonPagedPool,sizeof(memory_area));
|
||||
@@ -223,14 +250,14 @@ static LPVOID allocate_marea(DWORD dwSize, DWORD flAllocationType,
|
||||
ndesc->lock=FALSE;
|
||||
ndesc->base=last_addr+PAGESIZE;
|
||||
ndesc->length=dwSize;
|
||||
ndesc->previous=current;
|
||||
if (current!=NULL)
|
||||
ndesc->previous=previous;
|
||||
if (previous!=NULL)
|
||||
{
|
||||
ndesc->next=current->next;
|
||||
current->next=ndesc;
|
||||
if (current->next!=NULL)
|
||||
ndesc->next=previous->next;
|
||||
previous->next=ndesc;
|
||||
if (previous->next!=NULL)
|
||||
{
|
||||
current->next->previous=ndesc;
|
||||
previous->next->previous=ndesc;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@@ -11,11 +11,11 @@
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/objmgr.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/kernel.h>
|
||||
#include <wstring.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
@@ -48,6 +48,78 @@ static struct
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||
{
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ObOpenObjectByName(ObjectAttributes,&Object);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
*DirectoryHandle = ObAddHandle(Object);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
POBJECT_HEADER hdr = ObGetObjectByHandle(DirObjHandle);
|
||||
PDIRECTORY_OBJECT dir = (PDIRECTORY_OBJECT)(HEADER_TO_BODY(hdr));
|
||||
PLIST_ENTRY current_entry;
|
||||
POBJECT_HEADER current;
|
||||
PWSTR outbuffer = (PWSTR)(ObjectIndex);
|
||||
|
||||
current_entry = dir->head.Flink;
|
||||
while (current_entry!=NULL)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,entry);
|
||||
if (BufferLength < wstrlen(current->name.Buffer))
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
BufferLength = BufferLength - wstrlen(current->name.Buffer);
|
||||
// wcscpy(outbuffer,current->name.Buffer);
|
||||
outbuffer = outbuffer + wstrlen(current->name.Buffer);
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
PVOID* Object)
|
||||
{
|
||||
|
||||
DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",
|
||||
ObjectAttributes,Object);
|
||||
DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",
|
||||
ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);
|
||||
|
||||
*Object = ObLookupObject(ObjectAttributes->RootDirectory,
|
||||
ObjectAttributes->ObjectName->Buffer);
|
||||
DPRINT("*Object %x\n",*Object);
|
||||
if ((*Object)==NULL)
|
||||
{
|
||||
return(STATUS_NO_SUCH_FILE);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
void ObjNamespcInit(void)
|
||||
/*
|
||||
* FUNCTION: Initialize the object manager namespace
|
||||
@@ -92,20 +164,6 @@ NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
PWSTR Rtlstrrchr(PUNICODE_STRING string, WCHAR c)
|
||||
{
|
||||
int i;
|
||||
DPRINT("string->Length %d\n",string->Length);
|
||||
for (i=(string->Length-1);i>=0;i--)
|
||||
{
|
||||
if (string->Buffer[i]==c)
|
||||
{
|
||||
return(&string->Buffer[i]);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
|
||||
PUNICODE_STRING ObjectName,
|
||||
ULONG Attributes,
|
||||
@@ -127,70 +185,15 @@ VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
|
||||
* to RootDirectory
|
||||
*/
|
||||
{
|
||||
UNICODE_STRING path;
|
||||
PWSTR name = NULL;
|
||||
PDIRECTORY_OBJECT parent_dir;
|
||||
|
||||
DPRINT("InitalizeObjectAttributes(ObjectName %w)\n",ObjectName->Buffer);
|
||||
|
||||
if (RootDirectory!=NULL)
|
||||
{
|
||||
ObReferenceObjectByHandle(RootDirectory,DIRECTORY_TRAVERSE,NULL,
|
||||
UserMode,(PVOID*)&parent_dir,NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_dir = HEADER_TO_BODY((POBJECT_HEADER)&namespc_root);
|
||||
}
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
|
||||
path.Buffer = ExAllocatePool(NonPagedPool,
|
||||
ObjectName->Length*sizeof(WCHAR));
|
||||
path.MaximumLength = ObjectName->Length;
|
||||
RtlCopyUnicodeString(&path,ObjectName);
|
||||
|
||||
/*
|
||||
* Seperate the path into the name of the object and the name of its
|
||||
* direct parent directory
|
||||
*/
|
||||
name = Rtlstrrchr(&path,'\\');
|
||||
*name=0;
|
||||
|
||||
/*
|
||||
* Find the objects parent directory
|
||||
*/
|
||||
DPRINT("parent_dir %x\n",&(parent_dir->Type));
|
||||
parent_dir=(PDIRECTORY_OBJECT)ObLookupObject(parent_dir,&path);
|
||||
if (parent_dir==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the parent directory doesn't disappear
|
||||
*/
|
||||
ObReferenceObjectByPointer(parent_dir,DIRECTORY_CREATE_OBJECT,NULL,
|
||||
UserMode);
|
||||
|
||||
InitializedAttributes->Attributes = Attributes;
|
||||
InitializedAttributes->parent = parent_dir;
|
||||
RtlInitUnicodeString(&InitializedAttributes->name,name+1);
|
||||
InitializedAttributes->path = path;
|
||||
}
|
||||
|
||||
int _wcscmp(wchar_t* str1, wchar_t* str2)
|
||||
{
|
||||
while ( (*str1)==(*str2) )
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
if ( (*str1)==((wchar_t)0) && (*str1)==((wchar_t)0) )
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return( (*str1) - (*str2) );
|
||||
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)
|
||||
@@ -205,12 +208,24 @@ static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name)
|
||||
{
|
||||
LIST_ENTRY* current = ((PDIRECTORY_OBJECT)dir)->head.Flink;
|
||||
POBJECT_HEADER current_obj;
|
||||
DPRINT("ObDirLookup(dir %x, name %w\n",dir,name);
|
||||
DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);
|
||||
if (name[0]==0)
|
||||
{
|
||||
return(BODY_TO_HEADER(dir));
|
||||
}
|
||||
if (name[0]=='.'&&name[1]==0)
|
||||
{
|
||||
return(BODY_TO_HEADER(dir));
|
||||
}
|
||||
if (name[0]=='.'&&name[1]=='.'&&name[2]==0)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return(NULL);
|
||||
}
|
||||
while (current!=NULL)
|
||||
{
|
||||
current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,entry);
|
||||
DPRINT("current_obj->name %w\n",current_obj->name.Buffer);
|
||||
if ( _wcscmp(current_obj->name.Buffer, name)==0)
|
||||
if ( wcscmp(current_obj->name.Buffer, name)==0)
|
||||
{
|
||||
return(current_obj);
|
||||
}
|
||||
@@ -244,20 +259,7 @@ VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)
|
||||
InsertTailList(&parent->head,&Object->entry);
|
||||
}
|
||||
|
||||
wchar_t* _wcschr(wchar_t* str, wchar_t ch)
|
||||
{
|
||||
while ((*str)!=((wchar_t)0))
|
||||
{
|
||||
if ((*str)==ch)
|
||||
{
|
||||
return(str);
|
||||
}
|
||||
str++;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string)
|
||||
PVOID ObLookupObject(HANDLE rooth, PWSTR string)
|
||||
/*
|
||||
* FUNCTION: Lookup an object within the system namespc
|
||||
* ARGUMENTS:
|
||||
@@ -269,30 +271,31 @@ PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string)
|
||||
{
|
||||
PWSTR current;
|
||||
PWSTR next;
|
||||
PDIRECTORY_OBJECT current_dir = root;
|
||||
PDIRECTORY_OBJECT current_dir = NULL;
|
||||
POBJECT_HEADER current_hdr;
|
||||
PWSTR string;
|
||||
|
||||
DPRINT("root %x string %w\n",root,_string->Buffer);
|
||||
DPRINT("root %x string %w\n",rooth,string);
|
||||
|
||||
if (root==NULL)
|
||||
if (rooth==NULL)
|
||||
{
|
||||
current_dir = HEADER_TO_BODY(&(namespc_root.hdr));
|
||||
}
|
||||
else
|
||||
{
|
||||
ObReferenceObjectByHandle(rooth,DIRECTORY_TRAVERSE,NULL,
|
||||
UserMode,(PVOID*)¤t_dir,NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bit of a hack this
|
||||
*/
|
||||
if (_string->Buffer[0]==0)
|
||||
if (string[0]==0)
|
||||
{
|
||||
DPRINT("current_dir %x\n",current_dir);
|
||||
DPRINT("type %d\n",current_dir->Type);
|
||||
return(current_dir);
|
||||
}
|
||||
|
||||
string=(PWSTR)ExAllocatePool(NonPagedPool,(_string->Length+1)*2);
|
||||
wcscpy(string,_string->Buffer);
|
||||
|
||||
DPRINT("string = %w\n",string);
|
||||
|
||||
if (string[0]!='\\')
|
||||
@@ -304,7 +307,7 @@ PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string)
|
||||
|
||||
current = string+1;
|
||||
DPRINT("current %w\n",current);
|
||||
next = _wcschr(string+1,'\\');
|
||||
next = wcschr(string+1,'\\');
|
||||
if (next!=NULL)
|
||||
{
|
||||
*next=0;
|
||||
@@ -341,7 +344,7 @@ PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string)
|
||||
current_dir = HEADER_TO_BODY(current_hdr);
|
||||
|
||||
current = next+1;
|
||||
next = _wcschr(next+1,'\\');
|
||||
next = wcschr(next+1,'\\');
|
||||
if (next!=NULL)
|
||||
{
|
||||
*next=0;
|
||||
@@ -353,11 +356,9 @@ PVOID ObLookupObject(PDIRECTORY_OBJECT root, PUNICODE_STRING _string)
|
||||
current_hdr = ObDirLookup(current_dir,current);
|
||||
if (current_hdr==NULL)
|
||||
{
|
||||
ExFreePool(string);
|
||||
return(NULL);
|
||||
}
|
||||
DPRINT("Returning %x %x\n",current_hdr,HEADER_TO_BODY(current_hdr));
|
||||
ExFreePool(string);
|
||||
return(HEADER_TO_BODY(current_hdr));
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/objmgr.h>
|
||||
#include <internal/kernel.h>
|
||||
#include <wstring.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
@@ -37,9 +38,14 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
CSHORT Type)
|
||||
{
|
||||
POBJECT_HEADER hdr = NULL;
|
||||
UNICODE_STRING ObjectName;
|
||||
PWSTR path;
|
||||
PWSTR name;
|
||||
PDIRECTORY_OBJECT parent;
|
||||
|
||||
DPRINT("ObGenericCreateObject(Handle %x ObjectAttributes %x Type %x)\n",
|
||||
Handle,ObjectAttributes,Type);
|
||||
DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
|
||||
"ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,ObjectAttributes,
|
||||
Type);
|
||||
|
||||
/*
|
||||
* Allocate the object body and header
|
||||
@@ -51,27 +57,53 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the object header
|
||||
* If unnamed then initalize
|
||||
*/
|
||||
if (ObjectAttributes!=NULL)
|
||||
if (ObjectAttributes==NULL)
|
||||
{
|
||||
ObInitializeObjectHeader(Type,&ObjectAttributes->name,hdr);
|
||||
ObInitializeObjectHeader(Type,NULL,hdr);
|
||||
*Handle = ObAddHandle(HEADER_TO_BODY(hdr));
|
||||
return(HEADER_TO_BODY(hdr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the object name into a buffer
|
||||
*/
|
||||
DPRINT("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);
|
||||
DPRINT("ObjectAttributes->ObjectName->Length %d\n",
|
||||
ObjectAttributes->ObjectName->Length);
|
||||
ObjectName.MaximumLength = ObjectAttributes->ObjectName->Length;
|
||||
ObjectName.Buffer = ExAllocatePool(NonPagedPool,
|
||||
((ObjectAttributes->ObjectName->Length+1)*2));
|
||||
if (ObjectName.Buffer==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
RtlCopyUnicodeString(&ObjectName,ObjectAttributes->ObjectName);
|
||||
|
||||
/*
|
||||
* Seperate the name into a path and name
|
||||
*/
|
||||
name = wcsrchr(ObjectName.Buffer,'\\');
|
||||
if (name==NULL)
|
||||
{
|
||||
name=ObjectName.Buffer;
|
||||
path=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ObInitializeObjectHeader(Type,NULL,hdr);
|
||||
path=ObjectName.Buffer;
|
||||
*name=0;
|
||||
name=name+1;
|
||||
}
|
||||
|
||||
// DPRINT("ObjectAttributes->parent->Type %d\n",
|
||||
// ObjectAttributes->parent->Type);
|
||||
if (ObjectAttributes!=NULL)
|
||||
{
|
||||
/*
|
||||
* Add the object to its parent directory
|
||||
*/
|
||||
DPRINT("hdr->name.Buffer %x\n",hdr->name.Buffer);
|
||||
ObCreateEntry(ObjectAttributes->parent,hdr);
|
||||
}
|
||||
parent = ObLookupObject(ObjectAttributes->RootDirectory,path);
|
||||
|
||||
/*
|
||||
* Initialize the object header
|
||||
*/
|
||||
ObInitializeObjectHeader(Type,name,hdr);
|
||||
ObCreateEntry(parent,hdr);
|
||||
|
||||
DPRINT("Handle %x\n",Handle);
|
||||
*Handle = ObAddHandle(HEADER_TO_BODY(hdr));
|
||||
@@ -81,6 +113,8 @@ PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
|
||||
ULONG ObSizeOf(CSHORT Type)
|
||||
{
|
||||
DPRINT("ObSizeOf(Type %d)\n",Type);
|
||||
DPRINT("ObSizeOf() Returning %d\n",ObjectTypes[Type]->PagedPoolCharge);
|
||||
return(ObjectTypes[Type]->PagedPoolCharge);
|
||||
}
|
||||
|
||||
@@ -95,7 +129,7 @@ VOID ObRegisterType(CSHORT id, POBJECT_TYPE type)
|
||||
ObjectTypes[id]=type;
|
||||
}
|
||||
|
||||
VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
|
||||
VOID ObInitializeObjectHeader(CSHORT id, PWSTR name,
|
||||
POBJECT_HEADER obj)
|
||||
/*
|
||||
* FUNCTION: Creates a new object
|
||||
@@ -104,10 +138,12 @@ VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
|
||||
* obj = Pointer to the header of the object
|
||||
*/
|
||||
{
|
||||
PWSTR temp_name;
|
||||
|
||||
if (name!=NULL)
|
||||
{
|
||||
DPRINT("ObInitializeObjectHeader(id %d name %w obj %x)\n",id,
|
||||
name->Buffer,obj);
|
||||
name,obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -125,13 +161,13 @@ VOID ObInitializeObjectHeader(CSHORT id, PUNICODE_STRING name,
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->name.Length = 0;
|
||||
obj->name.MaximumLength = name->Length;
|
||||
DPRINT("name %w\n",name);
|
||||
obj->name.MaximumLength = wstrlen(name);
|
||||
obj->name.Buffer = ExAllocatePool(NonPagedPool,
|
||||
(name->Length+1)*sizeof(WCHAR));
|
||||
DPRINT("obj->name.Buffer %x\n",obj->name.Buffer);
|
||||
RtlCopyUnicodeString(&obj->name,name);
|
||||
DPRINT("obj->name.Buffer %x\n",obj->name.Buffer);
|
||||
(obj->name.MaximumLength+1)*2);
|
||||
DPRINT("name %w\n",name);
|
||||
RtlInitUnicodeString(&obj->name,name);
|
||||
DPRINT("name %w\n",obj->name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,10 +186,11 @@ NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
POBJECT_HEADER Object = BODY_TO_HEADER(ObjectBody);
|
||||
POBJECT_HEADER Object;
|
||||
|
||||
DPRINT("ObReferenceObjectByPointer(%x %x)\n",ObjectBody,Object);
|
||||
|
||||
Object = BODY_TO_HEADER(ObjectBody);
|
||||
Object->RefCount++;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
@@ -180,7 +217,7 @@ NTSTATUS ZwClose(HANDLE Handle)
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
ObjectBody = ObGetObjectByHandle(Handle);
|
||||
if (ObjectBody == NULL)
|
||||
|
@@ -310,6 +310,7 @@ NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||
|
||||
ExInterlockedInsertHeadList(&ThreadListHead,&thread->Entry,
|
||||
&ThreadListLock);
|
||||
InitializeListHead(&thread->ApcQueueHead);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
#include <wstring.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
@@ -30,59 +31,40 @@ WCHAR wtoupper(WCHAR c)
|
||||
{
|
||||
if((c>='a') && (c<='z')) return c+Aa_Difference;
|
||||
return c;
|
||||
}
|
||||
|
||||
unsigned long wstrlen(PWSTR s)
|
||||
{
|
||||
WCHAR c=' ';
|
||||
unsigned int len=0;
|
||||
|
||||
while(c!=0) {
|
||||
c=*s;
|
||||
s++;
|
||||
len++;
|
||||
};
|
||||
s-=len;
|
||||
|
||||
return len-1;
|
||||
}
|
||||
};
|
||||
|
||||
ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
|
||||
{
|
||||
return AnsiString->Length*2;
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PANSI_STRING SourceString,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
unsigned long i;
|
||||
unsigned long i;
|
||||
|
||||
if (AllocateDestinationString==TRUE)
|
||||
{
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool,
|
||||
(SourceString->Length+1)*2);
|
||||
DestinationString->MaximumLength=SourceString->Length;
|
||||
}
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
|
||||
DestinationString->MaximumLength=SourceString->Length;
|
||||
};
|
||||
|
||||
DestinationString->Length=SourceString->Length;
|
||||
DestinationString->Length=SourceString->Length;
|
||||
memset(DestinationString->Buffer, 0, SourceString->Length*2);
|
||||
|
||||
memset(DestinationString->Buffer,0,SourceString->Length*2);
|
||||
for (i=0; i<SourceString->Length; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
|
||||
for (i=0; i<SourceString->Length; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
SourceString->Buffer++;
|
||||
DestinationString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
SourceString->Buffer++;
|
||||
DestinationString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
|
||||
IN PUNICODE_STRING Source)
|
||||
@@ -104,7 +86,7 @@ NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
|
||||
|
||||
Destination->Length+=Source->Length;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
|
||||
IN PWSTR Source)
|
||||
@@ -126,12 +108,12 @@ NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
|
||||
|
||||
Destination->Length+=slen;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)
|
||||
{
|
||||
*Value=simple_strtoul((const char *)String, NULL, Base);
|
||||
}
|
||||
};
|
||||
|
||||
LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
|
||||
{
|
||||
@@ -160,7 +142,7 @@ LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
|
||||
String2->Buffer-=i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
BOOLEAN CaseInsensitive)
|
||||
@@ -194,7 +176,7 @@ LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
String2->Buffer-=i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
|
||||
{
|
||||
@@ -202,7 +184,6 @@ VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
|
||||
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
DestinationString->Buffer=NULL;
|
||||
} else {
|
||||
if(SourceString->Length<DestinationString->MaximumLength) {
|
||||
copylen=SourceString->Length;
|
||||
@@ -211,62 +192,40 @@ VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
|
||||
};
|
||||
for(i=0; i<copylen; i++)
|
||||
{
|
||||
*(DestinationString->Buffer)=*(SourceString->Buffer);
|
||||
DestinationString++;
|
||||
SourceString++;
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
DestinationString->Buffer-=copylen;
|
||||
SourceString->Buffer-=copylen;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString)
|
||||
{
|
||||
unsigned long copylen, i;
|
||||
WCHAR* src;
|
||||
WCHAR* dest;
|
||||
unsigned long copylen, i;
|
||||
|
||||
DPRINT("RtlCopyUnicodeString(Dest %x Source %x)\n",DestinationString,
|
||||
SourceString);
|
||||
DPRINT("Dest->Length %d Dest->Buffer %x\n",DestinationString->Length,
|
||||
DestinationString->Buffer);
|
||||
if (SourceString!=NULL)
|
||||
{
|
||||
DPRINT("Source->Length %d Source->Buffer %x\n",SourceString->Length,
|
||||
SourceString->Buffer);
|
||||
}
|
||||
|
||||
if(SourceString==NULL)
|
||||
{
|
||||
DestinationString->Length=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestinationString->Length=SourceString->Length;
|
||||
if(SourceString->Length<DestinationString->MaximumLength)
|
||||
{
|
||||
copylen=SourceString->Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
copylen=DestinationString->MaximumLength;
|
||||
}
|
||||
DPRINT("Beginning copy of length %d\n",copylen);
|
||||
src = SourceString->Buffer;
|
||||
dest = DestinationString->Buffer;
|
||||
for(i=0; i<copylen; i++)
|
||||
{
|
||||
*dest=*src;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
DPRINT("Finished copy %x\n",DestinationString->Buffer);
|
||||
*dest=0;
|
||||
DPRINT("Finished copy %x\n",DestinationString->Buffer);
|
||||
}
|
||||
}
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
} else {
|
||||
if(SourceString->Length<DestinationString->MaximumLength) {
|
||||
copylen=SourceString->Length;
|
||||
} else {
|
||||
copylen=DestinationString->MaximumLength;
|
||||
};
|
||||
for(i=0; i<copylen; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
DestinationString->Buffer-=copylen;
|
||||
SourceString->Buffer-=copylen;
|
||||
};
|
||||
};
|
||||
|
||||
BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
|
||||
{
|
||||
@@ -300,7 +259,7 @@ BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive
|
||||
String2->Buffer-=i;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
BOOLEAN CaseInsensitive)
|
||||
@@ -335,17 +294,17 @@ BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
String2->Buffer-=i;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)
|
||||
{
|
||||
ExFreePool(AnsiString->Buffer);
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
||||
{
|
||||
ExFreePool(UnicodeString->Buffer);
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
|
||||
IN PCSZ SourceString)
|
||||
@@ -361,7 +320,7 @@ VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
|
||||
DestinationString->MaximumLength=DestSize+1;
|
||||
};
|
||||
DestinationString->Buffer=(PCHAR)SourceString;
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlInitString(IN OUT PSTRING DestinationString,
|
||||
IN PCSZ SourceString)
|
||||
@@ -369,7 +328,7 @@ VOID RtlInitString(IN OUT PSTRING DestinationString,
|
||||
DestinationString->Length=strlen((char *)SourceString);
|
||||
DestinationString->MaximumLength=strlen((char *)SourceString)+1;
|
||||
DestinationString->Buffer=SourceString;
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PCWSTR SourceString)
|
||||
@@ -388,7 +347,7 @@ VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
|
||||
DestinationString->Buffer=(PWSTR)SourceString;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */
|
||||
IN OUT PUNICODE_STRING String)
|
||||
@@ -396,7 +355,7 @@ NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base,
|
||||
char *str;
|
||||
unsigned long len, i;
|
||||
|
||||
str=ExAllocatePool(NonPagedPool, 100);
|
||||
str=ExAllocatePool(NonPagedPool, 1024);
|
||||
if(Base==16) {
|
||||
sprintf(str, "%x", Value);
|
||||
} else
|
||||
@@ -424,37 +383,35 @@ NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base,
|
||||
ExFreePool(str);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
unsigned long i;
|
||||
WCHAR* dest;
|
||||
char* src;
|
||||
unsigned long i;
|
||||
|
||||
if(AllocateDestinationString==TRUE)
|
||||
{
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool,
|
||||
(SourceString->Length+1)*2);
|
||||
DestinationString->MaximumLength=SourceString->Length;
|
||||
}
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
|
||||
DestinationString->Length=SourceString->Length;
|
||||
// Causes excetion 14(0) in _Validate_Free_List
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);
|
||||
DestinationString->MaximumLength=SourceString->Length+1;
|
||||
};
|
||||
|
||||
dest = DestinationString->Buffer;
|
||||
src = SourceString->Buffer;
|
||||
for(i=0; i<SourceString->Length; i++)
|
||||
{
|
||||
*dest=*src;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
*DestinationString->Buffer=0;
|
||||
DestinationString->Length=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
for(i=0; i<SourceString->Length; i++) {
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,
|
||||
OUT PULONG Value)
|
||||
@@ -511,7 +468,7 @@ NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,
|
||||
*Value=simple_strtoul(str, NULL, Base);
|
||||
|
||||
ExFreePool(str);
|
||||
}
|
||||
};
|
||||
|
||||
NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString,
|
||||
@@ -520,15 +477,15 @@ NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
unsigned long i;
|
||||
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
|
||||
DestinationString->Length=SourceString->Length;
|
||||
DestinationString->MaximumLength-SourceString->Length+1;
|
||||
DestinationString->MaximumLength=SourceString->Length+1;
|
||||
};
|
||||
|
||||
for(i=0; i<SourceString->Length; i++) {
|
||||
*DestinationString->Buffer=wtoupper(*SourceString->Buffer);
|
||||
DestinationString++;
|
||||
SourceString++;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
@@ -536,7 +493,7 @@ NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
VOID RtlUpcaseString(IN OUT PSTRING DestinationString,
|
||||
IN PSTRING SourceString)
|
||||
@@ -551,11 +508,11 @@ VOID RtlUpcaseString(IN OUT PSTRING DestinationString,
|
||||
|
||||
for(i=0; i<len; i++) {
|
||||
*DestinationString->Buffer=toupper(*SourceString->Buffer);
|
||||
DestinationString++;
|
||||
SourceString++;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
DestinationString->Buffer-=len;
|
||||
SourceString->Buffer-=len;
|
||||
}
|
||||
};
|
||||
|
@@ -1,529 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/rtl/unicode.c
|
||||
* PURPOSE: String functions
|
||||
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
|
||||
* UPDATE HISTORY:
|
||||
* Created 10/08/98
|
||||
* Fixed bugs 21/08/98
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
#include <internal/string.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ctype.h>
|
||||
#include <internal/kernel.h>
|
||||
#include <internal/debug.h>
|
||||
|
||||
#define Aa_Difference 'A'-'a';
|
||||
|
||||
VOID RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
WCHAR wtoupper(WCHAR c)
|
||||
{
|
||||
if((c>='a') && (c<='z')) return c+Aa_Difference;
|
||||
return c;
|
||||
};
|
||||
|
||||
unsigned long wstrlen(PWSTR s)
|
||||
{
|
||||
WCHAR c=' ';
|
||||
unsigned int len=0;
|
||||
|
||||
while(c!=0) {
|
||||
c=*s;
|
||||
s++;
|
||||
len++;
|
||||
};
|
||||
s-=len;
|
||||
|
||||
return len-1;
|
||||
};
|
||||
|
||||
ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
|
||||
{
|
||||
return AnsiString->Length*2;
|
||||
};
|
||||
|
||||
NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
|
||||
DestinationString->MaximumLength=SourceString->Length;
|
||||
};
|
||||
|
||||
DestinationString->Length=SourceString->Length;
|
||||
memset(DestinationString->Buffer, 0, SourceString->Length*2);
|
||||
|
||||
for (i=0; i<SourceString->Length; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
|
||||
SourceString->Buffer++;
|
||||
DestinationString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
|
||||
IN PUNICODE_STRING Source)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if(Destination->MaximumLength-Destination->Length-Source->Length<0)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
Destination->Buffer+=Destination->Length;
|
||||
for(i=0; i<Source->Length; i++) {
|
||||
*Destination->Buffer=*Source->Buffer;
|
||||
Destination->Buffer++;
|
||||
Source->Buffer++;
|
||||
};
|
||||
*Destination->Buffer=0;
|
||||
Destination->Buffer-=(Destination->Length+Source->Length);
|
||||
Source->Buffer-=Source->Length;
|
||||
|
||||
Destination->Length+=Source->Length;
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
|
||||
IN PWSTR Source)
|
||||
{
|
||||
unsigned long i, slen=wstrlen(Source);
|
||||
|
||||
if(Destination->MaximumLength-Destination->Length-slen<0)
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
Destination->Buffer+=Destination->Length;
|
||||
for(i=0; i<slen; i++) {
|
||||
*Destination->Buffer=*Source;
|
||||
Destination->Buffer++;
|
||||
Source++;
|
||||
};
|
||||
*Destination->Buffer=0;
|
||||
Destination->Buffer-=(Destination->Length+slen);
|
||||
Source-=slen;
|
||||
|
||||
Destination->Length+=slen;
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)
|
||||
{
|
||||
*Value=simple_strtoul((const char *)String, NULL, Base);
|
||||
};
|
||||
|
||||
LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
|
||||
{
|
||||
unsigned long i;
|
||||
char c1, c2;
|
||||
|
||||
if(String1->Length!=String2->Length) return String1->Length-String2->Length;
|
||||
|
||||
for(i=0; i<String1->Length; i++) {
|
||||
if(CaseInsensitive==TRUE) {
|
||||
c1=toupper(*String1->Buffer);
|
||||
c2=toupper(*String2->Buffer);
|
||||
} else {
|
||||
c1=*String1->Buffer;
|
||||
c2=*String2->Buffer;
|
||||
};
|
||||
if(c1!=c2) {
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
return c1-c2;
|
||||
};
|
||||
String1->Buffer++;
|
||||
String2->Buffer++;
|
||||
};
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
BOOLEAN CaseInsensitive)
|
||||
{
|
||||
unsigned long i;
|
||||
WCHAR wc1, wc2;
|
||||
|
||||
if(String1->Length!=String2->Length) return
|
||||
String1->Length-String2->Length;
|
||||
|
||||
for(i=0; i<String1->Length; i++) {
|
||||
if(CaseInsensitive==TRUE) {
|
||||
wc1=wtoupper(*String1->Buffer);
|
||||
wc2=wtoupper(*String2->Buffer);
|
||||
} else {
|
||||
wc1=*String1->Buffer;
|
||||
wc2=*String2->Buffer;
|
||||
};
|
||||
|
||||
if(wc1!=wc2) {
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
return wc1-wc2;
|
||||
};
|
||||
|
||||
String1->Buffer++;
|
||||
String2->Buffer++;
|
||||
};
|
||||
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
|
||||
{
|
||||
unsigned long copylen, i;
|
||||
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
} else {
|
||||
if(SourceString->Length<DestinationString->MaximumLength) {
|
||||
copylen=SourceString->Length;
|
||||
} else {
|
||||
copylen=DestinationString->MaximumLength;
|
||||
};
|
||||
for(i=0; i<copylen; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
DestinationString->Buffer-=copylen;
|
||||
SourceString->Buffer-=copylen;
|
||||
};
|
||||
};
|
||||
|
||||
VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString)
|
||||
{
|
||||
unsigned long copylen, i;
|
||||
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
} else {
|
||||
if(SourceString->Length<DestinationString->MaximumLength) {
|
||||
copylen=SourceString->Length;
|
||||
} else {
|
||||
copylen=DestinationString->MaximumLength;
|
||||
};
|
||||
for(i=0; i<copylen; i++)
|
||||
{
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
DestinationString->Buffer-=copylen;
|
||||
SourceString->Buffer-=copylen;
|
||||
};
|
||||
};
|
||||
|
||||
BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
|
||||
{
|
||||
unsigned long s1l=String1->Length;
|
||||
unsigned long s2l=String2->Length;
|
||||
unsigned long i;
|
||||
char c1, c2;
|
||||
|
||||
if(s1l!=s2l) return FALSE;
|
||||
|
||||
for(i=0; i<s1l; i++) {
|
||||
c1=*String1->Buffer;
|
||||
c2=*String2->Buffer;
|
||||
|
||||
if(CaseInsensitive==TRUE) {
|
||||
c1=toupper(c1);
|
||||
c2=toupper(c2);
|
||||
};
|
||||
|
||||
if(c1!=c2) {
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
String1->Buffer++;
|
||||
String2->Buffer++;
|
||||
};
|
||||
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
|
||||
BOOLEAN CaseInsensitive)
|
||||
{
|
||||
unsigned long s1l=String1->Length;
|
||||
unsigned long s2l=String2->Length;
|
||||
unsigned long i;
|
||||
char wc1, wc2;
|
||||
|
||||
if(s1l!=s2l) return FALSE;
|
||||
|
||||
for(i=0; i<s1l; i++) {
|
||||
if(CaseInsensitive==TRUE) {
|
||||
wc1=wtoupper(*String1->Buffer);
|
||||
wc2=wtoupper(*String2->Buffer);
|
||||
} else {
|
||||
wc1=*String1->Buffer;
|
||||
wc2=*String2->Buffer;
|
||||
};
|
||||
|
||||
if(wc1!=wc2) {
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
String1->Buffer++;
|
||||
String2->Buffer++;
|
||||
};
|
||||
|
||||
String1->Buffer-=i;
|
||||
String2->Buffer-=i;
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)
|
||||
{
|
||||
ExFreePool(AnsiString->Buffer);
|
||||
};
|
||||
|
||||
VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
|
||||
{
|
||||
ExFreePool(UnicodeString->Buffer);
|
||||
};
|
||||
|
||||
VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
|
||||
IN PCSZ SourceString)
|
||||
{
|
||||
unsigned long DestSize;
|
||||
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
DestinationString->MaximumLength=0;
|
||||
} else {
|
||||
DestSize=strlen((const char *)SourceString);
|
||||
DestinationString->Length=DestSize;
|
||||
DestinationString->MaximumLength=DestSize+1;
|
||||
};
|
||||
DestinationString->Buffer=(PCHAR)SourceString;
|
||||
};
|
||||
|
||||
VOID RtlInitString(IN OUT PSTRING DestinationString,
|
||||
IN PCSZ SourceString)
|
||||
{
|
||||
DestinationString->Length=strlen((char *)SourceString);
|
||||
DestinationString->MaximumLength=strlen((char *)SourceString)+1;
|
||||
DestinationString->Buffer=SourceString;
|
||||
};
|
||||
|
||||
VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PCWSTR SourceString)
|
||||
{
|
||||
unsigned long i, DestSize;
|
||||
UNICODE_STRING Dest=*DestinationString;
|
||||
|
||||
if(SourceString==NULL) {
|
||||
DestinationString->Length=0;
|
||||
DestinationString->MaximumLength=0;
|
||||
DestinationString->Buffer=NULL;
|
||||
} else {
|
||||
DestSize=wstrlen((PWSTR)SourceString);
|
||||
DestinationString->Length=DestSize;
|
||||
DestinationString->MaximumLength=DestSize+1;
|
||||
|
||||
DestinationString->Buffer=(PWSTR)SourceString;
|
||||
};
|
||||
};
|
||||
|
||||
NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */
|
||||
IN OUT PUNICODE_STRING String)
|
||||
{
|
||||
char *str;
|
||||
unsigned long len, i;
|
||||
|
||||
str=ExAllocatePool(NonPagedPool, 1024);
|
||||
if(Base==16) {
|
||||
sprintf(str, "%x", Value);
|
||||
} else
|
||||
if(Base==8) {
|
||||
sprintf(str, "%o", Value);
|
||||
} else
|
||||
if(Base==2) {
|
||||
sprintf(str, "%b", Value);
|
||||
} else {
|
||||
sprintf(str, "%u", Value);
|
||||
};
|
||||
|
||||
len=strlen(str);
|
||||
if(String->MaximumLength<len) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
for(i=0; i<len; i++) {
|
||||
*String->Buffer=*str;
|
||||
String->Buffer++;
|
||||
str++;
|
||||
};
|
||||
*String->Buffer=0;
|
||||
String->Buffer-=len;
|
||||
String->Length=len;
|
||||
str-=len;
|
||||
ExFreePool(str);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
|
||||
// Causes excetion 14(0) in _Validate_Free_List
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);
|
||||
DestinationString->MaximumLength=SourceString->Length+1;
|
||||
};
|
||||
|
||||
DestinationString->Length=SourceString->Length;
|
||||
|
||||
for(i=0; i<SourceString->Length; i++) {
|
||||
*DestinationString->Buffer=*SourceString->Buffer;
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,
|
||||
OUT PULONG Value)
|
||||
{
|
||||
char *str;
|
||||
unsigned long i, lenmin=0;
|
||||
BOOLEAN addneg=FALSE;
|
||||
|
||||
str=ExAllocatePool(NonPagedPool, String->Length+1);
|
||||
|
||||
for(i=0; i<String->Length; i++) {
|
||||
*str=*String->Buffer;
|
||||
|
||||
if(*str=='b') { Base=2; lenmin++; } else
|
||||
if(*str=='o') { Base=8; lenmin++; } else
|
||||
if(*str=='d') { Base=10; lenmin++; } else
|
||||
if(*str=='x') { Base=16; lenmin++; } else
|
||||
if(*str=='+') { lenmin++; } else
|
||||
if(*str=='-') { addneg=TRUE; lenmin++; } else
|
||||
if((*str>'1') && (Base==2)) {
|
||||
String->Buffer-=i;
|
||||
*Value=0;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
} else
|
||||
if(((*str>'7') || (*str<'0')) && (Base==8)) {
|
||||
String->Buffer-=i;
|
||||
*Value=0;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
} else
|
||||
if(((*str>'9') || (*str<'0')) && (Base==10)) {
|
||||
String->Buffer-=i;
|
||||
*Value=0;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
} else
|
||||
if((((*str>'9') || (*str<'0')) ||
|
||||
((toupper(*str)>'F') || (toupper(*str)<'A'))) && (Base==16))
|
||||
{
|
||||
String->Buffer-=i;
|
||||
*Value=0;
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
} else
|
||||
str++;
|
||||
|
||||
String->Buffer++;
|
||||
};
|
||||
|
||||
*str=0;
|
||||
String->Buffer-=String->Length;
|
||||
str-=(String->Length-lenmin);
|
||||
|
||||
if(addneg==TRUE) {
|
||||
*Value=simple_strtoul(str, NULL, Base)*-1;
|
||||
} else
|
||||
*Value=simple_strtoul(str, NULL, Base);
|
||||
|
||||
ExFreePool(str);
|
||||
};
|
||||
|
||||
NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
|
||||
IN PUNICODE_STRING SourceString,
|
||||
IN BOOLEAN AllocateDestinationString)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if(AllocateDestinationString==TRUE) {
|
||||
DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
|
||||
DestinationString->Length=SourceString->Length;
|
||||
DestinationString->MaximumLength=SourceString->Length+1;
|
||||
};
|
||||
|
||||
for(i=0; i<SourceString->Length; i++) {
|
||||
*DestinationString->Buffer=wtoupper(*SourceString->Buffer);
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
DestinationString->Buffer-=SourceString->Length;
|
||||
SourceString->Buffer-=SourceString->Length;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
};
|
||||
|
||||
VOID RtlUpcaseString(IN OUT PSTRING DestinationString,
|
||||
IN PSTRING SourceString)
|
||||
{
|
||||
unsigned long i, len;
|
||||
|
||||
if(SourceString->Length>DestinationString->MaximumLength) {
|
||||
len=DestinationString->MaximumLength;
|
||||
} else {
|
||||
len=SourceString->Length;
|
||||
};
|
||||
|
||||
for(i=0; i<len; i++) {
|
||||
*DestinationString->Buffer=toupper(*SourceString->Buffer);
|
||||
DestinationString->Buffer++;
|
||||
SourceString->Buffer++;
|
||||
};
|
||||
*DestinationString->Buffer=0;
|
||||
|
||||
DestinationString->Buffer-=len;
|
||||
SourceString->Buffer-=len;
|
||||
};
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/test/test.c
|
||||
* FILE: ntoskrnl/tst/test.c
|
||||
* PURPOSE: Kernel regression tests
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
@@ -11,41 +11,52 @@
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/kernel.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include <in.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static KEVENT event;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
printk("Beginning Thread A\n");
|
||||
for(;;)
|
||||
{
|
||||
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
|
||||
KeClearEvent(&event);
|
||||
printk("AAA ");
|
||||
KeSetEvent(&event,IO_NO_INCREMENT,TRUE);
|
||||
}
|
||||
KeClearEvent(&event);
|
||||
KeSetEvent(&event,IO_NO_INCREMENT,TRUE);
|
||||
}
|
||||
|
||||
NTSTATUS TstSecondThread(PVOID start)
|
||||
{
|
||||
printk("Beginning Thread B\n");
|
||||
for(;;)
|
||||
{
|
||||
KeSetEvent(&event,IO_NO_INCREMENT,TRUE);
|
||||
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
|
||||
KeClearEvent(&event);
|
||||
printk("BBB ");
|
||||
}
|
||||
KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL);
|
||||
printk("Ending Thread B\n");
|
||||
}
|
||||
|
||||
NTSTATUS TstThreadSupport()
|
||||
@@ -53,22 +64,53 @@ NTSTATUS TstThreadSupport()
|
||||
HANDLE th1, th2;
|
||||
|
||||
KeInitializeEvent(&event,SynchronizationEvent,FALSE);
|
||||
PsCreateSystemThread(&th1,0,NULL,NULL,NULL,TstFirstThread,NULL);
|
||||
// PsCreateSystemThread(&th1,0,NULL,NULL,NULL,TstFirstThread,NULL);
|
||||
KeClearEvent(&event);
|
||||
PsCreateSystemThread(&th2,0,NULL,NULL,NULL,TstSecondThread,NULL);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
void TstGeneralWrite()
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE hfile;
|
||||
char buf[256];
|
||||
ANSI_STRING afilename;
|
||||
UNICODE_STRING ufilename;
|
||||
|
||||
DbgPrint("Opening test device\n");
|
||||
RtlInitAnsiString(&afilename,"\\Device\\Test");
|
||||
RtlAnsiStringToUnicodeString(&ufilename,&afilename,TRUE);
|
||||
InitializeObjectAttributes(&attr,&ufilename,0,NULL,NULL);
|
||||
ZwOpenFile(&hfile,0,&attr,NULL,0,0);
|
||||
if (hfile==NULL)
|
||||
{
|
||||
DbgPrint("Failed to open test device\n");
|
||||
return;
|
||||
}
|
||||
strcpy(buf,"hello world");
|
||||
ZwWriteFile(hfile,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
buf,
|
||||
strlen(buf),
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
void TstParallelPortWrite()
|
||||
{
|
||||
HANDLE hfile;
|
||||
|
||||
DbgPrint("Opening parallel port\n");
|
||||
hfile = CreateFile("\\Device\\Parallel",0,0,0,0,0,0);
|
||||
// hfile = CreateFile("\\Device\\Parallel",0,0,0,0,0,0);
|
||||
if (hfile==NULL)
|
||||
{
|
||||
DbgPrint("Failed to open parallel port\n");
|
||||
}
|
||||
WriteFile(hfile,"hello world",strlen("hello world"),NULL,NULL);
|
||||
// WriteFile(hfile,"hello world",strlen("hello world"),NULL,NULL);
|
||||
}
|
||||
|
||||
void TstKeyboardRead()
|
||||
@@ -76,7 +118,7 @@ void TstKeyboardRead()
|
||||
KEY_EVENT_RECORD key;
|
||||
HANDLE hfile;
|
||||
|
||||
hfile = CreateFile("\\Device\\Keyboard",0,0,0,0,0,0);
|
||||
// hfile = CreateFile("\\Device\\Keyboard",0,0,0,0,0,0);
|
||||
if (hfile == NULL)
|
||||
{
|
||||
printk("Failed to open keyboard\n");
|
||||
@@ -84,7 +126,7 @@ void TstKeyboardRead()
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
ReadFile(hfile,&key,sizeof(KEY_EVENT_RECORD),NULL,NULL);
|
||||
// ReadFile(hfile,&key,sizeof(KEY_EVENT_RECORD),NULL,NULL);
|
||||
printk("%c",key.AsciiChar);
|
||||
for(;;);
|
||||
}
|
||||
@@ -92,6 +134,6 @@ void TstKeyboardRead()
|
||||
|
||||
void TstBegin()
|
||||
{
|
||||
TstKeyboardRead();
|
||||
TstGeneralWrite();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user