--- /dev/null
+#include <ddk/ntddk.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+\r
+\r
+void main()\r
+{ \r
+ NtDisplayString("Shell Starting...\n");\r
+ ExitThread(0);\r
+}\r
-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
+++ /dev/null
-BITS 32
-
-EXTERN _NtDisplayString
-
-_main:
- push dword _string
- call _NtDisplayString
-l1:
- jmp l1
-
-_string db 'Hello world from user mode!',0xa,0
-
-#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);
- }
-}
+\r
+#include <internal/mmhal.h>\r
+\r
+#include <ddk/ntddk.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+\r
+void debug_printf(char* fmt, ...)\r
+{\r
+ va_list args;\r
+ char buffer[255];\r
+ \r
+ va_start(args,fmt);\r
+ vsprintf(buffer,fmt,args);\r
+ OutputDebugStringA(buffer);\r
+ va_end(args);\r
+}\r
+\r
+HANDLE KeyboardHandle;\r
+\r
+void ExecuteCd(char* cmdline)\r
+{\r
+ UCHAR Buffer[255];\r
+ \r
+ debug_printf("ExecuteCd(cmdline %s)\n",cmdline);\r
+ \r
+ if (cmdline[0] != '\\' &&\r
+ cmdline[1] != ':')\r
+ {\r
+ GetCurrentDirectoryA(255,Buffer);\r
+ }\r
+ else\r
+ {\r
+ Buffer[0] = 0;\r
+ }\r
+ debug_printf("Buffer %s\n",Buffer);\r
+ \r
+ lstrcatA(Buffer,cmdline);\r
+ \r
+ debug_printf("Buffer %s\n",Buffer);\r
+ \r
+ if (Buffer[lstrlenA(Buffer)-1] != '\\')\r
+ {\r
+ lstrcatA(Buffer,"\\");\r
+ }\r
+ debug_printf("Buffer %s\n",Buffer);\r
+ \r
+ SetCurrentDirectoryA(Buffer);\r
+}\r
+\r
+void ExecuteDir(char* cmdline)\r
+{\r
+ HANDLE shandle;\r
+ WIN32_FIND_DATA FindData;\r
+\r
+ shandle = FindFirstFile("*.*",&FindData);\r
+\r
+ if (shandle==INVALID_HANDLE_VALUE)\r
+ {\r
+ return;\r
+ }\r
+ do\r
+ {\r
+ debug_printf("Scanning %s\n",FindData.cFileName);\r
+ } while(FindNextFile(shandle,&FindData));\r
+}\r
+\r
+void ExecuteType(char* cmdline)\r
+{\r
+ HANDLE FileHandle;\r
+ char c;\r
+ DWORD Result;\r
+ \r
+ FileHandle = CreateFile(cmdline,\r
+ FILE_GENERIC_READ,\r
+ 0,\r
+ NULL,\r
+ OPEN_EXISTING,\r
+ 0,\r
+ NULL);\r
+ while (ReadFile(FileHandle,\r
+ &c,\r
+ 1,\r
+ &Result,\r
+ NULL))\r
+ {\r
+ debug_printf("%c",c);\r
+ c = 0;\r
+ }\r
+}\r
+\r
+int ExecuteProcess(char* name, char* cmdline)\r
+{\r
+ PROCESS_INFORMATION ProcessInformation;\r
+ STARTUPINFO StartupInfo;\r
+ char arguments;\r
+ \r
+ memset(&StartupInfo,0,sizeof(StartupInfo));\r
+ StartupInfo.cb = sizeof(STARTUPINFO);\r
+ StartupInfo.lpTitle = name;\r
+ \r
+ return(CreateProcessA(name,\r
+ cmdline,\r
+ NULL,\r
+ NULL,\r
+ TRUE,\r
+ CREATE_NEW_CONSOLE,\r
+ NULL,\r
+ NULL,\r
+ &StartupInfo,\r
+ &ProcessInformation));\r
+}\r
+\r
+void ExecuteCommand(char* line)\r
+{\r
+ char* cmd;\r
+ char* tail;\r
+ \r
+ if (line[1] == ':' && line[2] == 0)\r
+ {\r
+ line[2] = '\\';\r
+ line[3] = 0;\r
+ SetCurrentDirectoryA(line);\r
+ return;\r
+ }\r
+ \r
+ tail = line;\r
+ while ((*tail)!=' ' && (*tail)!=0)\r
+ {\r
+ tail++; \r
+ }\r
+ if ((*tail)==' ')\r
+ {\r
+ *tail = 0;\r
+ tail++;\r
+ }\r
+ cmd = line;\r
+ \r
+ debug_printf("cmd '%s' tail '%s'\n",cmd,tail);\r
+ \r
+ if (cmd==NULL)\r
+ {\r
+ return;\r
+ }\r
+ if (strcmp(cmd,"cd")==0)\r
+ {\r
+ ExecuteCd(tail);\r
+ return;\r
+ }\r
+ if (strcmp(cmd,"dir")==0)\r
+ {\r
+ ExecuteDir(tail);\r
+ return;\r
+ }\r
+ if (strcmp(cmd,"type")==0)\r
+ {\r
+ ExecuteType(tail); \r
+ return;\r
+ }\r
+ if (ExecuteProcess(cmd,tail))\r
+ {\r
+ debug_printf("Done ExecuteProcess\n");\r
+ return;\r
+ }\r
+ debug_printf("Unknown command\n");\r
+}\r
+\r
+void ReadLine(char* line)\r
+{\r
+ KEY_EVENT_RECORD KeyEvent;\r
+ DWORD Result;\r
+ UCHAR CurrentDir[255];\r
+ \r
+ GetCurrentDirectoryA(255,CurrentDir);\r
+ debug_printf(CurrentDir);\r
+ \r
+ do\r
+ {\r
+ ReadFile(KeyboardHandle,\r
+ &KeyEvent,\r
+ sizeof(KEY_EVENT_RECORD),\r
+ &Result,\r
+ NULL);\r
+ if (KeyEvent.bKeyDown && KeyEvent.AsciiChar != 0)\r
+ {\r
+ debug_printf("%c",KeyEvent.AsciiChar);\r
+ *line = KeyEvent.AsciiChar;\r
+ line++;\r
+ }\r
+ } while (!(KeyEvent.bKeyDown && KeyEvent.AsciiChar == '\n'));\r
+ line--;\r
+ *line = 0;\r
+}\r
+\r
+void main()\r
+{\r
+ static char line[255];\r
+ \r
+ KERNEL32_Init();\r
+ \r
+ NtDisplayString("Shell Starting...\n");\r
+ \r
+ KeyboardHandle = CreateFile("Keyboard",\r
+ FILE_GENERIC_READ,\r
+ 0,\r
+ NULL,\r
+ OPEN_EXISTING,\r
+ 0,\r
+ NULL);\r
+ \r
+ SetCurrentDirectoryA("C:\\");\r
+ \r
+ for(;;)\r
+ {\r
+ ReadLine(line);\r
+ ExecuteCommand(line);\r
+ }\r
+}\r
IN CINT IrqLevel
);
-NTSTATUS
-STDCALL
-ZwContinue(
- IN PCONTEXT Context,
- IN CINT IrqLevel
- );
+NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel);
/*
+/*
+ * 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));
}
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS system libraries\r
+ * FILE: lib/kernel32/file/find.c\r
+ * PURPOSE: Find functions\r
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
+ * UPDATE HISTORY:\r
+ * Created 01/11/98\r
+ */\r
+#include <windows.h>\r
+#include <wstring.h>\r
+#include <ddk/ntddk.h>\r
+\r
+typedef enum _FINDEX_INFO_LEVELS \r
+{ \r
+ FindExSearchNameMatch, \r
+ FindExSearchLimitToDirectories, \r
+ FindExSearchLimitToDevices, \r
+\r
+} FINDEX_INFO_LEVELS ; \r
+\r
+typedef enum _FINDEX_SEARCH_OPS \r
+{ \r
+ FindExInfoStandard \r
+\r
+} FINDEX_SEARCH_OPS; \r
+\r
+int wcharicmp ( WCHAR char1, WCHAR char2 );\r
+\r
+WINBOOL\r
+mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);\r
+\r
+HANDLE\r
+STDCALL\r
+FindFirstFileW(\r
+ LPCWSTR lpFileName,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ );\r
+\r
+WINBOOL\r
+STDCALL\r
+FindNextFileW(\r
+ HANDLE hFind,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ );\r
+\r
+HANDLE \r
+STDCALL\r
+FindFirstFileExA( \r
+ LPCSTR lpFileName, \r
+ FINDEX_INFO_LEVELS fInfoLevelId, \r
+ LPVOID lpFindFileData, \r
+ FINDEX_SEARCH_OPS fSearchOp, \r
+ LPVOID lpSearchFilter, \r
+ DWORD dwAdditionalFlags \r
+ ); \r
+ \r
+HANDLE \r
+STDCALL \r
+FindFirstFileExW( \r
+ LPCWSTR lpFileName, \r
+ FINDEX_INFO_LEVELS fInfoLevelId, \r
+ LPVOID lpFindFileData, \r
+ FINDEX_SEARCH_OPS fSearchOp, \r
+ LPVOID lpSearchFilter, \r
+ DWORD dwAdditionalFlags \r
+ );\r
+\r
+typedef struct _FIND_FILE_INFO\r
+{\r
+ ULONG Offset;\r
+ PVOID SearchFilter;\r
+ WCHAR FileName[MAX_PATH];\r
+ WCHAR PathName[MAX_PATH];\r
+ FILE_DIRECTORY_INFORMATION *FileDirectory;\r
+} FIND_FILE_INFO;\r
+\r
+typedef struct _WIN32_FIND_DATAW { \r
+ DWORD dwFileAttributes; \r
+ FILETIME ftCreationTime; \r
+ FILETIME ftLastAccessTime; \r
+ FILETIME ftLastWriteTime; \r
+ DWORD nFileSizeHigh; \r
+ DWORD nFileSizeLow; \r
+ DWORD dwReserved0; \r
+ DWORD dwReserved1; \r
+ WCHAR cFileName[ MAX_PATH ]; \r
+ WCHAR cAlternateFileName[ 14 ]; \r
+} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW; \r
+\r
+\r
+WINBOOL\r
+STDCALL\r
+FindClose(\r
+ HANDLE hFind\r
+ )\r
+{\r
+ \r
+ if ( hFind == NULL)\r
+ return FALSE;\r
+\r
+ \r
+ HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);\r
+ HeapFree(GetProcessHeap(),0,hFind);\r
+ return TRUE;\r
+}\r
+\r
+\r
+HANDLE\r
+STDCALL\r
+FindFirstFileA(\r
+ LPCSTR lpFileName,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ )\r
+{\r
+ WIN32_FIND_DATA FindFileDataW;\r
+ WCHAR FileNameW[MAX_PATH];\r
+ ULONG i;\r
+\r
+ i = 0;\r
+ while ((*lpFileName)!=0 && i < MAX_PATH)\r
+ {\r
+ FileNameW[i] = *lpFileName;\r
+ lpFileName++;\r
+ i++;\r
+ }\r
+ FileNameW[i] = 0;\r
+ FindFirstFileW(FileNameW,&FindFileDataW);\r
+\r
+ // converteer FindFileDataW \r
+\r
+}\r
+\r
+HANDLE\r
+STDCALL\r
+FindFirstFileW(\r
+ LPCWSTR lpFileName,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ )\r
+{\r
+ return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);\r
+}\r
+\r
+WINBOOL\r
+STDCALL\r
+FindNextFileA(\r
+ HANDLE hFind,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ )\r
+{\r
+ WIN32_FIND_DATA FindFileDataW;\r
+ FindNextFileW(hFind,&FindFileDataW);\r
+ // converteer FindFileDataW \r
+}\r
+\r
+WINBOOL\r
+STDCALL\r
+FindNextFileW(\r
+ HANDLE hFind,\r
+ LPWIN32_FIND_DATA lpFindFileData\r
+ )\r
+{\r
+ int i;\r
+ WCHAR *pNameRead;\r
+ WCHAR FileName[MAX_PATH];\r
+\r
+ FIND_FILE_INFO *FindPtr = hFind;\r
+ FILE_DIRECTORY_INFORMATION *FileDirectory;\r
+ \r
+ if ( FindPtr == NULL )\r
+ return FALSE;\r
+ \r
+ /* Try to find a file */\r
+ FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;\r
+ while ( FileDirectory->NextEntryOffset != 0 ) {\r
+ \r
+ pNameRead = FileDirectory->FileName;\r
+ FindPtr->Offset += FileDirectory->NextEntryOffset;\r
+ for(i=0;i<FileDirectory->FileNameLength;i++)\r
+ dprintf("%c\n",(char)pNameRead[i]);\r
+ if (mfs_regexp(pNameRead, FindPtr->FileName))\r
+ { \r
+ /* We found one! */\r
+ if (FindPtr->PathName[0] != L'\0')\r
+ {\r
+ lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);\r
+ lstrcatW(lpFindFileData->cFileName, L"/");\r
+ lstrcatW(lpFindFileData->cFileName, pNameRead);\r
+ }\r
+ else\r
+ \r
+ lstrcpyW(lpFindFileData->cFileName, pNameRead);\r
+\r
+ \r
+ \r
+ lstrcpyW(lpFindFileData->cAlternateFileName, L"");\r
+ lpFindFileData->dwReserved0 = 0;\r
+ lpFindFileData->dwReserved1 = 0;\r
+ return TRUE;\r
+ }\r
+ FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+\r
+HANDLE \r
+STDCALL\r
+FindFirstFileExA( \r
+ LPCSTR lpFileName, \r
+ FINDEX_INFO_LEVELS fInfoLevelId, \r
+ LPVOID lpFindFileData, \r
+ FINDEX_SEARCH_OPS fSearchOp, \r
+ LPVOID lpSearchFilter, \r
+ DWORD dwAdditionalFlags \r
+ )\r
+{\r
+ WCHAR FileNameW[MAX_PATH];\r
+ WIN32_FIND_DATAW FindFileDataW;\r
+ FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);\r
+ // conerteer FindFileDataW \r
+\r
+}\r
+ \r
+HANDLE \r
+STDCALL \r
+FindFirstFileExW( \r
+ LPCWSTR lpFileName, \r
+ FINDEX_INFO_LEVELS fInfoLevelId, \r
+ LPVOID lpFindFileData, \r
+ FINDEX_SEARCH_OPS fSearchOp, \r
+ LPVOID lpSearchFilter, \r
+ DWORD dwAdditionalFlags \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ IO_STATUS_BLOCK IoStatusBlock; \r
+ HANDLE FileHandle = NULL;\r
+ FIND_FILE_INFO *hFind;\r
+ WCHAR *FilePart;\r
+ UNICODE_STRING FileNameString, PathNameString;\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+\r
+\r
+ ACCESS_MASK DesiredAccess=FILE_READ_DATA;\r
+ \r
+ ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;\r
+ ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;\r
+ ULONG CreateDisposition=FILE_OPEN;\r
+ ULONG CreateOptions=FILE_DIRECTORY_FILE;\r
+\r
+\r
+ hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));\r
+\r
+ hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);\r
+\r
+\r
+\r
+ /* Try to find a path and a filename in the passed filename */\r
+\r
+ lstrcpyW(hFind->PathName, lpFileName);\r
+ FilePart = wcsrchr(hFind->PathName, '\\');\r
+ \r
+ if (FilePart == NULL){\r
+ GetCurrentDirectory(MAX_PATH, hFind->PathName);\r
+ lstrcpyW(hFind->FileName, lpFileName);\r
+ }\r
+ else {\r
+ FilePart[0] = L'\0';\r
+ lstrcpyW(hFind->FileName, &FilePart[1]);\r
+ }\r
+\r
+ hFind->Offset = 0;\r
+ \r
+\r
+ PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);\r
+ PathNameString.Buffer = hFind->PathName;\r
+ PathNameString.MaximumLength = FileNameString.Length;\r
+ \r
+\r
+ FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);\r
+ FileNameString.Buffer = hFind->FileName;\r
+ FileNameString.MaximumLength = FileNameString.Length;\r
+\r
+\r
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);\r
+ ObjectAttributes.RootDirectory = NULL;\r
+ ObjectAttributes.ObjectName = &PathNameString;\r
+ ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;\r
+ ObjectAttributes.SecurityDescriptor = NULL;\r
+ ObjectAttributes.SecurityQualityOfService = NULL;\r
+\r
+ \r
+\r
+\r
+ \r
+\r
+ errCode = NtCreateFile(\r
+ &FileHandle,\r
+ DesiredAccess,\r
+ &ObjectAttributes,\r
+ &IoStatusBlock,\r
+ NULL, // AllocationSize\r
+ FileAttributes,\r
+ ShareAccess,\r
+ CreateDisposition,\r
+ CreateOptions,\r
+ NULL, // EaBuffer\r
+ 0); //\r
+\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ printf("%x\n",errCode);\r
+ return NULL;\r
+ }\r
+\r
+ errCode = NtQueryDirectoryFile(\r
+ FileHandle,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ &IoStatusBlock,\r
+ hFind->FileDirectory,\r
+ 8192,\r
+ FileDirectoryInformation,\r
+ FALSE,\r
+ &FileNameString,\r
+ FALSE\r
+ );\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ printf("%x\n",errCode);\r
+ return NULL;\r
+ }\r
+\r
+\r
+\r
+\r
+ if ( FindNextFileW(hFind,lpFindFileData) )\r
+ return hFind;\r
+ else {\r
+ FindClose(hFind);\r
+ return NULL;\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/************************************************************************/\r
+WINBOOL\r
+mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)\r
+{\r
+ /* The following code is provided by Tarang and I trust him...\r
+ */\r
+ LPWSTR lpTempFileName = (LPWSTR)lpFileName;\r
+ LPWSTR lpTempFilter = (LPWSTR)lpFilter;\r
+ WCHAR TempToken [ 2 ];\r
+ WCHAR TempFilter [ 2 ];\r
+ WINBOOL Matched = FALSE;\r
+\r
+ if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||\r
+ ( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )\r
+ return 0L;\r
+\r
+ if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )\r
+ {\r
+ wsprintf ( TempFilter, "*" );\r
+ lpTempFilter = TempFilter;\r
+ lpFilter = TempFilter;\r
+ }\r
+\r
+ while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )\r
+ {\r
+ memset ( TempToken, 0, sizeof ( TempToken ) );\r
+ switch ( *lpTempFilter )\r
+ {\r
+ default:\r
+ if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )\r
+ {\r
+ lpTempFileName = (LPWSTR)lpFileName;\r
+ lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );\r
+ if ( lpTempFilter )\r
+ lpTempFilter+=sizeof(WCHAR);\r
+ }\r
+ else\r
+ {\r
+ lpTempFilter+=sizeof(WCHAR);\r
+ lpTempFileName+=sizeof(WCHAR);\r
+ switch ( *lpTempFilter )\r
+ {\r
+ default:\r
+ break;\r
+\r
+ case L'\0':\r
+ case L' ':\r
+ case L',':\r
+ case L';':\r
+ if ( ! *lpTempFileName )\r
+ Matched = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case L'?':\r
+ lpTempFilter+=sizeof(WCHAR);\r
+ lpTempFileName+=sizeof(WCHAR);\r
+ break;\r
+\r
+ case L'*':\r
+ lpTempFilter += sizeof(WCHAR);\r
+ if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )\r
+ Matched = TRUE;\r
+ else\r
+ {\r
+ lpTempFilter+=sizeof(WCHAR);\r
+ while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&\r
+ ( ! Matched ) ) {\r
+ lpTempFileName+= sizeof(WCHAR);\r
+ Matched = mfs_regexp ( lpTempFileName, lpTempFilter );\r
+ }\r
+ if ( ( ! lpTempFileName ) && ( ! Matched ) )\r
+ {\r
+ lpTempFileName = (LPWSTR)lpFileName;\r
+ lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );\r
+ if ( lpTempFilter )\r
+ lpTempFilter+=sizeof(WCHAR);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case L'\0':\r
+ case L' ':\r
+ case L',':\r
+ case L';':\r
+ Matched = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ return (DWORD)Matched;\r
+\r
+\r
+}\r
+\r
+int wcharicmp ( WCHAR char1, WCHAR char2 )\r
+{\r
+ WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ? \r
+ char1 - L'a' + L'A' : char1;\r
+ WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ? \r
+ char2 - L'a' + L'A' : char2;\r
+ return ( Char2 - Char1 );\r
+}\r
-/*
- * 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 );
-}
-
-
-
-
-
-
-
-
-
-
-
-
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS system libraries\r
+ * FILE: lib/kernel32/file/find.c\r
+ * PURPOSE: Find functions\r
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
+ * UPDATE HISTORY:\r
+ * Created 01/11/98\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <windows.h>\r
+#include <wstring.h>\r
+#include <ddk/ntddk.h>\r
+\r
+/* TYPES ********************************************************************/\r
+\r
+typedef struct _KERNEL32_FIND_FILE_DATA\r
+{\r
+ HANDLE DirectoryHandle;\r
+ FILE_DIRECTORY_INFORMATION FileInfo;\r
+} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ WCHAR lpFileNameW[MAX_PATH];\r
+ ULONG i;\r
+ \r
+ i = 0;\r
+ while (lpFileName[i]!=0)\r
+ {\r
+ lpFileNameW[i] = lpFileName[i];\r
+ i++;\r
+ }\r
+ \r
+ return(FindFirstFileW(lpFileNameW,lpFindFileData));\r
+}\r
+\r
+WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ return(FindNextFileW(hFindFile, lpFindFileData));\r
+}\r
+\r
+BOOL FindClose(HANDLE hFindFile)\r
+{\r
+ PKERNEL32_FIND_FILE_DATA IData;\r
+ \r
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;\r
+ NtClose(IData->DirectoryHandle);\r
+ HeapFree(GetProcessHeap(), 0, IData);\r
+ return(TRUE);\r
+}\r
+\r
+HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName, \r
+ LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ WCHAR CurrentDirectory[MAX_PATH];\r
+ WCHAR Pattern[MAX_PATH];\r
+ WCHAR Directory[MAX_PATH];\r
+ PWSTR End;\r
+ PKERNEL32_FIND_FILE_DATA IData;\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+ UNICODE_STRING DirectoryNameStr;\r
+ IO_STATUS_BLOCK IoStatusBlock;\r
+ UNICODE_STRING PatternStr;\r
+ \r
+ dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",\r
+ lpFileName, lpFindFileData);\r
+ \r
+ GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);\r
+ Directory[0] = '\\';\r
+ Directory[1] = '?';\r
+ Directory[2] = '?';\r
+ Directory[3] = '\\';\r
+ Directory[4] = 0;\r
+ wcscat(Directory, CurrentDirectory);\r
+ wcscat(Directory, lpFileName);\r
+ End = wcschr(Directory, '\\');\r
+ *End = 0;\r
+ \r
+ wcscpy(Pattern, End+1);\r
+ \r
+ dprintf("Directory %w End %w\n",Directory,End);\r
+ \r
+ IData = HeapAlloc(GetProcessHeap(), \r
+ HEAP_ZERO_MEMORY, \r
+ sizeof(KERNEL32_FIND_FILE_DATA));\r
+ \r
+ RtlInitUnicodeString(&DirectoryNameStr, Directory);\r
+ InitializeObjectAttributes(&ObjectAttributes,\r
+ &DirectoryNameStr,\r
+ 0,\r
+ NULL,\r
+ NULL);\r
+ \r
+ if (ZwOpenFile(&IData->DirectoryHandle,\r
+ FILE_TRAVERSE, \r
+ &ObjectAttributes,\r
+ &IoStatusBlock,\r
+ 0,\r
+ OPEN_EXISTING)!=STATUS_SUCCESS)\r
+ {\r
+ return(NULL);\r
+ }\r
+ \r
+ RtlInitUnicodeString(&PatternStr, Pattern);\r
+ \r
+ NtQueryDirectoryFile(IData->DirectoryHandle,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ &IoStatusBlock,\r
+ (PVOID)&IData->FileInfo,\r
+ sizeof(IData->FileInfo),\r
+ FileDirectoryInformation,\r
+ TRUE,\r
+ &PatternStr,\r
+ FALSE);\r
+ \r
+ return(IData);\r
+}\r
+\r
+WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,\r
+ LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+}\r
--- /dev/null
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS system libraries\r
+ * FILE: lib/kernel32/file/find.c\r
+ * PURPOSE: Find functions\r
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
+ * UPDATE HISTORY:\r
+ * Created 01/11/98\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <windows.h>\r
+#include <wstring.h>\r
+#include <ddk/ntddk.h>\r
+\r
+/* TYPES ********************************************************************/\r
+\r
+typedef struct _KERNEL32_FIND_FILE_DATA;\r
+{\r
+ HANDLE DirectoryHandle;\r
+ FILE_DIRECTORY_INFORMATION FileInfo;\r
+} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ WCHAR lpFileNameW[MAX_PATH];\r
+ ULONG i;\r
+ \r
+ i = 0;\r
+ while (lpFileName[i]!=0)\r
+ {\r
+ lpFileName[i] = lpFileName[i];\r
+ i++;\r
+ }\r
+ \r
+ return(FindFirstFileW(lpFileName,lpFindFileData));\r
+}\r
+\r
+BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ return(FindNextFileW(hFindFile, lpFindFileData));\r
+}\r
+\r
+BOOL FindClose(HANDLE hFindFile)\r
+{\r
+ PKERNEL32_FIND_FILE_DATA IData;\r
+ \r
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;\r
+ NtClose(IData->DirectoryHandle);\r
+ HeapFree(IData);\r
+}\r
+\r
+HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName, \r
+ LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+ WCHAR CurrentDirectory[MAX_PATH];\r
+ WCHAR Pattern[MAX_PATH];\r
+ WCHAR Directory[MAX_PATH];\r
+ PWSTR End;\r
+ PKERNEL32_FIND_FILE_DATA IData;\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+ UNICODE_STRING DirectoryNameStr;\r
+ IO_STATUS_BLOCK IoStatusBlock;\r
+ \r
+ dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",\r
+ lpFileName, lpFindFileData);\r
+ \r
+ GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);\r
+ Directory[0] = '\\';\r
+ Directory[1] = '?';\r
+ Directory[2] = '?';\r
+ Directory[3] = '\\';\r
+ Directory[4] = 0;\r
+ wstrcat(Directory, CurrentDirectory);\r
+ wstrcat(Directory, lpFileName);\r
+ End = wstrchr(Directory, '\\');\r
+ *End = 0;\r
+ \r
+ wstrcpy(Pattern, End+1);\r
+ \r
+ dprintf("Directory %w End %w\n",Directory,End);\r
+ \r
+ IData = HeapAlloc(GetProcessHeap(), \r
+ HEAP_ZERO_MEMORY, \r
+ sizeof(KERNEL32_FIND_FILE_DATA));\r
+ \r
+ RtlInitUnicodeString(&DirectoryNameStr, Directory);\r
+ InitializeObjectAttributes(&ObjectAttributes,\r
+ &DirectoryNameStr,\r
+ 0,\r
+ NULL,\r
+ NULL);\r
+ \r
+ if (ZwOpenFile(&IData->DirectoryHandle,\r
+ FILE_TRAVERSE,\r
+ &ObjectAttributes,\r
+ 0,\r
+ OPEN_EXISTING)!=STATUS_SUCCESS)\r
+ {\r
+ return(NULL);\r
+ }\r
+ \r
+ NtQueryDirectoryFile(IData->DirectoryHandle,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ &IoStatusBlock,\r
+ &IData->FileInfo,\r
+ sizeof(IData->FileInfo),\r
+ FileDirectoryInformation,\r
+ TRUE,\r
+ Pattern,\r
+ FALSE);\r
+ \r
+ return(IData);\r
+}\r
+\r
+WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,\r
+ LPWIN32_FIND_DATA lpFindFileData)\r
+{\r
+}\r
--- /dev/null
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <stdarg.h>
+
+VOID KERNEL32_Init(VOID)
+{
+ __HeapInit(0, 4*1024*1024, 4*1024*1024);
+}
+++ /dev/null
-/*
- * 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;
-}
-
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
kernel32.a: $(OBJECTS)
- $(AR) vrcs kernel32.a $(OBJECTS)
+ $(AR) rcs kernel32.a $(OBJECTS)
dummy:
{ 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);
static PHEAP __HeapPrepare(LPVOID base, ULONG minsize, ULONG maxsize,
ULONG flags);
-
-
/*********************************************************************
* __HeapCommit *
* *
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);
--- /dev/null
+/*
+ * 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;
+}
+
* UPDATE HISTORY:
* Created 01/11/98
*/
+
+/* INCLUDES ****************************************************************/
+
#define UNICODE
#include <windows.h>
#include <kernel32/proc.h>
#include <ddk/rtl.h>
#include <ddk/li.h>
+/* GLOBALS *****************************************************************/
+
extern NT_PEB *CurrentPeb;
extern NT_PEB Peb;
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
-WINBOOL
-STDCALL
-GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
+/* FUNCTIONS ****************************************************************/
+WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
NT_PEB *GetCurrentPeb(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
- )
-{
- 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
- )
+WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
{
- return GetCurrentPeb()->StartupInfo->CommandLine;
+ 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
-GetExitCodeProcess(
- HANDLE hProcess,
- LPDWORD lpExitCode
- )
+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( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
- return TRUE;
-
+ 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
-GetProcessId(
- HANDLE hProcess,
- LPDWORD lpProcessId
- )
+PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
{
- 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;
-
+ 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
- )
+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];
-
-
- 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);
-
-
+ 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);
}
-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
- )
+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);
+ 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;
- ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
- ApplicationNameString.MaximumLength = ApplicationNameString.Length;
-
-
- 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);
+ 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);
+
+ 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);
+
+ /*
+ * 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);
- return TRUE;
-
-
- }
+ 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
- )
+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;
+ 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;
}
-/*
- * 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);
-}
-
-/*************************************************************/
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS system libraries\r
+ * FILE: lib/kernel32/thread/thread.c\r
+ * PURPOSE: Thread functions\r
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
+ Tls functions are modified from WINE\r
+ * UPDATE HISTORY:\r
+ * Created 01/11/98\r
+ */\r
+\r
+#include <windows.h>\r
+#include <kernel32/thread.h>\r
+#include <ddk/ntddk.h>\r
+#include <string.h>\r
+#include <internal/i386/segment.h>\r
+\r
+HANDLE\r
+STDCALL\r
+CreateThread(\r
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,\r
+ DWORD dwStackSize,\r
+ LPTHREAD_START_ROUTINE lpStartAddress,\r
+ LPVOID lpParameter,\r
+ DWORD dwCreationFlags,\r
+ LPDWORD lpThreadId\r
+ )\r
+{\r
+ return CreateRemoteThread(NtCurrentProcess(),lpThreadAttributes,dwStackSize,\r
+ lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);\r
+}\r
+\r
+\r
+\r
+\r
+HANDLE\r
+STDCALL\r
+CreateRemoteThread(\r
+ HANDLE hProcess,\r
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,\r
+ DWORD dwStackSize,\r
+ LPTHREAD_START_ROUTINE lpStartAddress,\r
+ LPVOID lpParameter,\r
+ DWORD dwCreationFlags,\r
+ LPDWORD lpThreadId\r
+ )\r
+{ \r
+ NTSTATUS errCode;\r
+ HANDLE ThreadHandle;\r
+ OBJECT_ATTRIBUTES ObjectAttributes;\r
+ CLIENT_ID ClientId;\r
+ CONTEXT ThreadContext;\r
+ INITIAL_TEB InitialTeb;\r
+ BOOLEAN CreateSuspended = FALSE;\r
+ ULONG BaseAddress;\r
+ \r
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);\r
+ ObjectAttributes.RootDirectory = NULL;\r
+ ObjectAttributes.ObjectName = NULL;\r
+ ObjectAttributes.Attributes = 0;\r
+ if ( lpThreadAttributes != NULL ) {\r
+ if ( lpThreadAttributes->bInheritHandle ) \r
+ ObjectAttributes.Attributes = OBJ_INHERIT;\r
+ ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;\r
+ }\r
+ ObjectAttributes.SecurityQualityOfService = NULL;\r
+ \r
+ if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )\r
+ CreateSuspended = TRUE;\r
+ else\r
+ CreateSuspended = FALSE;\r
+\r
+ BaseAddress = 0;\r
+ ZwAllocateVirtualMemory(hProcess,\r
+ &BaseAddress,\r
+ 0,\r
+ &dwStackSize,\r
+ MEM_COMMIT,\r
+ PAGE_READWRITE);\r
+ \r
+\r
+ memset(&ThreadContext,0,sizeof(CONTEXT));\r
+ ThreadContext.Eip = lpStartAddress;\r
+ ThreadContext.SegGs = USER_DS;\r
+ ThreadContext.SegFs = USER_DS;\r
+ ThreadContext.SegEs = USER_DS;\r
+ ThreadContext.SegDs = USER_DS;\r
+ ThreadContext.SegCs = USER_CS;\r
+ ThreadContext.SegSs = USER_DS; \r
+ ThreadContext.Esp = BaseAddress + dwStackSize;\r
+ ThreadContext.EFlags = (1<<1) + (1<<9);\r
+\r
+\r
+ errCode = NtCreateThread(&ThreadHandle,\r
+ THREAD_ALL_ACCESS,\r
+ &ObjectAttributes,\r
+ hProcess,\r
+ &ClientId,\r
+ &ThreadContext,\r
+ &InitialTeb,\r
+ CreateSuspended);\r
+ if ( lpThreadId != NULL )\r
+ memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));\r
+ \r
+ return ThreadHandle;\r
+}\r
+\r
+NT_TEB *GetTeb(VOID)\r
+{\r
+ return NULL;\r
+}\r
+\r
+WINBOOL STDCALL\r
+SwitchToThread(VOID )\r
+{\r
+ NTSTATUS errCode;\r
+ errCode = NtYieldExecution();\r
+ return TRUE;\r
+}\r
+\r
+DWORD\r
+STDCALL\r
+GetCurrentThreadId()\r
+{\r
+\r
+ return (DWORD)(GetTeb()->Cid).UniqueThread; \r
+}\r
+\r
+VOID\r
+STDCALL\r
+ExitThread(\r
+ UINT uExitCode\r
+ ) \r
+{\r
+ NTSTATUS errCode; \r
+\r
+ errCode = NtTerminateThread(\r
+ NtCurrentThread() ,\r
+ uExitCode\r
+ );\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ }\r
+ return;\r
+}\r
+\r
+WINBOOL\r
+STDCALL\r
+GetThreadTimes(\r
+ HANDLE hThread,\r
+ LPFILETIME lpCreationTime,\r
+ LPFILETIME lpExitTime,\r
+ LPFILETIME lpKernelTime,\r
+ LPFILETIME lpUserTime\r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ KERNEL_USER_TIMES KernelUserTimes;\r
+ ULONG ReturnLength;\r
+ errCode = NtQueryInformationThread(hThread,ThreadTimes,&KernelUserTimes,sizeof(KERNEL_USER_TIMES),&ReturnLength);\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ memcpy(lpCreationTime, &KernelUserTimes.CreateTime, sizeof(FILETIME));\r
+ memcpy(lpExitTime, &KernelUserTimes.ExitTime, sizeof(FILETIME));\r
+ memcpy(lpKernelTime, &KernelUserTimes.KernelTime, sizeof(FILETIME));\r
+ memcpy(lpUserTime, &KernelUserTimes.UserTime, sizeof(FILETIME));\r
+ return TRUE;\r
+ \r
+}\r
+\r
+\r
+WINBOOL\r
+STDCALL GetThreadContext(\r
+ HANDLE hThread, \r
+ LPCONTEXT lpContext \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ errCode = NtGetContextThread(hThread,lpContext);\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+WINBOOL\r
+STDCALL\r
+SetThreadContext(\r
+ HANDLE hThread, \r
+ CONST CONTEXT *lpContext \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+\r
+ errCode = NtSetContextThread(hThread,(void *)lpContext);\r
+ if (!NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+\r
+\r
+WINBOOL \r
+STDCALL\r
+GetExitCodeThread(\r
+ HANDLE hThread, \r
+ LPDWORD lpExitCode \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ THREAD_BASIC_INFORMATION ThreadBasic;\r
+ ULONG DataWritten;\r
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ memcpy( lpExitCode ,&ThreadBasic.ExitStatus,sizeof(DWORD));\r
+ return TRUE;\r
+ \r
+}\r
+\r
+\r
+DWORD \r
+STDCALL\r
+ResumeThread(\r
+ HANDLE hThread \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ ULONG PreviousResumeCount;\r
+\r
+ errCode = NtResumeThread(hThread,&PreviousResumeCount );\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return -1;\r
+ }\r
+ return PreviousResumeCount;\r
+}\r
+\r
+DWORD \r
+STDCALL\r
+SuspendThread(\r
+ HANDLE hThread \r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ ULONG PreviousSuspendCount;\r
+\r
+ errCode = NtSuspendThread(hThread,&PreviousSuspendCount );\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return -1;\r
+ }\r
+ return PreviousSuspendCount;\r
+}\r
+\r
+\r
+DWORD\r
+STDCALL\r
+SetThreadAffinityMask(\r
+ HANDLE hThread,\r
+ DWORD dwThreadAffinityMask\r
+ )\r
+{\r
+ return 0;\r
+}\r
+\r
+\r
+WINBOOL\r
+STDCALL\r
+SetThreadPriority(\r
+ HANDLE hThread,\r
+ int nPriority\r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ THREAD_BASIC_INFORMATION ThreadBasic;\r
+ ULONG DataWritten;\r
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ ThreadBasic.BasePriority = nPriority;\r
+ errCode = NtSetInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION));\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+\r
+int\r
+STDCALL\r
+GetThreadPriority(\r
+ HANDLE hThread\r
+ )\r
+{\r
+ NTSTATUS errCode;\r
+ THREAD_BASIC_INFORMATION ThreadBasic;\r
+ ULONG DataWritten;\r
+ errCode = NtQueryInformationThread(hThread,ThreadBasicInformation,&ThreadBasic,sizeof(THREAD_BASIC_INFORMATION),&DataWritten);\r
+ if ( !NT_SUCCESS(errCode) ) {\r
+ SetLastError(RtlNtStatusToDosError(errCode));\r
+ return THREAD_PRIORITY_ERROR_RETURN;\r
+ }\r
+ return ThreadBasic.BasePriority;\r
+}\r
+\r
+\r
+/* (WIN32) Thread Local Storage ******************************************** */\r
+\r
+DWORD STDCALL\r
+TlsAlloc(VOID)\r
+{\r
+ DWORD dwTlsIndex = GetTeb()->dwTlsIndex;\r
+ \r
+\r
+ void **TlsData = GetTeb()->TlsData;\r
+ \r
+ \r
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
+ {\r
+ TlsData[dwTlsIndex] = NULL;\r
+ return (dwTlsIndex++);\r
+ }\r
+ return (0xFFFFFFFFUL);\r
+}\r
+\r
+WINBOOL STDCALL\r
+TlsFree(DWORD dwTlsIndex)\r
+{\r
+ \r
+ return (TRUE);\r
+}\r
+\r
+LPVOID STDCALL\r
+TlsGetValue(DWORD dwTlsIndex)\r
+{\r
+ \r
+ \r
+ void **TlsData = GetTeb()->TlsData;\r
+\r
+ \r
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
+ {\r
+ \r
+ SetLastError(NO_ERROR);\r
+ return (TlsData[dwTlsIndex]);\r
+ }\r
+ SetLastError(1);\r
+ return (NULL);\r
+}\r
+\r
+WINBOOL STDCALL\r
+TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)\r
+{\r
+ \r
+ \r
+ void **TlsData = GetTeb()->TlsData;\r
+\r
+ \r
+ if (dwTlsIndex < sizeof(TlsData) / sizeof(TlsData[0]))\r
+ {\r
+ \r
+ TlsData[dwTlsIndex] = lpTlsValue;\r
+ return (TRUE);\r
+ }\r
+ return (FALSE);\r
+}\r
+\r
+/*************************************************************/\r
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)
s++;
str2++;
}
+ *s = 0;
return(str1);
}
#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)
STUB(RtlAllocateHandle)
STUB(RtlAllocateHeap)
STUB(RtlAnsiCharToUnicodeChar)
-STUB(RtlAnsiStringToUnicodeSize)
-STUB(RtlAnsiStringToUnicodeString)
STUB(RtlAppendAsciizToString)
STUB(RtlAppendStringToString)
-STUB(RtlAppendUnicodeStringToString)
-STUB(RtlAppendUnicodeToString)
STUB(RtlApplyRXact)
STUB(RtlApplyRXactNoFlush)
STUB(RtlAreAllAccessesGranted)
STUB(RtlAreBitsSet)
STUB(RtlAssert)
STUB(RtlCaptureStackBackTrace)
-STUB(RtlCharToInteger)
STUB(RtlCheckRegistryKey)
STUB(RtlClearAllBits)
STUB(RtlClearBits)
STUB(RtlCompactHeap)
STUB(RtlCompareMemory)
STUB(RtlCompareMemoryUlong)
-STUB(RtlCompareString)
-STUB(RtlCompareUnicodeString)
STUB(RtlCompressBuffer)
STUB(RtlConsoleMultiByteToUnicodeN)
STUB(RtlConvertExclusiveToShared)
STUB(RtlCopySecurityDescriptor)
STUB(RtlCopySid)
STUB(RtlCopySidAndAttributesArray)
-STUB(RtlCopyString)
-STUB(RtlCopyUnicodeString)
STUB(RtlCreateAcl)
STUB(RtlCreateAndSetSD)
STUB(RtlCreateAtomTable)
STUB(RtlEqualLuid)
STUB(RtlEqualPrefixSid)
STUB(RtlEqualSid)
-STUB(RtlEqualString)
-STUB(RtlEqualUnicodeString)
STUB(RtlEraseUnicodeString)
STUB(RtlExpandEnvironmentStrings_U)
STUB(RtlExtendHeap)
STUB(RtlFlushPropertySet)
STUB(RtlFormatCurrentUserKeyPath)
STUB(RtlFormatMessage)
-STUB(RtlFreeAnsiString)
STUB(RtlFreeHandle)
STUB(RtlFreeHeap)
STUB(RtlFreeOemString)
STUB(RtlFreeSid)
-STUB(RtlFreeUnicodeString)
STUB(RtlFreeUserThreadStack)
STUB(RtlGenerate8dot3Name)
STUB(RtlGetAce)
STUB(RtlImageRvaToSection)
STUB(RtlImageRvaToVa)
STUB(RtlImpersonateSelf)
-STUB(RtlInitAnsiString)
STUB(RtlInitCodePageTable)
STUB(RtlInitNlsTables)
-STUB(RtlInitString)
-STUB(RtlInitUnicodeString)
STUB(RtlInitializeAtomPackage)
STUB(RtlInitializeBitMap)
STUB(RtlInitializeContext)
STUB(RtlInitializeSid)
STUB(RtlInsertElementGenericTable)
STUB(RtlIntegerToChar)
-STUB(RtlIntegerToUnicodeString)
STUB(RtlIsDosDeviceName_U)
STUB(RtlIsGenericTableEmpty)
STUB(RtlIsNameLegalDOS8Dot3)
STUB(RtlTimeToTimeFields)
STUB(RtlTryEnterCriticalSection)
STUB(RtlUnicodeStringToAnsiSize)
-STUB(RtlUnicodeStringToAnsiString)
STUB(RtlUnicodeStringToCountedOemString)
-STUB(RtlUnicodeStringToInteger)
STUB(RtlUnicodeStringToOemSize)
STUB(RtlUnicodeStringToOemString)
STUB(RtlUnicodeToCustomCPN)
STUB(RtlUnlockHeap)
STUB(RtlUnwind)
STUB(RtlUpcaseUnicodeChar)
-STUB(RtlUpcaseUnicodeString)
STUB(RtlUpcaseUnicodeStringToAnsiString)
STUB(RtlUpcaseUnicodeStringToCountedOemString)
STUB(RtlUpcaseUnicodeStringToOemString)
STUB(RtlUpcaseUnicodeToMultiByteN)
STUB(RtlUpcaseUnicodeToOemN)
STUB(RtlUpperChar)
-STUB(RtlUpperString)
STUB(RtlUsageHeap)
STUB(RtlValidAcl)
STUB(RtlValidSecurityDescriptor)
# 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
sound: dummy
make -C services/dd/sound
-ext2fs: dummy
- make -C services/fs/ext2fs
+ext2: dummy
+ make -C services/fs/ext2
#
# Kernel loaders
;
pusha
push ds
+ push es
;
; Load DS
;
mov ax,KERNEL_DS
mov ds,ax
+ mov es,ax
;
; Mask the corresponding vector at the PIC
; Restore stack, registers and return to interrupted routine
;
pop eax
+ pop es
pop ds
popa
iret
* 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;
/*
-/*
- * 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;
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/hal/x86/thread.c\r
+ * PURPOSE: HAL multitasking functions\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * REVISION HISTORY:\r
+ * 27/06/98: Created\r
+ */\r
+\r
+/* INCLUDES ****************************************************************/\r
+\r
+#include <windows.h>\r
+#include <ddk/ntddk.h>\r
+#include <internal/ntoskrnl.h>\r
+#include <internal/ps.h>\r
+#include <internal/string.h>\r
+#include <internal/hal.h>\r
+#include <internal/i386/segment.h>\r
+#include <internal/mmhal.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS ***************************************************************/\r
+\r
+VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);\r
+VOID PsBeginThreadWithContextInternal(VOID);\r
+\r
+#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)\r
+#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)\r
+\r
+static char null_ldt[8]={0,};\r
+static unsigned int null_ldt_sel=0;\r
+static PETHREAD FirstThread=NULL;\r
+\r
+/* FUNCTIONS **************************************************************/\r
+\r
+void HalTaskSwitch(PKTHREAD thread)\r
+/*\r
+ * FUNCTION: Switch tasks\r
+ * ARGUMENTS:\r
+ * thread = Thread to switch to\r
+ * NOTE: This function will not return until the current thread is scheduled\r
+ * again\r
+ */\r
+{\r
+ DPRINT("Scheduling thread %x\n",thread);\r
+ DPRINT("Scheduling thread %x\n",thread->Context.nr);\r
+ DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",\r
+ thread->Context.previous_task,thread->Context.reserved1,\r
+ thread->Context.esp0,thread->Context.ss0);\r
+ DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",\r
+ thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,\r
+ thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);\r
+ DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",\r
+ thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,\r
+ thread->Context.eflags,thread->Context.eax);\r
+ DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",\r
+ thread->Context.ecx,thread->Context.edx,thread->Context.ebx,\r
+ thread->Context.esp,thread->Context.ebp,thread->Context.esi);\r
+ DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",\r
+ thread->Context.edi,thread->Context.es,thread->Context.reserved5,\r
+ thread->Context.cs,thread->Context.reserved6);\r
+ DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",\r
+ thread->Context.ss,thread->Context.reserved7,thread->Context.ds,\r
+ thread->Context.reserved8,thread->Context.fs);\r
+ DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",\r
+ thread->Context.reserved9,thread->Context.gs,\r
+ thread->Context.reserved10,thread->Context.ldt,\r
+ thread->Context.reserved11);\r
+ DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",\r
+ thread->Context.trap,thread->Context.iomap_base,\r
+ thread->Context.nr,thread->Context.io_bitmap[0]);\r
+ DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",\r
+ &(gdt[thread->Context.nr/8].a),\r
+ gdt[thread->Context.nr/8].a,\r
+ gdt[thread->Context.nr/8].b);\r
+ __asm__("pushfl\n\t"\r
+ "cli\n\t"\r
+ "ljmp %0\n\t"\r
+ "popfl\n\t"\r
+ : /* No outputs */\r
+ : "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )\r
+ : "ax","dx");\r
+}\r
+\r
+static unsigned int allocate_tss_descriptor(void)\r
+/*\r
+ * FUNCTION: Allocates a slot within the GDT to describe a TSS\r
+ * RETURNS: The offset within the GDT of the slot allocated on succcess\r
+ * Zero on failure\r
+ */\r
+{\r
+ unsigned int i;\r
+ for (i=0;i<16;i++)\r
+ {\r
+ if (gdt[FIRST_TSS_OFFSET + i].a==0 &&\r
+ gdt[FIRST_TSS_OFFSET + i].b==0)\r
+ {\r
+ return(FIRST_TSS_OFFSET + i);\r
+ }\r
+ }\r
+ return(0);\r
+}\r
+\r
+#define FLAG_NT (1<<14)\r
+#define FLAG_VM (1<<17)\r
+#define FLAG_IF (1<<9)\r
+#define FLAG_IOPL ((1<<12)+(1<<13))\r
+\r
+NTSTATUS KeValidateUserContext(PCONTEXT Context)\r
+/*\r
+ * FUNCTION: Validates a processor context\r
+ * ARGUMENTS:\r
+ * Context = Context to validate\r
+ * RETURNS: Status\r
+ * NOTE: This only validates the context as not violating system security, it\r
+ * doesn't guararantee the thread won't crash at some point\r
+ * NOTE2: This relies on there only being two selectors which can access \r
+ * system space\r
+ */\r
+{\r
+ if (Context->Eip >= KERNEL_BASE)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (Context->SegCs == KERNEL_CS)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (Context->SegDs == KERNEL_DS)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (Context->SegEs == KERNEL_DS)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (Context->SegFs == KERNEL_DS)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (Context->SegGs == KERNEL_DS)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if ((Context->EFlags & FLAG_IOPL) != 0 ||\r
+ (Context->EFlags & FLAG_NT) ||\r
+ (Context->EFlags & FLAG_VM) ||\r
+ (!(Context->EFlags & FLAG_IF)))\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)\r
+/*\r
+ * FUNCTION: Initialize a task with a user mode context\r
+ * ARGUMENTS:\r
+ * Thread = Thread to initialize\r
+ * Context = Processor context to initialize it with\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ unsigned int desc;\r
+ unsigned int length;\r
+ unsigned int base;\r
+ PVOID kernel_stack;\r
+ NTSTATUS Status;\r
+ PVOID stack_start;\r
+ \r
+ DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",\r
+ Thread,Context);\r
+\r
+ assert(sizeof(hal_thread_state)>=0x68);\r
+ \r
+ if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ desc = allocate_tss_descriptor();\r
+ length = sizeof(hal_thread_state) - 1;\r
+ base = (unsigned int)(&(Thread->Tcb.Context));\r
+ kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);\r
+ \r
+ /*\r
+ * Setup a TSS descriptor\r
+ */\r
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)\r
+ | (base & 0xff000000);\r
+ \r
+ stack_start = kernel_stack + 4096 - sizeof(CONTEXT);\r
+ memcpy(stack_start, Context, sizeof(CONTEXT));\r
+ \r
+ /*\r
+ * Initialize the thread context\r
+ */\r
+ memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));\r
+ Thread->Tcb.Context.ldt = null_ldt_sel;\r
+ Thread->Tcb.Context.eflags = (1<<1) + (1<<9);\r
+ Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);\r
+ Thread->Tcb.Context.esp0 = stack_start;\r
+ Thread->Tcb.Context.ss0 = KERNEL_DS;\r
+ Thread->Tcb.Context.esp = stack_start;\r
+ Thread->Tcb.Context.ss = KERNEL_DS;\r
+ Thread->Tcb.Context.cs = KERNEL_CS;\r
+ Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;\r
+ Thread->Tcb.Context.io_bitmap[0] = 0xff;\r
+ Thread->Tcb.Context.cr3 = \r
+ linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);\r
+ Thread->Tcb.Context.ds = KERNEL_DS;\r
+ Thread->Tcb.Context.es = KERNEL_DS;\r
+ Thread->Tcb.Context.fs = KERNEL_DS;\r
+ Thread->Tcb.Context.gs = KERNEL_DS;\r
+\r
+ Thread->Tcb.Context.nr = desc * 8;\r
+ DPRINT("Allocated %x\n",desc*8);\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)\r
+/*\r
+ * FUNCTION: Initializes the HAL portion of a thread object\r
+ * ARGUMENTS:\r
+ * thread = Object describes the thread\r
+ * fn = Entrypoint for the thread\r
+ * StartContext = parameter to pass to the thread entrypoint\r
+ * RETURNS: True if the function succeeded\r
+ */\r
+{\r
+ unsigned int desc = allocate_tss_descriptor();\r
+ unsigned int length = sizeof(hal_thread_state) - 1;\r
+ unsigned int base = (unsigned int)(&(thread->Tcb.Context));\r
+ unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);\r
+ \r
+ DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",\r
+ thread,fn,StartContext);\r
+ DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);\r
+ \r
+ /*\r
+ * Make sure\r
+ */\r
+ assert(sizeof(hal_thread_state)>=0x68);\r
+ \r
+ /*\r
+ * Setup a TSS descriptor\r
+ */\r
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)\r
+ | (base & 0xff000000);\r
+ \r
+// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));\r
+// DPRINT("desc %d\n",desc);\r
+ DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",\r
+ &(gdt[desc].a),\r
+ gdt[desc].a,\r
+ gdt[desc].b);\r
+ \r
+ /*\r
+ * Initialize the stack for the thread (including the two arguments to \r
+ * the general start routine). \r
+ */\r
+ kernel_stack[1023] = (unsigned int)StartContext;\r
+ kernel_stack[1022] = (unsigned int)fn;\r
+ kernel_stack[1021] = NULL; \r
+ \r
+ /*\r
+ * Initialize the thread context\r
+ */\r
+ memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));\r
+ thread->Tcb.Context.ldt = null_ldt_sel;\r
+ thread->Tcb.Context.eflags = (1<<1)+(1<<9);\r
+ thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);\r
+ thread->Tcb.Context.esp0 = &kernel_stack[1021];\r
+ thread->Tcb.Context.ss0 = KERNEL_DS;\r
+ thread->Tcb.Context.esp = &kernel_stack[1021];\r
+ thread->Tcb.Context.ss = KERNEL_DS;\r
+ thread->Tcb.Context.cs = KERNEL_CS;\r
+ thread->Tcb.Context.eip = (unsigned long)PsBeginThread;\r
+ thread->Tcb.Context.io_bitmap[0] = 0xff;\r
+ thread->Tcb.Context.cr3 = \r
+ linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);\r
+ thread->Tcb.Context.ds = KERNEL_DS;\r
+ thread->Tcb.Context.es = KERNEL_DS;\r
+ thread->Tcb.Context.fs = KERNEL_DS;\r
+ thread->Tcb.Context.gs = KERNEL_DS;\r
+ thread->Tcb.Context.nr = desc * 8;\r
+ DPRINT("Allocated %x\n",desc*8);\r
+ \r
+\r
+ return(TRUE);\r
+}\r
+\r
+void HalInitFirstTask(PETHREAD thread)\r
+/*\r
+ * FUNCTION: Called to setup the HAL portion of a thread object for the \r
+ * initial thread\r
+ */\r
+{\r
+ unsigned int base;\r
+ unsigned int length;\r
+ unsigned int desc;\r
+ \r
+ memset(null_ldt,0,sizeof(null_ldt));\r
+ desc = allocate_tss_descriptor();\r
+ base = (unsigned int)&null_ldt;\r
+ length = sizeof(null_ldt) - 1;\r
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)\r
+ | (base & 0xff000000);\r
+ null_ldt_sel = desc*8;\r
+ \r
+ /*\r
+ * Initialize the thread context\r
+ */\r
+ HalInitTask(thread,NULL,NULL);\r
+\r
+ /*\r
+ * Load the task register\r
+ */\r
+ __asm__("ltr %%ax" \r
+ : /* no output */\r
+ : "a" (thread->Tcb.Context.nr));\r
+ FirstThread = thread;\r
+}\r
/*
* 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)
-/*
- * 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);
- }
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/io/irp.c\r
+ * PURPOSE: Handle IRPs\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * UPDATE HISTORY: \r
+ * 24/05/98: Created \r
+ */\r
+\r
+/* NOTES *******************************************************************\r
+ * \r
+ * Layout of an IRP \r
+ * \r
+ * ################\r
+ * # Headers #\r
+ * ################\r
+ * # #\r
+ * # Variable #\r
+ * # length list #\r
+ * # of io stack #\r
+ * # locations #\r
+ * # #\r
+ * ################\r
+ * \r
+ * \r
+ * \r
+ */\r
+\r
+/* INCLUDES ****************************************************************/\r
+\r
+#include <internal/string.h>\r
+#include <internal/io.h>\r
+#include <ddk/ntddk.h>\r
+\r
+//#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+PDEVICE_OBJECT IoGetDeviceToVerify(PETHREAD Thread)\r
+/*\r
+ * FUNCTION: Returns a pointer to the device, representing a removable-media\r
+ * device, that is the target of the given thread's I/O request\r
+ */\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+VOID IoFreeIrp(PIRP Irp)\r
+/*\r
+ * FUNCTION: Releases a caller allocated irp\r
+ * ARGUMENTS:\r
+ * Irp = Irp to free\r
+ */\r
+{\r
+ ExFreePool(Irp);\r
+}\r
+\r
+PIRP IoMakeAssociatedIrp(PIRP Irp, CCHAR StackSize)\r
+/*\r
+ * FUNCTION: Allocates and initializes an irp to associated with a master irp\r
+ * ARGUMENTS:\r
+ * Irp = Master irp\r
+ * StackSize = Number of stack locations to be allocated in the irp\r
+ * RETURNS: The irp allocated\r
+ */\r
+{\r
+ PIRP AssocIrp;\r
+ \r
+ AssocIrp = IoAllocateIrp(StackSize,FALSE);\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+VOID IoMarkIrpPending(PIRP Irp)\r
+/*\r
+ * FUNCTION: Marks the specified irp, indicating further processing will\r
+ * be required by other driver routines\r
+ * ARGUMENTS:\r
+ * Irp = Irp to mark\r
+ */\r
+{\r
+ DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",\r
+ IoGetCurrentIrpStackLocation(Irp));\r
+ IoGetCurrentIrpStackLocation(Irp)->Control |= SL_PENDING_RETURNED;\r
+ Irp->Tail.Overlay.Thread = KeGetCurrentThread();\r
+ DPRINT("IoGetCurrentIrpStackLocation(Irp)->Control %x\n",\r
+ IoGetCurrentIrpStackLocation(Irp)->Control);\r
+ DPRINT("SL_PENDING_RETURNED %x\n",SL_PENDING_RETURNED);\r
+}\r
+\r
+USHORT IoSizeOfIrp(CCHAR StackSize)\r
+/*\r
+ * FUNCTION: Determines the size of an IRP\r
+ * ARGUMENTS: \r
+ * StackSize = number of stack locations in the IRP\r
+ * RETURNS: The size of the IRP in bytes \r
+ */\r
+{\r
+ return(sizeof(IRP)+((StackSize-1)*sizeof(IO_STACK_LOCATION)));\r
+}\r
+\r
+VOID IoInitializeIrp(PIRP Irp, USHORT PacketSize, CCHAR StackSize)\r
+/*\r
+ * FUNCTION: Initalizes an irp allocated by the caller\r
+ * ARGUMENTS:\r
+ * Irp = IRP to initalize\r
+ * PacketSize = Size in bytes of the IRP\r
+ * StackSize = Number of stack locations in the IRP\r
+ */\r
+{\r
+ assert(Irp!=NULL);\r
+ memset(Irp,0,PacketSize);\r
+ Irp->StackCount=StackSize;\r
+ Irp->CurrentLocation=StackSize;\r
+ Irp->Tail.Overlay.CurrentStackLocation=IoGetCurrentIrpStackLocation(Irp);\r
+}\r
+\r
+PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)\r
+/*\r
+ * FUNCTION: Gets a pointer to the callers location in the I/O stack in\r
+ * the given IRP\r
+ * ARGUMENTS:\r
+ * Irp = Points to the IRP\r
+ * RETURNS: A pointer to the stack location\r
+ */\r
+{\r
+ DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", \r
+ Irp,\r
+ Irp->CurrentLocation,\r
+ Irp->StackCount);\r
+\r
+ return &Irp->Stack[Irp->CurrentLocation];\r
+}\r
+\r
+\r
+VOID IoSetNextIrpStackLocation(PIRP Irp)\r
+{\r
+ Irp->CurrentLocation--;\r
+ Irp->Tail.Overlay.CurrentStackLocation--;\r
+}\r
+\r
+PIO_STACK_LOCATION IoGetNextIrpStackLocation(PIRP Irp)\r
+/*\r
+ * FUNCTION: Gives a higher level driver access to the next lower driver's \r
+ * I/O stack location\r
+ * ARGUMENTS: \r
+ * Irp = points to the irp\r
+ * RETURNS: A pointer to the stack location \r
+ */\r
+{\r
+ DPRINT("IoGetNextIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n", \r
+ Irp,\r
+ Irp->CurrentLocation,\r
+ Irp->StackCount);\r
+\r
+ assert(Irp!=NULL);\r
+ DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);\r
+ return(&Irp->Stack[Irp->CurrentLocation-1]);\r
+}\r
+\r
+NTSTATUS IoCallDriver(PDEVICE_OBJECT DevObject, PIRP irp)\r
+/*\r
+ * FUNCTION: Sends an IRP to the next lower driver\r
+ */\r
+{\r
+ NTSTATUS Status;\r
+ PDRIVER_OBJECT drv = DevObject->DriverObject;\r
+ IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(irp);\r
+\r
+ DPRINT("Deviceobject %x\n",DevObject);\r
+ DPRINT("Irp %x\n",irp);\r
+\r
+ irp->Tail.Overlay.CurrentStackLocation--;\r
+ irp->CurrentLocation--;\r
+\r
+ DPRINT("Io stack address %x\n",param);\r
+ DPRINT("Function %d Routine %x\n",param->MajorFunction,\r
+ drv->MajorFunction[param->MajorFunction]);\r
+\r
+ Status = drv->MajorFunction[param->MajorFunction](DevObject,irp);\r
+ return Status;\r
+}\r
+\r
+PIRP IoAllocateIrp(CCHAR StackSize, BOOLEAN ChargeQuota)\r
+/*\r
+ * FUNCTION: Allocates an IRP\r
+ * ARGUMENTS:\r
+ * StackSize = the size of the stack required for the irp\r
+ * ChargeQuota = Charge allocation to current threads quota\r
+ * RETURNS: Irp allocated\r
+ */\r
+{\r
+ PIRP Irp;\r
+ \r
+ DPRINT("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",StackSize,\r
+ ChargeQuota);\r
+ if (ChargeQuota)\r
+ {\r
+ Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));\r
+ }\r
+ else\r
+ { \r
+ Irp = ExAllocatePool(NonPagedPool,IoSizeOfIrp(StackSize));\r
+ }\r
+ \r
+ if (Irp==NULL)\r
+ {\r
+ return(NULL);\r
+ }\r
+ \r
+ Irp->StackCount=StackSize;\r
+ Irp->CurrentLocation=StackSize;\r
+\r
+ DPRINT("Irp %x Irp->StackPtr %d\n",Irp,Irp->CurrentLocation);\r
+ return(Irp);\r
+}\r
+\r
+VOID IoSetCompletionRoutine(PIRP Irp,\r
+ PIO_COMPLETION_ROUTINE CompletionRoutine,\r
+ PVOID Context,\r
+ BOOLEAN InvokeOnSuccess,\r
+ BOOLEAN InvokeOnError,\r
+ BOOLEAN InvokeOnCancel)\r
+{\r
+ IO_STACK_LOCATION* param = IoGetNextIrpStackLocation(Irp);\r
+ \r
+ param->CompletionRoutine=CompletionRoutine;\r
+ param->CompletionContext=Context;\r
+ if (InvokeOnSuccess)\r
+ {\r
+ param->Control = param->Control | SL_INVOKE_ON_SUCCESS;\r
+ }\r
+ if (InvokeOnError)\r
+ {\r
+ param->Control = param->Control | SL_INVOKE_ON_ERROR;\r
+ }\r
+ if (InvokeOnCancel)\r
+ {\r
+ param->Control = param->Control | SL_INVOKE_ON_CANCEL;\r
+ }\r
+}\r
+\r
+VOID IopCompleteRequest(struct _KAPC* Apc,\r
+ PKNORMAL_ROUTINE* NormalRoutine,\r
+ PVOID* NormalContext,\r
+ PVOID* SystemArgument1,\r
+ PVOID* SystemArgument2)\r
+{\r
+ IoSecondStageCompletion((PIRP)(*NormalContext),\r
+ IO_NO_INCREMENT);\r
+}\r
+\r
+VOID IoCompleteRequest(PIRP Irp, CCHAR PriorityBoost)\r
+/*\r
+ * FUNCTION: Indicates the caller has finished all processing for a given\r
+ * I/O request and is returning the given IRP to the I/O manager\r
+ * ARGUMENTS:\r
+ * Irp = Irp to be cancelled\r
+ * PriorityBoost = Increment by which to boost the priority of the\r
+ * thread making the request\r
+ */\r
+{\r
+ unsigned int i;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d)\n",\r
+ Irp,PriorityBoost);\r
+\r
+ for (i=0;i<Irp->StackCount;i++)\r
+ {\r
+ DPRINT("&Irp->Stack[i] %x\n",&Irp->Stack[i]);\r
+ if (Irp->Stack[i].CompletionRoutine!=NULL)\r
+ {\r
+ Status = Irp->Stack[i].CompletionRoutine(\r
+ Irp->Stack[i].DeviceObject,\r
+ Irp,\r
+ Irp->Stack[i].CompletionContext);\r
+ if (Status == STATUS_MORE_PROCESSING_REQUIRED)\r
+ {\r
+ return;\r
+ }\r
+ }\r
+ DPRINT("Irp->Stack[i].Control %x\n",Irp->Stack[i].Control);\r
+ if (Irp->Stack[i].Control & SL_PENDING_RETURNED)\r
+ {\r
+ DPRINT("Setting PendingReturned flag\n");\r
+ Irp->PendingReturned = TRUE;\r
+ }\r
+ }\r
+\r
+ if (Irp->PendingReturned)\r
+ {\r
+ KeInitializeApc(&Irp->Tail.Apc,\r
+ &Irp->Tail.Overlay.Thread->Tcb,\r
+ 0,\r
+ IopCompleteRequest,\r
+ NULL,\r
+ NULL,\r
+ 0,\r
+ Irp);\r
+ KeInsertQueueApc(&Irp->Tail.Apc,NULL,NULL,0);\r
+ }\r
+ else\r
+ {\r
+ IoSecondStageCompletion(Irp,PriorityBoost);\r
+ }\r
+}\r
+>>>>>>> 1.7\r
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,
-/*
- * 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);
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/ke/main.c\r
+ * PURPOSE: Initalizes the kernel\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * UPDATE HISTORY:\r
+ * 28/05/98: Created\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <windows.h>\r
+\r
+#include <internal/ntoskrnl.h>\r
+#include <internal/version.h>\r
+#include <internal/mm.h>\r
+#include <internal/string.h>\r
+#include <internal/symbol.h>\r
+#include <internal/module.h>\r
+\r
+#include <internal/mmhal.h>\r
+#include <internal/i386/segment.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+ \r
+void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type,\r
+ unsigned int len)\r
+/*\r
+ * FUNCTION: Sets a hardware breakpoint\r
+ * ARGUMENTS:\r
+ * i = breakpoint to set (0 to 3)\r
+ * addr = linear address to break on\r
+ * type = Type of access to break on\r
+ * len = length of the variable to watch\r
+ * NOTES:\r
+ * The variable to watch must be aligned to its length (i.e. a dword\r
+ * breakpoint must be aligned to a dword boundary)\r
+ * \r
+ * A fatal exception will be generated on the access to the variable.\r
+ * It is (at the moment) only really useful for catching undefined\r
+ * pointers if you know the variable effected but not the buggy\r
+ * routine. \r
+ * \r
+ * FIXME: Extend to call out to kernel debugger on breakpoint\r
+ * Add support for I/O breakpoints\r
+ * REFERENCES: See the i386 programmer manual for more details\r
+ */ \r
+{\r
+ unsigned int mask;\r
+ \r
+ if (i>3)\r
+ {\r
+ printk("Invalid breakpoint index at %s:%d\n",__FILE__,__LINE__);\r
+ return;\r
+ }\r
+ \r
+ /*\r
+ * Load the linear address\r
+ */\r
+ switch (i)\r
+ {\r
+ case 0:\r
+ __asm("movl %0,%%db0\n\t"\r
+ : /* no outputs */\r
+ : "d" (addr));\r
+ break;\r
+ \r
+ case 1:\r
+ __asm__("movl %0,%%db1\n\t"\r
+ : /* no outputs */\r
+ : "d" (addr));\r
+ break; \r
+ \r
+ case 2:\r
+ __asm__("movl %0,%%db2\n\t"\r
+ : /* no outputs */\r
+ : "d" (addr));\r
+ break; \r
+ \r
+ case 3:\r
+ __asm__("movl %0,%%db3\n\t"\r
+ : /* no outputs */\r
+ : "d" (addr));\r
+ break; \r
+ }\r
+ \r
+ /*\r
+ * Setup mask for dr7\r
+ */\r
+ mask = (len<<(16 + 2 + i*4)) + (type<<(16 + i*4)) + (1<<(i*2));\r
+ __asm__("movl %%db7,%%eax\n\t"\r
+ "orl %0,%%eax\n\t"\r
+ "movl %%eax,%%db7\n\t"\r
+ : /* no outputs */\r
+ : "d" (mask)\r
+ : "ax");\r
+}\r
+\r
+extern int edata;\r
+extern int end;\r
+\r
+asmlinkage void _main(boot_param* _bp)\r
+/*\r
+ * FUNCTION: Called by the boot loader to start the kernel\r
+ * ARGUMENTS:\r
+ * _bp = Pointer to boot parameters initialized by the boot loader\r
+ * NOTE: The boot parameters are stored in low memory which will become\r
+ * invalid after the memory managment is initialized so we make a local copy.\r
+ */\r
+{\r
+ unsigned int i;\r
+ unsigned int start;\r
+ unsigned int start1;\r
+ boot_param bp;\r
+ \r
+ memset((void *)&edata,0,((int)&end)-((int)&edata));\r
+ \r
+ /*\r
+ * Copy the parameters to a local buffer because lowmem will go away\r
+ */\r
+ memcpy(&bp,_bp,sizeof(boot_param));\r
+ \r
+ /*\r
+ * Initalize the console (before printing anything)\r
+ */\r
+ HalInitConsole(&bp);\r
+ \r
+ DbgPrint("Starting ReactOS "KERNEL_VERSION"\n");\r
+\r
+ start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);\r
+ if (start < ((int)&end))\r
+ {\r
+ DbgPrint("start %x end %x\n",start,(int)&end);\r
+ DbgPrint("Kernel booted incorrectly, aborting\n");\r
+ DbgPrint("Reduce the amount of uninitialized data\n");\r
+ for(;;);\r
+ } \r
+ start1 = start+PAGE_ROUND_UP(bp.module_length[1]);\r
+\r
+ \r
+ /*\r
+ * Initalize various critical subsystems\r
+ */\r
+ HalInit(&bp);\r
+ MmInitalize(&bp);\r
+ KeInit();\r
+ ObInit();\r
+ PsInit();\r
+ IoInit(); \r
+ \r
+ /*\r
+ * Initalize services loaded at boot time\r
+ */\r
+ DPRINT("%d files loaded\n",bp.nr_files);\r
+ \r
+ start = KERNEL_BASE + PAGE_ROUND_UP(bp.module_length[0]);\r
+ start1 = start+PAGE_ROUND_UP(bp.module_length[1]);\r
+ for (i=1;i<bp.nr_files;i++)\r
+ {\r
+ process_boot_module(start);\r
+ start=start+PAGE_ROUND_UP(bp.module_length[i]);\r
+ }\r
+ \r
+ /*\r
+ * Test various features of the kernel\r
+ */\r
+ TstBegin();\r
+ \r
+ /*\r
+ * Enter idle loop\r
+ */\r
+ printk("Finished main()\n");\r
+ PsTerminateSystemThread(STATUS_SUCCESS);\r
+}\r
/*
* 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)
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++;
* 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)
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;
/*
(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++)
{
-/*
- * 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)
- * UPDATE HISTORY:
- * 27/05/98: Created
- * 10/06/98: Bug fixes by Iwan Fatahi (i_fatahi@hotmail.com)
- * in take_block (if current bigger than required)
- * in remove_from_used_list
- * in ExFreePool
- * 23/08/98: Fixes from Robert Bergkvist (fragdance@hotmail.com)
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <internal/string.h>
-#include <internal/stddef.h>
-#include <internal/mm.h>
-#include <internal/mmhal.h>
-#include <internal/bitops.h>
-#include <internal/ntoskrnl.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-#include <ddk/ntddk.h>
-
-
-#if CHECKED
-#define VALIDATE_POOL validate_kernel_pool()
-#else
-#define VALIDATE_POOL
-#endif
-
-/* TYPES *******************************************************************/
-
-#define BLOCK_HDR_MAGIC (0xdeadbeef)
-
-/*
- * fields present at the start of a block (this is for internal use only)
- */
-typedef struct _block_hdr
-{
- ULONG magic;
- unsigned int size;
- struct _block_hdr* previous;
- struct _block_hdr* next;
- ULONG tag;
-} block_hdr;
-
-/* GLOBALS *****************************************************************/
-
-/*
- * Memory managment initalized symbol for the base of the pool
- */
-static unsigned int kernel_pool_base = 0;
-
-/*
- * Pointer to the first block in the free list
- */
-static block_hdr* free_list_head = NULL;
-static block_hdr* used_list_head = NULL;
-static unsigned int nr_free_blocks = 0;
-unsigned int nr_used_blocks = 0;
-
-#define ALLOC_MAP_SIZE (NONPAGED_POOL_SIZE / PAGESIZE)
-
-/*
- * One bit for each page in the kmalloc region
- * If set then the page is used by a kmalloc block
- */
-static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,};
-
-static unsigned int pool_free_mem = 0;
-
-unsigned int EiFreeNonPagedPool = 0;
-unsigned int EiUsedNonPagedPool = 0;
-
-/* FUNCTIONS ***************************************************************/
-
-VOID ExInitNonPagedPool(ULONG BaseAddress)
-{
- kernel_pool_base=BaseAddress;
-}
-
-static void validate_free_list(void)
-/*
- * FUNCTION: Validate the integrity of the list of free blocks
- */
-{
- block_hdr* current=free_list_head;
- unsigned int blocks_seen=0;
-
- while (current!=NULL)
- {
- unsigned int base_addr = (int)current;
-
- if (current->magic != BLOCK_HDR_MAGIC)
- {
- DbgPrint("Bad block magic (probable pool corruption)\n");
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
-
- if (base_addr < (kernel_pool_base) ||
- (base_addr+current->size) >
- (kernel_pool_base)+NONPAGED_POOL_SIZE)
- {
- printk("Block %x found outside pool area\n",current);
- printk("Size %d\n",current->size);
- printk("Limits are %x %x\n",kernel_pool_base,
- kernel_pool_base+NONPAGED_POOL_SIZE);
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
- blocks_seen++;
- if (blocks_seen > nr_free_blocks)
- {
- printk("Too many blocks on list\n");
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
-// verify_for_write(base_addr,current->size);
- if (current->next!=NULL&¤t->next->previous!=current)
- {
- printk("%s:%d:Break in list (current %x next %x "
- "current->next->previous %x)\n",
- __FILE__,__LINE__,current,current->next,
- current->next->previous);
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
- current=current->next;
- }
-}
-
-static void validate_used_list(void)
-/*
- * FUNCTION: Validate the integrity of the list of used blocks
- */
-{
- block_hdr* current=used_list_head;
- unsigned int blocks_seen=0;
-
- while (current!=NULL)
- {
- unsigned int base_addr = (int)current;
-
- if (current->magic != BLOCK_HDR_MAGIC)
- {
- DbgPrint("Bad block magic (probable pool corruption)\n");
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
- if (base_addr < (kernel_pool_base) ||
- (base_addr+current->size) >
- (kernel_pool_base)+NONPAGED_POOL_SIZE)
- {
- printk("Block %x found outside pool area\n",current);
- for(;;);
- }
- blocks_seen++;
- if (blocks_seen > nr_used_blocks)
- {
- printk("Too many blocks on list\n");
- for(;;);
- }
- // verify_for_write(base_addr,current->size);
- if (current->next!=NULL&¤t->next->previous!=current)
- {
- printk("Break in list (current %x next %x)\n",
- current,current->next);
- for(;;);
- }
- current=current->next;
- }
-}
-
-static void check_duplicates(block_hdr* blk)
-/*
- * FUNCTION: Check a block has no duplicates
- * ARGUMENTS:
- * blk = block to check
- * NOTE: Bug checks if duplicates are found
- */
-{
- unsigned int base = (int)blk;
- unsigned int last = ((int)blk) + +sizeof(block_hdr) + blk->size;
-
- block_hdr* current=free_list_head;
- while (current!=NULL)
- {
- if (current->magic != BLOCK_HDR_MAGIC)
- {
- DbgPrint("Bad block magic (probable pool corruption)\n");
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
-
- if ( (int)current > base && (int)current < last )
- {
- printk("intersecting blocks on list\n");
- for(;;);
- }
- if ( (int)current < base &&
- ((int)current + current->size + sizeof(block_hdr))
- > base )
- {
- printk("intersecting blocks on list\n");
- for(;;);
- }
- current=current->next;
- }
- current=used_list_head;
- while (current!=NULL)
- {
- if ( (int)current > base && (int)current < last )
- {
- printk("intersecting blocks on list\n");
- for(;;);
- }
- if ( (int)current < base &&
- ((int)current + current->size + sizeof(block_hdr))
- > base )
- {
- printk("intersecting blocks on list\n");
- for(;;);
- }
- current=current->next;
- }
-
-}
-
-static void validate_kernel_pool(void)
-/*
- * FUNCTION: Checks the integrity of the kernel memory heap
- */
-{
- block_hdr* current=NULL;
-
- validate_free_list();
- validate_used_list();
-
- current=free_list_head;
- while (current!=NULL)
- {
- check_duplicates(current);
- current=current->next;
- }
- current=used_list_head;
- while (current!=NULL)
- {
- check_duplicates(current);
- current=current->next;
- }
-}
-
-static void add_to_free_list(block_hdr* blk)
-/*
- * FUNCTION: add the block to the free list (internal)
- */
-{
- blk->next=free_list_head;
- blk->previous=NULL;
- if (free_list_head!=NULL)
- {
- free_list_head->previous=blk;
- }
- free_list_head=blk;
- nr_free_blocks++;
-}
-
-static void add_to_used_list(block_hdr* blk)
-/*
- * FUNCTION: add the block to the used list (internal)
- */
-{
- blk->next=used_list_head;
- blk->previous=NULL;
- if (used_list_head!=NULL)
- {
- used_list_head->previous=blk;
- }
- used_list_head=blk;
- nr_used_blocks++;
-}
-
-
-static void remove_from_free_list(block_hdr* current)
-{
- if (current->next==NULL&¤t->previous==NULL)
- {
- free_list_head=NULL;
- }
- else
- {
- if (current->next==NULL)
- {
- current->previous->next=NULL;
- }
- else if (current->previous==NULL)
- {
- current->next->previous=NULL;
- free_list_head=current->next;
- }
- else
- {
- current->next->previous=current->previous;
- current->previous->next=current->next;
- }
- }
- nr_free_blocks--;
-}
-
-
-static void remove_from_used_list(block_hdr* current)
-{
- if (current->next==NULL&¤t->previous==NULL)
- {
- used_list_head=NULL;
- }
- else
- {
- if (current->previous==NULL)
- {
- current->next->previous=NULL;
- used_list_head=current->next;
- }
- else
- {
- current->previous->next=current->next;
- }
- if (current->next!=NULL)
- {
- current->next->previous=current->previous;
- }
- else
- {
- current->previous->next=NULL;
- }
- }
- nr_used_blocks--;
-}
-
-
-inline static void* block_to_address(block_hdr* blk)
-/*
- * FUNCTION: Translate a block header address to the corresponding block
- * address (internal)
- */
-{
- return ( (void *) ((int)blk + sizeof(block_hdr)) );
-}
-
-inline static block_hdr* address_to_block(void* addr)
-{
- return (block_hdr *)
- ( ((int)addr) - sizeof(block_hdr) );
-}
-
-static unsigned int alloc_pool_region(unsigned int nr_pages)
-/*
- * FUNCTION: Allocates a region of pages within the nonpaged pool area
- */
-{
- unsigned int start = 0;
- unsigned int length = 0;
- unsigned int i,j;
-
- OLD_DPRINT("alloc_pool_region(nr_pages = %d)\n",nr_pages);
-
- for (i=1; i<ALLOC_MAP_SIZE;i++)
- {
- if (!test_bit(i%32,&alloc_map[i/32]))
- {
- if (length == 0)
- {
- start=i;
- length = 1;
- }
- else
- {
- length++;
- }
- if (length==nr_pages)
- {
- OLD_DPRINT("found region at %d for %d\n",start,
- length);
- for (j=start;j<(start+length);j++)
- {
- set_bit(j%32,&alloc_map[j/32]);
- }
- OLD_DPRINT("returning %x\n",(start*PAGESIZE)
- +kernel_pool_base);
- return((start*PAGESIZE)+kernel_pool_base);
- }
- }
- else
- {
- start=0;
- length=0;
- }
- }
- printk("CRITICAL: Out of non-paged pool space\n");
- for(;;);
- return(0);
-}
-
-static block_hdr* grow_kernel_pool(unsigned int size)
-/*
- * FUNCTION: Grow the executive heap to accomodate a block of at least 'size'
- * bytes
- */
-{
- unsigned int total_size = size + sizeof(block_hdr);
- unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE;
- unsigned int start = alloc_pool_region(nr_pages);
- block_hdr* used_blk=NULL;
- block_hdr* free_blk=NULL;
- int i;
-
- OLD_DPRINT("growing heap for block size %d, ",size);
- OLD_DPRINT("start %x\n",start);
-
- for (i=0;i<nr_pages;i++)
- {
- set_page(start+(i*PAGESIZE),PA_SYSTEM | PA_WRITE | PA_READ,
- get_free_page());
- }
-
-
- if ((PAGESIZE-(total_size%PAGESIZE))>(2*sizeof(block_hdr)))
- {
- used_blk = (struct _block_hdr *)start;
- OLD_DPRINT("Creating block at %x\n",start);
- used_blk->magic = BLOCK_HDR_MAGIC;
- used_blk->size = size;
- add_to_used_list(used_blk);
-
- free_blk = (block_hdr *)(start + sizeof(block_hdr) + size);
- OLD_DPRINT("Creating block at %x\n",free_blk);
- free_blk->magic = BLOCK_HDR_MAGIC;
- free_blk->size = (nr_pages * PAGESIZE) -((sizeof(block_hdr)*2) + size);
- add_to_free_list(free_blk);
-
- EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size;
- EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size;
- }
- else
- {
- used_blk = (struct _block_hdr *)start;
- used_blk->magic = BLOCK_HDR_MAGIC;
- used_blk->size = nr_pages * PAGESIZE;
- add_to_used_list(used_blk);
-
- EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size;
- }
-
- VALIDATE_POOL;
- return(used_blk);
-}
-
-static void* take_block(block_hdr* current, unsigned int size)
-/*
- * FUNCTION: Allocate a used block of least 'size' from the specified
- * free block
- * RETURNS: The address of the created memory block
- */
-{
- /*
- * If the block is much bigger than required then split it and
- * return a pointer to the allocated section. If the difference
- * between the sizes is marginal it makes no sense to have the
- * extra overhead
- */
- if (current->size > (1 + size + sizeof(block_hdr)))
- {
- block_hdr* free_blk;
-
- EiFreeNonPagedPool = EiFreeNonPagedPool - current->size;
-
- /*
- * Replace the bigger block with a smaller block in the
- * same position in the list
- */
- free_blk = (block_hdr *)(((int)current)
- + sizeof(block_hdr) + size);
- free_blk->magic = BLOCK_HDR_MAGIC;
- free_blk->next = current->next;
- free_blk->previous = current->previous;
- if (current->next)
- {
- current->next->previous = free_blk;
- }
- if (current->previous)
- {
- current->previous->next = free_blk;
- }
- free_blk->size = current->size - (sizeof(block_hdr) + size);
- if (current==free_list_head)
- {
- free_list_head=free_blk;
- }
-
- current->size=size;
- add_to_used_list(current);
-
- EiUsedNonPagedPool = EiUsedNonPagedPool + current->size;
- EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size;
-
- VALIDATE_POOL;
- return(block_to_address(current));
- }
-
- /*
- * Otherwise allocate the whole block
- */
- remove_from_free_list(current);
- add_to_used_list(current);
-
- EiFreeNonPagedPool = EiFreeNonPagedPool - current->size;
- EiUsedNonPagedPool = EiUsedNonPagedPool + current->size;
-
- VALIDATE_POOL;
- return(block_to_address(current));
-}
-
-asmlinkage VOID ExFreePool(PVOID block)
-/*
- * FUNCTION: Releases previously allocated memory
- * ARGUMENTS:
- * block = block to free
- */
-{
- block_hdr *blk = address_to_block(block);
-
- OLD_DPRINT("ExFreePool(block %x), size %d, caller %x\n",
- block,
- blk->size,
- ((PULONG)&block)[-1]);
- OLD_DPRINT("freeing block %x\n",blk);
-
- VALIDATE_POOL;
-
- if (blk->magic != BLOCK_HDR_MAGIC)
- {
- DbgPrint("ExFreePool of non-allocated address\n");
- for(;;);
- return;
- }
-
- /*
- * Please don't change the order
- */
- remove_from_used_list(blk);
- add_to_free_list(blk);
-
- EiUsedNonPagedPool = EiUsedNonPagedPool - blk->size;
- EiFreeNonPagedPool = EiFreeNonPagedPool + blk->size;
-
- VALIDATE_POOL;
-}
-
-PVOID ExAllocateNonPagedPoolWithTag(ULONG type, ULONG size, ULONG Tag)
-{
- block_hdr* current=NULL;
- void* block;
-
- OLD_DPRINT("Blocks on free list %d\n",nr_free_blocks);
- OLD_DPRINT("Blocks on used list %d\n",nr_used_blocks);
- OLD_DPRINT("ExAllocateNonPagedPool(type %d, size %d)\n",type,size);
- VALIDATE_POOL;
-
- /*
- * accomodate this useful idiom
- */
- if (size==0)
- {
- return(NULL);
- }
-
- /*
- * Look for an already created block of sufficent size
- */
- current=free_list_head;
-
- while (current!=NULL)
- {
- OLD_DPRINT("current %x size %x next %x\n",current,current->size,
- current->next);
- if (current->magic != BLOCK_HDR_MAGIC)
- {
- DbgPrint("Bad block magic (probable pool corruption)\n");
- KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
- }
- if (current->size>=size)
- {
- OLD_DPRINT("found block %x of size %d\n",current,size);
- block=take_block(current,size);
- memset(block,0,size);
- return(block);
- }
- current=current->next;
- }
-
- /*
- * Otherwise create a new block
- */
- block=block_to_address(grow_kernel_pool(size));
- memset(block,0,size);
-
- return block;
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/mm/pool.c\r
+ * PURPOSE: Implements the kernel memory pool\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * UPDATE HISTORY:\r
+ * 27/05/98: Created\r
+ * 10/06/98: Bug fixes by Iwan Fatahi (i_fatahi@hotmail.com)\r
+ * in take_block (if current bigger than required)\r
+ * in remove_from_used_list \r
+ * in ExFreePool\r
+ * 23/08/98: Fixes from Robert Bergkvist (fragdance@hotmail.com)\r
+ */\r
+\r
+/* INCLUDES ****************************************************************/\r
+\r
+#include <internal/string.h>\r
+#include <internal/stddef.h>\r
+#include <internal/mm.h>\r
+#include <internal/mmhal.h>\r
+#include <internal/bitops.h>\r
+#include <internal/ntoskrnl.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+#include <ddk/ntddk.h>\r
+\r
+\r
+#if 0\r
+#define VALIDATE_POOL validate_kernel_pool()\r
+#else\r
+#define VALIDATE_POOL\r
+#endif\r
+\r
+/* TYPES *******************************************************************/\r
+\r
+#define BLOCK_HDR_MAGIC (0xdeadbeef)\r
+\r
+/*\r
+ * fields present at the start of a block (this is for internal use only)\r
+ */\r
+typedef struct _block_hdr\r
+{\r
+ ULONG magic;\r
+ ULONG size;\r
+ struct _block_hdr* previous;\r
+ struct _block_hdr* next;\r
+ ULONG tag;\r
+} block_hdr;\r
+\r
+/* GLOBALS *****************************************************************/\r
+\r
+/*\r
+ * Memory managment initalized symbol for the base of the pool\r
+ */\r
+static unsigned int kernel_pool_base = 0;\r
+\r
+/*\r
+ * Pointer to the first block in the free list\r
+ */\r
+static block_hdr* free_list_head = NULL;\r
+static block_hdr* used_list_head = NULL;\r
+static ULONG nr_free_blocks;\r
+ULONG EiNrUsedBlocks = 0;\r
+\r
+#define ALLOC_MAP_SIZE (NONPAGED_POOL_SIZE / PAGESIZE)\r
+\r
+/*\r
+ * One bit for each page in the kmalloc region\r
+ * If set then the page is used by a kmalloc block\r
+ */\r
+static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,};\r
+\r
+static unsigned int pool_free_mem = 0;\r
+\r
+unsigned int EiFreeNonPagedPool = 0;\r
+unsigned int EiUsedNonPagedPool = 0;\r
+\r
+/* FUNCTIONS ***************************************************************/\r
+\r
+VOID ExInitNonPagedPool(ULONG BaseAddress)\r
+{\r
+ kernel_pool_base=BaseAddress;\r
+}\r
+\r
+static void validate_free_list(void)\r
+/*\r
+ * FUNCTION: Validate the integrity of the list of free blocks\r
+ */\r
+{\r
+ block_hdr* current=free_list_head;\r
+ unsigned int blocks_seen=0; \r
+ \r
+ while (current!=NULL)\r
+ {\r
+ unsigned int base_addr = (int)current;\r
+\r
+ if (current->magic != BLOCK_HDR_MAGIC)\r
+ {\r
+ DbgPrint("Bad block magic (probable pool corruption)\n");\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+ \r
+ if (base_addr < (kernel_pool_base) ||\r
+ (base_addr+current->size) >\r
+ (kernel_pool_base)+NONPAGED_POOL_SIZE)\r
+ { \r
+ printk("Block %x found outside pool area\n",current);\r
+ printk("Size %d\n",current->size);\r
+ printk("Limits are %x %x\n",kernel_pool_base,\r
+ kernel_pool_base+NONPAGED_POOL_SIZE);\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+ blocks_seen++;\r
+ if (blocks_seen > nr_free_blocks)\r
+ {\r
+ printk("Too many blocks on list\n");\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+// verify_for_write(base_addr,current->size); \r
+ if (current->next!=NULL&¤t->next->previous!=current)\r
+ {\r
+ printk("%s:%d:Break in list (current %x next %x "\r
+ "current->next->previous %x)\n",\r
+ __FILE__,__LINE__,current,current->next,\r
+ current->next->previous);\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+ current=current->next;\r
+ }\r
+}\r
+\r
+static void validate_used_list(void)\r
+/*\r
+ * FUNCTION: Validate the integrity of the list of used blocks\r
+ */\r
+{\r
+ block_hdr* current=used_list_head;\r
+ unsigned int blocks_seen=0;\r
+ \r
+ while (current!=NULL)\r
+ {\r
+ unsigned int base_addr = (int)current;\r
+ \r
+ if (current->magic != BLOCK_HDR_MAGIC)\r
+ {\r
+ DbgPrint("Bad block magic (probable pool corruption)\n");\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+ if (base_addr < (kernel_pool_base) ||\r
+ (base_addr+current->size) >\r
+ (kernel_pool_base)+NONPAGED_POOL_SIZE)\r
+ {\r
+ printk("Block %x found outside pool area\n",current);\r
+ for(;;);\r
+ }\r
+ blocks_seen++;\r
+ if (blocks_seen > EiNrUsedBlocks)\r
+ {\r
+ printk("Too many blocks on list\n");\r
+ for(;;);\r
+ }\r
+ // verify_for_write(base_addr,current->size);\r
+ if (current->next!=NULL&¤t->next->previous!=current)\r
+ {\r
+ printk("Break in list (current %x next %x)\n",\r
+ current,current->next);\r
+ for(;;);\r
+ }\r
+ current=current->next;\r
+ }\r
+}\r
+\r
+static void check_duplicates(block_hdr* blk)\r
+/*\r
+ * FUNCTION: Check a block has no duplicates\r
+ * ARGUMENTS:\r
+ * blk = block to check\r
+ * NOTE: Bug checks if duplicates are found\r
+ */\r
+{\r
+ unsigned int base = (int)blk;\r
+ unsigned int last = ((int)blk) + +sizeof(block_hdr) + blk->size;\r
+ \r
+ block_hdr* current=free_list_head;\r
+ while (current!=NULL)\r
+ {\r
+ if (current->magic != BLOCK_HDR_MAGIC)\r
+ {\r
+ DbgPrint("Bad block magic (probable pool corruption)\n");\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+\r
+ if ( (int)current > base && (int)current < last ) \r
+ {\r
+ printk("intersecting blocks on list\n");\r
+ for(;;);\r
+ }\r
+ if ( (int)current < base &&\r
+ ((int)current + current->size + sizeof(block_hdr))\r
+ > base )\r
+ {\r
+ printk("intersecting blocks on list\n");\r
+ for(;;);\r
+ }\r
+ current=current->next;\r
+ }\r
+ current=used_list_head;\r
+ while (current!=NULL)\r
+ {\r
+ if ( (int)current > base && (int)current < last ) \r
+ {\r
+ printk("intersecting blocks on list\n");\r
+ for(;;);\r
+ }\r
+ if ( (int)current < base &&\r
+ ((int)current + current->size + sizeof(block_hdr))\r
+ > base )\r
+ {\r
+ printk("intersecting blocks on list\n");\r
+ for(;;);\r
+ }\r
+ current=current->next;\r
+ }\r
+ \r
+}\r
+\r
+static void validate_kernel_pool(void)\r
+/*\r
+ * FUNCTION: Checks the integrity of the kernel memory heap\r
+ */\r
+{\r
+ block_hdr* current=NULL;\r
+ \r
+ validate_free_list();\r
+ validate_used_list();\r
+\r
+ current=free_list_head;\r
+ while (current!=NULL)\r
+ {\r
+ check_duplicates(current);\r
+ current=current->next;\r
+ }\r
+ current=used_list_head;\r
+ while (current!=NULL)\r
+ {\r
+ check_duplicates(current);\r
+ current=current->next;\r
+ }\r
+}\r
+\r
+static void add_to_free_list(block_hdr* blk)\r
+/*\r
+ * FUNCTION: add the block to the free list (internal)\r
+ */\r
+{\r
+ blk->next=free_list_head;\r
+ blk->previous=NULL;\r
+ if (free_list_head!=NULL)\r
+ {\r
+ free_list_head->previous=blk;\r
+ }\r
+ free_list_head=blk;\r
+ nr_free_blocks++;\r
+}\r
+\r
+static void add_to_used_list(block_hdr* blk)\r
+/*\r
+ * FUNCTION: add the block to the used list (internal)\r
+ */\r
+{\r
+ blk->next=used_list_head;\r
+ blk->previous=NULL;\r
+ if (used_list_head!=NULL)\r
+ {\r
+ used_list_head->previous=blk;\r
+ }\r
+ used_list_head=blk;\r
+ EiNrUsedBlocks++;\r
+}\r
+\r
+\r
+static void remove_from_free_list(block_hdr* current)\r
+{\r
+ if (current->next==NULL&¤t->previous==NULL)\r
+ {\r
+ free_list_head=NULL; \r
+ }\r
+ else\r
+ {\r
+ if (current->next==NULL)\r
+ {\r
+ current->previous->next=NULL;\r
+ }\r
+ else if (current->previous==NULL)\r
+ {\r
+ current->next->previous=NULL;\r
+ free_list_head=current->next;\r
+ }\r
+ else\r
+ {\r
+ current->next->previous=current->previous;\r
+ current->previous->next=current->next;\r
+ }\r
+ }\r
+ nr_free_blocks--;\r
+}\r
+\r
+\r
+static void remove_from_used_list(block_hdr* current)\r
+{\r
+ if (current->next==NULL&¤t->previous==NULL)\r
+ {\r
+ used_list_head=NULL; \r
+ }\r
+ else\r
+ { \r
+ if (current->previous==NULL)\r
+ {\r
+ current->next->previous=NULL;\r
+ used_list_head=current->next;\r
+ }\r
+ else\r
+ {\r
+ current->previous->next=current->next;\r
+ }\r
+ if (current->next!=NULL)\r
+ {\r
+ current->next->previous=current->previous;\r
+ }\r
+ else\r
+ {\r
+ current->previous->next=NULL;\r
+ }\r
+ }\r
+ EiNrUsedBlocks--;\r
+}\r
+\r
+\r
+inline static void* block_to_address(block_hdr* blk)\r
+/*\r
+ * FUNCTION: Translate a block header address to the corresponding block\r
+ * address (internal)\r
+ */\r
+{\r
+ return ( (void *) ((int)blk + sizeof(block_hdr)) );\r
+}\r
+\r
+inline static block_hdr* address_to_block(void* addr)\r
+{\r
+ return (block_hdr *)\r
+ ( ((int)addr) - sizeof(block_hdr) );\r
+}\r
+\r
+static unsigned int alloc_pool_region(unsigned int nr_pages)\r
+/*\r
+ * FUNCTION: Allocates a region of pages within the nonpaged pool area\r
+ */\r
+{\r
+ unsigned int start = 0;\r
+ unsigned int length = 0;\r
+ unsigned int i,j;\r
+ \r
+ OLD_DPRINT("alloc_pool_region(nr_pages = %d)\n",nr_pages);\r
+\r
+ for (i=1; i<ALLOC_MAP_SIZE;i++)\r
+ {\r
+ if (!test_bit(i%32,&alloc_map[i/32]))\r
+ {\r
+ if (length == 0)\r
+ {\r
+ start=i;\r
+ length = 1;\r
+ }\r
+ else\r
+ {\r
+ length++;\r
+ }\r
+ if (length==nr_pages)\r
+ {\r
+ OLD_DPRINT("found region at %d for %d\n",start,\r
+ length);\r
+ for (j=start;j<(start+length);j++)\r
+ {\r
+ set_bit(j%32,&alloc_map[j/32]);\r
+ }\r
+ OLD_DPRINT("returning %x\n",(start*PAGESIZE)\r
+ +kernel_pool_base);\r
+ return((start*PAGESIZE)+kernel_pool_base);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ start=0;\r
+ length=0;\r
+ }\r
+ }\r
+ printk("CRITICAL: Out of non-paged pool space\n");\r
+ for(;;);\r
+ return(0);\r
+}\r
+\r
+static block_hdr* grow_kernel_pool(unsigned int size)\r
+/*\r
+ * FUNCTION: Grow the executive heap to accomodate a block of at least 'size'\r
+ * bytes\r
+ */\r
+{\r
+ unsigned int total_size = size + sizeof(block_hdr);\r
+ unsigned int nr_pages = PAGE_ROUND_UP(total_size) / PAGESIZE;\r
+ unsigned int start = alloc_pool_region(nr_pages);\r
+ block_hdr* used_blk=NULL;\r
+ block_hdr* free_blk=NULL;\r
+ int i;\r
+ \r
+ OLD_DPRINT("growing heap for block size %d, ",size);\r
+ OLD_DPRINT("start %x\n",start);\r
+ \r
+ for (i=0;i<nr_pages;i++)\r
+ {\r
+ set_page(start+(i*PAGESIZE),PA_SYSTEM | PA_WRITE | PA_READ,\r
+ get_free_page());\r
+ }\r
+\r
+ \r
+ if ((PAGESIZE-(total_size%PAGESIZE))>(2*sizeof(block_hdr)))\r
+ {\r
+ used_blk = (struct _block_hdr *)start;\r
+ OLD_DPRINT("Creating block at %x\n",start);\r
+ used_blk->magic = BLOCK_HDR_MAGIC;\r
+ used_blk->size = size;\r
+ add_to_used_list(used_blk);\r
+ \r
+ free_blk = (block_hdr *)(start + sizeof(block_hdr) + size);\r
+ OLD_DPRINT("Creating block at %x\n",free_blk);\r
+ free_blk->magic = BLOCK_HDR_MAGIC;\r
+ free_blk->size = (nr_pages * PAGESIZE) -((sizeof(block_hdr)*2) + size);\r
+ add_to_free_list(free_blk);\r
+ \r
+ EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size;\r
+ EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size;\r
+ }\r
+ else\r
+ {\r
+ used_blk = (struct _block_hdr *)start;\r
+ used_blk->magic = BLOCK_HDR_MAGIC;\r
+ used_blk->size = nr_pages * PAGESIZE;\r
+ add_to_used_list(used_blk);\r
+ \r
+ EiUsedNonPagedPool = EiUsedNonPagedPool + used_blk->size;\r
+ }\r
+ \r
+ VALIDATE_POOL;\r
+ return(used_blk);\r
+}\r
+\r
+static void* take_block(block_hdr* current, unsigned int size)\r
+/*\r
+ * FUNCTION: Allocate a used block of least 'size' from the specified\r
+ * free block\r
+ * RETURNS: The address of the created memory block\r
+ */\r
+{\r
+ /*\r
+ * If the block is much bigger than required then split it and\r
+ * return a pointer to the allocated section. If the difference\r
+ * between the sizes is marginal it makes no sense to have the\r
+ * extra overhead \r
+ */\r
+ if (current->size > (1 + size + sizeof(block_hdr)))\r
+ {\r
+ block_hdr* free_blk;\r
+ \r
+ EiFreeNonPagedPool = EiFreeNonPagedPool - current->size;\r
+ \r
+ /*\r
+ * Replace the bigger block with a smaller block in the\r
+ * same position in the list\r
+ */\r
+ free_blk = (block_hdr *)(((int)current)\r
+ + sizeof(block_hdr) + size); \r
+ free_blk->magic = BLOCK_HDR_MAGIC;\r
+ free_blk->next = current->next;\r
+ free_blk->previous = current->previous;\r
+ if (current->next) \r
+ {\r
+ current->next->previous = free_blk;\r
+ }\r
+ if (current->previous)\r
+ {\r
+ current->previous->next = free_blk;\r
+ }\r
+ free_blk->size = current->size - (sizeof(block_hdr) + size);\r
+ if (current==free_list_head)\r
+ {\r
+ free_list_head=free_blk;\r
+ }\r
+ \r
+ current->size=size;\r
+ add_to_used_list(current);\r
+ \r
+ EiUsedNonPagedPool = EiUsedNonPagedPool + current->size;\r
+ EiFreeNonPagedPool = EiFreeNonPagedPool + free_blk->size;\r
+ \r
+ VALIDATE_POOL;\r
+ return(block_to_address(current));\r
+ }\r
+ \r
+ /*\r
+ * Otherwise allocate the whole block\r
+ */\r
+ remove_from_free_list(current);\r
+ add_to_used_list(current);\r
+ \r
+ EiFreeNonPagedPool = EiFreeNonPagedPool - current->size;\r
+ EiUsedNonPagedPool = EiUsedNonPagedPool + current->size;\r
+ \r
+ VALIDATE_POOL;\r
+ return(block_to_address(current));\r
+}\r
+\r
+asmlinkage VOID ExFreePool(PVOID block)\r
+/*\r
+ * FUNCTION: Releases previously allocated memory\r
+ * ARGUMENTS:\r
+ * block = block to free\r
+ */\r
+{\r
+ block_hdr* blk=address_to_block(block);\r
+ OLD_DPRINT("(%s:%d) freeing block %x\n",__FILE__,__LINE__,blk);\r
+ \r
+// DbgPrint("ExFreePool(block %x), size %d, caller %x\n",block,blk->size,\r
+// ((PULONG)&block)[-1]);\r
+ \r
+ VALIDATE_POOL;\r
+ \r
+ if (blk->magic != BLOCK_HDR_MAGIC)\r
+ {\r
+ DbgPrint("ExFreePool of non-allocated address\n");\r
+ for(;;);\r
+ return;\r
+ }\r
+ \r
+ /*\r
+ * Please don't change the order\r
+ */\r
+ remove_from_used_list(blk);\r
+ add_to_free_list(blk);\r
+ \r
+ EiUsedNonPagedPool = EiUsedNonPagedPool - blk->size;\r
+ EiFreeNonPagedPool = EiFreeNonPagedPool + blk->size; \r
+ \r
+ VALIDATE_POOL;\r
+}\r
+\r
+PVOID ExAllocateNonPagedPoolWithTag(ULONG type, ULONG size, ULONG Tag)\r
+{\r
+ block_hdr* current=NULL;\r
+ void* block;\r
+ \r
+// DbgPrint("Blocks on free list %d\n",nr_free_blocks);\r
+// DbgPrint("Blocks on used list %d\n",eiNrUsedblocks);\r
+// OLD_DPRINT("ExAllocateNonPagedPool(type %d, size %d)\n",type,size);\r
+ VALIDATE_POOL;\r
+ \r
+ /*\r
+ * accomodate this useful idiom\r
+ */\r
+ if (size==0)\r
+ {\r
+ return(NULL);\r
+ }\r
+ \r
+ /*\r
+ * Look for an already created block of sufficent size\r
+ */\r
+ current=free_list_head;\r
+ \r
+ while (current!=NULL)\r
+ {\r
+ OLD_DPRINT("current %x size %x next %x\n",current,current->size,\r
+ current->next);\r
+ if (current->magic != BLOCK_HDR_MAGIC)\r
+ {\r
+ DbgPrint("Bad block magic (probable pool corruption)\n");\r
+ KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);\r
+ }\r
+ if (current->size>=size)\r
+ {\r
+ OLD_DPRINT("found block %x of size %d\n",current,size);\r
+ block=take_block(current,size);\r
+ VALIDATE_POOL;\r
+ memset(block,0,size);\r
+ return(block);\r
+ }\r
+ current=current->next;\r
+ }\r
+ \r
+ /*\r
+ * Otherwise create a new block\r
+ */\r
+ block=block_to_address(grow_kernel_pool(size));\r
+ VALIDATE_POOL;\r
+ memset(block,0,size);\r
+ return(block);\r
+}\r
-/*
- * 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));
-}
-
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/mm/pool.c\r
+ * PURPOSE: Implements the kernel memory pool\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ */\r
+\r
+/* INCLUDES ****************************************************************/\r
+\r
+#include <internal/ntoskrnl.h>\r
+#include <ddk/ntddk.h>\r
+#include <internal/pool.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS *****************************************************************/\r
+\r
+#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))\r
+\r
+/* FUNCTIONS ***************************************************************/\r
+\r
+PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)\r
+/*\r
+ * FUNCTION: Allocates pool memory of a specified type and returns a pointer\r
+ * to the allocated block. This routine is used for general purpose allocation\r
+ * of memory\r
+ * ARGUMENTS:\r
+ * PoolType\r
+ * Specifies the type of memory to allocate which can be one\r
+ * of the following:\r
+ * \r
+ * NonPagedPool\r
+ * NonPagedPoolMustSucceed\r
+ * NonPagedPoolCacheAligned\r
+ * NonPagedPoolCacheAlignedMustS\r
+ * PagedPool\r
+ * PagedPoolCacheAligned\r
+ * \r
+ * NumberOfBytes\r
+ * Specifies the number of bytes to allocate\r
+ * RETURNS: The allocated block on success\r
+ * NULL on failure\r
+ */\r
+{\r
+ PVOID Block;\r
+// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",\r
+// NumberOfBytes,((PULONG)&PoolType)[-1]);\r
+ Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);\r
+// DbgPrint("ExAllocatePool() = %x\n",Block);\r
+ return(Block);\r
+}\r
+\r
+PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)\r
+{\r
+ PVOID Block;\r
+ \r
+ if (type == NonPagedPoolCacheAligned || \r
+ type == NonPagedPoolCacheAlignedMustS)\r
+ {\r
+ UNIMPLEMENTED;\r
+ }\r
+ \r
+ switch(type)\r
+ {\r
+ case NonPagedPool:\r
+ case NonPagedPoolMustSucceed:\r
+ case NonPagedPoolCacheAligned:\r
+ case NonPagedPoolCacheAlignedMustS:\r
+ Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);\r
+ break;\r
+ \r
+ case PagedPool:\r
+ case PagedPoolCacheAligned:\r
+ Block = ExAllocatePagedPoolWithTag(type,size,Tag);\r
+ break;\r
+ \r
+ default:\r
+ return(NULL);\r
+ };\r
+ \r
+ if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)\r
+ && Block==NULL) \r
+ {\r
+ KeBugCheck(MUST_SUCCEED_POOL_EMPTY);\r
+ }\r
+ return(Block);\r
+}\r
+\r
+PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,\r
+ ULONG Tag)\r
+{\r
+ PVOID Block;\r
+ PKTHREAD current = KeGetCurrentThread();\r
+ \r
+ Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);\r
+ switch(PoolType)\r
+ {\r
+ case NonPagedPool:\r
+ case NonPagedPoolMustSucceed:\r
+ case NonPagedPoolCacheAligned:\r
+ case NonPagedPoolCacheAlignedMustS:\r
+// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;\r
+ break;\r
+ \r
+ case PagedPool:\r
+ case PagedPoolCacheAligned:\r
+// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;\r
+ break; \r
+ };\r
+ return(Block);\r
+}\r
+ \r
+PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)\r
+{\r
+ return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));\r
+}\r
PSECTION_OBJECT Section;
NTSTATUS Status;
- DPRINT("ZwCreateSection()\n");
-
+ DbgPrint("ZwCreateSection()\n");
+
Section = ObGenericCreateObject(SectionHandle,
DesiredAccess,
ObjectAttributes,
NULL);
if (Status != STATUS_SUCCESS)
{
+ DPRINT("ZwCreateSection() = %x\n",Status);
return(Status);
}
Section->AllocateAttributes = AllocationAttributes;
+ DPRINT("ZwCreateSection() = STATUS_SUCCESS\n");
return(STATUS_SUCCESS);
}
-/*
- * COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/virtual.c
- * PURPOSE: implementing the Virtualxxx section of the win32 api
- * PROGRAMMER: David Welch
- * UPDATE HISTORY:
- * 09/4/98: Created
- * 10/6/98: Corrections from Fatahi (i_fatahi@hotmail.com)
- * 30/9/98: Implemented ZwxxxVirtualMemory functions
- */
-
-/* INCLUDE *****************************************************************/
-
-#include <windows.h>
-
-#include <internal/i386/segment.h>
-#include <internal/mm.h>
-#include <internal/mmhal.h>
-#include <internal/ob.h>
-#include <internal/io.h>
-#include <internal/ps.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* TYPES *******************************************************************/
-
-extern unsigned int etext;
-extern unsigned int end;
-
-static MEMORY_AREA* kernel_text_desc = NULL;
-static MEMORY_AREA* kernel_data_desc = NULL;
-static MEMORY_AREA* kernel_param_desc = NULL;
-static MEMORY_AREA* kernel_pool_desc = NULL;
-
-/* FUNCTIONS ****************************************************************/
-
-void VirtualInit(boot_param* bp)
-/*
- * FUNCTION: Intialize the memory areas list
- * ARGUMENTS:
- * bp = Pointer to the boot parameters
- * kernel_len = Length of the kernel
- */
-{
- unsigned int kernel_len = bp->end_mem - bp->start_mem;
- PVOID BaseAddress;
- ULONG Length;
- ULONG ParamLength = kernel_len;
-
- DPRINT("VirtualInit() %x\n",bp);
-
- MmInitMemoryAreas();
- ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE);
-
-
- /*
- * Setup the system area descriptor list
- */
- BaseAddress = (PVOID)KERNEL_BASE;
- Length = PAGE_ROUND_UP(((ULONG)&etext)) - KERNEL_BASE;
- ParamLength = ParamLength - Length;
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
- Length,0,&kernel_text_desc);
-
- Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext));
- ParamLength = ParamLength - Length;
- DPRINT("Length %x\n",Length);
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext));
- MmCreateMemoryArea(KernelMode,
- NULL,
- MEMORY_AREA_SYSTEM,
- &BaseAddress,
- Length,
- 0,
- &kernel_data_desc);
-
-
- BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));
- Length = ParamLength;
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
- Length,0,&kernel_param_desc);
-
- BaseAddress = (PVOID)(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);
- Length = NONPAGED_POOL_SIZE;
- MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,
- Length,0,&kernel_pool_desc);
-
-// MmDumpMemoryAreas();
- CHECKPOINT;
-
- MmInitSectionImplementation();
-}
-
-ULONG MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, ULONG Address)
-{
- set_page(Address,0x7,get_free_page());
- return(TRUE);
-}
-
-NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)
-{
- LARGE_INTEGER Offset;
- IO_STATUS_BLOCK IoStatus;
-
- DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
- MemoryArea,Address);
-
- set_page((DWORD)Address,0x7,get_free_page());
-
- LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) +
- MemoryArea->Data.SectionData.ViewOffset;
-
- DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",
- MemoryArea->Data.SectionData.Section->FileObject);
-
- if (MemoryArea->Data.SectionData.Section->FileObject == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
- (PVOID)Address,
- &Offset,
- &IoStatus);
-
- DPRINT("Returning from MmSectionHandleFault()\n");
-
- return(STATUS_SUCCESS);
-}
-
-asmlinkage int page_fault_handler(unsigned int cs,
- unsigned int eip)
-/*
- * FUNCTION: Handle a page fault
- */
-{
- KPROCESSOR_MODE FaultMode;
- MEMORY_AREA* MemoryArea;
- KIRQL oldlvl;
- ULONG stat;
-
- /*
- * Get the address for the page fault
- */
- unsigned int cr2;
- __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
- DPRINT("Page fault at address %x with eip %x\n",cr2,eip);
-
- cr2 = PAGE_ROUND_DOWN(cr2);
-
- if (KeGetCurrentIrql()!=PASSIVE_LEVEL)
- {
- DbgPrint("Recursive page fault detected\n");
- return(0);
-// KeBugCheck(0);
- }
-
- KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
-
- /*
- * Find the memory area for the faulting address
- */
- if (cr2>=KERNEL_BASE)
- {
- /*
- * Check permissions
- */
- if (cs!=KERNEL_CS)
- {
- printk("%s:%d\n",__FILE__,__LINE__);
- return(0);
- }
- FaultMode = UserMode;
- }
- else
- {
- FaultMode = KernelMode;
- }
-
- MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2);
- if (MemoryArea==NULL)
- {
- printk("%s:%d\n",__FILE__,__LINE__);
- return(0);
- }
-
- switch (MemoryArea->Type)
- {
- case MEMORY_AREA_SYSTEM:
- stat = 0;
- break;
-
- case MEMORY_AREA_SECTION_VIEW_COMMIT:
- if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)
- {
- stat=1;
- }
- else
- {
- stat = 0;
- }
- break;
-
- case MEMORY_AREA_COMMIT:
- stat = MmCommitedSectionHandleFault(MemoryArea,cr2);
- break;
-
- default:
- stat = 0;
- break;
- }
- if (stat)
- {
- KeLowerIrql(oldlvl);
- }
- return(stat);
-}
-
-BOOLEAN MmIsNonPagedSystemAddressValid(PVOID VirtualAddress)
-{
- UNIMPLEMENTED;
-}
-
-BOOLEAN MmIsAddressValid(PVOID VirtualAddress)
-/*
- * FUNCTION: Checks whether the given address is valid for a read or write
- * ARGUMENTS:
- * VirtualAddress = address to check
- * RETURNS: True if the access would be valid
- * False if the access would cause a page fault
- * NOTES: This function checks whether a byte access to the page would
- * succeed. Is this realistic for RISC processors which don't
- * allow byte granular access?
- */
-{
- MEMORY_AREA* MemoryArea;
-
- MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),
- VirtualAddress);
-
- if (MemoryArea == NULL)
- {
- return(FALSE);
- }
- return(TRUE);
-}
-
-NTSTATUS
-STDCALL
-NtAllocateVirtualMemory(
- IN HANDLE ProcessHandle,
- IN OUT PVOID *BaseAddress,
- IN ULONG ZeroBits,
- IN OUT PULONG RegionSize,
- IN ULONG AllocationType,
- IN ULONG Protect
- )
-{
- return(ZwAllocateVirtualMemory(ProcessHandle,
- BaseAddress,
- ZeroBits,
- RegionSize,
- AllocationType,
- Protect));
-}
-
-NTSTATUS
-STDCALL
-ZwAllocateVirtualMemory(
- IN HANDLE ProcessHandle,
- IN OUT PVOID *BaseAddress,
- IN ULONG ZeroBits,
- IN OUT PULONG RegionSize,
- IN ULONG AllocationType,
- IN ULONG Protect
- )
-/*
- * FUNCTION: Allocates a block of virtual memory in the process address space
- * ARGUMENTS:
- * ProcessHandle = The handle of the process which owns the virtual memory
- * BaseAddress = A pointer to the virtual memory allocated. If you
- * supply a non zero value the system will try to
- * allocate the memory at the address supplied. It round
- * it down to a multiple of the page size.
- * ZeroBits = (OPTIONAL) You can specify the number of high order bits
- * that must be zero, ensuring that the memory will be
- * allocated at a address below a certain value.
- * RegionSize = The number of bytes to allocate
- * AllocationType = Indicates the type of virtual memory you like to
- * allocated, can be one of the values : MEM_COMMIT,
- * MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN
- * Protect = Indicates the protection type of the pages allocated, can be
- * a combination of PAGE_READONLY, PAGE_READWRITE,
- * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
- * PAGE_NOACCESS
- * REMARKS:
- * This function maps to the win32 VirtualAllocEx. Virtual memory is
- * process based so the protocol starts with a ProcessHandle. I
- * splitted the functionality of obtaining the actual address and
- * specifying the start address in two parameters ( BaseAddress and
- * StartAddress ) The NumberOfBytesAllocated specify the range and the
- * AllocationType and ProctectionType map to the other two parameters.
- * RETURNS: Status
- */
-{
- PEPROCESS Process;
- MEMORY_AREA* MemoryArea;
- ULONG Type;
- NTSTATUS Status;
-
- DPRINT("ZwAllocateVirtualMemory(ProcessHandle %x, *BaseAddress %x, "
- "ZeroBits %d, RegionSize %d, AllocationType %x, Protect %x)\n",
- ProcessHandle,*BaseAddress,ZeroBits,*RegionSize,AllocationType,
- Protect);
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- NULL,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- if (AllocationType & MEM_RESERVE)
- {
- Type = MEMORY_AREA_RESERVE;
- }
- else
- {
- Type = MEMORY_AREA_COMMIT;
- }
-
- if ((*BaseAddress) != 0)
- {
- MemoryArea = MmOpenMemoryAreaByAddress(Process, *BaseAddress);
-
- if (MemoryArea != NULL)
- {
- if (MemoryArea->BaseAddress == (*BaseAddress) &&
- MemoryArea->Length == *RegionSize)
- {
- MemoryArea->Type = Type;
- MemoryArea->Attributes =Protect;
- DPRINT("*BaseAddress %x\n",*BaseAddress);
- return(STATUS_SUCCESS);
- }
-
- MemoryArea = MmSplitMemoryArea(Process,
- MemoryArea,
- *BaseAddress,
- *RegionSize,
- Type,
- Protect);
- DPRINT("*BaseAddress %x\n",*BaseAddress);
- return(STATUS_SUCCESS);
- }
- }
-
- //FIXME RegionSize should be passed as pointer
-
-
- Status = MmCreateMemoryArea(UserMode,
- Process,
- Type,
- BaseAddress,
- *RegionSize,
- Protect,
- &MemoryArea);
-
- if (Status != STATUS_SUCCESS)
- {
- DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- DPRINT("*BaseAddress %x\n",*BaseAddress);
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtFlushVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToFlush,
- OUT PULONG NumberOfBytesFlushed OPTIONAL)
-{
- return(ZwFlushVirtualMemory(ProcessHandle,
- BaseAddress,
- NumberOfBytesToFlush,
- NumberOfBytesFlushed));
-}
-
-NTSTATUS STDCALL ZwFlushVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToFlush,
- OUT PULONG NumberOfBytesFlushed OPTIONAL)
-
-/*
- * FUNCTION: Flushes virtual memory to file
- * ARGUMENTS:
- * ProcessHandle = Points to the process that allocated the virtual
- * memory
- * BaseAddress = Points to the memory address
- * NumberOfBytesToFlush = Limits the range to flush,
- * NumberOfBytesFlushed = Actual number of bytes flushed
- * RETURNS: Status
- */
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID *BaseAddress,
- IN PULONG RegionSize,
- IN ULONG FreeType)
-{
- return(ZwFreeVirtualMemory(ProcessHandle,
- BaseAddress,
- RegionSize,
- FreeType));
-}
-
-NTSTATUS STDCALL ZwFreeVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID *BaseAddress,
- IN PULONG RegionSize,
- IN ULONG FreeType)
-
-/*
- * FUNCTION: Frees a range of virtual memory
- * ARGUMENTS:
- * ProcessHandle = Points to the process that allocated the virtual
- * memory
- * BaseAddress = Points to the memory address, rounded down to a
- * multiple of the pagesize
- * RegionSize = Limits the range to free, rounded up to a multiple of
- * the paging size
- * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
- * RETURNS: Status
- */
-{
- MEMORY_AREA* MemoryArea;
- NTSTATUS Status;
- PEPROCESS Process;
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- DbgPrint("ZwFreeVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- MemoryArea = MmOpenMemoryAreaByAddress(Process,*BaseAddress);
- if (MemoryArea == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (FreeType == MEM_RELEASE)
- {
- if (MemoryArea->BaseAddress != (*BaseAddress))
- {
- return(STATUS_UNSUCCESSFUL);
- }
- MmFreeMemoryArea(PsGetCurrentProcess(),
- BaseAddress,
- 0,
- TRUE);
- return(STATUS_SUCCESS);
- }
-
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtLockVirtualMemory(HANDLE ProcessHandle,
- PVOID BaseAddress,
- ULONG NumberOfBytesToLock,
- PULONG NumberOfBytesLocked)
-{
- return(ZwLockVirtualMemory(ProcessHandle,
- BaseAddress,
- NumberOfBytesToLock,
- NumberOfBytesLocked));
-}
-
-NTSTATUS STDCALL ZwLockVirtualMemory(HANDLE ProcessHandle,
- PVOID BaseAddress,
- ULONG NumberOfBytesToLock,
- PULONG NumberOfBytesLocked)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtProtectVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToProtect,
- IN ULONG NewAccessProtection,
- OUT PULONG OldAccessProtection)
-{
- return(ZwProtectVirtualMemory(ProcessHandle,
- BaseAddress,
- NumberOfBytesToProtect,
- NewAccessProtection,
- OldAccessProtection));
-}
-
-VOID MmChangeAreaProtection(PEPROCESS Process,
- PVOID BaseAddress,
- ULONG Length,
- ULONG Protect)
-{
- ULONG i;
-
- for (i=0; i<(Length/PAGESIZE); i++)
- {
- if (MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))
- {
- MmSetPageProtect(Process, BaseAddress + (i*PAGESIZE), Protect);
- }
- }
-}
-
-NTSTATUS STDCALL ZwProtectVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToProtect,
- IN ULONG NewAccessProtection,
- OUT PULONG OldAccessProtection)
-{
- PMEMORY_AREA MemoryArea;
- PEPROCESS Process;
- NTSTATUS Status;
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- DbgPrint("ZwProtectVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
- if (MemoryArea == NULL)
- {
- DbgPrint("ZwProtectVirtualMemory() = %x\n",STATUS_UNSUCCESSFUL);
- return(STATUS_UNSUCCESSFUL);
- }
-
- *OldAccessProtection = MemoryArea->Attributes;
-
- if (MemoryArea->BaseAddress == BaseAddress &&
- MemoryArea->Length == NumberOfBytesToProtect)
- {
- MemoryArea->Attributes = NewAccessProtection;
- }
- else
- {
- MemoryArea = MmSplitMemoryArea(Process,
- MemoryArea,
- BaseAddress,
- NumberOfBytesToProtect,
- MemoryArea->Type,
- NewAccessProtection);
- }
- MmChangeAreaProtection(Process,BaseAddress,NumberOfBytesToProtect,
- NewAccessProtection);
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL NtQueryVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID Address,
- IN IN CINT VirtualMemoryInformationClass,
- OUT PVOID VirtualMemoryInformation,
- IN ULONG Length,
- OUT PULONG ResultLength)
-{
- return(ZwQueryVirtualMemory(ProcessHandle,
- Address,
- VirtualMemoryInformationClass,
- VirtualMemoryInformation,
- Length,
- ResultLength));
-}
-
-NTSTATUS STDCALL ZwQueryVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID Address,
- IN CINT VirtualMemoryInformationClass,
- OUT PVOID VirtualMemoryInformation,
- IN ULONG Length,
- OUT PULONG ResultLength)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- OUT PVOID Buffer,
- IN ULONG NumberOfBytesToRead,
- OUT PULONG NumberOfBytesRead)
-{
- return(ZwReadVirtualMemory(ProcessHandle,
- BaseAddress,
- Buffer,
- NumberOfBytesToRead,
- NumberOfBytesRead));
-}
-
-NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- OUT PVOID Buffer,
- IN ULONG NumberOfBytesToRead,
- OUT PULONG NumberOfBytesRead)
-{
- PEPROCESS Process;
- MEMORY_AREA* MemoryArea;
- ULONG i;
- NTSTATUS Status;
- PULONG CurrentEntry;
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_READ,
- NULL,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
-
- if (MemoryArea == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (MemoryArea->Length > NumberOfBytesToRead)
- {
- NumberOfBytesToRead = MemoryArea->Length;
- }
-
- *NumberOfBytesRead = NumberOfBytesToRead;
-
- for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)
- {
- CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
- RtlCopyMemory(Buffer + (i*PAGESIZE),
- (PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
- PAGESIZE);
-
- }
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,
- PVOID BaseAddress,
- ULONG NumberOfBytesToUnlock,
- PULONG NumberOfBytesUnlocked OPTIONAL)
-{
- return(ZwUnlockVirtualMemory(ProcessHandle,
- BaseAddress,
- NumberOfBytesToUnlock,
- NumberOfBytesUnlocked));
-}
-
-NTSTATUS STDCALL ZwUnlockVirtualMemory(HANDLE ProcessHandle,
- PVOID BaseAddress,
- ULONG NumberOfBytesToUnlock,
- PULONG NumberOfBytesUnlocked OPTIONAL)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN PVOID Buffer,
- IN ULONG NumberOfBytesToWrite,
- OUT PULONG NumberOfBytesWritten)
-{
- return(ZwWriteVirtualMemory(ProcessHandle,
- BaseAddress,
- Buffer,
- NumberOfBytesToWrite,
- NumberOfBytesWritten));
-}
-
-NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN PVOID Buffer,
- IN ULONG NumberOfBytesToWrite,
- OUT PULONG NumberOfBytesWritten)
-{
- PEPROCESS Process;
- MEMORY_AREA* MemoryArea;
- ULONG i;
- NTSTATUS Status;
- PULONG CurrentEntry;
-
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_WRITE,
- NULL,
- UserMode,
- (PVOID*)(&Process),
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);
-
- if (MemoryArea == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
- if (MemoryArea->Length > NumberOfBytesToWrite)
- {
- NumberOfBytesToWrite = MemoryArea->Length;
- }
-
- *NumberOfBytesWritten = NumberOfBytesToWrite;
-
- for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)
- {
- CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));
- RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),
- Buffer + (i*PAGESIZE),
- PAGESIZE);
-
- }
- return(STATUS_SUCCESS);
-}
-
+/*\r
+ * COPYRIGHT: See COPYING in the top directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/mm/virtual.c\r
+ * PURPOSE: implementing the Virtualxxx section of the win32 api\r
+ * PROGRAMMER: David Welch\r
+ * UPDATE HISTORY:\r
+ * 09/4/98: Created\r
+ * 10/6/98: Corrections from Fatahi (i_fatahi@hotmail.com)\r
+ * 30/9/98: Implemented ZwxxxVirtualMemory functions\r
+ */\r
+ \r
+/* INCLUDE *****************************************************************/\r
+\r
+#include <windows.h>\r
+\r
+#include <internal/i386/segment.h>\r
+#include <internal/mm.h>\r
+#include <internal/mmhal.h>\r
+#include <internal/ob.h>\r
+#include <internal/io.h>\r
+#include <internal/ps.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* TYPES *******************************************************************/\r
+\r
+extern unsigned int etext;\r
+extern unsigned int end;\r
+\r
+static MEMORY_AREA* kernel_text_desc = NULL;\r
+static MEMORY_AREA* kernel_data_desc = NULL;\r
+static MEMORY_AREA* kernel_param_desc = NULL;\r
+static MEMORY_AREA* kernel_pool_desc = NULL;\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+void VirtualInit(boot_param* bp)\r
+/*\r
+ * FUNCTION: Intialize the memory areas list\r
+ * ARGUMENTS:\r
+ * bp = Pointer to the boot parameters\r
+ * kernel_len = Length of the kernel\r
+ */\r
+{\r
+ unsigned int kernel_len = bp->end_mem - bp->start_mem;\r
+ PVOID BaseAddress;\r
+ ULONG Length;\r
+ ULONG ParamLength = kernel_len;\r
+ \r
+ DPRINT("VirtualInit() %x\n",bp);\r
+ \r
+ MmInitMemoryAreas();\r
+ ExInitNonPagedPool(KERNEL_BASE+ PAGE_ROUND_UP(kernel_len) + PAGESIZE);\r
+ \r
+ \r
+ /*\r
+ * Setup the system area descriptor list\r
+ */\r
+ BaseAddress = (PVOID)KERNEL_BASE;\r
+ Length = PAGE_ROUND_UP(((ULONG)&etext)) - KERNEL_BASE;\r
+ ParamLength = ParamLength - Length;\r
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
+ Length,0,&kernel_text_desc);\r
+ \r
+ Length = PAGE_ROUND_UP(((ULONG)&end)) - PAGE_ROUND_UP(((ULONG)&etext));\r
+ ParamLength = ParamLength - Length;\r
+ DPRINT("Length %x\n",Length);\r
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&etext));\r
+ MmCreateMemoryArea(KernelMode,\r
+ NULL,\r
+ MEMORY_AREA_SYSTEM,\r
+ &BaseAddress,\r
+ Length,\r
+ 0,\r
+ &kernel_data_desc);\r
+ \r
+ \r
+ BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&end));\r
+ Length = ParamLength;\r
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
+ Length,0,&kernel_param_desc);\r
+ \r
+ BaseAddress = (PVOID)(KERNEL_BASE + PAGE_ROUND_UP(kernel_len) + PAGESIZE);\r
+ Length = NONPAGED_POOL_SIZE;\r
+ MmCreateMemoryArea(KernelMode,NULL,MEMORY_AREA_SYSTEM,&BaseAddress,\r
+ Length,0,&kernel_pool_desc);\r
+ \r
+// MmDumpMemoryAreas();\r
+ CHECKPOINT;\r
+ \r
+ MmInitSectionImplementation();\r
+}\r
+\r
+ULONG MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, ULONG Address)\r
+{\r
+ set_page(Address,0x7,get_free_page());\r
+ return(TRUE);\r
+}\r
+\r
+NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)\r
+{\r
+ LARGE_INTEGER Offset;\r
+ IO_STATUS_BLOCK IoStatus;\r
+ \r
+ DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",\r
+ MemoryArea,Address);\r
+ \r
+ set_page((DWORD)Address,0x7,get_free_page());\r
+ \r
+ LARGE_INTEGER_QUAD_PART(Offset) = (Address - MemoryArea->BaseAddress) + \r
+ MemoryArea->Data.SectionData.ViewOffset;\r
+ \r
+ DPRINT("MemoryArea->Data.SectionData.Section->FileObject %x\n",\r
+ MemoryArea->Data.SectionData.Section->FileObject);\r
+ \r
+ if (MemoryArea->Data.SectionData.Section->FileObject == NULL)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ \r
+ IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,\r
+ (PVOID)Address,\r
+ &Offset,\r
+ &IoStatus);\r
+ \r
+ DPRINT("Returning from MmSectionHandleFault()\n");\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+asmlinkage int page_fault_handler(unsigned int cs,\r
+ unsigned int eip)\r
+/*\r
+ * FUNCTION: Handle a page fault\r
+ */\r
+{\r
+ KPROCESSOR_MODE FaultMode;\r
+ MEMORY_AREA* MemoryArea;\r
+ KIRQL oldlvl;\r
+ ULONG stat;\r
+ \r
+ /*\r
+ * Get the address for the page fault\r
+ */\r
+ unsigned int cr2;\r
+ __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); \r
+ DPRINT("Page fault at address %x with eip %x\n",cr2,eip);\r
+\r
+ cr2 = PAGE_ROUND_DOWN(cr2);\r
+ \r
+ if (KeGetCurrentIrql()!=PASSIVE_LEVEL)\r
+ {\r
+ DbgPrint("Recursive page fault detected\n");\r
+ return(0);\r
+// KeBugCheck(0);\r
+ }\r
+ \r
+ KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);\r
+ \r
+ /*\r
+ * Find the memory area for the faulting address\r
+ */\r
+ if (cr2>=KERNEL_BASE)\r
+ {\r
+ /*\r
+ * Check permissions\r
+ */\r
+ if (cs!=KERNEL_CS)\r
+ {\r
+ printk("%s:%d\n",__FILE__,__LINE__);\r
+ return(0);\r
+ }\r
+ FaultMode = UserMode;\r
+ }\r
+ else\r
+ {\r
+ FaultMode = KernelMode;\r
+ }\r
+ \r
+ MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2);\r
+ if (MemoryArea==NULL)\r
+ {\r
+ printk("%s:%d\n",__FILE__,__LINE__);\r
+ return(0);\r
+ }\r
+ \r
+ switch (MemoryArea->Type)\r
+ {\r
+ case MEMORY_AREA_SYSTEM:\r
+ stat = 0;\r
+ break;\r
+ \r
+ case MEMORY_AREA_SECTION_VIEW_COMMIT:\r
+ if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS)\r
+ {\r
+ stat=1;\r
+ }\r
+ else\r
+ {\r
+ stat = 0;\r
+ }\r
+ break;\r
+ \r
+ case MEMORY_AREA_COMMIT:\r
+ stat = MmCommitedSectionHandleFault(MemoryArea,cr2);\r
+ break;\r
+ \r
+ default:\r
+ stat = 0;\r
+ break;\r
+ }\r
+ if (stat)\r
+ {\r
+ KeLowerIrql(oldlvl);\r
+ }\r
+ return(stat);\r
+}\r
+\r
+BOOLEAN MmIsNonPagedSystemAddressValid(PVOID VirtualAddress)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+BOOLEAN MmIsAddressValid(PVOID VirtualAddress)\r
+/*\r
+ * FUNCTION: Checks whether the given address is valid for a read or write\r
+ * ARGUMENTS:\r
+ * VirtualAddress = address to check\r
+ * RETURNS: True if the access would be valid\r
+ * False if the access would cause a page fault\r
+ * NOTES: This function checks whether a byte access to the page would\r
+ * succeed. Is this realistic for RISC processors which don't\r
+ * allow byte granular access?\r
+ */\r
+{\r
+ MEMORY_AREA* MemoryArea;\r
+ \r
+ MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),\r
+ VirtualAddress);\r
+\r
+ if (MemoryArea == NULL)\r
+ {\r
+ return(FALSE);\r
+ }\r
+ return(TRUE);\r
+}\r
+\r
+NTSTATUS\r
+STDCALL\r
+NtAllocateVirtualMemory( \r
+ IN HANDLE ProcessHandle,\r
+ IN OUT PVOID *BaseAddress,\r
+ IN ULONG ZeroBits,\r
+ IN OUT PULONG RegionSize,\r
+ IN ULONG AllocationType, \r
+ IN ULONG Protect\r
+ )\r
+{\r
+ return(ZwAllocateVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ ZeroBits,\r
+ RegionSize,\r
+ AllocationType,\r
+ Protect));\r
+}\r
+\r
+NTSTATUS\r
+STDCALL\r
+ZwAllocateVirtualMemory( \r
+ IN HANDLE ProcessHandle,\r
+ IN OUT PVOID *BaseAddress,\r
+ IN ULONG ZeroBits,\r
+ IN OUT PULONG RegionSize,\r
+ IN ULONG AllocationType, \r
+ IN ULONG Protect\r
+ )\r
+/*\r
+ * FUNCTION: Allocates a block of virtual memory in the process address space\r
+ * ARGUMENTS:\r
+ * ProcessHandle = The handle of the process which owns the virtual memory\r
+ * BaseAddress = A pointer to the virtual memory allocated. If you \r
+ * supply a non zero value the system will try to \r
+ * allocate the memory at the address supplied. It round \r
+ * it down to a multiple of the page size.\r
+ * ZeroBits = (OPTIONAL) You can specify the number of high order bits \r
+ * that must be zero, ensuring that the memory will be \r
+ * allocated at a address below a certain value.\r
+ * RegionSize = The number of bytes to allocate\r
+ * AllocationType = Indicates the type of virtual memory you like to \r
+ * allocated, can be one of the values : MEM_COMMIT, \r
+ * MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN\r
+ * Protect = Indicates the protection type of the pages allocated, can be\r
+ * a combination of PAGE_READONLY, PAGE_READWRITE, \r
+ * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD, \r
+ * PAGE_NOACCESS\r
+ * REMARKS:\r
+ * This function maps to the win32 VirtualAllocEx. Virtual memory is \r
+ * process based so the protocol starts with a ProcessHandle. I \r
+ * splitted the functionality of obtaining the actual address and \r
+ * specifying the start address in two parameters ( BaseAddress and \r
+ * StartAddress ) The NumberOfBytesAllocated specify the range and the \r
+ * AllocationType and ProctectionType map to the other two parameters.\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PEPROCESS Process;\r
+ MEMORY_AREA* MemoryArea;\r
+ ULONG Type;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("ZwAllocateVirtualMemory(ProcessHandle %x, *BaseAddress %x, "\r
+ "ZeroBits %d, RegionSize %d, AllocationType %x, Protect %x)\n",\r
+ ProcessHandle,*BaseAddress,ZeroBits,*RegionSize,AllocationType,\r
+ Protect);\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_VM_OPERATION,\r
+ NULL,\r
+ UserMode,\r
+ (PVOID*)(&Process),\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);\r
+ return(Status);\r
+ }\r
+ \r
+ if (AllocationType & MEM_RESERVE)\r
+ {\r
+ Type = MEMORY_AREA_RESERVE;\r
+ }\r
+ else\r
+ {\r
+ Type = MEMORY_AREA_COMMIT;\r
+ }\r
+ \r
+ if ((*BaseAddress) != 0)\r
+ {\r
+ MemoryArea = MmOpenMemoryAreaByAddress(Process, *BaseAddress);\r
+ \r
+ if (MemoryArea != NULL)\r
+ {\r
+ if (MemoryArea->BaseAddress == (*BaseAddress) &&\r
+ MemoryArea->Length == *RegionSize)\r
+ {\r
+ MemoryArea->Type = Type;\r
+ MemoryArea->Attributes =Protect;\r
+ DPRINT("*BaseAddress %x\n",*BaseAddress);\r
+ return(STATUS_SUCCESS);\r
+ }\r
+ \r
+ MemoryArea = MmSplitMemoryArea(Process,\r
+ MemoryArea,\r
+ *BaseAddress,\r
+ *RegionSize,\r
+ Type,\r
+ Protect);\r
+ DPRINT("*BaseAddress %x\n",*BaseAddress);\r
+ return(STATUS_SUCCESS);\r
+ }\r
+ }\r
+ \r
+ //FIXME RegionSize should be passed as pointer\r
+\r
+\r
+ Status = MmCreateMemoryArea(UserMode,\r
+ Process,\r
+ Type,\r
+ BaseAddress,\r
+ *RegionSize,\r
+ Protect,\r
+ &MemoryArea);\r
+ \r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);\r
+ return(Status);\r
+ }\r
+ \r
+ DPRINT("*BaseAddress %x\n",*BaseAddress);\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS STDCALL NtFlushVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN ULONG NumberOfBytesToFlush,\r
+ OUT PULONG NumberOfBytesFlushed OPTIONAL)\r
+{\r
+ return(ZwFlushVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ NumberOfBytesToFlush,\r
+ NumberOfBytesFlushed));\r
+}\r
+\r
+NTSTATUS STDCALL ZwFlushVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN ULONG NumberOfBytesToFlush,\r
+ OUT PULONG NumberOfBytesFlushed OPTIONAL)\r
+\r
+/*\r
+ * FUNCTION: Flushes virtual memory to file\r
+ * ARGUMENTS:\r
+ * ProcessHandle = Points to the process that allocated the virtual \r
+ * memory\r
+ * BaseAddress = Points to the memory address\r
+ * NumberOfBytesToFlush = Limits the range to flush,\r
+ * NumberOfBytesFlushed = Actual number of bytes flushed\r
+ * RETURNS: Status \r
+ */\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtFreeVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID *BaseAddress, \r
+ IN PULONG RegionSize, \r
+ IN ULONG FreeType)\r
+{\r
+ return(ZwFreeVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ RegionSize,\r
+ FreeType));\r
+}\r
+\r
+NTSTATUS STDCALL ZwFreeVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID *BaseAddress, \r
+ IN PULONG RegionSize, \r
+ IN ULONG FreeType)\r
+\r
+/*\r
+ * FUNCTION: Frees a range of virtual memory\r
+ * ARGUMENTS:\r
+ * ProcessHandle = Points to the process that allocated the virtual \r
+ * memory\r
+ * BaseAddress = Points to the memory address, rounded down to a \r
+ * multiple of the pagesize\r
+ * RegionSize = Limits the range to free, rounded up to a multiple of \r
+ * the paging size\r
+ * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE\r
+ * RETURNS: Status \r
+ */\r
+{\r
+ MEMORY_AREA* MemoryArea;\r
+ NTSTATUS Status;\r
+ PEPROCESS Process;\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_VM_OPERATION,\r
+ PsProcessType,\r
+ UserMode,\r
+ (PVOID*)(&Process),\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ DbgPrint("ZwFreeVirtualMemory() = %x\n",Status);\r
+ return(Status);\r
+ }\r
+\r
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,*BaseAddress);\r
+ if (MemoryArea == NULL)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ \r
+ if (FreeType == MEM_RELEASE)\r
+ {\r
+ if (MemoryArea->BaseAddress != (*BaseAddress))\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ MmFreeMemoryArea(PsGetCurrentProcess(),\r
+ BaseAddress,\r
+ 0,\r
+ TRUE);\r
+ return(STATUS_SUCCESS);\r
+ }\r
+ \r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtLockVirtualMemory(HANDLE ProcessHandle,\r
+ PVOID BaseAddress,\r
+ ULONG NumberOfBytesToLock,\r
+ PULONG NumberOfBytesLocked)\r
+{\r
+ return(ZwLockVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ NumberOfBytesToLock,\r
+ NumberOfBytesLocked));\r
+}\r
+\r
+NTSTATUS STDCALL ZwLockVirtualMemory(HANDLE ProcessHandle,\r
+ PVOID BaseAddress,\r
+ ULONG NumberOfBytesToLock,\r
+ PULONG NumberOfBytesLocked)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtProtectVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN ULONG NumberOfBytesToProtect,\r
+ IN ULONG NewAccessProtection,\r
+ OUT PULONG OldAccessProtection)\r
+{\r
+ return(ZwProtectVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ NumberOfBytesToProtect,\r
+ NewAccessProtection,\r
+ OldAccessProtection));\r
+}\r
+\r
+VOID MmChangeAreaProtection(PEPROCESS Process, \r
+ PVOID BaseAddress,\r
+ ULONG Length, \r
+ ULONG Protect)\r
+{\r
+ ULONG i;\r
+ \r
+ for (i=0; i<(Length/PAGESIZE); i++)\r
+ {\r
+ if (MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE)))\r
+ {\r
+ MmSetPageProtect(Process, BaseAddress + (i*PAGESIZE), Protect);\r
+ }\r
+ }\r
+}\r
+\r
+NTSTATUS STDCALL ZwProtectVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN ULONG NumberOfBytesToProtect,\r
+ IN ULONG NewAccessProtection,\r
+ OUT PULONG OldAccessProtection)\r
+{\r
+ PMEMORY_AREA MemoryArea;\r
+ PEPROCESS Process;\r
+ NTSTATUS Status;\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_VM_OPERATION,\r
+ PsProcessType,\r
+ UserMode,\r
+ (PVOID*)(&Process),\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ DbgPrint("ZwProtectVirtualMemory() = %x\n",Status);\r
+ return(Status);\r
+ }\r
+\r
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
+ if (MemoryArea == NULL)\r
+ {\r
+ DbgPrint("ZwProtectVirtualMemory() = %x\n",STATUS_UNSUCCESSFUL);\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+\r
+ *OldAccessProtection = MemoryArea->Attributes;\r
+\r
+ if (MemoryArea->BaseAddress == BaseAddress &&\r
+ MemoryArea->Length == NumberOfBytesToProtect)\r
+ {\r
+ MemoryArea->Attributes = NewAccessProtection; \r
+ }\r
+ else\r
+ {\r
+ MemoryArea = MmSplitMemoryArea(Process,\r
+ MemoryArea,\r
+ BaseAddress,\r
+ NumberOfBytesToProtect,\r
+ MemoryArea->Type,\r
+ NewAccessProtection);\r
+ }\r
+ MmChangeAreaProtection(Process,BaseAddress,NumberOfBytesToProtect,\r
+ NewAccessProtection);\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+\r
+NTSTATUS STDCALL NtQueryVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID Address,\r
+ IN IN CINT VirtualMemoryInformationClass,\r
+ OUT PVOID VirtualMemoryInformation,\r
+ IN ULONG Length,\r
+ OUT PULONG ResultLength)\r
+{\r
+ return(ZwQueryVirtualMemory(ProcessHandle,\r
+ Address,\r
+ VirtualMemoryInformationClass,\r
+ VirtualMemoryInformation,\r
+ Length,\r
+ ResultLength));\r
+}\r
+\r
+NTSTATUS STDCALL ZwQueryVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID Address,\r
+ IN CINT VirtualMemoryInformationClass,\r
+ OUT PVOID VirtualMemoryInformation,\r
+ IN ULONG Length,\r
+ OUT PULONG ResultLength)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ OUT PVOID Buffer,\r
+ IN ULONG NumberOfBytesToRead,\r
+ OUT PULONG NumberOfBytesRead)\r
+{\r
+ return(ZwReadVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ Buffer,\r
+ NumberOfBytesToRead,\r
+ NumberOfBytesRead));\r
+}\r
+\r
+NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ OUT PVOID Buffer,\r
+ IN ULONG NumberOfBytesToRead,\r
+ OUT PULONG NumberOfBytesRead)\r
+{\r
+ PEPROCESS Process;\r
+ MEMORY_AREA* MemoryArea;\r
+ ULONG i;\r
+ NTSTATUS Status;\r
+ PULONG CurrentEntry;\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_VM_READ,\r
+ NULL,\r
+ UserMode,\r
+ (PVOID*)(&Process),\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+\r
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
+ \r
+ if (MemoryArea == NULL)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (MemoryArea->Length > NumberOfBytesToRead)\r
+ {\r
+ NumberOfBytesToRead = MemoryArea->Length;\r
+ }\r
+ \r
+ *NumberOfBytesRead = NumberOfBytesToRead;\r
+ \r
+ for (i=0; i<(NumberOfBytesToRead/PAGESIZE); i++)\r
+ {\r
+ CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));\r
+ RtlCopyMemory(Buffer + (i*PAGESIZE),\r
+ (PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),\r
+ PAGESIZE);\r
+ \r
+ }\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle,\r
+ PVOID BaseAddress,\r
+ ULONG NumberOfBytesToUnlock,\r
+ PULONG NumberOfBytesUnlocked OPTIONAL)\r
+{\r
+ return(ZwUnlockVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ NumberOfBytesToUnlock,\r
+ NumberOfBytesUnlocked));\r
+}\r
+\r
+NTSTATUS STDCALL ZwUnlockVirtualMemory(HANDLE ProcessHandle,\r
+ PVOID BaseAddress,\r
+ ULONG NumberOfBytesToUnlock,\r
+ PULONG NumberOfBytesUnlocked OPTIONAL)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN PVOID Buffer,\r
+ IN ULONG NumberOfBytesToWrite,\r
+ OUT PULONG NumberOfBytesWritten)\r
+{\r
+ return(ZwWriteVirtualMemory(ProcessHandle,\r
+ BaseAddress,\r
+ Buffer,\r
+ NumberOfBytesToWrite,\r
+ NumberOfBytesWritten));\r
+}\r
+\r
+NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle,\r
+ IN PVOID BaseAddress,\r
+ IN PVOID Buffer,\r
+ IN ULONG NumberOfBytesToWrite,\r
+ OUT PULONG NumberOfBytesWritten)\r
+{\r
+ PEPROCESS Process;\r
+ MEMORY_AREA* MemoryArea;\r
+ ULONG i;\r
+ NTSTATUS Status;\r
+ PULONG CurrentEntry;\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_VM_WRITE,\r
+ NULL,\r
+ UserMode,\r
+ (PVOID*)(&Process),\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+\r
+ MemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress);\r
+ \r
+ if (MemoryArea == NULL)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ if (MemoryArea->Length > NumberOfBytesToWrite)\r
+ {\r
+ NumberOfBytesToWrite = MemoryArea->Length;\r
+ }\r
+ \r
+ *NumberOfBytesWritten = NumberOfBytesToWrite;\r
+ \r
+ for (i=0; i<(NumberOfBytesToWrite/PAGESIZE); i++)\r
+ {\r
+ CurrentEntry = MmGetPageEntry(Process, (DWORD)BaseAddress + (i*PAGESIZE));\r
+ RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)),\r
+ Buffer + (i*PAGESIZE),\r
+ PAGESIZE);\r
+ \r
+ }\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ob/namespc.c
- * PURPOSE: Manages the system namespace
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- * 22/05/98: Created
- */
-
-/* INCLUDES ***************************************************************/
-
-#include <windows.h>
-#include <wstring.h>
-#include <ddk/ntddk.h>
-#include <internal/ob.h>
-#include <internal/io.h>
-#include <internal/string.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS ****************************************************************/
-
-POBJECT_TYPE ObDirectoryType = NULL;
-
-static struct
-{
- OBJECT_HEADER hdr;
-// DIRECTORY_OBJECT directory;
- LIST_ENTRY head;
- KSPIN_LOCK Lock;
-} namespc_root = {{0,},};
-
-/* FUNCTIONS **************************************************************/
-
-NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- return(ZwOpenDirectoryObject(DirectoryHandle,
- DesiredAccess,
- ObjectAttributes));
-}
-
-NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes)
-/*
- * FUNCTION: Opens a namespace directory object
- * ARGUMENTS:
- * DirectoryHandle (OUT) = Variable which receives the directory handle
- * DesiredAccess = Desired access to the directory
- * ObjectAttributes = Structure describing the directory
- * RETURNS: Status
- * NOTES: Undocumented
- */
-{
- PVOID Object;
- NTSTATUS Status;
- PWSTR Ignored;
-
- *DirectoryHandle = 0;
-
- Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object,
- DesiredAccess,FALSE);
- CHECKPOINT;
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle,
- OUT POBJDIR_INFORMATION DirObjInformation,
- IN ULONG BufferLength,
- IN BOOLEAN GetNextIndex,
- IN BOOLEAN IgnoreInputIndex,
- IN OUT PULONG ObjectIndex,
- OUT PULONG DataWritten OPTIONAL)
-{
- return(ZwQueryDirectoryObject(DirObjHandle,
- DirObjInformation,
- BufferLength,
- GetNextIndex,
- IgnoreInputIndex,
- ObjectIndex,
- DataWritten));
-}
-
-NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,
- OUT POBJDIR_INFORMATION DirObjInformation,
- IN ULONG BufferLength,
- IN BOOLEAN GetNextIndex,
- IN BOOLEAN IgnoreInputIndex,
- IN OUT PULONG ObjectIndex,
- OUT PULONG DataWritten OPTIONAL)
-/*
- * FUNCTION: Reads information from a namespace directory
- * ARGUMENTS:
- * DirObjInformation (OUT) = Buffer to hold the data read
- * BufferLength = Size of the buffer in bytes
- * GetNextIndex = If TRUE then set ObjectIndex to the index of the
- * next object
- * If FALSE then set ObjectIndex to the number of
- * objects in the directory
- * IgnoreInputIndex = If TRUE start reading at index 0
- * If FALSE start reading at the index specified
- * by object index
- * ObjectIndex = Zero based index into the directory, interpretation
- * depends on IgnoreInputIndex and GetNextIndex
- * DataWritten (OUT) = Caller supplied storage for the number of bytes
- * written (or NULL)
- * RETURNS: Status
- */
-{
- PDIRECTORY_OBJECT dir = NULL;
- ULONG EntriesToRead;
- PLIST_ENTRY current_entry;
- POBJECT_HEADER current;
- ULONG i=0;
- ULONG EntriesToSkip;
- NTSTATUS Status;
-
- DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);
- DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));
-
-// assert_irql(PASSIVE_LEVEL);
-
- Status = ObReferenceObjectByHandle(DirObjHandle,
- DIRECTORY_QUERY,
- ObDirectoryType,
- UserMode,
- (PVOID*)&dir,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);
- *DataWritten = 0;
-
- DPRINT("EntriesToRead %d\n",EntriesToRead);
-
- current_entry = dir->head.Flink;
-
- /*
- * Optionally, skip over some entries at the start of the directory
- */
- if (!IgnoreInputIndex)
- {
- CHECKPOINT;
-
- EntriesToSkip = *ObjectIndex;
- while ( i<EntriesToSkip && current_entry!=NULL)
- {
- current_entry = current_entry->Flink;
- }
- }
-
- DPRINT("DirObjInformation %x\n",DirObjInformation);
-
- /*
- * Read the maximum entries possible into the buffer
- */
- while ( i<EntriesToRead && current_entry!=(&(dir->head)))
- {
- current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
- DPRINT("Scanning %w\n",current->Name.Buffer);
- DirObjInformation[i].ObjectName.Buffer =
- ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);
- DirObjInformation[i].ObjectName.Length = current->Name.Length;
- DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;
- DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
- DirObjInformation[i].ObjectName.Buffer);
- RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
- &(current->Name));
- i++;
- current_entry = current_entry->Flink;
- (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);
- CHECKPOINT;
- }
- CHECKPOINT;
-
- /*
- * Optionally, count the number of entries in the directory
- */
- if (GetNextIndex)
- {
- *ObjectIndex=i;
- }
- else
- {
- while ( current_entry!=(&(dir->head)) )
- {
- current_entry=current_entry->Flink;
- i++;
- }
- *ObjectIndex=i;
- }
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
- ULONG Attributes,
- PACCESS_STATE PassedAccessState,
- ACCESS_MASK DesiredAccess,
- POBJECT_TYPE ObjectType,
- KPROCESSOR_MODE AccessMode,
- PVOID ParseContext,
- PVOID* ObjectPtr)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,
- PVOID* Object, PWSTR* UnparsedSection)
-{
- NTSTATUS Status;
-
- DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",
- ObjectAttributes,Object);
- DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",
- ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);
- DPRINT("ObjectAttributes->ObjectName->Length %d\n",
- ObjectAttributes->ObjectName->Length);
-
- *Object = NULL;
- Status = ObLookupObject(ObjectAttributes->RootDirectory,
- ObjectAttributes->ObjectName->Buffer,
- Object,
- UnparsedSection,
- ObjectAttributes->Attributes);
- DPRINT("*Object %x\n",*Object);
- DPRINT("ObjectAttributes->ObjectName->Length %d\n",
- ObjectAttributes->ObjectName->Length);
- return(Status);
-}
-
-void ObInit(void)
-/*
- * FUNCTION: Initialize the object manager namespace
- */
-{
- ANSI_STRING AnsiString;
-
- ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
- ObDirectoryType->TotalObjects = 0;
- ObDirectoryType->TotalHandles = 0;
- ObDirectoryType->MaxObjects = ULONG_MAX;
- ObDirectoryType->MaxHandles = ULONG_MAX;
- ObDirectoryType->PagedPoolCharge = 0;
- ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);
- ObDirectoryType->Dump = NULL;
- ObDirectoryType->Open = NULL;
- ObDirectoryType->Close = NULL;
- ObDirectoryType->Delete = NULL;
- ObDirectoryType->Parse = NULL;
- ObDirectoryType->Security = NULL;
- ObDirectoryType->QueryName = NULL;
- ObDirectoryType->OkayToClose = NULL;
-
- RtlInitAnsiString(&AnsiString,"Directory");
- RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName,
- &AnsiString,TRUE);
-
- ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr);
- InitializeListHead(&namespc_root.head);
-}
-
-NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- return(ZwCreateDirectoryObject(DirectoryHandle,
- DesiredAccess,
- ObjectAttributes));
-}
-
-NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes)
-/*
- * FUNCTION: Creates or opens a directory object (a container for other
- * objects)
- * ARGUMENTS:
- * DirectoryHandle (OUT) = Caller supplied storage for the handle
- * of the directory
- * DesiredAccess = Access desired to the directory
- * ObjectAttributes = Object attributes initialized with
- * InitializeObjectAttributes
- * RETURNS: Status
- */
-{
- PDIRECTORY_OBJECT dir;
-
- dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes,
- ObDirectoryType);
-
- /*
- * Initialize the object body
- */
- InitializeListHead(&dir->head);
- KeInitializeSpinLock(&(dir->Lock));
-
- return(STATUS_SUCCESS);
-}
-
-VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,
- PUNICODE_STRING ObjectName,
- ULONG Attributes,
- HANDLE RootDirectory,
- PSECURITY_DESCRIPTOR SecurityDescriptor)
-/*
- * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a
- * subsequent call to ZwCreateXXX or ZwOpenXXX
- * ARGUMENTS:
- * InitializedAttributes (OUT) = Caller supplied storage for the
- * object attributes
- * ObjectName = Full path name for object
- * Attributes = Attributes for the object
- * RootDirectory = Where the object should be placed or NULL
- * SecurityDescriptor = Ignored
- *
- * NOTE:
- * Either ObjectName is a fully qualified pathname or a path relative
- * to RootDirectory
- */
-{
- DPRINT("InitializeObjectAttributes(InitializedAttributes %x "
- "ObjectName %x Attributes %x RootDirectory %x)\n",
- InitializedAttributes,ObjectName,Attributes,RootDirectory);
- InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);
- InitializedAttributes->RootDirectory=RootDirectory;
- InitializedAttributes->ObjectName=ObjectName;
- InitializedAttributes->Attributes=Attributes;
- InitializedAttributes->SecurityDescriptor=SecurityDescriptor;
- InitializedAttributes->SecurityQualityOfService=NULL;
-}
-
-static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name,
- ULONG Attributes)
-/*
- * FUNCTION: Looks up an entry within a namespace directory
- * ARGUMENTS:
- * dir = Directory to lookup in
- * name = Entry name to find
- * RETURNS: A pointer to the object body if found
- * NULL otherwise
- */
-{
- LIST_ENTRY* current = dir->head.Flink;
- POBJECT_HEADER current_obj;
-
- DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);
-
- if (name[0]==0)
- {
- return(dir);
- }
- if (name[0]=='.'&&name[1]==0)
- {
- return(dir);
- }
- if (name[0]=='.'&&name[1]=='.'&&name[2]==0)
- {
- return(BODY_TO_HEADER(dir)->Parent);
- }
- while (current!=(&(dir->head)))
- {
- current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);
- DPRINT("Scanning %w\n",current_obj->Name.Buffer);
- if (Attributes & OBJ_CASE_INSENSITIVE)
- {
- if (wcsicmp(current_obj->Name.Buffer, name)==0)
- {
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
- }
- }
- else
- {
- if ( wcscmp(current_obj->Name.Buffer, name)==0)
- {
- DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));
- return(HEADER_TO_BODY(current_obj));
- }
- }
- current = current->Flink;
- }
- DPRINT("%s() = NULL\n",__FUNCTION__);
- return(NULL);
-}
-
-VOID ObRemoveEntry(POBJECT_HEADER Header)
-{
- KIRQL oldlvl;
-
- DPRINT("ObRemoveEntry(Header %x)\n",Header);
-
- KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);
- RemoveEntryList(&(Header->Entry));
- KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);
-}
-
-VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)
-/*
- * FUNCTION: Add an entry to a namespace directory
- * ARGUMENTS:
- * parent = directory to add in
- * name = Name to give the entry
- * Object = Header of the object to add the entry for
- */
-{
- DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer,
- Object->Name.Buffer);
-
- /*
- * Insert ourselves in our parents list
- */
- InsertTailList(&parent->head,&Object->Entry);
-}
-
-NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,
- PWSTR* UnparsedSection, ULONG Attributes)
-/*
- * FUNCTION: Lookup an object within the system namespc
- * ARGUMENTS:
- * root = Directory to start lookup from
- * _string = Pathname to lookup
- * RETURNS: On success a pointer to the object body
- * On failure NULL
- */
-{
- PWSTR current;
- PWSTR next;
- PDIRECTORY_OBJECT current_dir = NULL;
- NTSTATUS Status;
-
- DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, "
- "UnparsedSection %x)\n",rootdir,string,string,Object,
- UnparsedSection);
-
-
- *UnparsedSection = NULL;
- *Object = NULL;
-
- if (rootdir==NULL)
- {
- current_dir = HEADER_TO_BODY(&(namespc_root.hdr));
- }
- else
- {
- ObReferenceObjectByHandle(rootdir,DIRECTORY_TRAVERSE,NULL,
- UserMode,(PVOID*)¤t_dir,NULL);
- }
-
- /*
- * Bit of a hack this
- */
- if (string[0]==0)
- {
- *Object=current_dir;
- return(STATUS_SUCCESS);
- }
-
- if (string[0]!='\\')
- {
- DbgPrint("(%s:%d) Non absolute pathname passed to %s\n",__FILE__,
- __LINE__,__FUNCTION__);
- return(STATUS_UNSUCCESSFUL);
- }
-
- next = &string[0];
- current = next+1;
-
- while (next!=NULL &&
- BODY_TO_HEADER(current_dir)->ObjectType==ObDirectoryType)
- {
- *next = '\\';
- current = next+1;
- next = wcschr(next+1,'\\');
- if (next!=NULL)
- {
- *next=0;
- }
-
- DPRINT("current %w current[5] %x next %x ",current,current[5],next);
- if (next!=NULL)
- {
- DPRINT("(next+1) %w",next+1);
- }
- DPRINT("\n",0);
-
- current_dir=(PDIRECTORY_OBJECT)ObDirLookup(current_dir,current,
- Attributes);
- if (current_dir==NULL)
- {
- DbgPrint("(%s:%d) Path component %w not found\n",__FILE__,
- __LINE__,current);
- return(STATUS_UNSUCCESSFUL);
- }
-
- if (BODY_TO_HEADER(current_dir)->ObjectType==IoSymbolicLinkType)
- {
- current_dir = IoOpenSymlink(current_dir);
- }
-
- }
- DPRINT("next %x\n",next);
- DPRINT("current %x current %w\n",current,current);
- if (next==NULL)
- {
- if (current_dir==NULL)
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- else
- {
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- CHECKPOINT;
- *next = '\\';
- *UnparsedSection = next;
- if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType)
- {
- Status = STATUS_FS_QUERY_REQUIRED;
- }
- else
- {
- Status = STATUS_UNSUCCESSFUL;
- }
- }
- CHECKPOINT;
- *Object = current_dir;
-
- return(Status);
-}
-
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/ob/namespc.c\r
+ * PURPOSE: Manages the system namespace\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * UPDATE HISTORY:\r
+ * 22/05/98: Created\r
+ */\r
+\r
+/* INCLUDES ***************************************************************/\r
+\r
+#include <windows.h>\r
+#include <wstring.h>\r
+#include <ddk/ntddk.h>\r
+#include <internal/ob.h>\r
+#include <internal/io.h>\r
+#include <internal/string.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS ****************************************************************/\r
+\r
+POBJECT_TYPE ObDirectoryType = NULL;\r
+\r
+static struct\r
+{\r
+ OBJECT_HEADER hdr;\r
+// DIRECTORY_OBJECT directory;\r
+ LIST_ENTRY head;\r
+ KSPIN_LOCK Lock;\r
+} namespc_root = {{0,},};\r
+\r
+/* FUNCTIONS **************************************************************/\r
+\r
+NTSTATUS NtOpenDirectoryObject(PHANDLE DirectoryHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes)\r
+{\r
+ return(ZwOpenDirectoryObject(DirectoryHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes));\r
+}\r
+\r
+NTSTATUS ZwOpenDirectoryObject(PHANDLE DirectoryHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes)\r
+/*\r
+ * FUNCTION: Opens a namespace directory object\r
+ * ARGUMENTS:\r
+ * DirectoryHandle (OUT) = Variable which receives the directory handle\r
+ * DesiredAccess = Desired access to the directory\r
+ * ObjectAttributes = Structure describing the directory\r
+ * RETURNS: Status\r
+ * NOTES: Undocumented\r
+ */\r
+{\r
+ PVOID Object;\r
+ NTSTATUS Status;\r
+ PWSTR Ignored;\r
+ \r
+ *DirectoryHandle = 0;\r
+ \r
+ Status = ObOpenObjectByName(ObjectAttributes,&Object,&Ignored);\r
+ if (!NT_SUCCESS(Status))\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ if (BODY_TO_HEADER(Object)->Type!=OBJTYP_DIRECTORY)\r
+ { \r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ \r
+ *DirectoryHandle = ObInsertHandle(KeGetCurrentProcess(),Object,\r
+ DesiredAccess,FALSE);\r
+ CHECKPOINT;\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS NtQueryDirectoryObject(IN HANDLE DirObjHandle,\r
+ OUT POBJDIR_INFORMATION DirObjInformation, \r
+ IN ULONG BufferLength, \r
+ IN BOOLEAN GetNextIndex, \r
+ IN BOOLEAN IgnoreInputIndex, \r
+ IN OUT PULONG ObjectIndex,\r
+ OUT PULONG DataWritten OPTIONAL)\r
+{\r
+ return(ZwQueryDirectoryObject(DirObjHandle,\r
+ DirObjInformation,\r
+ BufferLength,\r
+ GetNextIndex,\r
+ IgnoreInputIndex,\r
+ ObjectIndex,\r
+ DataWritten));\r
+}\r
+\r
+NTSTATUS ZwQueryDirectoryObject(IN HANDLE DirObjHandle,\r
+ OUT POBJDIR_INFORMATION DirObjInformation, \r
+ IN ULONG BufferLength, \r
+ IN BOOLEAN GetNextIndex, \r
+ IN BOOLEAN IgnoreInputIndex, \r
+ IN OUT PULONG ObjectIndex,\r
+ OUT PULONG DataWritten OPTIONAL)\r
+/*\r
+ * FUNCTION: Reads information from a namespace directory\r
+ * ARGUMENTS:\r
+ * DirObjInformation (OUT) = Buffer to hold the data read\r
+ * BufferLength = Size of the buffer in bytes\r
+ * GetNextIndex = If TRUE then set ObjectIndex to the index of the\r
+ * next object\r
+ * If FALSE then set ObjectIndex to the number of\r
+ * objects in the directory\r
+ * IgnoreInputIndex = If TRUE start reading at index 0\r
+ * If FALSE start reading at the index specified\r
+ * by object index\r
+ * ObjectIndex = Zero based index into the directory, interpretation\r
+ * depends on IgnoreInputIndex and GetNextIndex\r
+ * DataWritten (OUT) = Caller supplied storage for the number of bytes\r
+ * written (or NULL)\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PDIRECTORY_OBJECT dir = NULL;\r
+ ULONG EntriesToRead;\r
+ PLIST_ENTRY current_entry;\r
+ POBJECT_HEADER current;\r
+ ULONG i=0;\r
+ ULONG EntriesToSkip;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("ZwQueryDirectoryObject(DirObjHandle %x)\n",DirObjHandle);\r
+ DPRINT("dir %x namespc_root %x\n",dir,HEADER_TO_BODY(&(namespc_root.hdr)));\r
+ \r
+// assert_irql(PASSIVE_LEVEL);\r
+ \r
+ Status = ObReferenceObjectByHandle(DirObjHandle,\r
+ DIRECTORY_QUERY,\r
+ ObDirectoryType,\r
+ UserMode,\r
+ (PVOID*)&dir,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ EntriesToRead = BufferLength / sizeof(OBJDIR_INFORMATION);\r
+ *DataWritten = 0;\r
+ \r
+ DPRINT("EntriesToRead %d\n",EntriesToRead);\r
+ \r
+ current_entry = dir->head.Flink;\r
+ \r
+ /*\r
+ * Optionally, skip over some entries at the start of the directory\r
+ */\r
+ if (!IgnoreInputIndex)\r
+ {\r
+ CHECKPOINT;\r
+ \r
+ EntriesToSkip = *ObjectIndex;\r
+ while ( i<EntriesToSkip && current_entry!=NULL)\r
+ {\r
+ current_entry = current_entry->Flink;\r
+ }\r
+ }\r
+ \r
+ DPRINT("DirObjInformation %x\n",DirObjInformation);\r
+ \r
+ /*\r
+ * Read the maximum entries possible into the buffer\r
+ */\r
+ while ( i<EntriesToRead && current_entry!=(&(dir->head)))\r
+ {\r
+ current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);\r
+ DPRINT("Scanning %w\n",current->Name.Buffer);\r
+ DirObjInformation[i].ObjectName.Buffer = \r
+ ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);\r
+ DirObjInformation[i].ObjectName.Length = current->Name.Length;\r
+ DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;\r
+ DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",\r
+ DirObjInformation[i].ObjectName.Buffer);\r
+ RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,\r
+ &(current->Name));\r
+ i++;\r
+ current_entry = current_entry->Flink;\r
+ (*DataWritten) = (*DataWritten) + sizeof(OBJDIR_INFORMATION);\r
+ CHECKPOINT;\r
+ }\r
+ CHECKPOINT;\r
+ \r
+ /*\r
+ * Optionally, count the number of entries in the directory\r
+ */\r
+ if (GetNextIndex)\r
+ {\r
+ *ObjectIndex=i;\r
+ }\r
+ else\r
+ {\r
+ while ( current_entry!=(&(dir->head)) )\r
+ {\r
+ current_entry=current_entry->Flink;\r
+ i++;\r
+ }\r
+ *ObjectIndex=i;\r
+ }\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+\r
+NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectPath,\r
+ ULONG Attributes,\r
+ PACCESS_STATE PassedAccessState,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_TYPE ObjectType,\r
+ KPROCESSOR_MODE AccessMode,\r
+ PVOID ParseContext,\r
+ PVOID* ObjectPtr)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS ObOpenObjectByName(POBJECT_ATTRIBUTES ObjectAttributes,\r
+ PVOID* Object, PWSTR* UnparsedSection)\r
+{\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("ObOpenObjectByName(ObjectAttributes %x, Object %x)\n",\r
+ ObjectAttributes,Object);\r
+ DPRINT("ObjectAttributes = {ObjectName %x ObjectName->Buffer %w}\n",\r
+ ObjectAttributes->ObjectName,ObjectAttributes->ObjectName->Buffer);\r
+ DPRINT("ObjectAttributes->ObjectName->Length %d\n",\r
+ ObjectAttributes->ObjectName->Length);\r
+ \r
+ *Object = NULL;\r
+ Status = ObLookupObject(ObjectAttributes->RootDirectory, \r
+ ObjectAttributes->ObjectName->Buffer, \r
+ Object,\r
+ UnparsedSection,\r
+ ObjectAttributes->Attributes);\r
+ DPRINT("*Object %x\n",*Object);\r
+ DPRINT("ObjectAttributes->ObjectName->Length %d\n",\r
+ ObjectAttributes->ObjectName->Length);\r
+ return(Status);\r
+}\r
+\r
+void ObInit(void)\r
+/*\r
+ * FUNCTION: Initialize the object manager namespace\r
+ */\r
+{\r
+ ANSI_STRING AnsiString;\r
+ \r
+ ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));\r
+ \r
+ ObDirectoryType->TotalObjects = 0;\r
+ ObDirectoryType->TotalHandles = 0;\r
+ ObDirectoryType->MaxObjects = ULONG_MAX;\r
+ ObDirectoryType->MaxHandles = ULONG_MAX;\r
+ ObDirectoryType->PagedPoolCharge = 0;\r
+ ObDirectoryType->NonpagedPoolCharge = sizeof(DIRECTORY_OBJECT);\r
+ ObDirectoryType->Dump = NULL;\r
+ ObDirectoryType->Open = NULL;\r
+ ObDirectoryType->Close = NULL;\r
+ ObDirectoryType->Delete = NULL;\r
+ ObDirectoryType->Parse = NULL;\r
+ ObDirectoryType->Security = NULL;\r
+ ObDirectoryType->QueryName = NULL;\r
+ ObDirectoryType->OkayToClose = NULL;\r
+ \r
+ RtlInitAnsiString(&AnsiString,"Directory");\r
+ RtlAnsiStringToUnicodeString(&ObDirectoryType->TypeName,\r
+ &AnsiString,TRUE);\r
+ \r
+ ObInitializeObjectHeader(ObDirectoryType,NULL,&namespc_root.hdr);\r
+ InitializeListHead(&namespc_root.head);\r
+}\r
+\r
+NTSTATUS NtCreateDirectoryObject(PHANDLE DirectoryHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes)\r
+{\r
+ return(ZwCreateDirectoryObject(DirectoryHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes));\r
+}\r
+\r
+NTSTATUS ZwCreateDirectoryObject(PHANDLE DirectoryHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes)\r
+/*\r
+ * FUNCTION: Creates or opens a directory object (a container for other\r
+ * objects)\r
+ * ARGUMENTS:\r
+ * DirectoryHandle (OUT) = Caller supplied storage for the handle\r
+ * of the directory\r
+ * DesiredAccess = Access desired to the directory\r
+ * ObjectAttributes = Object attributes initialized with\r
+ * InitializeObjectAttributes\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PDIRECTORY_OBJECT dir;\r
+ \r
+ dir = ObGenericCreateObject(DirectoryHandle,DesiredAccess,ObjectAttributes,\r
+ ObDirectoryType);\r
+ \r
+ /*\r
+ * Initialize the object body\r
+ */\r
+ InitializeListHead(&dir->head);\r
+ KeInitializeSpinLock(&(dir->Lock));\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+VOID InitializeObjectAttributes(POBJECT_ATTRIBUTES InitializedAttributes,\r
+ PUNICODE_STRING ObjectName,\r
+ ULONG Attributes,\r
+ HANDLE RootDirectory,\r
+ PSECURITY_DESCRIPTOR SecurityDescriptor)\r
+/*\r
+ * FUNCTION: Sets up a parameter of type OBJECT_ATTRIBUTES for a \r
+ * subsequent call to ZwCreateXXX or ZwOpenXXX\r
+ * ARGUMENTS:\r
+ * InitializedAttributes (OUT) = Caller supplied storage for the\r
+ * object attributes\r
+ * ObjectName = Full path name for object\r
+ * Attributes = Attributes for the object\r
+ * RootDirectory = Where the object should be placed or NULL\r
+ * SecurityDescriptor = Ignored\r
+ * \r
+ * NOTE:\r
+ * Either ObjectName is a fully qualified pathname or a path relative\r
+ * to RootDirectory\r
+ */\r
+{\r
+ DPRINT("InitializeObjectAttributes(InitializedAttributes %x "\r
+ "ObjectName %x Attributes %x RootDirectory %x)\n",\r
+ InitializedAttributes,ObjectName,Attributes,RootDirectory);\r
+ InitializedAttributes->Length=sizeof(OBJECT_ATTRIBUTES);\r
+ InitializedAttributes->RootDirectory=RootDirectory;\r
+ InitializedAttributes->ObjectName=ObjectName;\r
+ InitializedAttributes->Attributes=Attributes;\r
+ InitializedAttributes->SecurityDescriptor=SecurityDescriptor;\r
+ InitializedAttributes->SecurityQualityOfService=NULL;\r
+}\r
+\r
+static PVOID ObDirLookup(PDIRECTORY_OBJECT dir, PWSTR name,\r
+ ULONG Attributes)\r
+/*\r
+ * FUNCTION: Looks up an entry within a namespace directory\r
+ * ARGUMENTS:\r
+ * dir = Directory to lookup in\r
+ * name = Entry name to find\r
+ * RETURNS: A pointer to the object body if found\r
+ * NULL otherwise\r
+ */\r
+{\r
+ LIST_ENTRY* current = dir->head.Flink;\r
+ POBJECT_HEADER current_obj;\r
+ \r
+ DPRINT("ObDirLookup(dir %x, name %w)\n",dir,name);\r
+ \r
+ if (name[0]==0)\r
+ {\r
+ return(dir);\r
+ }\r
+ if (name[0]=='.'&&name[1]==0)\r
+ {\r
+ return(dir);\r
+ }\r
+ if (name[0]=='.'&&name[1]=='.'&&name[2]==0)\r
+ {\r
+ return(BODY_TO_HEADER(dir)->Parent);\r
+ }\r
+ while (current!=(&(dir->head)))\r
+ {\r
+ current_obj = CONTAINING_RECORD(current,OBJECT_HEADER,Entry);\r
+ DPRINT("Scanning %w\n",current_obj->Name.Buffer);\r
+ if (Attributes & OBJ_CASE_INSENSITIVE)\r
+ {\r
+ if (wcsicmp(current_obj->Name.Buffer, name)==0)\r
+ {\r
+ DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));\r
+ return(HEADER_TO_BODY(current_obj));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if ( wcscmp(current_obj->Name.Buffer, name)==0)\r
+ {\r
+ DPRINT("Found it %x\n",HEADER_TO_BODY(current_obj));\r
+ return(HEADER_TO_BODY(current_obj));\r
+ }\r
+ }\r
+ current = current->Flink;\r
+ }\r
+ DPRINT("%s() = NULL\n",__FUNCTION__);\r
+ return(NULL);\r
+}\r
+\r
+VOID ObRemoveEntry(POBJECT_HEADER Header)\r
+{\r
+ KIRQL oldlvl;\r
+ \r
+ DPRINT("ObRemoveEntry(Header %x)\n",Header);\r
+ \r
+ KeAcquireSpinLock(&(Header->Parent->Lock),&oldlvl);\r
+ RemoveEntryList(&(Header->Entry));\r
+ KeReleaseSpinLock(&(Header->Parent->Lock),oldlvl);\r
+}\r
+\r
+VOID ObCreateEntry(PDIRECTORY_OBJECT parent,POBJECT_HEADER Object)\r
+/*\r
+ * FUNCTION: Add an entry to a namespace directory\r
+ * ARGUMENTS:\r
+ * parent = directory to add in\r
+ * name = Name to give the entry\r
+ * Object = Header of the object to add the entry for\r
+ */\r
+{\r
+ DPRINT("ObjCreateEntry(%x,%x,%x,%w)\n",parent,Object,Object->Name.Buffer,\r
+ Object->Name.Buffer);\r
+ \r
+ /*\r
+ * Insert ourselves in our parents list\r
+ */\r
+ InsertTailList(&parent->head,&Object->Entry);\r
+}\r
+\r
+NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object,\r
+ PWSTR* UnparsedSection, ULONG Attributes)\r
+/*\r
+ * FUNCTION: Lookup an object within the system namespc\r
+ * ARGUMENTS:\r
+ * root = Directory to start lookup from\r
+ * _string = Pathname to lookup\r
+ * RETURNS: On success a pointer to the object body\r
+ * On failure NULL\r
+ */\r
+{\r
+ PWSTR current;\r
+ PWSTR next;\r
+ PDIRECTORY_OBJECT current_dir = NULL;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("ObLookupObject(rootdir %x, string %x, string %w, Object %x, "\r
+ "UnparsedSection %x)\n",rootdir,string,string,Object,\r
+ UnparsedSection);\r
+ \r
+ \r
+ *UnparsedSection = NULL;\r
+ *Object = NULL;\r
+ \r
+ if (rootdir==NULL)\r
+ {\r
+ current_dir = HEADER_TO_BODY(&(namespc_root.hdr));\r
+ }\r
+ else\r
+ {\r
+ ObReferenceObjectByHandle(rootdir,DIRECTORY_TRAVERSE,NULL,\r
+ UserMode,(PVOID*)¤t_dir,NULL);\r
+ }\r
+ \r
+ /*\r
+ * Bit of a hack this\r
+ */\r
+ if (string[0]==0)\r
+ {\r
+ *Object=current_dir;\r
+ return(STATUS_SUCCESS);\r
+ }\r
+\r
+ if (string[0]!='\\')\r
+ {\r
+ DbgPrint("(%s:%d) Non absolute pathname passed to %s\n",__FILE__,\r
+ __LINE__,__FUNCTION__);\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ \r
+ next = &string[0];\r
+ current = next+1;\r
+ \r
+ while (next!=NULL && \r
+ BODY_TO_HEADER(current_dir)->ObjectType==ObDirectoryType)\r
+ { \r
+ *next = '\\';\r
+ current = next+1;\r
+ next = wcschr(next+1,'\\');\r
+ if (next!=NULL)\r
+ {\r
+ *next=0;\r
+ }\r
+\r
+ DPRINT("current %w current[5] %x next %x ",current,current[5],next);\r
+ if (next!=NULL)\r
+ {\r
+ DPRINT("(next+1) %w",next+1);\r
+ }\r
+ DPRINT("\n",0);\r
+ \r
+ current_dir=(PDIRECTORY_OBJECT)ObDirLookup(current_dir,current,\r
+ Attributes);\r
+ if (current_dir==NULL)\r
+ {\r
+ DbgPrint("(%s:%d) Path component %w not found\n",__FILE__,\r
+ __LINE__,current);\r
+ return(STATUS_UNSUCCESSFUL); \r
+ }\r
+ \r
+ if (BODY_TO_HEADER(current_dir)->ObjectType==IoSymbolicLinkType)\r
+ {\r
+ current_dir = IoOpenSymlink(current_dir); \r
+ }\r
+ \r
+ }\r
+ DPRINT("next %x\n",next);\r
+ DPRINT("current %x current %w\n",current,current);\r
+ if (next==NULL)\r
+ {\r
+ if (current_dir==NULL)\r
+ {\r
+ Status = STATUS_UNSUCCESSFUL;\r
+ }\r
+ else\r
+ {\r
+ Status = STATUS_SUCCESS;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ CHECKPOINT;\r
+ *next = '\\';\r
+ *UnparsedSection = next;\r
+ if (BODY_TO_HEADER(current_dir)->ObjectType == IoDeviceType)\r
+ {\r
+ Status = STATUS_FS_QUERY_REQUIRED;\r
+ }\r
+ else\r
+ {\r
+ Status = STATUS_UNSUCCESSFUL;\r
+ } \r
+ }\r
+ CHECKPOINT;\r
+ *Object = current_dir;\r
+ DPRINT("(%s:%d) current_dir %x\n",__FILE__,__LINE__,current_dir);\r
+\r
+ return(Status);\r
+}\r
+ \r
-/*
- * 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);
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/ob/object.c\r
+ * PURPOSE: Implements generic object managment functions\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * UPDATE HISTORY:\r
+ * 10/06/98: Created\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <ddk/ntddk.h>\r
+#include <internal/ob.h>\r
+#include <wstring.h>\r
+#include <string.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* FUNCTIONS ************************************************************/\r
+\r
+NTSTATUS STDCALL NtSetInformationObject(IN HANDLE ObjectHandle,\r
+ IN CINT ObjectInformationClass,\r
+ IN PVOID ObjectInformation,\r
+ IN ULONG Length)\r
+{\r
+ return(ZwSetInformationObject(ObjectHandle,\r
+ ObjectInformationClass,\r
+ ObjectInformation,\r
+ Length));\r
+}\r
+\r
+NTSTATUS STDCALL ZwSetInformationObject(IN HANDLE ObjectHandle,\r
+ IN CINT ObjectInformationClass,\r
+ IN PVOID ObjectInformation,\r
+ IN ULONG Length)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtQueryObject(IN HANDLE ObjectHandle,\r
+ IN CINT ObjectInformationClass,\r
+ OUT PVOID ObjectInformation,\r
+ IN ULONG Length,\r
+ OUT PULONG ResultLength)\r
+{\r
+ return(ZwQueryObject(ObjectHandle,\r
+ ObjectInformationClass,\r
+ ObjectInformation,\r
+ Length,\r
+ ResultLength));\r
+}\r
+\r
+NTSTATUS STDCALL ZwQueryObject(IN HANDLE ObjectHandle,\r
+ IN CINT ObjectInformationClass,\r
+ OUT PVOID ObjectInformation,\r
+ IN ULONG Length,\r
+ OUT PULONG ResultLength)\r
+{\r
+ UNIMPLEMENTED\r
+}\r
+\r
+NTSTATUS NtMakeTemporaryObject(HANDLE Handle)\r
+{\r
+ return(ZwMakeTemporaryObject(Handle));\r
+}\r
+\r
+NTSTATUS ZwMakeTemporaryObject(HANDLE Handle)\r
+{\r
+ PVOID Object;\r
+ NTSTATUS Status; \r
+ POBJECT_HEADER ObjectHeader;\r
+ \r
+ Status = ObReferenceObjectByHandle(Handle,\r
+ 0,\r
+ NULL,\r
+ KernelMode,\r
+ &Object,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+\r
+ ObjectHeader = BODY_TO_HEADER(Object);\r
+ ObjectHeader->Permanent = FALSE;\r
+ \r
+ ObDereferenceObject(Object);\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+PVOID ObGenericCreateObject(PHANDLE Handle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes,\r
+ POBJECT_TYPE Type)\r
+{\r
+ POBJECT_HEADER hdr = NULL;\r
+ PWSTR path;\r
+ PWSTR name;\r
+ PWSTR Ignored;\r
+ PULONG addr;\r
+ PWSTR Buffer;\r
+ \r
+ DPRINT("ObGenericCreateObject(Handle %x, DesiredAccess %x,"\r
+ "ObjectAttributes %x, Type %x)\n",Handle,DesiredAccess,\r
+ ObjectAttributes,Type);\r
+ \r
+ /*\r
+ * Allocate the object body and header\r
+ */\r
+ hdr=(POBJECT_HEADER)ExAllocatePool(NonPagedPool,OBJECT_ALLOC_SIZE(Type));\r
+ DPRINT("OBJECT_ALLOC_SIZE(Type) %d\n",OBJECT_ALLOC_SIZE(Type));\r
+ if (hdr==NULL)\r
+ {\r
+ return(NULL);\r
+ }\r
+ DPRINT("hdr %x\n",hdr);\r
+\r
+\r
+ /*\r
+ * If unnamed then initalize\r
+ */\r
+ if (ObjectAttributes==NULL || ObjectAttributes->ObjectName==NULL)\r
+ {\r
+ ObInitializeObjectHeader(Type,NULL,hdr);\r
+ if (Handle != NULL)\r
+ {\r
+ *Handle = ObInsertHandle(KeGetCurrentProcess(),\r
+ HEADER_TO_BODY(hdr),\r
+ DesiredAccess,\r
+ FALSE);\r
+ }\r
+ return(HEADER_TO_BODY(hdr));\r
+ }\r
+\r
+ \r
+ /*\r
+ * Copy the object name into a buffer\r
+ */\r
+// DbgPrint("ObjectAttributes->ObjectName %x\n",ObjectAttributes->ObjectName);\r
+// DbgPrint("ObjectAttributes->ObjectName->Length %d\n",\r
+// ObjectAttributes->ObjectName->Length);\r
+// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",\r
+// ObjectAttributes->ObjectName->MaximumLength);\r
+ Buffer = ExAllocatePool(NonPagedPool,\r
+ ((ObjectAttributes->ObjectName->Length+1)*2)); \r
+ if (Buffer==NULL)\r
+ {\r
+ return(NULL); \r
+ }\r
+ memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,\r
+ (ObjectAttributes->ObjectName->Length+1)*2);\r
+ \r
+ /*\r
+ * Seperate the name into a path and name \r
+ */\r
+ name = wcsrchr(Buffer,'\\');\r
+ if (name==NULL)\r
+ {\r
+ name=Buffer;\r
+ path=NULL;\r
+ }\r
+ else\r
+ {\r
+ path=Buffer;\r
+ *name=0;\r
+ name=name+1;\r
+ }\r
+ DPRINT("name %w path %w\n",name,path);\r
+ \r
+ ObLookupObject(ObjectAttributes->RootDirectory,\r
+ path,\r
+ &hdr->Parent,\r
+ &Ignored, \r
+ 0L);\r
+\r
+ /*\r
+ * Initialize the object header\r
+ */\r
+ ObInitializeObjectHeader(Type,name,hdr);\r
+\r
+\r
+ ObCreateEntry(hdr->Parent,hdr);\r
+\r
+ DPRINT("Handle %x\n",Handle);\r
+ if (Handle != NULL)\r
+ {\r
+ *Handle = ObInsertHandle(KeGetCurrentProcess(),\r
+ HEADER_TO_BODY(hdr),\r
+ DesiredAccess,\r
+ FALSE);\r
+ }\r
+ \r
+ return(HEADER_TO_BODY(hdr));\r
+}\r
+\r
+VOID ObInitializeObjectHeader(POBJECT_TYPE Type, PWSTR name,\r
+ POBJECT_HEADER ObjectHeader)\r
+/*\r
+ * FUNCTION: Creates a new object\r
+ * ARGUMENT:\r
+ * id = Identifier for the type of object\r
+ * obj = Pointer to the header of the object\r
+ */\r
+{\r
+ PWSTR temp_name;\r
+ extern unsigned long long ticks;\r
+ \r
+ DPRINT("ObInitializeObjectHeader(id %x name %w obj %x)\n",Type,\r
+ name,ObjectHeader);\r
+\r
+ ObjectHeader->HandleCount = 0;\r
+ ObjectHeader->RefCount = 0;\r
+ ObjectHeader->ObjectType = Type;\r
+ ObjectHeader->Permanent = FALSE;\r
+ if (name==NULL)\r
+ {\r
+ ObjectHeader->Name.Length=0;\r
+ ObjectHeader->Name.Buffer=NULL;\r
+ }\r
+ else\r
+ {\r
+ RtlInitUnicodeString(&(ObjectHeader->Name),name);\r
+ }\r
+}\r
+\r
+\r
+NTSTATUS ObReferenceObjectByPointer(PVOID ObjectBody,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_TYPE ObjectType,\r
+ KPROCESSOR_MODE AccessMode)\r
+/*\r
+ * FUNCTION: Increments the pointer reference count for a given object\r
+ * ARGUMENTS:\r
+ * ObjectBody = Object's body\r
+ * DesiredAccess = Desired access to the object\r
+ * ObjectType = Points to the object type structure\r
+ * AccessMode = Type of access check to perform\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ POBJECT_HEADER Object;\r
+\r
+ DPRINT("ObReferenceObjectByPointer(%x)\n",ObjectBody);\r
+ \r
+ Object = BODY_TO_HEADER(ObjectBody);\r
+ Object->RefCount++;\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)\r
+{\r
+ if (Header->RefCount == 0 && Header->HandleCount == 0 &&\r
+ !Header->Permanent)\r
+ {\r
+ ObRemoveEntry(Header);\r
+ ExFreePool(Header);\r
+ }\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+VOID ObDereferenceObject(PVOID ObjectBody)\r
+/*\r
+ * FUNCTION: Decrements a given object's reference count and performs\r
+ * retention checks\r
+ * ARGUMENTS:\r
+ * ObjectBody = Body of the object\r
+ */\r
+{\r
+ POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);\r
+ Header->RefCount--;\r
+ ObPerformRetentionChecks(Header);\r
+}\r
+\r
+\r
+NTSTATUS NtClose(HANDLE Handle)\r
+{\r
+ return(ZwClose(Handle));\r
+}\r
+\r
+NTSTATUS ZwClose(HANDLE Handle)\r
+/*\r
+ * FUNCTION: Closes a handle reference to an object\r
+ * ARGUMENTS:\r
+ * Handle = handle to close\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PVOID ObjectBody;\r
+ POBJECT_HEADER Header;\r
+ PHANDLE_REP HandleRep;\r
+ \r
+ assert_irql(PASSIVE_LEVEL);\r
+ \r
+ HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);\r
+ if (HandleRep == NULL)\r
+ {\r
+ return(STATUS_INVALID_HANDLE);\r
+ } \r
+ ObjectBody = HandleRep->ObjectBody;\r
+ \r
+ HandleRep->ObjectBody = NULL;\r
+ \r
+ Header = BODY_TO_HEADER(ObjectBody);\r
+ \r
+ Header->HandleCount--;\r
+ ObPerformRetentionChecks(Header);\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS ObReferenceObjectByHandle(HANDLE Handle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_TYPE ObjectType,\r
+ KPROCESSOR_MODE AccessMode,\r
+ PVOID* Object,\r
+ POBJECT_HANDLE_INFORMATION \r
+ HandleInformationPtr\r
+ )\r
+/*\r
+ * FUNCTION: Increments the reference count for an object and returns a \r
+ * pointer to its body\r
+ * ARGUMENTS:\r
+ * Handle = Handle for the object\r
+ * DesiredAccess = Desired access to the object\r
+ * ObjectType\r
+ * AccessMode \r
+ * Object (OUT) = Points to the object body on return\r
+ * HandleInformation (OUT) = Contains information about the handle \r
+ * on return\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PHANDLE_REP HandleRep;\r
+ POBJECT_HEADER ObjectHeader;\r
+ \r
+ ASSERT_IRQL(PASSIVE_LEVEL);\r
+ \r
+ DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "\r
+ "ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,\r
+ ObjectType,AccessMode,Object);\r
+ \r
+ if (Handle == NtCurrentProcess())\r
+ {\r
+ *Object = PsGetCurrentProcess();\r
+ return(STATUS_SUCCESS);\r
+ }\r
+ if (Handle == NtCurrentThread())\r
+ {\r
+ *Object = PsGetCurrentThread();\r
+ return(STATUS_SUCCESS);\r
+ }\r
+ \r
+ HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);\r
+ if (HandleRep == NULL || HandleRep->ObjectBody == NULL)\r
+ {\r
+ return(STATUS_INVALID_HANDLE);\r
+ }\r
+ \r
+ ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody);\r
+ \r
+ if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)\r
+ {\r
+ return(STATUS_UNSUCCESSFUL);\r
+ } \r
+ \r
+ if (!(HandleRep->GrantedAccess & DesiredAccess))\r
+ {\r
+ return(STATUS_ACCESS_DENIED);\r
+ }\r
+ \r
+ ObjectHeader->RefCount++;\r
+ \r
+ *Object = HandleRep->ObjectBody;\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+++ /dev/null
- .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"
/*
* 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
*/
#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,
}
}
+VOID PsReleaseThread(PETHREAD Thread)
+{
+ DPRINT("PsReleaseThread(Thread %x)\n",Thread);
+
+ RemoveEntryList(&Thread->Tcb.Entry);
+ ExFreePool(Thread);
+}
+
NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
/*
KIRQL oldlvl;
PETHREAD CurrentThread;
+ PiNrThreads--;
+
CurrentThread = PsGetCurrentThread();
CurrentThread->ExitStatus = ExitStatus;
DPRINT("terminating %x\n",CurrentThread);
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
- RemoveEntryList(&CurrentThread->Tcb.Entry);
ZwYieldExecution();
for(;;);
}
-/*
- * 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;
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/ps/process.c\r
+ * PURPOSE: Process managment\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * REVISION HISTORY:\r
+ * 21/07/98: Created\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ddk/ntddk.h>\r
+#include <internal/ob.h>\r
+#include <internal/mm.h>\r
+#include <internal/string.h>\r
+\r
+//#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS ******************************************************************/\r
+\r
+PEPROCESS SystemProcess = NULL;\r
+HANDLE SystemProcessHandle = NULL;\r
+\r
+POBJECT_TYPE PsProcessType = NULL;\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+VOID PsInitProcessManagment(VOID)\r
+{\r
+ ANSI_STRING AnsiString;\r
+ PKPROCESS KProcess;\r
+ \r
+ /*\r
+ * Register the process object type\r
+ */ \r
+ \r
+ PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));\r
+ \r
+ PsProcessType->TotalObjects = 0;\r
+ PsProcessType->TotalHandles = 0;\r
+ PsProcessType->MaxObjects = ULONG_MAX;\r
+ PsProcessType->MaxHandles = ULONG_MAX;\r
+ PsProcessType->PagedPoolCharge = 0;\r
+ PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);\r
+ PsProcessType->Dump = NULL;\r
+ PsProcessType->Open = NULL;\r
+ PsProcessType->Close = NULL;\r
+ PsProcessType->Delete = NULL;\r
+ PsProcessType->Parse = NULL;\r
+ PsProcessType->Security = NULL;\r
+ PsProcessType->QueryName = NULL;\r
+ PsProcessType->OkayToClose = NULL;\r
+ \r
+ RtlInitAnsiString(&AnsiString,"Process");\r
+ RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);\r
+ \r
+ /*\r
+ * Initialize the system process\r
+ */\r
+ SystemProcess = ObGenericCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,\r
+ PsProcessType);\r
+ KProcess = &SystemProcess->Pcb; \r
+ \r
+ InitializeListHead(&(KProcess->MemoryAreaList));\r
+ ObInitializeHandleTable(NULL,FALSE,KProcess);\r
+ KProcess->PageTableDirectory = get_page_directory();\r
+ \r
+ SystemProcessHandle = ObInsertHandle(KProcess,SystemProcess,\r
+ PROCESS_ALL_ACCESS,FALSE); \r
+}\r
+\r
+PKPROCESS KeGetCurrentProcess(VOID)\r
+/*\r
+ * FUNCTION: Returns a pointer to the current process\r
+ */\r
+{\r
+ return(&(PsGetCurrentProcess()->Pcb));\r
+}\r
+\r
+struct _EPROCESS* PsGetCurrentProcess(VOID)\r
+/*\r
+ * FUNCTION: Returns a pointer to the current process\r
+ */\r
+{\r
+ if (PsGetCurrentThread()==NULL \r
+ || PsGetCurrentThread()->ThreadsProcess==NULL)\r
+ {\r
+ return(SystemProcess);\r
+ }\r
+ else\r
+ {\r
+ return(PsGetCurrentThread()->ThreadsProcess);\r
+ }\r
+}\r
+\r
+NTSTATUS STDCALL NtCreateProcess(\r
+ OUT PHANDLE ProcessHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r
+ IN HANDLE ParentProcessHandle,\r
+ IN BOOLEAN InheritObjectTable,\r
+ IN HANDLE SectionHandle OPTIONAL,\r
+ IN HANDLE DebugPort OPTIONAL,\r
+ IN HANDLE ExceptionPort OPTIONAL)\r
+{\r
+ return(ZwCreateProcess(ProcessHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes,\r
+ ParentProcessHandle,\r
+ InheritObjectTable,\r
+ SectionHandle,\r
+ DebugPort,\r
+ ExceptionPort));\r
+}\r
+\r
+NTSTATUS STDCALL ZwCreateProcess(\r
+ OUT PHANDLE ProcessHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\r
+ IN HANDLE ParentProcessHandle,\r
+ IN BOOLEAN InheritObjectTable,\r
+ IN HANDLE SectionHandle OPTIONAL,\r
+ IN HANDLE DebugPort OPTIONAL,\r
+ IN HANDLE ExceptionPort OPTIONAL)\r
+/*\r
+ * FUNCTION: Creates a process.\r
+ * ARGUMENTS:\r
+ * ProcessHandle (OUT) = Caller supplied storage for the resulting \r
+ * handle\r
+ * DesiredAccess = Specifies the allowed or desired access to the \r
+ * process can be a combination of \r
+ * STANDARD_RIGHTS_REQUIRED| .. \r
+ * ObjectAttribute = Initialized attributes for the object, contains \r
+ * the rootdirectory and the filename\r
+ * ParentProcess = Handle to the parent process.\r
+ * InheritObjectTable = Specifies to inherit the objects of the parent \r
+ * process if true.\r
+ * SectionHandle = Handle to a section object to back the image file\r
+ * DebugPort = Handle to a DebugPort if NULL the system default debug \r
+ * port will be used.\r
+ * ExceptionPort = Handle to a exception port. \r
+ * REMARKS:\r
+ * This function maps to the win32 CreateProcess. \r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PEPROCESS Process;\r
+ PEPROCESS ParentProcess;\r
+ PULONG PageDirectory;\r
+ PULONG CurrentPageDirectory;\r
+ ULONG i;\r
+ PKPROCESS KProcess;\r
+ ULONG Base;\r
+ ULONG Length;\r
+ LARGE_INTEGER Offset;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);\r
+\r
+ Status = ObReferenceObjectByHandle(ParentProcessHandle,\r
+ PROCESS_CREATE_PROCESS,\r
+ PsProcessType,\r
+ UserMode,\r
+ &ParentProcessHandle,\r
+ NULL);\r
+\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ DPRINT("ZwCreateProcess() = %x\n",Status);\r
+ return(Status);\r
+ }\r
+\r
+ Process = ObGenericCreateObject(ProcessHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes,\r
+ PsProcessType);\r
+ KProcess = &(Process->Pcb);\r
+ \r
+ InitializeListHead(&(KProcess->MemoryAreaList));\r
+ ObInitializeHandleTable(KProcess,InheritObjectTable,KProcess);\r
+ \r
+ PageDirectory = physical_to_linear((ULONG)get_free_page());\r
+ KProcess->PageTableDirectory = PageDirectory;\r
+ \r
+ CurrentPageDirectory = get_page_directory();\r
+ \r
+ memset(PageDirectory,0,PAGESIZE);\r
+ for (i=768;i<1024;i++)\r
+ {\r
+ PageDirectory[i]=CurrentPageDirectory[i];\r
+ }\r
+ \r
+ /*\r
+ * FIXME: I don't what I'm supposed to know with a section handle\r
+ */\r
+ if (SectionHandle != NULL)\r
+ {\r
+ DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");\r
+ return(STATUS_UNSUCCESSFUL);\r
+ }\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+\r
+NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,\r
+ IN NTSTATUS ExitStatus)\r
+{\r
+ return(ZwTerminateProcess(ProcessHandle,ExitStatus));\r
+}\r
+\r
+NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,\r
+ IN NTSTATUS ExitStatus)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+\r
+NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes,\r
+ IN PCLIENT_ID ClientId)\r
+{\r
+ return(ZwOpenProcess(ProcessHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes,\r
+ ClientId));\r
+}\r
+\r
+NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes,\r
+ IN PCLIENT_ID ClientId)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtQueryInformationProcess(\r
+ IN HANDLE ProcessHandle,\r
+ IN CINT ProcessInformationClass,\r
+ OUT PVOID ProcessInformation,\r
+ IN ULONG ProcessInformationLength,\r
+ OUT PULONG ReturnLength)\r
+{\r
+ return(ZwQueryInformationProcess(ProcessHandle,\r
+ ProcessInformationClass,\r
+ ProcessInformation,\r
+ ProcessInformationLength,\r
+ ReturnLength));\r
+}\r
+\r
+NTSTATUS STDCALL ZwQueryInformationProcess(\r
+ IN HANDLE ProcessHandle,\r
+ IN CINT ProcessInformationClass,\r
+ OUT PVOID ProcessInformation,\r
+ IN ULONG ProcessInformationLength,\r
+ OUT PULONG ReturnLength)\r
+{\r
+ PEPROCESS Process;\r
+ NTSTATUS Status;\r
+ \r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_QUERY_INFORMATION,\r
+ PsProcessType,\r
+ UserMode,\r
+ &ProcessHandle,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ switch (ProcessInformationClass)\r
+ {\r
+ case ProcessBasicInformation:\r
+ case ProcessQuotaLimits:\r
+ case ProcessIoCounters:\r
+ case ProcessVmCounters:\r
+ case ProcessTimes:\r
+ case ProcessBasePriority:\r
+ case ProcessRaisePriority:\r
+ case ProcessDebugPort:\r
+ case ProcessExceptionPort:\r
+ case ProcessAccessToken:\r
+ case ProcessLdtInformation:\r
+ case ProcessLdtSize:\r
+ case ProcessDefaultHardErrorMode:\r
+ case ProcessIoPortHandlers:\r
+ case ProcessWorkingSetWatch:\r
+ case ProcessUserModeIOPL:\r
+ case ProcessEnableAlignmentFaultFixup:\r
+ case ProcessPriorityClass:\r
+ case ProcessWx86Information:\r
+ case ProcessHandleCount:\r
+ case ProcessAffinityMask:\r
+ default:\r
+ Status = STATUS_NOT_IMPLEMENTED;\r
+ }\r
+ return(Status);\r
+}\r
+\r
+NTSTATUS\r
+STDCALL\r
+NtSetInformationProcess(\r
+ IN HANDLE ProcessHandle,\r
+ IN CINT ProcessInformationClass,\r
+ IN PVOID ProcessInformation,\r
+ IN ULONG ProcessInformationLength\r
+ )\r
+{\r
+ return(ZwSetInformationProcess(ProcessHandle,\r
+ ProcessInformationClass,\r
+ ProcessInformation,\r
+ ProcessInformationLength));\r
+}\r
+\r
+NTSTATUS\r
+STDCALL\r
+ZwSetInformationProcess(\r
+ IN HANDLE ProcessHandle,\r
+ IN CINT ProcessInformationClass,\r
+ IN PVOID ProcessInformation,\r
+ IN ULONG ProcessInformationLength\r
+ )\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ps/thread.c
- * PURPOSE: Thread managment
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * REVISION HISTORY:
- * 23/06/98: Created
- */
-
-/*
- * NOTE:
- *
- * All of the routines that manipulate the thread queue synchronize on
- * a single spinlock
- *
- */
-
-/* INCLUDES ****************************************************************/
-
-#include <windows.h>
-#include <ddk/ntddk.h>
-#include <internal/ke.h>
-#include <internal/ob.h>
-#include <internal/string.h>
-#include <internal/hal.h>
-#include <internal/ps.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* TYPES *******************************************************************/
-
-/* GLOBALS ******************************************************************/
-
-POBJECT_TYPE PsThreadType = NULL;
-
-#define NR_THREAD_PRIORITY_LEVELS (31)
-#define THREAD_PRIORITY_MAX (15)
-
-static KSPIN_LOCK ThreadListLock = {0,};
-
-/*
- * PURPOSE: List of threads associated with each priority level
- */
-static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]={{NULL,NULL},};
-static BOOLEAN DoneInitYet = FALSE;
-
-static PETHREAD CurrentThread = NULL;
-
-static ULONG NextThreadUniqueId = 0;
-
-/* FUNCTIONS ***************************************************************/
-
-PKTHREAD KeGetCurrentThread(VOID)
-{
- return(&(CurrentThread->Tcb));
-}
-
-PETHREAD PsGetCurrentThread(VOID)
-{
- return((PETHREAD)KeGetCurrentThread());
-}
-
-static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
-{
- KIRQL oldlvl;
-
- DPRINT("PsInsertIntoThreadList(Priority %d, Thread %x)\n",Priority,Thread);
-
- KeAcquireSpinLock(&ThreadListLock,&oldlvl);
- InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],
- &Thread->Tcb.Entry);
- KeReleaseSpinLock(&ThreadListLock,oldlvl);
-}
-
-VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
-{
- NTSTATUS Ret;
-
- KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
- Ret = StartRoutine(StartContext);
- PsTerminateSystemThread(Ret);
- for(;;);
-}
-
-static PETHREAD PsScanThreadList(KPRIORITY Priority)
-{
- PLIST_ENTRY current_entry;
- PETHREAD current;
- PETHREAD oldest = NULL;
- ULONG oldest_time = 0;
-
- DPRINT("PsScanThreadList(Priority %d)\n",Priority);
-
- current_entry = PriorityListHead[THREAD_PRIORITY_MAX+Priority].Flink;
- while (current_entry != &PriorityListHead[THREAD_PRIORITY_MAX+Priority])
- {
- current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);
- if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)
- {
- if (oldest == NULL || oldest_time > current->Tcb.LastTick)
- {
- oldest = current;
- oldest_time = current->Tcb.LastTick;
- }
- }
- current_entry = current_entry->Flink;
- }
- DPRINT("PsScanThreadList() = %x\n",oldest);
- return(oldest);
-}
-
-VOID PsDispatchThread(VOID)
-{
- KPRIORITY CurrentPriority;
- PETHREAD Candidate;
- KIRQL irql;
- LARGE_INTEGER TickCount;
-
- KeAcquireSpinLock(&ThreadListLock,&irql);
-
- if (!DoneInitYet)
- {
- return;
- }
-
- DPRINT("PsDispatchThread() Current %x\n",CurrentThread);
-
- if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING)
- {
- CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE;
- }
-
- for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL;
- CurrentPriority>=THREAD_PRIORITY_IDLE;
- CurrentPriority--)
- {
- Candidate = PsScanThreadList(CurrentPriority);
- if (Candidate == CurrentThread)
- {
- DPRINT("Scheduling current thread\n");
- KeQueryTickCount(&TickCount);
- CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
- CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
- KeReleaseSpinLock(&ThreadListLock,irql);
- return;
- }
- if (Candidate != NULL)
- {
- DPRINT("Scheduling %x\n",Candidate);
-
- Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
-
- KeQueryTickCount(&TickCount);
- CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
-
- CurrentThread = Candidate;
-
- HalTaskSwitch(&CurrentThread->Tcb);
- KeReleaseSpinLock(&ThreadListLock,irql);
- return;
- }
- }
-}
-
-NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
- PETHREAD* ThreadPtr,
- PHANDLE ThreadHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ThreadAttributes)
-{
- ULONG ThreadId;
- ULONG ProcessId;
- PETHREAD Thread;
- NTSTATUS Status;
-
- Thread = ObGenericCreateObject(ThreadHandle,
- DesiredAccess,
- ThreadAttributes,
- PsThreadType);
- DPRINT("Thread = %x\n",Thread);
- Thread->Tcb.LastTick = 0;
- Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED;
- Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL;
- Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL;
- Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));
- Thread->Tcb.SuspendCount = 1;
- if (ProcessHandle!=NULL)
- {
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_CREATE_THREAD,
- PsProcessType,
- UserMode,
- (PVOID*)&Thread->ThreadsProcess,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
- }
- else
- {
- Thread->ThreadsProcess=SystemProcess;
- }
- InitializeListHead(Thread->Tcb.ApcList);
- InitializeListHead(&(Thread->IrpList));
- Thread->Cid.UniqueThread=NextThreadUniqueId++;
-// thread->Cid.ThreadId=InterlockedIncrement(&NextThreadUniqueId);
- PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);
-
- *ThreadPtr = Thread;
-
- return(STATUS_SUCCESS);
-}
-
-VOID PsResumeThread(PETHREAD Thread)
-{
- DPRINT("PsResumeThread(Thread %x)\n",Thread);
-
- Thread->Tcb.SuspendCount--;
- DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount);
- DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n",
- Thread->Tcb.ThreadState,THREAD_STATE_RUNNING);
- if (Thread->Tcb.SuspendCount <= 0 &&
- Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)
- {
- DPRINT("Setting thread to runnable\n");
- Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
- }
- DPRINT("Finished PsResumeThread()\n");
-}
-
-VOID PsSuspendThread(PETHREAD Thread)
-{
- DPRINT("PsSuspendThread(Thread %x)\n",Thread);
- Thread->Tcb.SuspendCount++;
- if (Thread->Tcb.SuspendCount > 0)
- {
- Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
- if (Thread == CurrentThread)
- {
- PsDispatchThread();
- }
- }
-}
-
-void PsInitThreadManagment(void)
-/*
- * FUNCTION: Initialize thread managment
- */
-{
- PETHREAD FirstThread;
- ULONG i;
- ANSI_STRING AnsiString;
- HANDLE FirstThreadHandle;
-
- KeInitializeSpinLock(&ThreadListLock);
- for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)
- {
- InitializeListHead(&PriorityListHead[i]);
- }
-
- PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
- RtlInitAnsiString(&AnsiString,"Thread");
- RtlAnsiStringToUnicodeString(&PsThreadType->TypeName,&AnsiString,TRUE);
-
- PsThreadType->TotalObjects = 0;
- PsThreadType->TotalHandles = 0;
- PsThreadType->MaxObjects = 0;
- PsThreadType->MaxHandles = 0;
- PsThreadType->PagedPoolCharge = 0;
- PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);
- PsThreadType->Dump = NULL;
- PsThreadType->Open = NULL;
- PsThreadType->Close = NULL;
- PsThreadType->Delete = NULL;
- PsThreadType->Parse = NULL;
- PsThreadType->Security = NULL;
- PsThreadType->QueryName = NULL;
- PsThreadType->OkayToClose = NULL;
-
- PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,
- THREAD_ALL_ACCESS,NULL);
- HalInitFirstTask(FirstThread);
- FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
- FirstThread->Tcb.SuspendCount = 0;
-
- DPRINT("FirstThread %x\n",FirstThread);
-
- CurrentThread = FirstThread;
-
- DoneInitYet = TRUE;
-}
-
-NTSTATUS NtCreateThread(PHANDLE ThreadHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- HANDLE ProcessHandle,
- PCLIENT_ID Client,
- PCONTEXT ThreadContext,
- PINITIAL_TEB InitialTeb,
- BOOLEAN CreateSuspended)
-{
- return(ZwCreateThread(ThreadHandle,
- DesiredAccess,
- ObjectAttributes,
- ProcessHandle,
- Client,
- ThreadContext,
- InitialTeb,
- CreateSuspended));
-}
-
-NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- HANDLE ProcessHandle,
- PCLIENT_ID Client,
- PCONTEXT ThreadContext,
- PINITIAL_TEB InitialTeb,
- BOOLEAN CreateSuspended)
-{
- PETHREAD Thread;
- NTSTATUS Status;
-
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
- DesiredAccess,ObjectAttributes);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- HalInitTaskWithContext(Thread,ThreadContext);
- Thread->StartAddress=NULL;
-
- if (Client!=NULL)
- {
- *Client=Thread->Cid;
- }
-
- if (!CreateSuspended)
- {
- DPRINT("Not creating suspended\n");
- PsResumeThread(Thread);
- }
- DPRINT("Finished PsCreateThread()\n");
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,
- HANDLE ProcessHandle,
- PCLIENT_ID ClientId,
- PKSTART_ROUTINE StartRoutine,
- PVOID StartContext)
-/*
- * FUNCTION: Creates a thread which executes in kernel mode
- * ARGUMENTS:
- * ThreadHandle (OUT) = Caller supplied storage for the returned thread
- * handle
- * DesiredAccess = Requested access to the thread
- * ObjectAttributes = Object attributes (optional)
- * ProcessHandle = Handle of process thread will run in
- * NULL to use system process
- * ClientId (OUT) = Caller supplied storage for the returned client id
- * of the thread (optional)
- * StartRoutine = Entry point for the thread
- * StartContext = Argument supplied to the thread when it begins
- * execution
- * RETURNS: Success or failure status
- */
-{
- PETHREAD Thread;
- NTSTATUS Status;
-
- DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",
- ThreadHandle,ProcessHandle);
-
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
- DesiredAccess,ObjectAttributes);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- Thread->StartAddress=StartRoutine;
- HalInitTask(Thread,StartRoutine,StartContext);
-
- if (ClientId!=NULL)
- {
- *ClientId=Thread->Cid;
- }
-
- PsResumeThread(Thread);
-
- return(STATUS_SUCCESS);
-}
-
-LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment)
-{
- UNIMPLEMENTED;
-}
-
-KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)
-{
- KPRIORITY OldPriority;
- OldPriority = Thread->CurrentPriority;
- Thread->CurrentPriority = Priority;
-
- RemoveEntryList(&Thread->Entry);
- PsInsertIntoThreadList(Thread->CurrentPriority,
- CONTAINING_RECORD(Thread,ETHREAD,Tcb));
-
- return(OldPriority);
-}
-
-NTSTATUS STDCALL NtAlertResumeThread(IN HANDLE ThreadHandle,
- OUT PULONG SuspendCount)
-{
- return(ZwAlertResumeThread(ThreadHandle,SuspendCount));
-}
-
-NTSTATUS STDCALL ZwAlertResumeThread(IN HANDLE ThreadHandle,
- OUT PULONG SuspendCount)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtAlertThread(IN HANDLE ThreadHandle)
-{
- return(ZwAlertThread(ThreadHandle));
-}
-
-NTSTATUS STDCALL ZwAlertThread(IN HANDLE ThreadHandle)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtGetContextThread(IN HANDLE ThreadHandle,
- OUT PCONTEXT Context)
-{
- return(ZwGetContextThread(ThreadHandle,Context));
-}
-
-NTSTATUS STDCALL ZwGetContextThread(IN HANDLE ThreadHandle,
- OUT PCONTEXT Context)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId)
-{
- return(ZwOpenThread(ThreadHandle,
- DesiredAccess,
- ObjectAttributes,
- ClientId));
-}
-
-NTSTATUS STDCALL ZwOpenThread(OUT PHANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtResumeThread(IN HANDLE ThreadHandle,
- IN PULONG SuspendCount)
-{
- return(ZwResumeThread(ThreadHandle,SuspendCount));
-}
-
-NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle,
- IN PULONG SuspendCount)
-/*
- * FUNCTION: Decrements a thread's resume count
- * ARGUMENTS:
- * ThreadHandle = Handle to the thread that should be resumed
- * ResumeCount = The resulting resume count.
- * REMARK:
- * A thread is resumed if its suspend count is 0. This procedure maps to
- * the win32 ResumeThread function. ( documentation about the the suspend count can be found here aswell )
- * RETURNS: Status
- */
-{
- PETHREAD Thread;
- NTSTATUS Status;
-
- Status = ObReferenceObjectByHandle(ThreadHandle,
- THREAD_SUSPEND_RESUME,
- PsThreadType,
- UserMode,
- (PVOID*)&Thread,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- (*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);
- if (Thread->Tcb.SuspendCount <= 0)
- {
- Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
- }
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtSetContextThread(IN HANDLE ThreadHandle,
- IN PCONTEXT Context)
-{
- return(ZwSetContextThread(ThreadHandle,Context));
-}
-
-NTSTATUS STDCALL ZwSetContextThread(IN HANDLE ThreadHandle,
- IN PCONTEXT Context)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtSuspendThread(IN HANDLE ThreadHandle,
- IN PULONG PreviousSuspendCount)
-{
- return(ZwSuspendThread(ThreadHandle,PreviousSuspendCount));
-}
-
-NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle,
- IN PULONG PreviousSuspendCount)
-/*
- * FUNCTION: Increments a thread's suspend count
- * ARGUMENTS:
- * ThreadHandle = Handle to the thread that should be resumed
- * PreviousSuspendCount = The resulting/previous suspend count.
- * REMARK:
- * A thread will be suspended if its suspend count is greater than 0.
- * This procedure maps to the win32 SuspendThread function. (
- * documentation about the the suspend count can be found here aswell )
- * The suspend count is not increased if it is greater than
- * MAXIMUM_SUSPEND_COUNT.
- * RETURNS: Status
- */
-{
- PETHREAD Thread;
- NTSTATUS Status;
-
- Status = ObReferenceObjectByHandle(ThreadHandle,
- THREAD_SUSPEND_RESUME,
- PsThreadType,
- UserMode,
- (PVOID*)&Thread,
- NULL);
- if (Status != STATUS_SUCCESS)
- {
- return(Status);
- }
-
- (*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount);
- if (Thread->Tcb.SuspendCount > 0)
- {
- Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
- if (Thread == PsGetCurrentThread())
- {
- PsDispatchThread();
- }
- }
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtContinue(IN PCONTEXT Context, IN CINT IrqLevel)
-{
- return(ZwContinue(Context,IrqLevel));
-}
-
-NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtYieldExecution(VOID)
-{
- return(ZwYieldExecution());
-}
-
-NTSTATUS STDCALL ZwYieldExecution(VOID)
-{
- PsDispatchThread();
- return(STATUS_SUCCESS);
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/ps/thread.c\r
+ * PURPOSE: Thread managment\r
+ * PROGRAMMER: David Welch (welch@mcmail.com)\r
+ * REVISION HISTORY: \r
+ * 23/06/98: Created\r
+ */\r
+\r
+/*\r
+ * NOTE:\r
+ * \r
+ * All of the routines that manipulate the thread queue synchronize on\r
+ * a single spinlock\r
+ * \r
+ */\r
+\r
+/* INCLUDES ****************************************************************/\r
+\r
+#include <windows.h>\r
+#include <ddk/ntddk.h>\r
+#include <internal/ke.h>\r
+#include <internal/ob.h>\r
+#include <internal/string.h>\r
+#include <internal/hal.h>\r
+#include <internal/ps.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* TYPES *******************************************************************/\r
+\r
+/* GLOBALS ******************************************************************/\r
+\r
+POBJECT_TYPE PsThreadType = NULL;\r
+\r
+#define NR_THREAD_PRIORITY_LEVELS (31)\r
+#define THREAD_PRIORITY_MAX (15)\r
+\r
+static KSPIN_LOCK ThreadListLock = {0,};\r
+\r
+/*\r
+ * PURPOSE: List of threads associated with each priority level\r
+ */\r
+static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]={{NULL,NULL},};\r
+static BOOLEAN DoneInitYet = FALSE;\r
+ULONG PiNrThreads = 0;\r
+\r
+static PETHREAD CurrentThread = NULL;\r
+\r
+static ULONG NextThreadUniqueId = 0;\r
+\r
+/* FUNCTIONS ***************************************************************/\r
+\r
+PKTHREAD KeGetCurrentThread(VOID)\r
+{\r
+ return(&(CurrentThread->Tcb));\r
+}\r
+\r
+PETHREAD PsGetCurrentThread(VOID)\r
+{\r
+ return((PETHREAD)KeGetCurrentThread());\r
+}\r
+\r
+static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)\r
+{\r
+ KIRQL oldlvl;\r
+ \r
+ DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,\r
+ Thread);\r
+ \r
+ KeAcquireSpinLock(&ThreadListLock,&oldlvl);\r
+ InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],\r
+ &Thread->Tcb.Entry);\r
+ KeReleaseSpinLock(&ThreadListLock,oldlvl);\r
+}\r
+\r
+VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)\r
+{\r
+ NTSTATUS Ret;\r
+ \r
+ KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);\r
+ Ret = StartRoutine(StartContext);\r
+ PsTerminateSystemThread(Ret);\r
+ for(;;);\r
+}\r
+\r
+static PETHREAD PsScanThreadList(KPRIORITY Priority)\r
+{\r
+ PLIST_ENTRY current_entry;\r
+ PETHREAD current;\r
+ PETHREAD oldest = NULL;\r
+ ULONG oldest_time = 0;\r
+ \r
+// DPRINT("PsScanThreadList(Priority %d)\n",Priority);\r
+ \r
+ current_entry = PriorityListHead[THREAD_PRIORITY_MAX+Priority].Flink;\r
+ while (current_entry != &PriorityListHead[THREAD_PRIORITY_MAX+Priority])\r
+ {\r
+ current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);\r
+ #if 0\r
+ if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED &&\r
+ current != CurrentThread)\r
+ {\r
+ PsReleaseThread(CurrentThread);\r
+ }\r
+ #endif\r
+ if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)\r
+ {\r
+ if (oldest == NULL || oldest_time > current->Tcb.LastTick)\r
+ {\r
+ oldest = current;\r
+ oldest_time = current->Tcb.LastTick;\r
+ }\r
+ }\r
+ current_entry = current_entry->Flink;\r
+ }\r
+// DPRINT("PsScanThreadList() = %x\n",oldest);\r
+ return(oldest);\r
+}\r
+\r
+VOID PsDispatchThread(VOID)\r
+{\r
+ KPRIORITY CurrentPriority;\r
+ PETHREAD Candidate;\r
+ KIRQL irql;\r
+ LARGE_INTEGER TickCount;\r
+ \r
+ KeAcquireSpinLock(&ThreadListLock,&irql);\r
+ \r
+ if (!DoneInitYet)\r
+ {\r
+ return;\r
+ }\r
+ \r
+ DPRINT("PsDispatchThread() Current %x\n",CurrentThread);\r
+ \r
+ if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING) \r
+ {\r
+ CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE;\r
+ }\r
+ \r
+ for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL; \r
+ CurrentPriority>=THREAD_PRIORITY_IDLE;\r
+ CurrentPriority--)\r
+ {\r
+ Candidate = PsScanThreadList(CurrentPriority);\r
+ if (Candidate == CurrentThread)\r
+ {\r
+// DbgPrint("Scheduling current thread\n");\r
+ KeQueryTickCount(&TickCount);\r
+ CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);\r
+ CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
+ KeReleaseSpinLock(&ThreadListLock,irql);\r
+ return;\r
+ }\r
+ if (Candidate != NULL)\r
+ { \r
+// DbgPrint("Scheduling %x\n",Candidate);\r
+ \r
+ Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
+ \r
+ KeQueryTickCount(&TickCount);\r
+ CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);\r
+ \r
+ CurrentThread = Candidate;\r
+ \r
+ HalTaskSwitch(&CurrentThread->Tcb);\r
+ KeReleaseSpinLock(&ThreadListLock,irql);\r
+ return;\r
+ }\r
+ }\r
+}\r
+\r
+NTSTATUS PsInitializeThread(HANDLE ProcessHandle, \r
+ PETHREAD* ThreadPtr,\r
+ PHANDLE ThreadHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ThreadAttributes)\r
+{\r
+ ULONG ThreadId;\r
+ ULONG ProcessId;\r
+ PETHREAD Thread;\r
+ NTSTATUS Status;\r
+ \r
+ PiNrThreads++;\r
+ \r
+ Thread = ObGenericCreateObject(ThreadHandle,\r
+ DesiredAccess,\r
+ ThreadAttributes,\r
+ PsThreadType);\r
+ DPRINT("Thread = %x\n",Thread);\r
+ Thread->Tcb.LastTick = 0;\r
+ Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED;\r
+ Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL;\r
+ Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL;\r
+ Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));\r
+ Thread->Tcb.SuspendCount = 1;\r
+ if (ProcessHandle!=NULL)\r
+ {\r
+ Status = ObReferenceObjectByHandle(ProcessHandle,\r
+ PROCESS_CREATE_THREAD,\r
+ PsProcessType,\r
+ UserMode,\r
+ (PVOID*)&Thread->ThreadsProcess,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ Thread->ThreadsProcess=SystemProcess;\r
+ ObReferenceObjectByPointer(Thread->ThreadsProcess,\r
+ PROCESS_CREATE_THREAD,\r
+ PsProcessType,\r
+ UserMode);\r
+ }\r
+ ObReferenceObjectByPointer(Thread->ThreadsProcess,\r
+ PROCESS_CREATE_THREAD,\r
+ PsProcessType,\r
+ UserMode);\r
+ InitializeListHead(Thread->Tcb.ApcList);\r
+ InitializeListHead(&(Thread->IrpList));\r
+ Thread->Cid.UniqueThread=InterlockedIncrement(&NextThreadUniqueId);\r
+ PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);\r
+ \r
+ *ThreadPtr = Thread;\r
+ \r
+ ObDereferenceObject(Thread->ThreadsProcess); \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+VOID PsResumeThread(PETHREAD Thread)\r
+{\r
+ DPRINT("PsResumeThread(Thread %x)\n",Thread);\r
+ \r
+ Thread->Tcb.SuspendCount--;\r
+ DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount);\r
+ DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n",\r
+ Thread->Tcb.ThreadState,THREAD_STATE_RUNNING);\r
+ if (Thread->Tcb.SuspendCount <= 0 && \r
+ Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)\r
+ {\r
+ DPRINT("Setting thread to runnable\n");\r
+ Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;\r
+ }\r
+ DPRINT("Finished PsResumeThread()\n");\r
+}\r
+\r
+VOID PsSuspendThread(PETHREAD Thread)\r
+{\r
+ DPRINT("PsSuspendThread(Thread %x)\n",Thread);\r
+ Thread->Tcb.SuspendCount++;\r
+ if (Thread->Tcb.SuspendCount > 0)\r
+ {\r
+ Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;\r
+ if (Thread == CurrentThread)\r
+ {\r
+ PsDispatchThread();\r
+ }\r
+ }\r
+}\r
+\r
+void PsInitThreadManagment(void)\r
+/*\r
+ * FUNCTION: Initialize thread managment\r
+ */\r
+{\r
+ PETHREAD FirstThread;\r
+ ULONG i;\r
+ ANSI_STRING AnsiString;\r
+ HANDLE FirstThreadHandle;\r
+ \r
+ KeInitializeSpinLock(&ThreadListLock);\r
+ for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)\r
+ {\r
+ InitializeListHead(&PriorityListHead[i]);\r
+ }\r
+ \r
+ PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));\r
+ \r
+ RtlInitAnsiString(&AnsiString,"Thread");\r
+ RtlAnsiStringToUnicodeString(&PsThreadType->TypeName,&AnsiString,TRUE);\r
+ \r
+ PsThreadType->TotalObjects = 0;\r
+ PsThreadType->TotalHandles = 0;\r
+ PsThreadType->MaxObjects = 0;\r
+ PsThreadType->MaxHandles = 0;\r
+ PsThreadType->PagedPoolCharge = 0;\r
+ PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);\r
+ PsThreadType->Dump = NULL;\r
+ PsThreadType->Open = NULL;\r
+ PsThreadType->Close = NULL;\r
+ PsThreadType->Delete = NULL;\r
+ PsThreadType->Parse = NULL;\r
+ PsThreadType->Security = NULL;\r
+ PsThreadType->QueryName = NULL;\r
+ PsThreadType->OkayToClose = NULL;\r
+ \r
+ PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,\r
+ THREAD_ALL_ACCESS,NULL);\r
+ HalInitFirstTask(FirstThread);\r
+ FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
+ FirstThread->Tcb.SuspendCount = 0;\r
+\r
+ DPRINT("FirstThread %x\n",FirstThread);\r
+ \r
+ CurrentThread = FirstThread;\r
+ \r
+ DoneInitYet = TRUE;\r
+}\r
+\r
+NTSTATUS NtCreateThread(PHANDLE ThreadHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes,\r
+ HANDLE ProcessHandle,\r
+ PCLIENT_ID Client,\r
+ PCONTEXT ThreadContext,\r
+ PINITIAL_TEB InitialTeb,\r
+ BOOLEAN CreateSuspended)\r
+{\r
+ return(ZwCreateThread(ThreadHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes,\r
+ ProcessHandle,\r
+ Client,\r
+ ThreadContext,\r
+ InitialTeb,\r
+ CreateSuspended));\r
+}\r
+\r
+NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes,\r
+ HANDLE ProcessHandle,\r
+ PCLIENT_ID Client,\r
+ PCONTEXT ThreadContext,\r
+ PINITIAL_TEB InitialTeb,\r
+ BOOLEAN CreateSuspended)\r
+{\r
+ PETHREAD Thread;\r
+ NTSTATUS Status;\r
+ \r
+ DbgPrint("ZwCreateThread(ThreadHandle %x, PCONTEXT %x)\n",\r
+ ThreadHandle,ThreadContext);\r
+ \r
+ Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,\r
+ DesiredAccess,ObjectAttributes);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ HalInitTaskWithContext(Thread,ThreadContext);\r
+ Thread->StartAddress=NULL;\r
+\r
+ if (Client!=NULL)\r
+ {\r
+ *Client=Thread->Cid;\r
+ } \r
+ \r
+ if (!CreateSuspended)\r
+ {\r
+ DPRINT("Not creating suspended\n");\r
+ PsResumeThread(Thread);\r
+ }\r
+ DPRINT("Finished PsCreateThread()\n");\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,\r
+ ACCESS_MASK DesiredAccess,\r
+ POBJECT_ATTRIBUTES ObjectAttributes,\r
+ HANDLE ProcessHandle,\r
+ PCLIENT_ID ClientId,\r
+ PKSTART_ROUTINE StartRoutine,\r
+ PVOID StartContext)\r
+/*\r
+ * FUNCTION: Creates a thread which executes in kernel mode\r
+ * ARGUMENTS:\r
+ * ThreadHandle (OUT) = Caller supplied storage for the returned thread \r
+ * handle\r
+ * DesiredAccess = Requested access to the thread\r
+ * ObjectAttributes = Object attributes (optional)\r
+ * ProcessHandle = Handle of process thread will run in\r
+ * NULL to use system process\r
+ * ClientId (OUT) = Caller supplied storage for the returned client id\r
+ * of the thread (optional)\r
+ * StartRoutine = Entry point for the thread\r
+ * StartContext = Argument supplied to the thread when it begins\r
+ * execution\r
+ * RETURNS: Success or failure status\r
+ */\r
+{\r
+ PETHREAD Thread;\r
+ NTSTATUS Status;\r
+ \r
+ DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",\r
+ ThreadHandle,ProcessHandle);\r
+ \r
+ Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,\r
+ DesiredAccess,ObjectAttributes);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ Thread->StartAddress=StartRoutine;\r
+ HalInitTask(Thread,StartRoutine,StartContext);\r
+\r
+ if (ClientId!=NULL)\r
+ {\r
+ *ClientId=Thread->Cid;\r
+ } \r
+\r
+ PsResumeThread(Thread);\r
+ \r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)\r
+{\r
+ KPRIORITY OldPriority;\r
+ OldPriority = Thread->CurrentPriority;\r
+ Thread->CurrentPriority = Priority;\r
+\r
+ RemoveEntryList(&Thread->Entry);\r
+ PsInsertIntoThreadList(Thread->CurrentPriority,\r
+ CONTAINING_RECORD(Thread,ETHREAD,Tcb));\r
+ \r
+ return(OldPriority);\r
+}\r
+\r
+NTSTATUS STDCALL NtAlertResumeThread(IN HANDLE ThreadHandle,\r
+ OUT PULONG SuspendCount)\r
+{\r
+ return(ZwAlertResumeThread(ThreadHandle,SuspendCount));\r
+}\r
+\r
+NTSTATUS STDCALL ZwAlertResumeThread(IN HANDLE ThreadHandle,\r
+ OUT PULONG SuspendCount)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtAlertThread(IN HANDLE ThreadHandle)\r
+{\r
+ return(ZwAlertThread(ThreadHandle));\r
+}\r
+\r
+NTSTATUS STDCALL ZwAlertThread(IN HANDLE ThreadHandle)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtGetContextThread(IN HANDLE ThreadHandle, \r
+ OUT PCONTEXT Context)\r
+{\r
+ return(ZwGetContextThread(ThreadHandle,Context));\r
+}\r
+\r
+NTSTATUS STDCALL ZwGetContextThread(IN HANDLE ThreadHandle, \r
+ OUT PCONTEXT Context)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes,\r
+ IN PCLIENT_ID ClientId)\r
+{\r
+ return(ZwOpenThread(ThreadHandle,\r
+ DesiredAccess,\r
+ ObjectAttributes,\r
+ ClientId));\r
+}\r
+\r
+NTSTATUS STDCALL ZwOpenThread(OUT PHANDLE ThreadHandle,\r
+ IN ACCESS_MASK DesiredAccess,\r
+ IN POBJECT_ATTRIBUTES ObjectAttributes,\r
+ IN PCLIENT_ID ClientId)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtResumeThread(IN HANDLE ThreadHandle,\r
+ IN PULONG SuspendCount)\r
+{\r
+ return(ZwResumeThread(ThreadHandle,SuspendCount));\r
+}\r
+\r
+NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle,\r
+ IN PULONG SuspendCount)\r
+/*\r
+ * FUNCTION: Decrements a thread's resume count\r
+ * ARGUMENTS: \r
+ * ThreadHandle = Handle to the thread that should be resumed\r
+ * ResumeCount = The resulting resume count.\r
+ * REMARK:\r
+ * A thread is resumed if its suspend count is 0. This procedure maps to\r
+ * the win32 ResumeThread function. ( documentation about the the suspend count can be found here aswell )\r
+ * RETURNS: Status\r
+ */\r
+{\r
+ PETHREAD Thread;\r
+ NTSTATUS Status;\r
+ \r
+ Status = ObReferenceObjectByHandle(ThreadHandle,\r
+ THREAD_SUSPEND_RESUME,\r
+ PsThreadType,\r
+ UserMode,\r
+ (PVOID*)&Thread,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ (*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);\r
+ if (Thread->Tcb.SuspendCount <= 0)\r
+ {\r
+ Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;\r
+ }\r
+ \r
+ ObDereferenceObject(Thread);\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS STDCALL NtSetContextThread(IN HANDLE ThreadHandle,\r
+ IN PCONTEXT Context)\r
+{\r
+ return(ZwSetContextThread(ThreadHandle,Context));\r
+}\r
+\r
+NTSTATUS STDCALL ZwSetContextThread(IN HANDLE ThreadHandle,\r
+ IN PCONTEXT Context)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtSuspendThread(IN HANDLE ThreadHandle,\r
+ IN PULONG PreviousSuspendCount)\r
+{\r
+ return(ZwSuspendThread(ThreadHandle,PreviousSuspendCount));\r
+}\r
+\r
+NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle,\r
+ IN PULONG PreviousSuspendCount)\r
+/*\r
+ * FUNCTION: Increments a thread's suspend count\r
+ * ARGUMENTS: \r
+ * ThreadHandle = Handle to the thread that should be resumed\r
+ * PreviousSuspendCount = The resulting/previous suspend count.\r
+ * REMARK:\r
+ * A thread will be suspended if its suspend count is greater than 0. \r
+ * This procedure maps to the win32 SuspendThread function. ( \r
+ * documentation about the the suspend count can be found here aswell )\r
+ * The suspend count is not increased if it is greater than \r
+ * MAXIMUM_SUSPEND_COUNT.\r
+ * RETURNS: Status\r
+ */ \r
+{\r
+ PETHREAD Thread;\r
+ NTSTATUS Status;\r
+ \r
+ Status = ObReferenceObjectByHandle(ThreadHandle,\r
+ THREAD_SUSPEND_RESUME,\r
+ PsThreadType,\r
+ UserMode,\r
+ (PVOID*)&Thread,\r
+ NULL);\r
+ if (Status != STATUS_SUCCESS)\r
+ {\r
+ return(Status);\r
+ }\r
+ \r
+ (*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount);\r
+ if (Thread->Tcb.SuspendCount > 0)\r
+ {\r
+ Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;\r
+ if (Thread == PsGetCurrentThread())\r
+ {\r
+ PsDispatchThread();\r
+ }\r
+ }\r
+ \r
+ ObDereferenceObject(Thread);\r
+ return(STATUS_SUCCESS);\r
+}\r
+\r
+NTSTATUS STDCALL NtContinue(IN PCONTEXT Context, IN CINT IrqLevel)\r
+{\r
+ return(ZwContinue(Context,IrqLevel));\r
+}\r
+\r
+NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+NTSTATUS STDCALL NtYieldExecution(VOID)\r
+{\r
+ return(ZwYieldExecution());\r
+}\r
+\r
+NTSTATUS STDCALL ZwYieldExecution(VOID)\r
+{\r
+ PsDispatchThread();\r
+ return(STATUS_SUCCESS);\r
+}\r
-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\r
+section .text\r
+\r
+DECLARE_GLOBAL_SYMBOL InterlockedIncrement\r
+ push ebp\r
+ mov ebp,esp\r
+\r
+ push eax\r
+ push ebx\r
+\r
+ mov eax,1\r
+ mov ebx,[ebp+8]\r
+ xadd [ebx],eax\r
+\r
+ pop ebx\r
+ pop eax\r
+\r
+ mov esp,ebp\r
+ pop ebp\r
+\r
+ ret\r
+ \r
+ \r
+DECLARE_GLOBAL_SYMBOL InterlockedDecrement\r
+ mov eax,0xffffffff\r
+ mov ebx,[esp+4]\r
+ xadd [ebx],eax\r
+ dec eax\r
+ ret\r
+ \r
+DECLARE_GLOBAL_SYMBOL InterlockedExchange \r
+ push ebp\r
+ mov ebp,esp\r
+\r
+ push eax\r
+ push ebx\r
+\r
+ mov eax,[ebp+12]\r
+ mov ebx,[ebp+8]\r
+ xchg [ebx],eax\r
+ \r
+ pop ebx\r
+ pop eax\r
+ \r
+ mov esp,ebp\r
+ pop ebp\r
+ ret\r
+\r
+DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd\r
+ mov eax,[esp+8]\r
+ mov ebx,[esp+4]\r
+ xadd [ebx],eax\r
+ ret\r
+\r
+DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange\r
+ mov eax,[esp+12]\r
+ mov edx,[esp+8]\r
+ mov ebx,[esp+4]\r
+ cmpxchg [ebx],edx\r
+ mov eax,edx\r
+ ret \r
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/rtl/unicode.c
- * PURPOSE: String functions
- * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
- * UPDATE HISTORY:
- * Created 10/08/98
- */
-
-#include <base.h>
-#include <wstring.h>
-
-#include <ddk/ntddk.h>
-
-#include <internal/string.h>
-#include <internal/ke.h>
-#include <internal/ctype.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-#define Aa_Difference ('A'-'a')
-
-PUNICODE_STRING RtlDuplicateUnicodeString(PUNICODE_STRING Dest,
- PUNICODE_STRING Src)
-{
- if (Dest==NULL)
- {
- Dest=ExAllocatePool(NonPagedPool,sizeof(UNICODE_STRING));
- }
-}
-
-VOID RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
-{
- UNIMPLEMENTED;
-}
-
-WCHAR wtoupper(WCHAR c)
-{
- if((c>='a') && (c<='z')) return c+Aa_Difference;
- return c;
-}
-
-WCHAR wtolower(WCHAR c)
-{
-// DPRINT("c %c (c-Aa_Difference) %c\n",(char)c,(char)(c-Aa_Difference));
- if((c>='A') && (c<='Z')) return c-Aa_Difference;
- return c;
-}
-
-ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
-{
- return AnsiString->Length*2;
-}
-
-NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
- IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)
-{
- unsigned long i;
-
- if(AllocateDestinationString==TRUE) {
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, (SourceString->Length+1)*2);
- DestinationString->MaximumLength=SourceString->Length;
- };
-
- DestinationString->Length=SourceString->Length;
- memset(DestinationString->Buffer, 0, SourceString->Length*2);
-
- for (i=0; i<SourceString->Length; i++)
- {
- *DestinationString->Buffer=*SourceString->Buffer;
-
- SourceString->Buffer++;
- DestinationString->Buffer++;
- };
- *DestinationString->Buffer=0;
-
- SourceString->Buffer-=SourceString->Length;
- DestinationString->Buffer-=SourceString->Length;
-
- return STATUS_SUCCESS;
-};
-
-NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
- IN PUNICODE_STRING Source)
-{
- unsigned long i;
-
- if(Destination->MaximumLength-Destination->Length-Source->Length<0)
- return STATUS_BUFFER_TOO_SMALL;
-
- Destination->Buffer+=Destination->Length;
- for(i=0; i<Source->Length; i++) {
- *Destination->Buffer=*Source->Buffer;
- Destination->Buffer++;
- Source->Buffer++;
- };
- *Destination->Buffer=0;
- Destination->Buffer-=(Destination->Length+Source->Length);
- Source->Buffer-=Source->Length;
-
- Destination->Length+=Source->Length;
- return STATUS_SUCCESS;
-};
-
-NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
- IN PWSTR Source)
-{
- unsigned long i, slen=wstrlen(Source);
-
- if(Destination->MaximumLength-Destination->Length-slen<0)
- return STATUS_BUFFER_TOO_SMALL;
-
- Destination->Buffer+=Destination->Length;
- for(i=0; i<slen; i++) {
- *Destination->Buffer=*Source;
- Destination->Buffer++;
- Source++;
- };
- *Destination->Buffer=0;
- Destination->Buffer-=(Destination->Length+slen);
- Source-=slen;
-
- Destination->Length+=slen;
- return STATUS_SUCCESS;
-};
-
-NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)
-{
- *Value=simple_strtoul((const char *)String, NULL, Base);
-};
-
-LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
-{
- unsigned long i;
- char c1, c2;
-
- if(String1->Length!=String2->Length) return String1->Length-String2->Length;
-
- for(i=0; i<String1->Length; i++) {
- if(CaseInsensitive==TRUE) {
- c1=toupper(*String1->Buffer);
- c2=toupper(*String2->Buffer);
- } else {
- c1=*String1->Buffer;
- c2=*String2->Buffer;
- };
- if(c1!=c2) {
- String1->Buffer-=i;
- String2->Buffer-=i;
- return c1-c2;
- };
- String1->Buffer++;
- String2->Buffer++;
- };
- String1->Buffer-=i;
- String2->Buffer-=i;
-
- return 0;
-};
-
-LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
- BOOLEAN CaseInsensitive)
-{
- unsigned long i;
- WCHAR wc1, wc2;
-
- if(String1->Length!=String2->Length) return
- String1->Length-String2->Length;
-
- for(i=0; i<String1->Length; i++) {
- if(CaseInsensitive==TRUE) {
- wc1=wtoupper(*String1->Buffer);
- wc2=wtoupper(*String2->Buffer);
- } else {
- wc1=*String1->Buffer;
- wc2=*String2->Buffer;
- };
-
- if(wc1!=wc2) {
- String1->Buffer-=i;
- String2->Buffer-=i;
- return wc1-wc2;
- };
-
- String1->Buffer++;
- String2->Buffer++;
- };
-
- String1->Buffer-=i;
- String2->Buffer-=i;
-
- return 0;
-};
-
-VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
-{
- unsigned long copylen, i;
-
- if(SourceString==NULL) {
- DestinationString->Length=0;
- } else {
- if(SourceString->Length<DestinationString->MaximumLength) {
- copylen=SourceString->Length;
- } else {
- copylen=DestinationString->MaximumLength;
- };
- for(i=0; i<copylen; i++)
- {
- *DestinationString->Buffer=*SourceString->Buffer;
- DestinationString->Buffer++;
- SourceString->Buffer++;
- };
- *DestinationString->Buffer=0;
- DestinationString->Buffer-=copylen;
- SourceString->Buffer-=copylen;
- };
-};
-
-VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
- IN PUNICODE_STRING SourceString)
-{
- unsigned long copylen, i;
-
- if(SourceString==NULL) {
- DestinationString->Length=0;
- } else {
- if(SourceString->Length<DestinationString->MaximumLength) {
- copylen=SourceString->Length;
- } else {
- copylen=DestinationString->MaximumLength;
- };
- for(i=0; i<copylen; i++)
- {
- *DestinationString->Buffer=*SourceString->Buffer;
- DestinationString->Buffer++;
- SourceString->Buffer++;
- };
- *DestinationString->Buffer=0;
- DestinationString->Buffer-=copylen;
- SourceString->Buffer-=copylen;
- };
-};
-
-BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
-{
- unsigned long s1l=String1->Length;
- unsigned long s2l=String2->Length;
- unsigned long i;
- char c1, c2;
-
- if(s1l!=s2l) return FALSE;
-
- for(i=0; i<s1l; i++) {
- c1=*String1->Buffer;
- c2=*String2->Buffer;
-
- if(CaseInsensitive==TRUE) {
- c1=toupper(c1);
- c2=toupper(c2);
- };
-
- if(c1!=c2) {
- String1->Buffer-=i;
- String2->Buffer-=i;
- return FALSE;
- };
-
- String1->Buffer++;
- String2->Buffer++;
- };
-
- String1->Buffer-=i;
- String2->Buffer-=i;
-
- return TRUE;
-};
-
-BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
- BOOLEAN CaseInsensitive)
-{
- unsigned long s1l=String1->Length;
- unsigned long s2l=String2->Length;
- unsigned long i;
- char wc1, wc2;
-
- if(s1l!=s2l) return FALSE;
-
- for(i=0; i<s1l; i++) {
- if(CaseInsensitive==TRUE) {
- wc1=wtoupper(*String1->Buffer);
- wc2=wtoupper(*String2->Buffer);
- } else {
- wc1=*String1->Buffer;
- wc2=*String2->Buffer;
- };
-
- if(wc1!=wc2) {
- String1->Buffer-=i;
- String2->Buffer-=i;
- return FALSE;
- };
-
- String1->Buffer++;
- String2->Buffer++;
- };
-
- String1->Buffer-=i;
- String2->Buffer-=i;
-
- return TRUE;
-};
-
-VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)
-{
- ExFreePool(AnsiString->Buffer);
-};
-
-VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
-{
- ExFreePool(UnicodeString->Buffer);
-};
-
-VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
- IN PCSZ SourceString)
-{
- unsigned long DestSize;
-
- if(SourceString==NULL) {
- DestinationString->Length=0;
- DestinationString->MaximumLength=0;
- } else {
- DestSize=strlen((const char *)SourceString);
- DestinationString->Length=DestSize;
- DestinationString->MaximumLength=DestSize+1;
- };
- DestinationString->Buffer=(PCHAR)SourceString;
-};
-
-VOID RtlInitString(IN OUT PSTRING DestinationString,
- IN PCSZ SourceString)
-{
- DestinationString->Length=strlen((char *)SourceString);
- DestinationString->MaximumLength=strlen((char *)SourceString)+1;
- DestinationString->Buffer=SourceString;
-};
-
-VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
- IN PCWSTR SourceString)
-{
- unsigned long i, DestSize;
- UNICODE_STRING Dest=*DestinationString;
-
- if(SourceString==NULL) {
- DestinationString->Length=0;
- DestinationString->MaximumLength=0;
- DestinationString->Buffer=NULL;
- } else {
- DestSize=wstrlen((PWSTR)SourceString);
- DestinationString->Length=DestSize;
- DestinationString->MaximumLength=DestSize+1;
-
- DestinationString->Buffer=(PWSTR)SourceString;
- };
-};
-
-NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */
- IN OUT PUNICODE_STRING String)
-{
- char *str;
- unsigned long len, i;
-
- str=ExAllocatePool(NonPagedPool, 1024);
- if(Base==16) {
- sprintf(str, "%x", Value);
- } else
- if(Base==8) {
- sprintf(str, "%o", Value);
- } else
- if(Base==2) {
- sprintf(str, "%b", Value);
- } else {
- sprintf(str, "%u", Value);
- };
-
- len=strlen(str);
- if(String->MaximumLength<len) return STATUS_INVALID_PARAMETER;
-
- for(i=0; i<len; i++) {
- *String->Buffer=*str;
- String->Buffer++;
- str++;
- };
- *String->Buffer=0;
- String->Buffer-=len;
- String->Length=len;
- str-=len;
- ExFreePool(str);
-
- return STATUS_SUCCESS;
-};
-
-NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
- IN PUNICODE_STRING SourceString,
- IN BOOLEAN AllocateDestinationString)
-{
- unsigned long i;
-
- if(AllocateDestinationString==TRUE) {
-
- // Causes excetion 14(0) in _Validate_Free_List
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);
- DestinationString->MaximumLength=SourceString->Length+1;
- };
-
- DestinationString->Length=SourceString->Length;
-
- for(i=0; i<SourceString->Length; i++) {
- *DestinationString->Buffer=*SourceString->Buffer;
- DestinationString->Buffer++;
- SourceString->Buffer++;
- };
- *DestinationString->Buffer=0;
-
- DestinationString->Buffer-=SourceString->Length;
- SourceString->Buffer-=SourceString->Length;
-
- return STATUS_SUCCESS;
-};
-
-NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,
- OUT PULONG Value)
-{
- char *str;
- unsigned long i, lenmin=0;
- BOOLEAN addneg=FALSE;
-
- str=ExAllocatePool(NonPagedPool, String->Length+1);
-
- for(i=0; i<String->Length; i++) {
- *str=*String->Buffer;
-
- if(*str=='b') { Base=2; lenmin++; } else
- if(*str=='o') { Base=8; lenmin++; } else
- if(*str=='d') { Base=10; lenmin++; } else
- if(*str=='x') { Base=16; lenmin++; } else
- if(*str=='+') { lenmin++; } else
- if(*str=='-') { addneg=TRUE; lenmin++; } else
- if((*str>'1') && (Base==2)) {
- String->Buffer-=i;
- *Value=0;
- return STATUS_INVALID_PARAMETER;
- } else
- if(((*str>'7') || (*str<'0')) && (Base==8)) {
- String->Buffer-=i;
- *Value=0;
- return STATUS_INVALID_PARAMETER;
- } else
- if(((*str>'9') || (*str<'0')) && (Base==10)) {
- String->Buffer-=i;
- *Value=0;
- return STATUS_INVALID_PARAMETER;
- } else
- if((((*str>'9') || (*str<'0')) ||
- ((toupper(*str)>'F') || (toupper(*str)<'A'))) && (Base==16))
- {
- String->Buffer-=i;
- *Value=0;
- return STATUS_INVALID_PARAMETER;
- } else
- str++;
-
- String->Buffer++;
- };
-
- *str=0;
- String->Buffer-=String->Length;
- str-=(String->Length-lenmin);
-
- if(addneg==TRUE) {
- *Value=simple_strtoul(str, NULL, Base)*-1;
- } else
- *Value=simple_strtoul(str, NULL, Base);
-
- ExFreePool(str);
-};
-
-NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
- IN PUNICODE_STRING SourceString,
- IN BOOLEAN AllocateDestinationString)
-{
- unsigned long i;
-
- if(AllocateDestinationString==TRUE) {
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
- DestinationString->Length=SourceString->Length;
- DestinationString->MaximumLength=SourceString->Length+1;
- };
-
- for(i=0; i<SourceString->Length; i++) {
- *DestinationString->Buffer=wtoupper(*SourceString->Buffer);
- DestinationString->Buffer++;
- SourceString->Buffer++;
- };
- *DestinationString->Buffer=0;
-
- DestinationString->Buffer-=SourceString->Length;
- SourceString->Buffer-=SourceString->Length;
-
- return STATUS_SUCCESS;
-};
-
-VOID RtlUpcaseString(IN OUT PSTRING DestinationString,
- IN PSTRING SourceString)
-{
- unsigned long i, len;
-
- if(SourceString->Length>DestinationString->MaximumLength) {
- len=DestinationString->MaximumLength;
- } else {
- len=SourceString->Length;
- };
-
- for(i=0; i<len; i++) {
- *DestinationString->Buffer=toupper(*SourceString->Buffer);
- DestinationString->Buffer++;
- SourceString->Buffer++;
- };
- *DestinationString->Buffer=0;
-
- DestinationString->Buffer-=len;
- SourceString->Buffer-=len;
-}
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS kernel\r
+ * FILE: ntoskrnl/rtl/unicode.c\r
+ * PURPOSE: String functions\r
+ * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)\r
+ * UPDATE HISTORY:\r
+ * Created 10/08/98\r
+ */\r
+\r
+#include <base.h>\r
+#include <wstring.h>\r
+\r
+#include <ddk/ntddk.h>\r
+\r
+#include <internal/string.h>\r
+#include <internal/ke.h>\r
+#include <internal/ctype.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+#define Aa_Difference ('A'-'a')\r
+\r
+PUNICODE_STRING RtlDuplicateUnicodeString(PUNICODE_STRING Dest, \r
+ PUNICODE_STRING Src)\r
+{\r
+ if (Dest==NULL)\r
+ {\r
+ Dest=ExAllocatePool(NonPagedPool,sizeof(UNICODE_STRING)); \r
+ } \r
+}\r
+\r
+VOID RtlUpperString(PSTRING DestinationString, PSTRING SourceString)\r
+{\r
+ UNIMPLEMENTED;\r
+}\r
+\r
+WCHAR wtoupper(WCHAR c)\r
+{\r
+ if((c>='a') && (c<='z')) return c+Aa_Difference;\r
+ return c;\r
+}\r
+\r
+WCHAR wtolower(WCHAR c)\r
+{\r
+// DPRINT("c %c (c-Aa_Difference) %c\n",(char)c,(char)(c-Aa_Difference));\r
+ if((c>='A') && (c<='Z')) return c-Aa_Difference;\r
+ return c;\r
+}\r
+\r
+ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)\r
+{\r
+ return AnsiString->Length*2;\r
+}\r
+\r
+NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
+ IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)\r
+{\r
+ unsigned long i;\r
+\r
+ if(AllocateDestinationString==TRUE) {\r
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, (SourceString->Length+1)*2);\r
+ DestinationString->MaximumLength=SourceString->Length;\r
+ };\r
+\r
+ DestinationString->Length=SourceString->Length;\r
+ memset(DestinationString->Buffer, 0, SourceString->Length*2);\r
+\r
+ for (i=0; i<SourceString->Length; i++)\r
+ {\r
+ *DestinationString->Buffer=*SourceString->Buffer;\r
+\r
+ SourceString->Buffer++;\r
+ DestinationString->Buffer++;\r
+ };\r
+ *DestinationString->Buffer=0;\r
+\r
+ SourceString->Buffer-=SourceString->Length;\r
+ DestinationString->Buffer-=SourceString->Length;\r
+\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,\r
+ IN PUNICODE_STRING Source)\r
+{\r
+ unsigned long i;\r
+\r
+ if(Destination->MaximumLength-Destination->Length-Source->Length<0)\r
+ return STATUS_BUFFER_TOO_SMALL;\r
+\r
+ Destination->Buffer+=Destination->Length;\r
+ for(i=0; i<Source->Length; i++) {\r
+ *Destination->Buffer=*Source->Buffer;\r
+ Destination->Buffer++;\r
+ Source->Buffer++;\r
+ };\r
+ *Destination->Buffer=0;\r
+ Destination->Buffer-=(Destination->Length+Source->Length);\r
+ Source->Buffer-=Source->Length;\r
+\r
+ Destination->Length+=Source->Length;\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,\r
+ IN PWSTR Source)\r
+{\r
+ unsigned long i, slen=wstrlen(Source);\r
+\r
+ if(Destination->MaximumLength-Destination->Length-slen<0)\r
+ return STATUS_BUFFER_TOO_SMALL;\r
+\r
+ Destination->Buffer+=Destination->Length;\r
+ for(i=0; i<slen; i++) {\r
+ *Destination->Buffer=*Source;\r
+ Destination->Buffer++;\r
+ Source++;\r
+ };\r
+ *Destination->Buffer=0;\r
+ Destination->Buffer-=(Destination->Length+slen);\r
+ Source-=slen;\r
+\r
+ Destination->Length+=slen;\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)\r
+{\r
+ *Value=simple_strtoul((const char *)String, NULL, Base);\r
+};\r
+\r
+LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)\r
+{\r
+ unsigned long i;\r
+ char c1, c2;\r
+\r
+ if(String1->Length!=String2->Length) return String1->Length-String2->Length;\r
+\r
+ for(i=0; i<String1->Length; i++) {\r
+ if(CaseInsensitive==TRUE) {\r
+ c1=toupper(*String1->Buffer);\r
+ c2=toupper(*String2->Buffer);\r
+ } else {\r
+ c1=*String1->Buffer;\r
+ c2=*String2->Buffer;\r
+ };\r
+ if(c1!=c2) {\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+ return c1-c2;\r
+ };\r
+ String1->Buffer++;\r
+ String2->Buffer++;\r
+ };\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+\r
+ return 0;\r
+};\r
+\r
+LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,\r
+ BOOLEAN CaseInsensitive)\r
+{\r
+ unsigned long i;\r
+ WCHAR wc1, wc2;\r
+\r
+ if(String1->Length!=String2->Length) return\r
+ String1->Length-String2->Length;\r
+\r
+ for(i=0; i<String1->Length; i++) {\r
+ if(CaseInsensitive==TRUE) {\r
+ wc1=wtoupper(*String1->Buffer);\r
+ wc2=wtoupper(*String2->Buffer);\r
+ } else {\r
+ wc1=*String1->Buffer;\r
+ wc2=*String2->Buffer;\r
+ };\r
+\r
+ if(wc1!=wc2) {\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+ return wc1-wc2;\r
+ };\r
+\r
+ String1->Buffer++;\r
+ String2->Buffer++;\r
+ };\r
+\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+\r
+ return 0;\r
+};\r
+\r
+VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)\r
+{\r
+ unsigned long copylen, i;\r
+\r
+ if(SourceString==NULL) {\r
+ DestinationString->Length=0;\r
+ } else {\r
+ if(SourceString->Length<DestinationString->MaximumLength) {\r
+ copylen=SourceString->Length;\r
+ } else {\r
+ copylen=DestinationString->MaximumLength;\r
+ };\r
+ for(i=0; i<copylen; i++)\r
+ {\r
+ *DestinationString->Buffer=*SourceString->Buffer;\r
+ DestinationString->Buffer++;\r
+ SourceString->Buffer++;\r
+ };\r
+ *DestinationString->Buffer=0;\r
+ DestinationString->Buffer-=copylen;\r
+ SourceString->Buffer-=copylen;\r
+ };\r
+};\r
+\r
+VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
+ IN PUNICODE_STRING SourceString)\r
+{\r
+ unsigned long copylen, i;\r
+ \r
+ if(SourceString==NULL) \r
+ {\r
+ DestinationString->Length=0;\r
+ } \r
+ else \r
+ {\r
+ copylen = min(DestinationString->MaximumLength,\r
+ SourceString->Length);\r
+ for(i=0; i<copylen; i++)\r
+ {\r
+ *DestinationString->Buffer=*SourceString->Buffer;\r
+ DestinationString->Buffer++;\r
+ SourceString->Buffer++;\r
+ }\r
+ *DestinationString->Buffer=0;\r
+ DestinationString->Buffer-=copylen;\r
+ SourceString->Buffer-=copylen;\r
+ }\r
+}\r
+\r
+BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)\r
+{\r
+ unsigned long s1l=String1->Length;\r
+ unsigned long s2l=String2->Length;\r
+ unsigned long i;\r
+ char c1, c2;\r
+\r
+ if(s1l!=s2l) return FALSE;\r
+\r
+ for(i=0; i<s1l; i++) {\r
+ c1=*String1->Buffer;\r
+ c2=*String2->Buffer;\r
+\r
+ if(CaseInsensitive==TRUE) {\r
+ c1=toupper(c1);\r
+ c2=toupper(c2);\r
+ };\r
+\r
+ if(c1!=c2) {\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+ return FALSE;\r
+ };\r
+\r
+ String1->Buffer++;\r
+ String2->Buffer++;\r
+ };\r
+\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+\r
+ return TRUE;\r
+};\r
+\r
+BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,\r
+ BOOLEAN CaseInsensitive)\r
+{\r
+ unsigned long s1l=String1->Length;\r
+ unsigned long s2l=String2->Length;\r
+ unsigned long i;\r
+ char wc1, wc2;\r
+\r
+ if(s1l!=s2l) return FALSE;\r
+\r
+ for(i=0; i<s1l; i++) {\r
+ if(CaseInsensitive==TRUE) {\r
+ wc1=wtoupper(*String1->Buffer);\r
+ wc2=wtoupper(*String2->Buffer);\r
+ } else {\r
+ wc1=*String1->Buffer;\r
+ wc2=*String2->Buffer;\r
+ };\r
+\r
+ if(wc1!=wc2) {\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+ return FALSE;\r
+ };\r
+\r
+ String1->Buffer++;\r
+ String2->Buffer++;\r
+ };\r
+\r
+ String1->Buffer-=i;\r
+ String2->Buffer-=i;\r
+\r
+ return TRUE;\r
+};\r
+\r
+VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)\r
+{\r
+ ExFreePool(AnsiString->Buffer);\r
+};\r
+\r
+VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)\r
+{\r
+ ExFreePool(UnicodeString->Buffer);\r
+};\r
+\r
+VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,\r
+ IN PCSZ SourceString)\r
+{\r
+ unsigned long DestSize;\r
+\r
+ if(SourceString==NULL) {\r
+ DestinationString->Length=0;\r
+ DestinationString->MaximumLength=0;\r
+ } else {\r
+ DestSize=strlen((const char *)SourceString);\r
+ DestinationString->Length=DestSize;\r
+ DestinationString->MaximumLength=DestSize+1;\r
+ };\r
+ DestinationString->Buffer=(PCHAR)SourceString;\r
+};\r
+\r
+VOID RtlInitString(IN OUT PSTRING DestinationString,\r
+ IN PCSZ SourceString)\r
+{\r
+ DestinationString->Length=strlen((char *)SourceString);\r
+ DestinationString->MaximumLength=strlen((char *)SourceString)+1;\r
+ DestinationString->Buffer=SourceString;\r
+};\r
+\r
+VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
+ IN PCWSTR SourceString)\r
+{\r
+ unsigned long i, DestSize;\r
+\r
+ DPRINT("RtlInitUnicodeString(DestinationString %x, "\r
+ "SourceString %x)\n",DestinationString,SourceString);\r
+\r
+ if (SourceString==NULL)\r
+ {\r
+ DestinationString->Length=0;\r
+ DestinationString->MaximumLength=0;\r
+ DestinationString->Buffer=NULL;\r
+ }\r
+ else\r
+ {\r
+ DestSize=wstrlen((PWSTR)SourceString);\r
+ DestinationString->Length=DestSize;\r
+ DestinationString->MaximumLength=DestSize+1;\r
+ DestinationString->Buffer=(PWSTR)SourceString;\r
+ }\r
+}\r
+\r
+NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */\r
+ IN OUT PUNICODE_STRING String)\r
+{\r
+ char *str;\r
+ unsigned long len, i;\r
+\r
+ str=ExAllocatePool(NonPagedPool, 1024);\r
+ if(Base==16) {\r
+ sprintf(str, "%x", Value);\r
+ } else\r
+ if(Base==8) {\r
+ sprintf(str, "%o", Value);\r
+ } else\r
+ if(Base==2) {\r
+ sprintf(str, "%b", Value);\r
+ } else {\r
+ sprintf(str, "%u", Value);\r
+ };\r
+\r
+ len=strlen(str);\r
+ if(String->MaximumLength<len) return STATUS_INVALID_PARAMETER;\r
+\r
+ for(i=0; i<len; i++) {\r
+ *String->Buffer=*str;\r
+ String->Buffer++;\r
+ str++;\r
+ };\r
+ *String->Buffer=0;\r
+ String->Buffer-=len;\r
+ String->Length=len;\r
+ str-=len;\r
+ ExFreePool(str);\r
+\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,\r
+ IN PUNICODE_STRING SourceString,\r
+ IN BOOLEAN AllocateDestinationString)\r
+{\r
+ unsigned long i;\r
+\r
+ if(AllocateDestinationString==TRUE) {\r
+\r
+ // Causes excetion 14(0) in _Validate_Free_List\r
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);\r
+ DestinationString->MaximumLength=SourceString->Length+1;\r
+ };\r
+\r
+ DestinationString->Length=SourceString->Length;\r
+\r
+ for(i=0; i<SourceString->Length; i++) {\r
+ *DestinationString->Buffer=*SourceString->Buffer;\r
+ DestinationString->Buffer++;\r
+ SourceString->Buffer++;\r
+ };\r
+ *DestinationString->Buffer=0;\r
+\r
+ DestinationString->Buffer-=SourceString->Length;\r
+ SourceString->Buffer-=SourceString->Length;\r
+\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,\r
+ OUT PULONG Value)\r
+{\r
+ char *str;\r
+ unsigned long i, lenmin=0;\r
+ BOOLEAN addneg=FALSE;\r
+\r
+ str=ExAllocatePool(NonPagedPool, String->Length+1);\r
+\r
+ for(i=0; i<String->Length; i++) {\r
+ *str=*String->Buffer;\r
+\r
+ if(*str=='b') { Base=2; lenmin++; } else\r
+ if(*str=='o') { Base=8; lenmin++; } else\r
+ if(*str=='d') { Base=10; lenmin++; } else\r
+ if(*str=='x') { Base=16; lenmin++; } else\r
+ if(*str=='+') { lenmin++; } else\r
+ if(*str=='-') { addneg=TRUE; lenmin++; } else\r
+ if((*str>'1') && (Base==2)) {\r
+ String->Buffer-=i;\r
+ *Value=0;\r
+ return STATUS_INVALID_PARAMETER;\r
+ } else\r
+ if(((*str>'7') || (*str<'0')) && (Base==8)) {\r
+ String->Buffer-=i;\r
+ *Value=0;\r
+ return STATUS_INVALID_PARAMETER;\r
+ } else\r
+ if(((*str>'9') || (*str<'0')) && (Base==10)) {\r
+ String->Buffer-=i;\r
+ *Value=0;\r
+ return STATUS_INVALID_PARAMETER;\r
+ } else\r
+ if((((*str>'9') || (*str<'0')) ||\r
+ ((toupper(*str)>'F') || (toupper(*str)<'A'))) && (Base==16))\r
+ {\r
+ String->Buffer-=i;\r
+ *Value=0;\r
+ return STATUS_INVALID_PARAMETER;\r
+ } else\r
+ str++;\r
+\r
+ String->Buffer++;\r
+ };\r
+\r
+ *str=0;\r
+ String->Buffer-=String->Length;\r
+ str-=(String->Length-lenmin);\r
+\r
+ if(addneg==TRUE) {\r
+ *Value=simple_strtoul(str, NULL, Base)*-1;\r
+ } else\r
+ *Value=simple_strtoul(str, NULL, Base);\r
+\r
+ ExFreePool(str);\r
+};\r
+\r
+NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
+ IN PUNICODE_STRING SourceString,\r
+ IN BOOLEAN AllocateDestinationString)\r
+{\r
+ unsigned long i;\r
+\r
+ if(AllocateDestinationString==TRUE) {\r
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);\r
+ DestinationString->Length=SourceString->Length;\r
+ DestinationString->MaximumLength=SourceString->Length+1;\r
+ };\r
+\r
+ for(i=0; i<SourceString->Length; i++) {\r
+ *DestinationString->Buffer=wtoupper(*SourceString->Buffer);\r
+ DestinationString->Buffer++;\r
+ SourceString->Buffer++;\r
+ };\r
+ *DestinationString->Buffer=0;\r
+\r
+ DestinationString->Buffer-=SourceString->Length;\r
+ SourceString->Buffer-=SourceString->Length;\r
+\r
+ return STATUS_SUCCESS;\r
+};\r
+\r
+VOID RtlUpcaseString(IN OUT PSTRING DestinationString,\r
+ IN PSTRING SourceString)\r
+{\r
+ unsigned long i, len;\r
+\r
+ if(SourceString->Length>DestinationString->MaximumLength) {\r
+ len=DestinationString->MaximumLength;\r
+ } else {\r
+ len=SourceString->Length;\r
+ };\r
+\r
+ for(i=0; i<len; i++) {\r
+ *DestinationString->Buffer=toupper(*SourceString->Buffer);\r
+ DestinationString->Buffer++;\r
+ SourceString->Buffer++;\r
+ };\r
+ *DestinationString->Buffer=0;\r
+\r
+ DestinationString->Buffer-=len;\r
+ SourceString->Buffer-=len;\r
+}\r
BaseAddress = (PVOID)0x10000;
LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
- Size = 0x10000;
+ Size = 0x20000;
ZwMapViewOfSection(SectionHandle,
ShellHandle,
&BaseAddress,