mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
*** empty log message ***
svn path=/trunk/; revision=143
This commit is contained in:
parent
d55d012d33
commit
02e3d7b08e
45 changed files with 6603 additions and 7008 deletions
10
reactos/apps/tests/hello/hello.c
Normal file
10
reactos/apps/tests/hello/hello.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
NtDisplayString("Shell Starting...\n");
|
||||
ExitThread(0);
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
all: test.bin
|
||||
all: hello.bin
|
||||
|
||||
test.bin: test.o
|
||||
$(LD) -Ttext 0x10000 test.o ../../lib/ntdll/ntdll.a -o test.exe
|
||||
$(OBJCOPY) -O binary test.exe test.bin
|
||||
OBJECTS = ../common/crt0.o hello.o
|
||||
|
||||
hello.bin: $(OBJECTS)
|
||||
$(LD) -Ttext 0x10000 $(OBJECTS) ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a -o hello.exe
|
||||
$(OBJCOPY) -O binary hello.exe hello.bin
|
||||
|
||||
include ../../rules.mak
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
BITS 32
|
||||
|
||||
EXTERN _NtDisplayString
|
||||
|
||||
_main:
|
||||
push dword _string
|
||||
call _NtDisplayString
|
||||
l1:
|
||||
jmp l1
|
||||
|
||||
_string db 'Hello world from user mode!',0xa,0
|
|
@ -1,176 +1,218 @@
|
|||
|
||||
#include <internal/mmhal.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
OutputDebugStringA(buffer);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
HANDLE KeyboardHandle;
|
||||
|
||||
void ExecuteCd(char* cmdline)
|
||||
{
|
||||
UCHAR Buffer[255];
|
||||
|
||||
debug_printf("ExecuteCd(cmdline %s)\n",cmdline);
|
||||
|
||||
if (cmdline[0] != '\\' &&
|
||||
cmdline[1] != ':')
|
||||
{
|
||||
GetCurrentDirectoryA(255,Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer[0] = 0;
|
||||
}
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
lstrcatA(Buffer,cmdline);
|
||||
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
if (Buffer[lstrlenA(Buffer)-1] != '\\')
|
||||
{
|
||||
lstrcatA(Buffer,"\\");
|
||||
}
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
SetCurrentDirectoryA(Buffer);
|
||||
}
|
||||
|
||||
void ExecuteDir(char* cmdline)
|
||||
{
|
||||
}
|
||||
|
||||
void ExecuteType(char* cmdline)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
char c;
|
||||
DWORD Result;
|
||||
|
||||
FileHandle = CreateFile(cmdline,
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
while (ReadFile(FileHandle,
|
||||
&c,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("%c",c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteCommand(char* line)
|
||||
{
|
||||
char* cmd;
|
||||
char* tail;
|
||||
|
||||
if (line[1] == ':' && line[2] == 0)
|
||||
{
|
||||
line[2] = '\\';
|
||||
line[3] = 0;
|
||||
SetCurrentDirectoryA(line);
|
||||
return;
|
||||
}
|
||||
|
||||
tail = line;
|
||||
while ((*tail)!=' ' && (*tail)!=0)
|
||||
{
|
||||
tail++;
|
||||
}
|
||||
if ((*tail)==' ')
|
||||
{
|
||||
*tail = 0;
|
||||
tail++;
|
||||
}
|
||||
cmd = line;
|
||||
|
||||
debug_printf("cmd '%s' tail '%s'\n",cmd,tail);
|
||||
|
||||
if (cmd==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"cd")==0)
|
||||
{
|
||||
ExecuteCd(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"dir")==0)
|
||||
{
|
||||
ExecuteDir(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"type")==0)
|
||||
{
|
||||
ExecuteType(tail);
|
||||
return;
|
||||
}
|
||||
debug_printf("Unknown command\n");
|
||||
}
|
||||
|
||||
void ReadLine(char* line)
|
||||
{
|
||||
KEY_EVENT_RECORD KeyEvent;
|
||||
DWORD Result;
|
||||
UCHAR CurrentDir[255];
|
||||
|
||||
GetCurrentDirectoryA(255,CurrentDir);
|
||||
debug_printf(CurrentDir);
|
||||
|
||||
do
|
||||
{
|
||||
ReadFile(KeyboardHandle,
|
||||
&KeyEvent,
|
||||
sizeof(KEY_EVENT_RECORD),
|
||||
&Result,
|
||||
NULL);
|
||||
if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0)
|
||||
{
|
||||
debug_printf("%c",KeyEvent.AsciiChar);
|
||||
*line = KeyEvent.AsciiChar;
|
||||
line++;
|
||||
}
|
||||
} while (!(KeyEvent.bKeyDown && KeyEvent.AsciiChar == '\n'));
|
||||
line--;
|
||||
*line = 0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
static char line[255];
|
||||
|
||||
NtDisplayString("Shell Starting...\n");
|
||||
|
||||
KeyboardHandle = CreateFile("Keyboard",
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
SetCurrentDirectoryA("C:\\");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ReadLine(line);
|
||||
ExecuteCommand(line);
|
||||
}
|
||||
}
|
||||
|
||||
#include <internal/mmhal.h>
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
OutputDebugStringA(buffer);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
HANDLE KeyboardHandle;
|
||||
|
||||
void ExecuteCd(char* cmdline)
|
||||
{
|
||||
UCHAR Buffer[255];
|
||||
|
||||
debug_printf("ExecuteCd(cmdline %s)\n",cmdline);
|
||||
|
||||
if (cmdline[0] != '\\' &&
|
||||
cmdline[1] != ':')
|
||||
{
|
||||
GetCurrentDirectoryA(255,Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer[0] = 0;
|
||||
}
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
lstrcatA(Buffer,cmdline);
|
||||
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
if (Buffer[lstrlenA(Buffer)-1] != '\\')
|
||||
{
|
||||
lstrcatA(Buffer,"\\");
|
||||
}
|
||||
debug_printf("Buffer %s\n",Buffer);
|
||||
|
||||
SetCurrentDirectoryA(Buffer);
|
||||
}
|
||||
|
||||
void ExecuteDir(char* cmdline)
|
||||
{
|
||||
HANDLE shandle;
|
||||
WIN32_FIND_DATA FindData;
|
||||
|
||||
shandle = FindFirstFile("*.*",&FindData);
|
||||
|
||||
if (shandle==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
debug_printf("Scanning %s\n",FindData.cFileName);
|
||||
} while(FindNextFile(shandle,&FindData));
|
||||
}
|
||||
|
||||
void ExecuteType(char* cmdline)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
char c;
|
||||
DWORD Result;
|
||||
|
||||
FileHandle = CreateFile(cmdline,
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
while (ReadFile(FileHandle,
|
||||
&c,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("%c",c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ExecuteProcess(char* name, char* cmdline)
|
||||
{
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFO StartupInfo;
|
||||
char arguments;
|
||||
|
||||
memset(&StartupInfo,0,sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(STARTUPINFO);
|
||||
StartupInfo.lpTitle = name;
|
||||
|
||||
return(CreateProcessA(name,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
CREATE_NEW_CONSOLE,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation));
|
||||
}
|
||||
|
||||
void ExecuteCommand(char* line)
|
||||
{
|
||||
char* cmd;
|
||||
char* tail;
|
||||
|
||||
if (line[1] == ':' && line[2] == 0)
|
||||
{
|
||||
line[2] = '\\';
|
||||
line[3] = 0;
|
||||
SetCurrentDirectoryA(line);
|
||||
return;
|
||||
}
|
||||
|
||||
tail = line;
|
||||
while ((*tail)!=' ' && (*tail)!=0)
|
||||
{
|
||||
tail++;
|
||||
}
|
||||
if ((*tail)==' ')
|
||||
{
|
||||
*tail = 0;
|
||||
tail++;
|
||||
}
|
||||
cmd = line;
|
||||
|
||||
debug_printf("cmd '%s' tail '%s'\n",cmd,tail);
|
||||
|
||||
if (cmd==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"cd")==0)
|
||||
{
|
||||
ExecuteCd(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"dir")==0)
|
||||
{
|
||||
ExecuteDir(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"type")==0)
|
||||
{
|
||||
ExecuteType(tail);
|
||||
return;
|
||||
}
|
||||
if (ExecuteProcess(cmd,tail))
|
||||
{
|
||||
debug_printf("Done ExecuteProcess\n");
|
||||
return;
|
||||
}
|
||||
debug_printf("Unknown command\n");
|
||||
}
|
||||
|
||||
void ReadLine(char* line)
|
||||
{
|
||||
KEY_EVENT_RECORD KeyEvent;
|
||||
DWORD Result;
|
||||
UCHAR CurrentDir[255];
|
||||
|
||||
GetCurrentDirectoryA(255,CurrentDir);
|
||||
debug_printf(CurrentDir);
|
||||
|
||||
do
|
||||
{
|
||||
ReadFile(KeyboardHandle,
|
||||
&KeyEvent,
|
||||
sizeof(KEY_EVENT_RECORD),
|
||||
&Result,
|
||||
NULL);
|
||||
if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0)
|
||||
{
|
||||
debug_printf("%c",KeyEvent.AsciiChar);
|
||||
*line = KeyEvent.AsciiChar;
|
||||
line++;
|
||||
}
|
||||
} while (!(KeyEvent.bKeyDown && KeyEvent.AsciiChar == '\n'));
|
||||
line--;
|
||||
*line = 0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
static char line[255];
|
||||
|
||||
KERNEL32_Init();
|
||||
|
||||
NtDisplayString("Shell Starting...\n");
|
||||
|
||||
KeyboardHandle = CreateFile("Keyboard",
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
SetCurrentDirectoryA("C:\\");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ReadLine(line);
|
||||
ExecuteCommand(line);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -486,12 +486,7 @@ NtContinue(
|
|||
IN CINT IrqLevel
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ZwContinue(
|
||||
IN PCONTEXT Context,
|
||||
IN CINT IrqLevel
|
||||
);
|
||||
NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,31 +1,34 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/crtdll/stdlib/malloc.c
|
||||
* PURPOSE: stdc memory allocation functions
|
||||
* PROGRAMMER: ??
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <types.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
void* malloc(size_t size)
|
||||
{
|
||||
return(HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
size));
|
||||
return(HeapAlloc(GetProcessHeap(), 0, size));
|
||||
}
|
||||
|
||||
void free(void* ptr)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ptr);
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
}
|
||||
|
||||
void* calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
return(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
nmemb*size));
|
||||
return(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nmemb*size));
|
||||
}
|
||||
|
||||
void* realloc(void* ptr, size_t size)
|
||||
{
|
||||
return(HeapReAlloc(GetProcessHeap(),
|
||||
0,
|
||||
ptr,
|
||||
size));
|
||||
return(HeapReAlloc(GetProcessHeap(), 0, ptr, size));
|
||||
}
|
||||
|
|
68
reactos/lib/kernel32/file/cnotify.c
Normal file
68
reactos/lib/kernel32/file/cnotify.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/find.c
|
||||
* PURPOSE: Find functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
|
||||
WINBOOL
|
||||
FindCloseChangeNotification(
|
||||
HANDLE hChangeHandle
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstChangeNotificationA(
|
||||
LPCSTR lpPathName,
|
||||
WINBOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
WCHAR PathNameW[MAX_PATH];
|
||||
|
||||
|
||||
|
||||
|
||||
i = 0;
|
||||
while ((*lpPathName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
PathNameW[i] = *lpPathName;
|
||||
lpPathName++;
|
||||
i++;
|
||||
}
|
||||
PathNameW[i] = 0;
|
||||
return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstChangeNotificationW(
|
||||
LPCWSTR lpPathName,
|
||||
WINBOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextChangeNotification(
|
||||
HANDLE hChangeHandle
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
450
reactos/lib/kernel32/file/find-bak.c
Normal file
450
reactos/lib/kernel32/file/find-bak.c
Normal file
|
@ -0,0 +1,450 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/find.c
|
||||
* PURPOSE: Find functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
typedef enum _FINDEX_INFO_LEVELS
|
||||
{
|
||||
FindExSearchNameMatch,
|
||||
FindExSearchLimitToDirectories,
|
||||
FindExSearchLimitToDevices,
|
||||
|
||||
} FINDEX_INFO_LEVELS ;
|
||||
|
||||
typedef enum _FINDEX_SEARCH_OPS
|
||||
{
|
||||
FindExInfoStandard
|
||||
|
||||
} FINDEX_SEARCH_OPS;
|
||||
|
||||
int wcharicmp ( WCHAR char1, WCHAR char2 );
|
||||
|
||||
WINBOOL
|
||||
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileW(
|
||||
LPCWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileW(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExA(
|
||||
LPCSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExW(
|
||||
LPCWSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
);
|
||||
|
||||
typedef struct _FIND_FILE_INFO
|
||||
{
|
||||
ULONG Offset;
|
||||
PVOID SearchFilter;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
WCHAR PathName[MAX_PATH];
|
||||
FILE_DIRECTORY_INFORMATION *FileDirectory;
|
||||
} FIND_FILE_INFO;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAW {
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD dwReserved0;
|
||||
DWORD dwReserved1;
|
||||
WCHAR cFileName[ MAX_PATH ];
|
||||
WCHAR cAlternateFileName[ 14 ];
|
||||
} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindClose(
|
||||
HANDLE hFind
|
||||
)
|
||||
{
|
||||
|
||||
if ( hFind == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
|
||||
HeapFree(GetProcessHeap(),0,hFind);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileA(
|
||||
LPCSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileDataW;
|
||||
WCHAR FileNameW[MAX_PATH];
|
||||
ULONG i;
|
||||
|
||||
i = 0;
|
||||
while ((*lpFileName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
FileNameW[i] = *lpFileName;
|
||||
lpFileName++;
|
||||
i++;
|
||||
}
|
||||
FileNameW[i] = 0;
|
||||
FindFirstFileW(FileNameW,&FindFileDataW);
|
||||
|
||||
// converteer FindFileDataW
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileW(
|
||||
LPCWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileA(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileDataW;
|
||||
FindNextFileW(hFind,&FindFileDataW);
|
||||
// converteer FindFileDataW
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileW(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
int i;
|
||||
WCHAR *pNameRead;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
FIND_FILE_INFO *FindPtr = hFind;
|
||||
FILE_DIRECTORY_INFORMATION *FileDirectory;
|
||||
|
||||
if ( FindPtr == NULL )
|
||||
return FALSE;
|
||||
|
||||
/* Try to find a file */
|
||||
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
|
||||
while ( FileDirectory->NextEntryOffset != 0 ) {
|
||||
|
||||
pNameRead = FileDirectory->FileName;
|
||||
FindPtr->Offset += FileDirectory->NextEntryOffset;
|
||||
for(i=0;i<FileDirectory->FileNameLength;i++)
|
||||
dprintf("%c\n",(char)pNameRead[i]);
|
||||
if (mfs_regexp(pNameRead, FindPtr->FileName))
|
||||
{
|
||||
/* We found one! */
|
||||
if (FindPtr->PathName[0] != L'\0')
|
||||
{
|
||||
lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);
|
||||
lstrcatW(lpFindFileData->cFileName, L"/");
|
||||
lstrcatW(lpFindFileData->cFileName, pNameRead);
|
||||
}
|
||||
else
|
||||
|
||||
lstrcpyW(lpFindFileData->cFileName, pNameRead);
|
||||
|
||||
|
||||
|
||||
lstrcpyW(lpFindFileData->cAlternateFileName, L"");
|
||||
lpFindFileData->dwReserved0 = 0;
|
||||
lpFindFileData->dwReserved1 = 0;
|
||||
return TRUE;
|
||||
}
|
||||
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExA(
|
||||
LPCSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
)
|
||||
{
|
||||
WCHAR FileNameW[MAX_PATH];
|
||||
WIN32_FIND_DATAW FindFileDataW;
|
||||
FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);
|
||||
// conerteer FindFileDataW
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExW(
|
||||
LPCWSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle = NULL;
|
||||
FIND_FILE_INFO *hFind;
|
||||
WCHAR *FilePart;
|
||||
UNICODE_STRING FileNameString, PathNameString;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
|
||||
ACCESS_MASK DesiredAccess=FILE_READ_DATA;
|
||||
|
||||
ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
|
||||
ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
ULONG CreateDisposition=FILE_OPEN;
|
||||
ULONG CreateOptions=FILE_DIRECTORY_FILE;
|
||||
|
||||
|
||||
hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
|
||||
|
||||
hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
|
||||
|
||||
|
||||
|
||||
/* Try to find a path and a filename in the passed filename */
|
||||
|
||||
lstrcpyW(hFind->PathName, lpFileName);
|
||||
FilePart = wcsrchr(hFind->PathName, '\\');
|
||||
|
||||
if (FilePart == NULL){
|
||||
GetCurrentDirectory(MAX_PATH, hFind->PathName);
|
||||
lstrcpyW(hFind->FileName, lpFileName);
|
||||
}
|
||||
else {
|
||||
FilePart[0] = L'\0';
|
||||
lstrcpyW(hFind->FileName, &FilePart[1]);
|
||||
}
|
||||
|
||||
hFind->Offset = 0;
|
||||
|
||||
|
||||
PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
|
||||
PathNameString.Buffer = hFind->PathName;
|
||||
PathNameString.MaximumLength = FileNameString.Length;
|
||||
|
||||
|
||||
FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
|
||||
FileNameString.Buffer = hFind->FileName;
|
||||
FileNameString.MaximumLength = FileNameString.Length;
|
||||
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = &PathNameString;
|
||||
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
errCode = NtCreateFile(
|
||||
&FileHandle,
|
||||
DesiredAccess,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL, // AllocationSize
|
||||
FileAttributes,
|
||||
ShareAccess,
|
||||
CreateDisposition,
|
||||
CreateOptions,
|
||||
NULL, // EaBuffer
|
||||
0); //
|
||||
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
printf("%x\n",errCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
errCode = NtQueryDirectoryFile(
|
||||
FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
hFind->FileDirectory,
|
||||
8192,
|
||||
FileDirectoryInformation,
|
||||
FALSE,
|
||||
&FileNameString,
|
||||
FALSE
|
||||
);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
printf("%x\n",errCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ( FindNextFileW(hFind,lpFindFileData) )
|
||||
return hFind;
|
||||
else {
|
||||
FindClose(hFind);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
WINBOOL
|
||||
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)
|
||||
{
|
||||
/* The following code is provided by Tarang and I trust him...
|
||||
*/
|
||||
LPWSTR lpTempFileName = (LPWSTR)lpFileName;
|
||||
LPWSTR lpTempFilter = (LPWSTR)lpFilter;
|
||||
WCHAR TempToken [ 2 ];
|
||||
WCHAR TempFilter [ 2 ];
|
||||
WINBOOL Matched = FALSE;
|
||||
|
||||
if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||
|
||||
( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )
|
||||
return 0L;
|
||||
|
||||
if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )
|
||||
{
|
||||
wsprintf ( TempFilter, "*" );
|
||||
lpTempFilter = TempFilter;
|
||||
lpFilter = TempFilter;
|
||||
}
|
||||
|
||||
while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )
|
||||
{
|
||||
memset ( TempToken, 0, sizeof ( TempToken ) );
|
||||
switch ( *lpTempFilter )
|
||||
{
|
||||
default:
|
||||
if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )
|
||||
{
|
||||
lpTempFileName = (LPWSTR)lpFileName;
|
||||
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
|
||||
if ( lpTempFilter )
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
lpTempFileName+=sizeof(WCHAR);
|
||||
switch ( *lpTempFilter )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case L'\0':
|
||||
case L' ':
|
||||
case L',':
|
||||
case L';':
|
||||
if ( ! *lpTempFileName )
|
||||
Matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case L'?':
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
lpTempFileName+=sizeof(WCHAR);
|
||||
break;
|
||||
|
||||
case L'*':
|
||||
lpTempFilter += sizeof(WCHAR);
|
||||
if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )
|
||||
Matched = TRUE;
|
||||
else
|
||||
{
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&
|
||||
( ! Matched ) ) {
|
||||
lpTempFileName+= sizeof(WCHAR);
|
||||
Matched = mfs_regexp ( lpTempFileName, lpTempFilter );
|
||||
}
|
||||
if ( ( ! lpTempFileName ) && ( ! Matched ) )
|
||||
{
|
||||
lpTempFileName = (LPWSTR)lpFileName;
|
||||
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
|
||||
if ( lpTempFilter )
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case L'\0':
|
||||
case L' ':
|
||||
case L',':
|
||||
case L';':
|
||||
Matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (DWORD)Matched;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int wcharicmp ( WCHAR char1, WCHAR char2 )
|
||||
{
|
||||
WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ?
|
||||
char1 - L'a' + L'A' : char1;
|
||||
WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ?
|
||||
char2 - L'a' + L'A' : char2;
|
||||
return ( Char2 - Char1 );
|
||||
}
|
|
@ -1,521 +1,129 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/find.c
|
||||
* PURPOSE: Find functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
|
||||
typedef enum _FINDEX_INFO_LEVELS
|
||||
{
|
||||
FindExSearchNameMatch,
|
||||
FindExSearchLimitToDirectories,
|
||||
FindExSearchLimitToDevices,
|
||||
|
||||
} FINDEX_INFO_LEVELS ;
|
||||
|
||||
typedef enum _FINDEX_SEARCH_OPS
|
||||
{
|
||||
FindExInfoStandard
|
||||
|
||||
} FINDEX_SEARCH_OPS;
|
||||
|
||||
int wcharicmp ( WCHAR char1, WCHAR char2 );
|
||||
|
||||
WINBOOL
|
||||
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileW(
|
||||
LPWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileW(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExA(
|
||||
LPCSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExW(
|
||||
LPCWSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
);
|
||||
|
||||
typedef struct _FIND_FILE_INFO
|
||||
{
|
||||
ULONG Offset;
|
||||
PVOID SearchFilter;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
WCHAR PathName[MAX_PATH];
|
||||
FILE_DIRECTORY_INFORMATION *FileDirectory;
|
||||
} FIND_FILE_INFO;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
typedef struct _WIN32_FIND_DATAW {
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD dwReserved0;
|
||||
DWORD dwReserved1;
|
||||
WCHAR cFileName[ MAX_PATH ];
|
||||
WCHAR cAlternateFileName[ 14 ];
|
||||
} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
|
||||
*/
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindClose(
|
||||
HANDLE hFind
|
||||
)
|
||||
{
|
||||
|
||||
if ( hFind == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
|
||||
HeapFree(GetProcessHeap(),0,hFind);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileA(
|
||||
LPCSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileDataW;
|
||||
WCHAR FileNameW[MAX_PATH];
|
||||
ULONG i;
|
||||
|
||||
i = 0;
|
||||
while ((*lpFileName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
FileNameW[i] = *lpFileName;
|
||||
lpFileName++;
|
||||
i++;
|
||||
}
|
||||
FileNameW[i] = 0;
|
||||
FindFirstFileW(FileNameW,&FindFileDataW);
|
||||
|
||||
// converteer FindFileDataW
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileW(
|
||||
LPWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileA(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileDataW;
|
||||
FindNextFileW(hFind,&FindFileDataW);
|
||||
// converteer FindFileDataW
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextFileW(
|
||||
HANDLE hFind,
|
||||
LPWIN32_FIND_DATA lpFindFileData
|
||||
)
|
||||
{
|
||||
int i;
|
||||
WCHAR *pNameRead;
|
||||
WCHAR FileName[MAX_PATH];
|
||||
|
||||
FIND_FILE_INFO *FindPtr = hFind;
|
||||
FILE_DIRECTORY_INFORMATION *FileDirectory;
|
||||
|
||||
if ( FindPtr == NULL )
|
||||
return FALSE;
|
||||
|
||||
/* Try to find a file */
|
||||
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
|
||||
while ( FileDirectory->NextEntryOffset != 0 ) {
|
||||
|
||||
pNameRead = FileDirectory->FileName;
|
||||
FindPtr->Offset += FileDirectory->NextEntryOffset;
|
||||
for(i=0;i<FileDirectory->FileNameLength;i++)
|
||||
printf("%c\n",(char)pNameRead[i]);
|
||||
if (mfs_regexp(pNameRead, FindPtr->FileName))
|
||||
{
|
||||
/* We found one! */
|
||||
if (FindPtr->PathName[0] != L'\0')
|
||||
{
|
||||
lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);
|
||||
lstrcatW(lpFindFileData->cFileName, L"/");
|
||||
lstrcatW(lpFindFileData->cFileName, pNameRead);
|
||||
}
|
||||
else
|
||||
|
||||
lstrcpyW(lpFindFileData->cFileName, pNameRead);
|
||||
|
||||
|
||||
|
||||
lstrcpyW(lpFindFileData->cAlternateFileName, L"");
|
||||
lpFindFileData->dwReserved0 = 0;
|
||||
lpFindFileData->dwReserved1 = 0;
|
||||
return TRUE;
|
||||
}
|
||||
FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExA(
|
||||
LPCSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
)
|
||||
{
|
||||
WCHAR FileNameW[MAX_PATH];
|
||||
WIN32_FIND_DATAW FindFileDataW;
|
||||
FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);
|
||||
// conerteer FindFileDataW
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstFileExW(
|
||||
LPCWSTR lpFileName,
|
||||
FINDEX_INFO_LEVELS fInfoLevelId,
|
||||
LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp,
|
||||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE FileHandle = NULL;
|
||||
FIND_FILE_INFO *hFind;
|
||||
WCHAR *FilePart;
|
||||
UNICODE_STRING FileNameString, PathNameString;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
|
||||
ACCESS_MASK DesiredAccess=FILE_READ_DATA;
|
||||
|
||||
ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
|
||||
ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
ULONG CreateDisposition=FILE_OPEN;
|
||||
ULONG CreateOptions=FILE_DIRECTORY_FILE;
|
||||
|
||||
|
||||
hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
|
||||
|
||||
hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
|
||||
|
||||
|
||||
|
||||
/* Try to find a path and a filename in the passed filename */
|
||||
|
||||
lstrcpyW(hFind->PathName, lpFileName);
|
||||
FilePart = wcsrchr(hFind->PathName, '\\');
|
||||
|
||||
if (FilePart == NULL){
|
||||
GetCurrentDirectory(MAX_PATH, hFind->PathName);
|
||||
lstrcpyW(hFind->FileName, lpFileName);
|
||||
}
|
||||
else {
|
||||
FilePart[0] = L'\0';
|
||||
lstrcpyW(hFind->FileName, &FilePart[1]);
|
||||
}
|
||||
|
||||
hFind->Offset = 0;
|
||||
|
||||
|
||||
PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
|
||||
PathNameString.Buffer = hFind->PathName;
|
||||
PathNameString.MaximumLength = FileNameString.Length;
|
||||
|
||||
|
||||
FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
|
||||
FileNameString.Buffer = hFind->FileName;
|
||||
FileNameString.MaximumLength = FileNameString.Length;
|
||||
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = &PathNameString;
|
||||
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
errCode = NtCreateFile(
|
||||
&FileHandle,
|
||||
DesiredAccess,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL, // AllocationSize
|
||||
FileAttributes,
|
||||
ShareAccess,
|
||||
CreateDisposition,
|
||||
CreateOptions,
|
||||
NULL, // EaBuffer
|
||||
0); //
|
||||
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
printf("%x\n",errCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
errCode = NtQueryDirectoryFile(
|
||||
FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
hFind->FileDirectory,
|
||||
8192,
|
||||
FileDirectoryInformation,
|
||||
FALSE,
|
||||
&FileNameString,
|
||||
FALSE
|
||||
);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
printf("%x\n",errCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ( FindNextFileW(hFind,lpFindFileData) )
|
||||
return hFind;
|
||||
else {
|
||||
FindClose(hFind);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
FindCloseChangeNotification(
|
||||
HANDLE hChangeHandle
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstChangeNotificationA(
|
||||
LPCSTR lpPathName,
|
||||
WINBOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
WCHAR PathNameW[MAX_PATH];
|
||||
|
||||
|
||||
|
||||
|
||||
i = 0;
|
||||
while ((*lpPathName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
PathNameW[i] = *lpPathName;
|
||||
lpPathName++;
|
||||
i++;
|
||||
}
|
||||
PathNameW[i] = 0;
|
||||
return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
|
||||
|
||||
}
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
FindFirstChangeNotificationW(
|
||||
LPCWSTR lpPathName,
|
||||
WINBOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
FindNextChangeNotification(
|
||||
HANDLE hChangeHandle
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
WINBOOL
|
||||
mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)
|
||||
{
|
||||
/* The following code is provided by Tarang and I trust him...
|
||||
*/
|
||||
LPWSTR lpTempFileName = (LPWSTR)lpFileName;
|
||||
LPWSTR lpTempFilter = (LPWSTR)lpFilter;
|
||||
WCHAR TempToken [ 2 ];
|
||||
WCHAR TempFilter [ 2 ];
|
||||
WINBOOL Matched = FALSE;
|
||||
|
||||
if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||
|
||||
( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )
|
||||
return 0L;
|
||||
|
||||
if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )
|
||||
{
|
||||
wsprintf ( TempFilter, "*" );
|
||||
lpTempFilter = TempFilter;
|
||||
lpFilter = TempFilter;
|
||||
}
|
||||
|
||||
while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )
|
||||
{
|
||||
memset ( TempToken, 0, sizeof ( TempToken ) );
|
||||
switch ( *lpTempFilter )
|
||||
{
|
||||
default:
|
||||
if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )
|
||||
{
|
||||
lpTempFileName = (LPWSTR)lpFileName;
|
||||
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
|
||||
if ( lpTempFilter )
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
lpTempFileName+=sizeof(WCHAR);
|
||||
switch ( *lpTempFilter )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case L'\0':
|
||||
case L' ':
|
||||
case L',':
|
||||
case L';':
|
||||
if ( ! *lpTempFileName )
|
||||
Matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case L'?':
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
lpTempFileName+=sizeof(WCHAR);
|
||||
break;
|
||||
|
||||
case L'*':
|
||||
lpTempFilter += sizeof(WCHAR);
|
||||
if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )
|
||||
Matched = TRUE;
|
||||
else
|
||||
{
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&
|
||||
( ! Matched ) ) {
|
||||
lpTempFileName+= sizeof(WCHAR);
|
||||
Matched = mfs_regexp ( lpTempFileName, lpTempFilter );
|
||||
}
|
||||
if ( ( ! lpTempFileName ) && ( ! Matched ) )
|
||||
{
|
||||
lpTempFileName = (LPWSTR)lpFileName;
|
||||
lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
|
||||
if ( lpTempFilter )
|
||||
lpTempFilter+=sizeof(WCHAR);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case L'\0':
|
||||
case L' ':
|
||||
case L',':
|
||||
case L';':
|
||||
Matched = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (DWORD)Matched;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int wcharicmp ( WCHAR char1, WCHAR char2 )
|
||||
{
|
||||
WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ?
|
||||
char1 - L'a' + L'A' : char1;
|
||||
WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ?
|
||||
char2 - L'a' + L'A' : char2;
|
||||
return ( Char2 - Char1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/find.c
|
||||
* PURPOSE: Find functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
/* TYPES ********************************************************************/
|
||||
|
||||
typedef struct _KERNEL32_FIND_FILE_DATA
|
||||
{
|
||||
HANDLE DirectoryHandle;
|
||||
FILE_DIRECTORY_INFORMATION FileInfo;
|
||||
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
WCHAR lpFileNameW[MAX_PATH];
|
||||
ULONG i;
|
||||
|
||||
i = 0;
|
||||
while (lpFileName[i]!=0)
|
||||
{
|
||||
lpFileNameW[i] = lpFileName[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
return(FindFirstFileW(lpFileNameW,lpFindFileData));
|
||||
}
|
||||
|
||||
WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
return(FindNextFileW(hFindFile, lpFindFileData));
|
||||
}
|
||||
|
||||
BOOL FindClose(HANDLE hFindFile)
|
||||
{
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
NtClose(IData->DirectoryHandle);
|
||||
HeapFree(GetProcessHeap(), 0, IData);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
WCHAR CurrentDirectory[MAX_PATH];
|
||||
WCHAR Pattern[MAX_PATH];
|
||||
WCHAR Directory[MAX_PATH];
|
||||
PWSTR End;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirectoryNameStr;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
UNICODE_STRING PatternStr;
|
||||
|
||||
dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
|
||||
lpFileName, lpFindFileData);
|
||||
|
||||
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
|
||||
Directory[0] = '\\';
|
||||
Directory[1] = '?';
|
||||
Directory[2] = '?';
|
||||
Directory[3] = '\\';
|
||||
Directory[4] = 0;
|
||||
wcscat(Directory, CurrentDirectory);
|
||||
wcscat(Directory, lpFileName);
|
||||
End = wcschr(Directory, '\\');
|
||||
*End = 0;
|
||||
|
||||
wcscpy(Pattern, End+1);
|
||||
|
||||
dprintf("Directory %w End %w\n",Directory,End);
|
||||
|
||||
IData = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(KERNEL32_FIND_FILE_DATA));
|
||||
|
||||
RtlInitUnicodeString(&DirectoryNameStr, Directory);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirectoryNameStr,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (ZwOpenFile(&IData->DirectoryHandle,
|
||||
FILE_TRAVERSE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
0,
|
||||
OPEN_EXISTING)!=STATUS_SUCCESS)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&PatternStr, Pattern);
|
||||
|
||||
NtQueryDirectoryFile(IData->DirectoryHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
(PVOID)&IData->FileInfo,
|
||||
sizeof(IData->FileInfo),
|
||||
FileDirectoryInformation,
|
||||
TRUE,
|
||||
&PatternStr,
|
||||
FALSE);
|
||||
|
||||
return(IData);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
|
||||
LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
}
|
||||
|
|
124
reactos/lib/kernel32/file/find1.c
Normal file
124
reactos/lib/kernel32/file/find1.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/find.c
|
||||
* PURPOSE: Find functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <wstring.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
/* TYPES ********************************************************************/
|
||||
|
||||
typedef struct _KERNEL32_FIND_FILE_DATA;
|
||||
{
|
||||
HANDLE DirectoryHandle;
|
||||
FILE_DIRECTORY_INFORMATION FileInfo;
|
||||
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
WCHAR lpFileNameW[MAX_PATH];
|
||||
ULONG i;
|
||||
|
||||
i = 0;
|
||||
while (lpFileName[i]!=0)
|
||||
{
|
||||
lpFileName[i] = lpFileName[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
return(FindFirstFileW(lpFileName,lpFindFileData));
|
||||
}
|
||||
|
||||
BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
return(FindNextFileW(hFindFile, lpFindFileData));
|
||||
}
|
||||
|
||||
BOOL FindClose(HANDLE hFindFile)
|
||||
{
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
NtClose(IData->DirectoryHandle);
|
||||
HeapFree(IData);
|
||||
}
|
||||
|
||||
HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
|
||||
LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
WCHAR CurrentDirectory[MAX_PATH];
|
||||
WCHAR Pattern[MAX_PATH];
|
||||
WCHAR Directory[MAX_PATH];
|
||||
PWSTR End;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirectoryNameStr;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
|
||||
lpFileName, lpFindFileData);
|
||||
|
||||
GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
|
||||
Directory[0] = '\\';
|
||||
Directory[1] = '?';
|
||||
Directory[2] = '?';
|
||||
Directory[3] = '\\';
|
||||
Directory[4] = 0;
|
||||
wstrcat(Directory, CurrentDirectory);
|
||||
wstrcat(Directory, lpFileName);
|
||||
End = wstrchr(Directory, '\\');
|
||||
*End = 0;
|
||||
|
||||
wstrcpy(Pattern, End+1);
|
||||
|
||||
dprintf("Directory %w End %w\n",Directory,End);
|
||||
|
||||
IData = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(KERNEL32_FIND_FILE_DATA));
|
||||
|
||||
RtlInitUnicodeString(&DirectoryNameStr, Directory);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirectoryNameStr,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (ZwOpenFile(&IData->DirectoryHandle,
|
||||
FILE_TRAVERSE,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
OPEN_EXISTING)!=STATUS_SUCCESS)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
NtQueryDirectoryFile(IData->DirectoryHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatusBlock,
|
||||
&IData->FileInfo,
|
||||
sizeof(IData->FileInfo),
|
||||
FileDirectoryInformation,
|
||||
TRUE,
|
||||
Pattern,
|
||||
FALSE);
|
||||
|
||||
return(IData);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
|
||||
LPWIN32_FIND_DATA lpFindFileData)
|
||||
{
|
||||
}
|
8
reactos/lib/kernel32/internal/init.c
Normal file
8
reactos/lib/kernel32/internal/init.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
VOID KERNEL32_Init(VOID)
|
||||
{
|
||||
__HeapInit(0, 4*1024*1024, 4*1024*1024);
|
||||
}
|
|
@ -1,379 +0,0 @@
|
|||
/*
|
||||
* linux/lib/vsprintf.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
|
||||
/*
|
||||
* Wirzenius wrote this portably, Torvalds fucked it up :-)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Appropiated for the reactos kernel, March 1998 -- David Welch
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
#include <internal/ctype.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
|
||||
{
|
||||
unsigned long result = 0,value;
|
||||
|
||||
if (!base) {
|
||||
base = 10;
|
||||
if (*cp == '0') {
|
||||
base = 8;
|
||||
cp++;
|
||||
if ((*cp == 'x') && isxdigit(cp[1])) {
|
||||
cp++;
|
||||
base = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
|
||||
? toupper(*cp) : *cp)-'A'+10) < base) {
|
||||
result = result*base + value;
|
||||
cp++;
|
||||
}
|
||||
if (endp)
|
||||
*endp = (char *)cp;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* we use this so that we can do without the ctype library */
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
static int skip_atoi(const char **s)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
while (is_digit(**s))
|
||||
i = i*10 + *((*s)++) - '0';
|
||||
return i;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define PLUS 4 /* show plus */
|
||||
#define SPACE 8 /* space if plus */
|
||||
#define LEFT 16 /* left justified */
|
||||
#define SPECIAL 32 /* 0x */
|
||||
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
#define do_div(n,base) ({ \
|
||||
int __res; \
|
||||
__res = ((unsigned long) n) % (unsigned) base; \
|
||||
n = ((unsigned long) n) / (unsigned) base; \
|
||||
__res; })
|
||||
|
||||
static char * number(char * str, long num, int base, int size, int precision
|
||||
,int type)
|
||||
{
|
||||
char c,sign,tmp[66];
|
||||
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
int i;
|
||||
|
||||
if (type & LARGE)
|
||||
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
if (type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
if (base < 2 || base > 36)
|
||||
return 0;
|
||||
c = (type & ZEROPAD) ? '0' : ' ';
|
||||
sign = 0;
|
||||
if (type & SIGN) {
|
||||
if (num < 0) {
|
||||
sign = '-';
|
||||
num = -num;
|
||||
size--;
|
||||
} else if (type & PLUS) {
|
||||
sign = '+';
|
||||
size--;
|
||||
} else if (type & SPACE) {
|
||||
sign = ' ';
|
||||
size--;
|
||||
}
|
||||
}
|
||||
if (type & SPECIAL) {
|
||||
if (base == 16)
|
||||
size -= 2;
|
||||
else if (base == 8)
|
||||
size--;
|
||||
}
|
||||
i = 0;
|
||||
if (num == 0)
|
||||
tmp[i++]='0';
|
||||
else while (num != 0)
|
||||
tmp[i++] = digits[do_div(num,base)];
|
||||
if (i > precision)
|
||||
precision = i;
|
||||
size -= precision;
|
||||
if (!(type&(ZEROPAD+LEFT)))
|
||||
while(size-->0)
|
||||
*str++ = ' ';
|
||||
if (sign)
|
||||
*str++ = sign;
|
||||
if (type & SPECIAL)
|
||||
if (base==8)
|
||||
*str++ = '0';
|
||||
else if (base==16) {
|
||||
*str++ = '0';
|
||||
*str++ = digits[33];
|
||||
}
|
||||
if (!(type & LEFT))
|
||||
while (size-- > 0)
|
||||
*str++ = c;
|
||||
while (i < precision--)
|
||||
*str++ = '0';
|
||||
while (i-- > 0)
|
||||
*str++ = tmp[i];
|
||||
while (size-- > 0)
|
||||
*str++ = ' ';
|
||||
return str;
|
||||
}
|
||||
|
||||
int vsprintf(char *buf, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
unsigned long num;
|
||||
int i, base;
|
||||
char * str;
|
||||
const char *s;
|
||||
const short int* sw;
|
||||
|
||||
int flags; /* flags to number() */
|
||||
|
||||
int field_width; /* width of output field */
|
||||
int precision; /* min. # of digits for integers; max
|
||||
number of chars for from string */
|
||||
int qualifier; /* 'h', 'l', or 'L' for integer fields */
|
||||
|
||||
for (str=buf ; *fmt ; ++fmt) {
|
||||
if (*fmt != '%') {
|
||||
*str++ = *fmt;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* process flags */
|
||||
flags = 0;
|
||||
repeat:
|
||||
++fmt; /* this also skips first '%' */
|
||||
switch (*fmt) {
|
||||
case '-': flags |= LEFT; goto repeat;
|
||||
case '+': flags |= PLUS; goto repeat;
|
||||
case ' ': flags |= SPACE; goto repeat;
|
||||
case '#': flags |= SPECIAL; goto repeat;
|
||||
case '0': flags |= ZEROPAD; goto repeat;
|
||||
}
|
||||
|
||||
/* get field width */
|
||||
field_width = -1;
|
||||
if (is_digit(*fmt))
|
||||
field_width = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
field_width = va_arg(args, int);
|
||||
if (field_width < 0) {
|
||||
field_width = -field_width;
|
||||
flags |= LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the precision */
|
||||
precision = -1;
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if (is_digit(*fmt))
|
||||
precision = skip_atoi(&fmt);
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
/* it's the next argument */
|
||||
precision = va_arg(args, int);
|
||||
}
|
||||
if (precision < 0)
|
||||
precision = 0;
|
||||
}
|
||||
|
||||
/* get the conversion qualifier */
|
||||
qualifier = -1;
|
||||
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
|
||||
qualifier = *fmt;
|
||||
++fmt;
|
||||
}
|
||||
|
||||
/* default base */
|
||||
base = 10;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'c':
|
||||
if (!(flags & LEFT))
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
*str++ = (unsigned char) va_arg(args, int);
|
||||
while (--field_width > 0)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 'w':
|
||||
sw = va_arg(args,short int *);
|
||||
// DPRINT("L %x\n",sw);
|
||||
if (sw==NULL)
|
||||
{
|
||||
// CHECKPOINT;
|
||||
s = "<NULL>";
|
||||
while ((*s)!=0)
|
||||
{
|
||||
*str++ = *s++;
|
||||
}
|
||||
// CHECKPOINT;
|
||||
// DbgPrint("str %x\n",str);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((*sw)!=0)
|
||||
{
|
||||
*str++ = (char)(*sw++);
|
||||
}
|
||||
}
|
||||
// CHECKPOINT;
|
||||
continue;
|
||||
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
if (!s)
|
||||
s = "<NULL>";
|
||||
|
||||
len = strnlen(s, precision);
|
||||
|
||||
if (!(flags & LEFT))
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
for (i = 0; i < len; ++i)
|
||||
*str++ = *s++;
|
||||
while (len < field_width--)
|
||||
*str++ = ' ';
|
||||
continue;
|
||||
|
||||
case 'p':
|
||||
if (field_width == -1) {
|
||||
field_width = 2*sizeof(void *);
|
||||
flags |= ZEROPAD;
|
||||
}
|
||||
str = number(str,
|
||||
(unsigned long) va_arg(args, void *), 16,
|
||||
field_width, precision, flags);
|
||||
continue;
|
||||
|
||||
|
||||
case 'n':
|
||||
if (qualifier == 'l') {
|
||||
long * ip = va_arg(args, long *);
|
||||
*ip = (str - buf);
|
||||
} else {
|
||||
int * ip = va_arg(args, int *);
|
||||
*ip = (str - buf);
|
||||
}
|
||||
continue;
|
||||
|
||||
/* integer number formats - set up the flags and "break" */
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
base = 2;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
flags |= LARGE;
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
flags |= SIGN;
|
||||
case 'u':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (*fmt != '%')
|
||||
*str++ = '%';
|
||||
if (*fmt)
|
||||
*str++ = *fmt;
|
||||
else
|
||||
--fmt;
|
||||
continue;
|
||||
}
|
||||
if (qualifier == 'l')
|
||||
num = va_arg(args, unsigned long);
|
||||
else if (qualifier == 'h')
|
||||
if (flags & SIGN)
|
||||
num = va_arg(args, short);
|
||||
else
|
||||
num = va_arg(args, unsigned short);
|
||||
else if (flags & SIGN)
|
||||
num = va_arg(args, int);
|
||||
else
|
||||
num = va_arg(args, unsigned int);
|
||||
str = number(str, num, base, field_width, precision, flags);
|
||||
}
|
||||
*str = '\0';
|
||||
return str-buf;
|
||||
}
|
||||
|
||||
int sprintf(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
int wsprintfA(char * buf, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
int wsprintfW(unsigned short * buf, const unsigned short *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
//i=vsprintf(buf,fmt,args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
unsigned short towupper(unsigned short w)
|
||||
{
|
||||
if ( w < L'A' )
|
||||
return w + 'A';
|
||||
else
|
||||
return w;
|
||||
}
|
||||
|
||||
char iswlower(unsigned short w)
|
||||
{
|
||||
if ( w < L'A' )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6,17 +6,17 @@ MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o misc/dllmain.o
|
|||
|
||||
FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
|
||||
file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \
|
||||
file/create.o
|
||||
file/create.o file/find.o file/cnotify.o
|
||||
|
||||
MEM_OBJECTS = mem/virtual.o mem/heap.o mem/utils.o
|
||||
|
||||
THREAD_OBJECTS = thread/thread.o
|
||||
|
||||
PROCESS_OBJECTS = process/proc.o
|
||||
PROCESS_OBJECTS = process/proc.o process/cmdline.o
|
||||
|
||||
STRING_OBJECTS = string/lstring.o
|
||||
|
||||
INTERNAL_OBJECTS = internal/dprintf.o
|
||||
INTERNAL_OBJECTS = internal/dprintf.o internal/init.o
|
||||
|
||||
EXCEPT_OBJECTS = except/except.o
|
||||
|
||||
|
@ -29,7 +29,7 @@ OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
|
|||
|
||||
|
||||
kernel32.a: $(OBJECTS)
|
||||
$(AR) vrcs kernel32.a $(OBJECTS)
|
||||
$(AR) rcs kernel32.a $(OBJECTS)
|
||||
|
||||
dummy:
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static HEAP_BUCKET __HeapDefaultBuckets[]=
|
|||
{ NULL, 256, 15, 4088 },
|
||||
};
|
||||
|
||||
PHEAP __ProcessHeap;
|
||||
PHEAP __ProcessHeap = NULL;
|
||||
|
||||
static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end);
|
||||
static BOOL __HeapDecommit(PHEAP pheap, LPVOID start, LPVOID end);
|
||||
|
@ -61,8 +61,6 @@ static BOOL __HeapFreeFragment(PHEAP pheap, ULONG flags, LPVOID ptr);
|
|||
static PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize,
|
||||
ULONG flags);
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* __HeapCommit *
|
||||
* *
|
||||
|
@ -625,7 +623,7 @@ PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize, ULONG flags)
|
|||
|
||||
VOID WINAPI __HeapInit(LPVOID base, ULONG minsize, ULONG maxsize)
|
||||
{
|
||||
VirtualAlloc(base,maxsize,MEM_RESERVE,PAGE_READWRITE);
|
||||
base = VirtualAlloc(base,maxsize,MEM_RESERVE,PAGE_READWRITE);
|
||||
VirtualAlloc(base,PAGESIZE,MEM_COMMIT,PAGE_READWRITE);
|
||||
|
||||
__HeapPrepare(base, minsize, maxsize, 0);
|
||||
|
|
47
reactos/lib/kernel32/process/cmdline.c
Normal file
47
reactos/lib/kernel32/process/cmdline.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/proc/proc.c
|
||||
* PURPOSE: Process functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <kernel32/proc.h>
|
||||
#include <kernel32/thread.h>
|
||||
#include <wstring.h>
|
||||
#include <string.h>
|
||||
#include <ddk/rtl.h>
|
||||
#include <ddk/li.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
unsigned char CommandLineA[MAX_PATH];
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
LPSTR STDCALL GetCommandLineA(VOID)
|
||||
{
|
||||
WCHAR *CommandLineW;
|
||||
ULONG i = 0;
|
||||
|
||||
CommandLineW = GetCommandLineW();
|
||||
while ((CommandLineW[i])!=0 && i < MAX_PATH)
|
||||
{
|
||||
CommandLineA[i] = (unsigned char)CommandLineW[i];
|
||||
i++;
|
||||
}
|
||||
CommandLineA[i] = 0;
|
||||
return CommandLineA;
|
||||
}
|
||||
|
||||
LPWSTR STDCALL GetCommandLineW(VOID)
|
||||
{
|
||||
return GetCurrentPeb()->StartupInfo->CommandLine;
|
||||
}
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <kernel32/proc.h>
|
||||
|
@ -16,6 +19,8 @@
|
|||
#include <ddk/rtl.h>
|
||||
#include <ddk/li.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
extern NT_PEB *CurrentPeb;
|
||||
extern NT_PEB Peb;
|
||||
|
||||
|
@ -23,10 +28,9 @@ WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
|
|||
|
||||
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
|
||||
|
||||
NT_PEB *GetCurrentPeb(VOID)
|
||||
{
|
||||
|
@ -46,304 +50,334 @@ HANDLE STDCALL GetCurrentThread(VOID)
|
|||
return (HANDLE)NtCurrentThread();
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetCurrentProcessId(VOID)
|
||||
{
|
||||
|
||||
return (DWORD)(GetTeb()->Cid).UniqueProcess;
|
||||
|
||||
|
||||
DWORD STDCALL GetCurrentProcessId(VOID)
|
||||
{
|
||||
return (DWORD)(GetTeb()->Cid).UniqueProcess;
|
||||
}
|
||||
|
||||
unsigned char CommandLineA[MAX_PATH];
|
||||
|
||||
LPSTR
|
||||
STDCALL
|
||||
GetCommandLineA(
|
||||
VOID
|
||||
)
|
||||
WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
|
||||
{
|
||||
WCHAR *CommandLineW;
|
||||
ULONG i = 0;
|
||||
|
||||
CommandLineW = GetCommandLineW();
|
||||
while ((CommandLineW[i])!=0 && i < MAX_PATH)
|
||||
{
|
||||
CommandLineA[i] = (unsigned char)CommandLineW[i];
|
||||
i++;
|
||||
}
|
||||
CommandLineA[i] = 0;
|
||||
return CommandLineA;
|
||||
}
|
||||
LPWSTR
|
||||
STDCALL
|
||||
GetCommandLineW(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return GetCurrentPeb()->StartupInfo->CommandLine;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetExitCodeProcess(
|
||||
HANDLE hProcess,
|
||||
LPDWORD lpExitCode
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasic;
|
||||
ULONG BytesWritten;
|
||||
|
||||
errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetProcessId(
|
||||
HANDLE hProcess,
|
||||
LPDWORD lpProcessId
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasic;
|
||||
ULONG BytesWritten;
|
||||
|
||||
errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
CreateProcessA(
|
||||
LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
WINBOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFO lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation
|
||||
)
|
||||
{
|
||||
WCHAR ApplicationNameW[MAX_PATH];
|
||||
WCHAR CommandLineW[MAX_PATH];
|
||||
WCHAR CurrentDirectoryW[MAX_PATH];
|
||||
|
||||
|
||||
ULONG i;
|
||||
|
||||
i = 0;
|
||||
while ((*lpApplicationName)!=0 && i < MAX_PATH)
|
||||
{
|
||||
ApplicationNameW[i] = *lpApplicationName;
|
||||
lpApplicationName++;
|
||||
i++;
|
||||
}
|
||||
ApplicationNameW[i] = 0;
|
||||
|
||||
|
||||
i = 0;
|
||||
while ((*lpCommandLine)!=0 && i < MAX_PATH)
|
||||
{
|
||||
CommandLineW[i] = *lpCommandLine;
|
||||
lpCommandLine++;
|
||||
i++;
|
||||
}
|
||||
CommandLineW[i] = 0;
|
||||
|
||||
i = 0;
|
||||
while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
|
||||
{
|
||||
CurrentDirectoryW[i] = *lpCurrentDirectory;
|
||||
lpCurrentDirectory++;
|
||||
i++;
|
||||
}
|
||||
CurrentDirectoryW[i] = 0;
|
||||
|
||||
return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
|
||||
bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
|
||||
lpProcessInformation);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
CreateProcessW(
|
||||
LPCWSTR lpApplicationName,
|
||||
LPWSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
WINBOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCWSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFO lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation
|
||||
)
|
||||
{
|
||||
HANDLE hFile, hSection, hProcess, hThread;
|
||||
KPRIORITY PriorityClass;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
BOOLEAN CreateSuspended;
|
||||
|
||||
NTSTATUS errCode;
|
||||
|
||||
UNICODE_STRING ApplicationNameString;
|
||||
|
||||
|
||||
|
||||
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
|
||||
LPVOID lpParameter = NULL;
|
||||
|
||||
hFile = NULL;
|
||||
|
||||
ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
|
||||
NTSTATUS errCode;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasic;
|
||||
ULONG BytesWritten;
|
||||
|
||||
ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
|
||||
ApplicationNameString.MaximumLength = ApplicationNameString.Length;
|
||||
errCode = NtQueryInformationProcess(hProcess,
|
||||
ProcessBasicInformation,
|
||||
&ProcessBasic,
|
||||
sizeof(PROCESS_BASIC_INFORMATION),
|
||||
&BytesWritten);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
|
||||
|
||||
|
||||
if ( lpProcessAttributes != NULL ) {
|
||||
if ( lpProcessAttributes->bInheritHandle )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
else
|
||||
ObjectAttributes.Attributes = 0;
|
||||
ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
|
||||
|
||||
errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
|
||||
&IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
|
||||
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
|
||||
NtClose(hFile);
|
||||
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if ( lpProcessAttributes != NULL ) {
|
||||
if ( lpProcessAttributes->bInheritHandle )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
else
|
||||
ObjectAttributes.Attributes = 0;
|
||||
ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
|
||||
errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
|
||||
NtClose(hSection);
|
||||
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PriorityClass = NORMAL_PRIORITY_CLASS;
|
||||
NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
|
||||
|
||||
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED)
|
||||
CreateSuspended = TRUE;
|
||||
else
|
||||
CreateSuspended = FALSE;
|
||||
|
||||
hThread = CreateRemoteThread(
|
||||
hProcess,
|
||||
lpThreadAttributes,
|
||||
4096, // 1 page ??
|
||||
lpStartAddress,
|
||||
lpParameter,
|
||||
CREATE_SUSPENDED,
|
||||
&lpProcessInformation->dwThreadId
|
||||
);
|
||||
|
||||
|
||||
if ( hThread == NULL )
|
||||
return FALSE;
|
||||
|
||||
|
||||
|
||||
lpProcessInformation->hProcess = hProcess;
|
||||
lpProcessInformation->hThread = hThread;
|
||||
|
||||
|
||||
|
||||
|
||||
GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
|
||||
|
||||
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
OpenProcess(
|
||||
DWORD dwDesiredAccess,
|
||||
WINBOOL bInheritHandle,
|
||||
DWORD dwProcessId
|
||||
)
|
||||
WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId )
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasic;
|
||||
ULONG BytesWritten;
|
||||
|
||||
errCode = NtQueryInformationProcess(hProcess,
|
||||
ProcessBasicInformation,
|
||||
&ProcessBasic,
|
||||
sizeof(PROCESS_BASIC_INFORMATION),
|
||||
&BytesWritten);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (In == NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
while ((*In)!=0 && i < MaxLength)
|
||||
{
|
||||
Out[i] = *In;
|
||||
In++;
|
||||
i++;
|
||||
}
|
||||
Out[i] = 0;
|
||||
return(Out);
|
||||
}
|
||||
}
|
||||
|
||||
WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
WINBOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFO lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation)
|
||||
/*
|
||||
* FUNCTION: The CreateProcess function creates a new process and its
|
||||
* primary thread. The new process executes the specified executable file
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* lpApplicationName = Pointer to name of executable module
|
||||
* lpCommandLine = Pointer to command line string
|
||||
* lpProcessAttributes = Process security attributes
|
||||
* lpThreadAttributes = Thread security attributes
|
||||
* bInheritHandles = Handle inheritance flag
|
||||
* dwCreationFlags = Creation flags
|
||||
* lpEnvironment = Pointer to new environment block
|
||||
* lpCurrentDirectory = Pointer to current directory name
|
||||
* lpStartupInfo = Pointer to startup info
|
||||
* lpProcessInformation = Pointer to process information
|
||||
*/
|
||||
{
|
||||
WCHAR ApplicationNameW[MAX_PATH];
|
||||
WCHAR CommandLineW[MAX_PATH];
|
||||
WCHAR CurrentDirectoryW[MAX_PATH];
|
||||
PWSTR PApplicationNameW;
|
||||
PWSTR PCommandLineW;
|
||||
PWSTR PCurrentDirectoryW;
|
||||
ULONG i;
|
||||
|
||||
OutputDebugStringA("CreateProcessA\n");
|
||||
|
||||
PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
|
||||
lpApplicationName,
|
||||
MAX_PATH);
|
||||
PCommandLineW = InternalAnsiToUnicode(CommandLineW,
|
||||
lpCommandLine,
|
||||
MAX_PATH);
|
||||
PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
|
||||
lpCurrentDirectory,
|
||||
MAX_PATH);
|
||||
return CreateProcessW(PApplicationNameW,
|
||||
PCommandLineW,
|
||||
lpProcessAttributes,
|
||||
lpThreadAttributes,
|
||||
bInheritHandles,
|
||||
dwCreationFlags,
|
||||
lpEnvironment,
|
||||
PCurrentDirectoryW,
|
||||
lpStartupInfo,
|
||||
lpProcessInformation);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS errCode;
|
||||
HANDLE ProcessHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId ;
|
||||
|
||||
ClientId.UniqueProcess = (HANDLE)dwProcessId;
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = (HANDLE)NULL;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
|
||||
LPWSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
WINBOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCWSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFO lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation)
|
||||
{
|
||||
HANDLE hFile, hSection, hProcess, hThread;
|
||||
KPRIORITY PriorityClass;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
BOOLEAN CreateSuspended;
|
||||
NTSTATUS errCode;
|
||||
UNICODE_STRING ApplicationNameString;
|
||||
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
|
||||
LPVOID lpParameter = NULL;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||
WCHAR TempApplicationName[255];
|
||||
WCHAR TempFileName[255];
|
||||
WCHAR TempDirectoryName[255];
|
||||
ULONG i;
|
||||
ULONG BaseAddress;
|
||||
ULONG Size;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
|
||||
dprintf("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
|
||||
lpApplicationName,lpCommandLine);
|
||||
|
||||
hFile = NULL;
|
||||
|
||||
/*
|
||||
* Find the application name
|
||||
*/
|
||||
TempApplicationName[0] = '\\';
|
||||
TempApplicationName[1] = '?';
|
||||
TempApplicationName[2] = '?';
|
||||
TempApplicationName[3] = '\\';
|
||||
TempApplicationName[4] = 0;
|
||||
|
||||
dprintf("TempApplicationName '%w'\n",TempApplicationName);
|
||||
|
||||
if (lpApplicationName != NULL)
|
||||
{
|
||||
wcscpy(TempFileName, lpApplicationName);
|
||||
|
||||
if ( bInheritHandle == TRUE )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
else
|
||||
ObjectAttributes.Attributes = 0;
|
||||
dprintf("TempFileName '%w'\n",TempFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy(TempFileName, lpCommandLine);
|
||||
|
||||
dprintf("TempFileName '%w'\n",TempFileName);
|
||||
|
||||
for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
|
||||
TempFileName[i]=0;
|
||||
|
||||
}
|
||||
if (TempFileName[1] != ':')
|
||||
{
|
||||
GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
|
||||
wcscat(TempApplicationName,TempDirectoryName);
|
||||
}
|
||||
wcscat(TempApplicationName,TempFileName);
|
||||
|
||||
RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
|
||||
|
||||
dprintf("ApplicationName %w\n",ApplicationNameString.Buffer);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&ApplicationNameString,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
|
||||
errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return NULL;
|
||||
}
|
||||
return ProcessHandle;
|
||||
/*
|
||||
* Try to open the executable
|
||||
*/
|
||||
|
||||
errCode = NtOpenFile(&hFile,
|
||||
SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_DELETE|FILE_SHARE_READ,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
|
||||
|
||||
if ( !NT_SUCCESS(errCode) )
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
errCode = NtCreateSection(&hSection,
|
||||
SECTION_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
PAGE_EXECUTE,
|
||||
SEC_IMAGE,
|
||||
hFile);
|
||||
NtClose(hFile);
|
||||
|
||||
if ( !NT_SUCCESS(errCode) )
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
errCode = NtCreateProcess(&hProcess,
|
||||
PROCESS_ALL_ACCESS,
|
||||
NULL,
|
||||
NtCurrentProcess(),
|
||||
bInheritHandles,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
BaseAddress = (PVOID)0x10000;
|
||||
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
|
||||
Size = 0x10000;
|
||||
NtMapViewOfSection(hSection,
|
||||
hProcess,
|
||||
&BaseAddress,
|
||||
0,
|
||||
Size,
|
||||
&SectionOffset,
|
||||
&Size,
|
||||
0,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
|
||||
|
||||
NtClose(hSection);
|
||||
|
||||
if ( !NT_SUCCESS(errCode) )
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
PriorityClass = NORMAL_PRIORITY_CLASS;
|
||||
NtSetInformationProcess(hProcess,
|
||||
ProcessBasePriority,
|
||||
&PriorityClass,
|
||||
sizeof(KPRIORITY));
|
||||
#endif
|
||||
dprintf("Creating thread for process\n");
|
||||
lpStartAddress = BaseAddress;
|
||||
hThread = CreateRemoteThread(hProcess,
|
||||
lpThreadAttributes,
|
||||
4096, // 1 page ??
|
||||
lpStartAddress,
|
||||
lpParameter,
|
||||
dwCreationFlags,
|
||||
&lpProcessInformation->dwThreadId);
|
||||
|
||||
if ( hThread == NULL )
|
||||
return FALSE;
|
||||
|
||||
lpProcessInformation->hProcess = hProcess;
|
||||
lpProcessInformation->hThread = hThread;
|
||||
|
||||
GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
|
||||
WINBOOL bInheritHandle,
|
||||
DWORD dwProcessId)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
HANDLE ProcessHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId ;
|
||||
|
||||
ClientId.UniqueProcess = (HANDLE)dwProcessId;
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = (HANDLE)NULL;
|
||||
ObjectAttributes.SecurityDescriptor = NULL;
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
if ( bInheritHandle == TRUE )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
else
|
||||
ObjectAttributes.Attributes = 0;
|
||||
|
||||
errCode = NtOpenProcess(&ProcessHandle,
|
||||
dwDesiredAccess,
|
||||
&ObjectAttributes,
|
||||
&ClientId);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return NULL;
|
||||
}
|
||||
return ProcessHandle;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,362 +1,379 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/thread/thread.c
|
||||
* PURPOSE: Thread functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
Tls functions are modified from WINE
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <kernel32/thread.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateThread(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,
|
||||
lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
HANDLE ThreadHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId;
|
||||
CONTEXT ThreadContext;
|
||||
INITIAL_TEB InitialTeb;
|
||||
BOOLEAN CreateSuspended = FALSE;
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = NULL;
|
||||
ObjectAttributes.Attributes = 0;
|
||||
if ( lpThreadAttributes != NULL ) {
|
||||
if ( lpThreadAttributes->bInheritHandle )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
|
||||
CreateSuspended = TRUE;
|
||||
else
|
||||
CreateSuspended = FALSE;
|
||||
// fix context
|
||||
GetThreadContext(NtCurrentThread(),&ThreadContext);
|
||||
// fix teb [ stack context ] --> check the image file
|
||||
|
||||
errCode = NtCreateThread(
|
||||
&ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
hProcess,
|
||||
&ClientId,
|
||||
&ThreadContext,
|
||||
&InitialTeb,
|
||||
CreateSuspended
|
||||
);
|
||||
if ( lpThreadId != NULL )
|
||||
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
||||
|
||||
return ThreadHandle;
|
||||
}
|
||||
|
||||
NT_TEB *GetTeb(VOID)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
SwitchToThread(VOID )
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtYieldExecution();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetCurrentThreadId()
|
||||
{
|
||||
|
||||
return (DWORD)(GetTeb()->Cid).UniqueThread;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
ExitThread(
|
||||
UINT uExitCode
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtTerminateThread(
|
||||
NtCurrentThread() ,
|
||||
uExitCode
|
||||
);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetThreadTimes(
|
||||
HANDLE hThread,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpExitTime,
|
||||
LPFILETIME lpKernelTime,
|
||||
LPFILETIME lpUserTime
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
KERNEL_USER_TIMES KernelUserTimes;
|
||||
ULONG ReturnLength;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
|
||||
memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
|
||||
memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
|
||||
memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL GetThreadContext(
|
||||
HANDLE hThread,
|
||||
LPCONTEXT lpContext
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtGetContextThread(hThread,lpContext);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadContext(
|
||||
HANDLE hThread,
|
||||
CONST CONTEXT *lpContext
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtSetContextThread(hThread,(void *)lpContext);
|
||||
if (!NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetExitCodeThread(
|
||||
HANDLE hThread,
|
||||
LPDWORD lpExitCode
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
ResumeThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousResumeCount;
|
||||
|
||||
errCode = NtResumeThread(hThread,&PreviousResumeCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousResumeCount;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SuspendThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousSuspendCount;
|
||||
|
||||
errCode = NtSuspendThread(hThread,&PreviousSuspendCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousSuspendCount;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SetThreadAffinityMask(
|
||||
HANDLE hThread,
|
||||
DWORD dwThreadAffinityMask
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadPriority(
|
||||
HANDLE hThread,
|
||||
int nPriority
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
ThreadBasic.BasePriority = nPriority;
|
||||
errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
STDCALL
|
||||
GetThreadPriority(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return THREAD_PRIORITY_ERROR_RETURN;
|
||||
}
|
||||
return ThreadBasic.BasePriority;
|
||||
}
|
||||
|
||||
|
||||
/* (WIN32) Thread Local Storage ******************************************** */
|
||||
|
||||
DWORD STDCALL
|
||||
TlsAlloc(VOID)
|
||||
{
|
||||
DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
TlsData[dwTlsIndex] = NULL;
|
||||
return (dwTlsIndex++);
|
||||
}
|
||||
return (0xFFFFFFFFUL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsFree(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
LPVOID STDCALL
|
||||
TlsGetValue(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
return (TlsData[dwTlsIndex]);
|
||||
}
|
||||
SetLastError(1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
TlsData[dwTlsIndex] = lpTlsValue;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/thread/thread.c
|
||||
* PURPOSE: Thread functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
Tls functions are modified from WINE
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <kernel32/thread.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <string.h>
|
||||
#include <internal/i386/segment.h>
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateThread(
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,
|
||||
lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
CreateRemoteThread(
|
||||
HANDLE hProcess,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
DWORD dwStackSize,
|
||||
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||
LPVOID lpParameter,
|
||||
DWORD dwCreationFlags,
|
||||
LPDWORD lpThreadId
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
HANDLE ThreadHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
CLIENT_ID ClientId;
|
||||
CONTEXT ThreadContext;
|
||||
INITIAL_TEB InitialTeb;
|
||||
BOOLEAN CreateSuspended = FALSE;
|
||||
ULONG BaseAddress;
|
||||
|
||||
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory = NULL;
|
||||
ObjectAttributes.ObjectName = NULL;
|
||||
ObjectAttributes.Attributes = 0;
|
||||
if ( lpThreadAttributes != NULL ) {
|
||||
if ( lpThreadAttributes->bInheritHandle )
|
||||
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||
ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||
|
||||
if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
|
||||
CreateSuspended = TRUE;
|
||||
else
|
||||
CreateSuspended = FALSE;
|
||||
|
||||
BaseAddress = 0;
|
||||
ZwAllocateVirtualMemory(hProcess,
|
||||
&BaseAddress,
|
||||
0,
|
||||
&dwStackSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
|
||||
|
||||
memset(&ThreadContext,0,sizeof(CONTEXT));
|
||||
ThreadContext.Eip = lpStartAddress;
|
||||
ThreadContext.SegGs = USER_DS;
|
||||
ThreadContext.SegFs = USER_DS;
|
||||
ThreadContext.SegEs = USER_DS;
|
||||
ThreadContext.SegDs = USER_DS;
|
||||
ThreadContext.SegCs = USER_CS;
|
||||
ThreadContext.SegSs = USER_DS;
|
||||
ThreadContext.Esp = BaseAddress + dwStackSize;
|
||||
ThreadContext.EFlags = (1<<1) + (1<<9);
|
||||
|
||||
|
||||
errCode = NtCreateThread(&ThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
hProcess,
|
||||
&ClientId,
|
||||
&ThreadContext,
|
||||
&InitialTeb,
|
||||
CreateSuspended);
|
||||
if ( lpThreadId != NULL )
|
||||
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
||||
|
||||
return ThreadHandle;
|
||||
}
|
||||
|
||||
NT_TEB *GetTeb(VOID)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
SwitchToThread(VOID )
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtYieldExecution();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
GetCurrentThreadId()
|
||||
{
|
||||
|
||||
return (DWORD)(GetTeb()->Cid).UniqueThread;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
ExitThread(
|
||||
UINT uExitCode
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtTerminateThread(
|
||||
NtCurrentThread() ,
|
||||
uExitCode
|
||||
);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetThreadTimes(
|
||||
HANDLE hThread,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpExitTime,
|
||||
LPFILETIME lpKernelTime,
|
||||
LPFILETIME lpUserTime
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
KERNEL_USER_TIMES KernelUserTimes;
|
||||
ULONG ReturnLength;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));
|
||||
memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));
|
||||
memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));
|
||||
memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL GetThreadContext(
|
||||
HANDLE hThread,
|
||||
LPCONTEXT lpContext
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
errCode = NtGetContextThread(hThread,lpContext);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadContext(
|
||||
HANDLE hThread,
|
||||
CONST CONTEXT *lpContext
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
|
||||
errCode = NtSetContextThread(hThread,(void *)lpContext);
|
||||
if (!NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
GetExitCodeThread(
|
||||
HANDLE hThread,
|
||||
LPDWORD lpExitCode
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
ResumeThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousResumeCount;
|
||||
|
||||
errCode = NtResumeThread(hThread,&PreviousResumeCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousResumeCount;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SuspendThread(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
ULONG PreviousSuspendCount;
|
||||
|
||||
errCode = NtSuspendThread(hThread,&PreviousSuspendCount );
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return -1;
|
||||
}
|
||||
return PreviousSuspendCount;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
SetThreadAffinityMask(
|
||||
HANDLE hThread,
|
||||
DWORD dwThreadAffinityMask
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL
|
||||
STDCALL
|
||||
SetThreadPriority(
|
||||
HANDLE hThread,
|
||||
int nPriority
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
ThreadBasic.BasePriority = nPriority;
|
||||
errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
STDCALL
|
||||
GetThreadPriority(
|
||||
HANDLE hThread
|
||||
)
|
||||
{
|
||||
NTSTATUS errCode;
|
||||
THREAD_BASIC_INFORMATION ThreadBasic;
|
||||
ULONG DataWritten;
|
||||
errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);
|
||||
if ( !NT_SUCCESS(errCode) ) {
|
||||
SetLastError(RtlNtStatusToDosError(errCode));
|
||||
return THREAD_PRIORITY_ERROR_RETURN;
|
||||
}
|
||||
return ThreadBasic.BasePriority;
|
||||
}
|
||||
|
||||
|
||||
/* (WIN32) Thread Local Storage ******************************************** */
|
||||
|
||||
DWORD STDCALL
|
||||
TlsAlloc(VOID)
|
||||
{
|
||||
DWORD dwTlsIndex = GetTeb()->dwTlsIndex;
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
TlsData[dwTlsIndex] = NULL;
|
||||
return (dwTlsIndex++);
|
||||
}
|
||||
return (0xFFFFFFFFUL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsFree(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
LPVOID STDCALL
|
||||
TlsGetValue(DWORD dwTlsIndex)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
SetLastError(NO_ERROR);
|
||||
return (TlsData[dwTlsIndex]);
|
||||
}
|
||||
SetLastError(1);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
WINBOOL STDCALL
|
||||
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
|
||||
|
||||
void **TlsData = GetTeb()->TlsData;
|
||||
|
||||
|
||||
if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))
|
||||
{
|
||||
|
||||
TlsData[dwTlsIndex] = lpTlsValue;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
all: ntdll.a
|
||||
|
||||
OBJECTS = napi.o stubs/stubs.o string/wstring.o stdio/vsprintf.o
|
||||
OBJECTS = napi.o stubs/stubs.o string/wstring.o stdio/vsprintf.o \
|
||||
rtl/unicode.o rtl/namespc.o
|
||||
|
||||
ntdll.a: $(OBJECTS)
|
||||
$(AR) vcsr ntdll.a $(OBJECTS)
|
||||
|
|
|
@ -71,6 +71,7 @@ wchar_t* wcscpy(wchar_t* str1, const wchar_t* str2)
|
|||
s++;
|
||||
str2++;
|
||||
}
|
||||
*s = 0;
|
||||
return(str1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <windows.h>
|
||||
|
||||
#define STUB(x) void x(void) { NtDisplayString("NTDLL: Stub for "#x); }
|
||||
#define STUB(x) void x(void) { NtDisplayString("NTDLL: Stub for "#x"\n"); }
|
||||
|
||||
// ?Allocate@CBufferAllocator@@UAEPAXK@Z
|
||||
STUB(PropertyLengthAsVariant)
|
||||
|
@ -78,12 +78,8 @@ STUB(RtlAllocateAndInitializeSid)
|
|||
STUB(RtlAllocateHandle)
|
||||
STUB(RtlAllocateHeap)
|
||||
STUB(RtlAnsiCharToUnicodeChar)
|
||||
STUB(RtlAnsiStringToUnicodeSize)
|
||||
STUB(RtlAnsiStringToUnicodeString)
|
||||
STUB(RtlAppendAsciizToString)
|
||||
STUB(RtlAppendStringToString)
|
||||
STUB(RtlAppendUnicodeStringToString)
|
||||
STUB(RtlAppendUnicodeToString)
|
||||
STUB(RtlApplyRXact)
|
||||
STUB(RtlApplyRXactNoFlush)
|
||||
STUB(RtlAreAllAccessesGranted)
|
||||
|
@ -92,7 +88,6 @@ STUB(RtlAreBitsClear)
|
|||
STUB(RtlAreBitsSet)
|
||||
STUB(RtlAssert)
|
||||
STUB(RtlCaptureStackBackTrace)
|
||||
STUB(RtlCharToInteger)
|
||||
STUB(RtlCheckRegistryKey)
|
||||
STUB(RtlClearAllBits)
|
||||
STUB(RtlClearBits)
|
||||
|
@ -100,8 +95,6 @@ STUB(RtlClosePropertySet)
|
|||
STUB(RtlCompactHeap)
|
||||
STUB(RtlCompareMemory)
|
||||
STUB(RtlCompareMemoryUlong)
|
||||
STUB(RtlCompareString)
|
||||
STUB(RtlCompareUnicodeString)
|
||||
STUB(RtlCompressBuffer)
|
||||
STUB(RtlConsoleMultiByteToUnicodeN)
|
||||
STUB(RtlConvertExclusiveToShared)
|
||||
|
@ -115,8 +108,6 @@ STUB(RtlCopyLuidAndAttributesArray)
|
|||
STUB(RtlCopySecurityDescriptor)
|
||||
STUB(RtlCopySid)
|
||||
STUB(RtlCopySidAndAttributesArray)
|
||||
STUB(RtlCopyString)
|
||||
STUB(RtlCopyUnicodeString)
|
||||
STUB(RtlCreateAcl)
|
||||
STUB(RtlCreateAndSetSD)
|
||||
STUB(RtlCreateAtomTable)
|
||||
|
@ -173,8 +164,6 @@ STUB(RtlEqualDomainName)
|
|||
STUB(RtlEqualLuid)
|
||||
STUB(RtlEqualPrefixSid)
|
||||
STUB(RtlEqualSid)
|
||||
STUB(RtlEqualString)
|
||||
STUB(RtlEqualUnicodeString)
|
||||
STUB(RtlEraseUnicodeString)
|
||||
STUB(RtlExpandEnvironmentStrings_U)
|
||||
STUB(RtlExtendHeap)
|
||||
|
@ -194,12 +183,10 @@ STUB(RtlFirstFreeAce)
|
|||
STUB(RtlFlushPropertySet)
|
||||
STUB(RtlFormatCurrentUserKeyPath)
|
||||
STUB(RtlFormatMessage)
|
||||
STUB(RtlFreeAnsiString)
|
||||
STUB(RtlFreeHandle)
|
||||
STUB(RtlFreeHeap)
|
||||
STUB(RtlFreeOemString)
|
||||
STUB(RtlFreeSid)
|
||||
STUB(RtlFreeUnicodeString)
|
||||
STUB(RtlFreeUserThreadStack)
|
||||
STUB(RtlGenerate8dot3Name)
|
||||
STUB(RtlGetAce)
|
||||
|
@ -225,11 +212,8 @@ STUB(RtlImageNtHeader)
|
|||
STUB(RtlImageRvaToSection)
|
||||
STUB(RtlImageRvaToVa)
|
||||
STUB(RtlImpersonateSelf)
|
||||
STUB(RtlInitAnsiString)
|
||||
STUB(RtlInitCodePageTable)
|
||||
STUB(RtlInitNlsTables)
|
||||
STUB(RtlInitString)
|
||||
STUB(RtlInitUnicodeString)
|
||||
STUB(RtlInitializeAtomPackage)
|
||||
STUB(RtlInitializeBitMap)
|
||||
STUB(RtlInitializeContext)
|
||||
|
@ -242,7 +226,6 @@ STUB(RtlInitializeResource)
|
|||
STUB(RtlInitializeSid)
|
||||
STUB(RtlInsertElementGenericTable)
|
||||
STUB(RtlIntegerToChar)
|
||||
STUB(RtlIntegerToUnicodeString)
|
||||
STUB(RtlIsDosDeviceName_U)
|
||||
STUB(RtlIsGenericTableEmpty)
|
||||
STUB(RtlIsNameLegalDOS8Dot3)
|
||||
|
@ -353,9 +336,7 @@ STUB(RtlTimeToSecondsSince1980)
|
|||
STUB(RtlTimeToTimeFields)
|
||||
STUB(RtlTryEnterCriticalSection)
|
||||
STUB(RtlUnicodeStringToAnsiSize)
|
||||
STUB(RtlUnicodeStringToAnsiString)
|
||||
STUB(RtlUnicodeStringToCountedOemString)
|
||||
STUB(RtlUnicodeStringToInteger)
|
||||
STUB(RtlUnicodeStringToOemSize)
|
||||
STUB(RtlUnicodeStringToOemString)
|
||||
STUB(RtlUnicodeToCustomCPN)
|
||||
|
@ -366,7 +347,6 @@ STUB(RtlUniform)
|
|||
STUB(RtlUnlockHeap)
|
||||
STUB(RtlUnwind)
|
||||
STUB(RtlUpcaseUnicodeChar)
|
||||
STUB(RtlUpcaseUnicodeString)
|
||||
STUB(RtlUpcaseUnicodeStringToAnsiString)
|
||||
STUB(RtlUpcaseUnicodeStringToCountedOemString)
|
||||
STUB(RtlUpcaseUnicodeStringToOemString)
|
||||
|
@ -374,7 +354,6 @@ STUB(RtlUpcaseUnicodeToCustomCPN)
|
|||
STUB(RtlUpcaseUnicodeToMultiByteN)
|
||||
STUB(RtlUpcaseUnicodeToOemN)
|
||||
STUB(RtlUpperChar)
|
||||
STUB(RtlUpperString)
|
||||
STUB(RtlUsageHeap)
|
||||
STUB(RtlValidAcl)
|
||||
STUB(RtlValidSecurityDescriptor)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -31,7 +31,7 @@ LOADERS = dos
|
|||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
KERNEL_SERVICES = parallel keyboard null mouse serial sound ide test sdisk \
|
||||
minix vfat # ext2fs
|
||||
minix vfat ext2
|
||||
|
||||
APPS = hello shell
|
||||
|
||||
|
@ -104,8 +104,8 @@ serial: dummy
|
|||
sound: dummy
|
||||
make -C services/dd/sound
|
||||
|
||||
ext2fs: dummy
|
||||
make -C services/fs/ext2fs
|
||||
ext2: dummy
|
||||
make -C services/fs/ext2
|
||||
|
||||
#
|
||||
# Kernel loaders
|
||||
|
|
|
@ -17,12 +17,14 @@ _irq_handler_%1:
|
|||
;
|
||||
pusha
|
||||
push ds
|
||||
push es
|
||||
|
||||
;
|
||||
; Load DS
|
||||
;
|
||||
mov ax,KERNEL_DS
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
;
|
||||
; Mask the corresponding vector at the PIC
|
||||
|
@ -43,6 +45,7 @@ _irq_handler_%1:
|
|||
; Restore stack, registers and return to interrupted routine
|
||||
;
|
||||
pop eax
|
||||
pop es
|
||||
pop ds
|
||||
popa
|
||||
iret
|
||||
|
|
|
@ -223,11 +223,7 @@ BOOL is_page_present(unsigned int vaddr)
|
|||
* buffer from an irq.
|
||||
*/
|
||||
{
|
||||
#if 0
|
||||
unsigned int* page_dir = physical_to_linear(current_task->cr3);
|
||||
#else
|
||||
unsigned int* page_dir = get_page_directory();
|
||||
#endif
|
||||
unsigned int* page_tlb = NULL;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,330 +1,330 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/thread.c
|
||||
* PURPOSE: HAL multitasking functions
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* REVISION HISTORY:
|
||||
* 27/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/hal.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/mmhal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ***************************************************************/
|
||||
|
||||
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
|
||||
VOID PsBeginThreadWithContextInternal(VOID);
|
||||
|
||||
#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
|
||||
#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
|
||||
|
||||
static char null_ldt[8]={0,};
|
||||
static unsigned int null_ldt_sel=0;
|
||||
static PETHREAD FirstThread=NULL;
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
void HalTaskSwitch(PKTHREAD thread)
|
||||
/*
|
||||
* FUNCTION: Switch tasks
|
||||
* ARGUMENTS:
|
||||
* thread = Thread to switch to
|
||||
* NOTE: This function will not return until the current thread is scheduled
|
||||
* again
|
||||
*/
|
||||
{
|
||||
DPRINT("Scheduling thread %x\n",thread);
|
||||
DPRINT("Scheduling thread %x\n",thread->Context.nr);
|
||||
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
|
||||
thread->Context.previous_task,thread->Context.reserved1,
|
||||
thread->Context.esp0,thread->Context.ss0);
|
||||
DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
|
||||
thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
|
||||
thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
|
||||
DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
|
||||
thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
|
||||
thread->Context.eflags,thread->Context.eax);
|
||||
DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
|
||||
thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
|
||||
thread->Context.esp,thread->Context.ebp,thread->Context.esi);
|
||||
DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
|
||||
thread->Context.edi,thread->Context.es,thread->Context.reserved5,
|
||||
thread->Context.cs,thread->Context.reserved6);
|
||||
DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
|
||||
thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
|
||||
thread->Context.reserved8,thread->Context.fs);
|
||||
DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
|
||||
thread->Context.reserved9,thread->Context.gs,
|
||||
thread->Context.reserved10,thread->Context.ldt,
|
||||
thread->Context.reserved11);
|
||||
DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
|
||||
thread->Context.trap,thread->Context.iomap_base,
|
||||
thread->Context.nr,thread->Context.io_bitmap[0]);
|
||||
DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",
|
||||
&(gdt[thread->Context.nr/8].a),
|
||||
gdt[thread->Context.nr/8].a,
|
||||
gdt[thread->Context.nr/8].b);
|
||||
__asm__("pushfl\n\t"
|
||||
"cli\n\t"
|
||||
"ljmp %0\n\t"
|
||||
"popfl\n\t"
|
||||
: /* No outputs */
|
||||
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
|
||||
: "ax","dx");
|
||||
}
|
||||
|
||||
static unsigned int allocate_tss_descriptor(void)
|
||||
/*
|
||||
* FUNCTION: Allocates a slot within the GDT to describe a TSS
|
||||
* RETURNS: The offset within the GDT of the slot allocated on succcess
|
||||
* Zero on failure
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
|
||||
gdt[FIRST_TSS_OFFSET + i].b==0)
|
||||
{
|
||||
return(FIRST_TSS_OFFSET + i);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define FLAG_NT (1<<14)
|
||||
#define FLAG_VM (1<<17)
|
||||
#define FLAG_IF (1<<9)
|
||||
#define FLAG_IOPL ((1<<12)+(1<<13))
|
||||
|
||||
NTSTATUS KeValidateUserContext(PCONTEXT Context)
|
||||
/*
|
||||
* FUNCTION: Validates a processor context
|
||||
* ARGUMENTS:
|
||||
* Context = Context to validate
|
||||
* RETURNS: Status
|
||||
* NOTE: This only validates the context as not violating system security, it
|
||||
* doesn't guararantee the thread won't crash at some point
|
||||
* NOTE2: This relies on there only being two selectors which can access
|
||||
* system space
|
||||
*/
|
||||
{
|
||||
if (Context->Eip >= KERNEL_BASE)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegCs == KERNEL_CS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegDs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegEs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegFs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegGs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if ((Context->EFlags & FLAG_IOPL) != 0 ||
|
||||
(Context->EFlags & FLAG_NT) ||
|
||||
(Context->EFlags & FLAG_VM) ||
|
||||
(!(Context->EFlags & FLAG_IF)))
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
|
||||
/*
|
||||
* FUNCTION: Initialize a task with a user mode context
|
||||
* ARGUMENTS:
|
||||
* Thread = Thread to initialize
|
||||
* Context = Processor context to initialize it with
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
unsigned int desc;
|
||||
unsigned int length;
|
||||
unsigned int base;
|
||||
PVOID kernel_stack;
|
||||
NTSTATUS Status;
|
||||
PVOID stack_start;
|
||||
|
||||
DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
|
||||
Thread,Context);
|
||||
|
||||
assert(sizeof(hal_thread_state)>=0x68);
|
||||
|
||||
if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
desc = allocate_tss_descriptor();
|
||||
length = sizeof(hal_thread_state) - 1;
|
||||
base = (unsigned int)(&(Thread->Tcb.Context));
|
||||
kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
|
||||
|
||||
/*
|
||||
* Setup a TSS descriptor
|
||||
*/
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
|
||||
stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
|
||||
memcpy(stack_start, Context, sizeof(CONTEXT));
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
|
||||
Thread->Tcb.Context.ldt = null_ldt_sel;
|
||||
Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
|
||||
Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
|
||||
Thread->Tcb.Context.esp0 = stack_start;
|
||||
Thread->Tcb.Context.ss0 = KERNEL_DS;
|
||||
Thread->Tcb.Context.esp = stack_start;
|
||||
Thread->Tcb.Context.ss = KERNEL_DS;
|
||||
Thread->Tcb.Context.cs = KERNEL_CS;
|
||||
Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;
|
||||
Thread->Tcb.Context.io_bitmap[0] = 0xff;
|
||||
Thread->Tcb.Context.cr3 =
|
||||
linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
|
||||
Thread->Tcb.Context.ds = KERNEL_DS;
|
||||
Thread->Tcb.Context.es = KERNEL_DS;
|
||||
Thread->Tcb.Context.fs = KERNEL_DS;
|
||||
Thread->Tcb.Context.gs = KERNEL_DS;
|
||||
|
||||
Thread->Tcb.Context.nr = desc * 8;
|
||||
DPRINT("Allocated %x\n",desc*8);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
|
||||
/*
|
||||
* FUNCTION: Initializes the HAL portion of a thread object
|
||||
* ARGUMENTS:
|
||||
* thread = Object describes the thread
|
||||
* fn = Entrypoint for the thread
|
||||
* StartContext = parameter to pass to the thread entrypoint
|
||||
* RETURNS: True if the function succeeded
|
||||
*/
|
||||
{
|
||||
unsigned int desc = allocate_tss_descriptor();
|
||||
unsigned int length = sizeof(hal_thread_state) - 1;
|
||||
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
|
||||
unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);
|
||||
|
||||
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
|
||||
thread,fn,StartContext);
|
||||
DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
|
||||
|
||||
/*
|
||||
* Make sure
|
||||
*/
|
||||
assert(sizeof(hal_thread_state)>=0x68);
|
||||
|
||||
/*
|
||||
* Setup a TSS descriptor
|
||||
*/
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
|
||||
// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
|
||||
// DPRINT("desc %d\n",desc);
|
||||
DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",
|
||||
&(gdt[desc].a),
|
||||
gdt[desc].a,
|
||||
gdt[desc].b);
|
||||
|
||||
/*
|
||||
* Initialize the stack for the thread (including the two arguments to
|
||||
* the general start routine).
|
||||
*/
|
||||
kernel_stack[1023] = (unsigned int)StartContext;
|
||||
kernel_stack[1022] = (unsigned int)fn;
|
||||
kernel_stack[1021] = NULL;
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
|
||||
thread->Tcb.Context.ldt = null_ldt_sel;
|
||||
thread->Tcb.Context.eflags = (1<<1)+(1<<9);
|
||||
thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
|
||||
thread->Tcb.Context.esp0 = &kernel_stack[1021];
|
||||
thread->Tcb.Context.ss0 = KERNEL_DS;
|
||||
thread->Tcb.Context.esp = &kernel_stack[1021];
|
||||
thread->Tcb.Context.ss = KERNEL_DS;
|
||||
thread->Tcb.Context.cs = KERNEL_CS;
|
||||
thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
|
||||
thread->Tcb.Context.io_bitmap[0] = 0xff;
|
||||
thread->Tcb.Context.cr3 =
|
||||
linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
|
||||
thread->Tcb.Context.ds = KERNEL_DS;
|
||||
thread->Tcb.Context.es = KERNEL_DS;
|
||||
thread->Tcb.Context.fs = KERNEL_DS;
|
||||
thread->Tcb.Context.gs = KERNEL_DS;
|
||||
thread->Tcb.Context.nr = desc * 8;
|
||||
DPRINT("Allocated %x\n",desc*8);
|
||||
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
void HalInitFirstTask(PETHREAD thread)
|
||||
/*
|
||||
* FUNCTION: Called to setup the HAL portion of a thread object for the
|
||||
* initial thread
|
||||
*/
|
||||
{
|
||||
unsigned int base;
|
||||
unsigned int length;
|
||||
unsigned int desc;
|
||||
|
||||
memset(null_ldt,0,sizeof(null_ldt));
|
||||
desc = allocate_tss_descriptor();
|
||||
base = (unsigned int)&null_ldt;
|
||||
length = sizeof(null_ldt) - 1;
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
null_ldt_sel = desc*8;
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
HalInitTask(thread,NULL,NULL);
|
||||
|
||||
/*
|
||||
* Load the task register
|
||||
*/
|
||||
__asm__("ltr %%ax"
|
||||
: /* no output */
|
||||
: "a" (thread->Tcb.Context.nr));
|
||||
FirstThread = thread;
|
||||
}
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/hal/x86/thread.c
|
||||
* PURPOSE: HAL multitasking functions
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* REVISION HISTORY:
|
||||
* 27/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/hal.h>
|
||||
#include <internal/i386/segment.h>
|
||||
#include <internal/mmhal.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ***************************************************************/
|
||||
|
||||
VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
|
||||
VOID PsBeginThreadWithContextInternal(VOID);
|
||||
|
||||
#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
|
||||
#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
|
||||
|
||||
static char null_ldt[8]={0,};
|
||||
static unsigned int null_ldt_sel=0;
|
||||
static PETHREAD FirstThread=NULL;
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
void HalTaskSwitch(PKTHREAD thread)
|
||||
/*
|
||||
* FUNCTION: Switch tasks
|
||||
* ARGUMENTS:
|
||||
* thread = Thread to switch to
|
||||
* NOTE: This function will not return until the current thread is scheduled
|
||||
* again
|
||||
*/
|
||||
{
|
||||
DPRINT("Scheduling thread %x\n",thread);
|
||||
DPRINT("Scheduling thread %x\n",thread->Context.nr);
|
||||
DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
|
||||
thread->Context.previous_task,thread->Context.reserved1,
|
||||
thread->Context.esp0,thread->Context.ss0);
|
||||
DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
|
||||
thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
|
||||
thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
|
||||
DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
|
||||
thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
|
||||
thread->Context.eflags,thread->Context.eax);
|
||||
DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
|
||||
thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
|
||||
thread->Context.esp,thread->Context.ebp,thread->Context.esi);
|
||||
DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
|
||||
thread->Context.edi,thread->Context.es,thread->Context.reserved5,
|
||||
thread->Context.cs,thread->Context.reserved6);
|
||||
DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
|
||||
thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
|
||||
thread->Context.reserved8,thread->Context.fs);
|
||||
DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
|
||||
thread->Context.reserved9,thread->Context.gs,
|
||||
thread->Context.reserved10,thread->Context.ldt,
|
||||
thread->Context.reserved11);
|
||||
DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
|
||||
thread->Context.trap,thread->Context.iomap_base,
|
||||
thread->Context.nr,thread->Context.io_bitmap[0]);
|
||||
DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",
|
||||
&(gdt[thread->Context.nr/8].a),
|
||||
gdt[thread->Context.nr/8].a,
|
||||
gdt[thread->Context.nr/8].b);
|
||||
__asm__("pushfl\n\t"
|
||||
"cli\n\t"
|
||||
"ljmp %0\n\t"
|
||||
"popfl\n\t"
|
||||
: /* No outputs */
|
||||
: "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
|
||||
: "ax","dx");
|
||||
}
|
||||
|
||||
static unsigned int allocate_tss_descriptor(void)
|
||||
/*
|
||||
* FUNCTION: Allocates a slot within the GDT to describe a TSS
|
||||
* RETURNS: The offset within the GDT of the slot allocated on succcess
|
||||
* Zero on failure
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
|
||||
gdt[FIRST_TSS_OFFSET + i].b==0)
|
||||
{
|
||||
return(FIRST_TSS_OFFSET + i);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define FLAG_NT (1<<14)
|
||||
#define FLAG_VM (1<<17)
|
||||
#define FLAG_IF (1<<9)
|
||||
#define FLAG_IOPL ((1<<12)+(1<<13))
|
||||
|
||||
NTSTATUS KeValidateUserContext(PCONTEXT Context)
|
||||
/*
|
||||
* FUNCTION: Validates a processor context
|
||||
* ARGUMENTS:
|
||||
* Context = Context to validate
|
||||
* RETURNS: Status
|
||||
* NOTE: This only validates the context as not violating system security, it
|
||||
* doesn't guararantee the thread won't crash at some point
|
||||
* NOTE2: This relies on there only being two selectors which can access
|
||||
* system space
|
||||
*/
|
||||
{
|
||||
if (Context->Eip >= KERNEL_BASE)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegCs == KERNEL_CS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegDs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegEs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegFs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (Context->SegGs == KERNEL_DS)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if ((Context->EFlags & FLAG_IOPL) != 0 ||
|
||||
(Context->EFlags & FLAG_NT) ||
|
||||
(Context->EFlags & FLAG_VM) ||
|
||||
(!(Context->EFlags & FLAG_IF)))
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
|
||||
/*
|
||||
* FUNCTION: Initialize a task with a user mode context
|
||||
* ARGUMENTS:
|
||||
* Thread = Thread to initialize
|
||||
* Context = Processor context to initialize it with
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
unsigned int desc;
|
||||
unsigned int length;
|
||||
unsigned int base;
|
||||
PVOID kernel_stack;
|
||||
NTSTATUS Status;
|
||||
PVOID stack_start;
|
||||
|
||||
DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
|
||||
Thread,Context);
|
||||
|
||||
assert(sizeof(hal_thread_state)>=0x68);
|
||||
|
||||
if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
desc = allocate_tss_descriptor();
|
||||
length = sizeof(hal_thread_state) - 1;
|
||||
base = (unsigned int)(&(Thread->Tcb.Context));
|
||||
kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
|
||||
|
||||
/*
|
||||
* Setup a TSS descriptor
|
||||
*/
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
|
||||
stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
|
||||
memcpy(stack_start, Context, sizeof(CONTEXT));
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
|
||||
Thread->Tcb.Context.ldt = null_ldt_sel;
|
||||
Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
|
||||
Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
|
||||
Thread->Tcb.Context.esp0 = stack_start;
|
||||
Thread->Tcb.Context.ss0 = KERNEL_DS;
|
||||
Thread->Tcb.Context.esp = stack_start;
|
||||
Thread->Tcb.Context.ss = KERNEL_DS;
|
||||
Thread->Tcb.Context.cs = KERNEL_CS;
|
||||
Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;
|
||||
Thread->Tcb.Context.io_bitmap[0] = 0xff;
|
||||
Thread->Tcb.Context.cr3 =
|
||||
linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
|
||||
Thread->Tcb.Context.ds = KERNEL_DS;
|
||||
Thread->Tcb.Context.es = KERNEL_DS;
|
||||
Thread->Tcb.Context.fs = KERNEL_DS;
|
||||
Thread->Tcb.Context.gs = KERNEL_DS;
|
||||
|
||||
Thread->Tcb.Context.nr = desc * 8;
|
||||
DPRINT("Allocated %x\n",desc*8);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
|
||||
/*
|
||||
* FUNCTION: Initializes the HAL portion of a thread object
|
||||
* ARGUMENTS:
|
||||
* thread = Object describes the thread
|
||||
* fn = Entrypoint for the thread
|
||||
* StartContext = parameter to pass to the thread entrypoint
|
||||
* RETURNS: True if the function succeeded
|
||||
*/
|
||||
{
|
||||
unsigned int desc = allocate_tss_descriptor();
|
||||
unsigned int length = sizeof(hal_thread_state) - 1;
|
||||
unsigned int base = (unsigned int)(&(thread->Tcb.Context));
|
||||
unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);
|
||||
|
||||
DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
|
||||
thread,fn,StartContext);
|
||||
DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
|
||||
|
||||
/*
|
||||
* Make sure
|
||||
*/
|
||||
assert(sizeof(hal_thread_state)>=0x68);
|
||||
|
||||
/*
|
||||
* Setup a TSS descriptor
|
||||
*/
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
|
||||
// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
|
||||
// DPRINT("desc %d\n",desc);
|
||||
DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",
|
||||
&(gdt[desc].a),
|
||||
gdt[desc].a,
|
||||
gdt[desc].b);
|
||||
|
||||
/*
|
||||
* Initialize the stack for the thread (including the two arguments to
|
||||
* the general start routine).
|
||||
*/
|
||||
kernel_stack[1023] = (unsigned int)StartContext;
|
||||
kernel_stack[1022] = (unsigned int)fn;
|
||||
kernel_stack[1021] = NULL;
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
|
||||
thread->Tcb.Context.ldt = null_ldt_sel;
|
||||
thread->Tcb.Context.eflags = (1<<1)+(1<<9);
|
||||
thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
|
||||
thread->Tcb.Context.esp0 = &kernel_stack[1021];
|
||||
thread->Tcb.Context.ss0 = KERNEL_DS;
|
||||
thread->Tcb.Context.esp = &kernel_stack[1021];
|
||||
thread->Tcb.Context.ss = KERNEL_DS;
|
||||
thread->Tcb.Context.cs = KERNEL_CS;
|
||||
thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
|
||||
thread->Tcb.Context.io_bitmap[0] = 0xff;
|
||||
thread->Tcb.Context.cr3 =
|
||||
linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
|
||||
thread->Tcb.Context.ds = KERNEL_DS;
|
||||
thread->Tcb.Context.es = KERNEL_DS;
|
||||
thread->Tcb.Context.fs = KERNEL_DS;
|
||||
thread->Tcb.Context.gs = KERNEL_DS;
|
||||
thread->Tcb.Context.nr = desc * 8;
|
||||
DPRINT("Allocated %x\n",desc*8);
|
||||
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
void HalInitFirstTask(PETHREAD thread)
|
||||
/*
|
||||
* FUNCTION: Called to setup the HAL portion of a thread object for the
|
||||
* initial thread
|
||||
*/
|
||||
{
|
||||
unsigned int base;
|
||||
unsigned int length;
|
||||
unsigned int desc;
|
||||
|
||||
memset(null_ldt,0,sizeof(null_ldt));
|
||||
desc = allocate_tss_descriptor();
|
||||
base = (unsigned int)&null_ldt;
|
||||
length = sizeof(null_ldt) - 1;
|
||||
gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
|
||||
gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
|
||||
| (base & 0xff000000);
|
||||
null_ldt_sel = desc*8;
|
||||
|
||||
/*
|
||||
* Initialize the thread context
|
||||
*/
|
||||
HalInitTask(thread,NULL,NULL);
|
||||
|
||||
/*
|
||||
* Load the task register
|
||||
*/
|
||||
__asm__("ltr %%ax"
|
||||
: /* no output */
|
||||
: "a" (thread->Tcb.Context.nr));
|
||||
FirstThread = thread;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ NTSTATUS InitalizeLoadedDriver(PDRIVER_INITIALIZE entry)
|
|||
/*
|
||||
* Allocate memory for a driver object
|
||||
* NOTE: The object only becomes system visible once the associated
|
||||
* device objects are intialized
|
||||
* device objects are initialized
|
||||
*/
|
||||
DriverObject=ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
|
||||
if (DriverObject==NULL)
|
||||
|
|
|
@ -1,308 +1,309 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/io/irp.c
|
||||
* PURPOSE: Handle IRPs
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 24/05/98: Created
|
||||
*/
|
||||
|
||||
/* NOTES *******************************************************************
|
||||
*
|
||||
* Layout of an IRP
|
||||
*
|
||||
* ################
|
||||
* # Headers #
|
||||
* ################
|
||||
* # #
|
||||
* # Variable #
|
||||
* # length list #
|
||||
* # of io stack #
|
||||
* # locations #
|
||||
* # #
|
||||
* ################
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <internal/string.h>
|
||||
#include <internal/io.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the device, representing a removable-media
|
||||
* device, that is the target of the given thread's I/O request
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID IoFreeIrp(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Releases a caller allocated irp
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to free
|
||||
*/
|
||||
{
|
||||
ExFreePool(Irp);
|
||||
}
|
||||
|
||||
PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes an irp to associated with a master irp
|
||||
* ARGUMENTS:
|
||||
* Irp = Master irp
|
||||
* StackSize = Number of stack locations to be allocated in the irp
|
||||
* RETURNS: The irp allocated
|
||||
*/
|
||||
{
|
||||
PIRP AssocIrp;
|
||||
|
||||
AssocIrp = IoAllocateIrp(StackSize,FALSE);
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID IoMarkIrpPending(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Marks the specified irp, indicating further processing will
|
||||
* be required by other driver routines
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to mark
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp));
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
|
||||
Irp->Tail.Overlay.Thread = KeGetCurrentThread();
|
||||
DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control);
|
||||
DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
|
||||
}
|
||||
|
||||
USHORT IoSizeOfIrp(CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Determines the size of an IRP
|
||||
* ARGUMENTS:
|
||||
* StackSize = number of stack locations in the IRP
|
||||
* RETURNS: The size of the IRP in bytes
|
||||
*/
|
||||
{
|
||||
return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
|
||||
}
|
||||
|
||||
VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Initalizes an irp allocated by the caller
|
||||
* ARGUMENTS:
|
||||
* Irp = IRP to initalize
|
||||
* PacketSize = Size in bytes of the IRP
|
||||
* StackSize = Number of stack locations in the IRP
|
||||
*/
|
||||
{
|
||||
assert(Irp!=NULL);
|
||||
memset(Irp,0,PacketSize);
|
||||
Irp->StackCount=StackSize;
|
||||
Irp->CurrentLocation=StackSize;
|
||||
Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Gets a pointer to the callers location in the I/O stack in
|
||||
* the given IRP
|
||||
* ARGUMENTS:
|
||||
* Irp = Points to the IRP
|
||||
* RETURNS: A pointer to the stack location
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
|
||||
Irp,
|
||||
Irp->CurrentLocation,
|
||||
Irp->StackCount);
|
||||
|
||||
return &Irp->Stack[Irp->CurrentLocation];
|
||||
}
|
||||
|
||||
|
||||
VOID IoSetNextIrpStackLocation(PIRP Irp)
|
||||
{
|
||||
Irp->CurrentLocation--;
|
||||
Irp->Tail.Overlay.CurrentStackLocation--;
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Gives a higher level driver access to the next lower driver's
|
||||
* I/O stack location
|
||||
* ARGUMENTS:
|
||||
* Irp = points to the irp
|
||||
* RETURNS: A pointer to the stack location
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
|
||||
Irp,
|
||||
Irp->CurrentLocation,
|
||||
Irp->StackCount);
|
||||
|
||||
assert(Irp!=NULL);
|
||||
DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
|
||||
return(&Irp->Stack[Irp->CurrentLocation-1]);
|
||||
}
|
||||
|
||||
NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
|
||||
/*
|
||||
* FUNCTION: Sends an IRP to the next lower driver
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDRIVER_OBJECT drv = DevObject->DriverObject;
|
||||
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
|
||||
|
||||
DPRINT("Deviceobject %x\n",DevObject);
|
||||
DPRINT("Irp %x\n",irp);
|
||||
|
||||
irp->Tail.Overlay.CurrentStackLocation--;
|
||||
irp->CurrentLocation--;
|
||||
|
||||
DPRINT("Io stack address %x\n",param);
|
||||
DPRINT("Function %d Routine %x\n",param->MajorFunction,
|
||||
drv->MajorFunction[param->MajorFunction]);
|
||||
|
||||
Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
|
||||
/*
|
||||
* FUNCTION: Allocates an IRP
|
||||
* ARGUMENTS:
|
||||
* StackSize = the size of the stack required for the irp
|
||||
* ChargeQuota = Charge allocation to current threads quota
|
||||
* RETURNS: Irp allocated
|
||||
*/
|
||||
{
|
||||
PIRP Irp;
|
||||
|
||||
DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",StackSize,
|
||||
ChargeQuota);
|
||||
if (ChargeQuota)
|
||||
{
|
||||
Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
|
||||
}
|
||||
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Irp->StackCount=StackSize;
|
||||
Irp->CurrentLocation=StackSize;
|
||||
|
||||
DPRINT("Irp %x Irp->StackPtr %d\n",Irp,Irp->CurrentLocation);
|
||||
return(Irp);
|
||||
}
|
||||
|
||||
VOID IoSetCompletionRoutine(PIRP Irp,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||
PVOID Context,
|
||||
BOOLEAN InvokeOnSuccess,
|
||||
BOOLEAN InvokeOnError,
|
||||
BOOLEAN InvokeOnCancel)
|
||||
{
|
||||
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
param->CompletionRoutine=CompletionRoutine;
|
||||
param->CompletionContext=Context;
|
||||
if (InvokeOnSuccess)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_SUCCESS;
|
||||
}
|
||||
if (InvokeOnError)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_ERROR;
|
||||
}
|
||||
if (InvokeOnCancel)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_CANCEL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID IopCompleteRequest(struct _KAPC* Apc,
|
||||
PKNORMAL_ROUTINE* NormalRoutine,
|
||||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArgument2)
|
||||
{
|
||||
IoSecondStageCompletion((PIRP)(*NormalContext),
|
||||
IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
|
||||
/*
|
||||
* FUNCTION: Indicates the caller has finished all processing for a given
|
||||
* I/O request and is returning the given IRP to the I/O manager
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to be cancelled
|
||||
* PriorityBoost = Increment by which to boost the priority of the
|
||||
* thread making the request
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
|
||||
Irp,PriorityBoost);
|
||||
|
||||
for (i=0;i<Irp->StackCount;i++)
|
||||
{
|
||||
DPRINT("&Irp->Stack[i] %x\n",&Irp->Stack[i]);
|
||||
if (Irp->Stack[i].CompletionRoutine!=NULL)
|
||||
{
|
||||
Status = Irp->Stack[i].CompletionRoutine(
|
||||
Irp->Stack[i].DeviceObject,
|
||||
Irp,
|
||||
Irp->Stack[i].CompletionContext);
|
||||
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
DPRINT("Irp->Stack[i].Control %x\n",Irp->Stack[i].Control);
|
||||
if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
|
||||
{
|
||||
DPRINT("Setting PendingReturned flag\n");
|
||||
Irp->PendingReturned = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
KeInitializeApc(&Irp->Tail.Apc,
|
||||
&Irp->Tail.Overlay.Thread->Tcb,
|
||||
0,
|
||||
IopCompleteRequest,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
Irp);
|
||||
KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
IoSecondStageCompletion(Irp,PriorityBoost);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/io/irp.c
|
||||
* PURPOSE: Handle IRPs
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 24/05/98: Created
|
||||
*/
|
||||
|
||||
/* NOTES *******************************************************************
|
||||
*
|
||||
* Layout of an IRP
|
||||
*
|
||||
* ################
|
||||
* # Headers #
|
||||
* ################
|
||||
* # #
|
||||
* # Variable #
|
||||
* # length list #
|
||||
* # of io stack #
|
||||
* # locations #
|
||||
* # #
|
||||
* ################
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <internal/string.h>
|
||||
#include <internal/io.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the device, representing a removable-media
|
||||
* device, that is the target of the given thread's I/O request
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID IoFreeIrp(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Releases a caller allocated irp
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to free
|
||||
*/
|
||||
{
|
||||
ExFreePool(Irp);
|
||||
}
|
||||
|
||||
PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes an irp to associated with a master irp
|
||||
* ARGUMENTS:
|
||||
* Irp = Master irp
|
||||
* StackSize = Number of stack locations to be allocated in the irp
|
||||
* RETURNS: The irp allocated
|
||||
*/
|
||||
{
|
||||
PIRP AssocIrp;
|
||||
|
||||
AssocIrp = IoAllocateIrp(StackSize,FALSE);
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID IoMarkIrpPending(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Marks the specified irp, indicating further processing will
|
||||
* be required by other driver routines
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to mark
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp));
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;
|
||||
Irp->Tail.Overlay.Thread = KeGetCurrentThread();
|
||||
DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",
|
||||
IoGetCurrentIrpStackLocation(Irp)->Control);
|
||||
DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);
|
||||
}
|
||||
|
||||
USHORT IoSizeOfIrp(CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Determines the size of an IRP
|
||||
* ARGUMENTS:
|
||||
* StackSize = number of stack locations in the IRP
|
||||
* RETURNS: The size of the IRP in bytes
|
||||
*/
|
||||
{
|
||||
return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));
|
||||
}
|
||||
|
||||
VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)
|
||||
/*
|
||||
* FUNCTION: Initalizes an irp allocated by the caller
|
||||
* ARGUMENTS:
|
||||
* Irp = IRP to initalize
|
||||
* PacketSize = Size in bytes of the IRP
|
||||
* StackSize = Number of stack locations in the IRP
|
||||
*/
|
||||
{
|
||||
assert(Irp!=NULL);
|
||||
memset(Irp,0,PacketSize);
|
||||
Irp->StackCount=StackSize;
|
||||
Irp->CurrentLocation=StackSize;
|
||||
Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Gets a pointer to the callers location in the I/O stack in
|
||||
* the given IRP
|
||||
* ARGUMENTS:
|
||||
* Irp = Points to the IRP
|
||||
* RETURNS: A pointer to the stack location
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
|
||||
Irp,
|
||||
Irp->CurrentLocation,
|
||||
Irp->StackCount);
|
||||
|
||||
return &Irp->Stack[Irp->CurrentLocation];
|
||||
}
|
||||
|
||||
|
||||
VOID IoSetNextIrpStackLocation(PIRP Irp)
|
||||
{
|
||||
Irp->CurrentLocation--;
|
||||
Irp->Tail.Overlay.CurrentStackLocation--;
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Gives a higher level driver access to the next lower driver's
|
||||
* I/O stack location
|
||||
* ARGUMENTS:
|
||||
* Irp = points to the irp
|
||||
* RETURNS: A pointer to the stack location
|
||||
*/
|
||||
{
|
||||
DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
|
||||
Irp,
|
||||
Irp->CurrentLocation,
|
||||
Irp->StackCount);
|
||||
|
||||
assert(Irp!=NULL);
|
||||
DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
|
||||
return(&Irp->Stack[Irp->CurrentLocation-1]);
|
||||
}
|
||||
|
||||
NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)
|
||||
/*
|
||||
* FUNCTION: Sends an IRP to the next lower driver
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PDRIVER_OBJECT drv = DevObject->DriverObject;
|
||||
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);
|
||||
|
||||
DPRINT("Deviceobject %x\n",DevObject);
|
||||
DPRINT("Irp %x\n",irp);
|
||||
|
||||
irp->Tail.Overlay.CurrentStackLocation--;
|
||||
irp->CurrentLocation--;
|
||||
|
||||
DPRINT("Io stack address %x\n",param);
|
||||
DPRINT("Function %d Routine %x\n",param->MajorFunction,
|
||||
drv->MajorFunction[param->MajorFunction]);
|
||||
|
||||
Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)
|
||||
/*
|
||||
* FUNCTION: Allocates an IRP
|
||||
* ARGUMENTS:
|
||||
* StackSize = the size of the stack required for the irp
|
||||
* ChargeQuota = Charge allocation to current threads quota
|
||||
* RETURNS: Irp allocated
|
||||
*/
|
||||
{
|
||||
PIRP Irp;
|
||||
|
||||
DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",StackSize,
|
||||
ChargeQuota);
|
||||
if (ChargeQuota)
|
||||
{
|
||||
Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));
|
||||
}
|
||||
|
||||
if (Irp==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Irp->StackCount=StackSize;
|
||||
Irp->CurrentLocation=StackSize;
|
||||
|
||||
DPRINT("Irp %x Irp->StackPtr %d\n",Irp,Irp->CurrentLocation);
|
||||
return(Irp);
|
||||
}
|
||||
|
||||
VOID IoSetCompletionRoutine(PIRP Irp,
|
||||
PIO_COMPLETION_ROUTINE CompletionRoutine,
|
||||
PVOID Context,
|
||||
BOOLEAN InvokeOnSuccess,
|
||||
BOOLEAN InvokeOnError,
|
||||
BOOLEAN InvokeOnCancel)
|
||||
{
|
||||
IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
param->CompletionRoutine=CompletionRoutine;
|
||||
param->CompletionContext=Context;
|
||||
if (InvokeOnSuccess)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_SUCCESS;
|
||||
}
|
||||
if (InvokeOnError)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_ERROR;
|
||||
}
|
||||
if (InvokeOnCancel)
|
||||
{
|
||||
param->Control = param->Control | SL_INVOKE_ON_CANCEL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID IopCompleteRequest(struct _KAPC* Apc,
|
||||
PKNORMAL_ROUTINE* NormalRoutine,
|
||||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArgument2)
|
||||
{
|
||||
IoSecondStageCompletion((PIRP)(*NormalContext),
|
||||
IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)
|
||||
/*
|
||||
* FUNCTION: Indicates the caller has finished all processing for a given
|
||||
* I/O request and is returning the given IRP to the I/O manager
|
||||
* ARGUMENTS:
|
||||
* Irp = Irp to be cancelled
|
||||
* PriorityBoost = Increment by which to boost the priority of the
|
||||
* thread making the request
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",
|
||||
Irp,PriorityBoost);
|
||||
|
||||
for (i=0;i<Irp->StackCount;i++)
|
||||
{
|
||||
DPRINT("&Irp->Stack[i] %x\n",&Irp->Stack[i]);
|
||||
if (Irp->Stack[i].CompletionRoutine!=NULL)
|
||||
{
|
||||
Status = Irp->Stack[i].CompletionRoutine(
|
||||
Irp->Stack[i].DeviceObject,
|
||||
Irp,
|
||||
Irp->Stack[i].CompletionContext);
|
||||
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
DPRINT("Irp->Stack[i].Control %x\n",Irp->Stack[i].Control);
|
||||
if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
|
||||
{
|
||||
DPRINT("Setting PendingReturned flag\n");
|
||||
Irp->PendingReturned = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
KeInitializeApc(&Irp->Tail.Apc,
|
||||
&Irp->Tail.Overlay.Thread->Tcb,
|
||||
0,
|
||||
IopCompleteRequest,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
Irp);
|
||||
KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
IoSecondStageCompletion(Irp,PriorityBoost);
|
||||
}
|
||||
}
|
||||
>>>>>>> 1.7
|
||||
|
|
|
@ -28,6 +28,9 @@ NTSTATUS IoPageRead(PFILE_OBJECT FileObject,
|
|||
PIO_STACK_LOCATION StackPtr;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IoPageRead(FileObject %x, Address %x)\n",
|
||||
FileObject,Address);
|
||||
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||
FileObject->DeviceObject,
|
||||
|
|
|
@ -1,193 +1,178 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
* PURPOSE: Initalizes the kernel
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 28/05/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/version.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/symbol.h>
|
||||
#include <internal/module.h>
|
||||
|
||||
#include <internal/mmhal.h>
|
||||
#include <internal/i386/segment.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,
|
||||
unsigned int len)
|
||||
/*
|
||||
* FUNCTION: Sets a hardware breakpoint
|
||||
* ARGUMENTS:
|
||||
* i = breakpoint to set (0 to 3)
|
||||
* addr = linear address to break on
|
||||
* type = Type of access to break on
|
||||
* len = length of the variable to watch
|
||||
* NOTES:
|
||||
* The variable to watch must be aligned to its length (i.e. a dword
|
||||
* breakpoint must be aligned to a dword boundary)
|
||||
*
|
||||
* A fatal exception will be generated on the access to the variable.
|
||||
* It is (at the moment) only really useful for catching undefined
|
||||
* pointers if you know the variable effected but not the buggy
|
||||
* routine.
|
||||
*
|
||||
* FIXME: Extend to call out to kernel debugger on breakpoint
|
||||
* Add support for I/O breakpoints
|
||||
* REFERENCES: See the i386 programmer manual for more details
|
||||
*/
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
if (i>3)
|
||||
{
|
||||
printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the linear address
|
||||
*/
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
__asm("movl %0,%%db0\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
__asm__("movl %0,%%db1\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
__asm__("movl %0,%%db2\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
__asm__("movl %0,%%db3\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup mask for dr7
|
||||
*/
|
||||
mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2));
|
||||
__asm__("movl %%db7,%%eax\n\t"
|
||||
"orl %0,%%eax\n\t"
|
||||
"movl %%eax,%%db7\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (mask)
|
||||
: "ax");
|
||||
}
|
||||
|
||||
extern int edata;
|
||||
extern int end;
|
||||
|
||||
asmlinkage void _main(boot_param* _bp)
|
||||
/*
|
||||
* FUNCTION: Called by the boot loader to start the kernel
|
||||
* ARGUMENTS:
|
||||
* _bp = Pointer to boot parameters initialized by the boot loader
|
||||
* NOTE: The boot parameters are stored in low memory which will become
|
||||
* invalid after the memory managment is initialized so we make a local copy.
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int start;
|
||||
unsigned int start1;
|
||||
boot_param bp;
|
||||
|
||||
// memset((void *)&edata,0,((int)&end)-((int)&edata));
|
||||
|
||||
/*
|
||||
* Copy the parameters to a local buffer because lowmem will go away
|
||||
*/
|
||||
memcpy(&bp,_bp,sizeof(boot_param));
|
||||
|
||||
/*
|
||||
* Initalize the console (before printing anything)
|
||||
*/
|
||||
HalInitConsole(&bp);
|
||||
|
||||
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
|
||||
|
||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||
if (start < ((int)&end))
|
||||
{
|
||||
DbgPrint("start %x end %x\n",start,(int)&end);
|
||||
DbgPrint("Kernel booted incorrectly, aborting\n");
|
||||
DbgPrint("Reduce the amount of uninitialized data\n");
|
||||
for(;;);
|
||||
}
|
||||
DPRINT("MmGetPhysicalAddress(start) = %x\n",MmGetPhysicalAddress((void *)start));
|
||||
DPRINT("bp.module_length[0] %x PAGE_ROUND_UP(bp.module_length[0]) %x\n",
|
||||
bp.module_length[0],PAGE_ROUND_UP(bp.module_length[0]));
|
||||
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
|
||||
DPRINT("bp.module_length[1] %x PAGE_ROUND_UP(bp.module_length[1]) %x\n",
|
||||
bp.module_length[1],PAGE_ROUND_UP(bp.module_length[1]));
|
||||
|
||||
DPRINT("start %x *start %x\n",start,*((unsigned int *)start));
|
||||
DPRINT("start1 %x *start1 %x\n",start1,*((unsigned int *)start1));
|
||||
|
||||
|
||||
/*
|
||||
* Initalize various critical subsystems
|
||||
*/
|
||||
HalInit(&bp);
|
||||
MmInitalize(&bp);
|
||||
CHECKPOINT;
|
||||
KeInit();
|
||||
CHECKPOINT;
|
||||
ObInit();
|
||||
CHECKPOINT;
|
||||
PsInit();
|
||||
CHECKPOINT;
|
||||
IoInit();
|
||||
CHECKPOINT;
|
||||
|
||||
/*
|
||||
* Initalize services loaded at boot time
|
||||
*/
|
||||
DPRINT("%d files loaded\n",bp.nr_files);
|
||||
|
||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
|
||||
// DbgPrint("start1 %x *start1 %x\n",start1,*((unsigned int *)start1));
|
||||
for (i=1;i<bp.nr_files;i++)
|
||||
{
|
||||
process_boot_module(start);
|
||||
// DbgPrint("start1 %x *start1 %x\n",start1,*((unsigned int *)start1));
|
||||
start=start+PAGE_ROUND_UP(bp.module_length[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test various features of the kernel
|
||||
*/
|
||||
TstBegin();
|
||||
|
||||
/*
|
||||
* Enter idle loop
|
||||
*/
|
||||
printk("Finished main()\n");
|
||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
* PURPOSE: Initalizes the kernel
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 28/05/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/version.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/string.h>
|
||||
#include <internal/symbol.h>
|
||||
#include <internal/module.h>
|
||||
|
||||
#include <internal/mmhal.h>
|
||||
#include <internal/i386/segment.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,
|
||||
unsigned int len)
|
||||
/*
|
||||
* FUNCTION: Sets a hardware breakpoint
|
||||
* ARGUMENTS:
|
||||
* i = breakpoint to set (0 to 3)
|
||||
* addr = linear address to break on
|
||||
* type = Type of access to break on
|
||||
* len = length of the variable to watch
|
||||
* NOTES:
|
||||
* The variable to watch must be aligned to its length (i.e. a dword
|
||||
* breakpoint must be aligned to a dword boundary)
|
||||
*
|
||||
* A fatal exception will be generated on the access to the variable.
|
||||
* It is (at the moment) only really useful for catching undefined
|
||||
* pointers if you know the variable effected but not the buggy
|
||||
* routine.
|
||||
*
|
||||
* FIXME: Extend to call out to kernel debugger on breakpoint
|
||||
* Add support for I/O breakpoints
|
||||
* REFERENCES: See the i386 programmer manual for more details
|
||||
*/
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
if (i>3)
|
||||
{
|
||||
printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the linear address
|
||||
*/
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
__asm("movl %0,%%db0\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
__asm__("movl %0,%%db1\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
__asm__("movl %0,%%db2\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
__asm__("movl %0,%%db3\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (addr));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup mask for dr7
|
||||
*/
|
||||
mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2));
|
||||
__asm__("movl %%db7,%%eax\n\t"
|
||||
"orl %0,%%eax\n\t"
|
||||
"movl %%eax,%%db7\n\t"
|
||||
: /* no outputs */
|
||||
: "d" (mask)
|
||||
: "ax");
|
||||
}
|
||||
|
||||
extern int edata;
|
||||
extern int end;
|
||||
|
||||
asmlinkage void _main(boot_param* _bp)
|
||||
/*
|
||||
* FUNCTION: Called by the boot loader to start the kernel
|
||||
* ARGUMENTS:
|
||||
* _bp = Pointer to boot parameters initialized by the boot loader
|
||||
* NOTE: The boot parameters are stored in low memory which will become
|
||||
* invalid after the memory managment is initialized so we make a local copy.
|
||||
*/
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int start;
|
||||
unsigned int start1;
|
||||
boot_param bp;
|
||||
|
||||
memset((void *)&edata,0,((int)&end)-((int)&edata));
|
||||
|
||||
/*
|
||||
* Copy the parameters to a local buffer because lowmem will go away
|
||||
*/
|
||||
memcpy(&bp,_bp,sizeof(boot_param));
|
||||
|
||||
/*
|
||||
* Initalize the console (before printing anything)
|
||||
*/
|
||||
HalInitConsole(&bp);
|
||||
|
||||
DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");
|
||||
|
||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||
if (start < ((int)&end))
|
||||
{
|
||||
DbgPrint("start %x end %x\n",start,(int)&end);
|
||||
DbgPrint("Kernel booted incorrectly, aborting\n");
|
||||
DbgPrint("Reduce the amount of uninitialized data\n");
|
||||
for(;;);
|
||||
}
|
||||
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
|
||||
|
||||
|
||||
/*
|
||||
* Initalize various critical subsystems
|
||||
*/
|
||||
HalInit(&bp);
|
||||
MmInitalize(&bp);
|
||||
KeInit();
|
||||
ObInit();
|
||||
PsInit();
|
||||
IoInit();
|
||||
|
||||
/*
|
||||
* Initalize services loaded at boot time
|
||||
*/
|
||||
DPRINT("%d files loaded\n",bp.nr_files);
|
||||
|
||||
start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);
|
||||
start1 = start+PAGE_ROUND_UP(bp.module_length[1]);
|
||||
for (i=1;i<bp.nr_files;i++)
|
||||
{
|
||||
process_boot_module(start);
|
||||
start=start+PAGE_ROUND_UP(bp.module_length[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test various features of the kernel
|
||||
*/
|
||||
TstBegin();
|
||||
|
||||
/*
|
||||
* Enter idle loop
|
||||
*/
|
||||
printk("Finished main()\n");
|
||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ static unsigned long long system_time = 0;
|
|||
/*
|
||||
* Number of timer interrupts since initialisation
|
||||
*/
|
||||
static volatile unsigned long long ticks=0;
|
||||
volatile ULONGLONG KiTimerTicks;
|
||||
|
||||
/*
|
||||
* The increment in the system clock every timer tick (in system time units)
|
||||
|
@ -76,10 +76,10 @@ VOID KeCalibrateTimerLoop(VOID)
|
|||
for (i=0;i<20;i++)
|
||||
{
|
||||
|
||||
start_tick = ticks;
|
||||
start_tick = KiTimerTicks;
|
||||
microseconds = 0;
|
||||
while (start_tick == ticks);
|
||||
while (ticks == (start_tick+TICKS_TO_CALIBRATE))
|
||||
while (start_tick == KiTimerTicks);
|
||||
while (KiTimerTicks == (start_tick+TICKS_TO_CALIBRATE))
|
||||
{
|
||||
KeStallExecutionProcessor(1);
|
||||
microseconds++;
|
||||
|
@ -418,7 +418,7 @@ VOID KeQueryTickCount(PLARGE_INTEGER TickCount)
|
|||
* TickCount (OUT) = Points to storage for the number of ticks
|
||||
*/
|
||||
{
|
||||
LARGE_INTEGER_QUAD_PART(*TickCount) = ticks;
|
||||
LARGE_INTEGER_QUAD_PART(*TickCount) = KiTimerTicks;
|
||||
}
|
||||
|
||||
static void HandleExpiredTimer(PKTIMER current)
|
||||
|
@ -484,11 +484,13 @@ BOOLEAN KiTimerInterrupt(VOID)
|
|||
char* vidmem=(char *)physical_to_linear(0xb8000 + 160 - 36);
|
||||
int i;
|
||||
int x,y;
|
||||
extern ULONG PiNrThreads;
|
||||
extern ULONG EiNrUsedBlocks;
|
||||
|
||||
/*
|
||||
* Increment the number of timers ticks
|
||||
*/
|
||||
ticks++;
|
||||
KiTimerTicks++;
|
||||
system_time = system_time + CLOCK_INCREMENT;
|
||||
|
||||
/*
|
||||
|
@ -508,7 +510,8 @@ BOOLEAN KiTimerInterrupt(VOID)
|
|||
(EiFreeNonPagedPool + EiUsedNonPagedPool);
|
||||
}
|
||||
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,ticks);
|
||||
sprintf(str,"%.4u %.4u %.7u",x,y,ticks);
|
||||
memset(str, 0, sizeof(str));
|
||||
sprintf(str,"%.8u %.8u",EiNrUsedBlocks,KiTimerTicks);
|
||||
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
|
||||
for (i=0;i<17;i++)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,124 +1,118 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/pool.c
|
||||
* PURPOSE: Implements the kernel memory pool
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/pool.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)
|
||||
/*
|
||||
* FUNCTION: Allocates pool memory of a specified type and returns a pointer
|
||||
* to the allocated block. This routine is used for general purpose allocation
|
||||
* of memory
|
||||
* ARGUMENTS:
|
||||
* PoolType
|
||||
* Specifies the type of memory to allocate which can be one
|
||||
* of the following:
|
||||
*
|
||||
* NonPagedPool
|
||||
* NonPagedPoolMustSucceed
|
||||
* NonPagedPoolCacheAligned
|
||||
* NonPagedPoolCacheAlignedMustS
|
||||
* PagedPool
|
||||
* PagedPoolCacheAligned
|
||||
*
|
||||
* NumberOfBytes
|
||||
* Specifies the number of bytes to allocate
|
||||
* RETURNS: The allocated block on success
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
OLD_DPRINT("ExAllocatePool(NumberOfBytes %d) caller %x\n",
|
||||
NumberOfBytes,
|
||||
((PULONG)&PoolType)[-1]);
|
||||
|
||||
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);
|
||||
|
||||
OLD_DPRINT("ExAllocatePool() = %x\n",Block);
|
||||
|
||||
return Block;
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
if (type == NonPagedPoolCacheAligned ||
|
||||
type == NonPagedPoolCacheAlignedMustS)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case NonPagedPool:
|
||||
case NonPagedPoolMustSucceed:
|
||||
case NonPagedPoolCacheAligned:
|
||||
case NonPagedPoolCacheAlignedMustS:
|
||||
Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);
|
||||
break;
|
||||
|
||||
case PagedPool:
|
||||
case PagedPoolCacheAligned:
|
||||
Block = ExAllocatePagedPoolWithTag(type,size,Tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
return(NULL);
|
||||
};
|
||||
|
||||
if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)
|
||||
&& Block==NULL)
|
||||
{
|
||||
KeBugCheck(MUST_SUCCEED_POOL_EMPTY);
|
||||
}
|
||||
return(Block);
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,
|
||||
ULONG Tag)
|
||||
{
|
||||
PVOID Block;
|
||||
PKTHREAD current = KeGetCurrentThread();
|
||||
|
||||
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);
|
||||
switch(PoolType)
|
||||
{
|
||||
case NonPagedPool:
|
||||
case NonPagedPoolMustSucceed:
|
||||
case NonPagedPoolCacheAligned:
|
||||
case NonPagedPoolCacheAlignedMustS:
|
||||
// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;
|
||||
break;
|
||||
|
||||
case PagedPool:
|
||||
case PagedPoolCacheAligned:
|
||||
// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;
|
||||
break;
|
||||
};
|
||||
return(Block);
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)
|
||||
{
|
||||
return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));
|
||||
}
|
||||
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/pool.c
|
||||
* PURPOSE: Implements the kernel memory pool
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <internal/ntoskrnl.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/pool.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)
|
||||
/*
|
||||
* FUNCTION: Allocates pool memory of a specified type and returns a pointer
|
||||
* to the allocated block. This routine is used for general purpose allocation
|
||||
* of memory
|
||||
* ARGUMENTS:
|
||||
* PoolType
|
||||
* Specifies the type of memory to allocate which can be one
|
||||
* of the following:
|
||||
*
|
||||
* NonPagedPool
|
||||
* NonPagedPoolMustSucceed
|
||||
* NonPagedPoolCacheAligned
|
||||
* NonPagedPoolCacheAlignedMustS
|
||||
* PagedPool
|
||||
* PagedPoolCacheAligned
|
||||
*
|
||||
* NumberOfBytes
|
||||
* Specifies the number of bytes to allocate
|
||||
* RETURNS: The allocated block on success
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
PVOID Block;
|
||||
// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",
|
||||
// NumberOfBytes,((PULONG)&PoolType)[-1]);
|
||||
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);
|
||||
// DbgPrint("ExAllocatePool() = %x\n",Block);
|
||||
return(Block);
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)
|
||||
{
|
||||
PVOID Block;
|
||||
|
||||
if (type == NonPagedPoolCacheAligned ||
|
||||
type == NonPagedPoolCacheAlignedMustS)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case NonPagedPool:
|
||||
case NonPagedPoolMustSucceed:
|
||||
case NonPagedPoolCacheAligned:
|
||||
case NonPagedPoolCacheAlignedMustS:
|
||||
Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);
|
||||
break;
|
||||
|
||||
case PagedPool:
|
||||
case PagedPoolCacheAligned:
|
||||
Block = ExAllocatePagedPoolWithTag(type,size,Tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
return(NULL);
|
||||
};
|
||||
|
||||
if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)
|
||||
&& Block==NULL)
|
||||
{
|
||||
KeBugCheck(MUST_SUCCEED_POOL_EMPTY);
|
||||
}
|
||||
return(Block);
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,
|
||||
ULONG Tag)
|
||||
{
|
||||
PVOID Block;
|
||||
PKTHREAD current = KeGetCurrentThread();
|
||||
|
||||
Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);
|
||||
switch(PoolType)
|
||||
{
|
||||
case NonPagedPool:
|
||||
case NonPagedPoolMustSucceed:
|
||||
case NonPagedPoolCacheAligned:
|
||||
case NonPagedPoolCacheAlignedMustS:
|
||||
// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;
|
||||
break;
|
||||
|
||||
case PagedPool:
|
||||
case PagedPoolCacheAligned:
|
||||
// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;
|
||||
break;
|
||||
};
|
||||
return(Block);
|
||||
}
|
||||
|
||||
PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)
|
||||
{
|
||||
return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));
|
||||
}
|
||||
|
|
|
@ -104,8 +104,8 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle,
|
|||
PSECTION_OBJECT Section;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("ZwCreateSection()\n");
|
||||
|
||||
DbgPrint("ZwCreateSection()\n");
|
||||
|
||||
Section = ObGenericCreateObject(SectionHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
|
@ -128,11 +128,13 @@ NTSTATUS STDCALL ZwCreateSection(OUT PHANDLE SectionHandle,
|
|||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT("ZwCreateSection() = %x\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Section->AllocateAttributes = AllocationAttributes;
|
||||
|
||||
DPRINT("ZwCreateSection() = STATUS_SUCCESS\n");
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,367 +1,379 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ob/object.c
|
||||
* PURPOSE: Implements generic object managment functions
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 10/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ob.h>
|
||||
#include <wstring.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ************************************************************/
|
||||
|
||||
NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
IN PVOID ObjectInformation,
|
||||
IN ULONG Length)
|
||||
{
|
||||
return(ZwSetInformationObject(ObjectHandle,
|
||||
ObjectInformationClass,
|
||||
ObjectInformation,
|
||||
Length));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
IN PVOID ObjectInformation,
|
||||
IN ULONG Length)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
return(ZwQueryObject(ObjectHandle,
|
||||
ObjectInformationClass,
|
||||
ObjectInformation,
|
||||
Length,
|
||||
ResultLength));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
NTSTATUS NtMakeTemporaryObject(HANDLE Handle)
|
||||
{
|
||||
return(ZwMakeTemporaryObject(Handle));
|
||||
}
|
||||
|
||||
NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)
|
||||
{
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
Status = ObReferenceObjectByHandle(Handle,
|
||||
0,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&Object,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
ObjectHeader = BODY_TO_HEADER(Object);
|
||||
ObjectHeader->Permanent = FALSE;
|
||||
|
||||
ObDereferenceObject(Object);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
POBJECT_TYPE Type)
|
||||
{
|
||||
POBJECT_HEADER hdr = NULL;
|
||||
UNICODE_STRING ObjectName;
|
||||
PWSTR path;
|
||||
PWSTR name;
|
||||
PWSTR Ignored;
|
||||
|
||||
DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
|
||||
"ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,
|
||||
ObjectAttributes,Type);
|
||||
|
||||
/*
|
||||
* Allocate the object body and header
|
||||
*/
|
||||
hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));
|
||||
if (hdr==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If unnamed then initalize
|
||||
*/
|
||||
if (ObjectAttributes==NULL)
|
||||
{
|
||||
ObInitializeObjectHeader(Type,NULL,hdr);
|
||||
if (Handle != NULL)
|
||||
{
|
||||
*Handle = ObInsertHandle(KeGetCurrentProcess(),
|
||||
HEADER_TO_BODY(hdr),
|
||||
DesiredAccess,
|
||||
FALSE);
|
||||
}
|
||||
return(HEADER_TO_BODY(hdr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the object name into a buffer
|
||||
*/
|
||||
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
|
||||
{
|
||||
path=ObjectName.Buffer;
|
||||
*name=0;
|
||||
name=name+1;
|
||||
}
|
||||
|
||||
ObLookupObject(ObjectAttributes->RootDirectory,path,
|
||||
&hdr->Parent,&Ignored, 0L);
|
||||
|
||||
/*
|
||||
* Initialize the object header
|
||||
*/
|
||||
ObInitializeObjectHeader(Type,name,hdr);
|
||||
ObCreateEntry(hdr->Parent,hdr);
|
||||
|
||||
DPRINT("Handle %x\n",Handle);
|
||||
if (Handle != NULL)
|
||||
{
|
||||
*Handle = ObInsertHandle(KeGetCurrentProcess(),
|
||||
HEADER_TO_BODY(hdr),
|
||||
DesiredAccess,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
return(HEADER_TO_BODY(hdr));
|
||||
}
|
||||
|
||||
VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name,
|
||||
POBJECT_HEADER ObjectHeader)
|
||||
/*
|
||||
* FUNCTION: Creates a new object
|
||||
* ARGUMENT:
|
||||
* id = Identifier for the type of object
|
||||
* obj = Pointer to the header of the object
|
||||
*/
|
||||
{
|
||||
PWSTR temp_name;
|
||||
|
||||
DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type,
|
||||
name,ObjectHeader);
|
||||
|
||||
ObjectHeader->HandleCount = 0;
|
||||
ObjectHeader->RefCount = 0;
|
||||
ObjectHeader->ObjectType = Type;
|
||||
ObjectHeader->Permanent = FALSE;
|
||||
if (name==NULL)
|
||||
{
|
||||
ObjectHeader->Name.Length=0;
|
||||
ObjectHeader->Name.Buffer=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectHeader->Name.MaximumLength = wstrlen(name);
|
||||
ObjectHeader->Name.Buffer = ExAllocatePool(NonPagedPool,
|
||||
(ObjectHeader->Name.MaximumLength+1)*2);
|
||||
RtlInitUnicodeString(&ObjectHeader->Name,name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_TYPE ObjectType,
|
||||
KPROCESSOR_MODE AccessMode)
|
||||
/*
|
||||
* FUNCTION: Increments the pointer reference count for a given object
|
||||
* ARGUMENTS:
|
||||
* ObjectBody = Object's body
|
||||
* DesiredAccess = Desired access to the object
|
||||
* ObjectType = Points to the object type structure
|
||||
* AccessMode = Type of access check to perform
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
POBJECT_HEADER Object;
|
||||
|
||||
DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);
|
||||
|
||||
Object = BODY_TO_HEADER(ObjectBody);
|
||||
Object->RefCount++;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
|
||||
{
|
||||
if (Header->RefCount == 0 && Header->HandleCount == 0 &&
|
||||
!Header->Permanent)
|
||||
{
|
||||
ObRemoveEntry(Header);
|
||||
ExFreePool(Header);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
VOID ObDereferenceObject(PVOID ObjectBody)
|
||||
/*
|
||||
* FUNCTION: Decrements a given object's reference count and performs
|
||||
* retention checks
|
||||
* ARGUMENTS:
|
||||
* ObjectBody = Body of the object
|
||||
*/
|
||||
{
|
||||
POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
|
||||
Header->RefCount--;
|
||||
ObPerformRetentionChecks(Header);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS NtClose(HANDLE Handle)
|
||||
{
|
||||
return(ZwClose(Handle));
|
||||
}
|
||||
|
||||
NTSTATUS ZwClose(HANDLE Handle)
|
||||
/*
|
||||
* FUNCTION: Closes a handle reference to an object
|
||||
* ARGUMENTS:
|
||||
* Handle = handle to close
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
POBJECT_HEADER Header;
|
||||
PHANDLE_REP HandleRep;
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
|
||||
if (HandleRep == NULL)
|
||||
{
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
ObjectBody = HandleRep->ObjectBody;
|
||||
|
||||
HandleRep->ObjectBody = NULL;
|
||||
|
||||
Header = BODY_TO_HEADER(ObjectBody);
|
||||
|
||||
Header->HandleCount--;
|
||||
ObPerformRetentionChecks(Header);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_TYPE ObjectType,
|
||||
KPROCESSOR_MODE AccessMode,
|
||||
PVOID* Object,
|
||||
POBJECT_HANDLE_INFORMATION
|
||||
HandleInformationPtr
|
||||
)
|
||||
/*
|
||||
* FUNCTION: Increments the reference count for an object and returns a
|
||||
* pointer to its body
|
||||
* ARGUMENTS:
|
||||
* Handle = Handle for the object
|
||||
* DesiredAccess = Desired access to the object
|
||||
* ObjectType
|
||||
* AccessMode
|
||||
* Object (OUT) = Points to the object body on return
|
||||
* HandleInformation (OUT) = Contains information about the handle
|
||||
* on return
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PHANDLE_REP HandleRep;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
|
||||
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
|
||||
ObjectType,AccessMode,Object);
|
||||
|
||||
if (Handle == NtCurrentProcess())
|
||||
{
|
||||
*Object = PsGetCurrentProcess();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
if (Handle == NtCurrentThread())
|
||||
{
|
||||
*Object = PsGetCurrentThread();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
|
||||
if (HandleRep == NULL || HandleRep->ObjectBody == NULL)
|
||||
{
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody);
|
||||
|
||||
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
if (!(HandleRep->GrantedAccess & DesiredAccess))
|
||||
{
|
||||
return(STATUS_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
ObjectHeader->RefCount++;
|
||||
|
||||
*Object = HandleRep->ObjectBody;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ob/object.c
|
||||
* PURPOSE: Implements generic object managment functions
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* 10/06/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ob.h>
|
||||
#include <wstring.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* FUNCTIONS ************************************************************/
|
||||
|
||||
NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
IN PVOID ObjectInformation,
|
||||
IN ULONG Length)
|
||||
{
|
||||
return(ZwSetInformationObject(ObjectHandle,
|
||||
ObjectInformationClass,
|
||||
ObjectInformation,
|
||||
Length));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
IN PVOID ObjectInformation,
|
||||
IN ULONG Length)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
return(ZwQueryObject(ObjectHandle,
|
||||
ObjectInformationClass,
|
||||
ObjectInformation,
|
||||
Length,
|
||||
ResultLength));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
NTSTATUS NtMakeTemporaryObject(HANDLE Handle)
|
||||
{
|
||||
return(ZwMakeTemporaryObject(Handle));
|
||||
}
|
||||
|
||||
NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)
|
||||
{
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
Status = ObReferenceObjectByHandle(Handle,
|
||||
0,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&Object,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
ObjectHeader = BODY_TO_HEADER(Object);
|
||||
ObjectHeader->Permanent = FALSE;
|
||||
|
||||
ObDereferenceObject(Object);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
PVOID ObGenericCreateObject(PHANDLE Handle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
POBJECT_TYPE Type)
|
||||
{
|
||||
POBJECT_HEADER hdr = NULL;
|
||||
PWSTR path;
|
||||
PWSTR name;
|
||||
PWSTR Ignored;
|
||||
PULONG addr;
|
||||
PWSTR Buffer;
|
||||
|
||||
DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"
|
||||
"ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,
|
||||
ObjectAttributes,Type);
|
||||
|
||||
/*
|
||||
* Allocate the object body and header
|
||||
*/
|
||||
hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));
|
||||
DPRINT("OBJECT_ALLOC_SIZE(Type) %d\n",OBJECT_ALLOC_SIZE(Type));
|
||||
if (hdr==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
DPRINT("hdr %x\n",hdr);
|
||||
|
||||
|
||||
/*
|
||||
* If unnamed then initalize
|
||||
*/
|
||||
if (ObjectAttributes==NULL || ObjectAttributes->ObjectName==NULL)
|
||||
{
|
||||
ObInitializeObjectHeader(Type,NULL,hdr);
|
||||
if (Handle != NULL)
|
||||
{
|
||||
*Handle = ObInsertHandle(KeGetCurrentProcess(),
|
||||
HEADER_TO_BODY(hdr),
|
||||
DesiredAccess,
|
||||
FALSE);
|
||||
}
|
||||
return(HEADER_TO_BODY(hdr));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy the object name into a buffer
|
||||
*/
|
||||
// DbgPrint("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);
|
||||
// DbgPrint("ObjectAttributes->ObjectName->Length %d\n",
|
||||
// ObjectAttributes->ObjectName->Length);
|
||||
// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",
|
||||
// ObjectAttributes->ObjectName->MaximumLength);
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
((ObjectAttributes->ObjectName->Length+1)*2));
|
||||
if (Buffer==NULL)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,
|
||||
(ObjectAttributes->ObjectName->Length+1)*2);
|
||||
|
||||
/*
|
||||
* Seperate the name into a path and name
|
||||
*/
|
||||
name = wcsrchr(Buffer,'\\');
|
||||
if (name==NULL)
|
||||
{
|
||||
name=Buffer;
|
||||
path=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
path=Buffer;
|
||||
*name=0;
|
||||
name=name+1;
|
||||
}
|
||||
DPRINT("name %w path %w\n",name,path);
|
||||
|
||||
ObLookupObject(ObjectAttributes->RootDirectory,
|
||||
path,
|
||||
&hdr->Parent,
|
||||
&Ignored,
|
||||
0L);
|
||||
|
||||
/*
|
||||
* Initialize the object header
|
||||
*/
|
||||
ObInitializeObjectHeader(Type,name,hdr);
|
||||
|
||||
|
||||
ObCreateEntry(hdr->Parent,hdr);
|
||||
|
||||
DPRINT("Handle %x\n",Handle);
|
||||
if (Handle != NULL)
|
||||
{
|
||||
*Handle = ObInsertHandle(KeGetCurrentProcess(),
|
||||
HEADER_TO_BODY(hdr),
|
||||
DesiredAccess,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
return(HEADER_TO_BODY(hdr));
|
||||
}
|
||||
|
||||
VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name,
|
||||
POBJECT_HEADER ObjectHeader)
|
||||
/*
|
||||
* FUNCTION: Creates a new object
|
||||
* ARGUMENT:
|
||||
* id = Identifier for the type of object
|
||||
* obj = Pointer to the header of the object
|
||||
*/
|
||||
{
|
||||
PWSTR temp_name;
|
||||
extern unsigned long long ticks;
|
||||
|
||||
DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type,
|
||||
name,ObjectHeader);
|
||||
|
||||
ObjectHeader->HandleCount = 0;
|
||||
ObjectHeader->RefCount = 0;
|
||||
ObjectHeader->ObjectType = Type;
|
||||
ObjectHeader->Permanent = FALSE;
|
||||
if (name==NULL)
|
||||
{
|
||||
ObjectHeader->Name.Length=0;
|
||||
ObjectHeader->Name.Buffer=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitUnicodeString(&(ObjectHeader->Name),name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_TYPE ObjectType,
|
||||
KPROCESSOR_MODE AccessMode)
|
||||
/*
|
||||
* FUNCTION: Increments the pointer reference count for a given object
|
||||
* ARGUMENTS:
|
||||
* ObjectBody = Object's body
|
||||
* DesiredAccess = Desired access to the object
|
||||
* ObjectType = Points to the object type structure
|
||||
* AccessMode = Type of access check to perform
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
POBJECT_HEADER Object;
|
||||
|
||||
DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);
|
||||
|
||||
Object = BODY_TO_HEADER(ObjectBody);
|
||||
Object->RefCount++;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
|
||||
{
|
||||
if (Header->RefCount == 0 && Header->HandleCount == 0 &&
|
||||
!Header->Permanent)
|
||||
{
|
||||
ObRemoveEntry(Header);
|
||||
ExFreePool(Header);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
VOID ObDereferenceObject(PVOID ObjectBody)
|
||||
/*
|
||||
* FUNCTION: Decrements a given object's reference count and performs
|
||||
* retention checks
|
||||
* ARGUMENTS:
|
||||
* ObjectBody = Body of the object
|
||||
*/
|
||||
{
|
||||
POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
|
||||
Header->RefCount--;
|
||||
ObPerformRetentionChecks(Header);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS NtClose(HANDLE Handle)
|
||||
{
|
||||
return(ZwClose(Handle));
|
||||
}
|
||||
|
||||
NTSTATUS ZwClose(HANDLE Handle)
|
||||
/*
|
||||
* FUNCTION: Closes a handle reference to an object
|
||||
* ARGUMENTS:
|
||||
* Handle = handle to close
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
POBJECT_HEADER Header;
|
||||
PHANDLE_REP HandleRep;
|
||||
|
||||
assert_irql(PASSIVE_LEVEL);
|
||||
|
||||
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
|
||||
if (HandleRep == NULL)
|
||||
{
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
ObjectBody = HandleRep->ObjectBody;
|
||||
|
||||
HandleRep->ObjectBody = NULL;
|
||||
|
||||
Header = BODY_TO_HEADER(ObjectBody);
|
||||
|
||||
Header->HandleCount--;
|
||||
ObPerformRetentionChecks(Header);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_TYPE ObjectType,
|
||||
KPROCESSOR_MODE AccessMode,
|
||||
PVOID* Object,
|
||||
POBJECT_HANDLE_INFORMATION
|
||||
HandleInformationPtr
|
||||
)
|
||||
/*
|
||||
* FUNCTION: Increments the reference count for an object and returns a
|
||||
* pointer to its body
|
||||
* ARGUMENTS:
|
||||
* Handle = Handle for the object
|
||||
* DesiredAccess = Desired access to the object
|
||||
* ObjectType
|
||||
* AccessMode
|
||||
* Object (OUT) = Points to the object body on return
|
||||
* HandleInformation (OUT) = Contains information about the handle
|
||||
* on return
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PHANDLE_REP HandleRep;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
|
||||
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
|
||||
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
|
||||
ObjectType,AccessMode,Object);
|
||||
|
||||
if (Handle == NtCurrentProcess())
|
||||
{
|
||||
*Object = PsGetCurrentProcess();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
if (Handle == NtCurrentThread())
|
||||
{
|
||||
*Object = PsGetCurrentThread();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
|
||||
if (HandleRep == NULL || HandleRep->ObjectBody == NULL)
|
||||
{
|
||||
return(STATUS_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody);
|
||||
|
||||
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
if (!(HandleRep->GrantedAccess & DesiredAccess))
|
||||
{
|
||||
return(STATUS_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
ObjectHeader->RefCount++;
|
||||
|
||||
*Object = HandleRep->ObjectBody;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -1,468 +0,0 @@
|
|||
.file "object.c"
|
||||
.version "01.01"
|
||||
gcc2_compiled.:
|
||||
.text
|
||||
.align 16
|
||||
.globl NtSetInformationObject
|
||||
.type NtSetInformationObject,@function
|
||||
NtSetInformationObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%ebx
|
||||
movl 12(%ebp),%ecx
|
||||
movl 16(%ebp),%edx
|
||||
movl 20(%ebp),%eax
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
call ZwSetInformationObject
|
||||
movl -4(%ebp),%ebx
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $16
|
||||
.Lfe1:
|
||||
.size NtSetInformationObject,.Lfe1-NtSetInformationObject
|
||||
.section .rodata
|
||||
.LC0:
|
||||
.string "object.c"
|
||||
.LC1:
|
||||
.string "ZwSetInformationObject"
|
||||
.LC2:
|
||||
.string "%s at %s:%d is unimplemented, have a nice day\n"
|
||||
.text
|
||||
.align 16
|
||||
.globl ZwSetInformationObject
|
||||
.type ZwSetInformationObject,@function
|
||||
ZwSetInformationObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl $38
|
||||
pushl $.LC0
|
||||
pushl $.LC1
|
||||
pushl $.LC2
|
||||
call DbgPrint
|
||||
.align 4
|
||||
.L17:
|
||||
jmp .L17
|
||||
.align 16
|
||||
.Lfe2:
|
||||
.size ZwSetInformationObject,.Lfe2-ZwSetInformationObject
|
||||
.align 16
|
||||
.globl NtQueryObject
|
||||
.type NtQueryObject,@function
|
||||
NtQueryObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%esi
|
||||
movl 12(%ebp),%ebx
|
||||
movl 16(%ebp),%ecx
|
||||
movl 20(%ebp),%edx
|
||||
movl 24(%ebp),%eax
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
call ZwQueryObject
|
||||
leal -8(%ebp),%esp
|
||||
popl %ebx
|
||||
popl %esi
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $20
|
||||
.Lfe3:
|
||||
.size NtQueryObject,.Lfe3-NtQueryObject
|
||||
.section .rodata
|
||||
.LC3:
|
||||
.string "ZwQueryObject"
|
||||
.text
|
||||
.align 16
|
||||
.globl ZwQueryObject
|
||||
.type ZwQueryObject,@function
|
||||
ZwQueryObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl $60
|
||||
pushl $.LC0
|
||||
pushl $.LC3
|
||||
pushl $.LC2
|
||||
call DbgPrint
|
||||
.align 4
|
||||
.L26:
|
||||
jmp .L26
|
||||
.align 16
|
||||
.Lfe4:
|
||||
.size ZwQueryObject,.Lfe4-ZwQueryObject
|
||||
.align 16
|
||||
.globl NtMakeTemporaryObject
|
||||
.type NtMakeTemporaryObject,@function
|
||||
NtMakeTemporaryObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%eax
|
||||
pushl %eax
|
||||
call ZwMakeTemporaryObject
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.Lfe5:
|
||||
.size NtMakeTemporaryObject,.Lfe5-NtMakeTemporaryObject
|
||||
.align 16
|
||||
.globl ZwMakeTemporaryObject
|
||||
.type ZwMakeTemporaryObject,@function
|
||||
ZwMakeTemporaryObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $4,%esp
|
||||
movl 8(%ebp),%edx
|
||||
pushl $0
|
||||
leal -4(%ebp),%eax
|
||||
pushl %eax
|
||||
pushl $0
|
||||
pushl $0
|
||||
pushl $0
|
||||
pushl %edx
|
||||
call ObReferenceObjectByHandle
|
||||
addl $24,%esp
|
||||
testl %eax,%eax
|
||||
jne .L30
|
||||
movl -4(%ebp),%eax
|
||||
movb $0,-12(%eax)
|
||||
movl -4(%ebp),%eax
|
||||
pushl %eax
|
||||
call ObDereferenceObject
|
||||
xorl %eax,%eax
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.align 16
|
||||
.L30:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.Lfe6:
|
||||
.size ZwMakeTemporaryObject,.Lfe6-ZwMakeTemporaryObject
|
||||
.align 16
|
||||
.globl ObGenericCreateObject
|
||||
.type ObGenericCreateObject,@function
|
||||
ObGenericCreateObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $12,%esp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 16(%ebp),%edi
|
||||
movl 20(%ebp),%ecx
|
||||
movl 28(%ecx),%eax
|
||||
addl $36,%eax
|
||||
pushl %eax
|
||||
pushl $0
|
||||
call ExAllocatePool
|
||||
movl %eax,%esi
|
||||
addl $8,%esp
|
||||
testl %esi,%esi
|
||||
je .L46
|
||||
testl %edi,%edi
|
||||
jne .L35
|
||||
pushl %esi
|
||||
pushl $0
|
||||
movl 20(%ebp),%ecx
|
||||
pushl %ecx
|
||||
call ObInitializeObjectHeader
|
||||
addl $12,%esp
|
||||
jmp .L47
|
||||
.align 16
|
||||
.L35:
|
||||
movl 8(%edi),%ecx
|
||||
movw (%ecx),%dx
|
||||
sall $16,%edx
|
||||
movzwl -8(%ebp),%eax
|
||||
orl %edx,%eax
|
||||
movl %eax,-8(%ebp)
|
||||
movzwl (%ecx),%eax
|
||||
leal 2(,%eax,2),%eax
|
||||
pushl %eax
|
||||
pushl $0
|
||||
call ExAllocatePool
|
||||
movl %eax,-4(%ebp)
|
||||
addl $8,%esp
|
||||
testl %eax,%eax
|
||||
jne .L39
|
||||
.L46:
|
||||
xorl %eax,%eax
|
||||
jmp .L45
|
||||
.align 16
|
||||
.L39:
|
||||
movl 8(%edi),%eax
|
||||
pushl %eax
|
||||
leal -8(%ebp),%eax
|
||||
pushl %eax
|
||||
call RtlCopyUnicodeString
|
||||
pushl $92
|
||||
movl -4(%ebp),%eax
|
||||
pushl %eax
|
||||
call wcsrchr
|
||||
movl %eax,%ebx
|
||||
addl $16,%esp
|
||||
testl %ebx,%ebx
|
||||
jne .L40
|
||||
movl -4(%ebp),%ebx
|
||||
xorl %edx,%edx
|
||||
jmp .L41
|
||||
.align 16
|
||||
.L40:
|
||||
movl -4(%ebp),%edx
|
||||
movw $0,(%ebx)
|
||||
addl $2,%ebx
|
||||
.L41:
|
||||
leal -12(%ebp),%eax
|
||||
pushl %eax
|
||||
leal 28(%esi),%eax
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
movl 4(%edi),%eax
|
||||
pushl %eax
|
||||
call ObLookupObject
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 20(%ebp),%ecx
|
||||
pushl %ecx
|
||||
call ObInitializeObjectHeader
|
||||
pushl %esi
|
||||
movl 28(%esi),%eax
|
||||
pushl %eax
|
||||
call ObCreateEntry
|
||||
addl $36,%esp
|
||||
.L47:
|
||||
cmpl $0,8(%ebp)
|
||||
je .L42
|
||||
pushl $0
|
||||
movl 12(%ebp),%ecx
|
||||
pushl %ecx
|
||||
leal 36(%esi),%eax
|
||||
pushl %eax
|
||||
call KeGetCurrentProcess
|
||||
pushl %eax
|
||||
call ObInsertHandle
|
||||
movl 8(%ebp),%ecx
|
||||
movl %eax,(%ecx)
|
||||
.L42:
|
||||
leal 36(%esi),%eax
|
||||
.L45:
|
||||
leal -24(%ebp),%esp
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe7:
|
||||
.size ObGenericCreateObject,.Lfe7-ObGenericCreateObject
|
||||
.align 16
|
||||
.globl ObInitializeObjectHeader
|
||||
.type ObInitializeObjectHeader,@function
|
||||
ObInitializeObjectHeader:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%eax
|
||||
movl 12(%ebp),%esi
|
||||
movl 16(%ebp),%ebx
|
||||
movl $0,20(%ebx)
|
||||
movl $0,16(%ebx)
|
||||
movl %eax,32(%ebx)
|
||||
movb $0,24(%ebx)
|
||||
testl %esi,%esi
|
||||
jne .L49
|
||||
movw $0,(%ebx)
|
||||
movl $0,4(%ebx)
|
||||
jmp .L50
|
||||
.align 16
|
||||
.L49:
|
||||
pushl %esi
|
||||
call wstrlen
|
||||
movw %ax,2(%ebx)
|
||||
andl $65535,%eax
|
||||
leal 2(,%eax,2),%eax
|
||||
pushl %eax
|
||||
pushl $0
|
||||
call ExAllocatePool
|
||||
movl %eax,4(%ebx)
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
call RtlInitUnicodeString
|
||||
.L50:
|
||||
leal -8(%ebp),%esp
|
||||
popl %ebx
|
||||
popl %esi
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe8:
|
||||
.size ObInitializeObjectHeader,.Lfe8-ObInitializeObjectHeader
|
||||
.align 16
|
||||
.globl ObReferenceObjectByPointer
|
||||
.type ObReferenceObjectByPointer,@function
|
||||
ObReferenceObjectByPointer:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%eax
|
||||
incl -20(%eax)
|
||||
xorl %eax,%eax
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe9:
|
||||
.size ObReferenceObjectByPointer,.Lfe9-ObReferenceObjectByPointer
|
||||
.align 16
|
||||
.globl ObPerformRetentionChecks
|
||||
.type ObPerformRetentionChecks,@function
|
||||
ObPerformRetentionChecks:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%ebx
|
||||
cmpl $0,16(%ebx)
|
||||
jne .L54
|
||||
cmpl $0,20(%ebx)
|
||||
jne .L54
|
||||
cmpb $0,24(%ebx)
|
||||
jne .L54
|
||||
pushl %ebx
|
||||
call ObRemoveEntry
|
||||
pushl %ebx
|
||||
call ExFreePool
|
||||
.L54:
|
||||
xorl %eax,%eax
|
||||
movl -4(%ebp),%ebx
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe10:
|
||||
.size ObPerformRetentionChecks,.Lfe10-ObPerformRetentionChecks
|
||||
.align 16
|
||||
.globl ObDereferenceObject
|
||||
.type ObDereferenceObject,@function
|
||||
ObDereferenceObject:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%eax
|
||||
leal -36(%eax),%edx
|
||||
decl -20(%eax)
|
||||
pushl %edx
|
||||
call ObPerformRetentionChecks
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe11:
|
||||
.size ObDereferenceObject,.Lfe11-ObDereferenceObject
|
||||
.align 16
|
||||
.globl NtClose
|
||||
.type NtClose,@function
|
||||
NtClose:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%eax
|
||||
pushl %eax
|
||||
call ZwClose
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.Lfe12:
|
||||
.size NtClose,.Lfe12-NtClose
|
||||
.align 16
|
||||
.globl ZwClose
|
||||
.type ZwClose,@function
|
||||
ZwClose:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
movl 8(%ebp),%eax
|
||||
pushl %eax
|
||||
call KeGetCurrentProcess
|
||||
pushl %eax
|
||||
call ObTranslateHandle
|
||||
movl %eax,%edx
|
||||
addl $8,%esp
|
||||
testl %edx,%edx
|
||||
je .L59
|
||||
movl (%edx),%eax
|
||||
movl $0,(%edx)
|
||||
leal -36(%eax),%edx
|
||||
decl -16(%eax)
|
||||
pushl %edx
|
||||
call ObPerformRetentionChecks
|
||||
xorl %eax,%eax
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.align 16
|
||||
.L59:
|
||||
movl $-1073741816,%eax
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret $4
|
||||
.Lfe13:
|
||||
.size ZwClose,.Lfe13-ZwClose
|
||||
.align 16
|
||||
.globl ObReferenceObjectByHandle
|
||||
.type ObReferenceObjectByHandle,@function
|
||||
ObReferenceObjectByHandle:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%eax
|
||||
movl 16(%ebp),%ebx
|
||||
movl 24(%ebp),%esi
|
||||
pushl %eax
|
||||
call KeGetCurrentProcess
|
||||
pushl %eax
|
||||
call ObTranslateHandle
|
||||
testl %eax,%eax
|
||||
je .L64
|
||||
movl (%eax),%edx
|
||||
testl %edx,%edx
|
||||
jne .L63
|
||||
.L64:
|
||||
movl $-1073741816,%eax
|
||||
jmp .L68
|
||||
.align 16
|
||||
.L63:
|
||||
leal -36(%edx),%ecx
|
||||
testl %ebx,%ebx
|
||||
je .L66
|
||||
cmpl %ebx,-4(%edx)
|
||||
je .L66
|
||||
movl $-2147483605,%eax
|
||||
jmp .L68
|
||||
.align 16
|
||||
.L66:
|
||||
movl 12(%ebp),%edi
|
||||
testl %edi,4(%eax)
|
||||
jne .L67
|
||||
incl 16(%ecx)
|
||||
movl (%eax),%eax
|
||||
movl %eax,(%esi)
|
||||
xorl %eax,%eax
|
||||
jmp .L68
|
||||
.align 16
|
||||
.L67:
|
||||
movl $-2147483557,%eax
|
||||
.L68:
|
||||
leal -12(%ebp),%esp
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.Lfe14:
|
||||
.size ObReferenceObjectByHandle,.Lfe14-ObReferenceObjectByHandle
|
||||
.ident "GCC: (GNU) 2.7.2.3"
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/bug.c
|
||||
* PURPOSE: Graceful system shutdown if a bug is detected
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* FILE: ntoskrnl/ps/idle.c
|
||||
* PURPOSE: Using idle time
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
* UPDATE HISTORY:
|
||||
* Created 22/05/98
|
||||
*/
|
||||
|
|
|
@ -13,9 +13,13 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLBOALS *******************************************************************/
|
||||
|
||||
extern ULONG PiNrThreads;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
|
||||
|
@ -51,6 +55,14 @@ NTSTATUS STDCALL ZwTerminateThread(IN HANDLE ThreadHandle,
|
|||
}
|
||||
}
|
||||
|
||||
VOID PsReleaseThread(PETHREAD Thread)
|
||||
{
|
||||
DPRINT("PsReleaseThread(Thread %x)\n",Thread);
|
||||
|
||||
RemoveEntryList(&Thread->Tcb.Entry);
|
||||
ExFreePool(Thread);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
|
||||
/*
|
||||
|
@ -63,6 +75,8 @@ NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
|
|||
KIRQL oldlvl;
|
||||
PETHREAD CurrentThread;
|
||||
|
||||
PiNrThreads--;
|
||||
|
||||
CurrentThread = PsGetCurrentThread();
|
||||
|
||||
CurrentThread->ExitStatus = ExitStatus;
|
||||
|
@ -70,7 +84,6 @@ NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
|
|||
DPRINT("terminating %x\n",CurrentThread);
|
||||
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
|
||||
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
|
||||
RemoveEntryList(&CurrentThread->Tcb.Entry);
|
||||
ZwYieldExecution();
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
@ -1,316 +1,329 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ps/process.c
|
||||
* PURPOSE: Process managment
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* REVISION HISTORY:
|
||||
* 21/07/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ob.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
PEPROCESS SystemProcess = NULL;
|
||||
HANDLE SystemProcessHandle = NULL;
|
||||
|
||||
POBJECT_TYPE PsProcessType = NULL;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID PsInitProcessManagment(VOID)
|
||||
{
|
||||
ANSI_STRING AnsiString;
|
||||
PKPROCESS KProcess;
|
||||
|
||||
/*
|
||||
* Register the process object type
|
||||
*/
|
||||
|
||||
PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
|
||||
PsProcessType->TotalObjects = 0;
|
||||
PsProcessType->TotalHandles = 0;
|
||||
PsProcessType->MaxObjects = ULONG_MAX;
|
||||
PsProcessType->MaxHandles = ULONG_MAX;
|
||||
PsProcessType->PagedPoolCharge = 0;
|
||||
PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
|
||||
PsProcessType->Dump = NULL;
|
||||
PsProcessType->Open = NULL;
|
||||
PsProcessType->Close = NULL;
|
||||
PsProcessType->Delete = NULL;
|
||||
PsProcessType->Parse = NULL;
|
||||
PsProcessType->Security = NULL;
|
||||
PsProcessType->QueryName = NULL;
|
||||
PsProcessType->OkayToClose = NULL;
|
||||
|
||||
RtlInitAnsiString(&AnsiString,"Process");
|
||||
RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
|
||||
|
||||
/*
|
||||
* Initialize the system process
|
||||
*/
|
||||
SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,
|
||||
PsProcessType);
|
||||
KProcess = &SystemProcess->Pcb;
|
||||
|
||||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
ObInitializeHandleTable(NULL,FALSE,KProcess);
|
||||
KProcess->PageTableDirectory = get_page_directory();
|
||||
|
||||
SystemProcessHandle = ObInsertHandle(KProcess,SystemProcess,
|
||||
PROCESS_ALL_ACCESS,FALSE);
|
||||
}
|
||||
|
||||
PKPROCESS KeGetCurrentProcess(VOID)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the current process
|
||||
*/
|
||||
{
|
||||
return(&(PsGetCurrentProcess()->Pcb));
|
||||
}
|
||||
|
||||
struct _EPROCESS* PsGetCurrentProcess(VOID)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the current process
|
||||
*/
|
||||
{
|
||||
if (PsGetCurrentThread()==NULL
|
||||
|| PsGetCurrentThread()->ThreadsProcess==NULL)
|
||||
{
|
||||
return(SystemProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(PsGetCurrentThread()->ThreadsProcess);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtCreateProcess(
|
||||
OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN HANDLE ParentProcessHandle,
|
||||
IN BOOLEAN InheritObjectTable,
|
||||
IN HANDLE SectionHandle OPTIONAL,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL)
|
||||
{
|
||||
return(ZwCreateProcess(ProcessHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
ParentProcessHandle,
|
||||
InheritObjectTable,
|
||||
SectionHandle,
|
||||
DebugPort,
|
||||
ExceptionPort));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwCreateProcess(
|
||||
OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN HANDLE ParentProcessHandle,
|
||||
IN BOOLEAN InheritObjectTable,
|
||||
IN HANDLE SectionHandle OPTIONAL,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL)
|
||||
/*
|
||||
* FUNCTION: Creates a process.
|
||||
* ARGUMENTS:
|
||||
* ProcessHandle (OUT) = Caller supplied storage for the resulting
|
||||
* handle
|
||||
* DesiredAccess = Specifies the allowed or desired access to the
|
||||
* process can be a combination of
|
||||
* STANDARD_RIGHTS_REQUIRED| ..
|
||||
* ObjectAttribute = Initialized attributes for the object, contains
|
||||
* the rootdirectory and the filename
|
||||
* ParentProcess = Handle to the parent process.
|
||||
* InheritObjectTable = Specifies to inherit the objects of the parent
|
||||
* process if true.
|
||||
* SectionHandle = Handle to a section object to back the image file
|
||||
* DebugPort = Handle to a DebugPort if NULL the system default debug
|
||||
* port will be used.
|
||||
* ExceptionPort = Handle to a exception port.
|
||||
* REMARKS:
|
||||
* This function maps to the win32 CreateProcess.
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PEPROCESS Process;
|
||||
PEPROCESS ParentProcess;
|
||||
PULONG PageDirectory;
|
||||
PULONG CurrentPageDirectory;
|
||||
ULONG i;
|
||||
PKPROCESS KProcess;
|
||||
ULONG Base;
|
||||
ULONG Length;
|
||||
LARGE_INTEGER Offset;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ObReferenceObjectByHandle(ParentProcessHandle,
|
||||
PROCESS_CREATE_PROCESS,
|
||||
PsProcessType,
|
||||
UserMode,
|
||||
&ParentProcessHandle,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT("ZwCreateProcess() = %x\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Process = ObGenericCreateObject(ProcessHandle,DesiredAccess,
|
||||
ObjectAttributes,PsProcessType);
|
||||
KProcess = &(Process->Pcb);
|
||||
|
||||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
ObInitializeHandleTable(KProcess,InheritObjectTable,KProcess);
|
||||
|
||||
PageDirectory = physical_to_linear((ULONG)get_free_page());
|
||||
KProcess->PageTableDirectory = PageDirectory;
|
||||
|
||||
CurrentPageDirectory = get_page_directory();
|
||||
|
||||
memset(PageDirectory,0,PAGESIZE);
|
||||
for (i=768;i<1024;i++)
|
||||
{
|
||||
PageDirectory[i]=CurrentPageDirectory[i];
|
||||
}
|
||||
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
|
||||
IN NTSTATUS ExitStatus)
|
||||
{
|
||||
return(ZwTerminateProcess(ProcessHandle,ExitStatus));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
|
||||
IN NTSTATUS ExitStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN PCLIENT_ID ClientId)
|
||||
{
|
||||
return(ZwOpenProcess(ProcessHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
ClientId));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN PCLIENT_ID ClientId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength)
|
||||
{
|
||||
return(ZwQueryInformationProcess(ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
ProcessInformationLength,
|
||||
ReturnLength));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
PROCESS_QUERY_INFORMATION,
|
||||
PsProcessType,
|
||||
UserMode,
|
||||
&ProcessHandle,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
switch (ProcessInformationClass)
|
||||
{
|
||||
case ProcessBasicInformation:
|
||||
case ProcessQuotaLimits:
|
||||
case ProcessIoCounters:
|
||||
case ProcessVmCounters:
|
||||
case ProcessTimes:
|
||||
case ProcessBasePriority:
|
||||
case ProcessRaisePriority:
|
||||
case ProcessDebugPort:
|
||||
case ProcessExceptionPort:
|
||||
case ProcessAccessToken:
|
||||
case ProcessLdtInformation:
|
||||
case ProcessLdtSize:
|
||||
case ProcessDefaultHardErrorMode:
|
||||
case ProcessIoPortHandlers:
|
||||
case ProcessWorkingSetWatch:
|
||||
case ProcessUserModeIOPL:
|
||||
case ProcessEnableAlignmentFaultFixup:
|
||||
case ProcessPriorityClass:
|
||||
case ProcessWx86Information:
|
||||
case ProcessHandleCount:
|
||||
case ProcessAffinityMask:
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
IN PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength
|
||||
)
|
||||
{
|
||||
return(ZwSetInformationProcess(ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
ProcessInformationLength));
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ZwSetInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
IN PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ps/process.c
|
||||
* PURPOSE: Process managment
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* REVISION HISTORY:
|
||||
* 21/07/98: Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/ob.h>
|
||||
#include <internal/mm.h>
|
||||
#include <internal/string.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
PEPROCESS SystemProcess = NULL;
|
||||
HANDLE SystemProcessHandle = NULL;
|
||||
|
||||
POBJECT_TYPE PsProcessType = NULL;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID PsInitProcessManagment(VOID)
|
||||
{
|
||||
ANSI_STRING AnsiString;
|
||||
PKPROCESS KProcess;
|
||||
|
||||
/*
|
||||
* Register the process object type
|
||||
*/
|
||||
|
||||
PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||
|
||||
PsProcessType->TotalObjects = 0;
|
||||
PsProcessType->TotalHandles = 0;
|
||||
PsProcessType->MaxObjects = ULONG_MAX;
|
||||
PsProcessType->MaxHandles = ULONG_MAX;
|
||||
PsProcessType->PagedPoolCharge = 0;
|
||||
PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
|
||||
PsProcessType->Dump = NULL;
|
||||
PsProcessType->Open = NULL;
|
||||
PsProcessType->Close = NULL;
|
||||
PsProcessType->Delete = NULL;
|
||||
PsProcessType->Parse = NULL;
|
||||
PsProcessType->Security = NULL;
|
||||
PsProcessType->QueryName = NULL;
|
||||
PsProcessType->OkayToClose = NULL;
|
||||
|
||||
RtlInitAnsiString(&AnsiString,"Process");
|
||||
RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
|
||||
|
||||
/*
|
||||
* Initialize the system process
|
||||
*/
|
||||
SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,
|
||||
PsProcessType);
|
||||
KProcess = &SystemProcess->Pcb;
|
||||
|
||||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
ObInitializeHandleTable(NULL,FALSE,KProcess);
|
||||
KProcess->PageTableDirectory = get_page_directory();
|
||||
|
||||
SystemProcessHandle = ObInsertHandle(KProcess,SystemProcess,
|
||||
PROCESS_ALL_ACCESS,FALSE);
|
||||
}
|
||||
|
||||
PKPROCESS KeGetCurrentProcess(VOID)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the current process
|
||||
*/
|
||||
{
|
||||
return(&(PsGetCurrentProcess()->Pcb));
|
||||
}
|
||||
|
||||
struct _EPROCESS* PsGetCurrentProcess(VOID)
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the current process
|
||||
*/
|
||||
{
|
||||
if (PsGetCurrentThread()==NULL
|
||||
|| PsGetCurrentThread()->ThreadsProcess==NULL)
|
||||
{
|
||||
return(SystemProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(PsGetCurrentThread()->ThreadsProcess);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtCreateProcess(
|
||||
OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN HANDLE ParentProcessHandle,
|
||||
IN BOOLEAN InheritObjectTable,
|
||||
IN HANDLE SectionHandle OPTIONAL,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL)
|
||||
{
|
||||
return(ZwCreateProcess(ProcessHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
ParentProcessHandle,
|
||||
InheritObjectTable,
|
||||
SectionHandle,
|
||||
DebugPort,
|
||||
ExceptionPort));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwCreateProcess(
|
||||
OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN HANDLE ParentProcessHandle,
|
||||
IN BOOLEAN InheritObjectTable,
|
||||
IN HANDLE SectionHandle OPTIONAL,
|
||||
IN HANDLE DebugPort OPTIONAL,
|
||||
IN HANDLE ExceptionPort OPTIONAL)
|
||||
/*
|
||||
* FUNCTION: Creates a process.
|
||||
* ARGUMENTS:
|
||||
* ProcessHandle (OUT) = Caller supplied storage for the resulting
|
||||
* handle
|
||||
* DesiredAccess = Specifies the allowed or desired access to the
|
||||
* process can be a combination of
|
||||
* STANDARD_RIGHTS_REQUIRED| ..
|
||||
* ObjectAttribute = Initialized attributes for the object, contains
|
||||
* the rootdirectory and the filename
|
||||
* ParentProcess = Handle to the parent process.
|
||||
* InheritObjectTable = Specifies to inherit the objects of the parent
|
||||
* process if true.
|
||||
* SectionHandle = Handle to a section object to back the image file
|
||||
* DebugPort = Handle to a DebugPort if NULL the system default debug
|
||||
* port will be used.
|
||||
* ExceptionPort = Handle to a exception port.
|
||||
* REMARKS:
|
||||
* This function maps to the win32 CreateProcess.
|
||||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PEPROCESS Process;
|
||||
PEPROCESS ParentProcess;
|
||||
PULONG PageDirectory;
|
||||
PULONG CurrentPageDirectory;
|
||||
ULONG i;
|
||||
PKPROCESS KProcess;
|
||||
ULONG Base;
|
||||
ULONG Length;
|
||||
LARGE_INTEGER Offset;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
|
||||
|
||||
Status = ObReferenceObjectByHandle(ParentProcessHandle,
|
||||
PROCESS_CREATE_PROCESS,
|
||||
PsProcessType,
|
||||
UserMode,
|
||||
&ParentProcessHandle,
|
||||
NULL);
|
||||
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
DPRINT("ZwCreateProcess() = %x\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Process = ObGenericCreateObject(ProcessHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
PsProcessType);
|
||||
KProcess = &(Process->Pcb);
|
||||
|
||||
InitializeListHead(&(KProcess->MemoryAreaList));
|
||||
ObInitializeHandleTable(KProcess,InheritObjectTable,KProcess);
|
||||
|
||||
PageDirectory = physical_to_linear((ULONG)get_free_page());
|
||||
KProcess->PageTableDirectory = PageDirectory;
|
||||
|
||||
CurrentPageDirectory = get_page_directory();
|
||||
|
||||
memset(PageDirectory,0,PAGESIZE);
|
||||
for (i=768;i<1024;i++)
|
||||
{
|
||||
PageDirectory[i]=CurrentPageDirectory[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: I don't what I'm supposed to know with a section handle
|
||||
*/
|
||||
if (SectionHandle != NULL)
|
||||
{
|
||||
DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
|
||||
IN NTSTATUS ExitStatus)
|
||||
{
|
||||
return(ZwTerminateProcess(ProcessHandle,ExitStatus));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
|
||||
IN NTSTATUS ExitStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN PCLIENT_ID ClientId)
|
||||
{
|
||||
return(ZwOpenProcess(ProcessHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
ClientId));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN PCLIENT_ID ClientId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength)
|
||||
{
|
||||
return(ZwQueryInformationProcess(ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
ProcessInformationLength,
|
||||
ReturnLength));
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL ZwQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
PROCESS_QUERY_INFORMATION,
|
||||
PsProcessType,
|
||||
UserMode,
|
||||
&ProcessHandle,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
switch (ProcessInformationClass)
|
||||
{
|
||||
case ProcessBasicInformation:
|
||||
case ProcessQuotaLimits:
|
||||
case ProcessIoCounters:
|
||||
case ProcessVmCounters:
|
||||
case ProcessTimes:
|
||||
case ProcessBasePriority:
|
||||
case ProcessRaisePriority:
|
||||
case ProcessDebugPort:
|
||||
case ProcessExceptionPort:
|
||||
case ProcessAccessToken:
|
||||
case ProcessLdtInformation:
|
||||
case ProcessLdtSize:
|
||||
case ProcessDefaultHardErrorMode:
|
||||
case ProcessIoPortHandlers:
|
||||
case ProcessWorkingSetWatch:
|
||||
case ProcessUserModeIOPL:
|
||||
case ProcessEnableAlignmentFaultFixup:
|
||||
case ProcessPriorityClass:
|
||||
case ProcessWx86Information:
|
||||
case ProcessHandleCount:
|
||||
case ProcessAffinityMask:
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
IN PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength
|
||||
)
|
||||
{
|
||||
return(ZwSetInformationProcess(ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
ProcessInformationLength));
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ZwSetInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN CINT ProcessInformationClass,
|
||||
IN PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,48 +1,61 @@
|
|||
bits 32
|
||||
section .text
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedIncrement
|
||||
mov eax,1
|
||||
mov ebx,[esp+4]
|
||||
xadd [ebx],eax
|
||||
ret
|
||||
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedDecrement
|
||||
mov eax,0xffffffff
|
||||
mov ebx,[esp+4]
|
||||
xadd [ebx],eax
|
||||
dec eax
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedExchange
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
|
||||
mov eax,[ebp+12]
|
||||
mov ebx,[ebp+8]
|
||||
xchg [ebx],eax
|
||||
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd
|
||||
mov eax,[esp+8]
|
||||
mov ebx,[esp+4]
|
||||
xadd [ebx],eax
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange
|
||||
mov eax,[esp+12]
|
||||
mov edx,[esp+8]
|
||||
mov ebx,[esp+4]
|
||||
cmpxchg [ebx],edx
|
||||
mov eax,edx
|
||||
ret
|
||||
bits 32
|
||||
section .text
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedIncrement
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
|
||||
mov eax,1
|
||||
mov ebx,[ebp+8]
|
||||
xadd [ebx],eax
|
||||
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedDecrement
|
||||
mov eax,0xffffffff
|
||||
mov ebx,[esp+4]
|
||||
xadd [ebx],eax
|
||||
dec eax
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedExchange
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
|
||||
push eax
|
||||
push ebx
|
||||
|
||||
mov eax,[ebp+12]
|
||||
mov ebx,[ebp+8]
|
||||
xchg [ebx],eax
|
||||
|
||||
pop ebx
|
||||
pop eax
|
||||
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd
|
||||
mov eax,[esp+8]
|
||||
mov ebx,[esp+4]
|
||||
xadd [ebx],eax
|
||||
ret
|
||||
|
||||
DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange
|
||||
mov eax,[esp+12]
|
||||
mov edx,[esp+8]
|
||||
mov ebx,[esp+4]
|
||||
cmpxchg [ebx],edx
|
||||
mov eax,edx
|
||||
ret
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -129,7 +129,7 @@ VOID ExExecuteShell(VOID)
|
|||
|
||||
BaseAddress = (PVOID)0x10000;
|
||||
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
|
||||
Size = 0x10000;
|
||||
Size = 0x20000;
|
||||
ZwMapViewOfSection(SectionHandle,
|
||||
ShellHandle,
|
||||
&BaseAddress,
|
||||
|
|
Loading…
Reference in a new issue