Load services from registry - part 1 (disabled due to bug in registry).
svn path=/trunk/; revision=2216
install_before:
$(CP) boot.bat $(INSTALL_DIR)/boot.bat
$(CP) aboot.bat $(INSTALL_DIR)/aboot.bat
+ $(CP) boot.hiv $(INSTALL_DIR)/system32/boot.hiv
$(CP) media/fonts/helb____.ttf $(INSTALL_DIR)/media/fonts/helb____.ttf
$(CP) media/fonts/timr____.ttf $(INSTALL_DIR)/media/fonts/timr____.ttf
#ifndef __INCLUDE_CSRSS_CSRSS_H
#define __INCLUDE_CSRSS_CSRSS_H
+#include <windows.h>
#include <napi/lpc.h>
#include <ddk/ntddblue.h>
#include <ntos/keyboard.h>
WCHAR Title[1];
} CSRSS_GET_TITLE_REPLY, *PCSRSS_GET_TITLE_REPLY;
+typedef struct
+{
+ HANDLE ConsoleHandle;
+ COORD BufferSize;
+ COORD BufferCoord;
+ SMALL_RECT WriteRegion;
+ CHAR_INFO CharInfo[0];
+} CSRSS_WRITE_CONSOLE_OUTPUT_REQUEST, *PCSRSS_WRITE_CONSOLE_OUTPUT_REQUEST;
+
+typedef struct
+{
+ SMALL_RECT WriteRegion;
+} CSRSS_WRITE_CONSOLE_OUTPUT_REPLY, *PCSRSS_WRITE_CONSOLE_OUTPUT_REPLY;
+
+typedef struct
+{
+ HANDLE ConsoleInput;
+} CSRSS_FLUSH_INPUT_BUFFER_REQUEST, *PCSRSS_FLUSH_INPUT_BUFFER_REQUEST;
+
+typedef struct
+{
+ HANDLE ConsoleHandle;
+ SMALL_RECT ScrollRectangle;
+ BOOLEAN UseClipRectangle;
+ SMALL_RECT ClipRectangle;
+ COORD DestinationOrigin;
+ CHAR_INFO Fill;
+} CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST, *PCSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST;
+
+
#define CSRSS_MAX_WRITE_CONSOLE_REQUEST (MAX_MESSAGE_DATA - sizeof( ULONG ) - sizeof( CSRSS_WRITE_CONSOLE_REQUEST))
#define CSRSS_MAX_SET_TITLE_REQUEST (MAX_MESSAGE_DATA - sizeof( HANDLE ) - sizeof( DWORD ) - sizeof( ULONG ) - sizeof( LPC_MESSAGE_HEADER ))
// FIXME: it should be 80. Is this a limit due to LPC msg size?
#define CSRSS_MAX_TITLE_LENGTH 50
-#define CSRSS_CREATE_PROCESS (0x0)
-#define CSRSS_TERMINATE_PROCESS (0x1)
-#define CSRSS_WRITE_CONSOLE (0x2)
-#define CSRSS_READ_CONSOLE (0x3)
-#define CSRSS_ALLOC_CONSOLE (0x4)
-#define CSRSS_FREE_CONSOLE (0x5)
-#define CSRSS_CONNECT_PROCESS (0x6)
-#define CSRSS_SCREEN_BUFFER_INFO (0x7)
-#define CSRSS_SET_CURSOR (0x8)
-#define CSRSS_FILL_OUTPUT (0x9)
-#define CSRSS_READ_INPUT (0xA)
-#define CSRSS_WRITE_CONSOLE_OUTPUT_CHAR (0xB)
-#define CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB (0xC)
-#define CSRSS_FILL_OUTPUT_ATTRIB (0xD)
-#define CSRSS_GET_CURSOR_INFO (0xE)
-#define CSRSS_SET_CURSOR_INFO (0xF)
-#define CSRSS_SET_ATTRIB (0x10)
-#define CSRSS_GET_MODE (0x11)
-#define CSRSS_SET_MODE (0x12)
-#define CSRSS_CREATE_SCREEN_BUFFER (0x13)
-#define CSRSS_SET_SCREEN_BUFFER (0x14)
-#define CSRSS_SET_TITLE (0x15)
-#define CSRSS_GET_TITLE (0x16)
+#define CSRSS_CREATE_PROCESS (0x0)
+#define CSRSS_TERMINATE_PROCESS (0x1)
+#define CSRSS_WRITE_CONSOLE (0x2)
+#define CSRSS_READ_CONSOLE (0x3)
+#define CSRSS_ALLOC_CONSOLE (0x4)
+#define CSRSS_FREE_CONSOLE (0x5)
+#define CSRSS_CONNECT_PROCESS (0x6)
+#define CSRSS_SCREEN_BUFFER_INFO (0x7)
+#define CSRSS_SET_CURSOR (0x8)
+#define CSRSS_FILL_OUTPUT (0x9)
+#define CSRSS_READ_INPUT (0xA)
+#define CSRSS_WRITE_CONSOLE_OUTPUT_CHAR (0xB)
+#define CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB (0xC)
+#define CSRSS_FILL_OUTPUT_ATTRIB (0xD)
+#define CSRSS_GET_CURSOR_INFO (0xE)
+#define CSRSS_SET_CURSOR_INFO (0xF)
+#define CSRSS_SET_ATTRIB (0x10)
+#define CSRSS_GET_MODE (0x11)
+#define CSRSS_SET_MODE (0x12)
+#define CSRSS_CREATE_SCREEN_BUFFER (0x13)
+#define CSRSS_SET_SCREEN_BUFFER (0x14)
+#define CSRSS_SET_TITLE (0x15)
+#define CSRSS_GET_TITLE (0x16)
+#define CSRSS_WRITE_CONSOLE_OUTPUT (0x17)
+#define CSRSS_FLUSH_INPUT_BUFFER (0x18)
+#define CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER (0x19)
+
typedef struct
{
CSRSS_READ_INPUT_REQUEST ReadInputRequest;
CSRSS_WRITE_CONSOLE_OUTPUT_CHAR_REQUEST WriteConsoleOutputCharRequest;
CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB_REQUEST WriteConsoleOutputAttribRequest;
- CSRSS_FILL_OUTPUT_ATTRIB_REQUEST FillOutputAttribRequest;
+ CSRSS_FILL_OUTPUT_ATTRIB_REQUEST FillOutputAttribRequest;
CSRSS_SET_CURSOR_INFO_REQUEST SetCursorInfoRequest;
CSRSS_GET_CURSOR_INFO_REQUEST GetCursorInfoRequest;
CSRSS_SET_ATTRIB_REQUEST SetAttribRequest;
CSRSS_GET_CONSOLE_MODE_REQUEST GetConsoleModeRequest;
CSRSS_CREATE_SCREEN_BUFFER_REQUEST CreateScreenBufferRequest;
CSRSS_SET_ACTIVE_SCREEN_BUFFER_REQUEST SetActiveScreenBufferRequest;
- CSRSS_SET_TITLE_REQUEST SetTitleRequest;
- CSRSS_GET_TITLE_REQUEST GetTitleRequest;
+ CSRSS_SET_TITLE_REQUEST SetTitleRequest;
+ CSRSS_GET_TITLE_REQUEST GetTitleRequest;
+ CSRSS_WRITE_CONSOLE_OUTPUT_REQUEST WriteConsoleOutputRequest;
+ CSRSS_FLUSH_INPUT_BUFFER_REQUEST FlushInputBufferRequest;
+ CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER_REQUEST ScrollConsoleScreenBufferRequest;
} Data;
} CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
CSRSS_GET_CURSOR_INFO_REPLY GetCursorInfoReply;
CSRSS_GET_CONSOLE_MODE_REPLY GetConsoleModeReply;
CSRSS_CREATE_SCREEN_BUFFER_REPLY CreateScreenBufferReply;
- CSRSS_GET_TITLE_REPLY GetTitleReply;
+ CSRSS_GET_TITLE_REPLY GetTitleReply;
+ CSRSS_WRITE_CONSOLE_OUTPUT_REPLY WriteConsoleOutputReply;
} Data;
} CSRSS_API_REPLY, *PCSRSS_API_REPLY;
#endif /* __INCLUDE_CSRSS_CSRSS_H */
-
-/* $Id: rtl.h,v 1.56 2001/08/03 17:07:56 ekohl Exp $
+/* $Id: rtl.h,v 1.57 2001/09/01 15:36:43 chorns Exp $
*
*/
#define RTL_REGISTRY_WINDOWS_NT 3
#define RTL_REGISTRY_DEVICEMAP 4
#define RTL_REGISTRY_USER 5
-#define RTL_REGISTRY_MAXIMUM 6
+#define RTL_REGISTRY_ENUM 6 // ReactOS specific: Used internally in kernel only
+#define RTL_REGISTRY_MAXIMUM 7
#define RTL_REGISTRY_HANDLE 0x40000000
#define RTL_REGISTRY_OPTIONAL 0x80000000
extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG;
+/*
+ * NOTE: ReactOS extensions
+ */
+#define RtlMin(X,Y) (((X) < (Y))? (X) : (Y))
+#define RtlMax(X,Y) (((X) > (Y))? (X) : (Y))
+#define RtlMin3(X,Y,Z) (((X) < (Y)) ? RtlMin(X,Z) : RtlMin(Y,Z))
+#define RtlMax3(X,Y,Z) (((X) > (Y)) ? RtlMax(X,Z) : RtlMax(Y,Z))
+
+
/*
* VOID
* InitializeObjectAttributes (
#endif
#ifndef NASSERT
-#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
+#define assert(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
#else
#define assert(x)
#endif
-/* $Id: reg.c,v 1.12 2001/07/01 17:54:07 ekohl Exp $
+/* $Id: reg.c,v 1.13 2001/09/01 15:36:43 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
#define NDEBUG
#include <debug.h>
+#define CHECK_STATUS \
+{ \
+ if (!NT_SUCCESS(Status)) \
+ { \
+ LONG _ErrorCode = RtlNtStatusToDosError(Status); \
+ SetLastError(_ErrorCode); \
+ return _ErrorCode; \
+ } \
+}
+
/* GLOBALS *******************************************************************/
#define MAX_DEFAULT_HANDLES 6
/* FUNCTIONS *****************************************************************/
+inline RegiTerminateWideString(LPWSTR String, DWORD Length)
+{
+ LPWSTR AfterString = String + Length;
+ *AfterString = 0;
+}
+
/************************************************************************
* RegInitDefaultHandles
*/
PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR Name[MAX_PATH+1];
+ UNICODE_STRING UnicodeStringName;
+ WCHAR Class[MAX_PATH+1];
+ UNICODE_STRING UnicodeStringClass;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD NameLength;
+ DWORD ClassLength;
+
+ DPRINT("hKey 0x%x dwIndex %d lpName 0x%x *lpcbName %d lpClass 0x%x lpcbClass %d\n",
+ hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass);
+
+ if ((lpClass) && (!lpcbClass))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&UnicodeStringName, NULL);
+ UnicodeStringName.Buffer = &Name[0];
+ UnicodeStringName.MaximumLength = sizeof(Name);
+
+ RtlInitUnicodeString(&UnicodeStringClass, NULL);
+
+ if (lpClass)
+ {
+ UnicodeStringClass.Buffer = &Class[0];
+ UnicodeStringClass.MaximumLength = sizeof(Class);
+ ClassLength = *lpcbClass;
+ }
+ else
+ {
+ ClassLength = 0;
+ }
+
+ NameLength = *lpcbName;
+
+ ErrorCode = RegEnumKeyExW(
+ hKey,
+ dwIndex,
+ UnicodeStringName.Buffer,
+ &NameLength,
+ lpReserved,
+ UnicodeStringClass.Buffer,
+ &ClassLength,
+ lpftLastWriteTime);
+
+ if (ErrorCode != ERROR_SUCCESS)
+ return ErrorCode;
+
+ UnicodeStringName.Length = NameLength * sizeof(WCHAR);
+ UnicodeStringClass.Length = ClassLength * sizeof(WCHAR);
+
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpName;
+ AnsiString.MaximumLength = *lpcbName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringName, FALSE);
+ *lpcbName = AnsiString.Length;
+
+ DPRINT("Key Namea0 Length %d\n", UnicodeStringName.Length);
+ DPRINT("Key Namea1 Length %d\n", NameLength);
+ DPRINT("Key Namea Length %d\n", *lpcbName);
+ DPRINT("Key Namea %s\n", lpName);
+
+ if (lpClass)
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpClass;
+ AnsiString.MaximumLength = *lpcbClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE);
+ *lpcbClass = AnsiString.Length;
+ }
+
+ return ERROR_SUCCESS;
}
PFILETIME lpftLastWriteTime
)
{
- PKEY_NODE_INFORMATION KeyInfo;
+ PKEY_NODE_INFORMATION KeyInfo;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
ULONG BufferSize;
ULONG ResultSize;
- HANDLE KeyHandle;
+ HANDLE KeyHandle;
- Status = MapDefaultKey(&KeyHandle,
- hKey);
+ Status = MapDefaultKey(&KeyHandle, hKey);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
-
SetLastError (dwError);
return dwError;
}
- BufferSize = sizeof (KEY_NODE_INFORMATION) +
- *lpcbName * sizeof(WCHAR);
+ BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR);
if (lpClass)
BufferSize += *lpcbClass;
- KeyInfo = RtlAllocateHeap (RtlGetProcessHeap(),
- 0,
- BufferSize);
- if (KeyInfo == NULL)
- return ERROR_OUTOFMEMORY;
-
- Status = NtEnumerateKey (KeyHandle,
- (ULONG)dwIndex,
- KeyNodeInformation,
- KeyInfo,
- BufferSize,
- &ResultSize);
- if (!NT_SUCCESS(Status))
- {
- dwError = RtlNtStatusToDosError(Status);
-
- SetLastError(dwError);
- }
- else
- {
- memcpy (lpName, KeyInfo->Name, KeyInfo->NameLength);
- *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR)) - 1;
+ KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
+
+ /* We don't know the exact size of the data returned, so call
+ NtEnumerateKey() with a buffer size determined from parameters
+ to this function. If that call fails with a status code of
+ STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
+ while (TRUE) {
+ KeyInfo = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+ if (KeyInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
- if (lpClass)
- {
- memcpy (lpClass,
- KeyInfo->Name + KeyInfo->ClassOffset,
- KeyInfo->ClassLength);
- *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR)) - 1;
- }
+ Status = NtEnumerateKey(
+ KeyHandle,
+ (ULONG)dwIndex,
+ KeyNodeInformation,
+ KeyInfo,
+ BufferSize,
+ &ResultSize);
- if (lpftLastWriteTime)
- {
+ DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
- }
- }
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, KeyInfo);
+ BufferSize = ResultSize;
+ continue;
+ }
- RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ break;
+ }
+ else
+ {
+ if ((lpClass) && (*lpcbClass != 0) && (KeyInfo->ClassLength > *lpcbClass))
+ {
+ dwError = ERROR_MORE_DATA;
+ SetLastError(dwError);
+ break;
+ }
+
+ RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength);
+ *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR));
+ RegiTerminateWideString(lpName, *lpcbName);
+
+ if (lpClass)
+ {
+ RtlMoveMemory(lpClass,
+ (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset),
+ KeyInfo->ClassLength);
+ *lpcbClass = (DWORD)(KeyInfo->ClassLength / sizeof(WCHAR));
+ }
+
+ if (lpftLastWriteTime)
+ {
+ /* FIXME: Fill lpftLastWriteTime */
+ }
+
+ break;
+ }
+ }
+
+ RtlFreeHeap (RtlGetProcessHeap(), 0, KeyInfo);
return dwError;
}
LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ValueName[MAX_PATH+1];
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD ValueNameLength;
+
+ RtlInitUnicodeString(&UnicodeString, NULL);
+ UnicodeString.Buffer = &ValueName[0];
+ UnicodeString.MaximumLength = sizeof(ValueName);
+
+ ValueNameLength = *lpcbValueName;
+
+ ErrorCode = RegEnumValueW(
+ hKey,
+ dwIndex,
+ UnicodeString.Buffer,
+ &ValueNameLength,
+ lpReserved,
+ lpType,
+ lpData,
+ lpcbData);
+
+ if (ErrorCode != ERROR_SUCCESS)
+ return ErrorCode;
+
+ UnicodeString.Length = ValueNameLength * sizeof(WCHAR);
+
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpValueName;
+ AnsiString.MaximumLength = *lpcbValueName;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+ *lpcbValueName = AnsiString.Length;
+
+ return ERROR_SUCCESS;
}
BufferSize = sizeof (KEY_VALUE_FULL_INFORMATION) +
*lpcbValueName * sizeof(WCHAR);
- if (lpcbData)
+ if (lpcbData)
BufferSize += *lpcbData;
- ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
- 0,
- BufferSize);
- if (ValueInfo == NULL)
- return ERROR_OUTOFMEMORY;
- Status = NtEnumerateValueKey (hKey,
- (ULONG)dwIndex,
- KeyValueFullInformation,
- ValueInfo,
- BufferSize,
- &ResultSize);
- if (!NT_SUCCESS(Status))
- {
- dwError = RtlNtStatusToDosError(Status);
-
- SetLastError(dwError);
- }
- else
- {
- memcpy (lpValueName, ValueInfo->Name, ValueInfo->NameLength);
- *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR)) - 1;
-
- if (lpType)
- *lpType = ValueInfo->Type;
-
- if (lpData)
- {
- memcpy (lpData,
- ValueInfo->Name + ValueInfo->DataOffset,
- ValueInfo->DataLength);
- *lpcbValueName = (DWORD)ValueInfo->DataLength;
- }
- }
+ /* We don't know the exact size of the data returned, so call
+ NtEnumerateValueKey() with a buffer size determined from parameters
+ to this function. If that call fails with a status code of
+ STATUS_BUFFER_OVERFLOW, allocate a new buffer and try again */
+ while (TRUE) {
+ ValueInfo = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ BufferSize);
+ if (ValueInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ Status = NtEnumerateValueKey(
+ hKey,
+ (ULONG)dwIndex,
+ KeyValueFullInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+
+ DPRINT("NtEnumerateValueKey() returned status 0x%X\n", Status);
+
+ if (Status == STATUS_BUFFER_OVERFLOW)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
+ BufferSize = ResultSize;
+ continue;
+ }
- RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ SetLastError(dwError);
+ break;
+ }
+ else
+ {
+ if ((lpData) && (*lpcbData != 0) && (ValueInfo->DataLength > *lpcbData))
+ {
+ dwError = ERROR_MORE_DATA;
+ SetLastError(dwError);
+ break;
+ }
+
+ memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength);
+ *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR));
+ RegiTerminateWideString(lpValueName, *lpcbValueName);
+
+ if (lpType)
+ *lpType = ValueInfo->Type;
+
+ if (lpData)
+ {
+ memcpy(lpData,
+ (PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
+ ValueInfo->DataLength);
+ *lpcbData = (DWORD)ValueInfo->DataLength;
+ }
+
+ break;
+ }
+ }
+
+ RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
return dwError;
}
STDCALL
RegGetKeySecurity (
HKEY hKey,
- SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG ? */
+ SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
LPDWORD lpcbSecurityDescriptor
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPCSTR lpFile
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
BOOL fAsynchronous
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ClassName[MAX_PATH];
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+
+ RtlInitUnicodeString(&UnicodeString, NULL);
+
+ if (lpClass)
+ {
+ UnicodeString.Buffer = &ClassName[0];
+ UnicodeString.MaximumLength = sizeof(ClassName);
+ }
+
+ ErrorCode = RegQueryInfoKeyW(
+ hKey,
+ UnicodeString.Buffer,
+ lpcbClass,
+ lpReserved,
+ lpcSubKeys,
+ lpcbMaxSubKeyLen,
+ lpcbMaxClassLen,
+ lpcValues,
+ lpcbMaxValueNameLen,
+ lpcbMaxValueLen,
+ lpcbSecurityDescriptor,
+ lpftLastWriteTime);
+
+ if ((ErrorCode == ERROR_SUCCESS) && (lpClass))
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpClass;
+ AnsiString.MaximumLength = *lpcbClass;
+ RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+ *lpcbClass = AnsiString.Length;
+ }
+
+ return ErrorCode;
}
PFILETIME lpftLastWriteTime
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ KEY_FULL_INFORMATION FullInfoBuffer;
+ PKEY_FULL_INFORMATION FullInfo;
+ ULONG FullInfoSize;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ LONG ErrorCode;
+ ULONG Length;
+
+ if ((lpClass) && (!lpcbClass))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ CHECK_STATUS;
+
+ if (lpClass)
+ {
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass;
+ FullInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, FullInfoSize);
+ if (!FullInfo)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ FullInfo->ClassLength = *lpcbClass;
+ }
+ else
+ {
+ FullInfoSize = sizeof(KEY_FULL_INFORMATION);
+ FullInfo = &FullInfoBuffer;
+ FullInfo->ClassLength = 1;
+ }
+
+ FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
+
+ Status = NtQueryKey(
+ KeyHandle,
+ KeyFullInformation,
+ FullInfo,
+ FullInfoSize,
+ &Length);
+
+ if (!NT_SUCCESS(Status))
+ {
+ if (lpClass)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
+ }
+
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+
+ if (lpcSubKeys)
+ {
+ *lpcSubKeys = FullInfo->SubKeys;
+ }
+
+ if (lpcbMaxSubKeyLen)
+ {
+ *lpcbMaxSubKeyLen = FullInfo->MaxNameLen;
+ }
+
+ if (lpcbMaxClassLen)
+ {
+ *lpcbMaxClassLen = FullInfo->MaxClassLen;
+ }
+
+ if (lpcValues)
+ {
+ *lpcValues = FullInfo->Values;
+ }
+
+ if (lpcbMaxValueNameLen)
+ {
+ *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen;
+ }
+
+ if (lpcbMaxValueLen)
+ {
+ *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+ }
+
+ if (lpcbSecurityDescriptor)
+ {
+ *lpcbSecurityDescriptor = 0;
+ /* FIXME */
+ }
+
+ if (lpftLastWriteTime != NULL)
+ {
+ lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
+ lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
+ }
+
+ if (lpClass)
+ {
+ wcsncpy(lpClass, FullInfo->Class, *lpcbClass);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, FullInfo);
+ }
+
+ SetLastError(ERROR_SUCCESS);
+ return ERROR_SUCCESS;
}
LPDWORD ldwTotsize
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPDWORD ldwTotsize
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
PLONG lpcbValue
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR SubKeyNameBuffer[MAX_PATH+1];
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING Value;
+ ANSI_STRING AnsiString;
+ LONG ValueSize;
+ LONG ErrorCode;
+
+ if ((lpValue) && (!lpcbValue))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&SubKeyName, NULL);
+ RtlInitUnicodeString(&Value, NULL);
+
+ if ((lpSubKey) && (strlen(lpSubKey) != 0))
+ {
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+ SubKeyName.Buffer = &SubKeyNameBuffer[0];
+ SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+ RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+ }
+
+ if (lpValue)
+ {
+ ValueSize = *lpcbValue * sizeof(WCHAR);
+ Value.MaximumLength = ValueSize;
+ Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize);
+ if (!Value.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ ValueSize = 0;
+ }
+
+ ErrorCode = RegQueryValueW(
+ hKey,
+ (LPCWSTR)SubKeyName.Buffer,
+ Value.Buffer,
+ &ValueSize);
+
+ if (ErrorCode == ERROR_SUCCESS)
+ {
+ Value.Length = ValueSize;
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpValue;
+ AnsiString.MaximumLength = *lpcbValue;
+ RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE);
+ }
+
+ *lpcbValue = ValueSize;
+
+ if (Value.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer);
+ }
+
+ return ErrorCode;
}
LPDWORD lpcbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR ValueNameBuffer[MAX_PATH+1];
+ UNICODE_STRING ValueName;
+ UNICODE_STRING ValueData;
+ ANSI_STRING AnsiString;
+ LONG ErrorCode;
+ DWORD ResultSize;
+ DWORD Type;
+
+ /* FIXME: HKEY_PERFORMANCE_DATA is special, see MS SDK */
+
+ if ((lpData) && (!lpcbData))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&ValueData, NULL);
+
+ if (lpData)
+ {
+ ValueData.MaximumLength = *lpcbData * sizeof(WCHAR);
+ ValueData.Buffer = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ 0,
+ ValueData.MaximumLength);
+ if (!ValueData.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+ }
+
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpValueName);
+ RtlInitUnicodeString(&ValueName, NULL);
+ ValueName.Buffer = &ValueNameBuffer[0];
+ ValueName.MaximumLength = sizeof(ValueNameBuffer);
+ RtlAnsiStringToUnicodeString(&ValueName, &AnsiString, FALSE);
+
+ if (lpcbData)
+ {
+ ResultSize = *lpcbData;
+ }
+ else
+ {
+ ResultSize = 0;
+ }
+
+ ErrorCode = RegQueryValueExW(
+ hKey,
+ ValueName.Buffer,
+ lpReserved,
+ &Type,
+ (LPBYTE)ValueData.Buffer,
+ &ResultSize);
+
+ if ((ErrorCode == ERROR_SUCCESS) && (ValueData.Buffer != NULL))
+ {
+ if (lpType)
+ {
+ *lpType = Type;
+ }
+
+ if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
+ {
+ ValueData.Length = ResultSize;
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = lpData;
+ AnsiString.MaximumLength = *lpcbData;
+ RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+ }
+ else
+ {
+ RtlMoveMemory(lpData, ValueData.Buffer, ResultSize);
+ }
+ }
+
+ if (lpcbData)
+ {
+ *lpcbData = ResultSize;
+ }
+
+ if (ValueData.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueData.Buffer);
+ }
+
+ return ErrorCode;
}
ULONG BufferSize;
ULONG ResultSize;
+ DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
+ hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
+
+ if ((lpData) && (!lpcbData))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
RtlInitUnicodeString (&ValueName,
lpValueName);
0,
BufferSize);
if (ValueInfo == NULL)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
return ERROR_OUTOFMEMORY;
+ }
Status = NtQueryValueKey (hKey,
&ValueName,
ValueInfo,
BufferSize,
&ResultSize);
- if (!NT_SUCCESS(Status))
+
+ DPRINT("Status 0x%X\n", Status);
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
+ dwError = ERROR_SUCCESS;
+ }
+ else if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
-
SetLastError(dwError);
}
else
{
- *lpType = ValueInfo->Type;
- memcpy (lpData, ValueInfo->Data, ValueInfo->DataLength);
- if (ValueInfo->Type == REG_SZ)
+ if (lpType)
+ {
+ *lpType = ValueInfo->Type;
+ }
+
+ RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength);
+ if ((ValueInfo->Type == REG_SZ) ||
+ (ValueInfo->Type == REG_MULTI_SZ) ||
+ (ValueInfo->Type == REG_EXPAND_SZ))
+ {
((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
+ }
}
+
+ DPRINT("Type %d ResultSize %d\n", ValueInfo->Type, ResultSize);
+
*lpcbData = (DWORD)ResultSize;
- RtlFreeHeap (RtlGetProcessHeap(), 0, ValueInfo);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
return dwError;
}
PLONG lpcbValue
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ NTSTATUS errCode;
+ UNICODE_STRING SubKeyString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE KeyHandle;
+ HANDLE RealKey;
+ LONG ErrorCode;
+ BOOL CloseRealKey;
+
+ errCode = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(errCode))
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ if ((lpSubKey) && (wcslen(lpSubKey) != 0))
+ {
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ errCode = NtOpenKey(
+ &RealKey,
+ KEY_ALL_ACCESS,
+ & ObjectAttributes
+ );
+ if ( !NT_SUCCESS(errCode) )
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+ CloseRealKey = TRUE;
+ }
+ else
+ {
+ RealKey = hKey;
+ CloseRealKey = FALSE;
+ }
+
+ ErrorCode = RegQueryValueExW(
+ RealKey,
+ NULL,
+ NULL,
+ NULL,
+ (LPBYTE)lpValue,
+ (LPDWORD)lpcbValue);
+
+ if (CloseRealKey)
+ {
+ NtClose(RealKey);
+ }
+
+ return ErrorCode;
}
LPCSTR lpOldFile
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPCWSTR lpOldFile
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
DWORD dwFlags
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
DWORD dwFlags
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
PSECURITY_DESCRIPTOR pSecurityDescriptor
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
DWORD cbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ WCHAR SubKeyNameBuffer[MAX_PATH+1];
+ UNICODE_STRING SubKeyName;
+ UNICODE_STRING Data;
+ ANSI_STRING AnsiString;
+ LONG DataSize;
+ LONG ErrorCode;
+
+ if (!lpData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ RtlInitUnicodeString(&SubKeyName, NULL);
+ RtlInitUnicodeString(&Data, NULL);
+
+ if ((lpSubKey) && (strlen(lpSubKey) != 0))
+ {
+ RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+ SubKeyName.Buffer = &SubKeyNameBuffer[0];
+ SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+ RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+ }
+
+ DataSize = cbData * sizeof(WCHAR);
+ Data.MaximumLength = DataSize;
+ Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize);
+ if (!Data.Buffer)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ ErrorCode = RegSetValueW(
+ hKey,
+ (LPCWSTR)SubKeyName.Buffer,
+ dwType,
+ Data.Buffer,
+ DataSize);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+
+ return ErrorCode;
}
DWORD cbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ UNICODE_STRING ValueName;
+ LPWSTR pValueName;
+ ANSI_STRING AnsiString;
+ UNICODE_STRING Data;
+ LONG ErrorCode;
+ LPBYTE pData;
+ DWORD DataSize;
+
+ if (!lpData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((lpValueName) && (strlen(lpValueName) != 0))
+ {
+ RtlCreateUnicodeStringFromAsciiz(&ValueName, (LPSTR)lpValueName);
+ pValueName = (LPWSTR)ValueName.Buffer;
+ }
+ else
+ {
+ pValueName = NULL;
+ }
+
+ if ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ) || (dwType == REG_EXPAND_SZ))
+ {
+ RtlInitAnsiString(&AnsiString, NULL);
+ AnsiString.Buffer = (LPSTR)lpData;
+ AnsiString.Length = cbData;
+ AnsiString.MaximumLength = cbData;
+ RtlAnsiStringToUnicodeString(&Data, &AnsiString, TRUE);
+ pData = (LPBYTE)Data.Buffer;
+ DataSize = cbData * sizeof(WCHAR);
+ }
+ else
+ {
+ RtlInitUnicodeString(&Data, NULL);
+ pData = (LPBYTE)lpData;
+ DataSize = cbData;
+ }
+
+ ErrorCode = RegSetValueExW(
+ hKey,
+ pValueName,
+ Reserved,
+ dwType,
+ pData,
+ DataSize);
+
+ if (pValueName)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ValueName.Buffer);
+ }
+
+ if (Data.Buffer)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+ }
+
+ return ErrorCode;
}
)
{
UNICODE_STRING ValueName;
+ PUNICODE_STRING pValueName;
+ HANDLE KeyHandle;
NTSTATUS Status;
+ LONG ErrorCode;
- RtlInitUnicodeString (&ValueName,
- lpValueName);
+ Status = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(Status))
+ {
+ ErrorCode = RtlNtStatusToDosError(Status);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
- Status = NtSetValueKey (hKey,
- &ValueName,
- 0,
- dwType,
- (PVOID)lpData,
- (ULONG)cbData);
+ if (lpValueName)
+ {
+ RtlInitUnicodeString(&ValueName, lpValueName);
+ pValueName = &ValueName;
+ }
+ else
+ {
+ pValueName = NULL;
+ }
+
+ Status = NtSetValueKey(
+ KeyHandle,
+ pValueName,
+ 0,
+ dwType,
+ (PVOID)lpData,
+ (ULONG)cbData);
if (!NT_SUCCESS(Status))
{
LONG ErrorCode = RtlNtStatusToDosError(Status);
-
SetLastError (ErrorCode);
return ErrorCode;
}
DWORD cbData
)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ NTSTATUS errCode;
+ UNICODE_STRING SubKeyString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE KeyHandle;
+ HANDLE RealKey;
+ LONG ErrorCode;
+ BOOL CloseRealKey;
+
+ errCode = MapDefaultKey(&KeyHandle, hKey);
+ if (!NT_SUCCESS(errCode))
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError (ErrorCode);
+ return ErrorCode;
+ }
+
+ if ((lpSubKey) && (wcslen(lpSubKey) != 0))
+ {
+
+ RtlInitUnicodeString(&SubKeyString,
+ (LPWSTR)lpSubKey);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyString,
+ OBJ_CASE_INSENSITIVE,
+ KeyHandle,
+ NULL);
+
+ errCode = NtOpenKey(
+ &RealKey,
+ KEY_ALL_ACCESS,
+ & ObjectAttributes
+ );
+ if ( !NT_SUCCESS(errCode) )
+ {
+ ErrorCode = RtlNtStatusToDosError(errCode);
+ SetLastError(ErrorCode);
+ return ErrorCode;
+ }
+ CloseRealKey = TRUE;
+ }
+ else
+ {
+ RealKey = hKey;
+ CloseRealKey = FALSE;
+ }
+
+ ErrorCode = RegSetValueExW(
+ RealKey,
+ NULL,
+ 0,
+ dwType,
+ (LPBYTE)lpData,
+ cbData);
+
+ if (CloseRealKey)
+ {
+ NtClose(RealKey);
+ }
+
+ return ErrorCode;
}
LPCSTR lpSubKey
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
LPCWSTR lpSubKey
)
{
+ UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return ERROR_CALL_NOT_IMPLEMENTED;
}
-/* $Id: console.c,v 1.34 2001/08/14 12:57:15 ea Exp $
+/* $Id: console.c,v 1.35 2001/09/01 15:36:43 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
{
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
+ DWORD NumEventsRead;
NTSTATUS Status;
Request.Type = CSRSS_READ_INPUT;
SetLastErrorByStatus ( Status );
return FALSE;
}
- while( Status == STATUS_PENDING )
+
+ while (Status == STATUS_PENDING)
{
- Status = NtWaitForSingleObject( Reply.Data.ReadInputReply.Event, FALSE, 0 );
+
+ Status = NtWaitForSingleObject( Reply.Data.ReadInputReply.Event, FALSE, 0 );
if( !NT_SUCCESS( Status ) )
{
SetLastErrorByStatus ( Status );
return FALSE;
}
+
+ Request.Type = CSRSS_READ_INPUT;
+ Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
+ Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+ if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+ {
+ SetLastErrorByStatus ( Status );
+ return FALSE;
+ }
+ }
+
+ NumEventsRead = 0;
+ *lpBuffer = Reply.Data.ReadInputReply.Input;
+ lpBuffer++;
+ NumEventsRead++;
+
+ while( ( NumEventsRead < nLength ) && ( Reply.Data.ReadInputReply.MoreEvents ) )
+ {
+
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
SetLastErrorByStatus ( Status );
return FALSE;
}
- }
- *lpNumberOfEventsRead = 1;
+
+ if( Status == STATUS_PENDING )
+ {
+ break;
+ }
+
*lpBuffer = Reply.Data.ReadInputReply.Input;
+ lpBuffer++;
+ NumEventsRead++;
+
+ }
+ *lpNumberOfEventsRead = NumEventsRead;
+
return TRUE;
}
PSMALL_RECT lpWriteRegion
)
{
-/* TO DO */
- return FALSE;
+ PCSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+ DWORD Size;
+
+ Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
+
+ Request = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(CSRSS_API_REQUEST) + Size);
+ if( !Request )
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return FALSE;
+ }
+ Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
+ Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
+ Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
+ Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
+ Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
+ RtlCopyMemory(&Request->Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
+
+ Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
+ if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, Request );
+ SetLastErrorByStatus ( Status );
+ return FALSE;
+ }
+
+ *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
+
+ return TRUE;
}
Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
+ RtlFreeHeap( GetProcessHeap(), 0, Request );
SetLastErrorByStatus ( Status );
return FALSE;
}
Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
+ RtlFreeHeap( GetProcessHeap(), 0, Request );
SetLastErrorByStatus ( Status );
return FALSE;
}
Request.Type = CSRSS_GET_CURSOR_INFO;
Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
SetLastErrorByStatus ( Status );
HANDLE hConsoleInput
)
{
-/* TO DO */
- return FALSE;
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
+ Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
+ Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
+ Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+ if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+ {
+ SetLastErrorByStatus ( Status );
+ return FALSE;
+ }
+ return TRUE;
}
Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+
if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
{
SetLastErrorByStatus ( Status );
CONST CHAR_INFO *lpFill
)
{
-/* TO DO */
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
+ Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
+ Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
+ Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
+
+ if (lpClipRectangle != NULL)
+ {
+ Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
+ Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
+ }
+ else
+ {
+ Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
+ }
+
+ Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
+ Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
+ Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+
+ if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
+ {
+ SetLastErrorByStatus ( Status );
return FALSE;
+ }
+ return TRUE;
}
-/* $Id: registry.c,v 1.6 2001/06/19 15:08:46 ekohl Exp $
+/* $Id: registry.c,v 1.7 2001/09/01 15:36:43 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
(QueryEntry->Name != NULL))
{
if ((QueryEntry->QueryRoutine == NULL) &&
- (QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT) != 0))
+ ((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
{
Status = STATUS_INVALID_PARAMETER;
break;
ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
if (ValueString->Buffer == 0)
{
- /* FIXME: allocate buffer !!! */
-// ValueString->MaximumLength =
-// ValueString->Buffer =
+ RtlInitUnicodeString(ValueString, NULL);
+ ValueString->MaximumLength = 256 * sizeof(WCHAR);
+ ValueString->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ ValueString->MaximumLength);
+ if (!ValueString->Buffer)
+ break;
+ ValueString->Buffer[0] = 0;
}
ValueString->Length = min(ValueInfo->DataLength,
ValueString->MaximumLength - sizeof(WCHAR));
if (RelativeTo & RTL_REGISTRY_HANDLE)
{
- *KeyHandle = (HANDLE)Path;
- return STATUS_SUCCESS;
+ Status = NtDuplicateObject(
+ NtCurrentProcess(),
+ (HANDLE)Path,
+ NtCurrentProcess(),
+ KeyHandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ return Status;
}
if (RelativeTo & RTL_REGISTRY_OPTIONAL)
if (!NT_SUCCESS(Status))
return Status;
break;
+
+ /* ReactOS specific */
+ case RTL_REGISTRY_ENUM:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ break;
+
}
if (Path[0] != L'\\')
{
case KeyBasicInformation:
/* Check size of buffer */
- if (Length < sizeof(KEY_BASIC_INFORMATION) +
- (SubKeyBlock->NameSize ) * sizeof(WCHAR))
+ *ResultLength = sizeof(KEY_BASIC_INFORMATION) +
+ (SubKeyBlock->NameSize ) * sizeof(WCHAR);
+ if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
SubKeyBlock->Name,
SubKeyBlock->NameSize*2);
// BasicInformation->Name[SubKeyBlock->NameSize] = 0;
- *ResultLength = sizeof(KEY_BASIC_INFORMATION) +
- SubKeyBlock->NameSize * sizeof(WCHAR);
}
break;
case KeyNodeInformation:
/* Check size of buffer */
- if (Length < sizeof(KEY_NODE_INFORMATION) +
+ *ResultLength = sizeof(KEY_NODE_INFORMATION) +
(SubKeyBlock->NameSize ) * sizeof(WCHAR) +
- (SubKeyBlock->ClassSize ))
+ (SubKeyBlock->ClassSize );
+ if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
SubKeyBlock->ClassSize);
CmiReleaseBlock(RegistryFile, pClassData);
}
- *ResultLength = sizeof(KEY_NODE_INFORMATION) +
- (SubKeyBlock->NameSize) * sizeof(WCHAR) +
- (SubKeyBlock->ClassSize );
}
break;
case KeyFullInformation:
/* check size of buffer */
- if (Length < sizeof(KEY_FULL_INFORMATION) +
- SubKeyBlock->ClassSize)
+ *ResultLength = sizeof(KEY_FULL_INFORMATION) +
+ SubKeyBlock->ClassSize;
+ if (Length < *ResultLength)
{
Status = STATUS_BUFFER_OVERFLOW;
}
SubKeyBlock->ClassSize);
CmiReleaseBlock(RegistryFile, pClassData);
}
- *ResultLength = sizeof(KEY_FULL_INFORMATION) +
- SubKeyBlock->ClassSize ;
}
break;
}
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
char ValueName2[MAX_PATH];
+ DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x )\n",
+ KeyHandle, ValueName->Buffer, Length);
+
wcstombs(ValueName2,ValueName->Buffer,ValueName->Length>>1);
ValueName2[ValueName->Length>>1]=0;
NULL);
if (!NT_SUCCESS(Status))
{
+ DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
return Status;
}
&ValueBlock,NULL);
if (!NT_SUCCESS(Status))
{
+ DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
ObDereferenceObject(KeyObject);
return Status;
}
ValueBlock->NameSize * sizeof(WCHAR);
if (Length < *ResultLength)
{
- Status = STATUS_BUFFER_OVERFLOW;
+ Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
(ValueBlock->DataSize & LONG_MAX);
if (Length < *ResultLength)
{
- Status = STATUS_BUFFER_OVERFLOW;
+ Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
+ (ValueBlock->DataSize & LONG_MAX);
if (Length < *ResultLength)
{
- Status = STATUS_BUFFER_OVERFLOW;
+ Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
}
else
{
- Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
ObDereferenceObject(KeyObject);
PHEAP_BLOCK pHeap;
// KIRQL OldIrql;
+ DPRINT1("KeyHandle %x ValueName %S Type %d\n",
+ KeyHandle, ValueName->Buffer, Type);
+
wcstombs(ValueName2,ValueName->Buffer,ValueName->Length>>1);
ValueName2[ValueName->Length>>1]=0;
UserMode,
(PVOID *)&KeyObject,
NULL);
+ DPRINT1("Status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
return Status;
&ValueBlock, &VBOffset);
if (!NT_SUCCESS(Status))
{
+ DPRINT1("Not found Status 0x%X\n", Status);
+
ObDereferenceObject (KeyObject);
return Status;
}
}
if (!NT_SUCCESS(Status))
{
+ DPRINT1("Cannot Add Status 0x%X\n", Status);
ObDereferenceObject (KeyObject);
return Status;
}
// KeReleaseSpinLock(&RegistryFile->RegLock, OldIrql);
ObDereferenceObject (KeyObject);
+ DPRINT1("Return Status 0x%X\n", Status);
+
return Status;
}
OUT PVALUE_BLOCK *ValueBlock,
OUT BLOCK_OFFSET *VBOffset)
{
+ ULONG Length;
ULONG Idx;
PVALUE_LIST_BLOCK ValueListBlock;
PVALUE_BLOCK CurValueBlock;
*ValueBlock = NULL;
if (ValueListBlock == NULL)
{
+ DPRINT("ValueListBlock is NULL\n");
return STATUS_SUCCESS;
}
for (Idx = 0; Idx < KeyBlock->NumberOfValues; Idx++)
ValueListBlock->Values[Idx],NULL);
/* FIXME : perhaps we must not ignore case if NtCreateKey has not been */
/* called with OBJ_CASE_INSENSITIVE flag ? */
- if (CurValueBlock != NULL &&
- CurValueBlock->NameSize == strlen(ValueName) &&
- !_strnicmp(CurValueBlock->Name, ValueName,strlen(ValueName)))
+ Length = strlen(ValueName);
+ if ((CurValueBlock != NULL) &&
+ (CurValueBlock->NameSize == Length) &&
+ (_strnicmp(CurValueBlock->Name, ValueName, Length) == 0))
{
*ValueBlock = CurValueBlock;
if(VBOffset) *VBOffset = ValueListBlock->Values[Idx];
+ DPRINT("Found value %s\n", ValueName);
break;
}
CmiReleaseBlock(RegistryFile, CurValueBlock);
IN PVOID Context,
IN PVOID Environment)
{
- UNIMPLEMENTED;
+ NTSTATUS Status;
+ HANDLE BaseKeyHandle;
+ HANDLE CurrentKeyHandle;
+ PRTL_QUERY_REGISTRY_TABLE QueryEntry;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+ ULONG BufferSize;
+ ULONG ResultSize;
+
+ DPRINT("RtlQueryRegistryValues() called\n");
+
+ Status = RtlpGetRegistryHandle(RelativeTo,
+ Path,
+ FALSE,
+ &BaseKeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlpGetRegistryHandle() failed with status %x\n", Status);
+ return Status;
+ }
+
+ CurrentKeyHandle = BaseKeyHandle;
+ QueryEntry = QueryTable;
+ while ((QueryEntry->QueryRoutine != NULL) ||
+ (QueryEntry->Name != NULL))
+ {
+ //CSH: Was:
+ //if ((QueryEntry->QueryRoutine == NULL) &&
+ // ((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_DIRECT)) != 0))
+ // Which is more correct?
+ if ((QueryEntry->QueryRoutine == NULL) &&
+ ((QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY) != 0))
+ {
+ DPRINT("Bad parameters\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ DPRINT("Name: %S\n", QueryEntry->Name);
+
+ if (((QueryEntry->Flags & (RTL_QUERY_REGISTRY_SUBKEY | RTL_QUERY_REGISTRY_TOPKEY)) != 0) &&
+ (BaseKeyHandle != CurrentKeyHandle))
+ {
+ NtClose(CurrentKeyHandle);
+ CurrentKeyHandle = BaseKeyHandle;
+ }
+
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_SUBKEY)
+ {
+ DPRINT("Open new subkey: %S\n", QueryEntry->Name);
+
+ RtlInitUnicodeString(&KeyName,
+ QueryEntry->Name);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ BaseKeyHandle,
+ NULL);
+ Status = NtOpenKey(&CurrentKeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ else if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DIRECT)
+ {
+ DPRINT("Query value directly: %S\n", QueryEntry->Name);
+
+ RtlInitUnicodeString(&KeyName,
+ QueryEntry->Name);
+
+ BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + 4096;
+ ValueInfo = ExAllocatePool(PagedPool, BufferSize);
+ if (ValueInfo == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ Status = ZwQueryValueKey(CurrentKeyHandle,
+ &KeyName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwQueryValueKey() failed with status %x\n", Status);
+ ExFreePool(ValueInfo);
+ break;
+ }
+ else
+ {
+ if (ValueInfo->Type == REG_SZ)
+ {
+ PUNICODE_STRING ValueString;
+ ValueString = (PUNICODE_STRING)QueryEntry->EntryContext;
+ if (ValueString->Buffer == 0)
+ {
+ RtlInitUnicodeString(ValueString, NULL);
+ ValueString->MaximumLength = 256 * sizeof(WCHAR);
+ ValueString->Buffer = ExAllocatePool(PagedPool, ValueString->MaximumLength);
+ if (!ValueString->Buffer)
+ break;
+ ValueString->Buffer[0] = 0;
+ }
+ ValueString->Length = RtlMin(ValueInfo->DataLength,
+ ValueString->MaximumLength - sizeof(WCHAR));
+ memcpy(ValueString->Buffer,
+ ValueInfo->Data,
+ ValueInfo->DataLength);
+ ((PWSTR)ValueString->Buffer)[ValueString->Length / sizeof(WCHAR)] = 0;
+ }
+ else
+ {
+ memcpy(QueryEntry->EntryContext,
+ ValueInfo->Data,
+ ValueInfo->DataLength);
+ }
+ }
+
+ ExFreePool (ValueInfo);
+ }
+ else
+ {
+ DPRINT("Query value via query routine: %S\n", QueryEntry->Name);
+
+ }
+
+ if (QueryEntry->Flags & RTL_QUERY_REGISTRY_DELETE)
+ {
+ DPRINT("Delete value: %S\n", QueryEntry->Name);
+
+ }
+
+ QueryEntry++;
+ }
+
+ if (CurrentKeyHandle != BaseKeyHandle)
+ NtClose(CurrentKeyHandle);
+
+ NtClose(BaseKeyHandle);
+
+ return Status;
}
if (RelativeTo & RTL_REGISTRY_HANDLE)
{
- *KeyHandle = (HANDLE)Path;
- return STATUS_SUCCESS;
+ Status = NtDuplicateObject(
+ PsGetCurrentProcessId(),
+ (PHANDLE)&Path,
+ PsGetCurrentProcessId(),
+ KeyHandle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ return Status;
}
if (RelativeTo & RTL_REGISTRY_OPTIONAL)
if (!NT_SUCCESS(Status))
return Status;
break;
+
+ /* ReactOS specific */
+ case RTL_REGISTRY_ENUM:
+ RtlAppendUnicodeToString(&KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ break;
}
if (Path[0] != L'\\')
- RtlAppendUnicodeToString(&KeyName,
- L"\\");
-
- RtlAppendUnicodeToString(&KeyName,
- Path);
+ {
+ RtlAppendUnicodeToString(&KeyName,
+ Path);
+ }
+ else
+ {
+ Path++;
+ RtlAppendUnicodeToString(&KeyName,
+ Path);
+ }
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
return Status;
}
+
+
+NTSTATUS
+RtlpCreateRegistryKeyPath(PWSTR Path)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ WCHAR KeyBuffer[MAX_PATH];
+ UNICODE_STRING KeyName;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ PWCHAR Current;
+ PWCHAR Next;
+
+ if (_wcsnicmp(Path, L"\\Registry\\", 10) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ wcsncpy(KeyBuffer, Path, MAX_PATH-1);
+ RtlInitUnicodeString(&KeyName, KeyBuffer);
+
+ /* Skip \\Registry\\ */
+ Current = KeyName.Buffer;
+ Current = wcschr(Current, '\\') + 1;
+ Current = wcschr(Current, '\\') + 1;
+
+ do {
+ Next = wcschr(Current, '\\');
+ if (Next == NULL)
+ {
+ /* The end */
+ }
+ else
+ {
+ *Next = 0;
+ }
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ DPRINT("Create '%S'\n", KeyName.Buffer);
+
+ Status = NtCreateKey(
+ &KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ 0,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtCreateKey() failed with status %x\n", Status);
+ return Status;
+ }
+
+ NtClose(KeyHandle);
+
+ if (Next != NULL)
+ {
+ *Next = L'\\';
+ }
+
+ Current = Next + 1;
+ } while (Next != NULL);
+
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: io.h,v 1.12 2001/08/26 17:25:29 ekohl Exp $
+/* $Id: io.h,v 1.13 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
struct _DEVICE_NODE *PrevSibling;
struct _DEVICE_NODE *NextSibling;
struct _DEVICE_NODE *Child;
+ PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT Pdo;
UNICODE_STRING InstancePath;
UNICODE_STRING ServiceName;
} DEVICE_NODE, *PDEVICE_NODE;
/* For Flags field */
-#define DNF_MADEUP 0x0001
-#define DNF_HAL_NODE 0x0002
-#define DNF_PROCESSED 0x0004
-#define DNF_ENUMERATED 0x0008
-#define DNF_ADDED 0x0010
-#define DNF_HAS_BOOT_CONFIG 0x0020
-#define DNF_BOOT_CONFIG_RESERVED 0x0040
-#define DNF_RESOURCE_ASSIGNED 0x0080
-#define DNF_NO_RESOURCE_REQUIRED 0x0100
-#define DNF_STARTED 0x0200
-#define DNF_LEGACY_DRIVER 0x0400
-#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x0800
-#define DNF_HAS_PROBLEM 0x1000
+#define DNF_PROCESSED 0x00000001
+#define DNF_STARTED 0x00000002
+#define DNF_START_FAILED 0x00000004
+#define DNF_ENUMERATED 0x00000008
+#define DNF_DELETED 0x00000010
+#define DNF_MADEUP 0x00000020
+#define DNF_START_REQUEST_PENDING 0x00000040
+#define DNF_NO_RESOURCE_REQUIRED 0x00000080
+#define DNF_INSUFFICIENT_RESOURCES 0x00000100
+#define DNF_RESOURCE_ASSIGNED 0x00000200
+#define DNF_RESOURCE_REPORTED 0x00000400
+#define DNF_HAL_NODE 0x00000800 // ???
+#define DNF_ADDED 0x00001000
+#define DNF_ADD_FAILED 0x00002000
+#define DNF_LEGACY_DRIVER 0x00004000
+#define DNF_STOPPED 0x00008000
+#define DNF_WILL_BE_REMOVED 0x00010000
+#define DNF_NEED_TO_ENUM 0x00020000
+#define DNF_NOT_CONFIGURED 0x00040000
+#define DNF_REINSTALL 0x00080000
+#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ???
+#define DNF_DISABLED 0x00200000
+#define DNF_RESTART_OK 0x00400000
+#define DNF_NEED_RESTART 0x00800000
+#define DNF_VISITED 0x01000000
+#define DNF_ASSIGNING_RESOURCES 0x02000000
+#define DNF_BEEING_ENUMERATED 0x04000000
+#define DNF_NEED_ENUMERATION_ONLY 0x08000000
+#define DNF_LOCKED 0x10000000
+#define DNF_HAS_BOOT_CONFIG 0x20000000
+#define DNF_BOOT_CONFIG_RESERVED 0x40000000
+#define DNF_HAS_PROBLEM 0x80000000 // ???
/* For UserFlags field */
#define DNUF_DONT_SHOW_IN_UI 0x0002
#define DNUF_NOT_DISABLEABLE 0x0008
/* For Problem field */
-#define CM_PROB_FAILED_INSTALL 0x0001
+#define CM_PROB_NOT_CONFIGURED 1
+#define CM_PROB_FAILED_START 10
+#define CM_PROB_NORMAL_CONFLICT 12
+#define CM_PROB_NEED_RESTART 14
+#define CM_PROB_REINSTALL 18
+#define CM_PROB_WILL_BE_REMOVED 21
+#define CM_PROB_DISABLED 22
+#define CM_PROB_FAILED_INSTALL 28
+#define CM_PROB_FAILED_ADD 31
extern PDEVICE_NODE IopRootDeviceNode;
NTSTATUS
IopCreateDriverObject(PDRIVER_OBJECT *DriverObject);
NTSTATUS
+IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode);
+NTSTATUS
IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
- PDEVICE_NODE ParentDeviceNode,
- PUNICODE_STRING Filename,
- BOOLEAN BootDriversOnly);
+ PDEVICE_NODE DeviceNode);
VOID
IoInitCancelHandling(VOID);
VOID
PLARGE_INTEGER Offset,
PIO_STATUS_BLOCK StatusBlock);
+NTSTATUS
+IopInitiatePnpIrp(
+ PDEVICE_OBJECT DeviceObject,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG MinorFunction,
+ PIO_STACK_LOCATION Stack);
+
#endif
#include <pe.h>
#include <internal/io.h>
#include <ntdll/ldr.h>
+#include <internal/module.h>
NTSTATUS
LdrLoadDriver (
PVOID ImportModuleBase,
PULONG DriverSize);
+PMODULE_OBJECT
+LdrLoadModule(PUNICODE_STRING Filename);
+
+NTSTATUS LdrFindModuleObject(
+ PUNICODE_STRING ModuleName,
+ PMODULE_OBJECT *ModuleObject);
+
extern ULONG_PTR LdrHalBase;
#endif /* __INCLUDE_INTERNAL_LDR_H */
BOOLEAN Create,
PHANDLE KeyHandle);
+NTSTATUS
+RtlpCreateRegistryKeyPath(PWSTR Path);
+
#endif /* __INCLUDE_INTERNAL_REGISTRY_H */
-/* $Id: create.c,v 1.47 2001/08/26 17:27:00 ekohl Exp $
+/* $Id: create.c,v 1.48 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
&& (DeviceObject->DeviceType != FILE_DEVICE_MAILSLOT))
{
CPRINT ("Device was wrong type\n");
- assert(FALSE);
return (STATUS_UNSUCCESSFUL);
}
-/* $Id: device.c,v 1.32 2001/08/30 20:38:19 dwelch Exp $
+/* $Id: device.c,v 1.33 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include <internal/id.h>
#include <internal/ps.h>
#include <internal/pool.h>
+#include <internal/registry.h>
+
#include <roscfg.h>
#define NDEBUG
return STATUS_SUCCESS;
}
+NTSTATUS
+IopAttachFilterDrivers(PDEVICE_NODE DeviceNode,
+ BOOLEAN Lower)
+{
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
-IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
- PDEVICE_NODE DeviceNode,
- PUNICODE_STRING Filename,
+IopInitializeDevice(PDEVICE_NODE DeviceNode,
BOOLEAN BootDriversOnly)
-/*
- * FUNCTION: Called to initalize a loaded driver
- * ARGUMENTS:
- */
{
IO_STATUS_BLOCK IoStatusBlock;
PDRIVER_OBJECT DriverObject;
- PIO_STACK_LOCATION IrpSp;
+ IO_STACK_LOCATION Stack;
PDEVICE_OBJECT Fdo;
NTSTATUS Status;
- KEVENT Event;
- PIRP Irp;
- WCHAR DriverName [MAX_PATH];
- WCHAR RegistryKeyBuffer [MAX_PATH];
- UNICODE_STRING RegistryKey;
- DPRINT("IopInitializeDriver (DriverEntry %08lx, DeviceNode %08lx, "
- "BootDriversOnly %d)\n", DriverEntry, DeviceNode, BootDriversOnly);
-
- Status = IopCreateDriverObject(&DriverObject);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- if (Filename != 0)
- {
- if (wcsrchr (Filename->Buffer, '\\') != 0)
- {
- wcscpy (DriverName, wcsrchr (Filename->Buffer, '\\'));
- }
- else
- {
- wcscpy (DriverName, Filename->Buffer);
- }
- if (wcsrchr (DriverName, '.') != 0)
- {
- *(wcsrchr (DriverName, '.')) = 0;
- }
- wcscpy (RegistryKeyBuffer, DRIVER_REGISTRY_KEY_BASENAME);
- wcscpy (RegistryKeyBuffer, DriverName);
- RtlInitUnicodeString (&RegistryKey, RegistryKeyBuffer);
- DPRINT("RegistryKey: %wZ\n", &RegistryKey);
- }
-
- DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
- Status = DriverEntry(DriverObject, Filename != 0 ? &RegistryKey : 0);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(DriverObject->DriverExtension);
- ExFreePool(DriverObject);
- return(Status);
- }
+ DriverObject = DeviceNode->DriverObject;
if (DriverObject->DriverExtension->AddDevice)
{
KeBugCheck(0);
}
- KeInitializeEvent(&Event,
- NotificationEvent,
- FALSE);
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
- Fdo,
- NULL,
- 0,
- NULL,
- &Event,
- &IoStatusBlock);
-
- IrpSp = IoGetNextIrpStackLocation(Irp);
- IrpSp->MinorFunction = IRP_MN_START_DEVICE;
-
/* FIXME: Put some resources in the IRP for the device */
+ Stack.Parameters.StartDevice.AllocatedResources = NULL;
+ Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL;
- Status = IoCallDriver(Fdo, Irp);
-
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- Status = IoStatusBlock.Status;
- }
+ Status = IopInitiatePnpIrp(
+ Fdo,
+ &IoStatusBlock,
+ IRP_MN_START_DEVICE,
+ &Stack);
if (!NT_SUCCESS(Status))
{
+ DPRINT("IopInitiatePnpIrp() failed\n");
ObDereferenceObject(Fdo);
ExFreePool(DriverObject->DriverExtension);
ExFreePool(DriverObject);
#ifdef ACPI
static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
- /* The system power device node is the first bus enumerator
- device node created after the root device node */
+ /* There can be only one system power device */
if (!SystemPowerDeviceNodeCreated)
{
PopSystemPowerDeviceNode = DeviceNode;
ObDereferenceObject(Fdo);
}
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IopInitializeService(
+ PDEVICE_NODE DeviceNode,
+ PUNICODE_STRING ImagePath)
+{
+ PMODULE_OBJECT ModuleObject;
+ NTSTATUS Status;
+
+ Status = LdrFindModuleObject(&DeviceNode->ServiceName, &ModuleObject);
+ if (!NT_SUCCESS(Status))
+ {
+ /* The module is currently not loaded, so load it now */
+
+ ModuleObject = LdrLoadModule(ImagePath);
+ if (!ModuleObject)
+ {
+ /* FIXME: Log the error */
+ CPRINT("Driver load failed\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ /* FIXME: Log the error */
+ CPRINT("A driver failed to initialize\n");
+ return Status;
+ }
+ }
+
+ ObDereferenceObject(ModuleObject);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IopInitializeDeviceNodeService(
+ PDEVICE_NODE DeviceNode)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ UNICODE_STRING ImagePath;
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+
+ Status = RtlpGetRegistryHandle(
+ RTL_REGISTRY_SERVICES,
+ DeviceNode->ServiceName.Buffer,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
+ return Status;
+ }
+
+ RtlZeroMemory(QueryTable, sizeof(QueryTable));
+
+ RtlInitUnicodeString(&ImagePath, NULL);
+
+ QueryTable[0].Name = L"ImagePath";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &ImagePath;
+
+ Status = RtlQueryRegistryValues(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ QueryTable,
+ NULL,
+ NULL);
+ NtClose(KeyHandle);
+
+ DPRINT("RtlQueryRegistryValues() returned status %x\n", Status);
+
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Got ImagePath %S\n", ImagePath.Buffer);
+
+ Status = IopInitializeService(DeviceNode, &ImagePath);
+
+ RtlFreeUnicodeString(&ImagePath);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
+ PDEVICE_NODE DeviceNode)
+/*
+ * FUNCTION: Called to initalize a loaded driver
+ * ARGUMENTS:
+ */
+{
+ WCHAR RegistryKeyBuffer[MAX_PATH];
+ PDRIVER_OBJECT DriverObject;
+ UNICODE_STRING RegistryKey;
+ NTSTATUS Status;
+
+ DPRINT("IopInitializeDriver(DriverEntry %08lx, DeviceNode %08lx)\n",
+ DriverEntry, DeviceNode);
+
+ Status = IopCreateDriverObject(&DriverObject);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ DeviceNode->DriverObject = DriverObject;
+
+ if (DeviceNode->ServiceName.Buffer)
+ {
+ wcscpy(RegistryKeyBuffer, DRIVER_REGISTRY_KEY_BASENAME);
+ wcscat(RegistryKeyBuffer, DeviceNode->ServiceName.Buffer);
+ RtlInitUnicodeString(&RegistryKey, RegistryKeyBuffer);
+ }
+ else
+ {
+ RtlInitUnicodeString(&RegistryKey, NULL);
+ }
+
+ DPRINT("RegistryKey: %wZ\n", &RegistryKey);
+ DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry);
+
+ Status = DriverEntry(DriverObject, &RegistryKey);
+ if (!NT_SUCCESS(Status))
+ {
+ DeviceNode->DriverObject = NULL;
+ ExFreePool(DriverObject->DriverExtension);
+ ExFreePool(DriverObject);
+ return(Status);
+ }
+
+ Status = IopInitializeDevice(DeviceNode, TRUE);
+
return(Status);
}
-/* $Id: pnpmgr.c,v 1.2 2001/05/01 23:08:19 chorns Exp $
+/* $Id: pnpmgr.c,v 1.3 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
IopCreateDeviceNode(PDEVICE_NODE ParentNode,
PDEVICE_OBJECT PhysicalDeviceObject,
PDEVICE_NODE *DeviceNode)
-/* */
{
PDEVICE_NODE Node;
NTSTATUS Status;
KIRQL OldIrql;
- DPRINT("ParentNode %x PhysicalDeviceObject %x\n");
+ DPRINT("ParentNode %x PhysicalDeviceObject %x\n",
+ ParentNode, PhysicalDeviceObject);
Node = (PDEVICE_NODE)ExAllocatePool(PagedPool, sizeof(DEVICE_NODE));
if (!Node)
KeReleaseSpinLock(&IopDeviceTreeLock, OldIrql);
+ RtlFreeUnicodeString(&DeviceNode->InstancePath);
+
+ RtlFreeUnicodeString(&DeviceNode->ServiceName);
+
+ /* FIXME: Other fields may need to be released */
+
ExFreePool(DeviceNode);
return STATUS_SUCCESS;
}
NTSTATUS
-IopInterrogateBusExtender(PDEVICE_NODE DeviceNode,
- PDEVICE_OBJECT FunctionDeviceObject,
- BOOLEAN BootDriversOnly)
+IopInitiatePnpIrp(
+ PDEVICE_OBJECT DeviceObject,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG MinorFunction,
+ PIO_STACK_LOCATION Stack)
{
- IO_STATUS_BLOCK IoStatusBlock;
+ PDEVICE_OBJECT TopDeviceObject;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
- DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to bus driver\n");
+ /* Always call the top of the device stack */
+ TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
- KeInitializeEvent(&Event,
+ KeInitializeEvent(
+ &Event,
NotificationEvent,
FALSE);
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
- FunctionDeviceObject,
+ /* PNP IRPs are always initialized with a status code of
+ STATUS_NOT_IMPLEMENTED */
+ IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
+
+ Irp = IoBuildSynchronousFsdRequest(
+ IRP_MJ_PNP,
+ TopDeviceObject,
NULL,
0,
NULL,
&Event,
- &IoStatusBlock);
+ IoStatusBlock);
IrpSp = IoGetNextIrpStackLocation(Irp);
- IrpSp->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
- IrpSp->Parameters.QueryDeviceRelations.Type = BusRelations;
+ IrpSp->MinorFunction = MinorFunction;
+ RtlMoveMemory(
+ &IrpSp->Parameters,
+ &Stack->Parameters,
+ sizeof(Stack->Parameters));
- Status = IoCallDriver(FunctionDeviceObject, Irp);
+ Status = IoCallDriver(TopDeviceObject, Irp);
if (Status == STATUS_PENDING)
{
- KeWaitForSingleObject(&Event,
+ KeWaitForSingleObject(
+ &Event,
Executive,
KernelMode,
FALSE,
NULL);
- Status = IoStatusBlock.Status;
+ Status = IoStatusBlock->Status;
+ }
+
+ return Status;
+}
+
+NTSTATUS
+IopInterrogateBusExtender(
+ PDEVICE_NODE DeviceNode,
+ PDEVICE_OBJECT FunctionDeviceObject,
+ BOOLEAN BootDriversOnly)
+{
+ PDEVICE_RELATIONS DeviceRelations;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING DriverName;
+ IO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+
+ DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to bus driver\n");
+
+ Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
+
+ Status = IopInitiatePnpIrp(
+ FunctionDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_DEVICE_RELATIONS,
+ &Stack);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopInitiatePnpIrp() failed\n");
+ }
+
+ DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
+
+ DPRINT("Got %d PDOs\n", DeviceRelations->Count);
+
+ if (DeviceRelations->Count <= 0)
+ {
+ DPRINT("No PDOs\n");
+ ExFreePool(DeviceRelations);
+ return STATUS_SUCCESS;
}
+
+ Status = IopCreateDeviceNode(DeviceNode, NULL, &DeviceNode);
if (!NT_SUCCESS(Status))
{
- CPRINT("IoCallDriver() failed\n");
+ DPRINT("No resources\n");
+ ExFreePool(DeviceRelations);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
+ /* FIXME: Use registry to find name of driver and only load driver if not
+ already loaded. If loaded, just call AddDevice() */
+ Status = LdrLoadDriver(&DriverName, DeviceNode, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Don't free the device node, just log the error and return */
+ /* FIXME: Log the error */
+ CPRINT("Driver load failed, status (%x)\n", Status);
+ ExFreePool(DeviceRelations);
+ return Status;
+ }
+
+ ExFreePool(DeviceRelations);
+
return Status;
}
VOID IopLoadBootStartDrivers(VOID)
{
- UNICODE_STRING DriverName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PKEY_BASIC_INFORMATION KeyInfo;
PDEVICE_NODE DeviceNode;
+ UNICODE_STRING KeyName;
+ HANDLE KeyHandle;
+ ULONG BufferSize;
+ ULONG ResultSize;
NTSTATUS Status;
+ ULONG Index;
DPRINT("Loading boot start drivers\n");
-return;
-
- /* FIXME: Get these from registry */
-
- /* Use IopRootDeviceNode for now */
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
+ BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
+ KeyInfo = ExAllocatePool(PagedPool, BufferSize);
+ if (!KeyInfo)
+ {
+ return;
+ }
+
+ RtlInitUnicodeString(
+ &KeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
if (!NT_SUCCESS(Status))
{
+ DPRINT("NtOpenKey() failed (Status %x)\n", Status);
+ ExFreePool(KeyInfo);
return;
}
- /*
- * ISA Plug and Play driver
- */
- RtlInitUnicodeString(&DriverName,
- L"\\SystemRoot\\system32\\drivers\\isapnp.sys");
- Status = LdrLoadDriver(&DriverName, DeviceNode, TRUE);
- if (!NT_SUCCESS(Status))
+ Index = 0;
+ do {
+ Status = ZwEnumerateKey(
+ KeyHandle,
+ Index,
+ KeyBasicInformation,
+ KeyInfo,
+ BufferSize,
+ &ResultSize);
+ if (!NT_SUCCESS(Status))
{
- IopFreeDeviceNode(DeviceNode);
+ DPRINT("ZwEnumerateKey() (Status %x)\n", Status);
+ break;
+ }
+
+ /* Terminate the string */
+ KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
+
+ /* Use IopRootDeviceNode for now */
+ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IopCreateDeviceNode() failed with status 0x%X\n", Status);
+ break;
+ }
+
+ if (!RtlCreateUnicodeString(&DeviceNode->ServiceName, KeyInfo->Name))
+ {
+ CPRINT("RtlCreateUnicodeString() failed\n");
+ IopFreeDeviceNode(DeviceNode);
+ break;
+ }
+ Status = IopInitializeDeviceNodeService(DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
/* FIXME: Write an entry in the system error log */
- DbgPrint("Could not load boot start driver: %wZ, status 0x%X\n",
- &DriverName, Status);
- return;
+ CPRINT("Could not load boot start driver: %wZ, status 0x%X\n",
+ &DeviceNode->ServiceName, Status);
+
+ IopFreeDeviceNode(DeviceNode);
}
+
+ Index++;
+ } while (TRUE);
+
+ DPRINT("Services found: %d\n", Index);
+
+ NtClose(KeyHandle);
+
+ ExFreePool(KeyInfo);
}
VOID PnpInit(VOID)
Status = IopCreateDriverObject(&IopRootDriverObject);
if (!NT_SUCCESS(Status))
{
- DbgPrint("IoCreateDriverObject() failed\n");
+ CPRINT("IoCreateDriverObject() failed\n");
KeBugCheck(0);
}
FILE_DEVICE_CONTROLLER, 0, FALSE, &IopRootDeviceNode->Pdo);
if (!NT_SUCCESS(Status))
{
- DbgPrint("IoCreateDevice() failed\n");
+ CPRINT("IoCreateDevice() failed\n");
KeBugCheck(0);
}
-/* $Id: pnproot.c,v 1.4 2001/08/27 01:20:50 ekohl Exp $
+/* $Id: pnproot.c,v 1.5 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
DPRINT("Called\n");
+ Status = Irp->IoStatus.Status;
+
IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
switch (IrpSp->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: main.c,v 1.103 2001/09/01 11:55:37 dwelch Exp $
+/* $Id: main.c,v 1.104 2001/09/01 15:36:44 chorns Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
#include <internal/kd.h>
#include <internal/trap.h>
#include "../dbg/kdb.h"
+#include <internal/registry.h>
#ifdef HALDBG
#include <internal/ntosdbg.h>
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+typedef struct
+{
+ LPWSTR ServiceName;
+ LPWSTR DeviceDesc;
+ LPWSTR Group;
+ DWORD Start;
+ DWORD Type;
+} SERVICE, *PSERVICE;
+
+SERVICE Services[] = {
+ {L"keyboard", L"Standard Keyboard Driver", L"Base", 0, 1},
+ {L"blue", L"Bluescreen Driver", L"Base", 0, 1},
+ {L"vidport", L"Video Port Driver", L"Base", 0, 1},
+ {L"vgamp", L"VGA Miniport", L"Base", 0, 1},
+ {L"minixfs", L"Minix File System", L"File system", 0, 1},
+ {L"msfs", L"Mail Slot File System", L"File system", 0, 1},
+ {L"npfs", L"Named Pipe File System", L"File system", 0, 1},
+ {L"psaux", L"PS/2 Auxillary Port Driver", L"", 0, 1},
+ {L"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
+ {L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 0, 1},
+ {L"ne2000", L"Novell Eagle 2000 Driver", L"NDIS", 0, 1},
+ {L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},
+ {NULL,}
+};
+
/* FUNCTIONS ****************************************************************/
+VOID CreateDefaultRegistryForLegacyDriver(
+ PSERVICE Service)
+{
+ WCHAR LegacyDriver[] = L"LegacyDriver";
+ WCHAR InstancePath[MAX_PATH];
+ WCHAR KeyNameBuffer[MAX_PATH];
+ WCHAR Name[MAX_PATH];
+ UNICODE_STRING KeyName;
+ HANDLE KeyHandle;
+ DWORD DwordData;
+ ULONG Length;
+ NTSTATUS Status;
+ WCHAR ImagePath[MAX_PATH];
+
+ /* Enum section */
+ wcscpy(Name, Service->ServiceName);
+ _wcsupr(Name);
+ wcscpy(InstancePath, L"Root\\LEGACY_");
+ wcscat(InstancePath, Name);
+ wcscat(InstancePath, L"\\0000");
+
+ wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ wcscat(KeyNameBuffer, InstancePath);
+
+ RtlInitUnicodeString(&KeyName, KeyNameBuffer);
+
+ DPRINT("Key name is %S\n", KeyName.Buffer);
+
+ Status = RtlpCreateRegistryKeyPath(KeyName.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status);
+ return;
+ }
+
+ Status = RtlpGetRegistryHandle(
+ RTL_REGISTRY_ENUM,
+ InstancePath,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
+ return;
+ }
+
+ DwordData = 0;
+ Length = sizeof(DWORD);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Capabilities",
+ REG_DWORD,
+ (LPWSTR)&DwordData,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ Length = (wcslen(LegacyDriver) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Class",
+ REG_SZ,
+ LegacyDriver,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"DeviceDesc",
+ REG_SZ,
+ Service->DeviceDesc,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ DwordData = 0;
+ Length = Length = sizeof(DWORD);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Legacy",
+ REG_DWORD,
+ (LPWSTR)&DwordData,
+ sizeof(DWORD));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Service",
+ REG_SZ,
+ Service->ServiceName,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ NtClose(KeyHandle);
+
+ /* Services section */
+
+ Status = RtlpGetRegistryHandle(
+ RTL_REGISTRY_SERVICES,
+ Service->ServiceName,
+ TRUE,
+ &KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
+ return;
+ }
+
+ Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"DisplayName",
+ REG_SZ,
+ Service->DeviceDesc,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ DwordData = 1;
+ Length = sizeof(DWORD);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"ErrorControl",
+ REG_DWORD,
+ (LPWSTR)&DwordData,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ Length = (wcslen(Service->Group) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Group",
+ REG_SZ,
+ Service->Group,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
+ wcscat(ImagePath, Service->ServiceName);
+ wcscat(ImagePath, L".sys");
+
+ Length = (wcslen(ImagePath) + 1) * sizeof(WCHAR);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"ImagePath",
+ REG_SZ,
+ ImagePath,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ DwordData = Service->Start;
+ Length = sizeof(DWORD);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Start",
+ REG_DWORD,
+ (LPWSTR)&DwordData,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ DwordData = Service->Type;
+ Length = sizeof(DWORD);
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_HANDLE,
+ (PWSTR)KeyHandle,
+ L"Type",
+ REG_DWORD,
+ (LPWSTR)&DwordData,
+ Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
+ NtClose(KeyHandle);
+ return;
+ }
+
+ NtClose(KeyHandle);
+}
+
+VOID CreateDefaultRegistry()
+{
+ NTSTATUS Status;
+ ULONG i;
+
+ Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
+ return;
+ }
+
+ Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
+ return;
+ }
+
+ for (i = 0; Services[i].ServiceName != NULL; i++)
+ {
+ CreateDefaultRegistryForLegacyDriver(&Services[i]);
+ }
+}
+
+
static BOOLEAN
RtlpCheckFileNameExtension(PCHAR FileName,
PCHAR Extension)
CmInitializeRegistry2();
+#if 0
+ CreateDefaultRegistry();
+#endif
+
PiInitDefaultLocale();
/*
* Start the motherboard enumerator (the HAL)
*/
HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
+#if 0
/*
* Load boot start drivers
*/
IopLoadBootStartDrivers();
-
+#else
/*
* Load Auto configured drivers
*/
LdrLoadAutoConfigDrivers();
-
+#endif
/*
* Assign drive letters
*/
* This should be done by the boot loader.
*/
strcpy (KeLoaderCommandLine,
- "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
+ "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=COM1");
strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
-/* $Id: loader.c,v 1.88 2001/08/30 20:38:20 dwelch Exp $
+/* $Id: loader.c,v 1.89 2001/09/01 15:36:44 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
ExFreePool(FileBuffer);
}
-NTSTATUS LdrpFindModuleObject(
+#endif /* KDBG */
+
+
+NTSTATUS LdrFindModuleObject(
PUNICODE_STRING ModuleName,
PMODULE_OBJECT *ModuleObject)
{
return STATUS_SUCCESS;
}
-#endif /* KDBG */
-
VOID LdrLoadAutoConfigDrivers (VOID)
{
is created after their module entries */
RtlInitUnicodeString(&ModuleName, KERNEL_MODULE_NAME);
- Status = LdrpFindModuleObject(&ModuleName, &ModuleObject);
+ Status = LdrFindModuleObject(&ModuleName, &ModuleObject);
if (NT_SUCCESS(Status))
{
LdrpLoadModuleSymbols(ModuleObject);
}
RtlInitUnicodeString(&ModuleName, HAL_MODULE_NAME);
- Status = LdrpFindModuleObject(&ModuleName, &ModuleObject);
+ Status = LdrFindModuleObject(&ModuleName, &ModuleObject);
if (NT_SUCCESS(Status))
{
LdrpLoadModuleSymbols(ModuleObject);
}
+
#endif /* KDBG */
/*
/*
* Ancillary Function Driver
*/
- LdrLoadAutoConfigDriver(L"afd.sys");
+ //LdrLoadAutoConfigDriver(L"afd.sys");
#endif
}
return STATUS_UNSUCCESSFUL;
}
- Status = IopInitializeDriver(ModuleObject->EntryPoint,
- DeviceNode, Filename, BootDriversOnly);
+ Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(ModuleObject);
DPRINT("dasdsad: %s\n", TmpFileName);
RtlAnsiStringToUnicodeString(&ModuleName, &AnsiString, TRUE);
- Status = LdrpFindModuleObject(&ModuleName, &ModuleObject);
+ Status = LdrFindModuleObject(&ModuleName, &ModuleObject);
RtlFreeUnicodeString(&ModuleName);
if (!NT_SUCCESS(Status))
{
strcat(TmpFileName, ".exe");
RtlInitAnsiString(&AnsiString, TmpFileName);
RtlAnsiStringToUnicodeString(&ModuleName, &AnsiString, TRUE);
- Status = LdrpFindModuleObject(&ModuleName, &ModuleObject);
+ Status = LdrFindModuleObject(&ModuleName, &ModuleObject);
RtlFreeUnicodeString(&ModuleName);
}
if (NT_SUCCESS(Status))
return(STATUS_UNSUCCESSFUL);
}
- Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, NULL, FALSE);
+ Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode);
if (!NT_SUCCESS(Status))
{
IopFreeDeviceNode(DeviceNode);
HANDLE ConsoleEvent;
} CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA;
-
#define CSR_API(n) NTSTATUS n (\
PCSRSS_PROCESS_DATA ProcessData,\
PCSRSS_API_REQUEST Request,\
CSR_API(CsrSetScreenBuffer);
CSR_API(CsrSetTitle);
CSR_API(CsrGetTitle);
+CSR_API(CsrWriteConsoleOutput);
+CSR_API(CsrFlushInputBuffer);
+CSR_API(CsrScrollConsoleScreenBuffer);
/* print.c */
VOID STDCALL DisplayString(LPCWSTR lpwString);
-/* $Id: conio.c,v 1.24 2001/08/14 22:00:21 ea Exp $
+/* $Id: conio.c,v 1.25 2001/09/01 15:36:45 chorns Exp $
*
* reactos/subsys/csrss/api/conio.c
*
#define LOCK RtlEnterCriticalSection(&ActiveConsoleLock)
#define UNLOCK RtlLeaveCriticalSection(&ActiveConsoleLock)
+/* FIXME: Is there a way to create real aliasses with gcc? [CSH] */
+#define ALIAS(Name, Target) typeof(Target) Name = Target
+
/* GLOBALS *******************************************************************/
CSR_API(CsrReadConsole)
{
+ PLIST_ENTRY CurrentEntry;
ConsoleInput *Input;
PCHAR Buffer;
int i = 0;
for (; i<nNumberOfCharsToRead && Console->InputEvents.Flink != &Console->InputEvents; i++ )
{
// remove input event from queue
- Input = (ConsoleInput *)Console->InputEvents.Flink;
-
- Input->ListEntry.Blink->Flink = Input->ListEntry.Flink;
- Input->ListEntry.Flink->Blink = Input->ListEntry.Blink;
+ CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+
// only pay attention to valid ascii chars, on key down
if( Input->InputEvent.EventType == KEY_EVENT &&
Input->InputEvent.Event.KeyEvent.bKeyDown == TRUE &&
return Reply->Status;
}
+#define GET_CELL_BUFFER(b,o)\
+(b)->Buffer[(o)++];
+
#define SET_CELL_BUFFER(b,o,c,a)\
(b)->Buffer[(o)++]=(c);\
(b)->Buffer[(o)++]=(a);
return(STATUS_SUCCESS);
}
+#define CsrpInitRect(_Rect, _Top, _Left, _Bottom, _Right) \
+{ \
+ ((_Rect).Top) = _Top; \
+ ((_Rect).Left) = _Left; \
+ ((_Rect).Bottom) = _Bottom; \
+ ((_Rect).Right) = _Right; \
+}
+
+#define CsrpRectHeight(Rect) \
+ ((Rect.Bottom) - (Rect.Top) + 1)
+
+#define CsrpRectWidth(Rect) \
+ ((Rect.Right) - (Rect.Left) + 1)
+
+#define CsrpIsRectEmpty(Rect) \
+ ((Rect.Left >= Rect.Right) || (Rect.Top >= Rect.Bottom))
+
+
+inline BOOLEAN CsrpIsEqualRect(
+ SMALL_RECT Rect1,
+ SMALL_RECT Rect2)
+{
+ return ((Rect1.Left == Rect2.Left) && (Rect1.Right == Rect2.Right) &&
+ (Rect1.Top == Rect2.Top) && (Rect1.Bottom == Rect2.Bottom));
+}
+
+inline BOOLEAN CsrpGetIntersection(
+ PSMALL_RECT Intersection,
+ SMALL_RECT Rect1,
+ SMALL_RECT Rect2)
+{
+ if (CsrpIsRectEmpty(Rect1) ||
+ (CsrpIsRectEmpty(Rect2)) ||
+ (Rect1.Top >= Rect2.Bottom) ||
+ (Rect1.Left >= Rect2.Right) ||
+ (Rect1.Bottom <= Rect2.Top) ||
+ (Rect1.Right <= Rect2.Left))
+ {
+ /* The rectangles do not intersect */
+ CsrpInitRect(*Intersection, 0, 0, 0, 0)
+ return FALSE;
+ }
+
+ CsrpInitRect(
+ *Intersection,
+ RtlMax(Rect1.Top, Rect2.Top),
+ RtlMax(Rect1.Left, Rect2.Left),
+ RtlMin(Rect1.Bottom, Rect2.Bottom),
+ RtlMin(Rect1.Right, Rect2.Right));
+ return TRUE;
+}
+
+inline BOOLEAN CsrpGetUnion(
+ PSMALL_RECT Union,
+ SMALL_RECT Rect1,
+ SMALL_RECT Rect2)
+{
+ if (CsrpIsRectEmpty(Rect1))
+ {
+ if (CsrpIsRectEmpty(Rect2))
+ {
+ CsrpInitRect(*Union, 0, 0, 0, 0);
+ return FALSE;
+ }
+ else
+ *Union = Rect2;
+ }
+ else
+ {
+ if (CsrpIsRectEmpty(Rect2))
+ {
+ *Union = Rect1;
+ }
+ else
+ {
+ CsrpInitRect(
+ *Union,
+ RtlMin(Rect1.Top, Rect2.Top),
+ RtlMin(Rect1.Left, Rect2.Left),
+ RtlMax(Rect1.Bottom, Rect2.Bottom),
+ RtlMax(Rect1.Right, Rect2.Right));
+ }
+ }
+ return TRUE;
+}
+
+inline BOOLEAN CsrpSubtractRect(
+ PSMALL_RECT Subtraction,
+ SMALL_RECT Rect1,
+ SMALL_RECT Rect2)
+{
+ SMALL_RECT tmp;
+
+ if (CsrpIsRectEmpty(Rect1))
+ {
+ CsrpInitRect(*Subtraction, 0, 0, 0, 0);
+ return FALSE;
+ }
+ *Subtraction = Rect1;
+ if (CsrpGetIntersection(&tmp, Rect1, Rect2))
+ {
+ if (CsrpIsEqualRect(tmp, *Subtraction))
+ {
+ CsrpInitRect(*Subtraction, 0, 0, 0, 0);
+ return FALSE;
+ }
+ if ((tmp.Top == Subtraction->Top) && (tmp.Bottom == Subtraction->Bottom))
+ {
+ if (tmp.Left == Subtraction->Left)
+ Subtraction->Left = tmp.Right;
+ else if (tmp.Right == Subtraction->Right)
+ Subtraction->Right = tmp.Left;
+ }
+ else if ((tmp.Left == Subtraction->Left) && (tmp.Right == Subtraction->Right))
+ {
+ if (tmp.Top == Subtraction->Top)
+ Subtraction->Top = tmp.Bottom;
+ else if (tmp.Bottom == Subtraction->Bottom)
+ Subtraction->Bottom = tmp.Top;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Screen buffer must be locked when this function is called
+ */
+static VOID CsrpCopyRegion(
+ PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ SMALL_RECT SrcRegion,
+ SMALL_RECT DstRegion)
+{
+ SHORT SrcY, DstY;
+ DWORD SrcOffset;
+ DWORD DstOffset;
+ DWORD BytesPerLine;
+
+ DstY = DstRegion.Top;
+ BytesPerLine = CsrpRectWidth(DstRegion) * 2;
+ for (SrcY = SrcRegion.Top; SrcY <= SrcRegion.Bottom; SrcY++)
+ {
+ SrcOffset = (SrcY * ScreenBuffer->MaxX * 2) + (SrcRegion.Left * 2);
+ DstOffset = (DstY * ScreenBuffer->MaxX * 2) + (DstRegion.Left * 2);
+ RtlCopyMemory(
+ &ScreenBuffer->Buffer[DstOffset],
+ &ScreenBuffer->Buffer[SrcOffset],
+ BytesPerLine);
+ DstY++;
+ }
+}
+
+/*
+ * Screen buffer must be locked when this function is called
+ */
+static VOID CsrpFillRegion(
+ PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ SMALL_RECT Region,
+ CHAR_INFO CharInfo)
+{
+ SHORT X, Y;
+ DWORD Offset;
+
+ for (Y = Region.Top; Y <= Region.Bottom; Y++)
+ {
+ Offset = (Y * ScreenBuffer->MaxX + Region.Left) * 2;
+ for (X = Region.Left; X <= Region.Right; X++)
+ {
+ SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes);
+ }
+ }
+}
+
+/*
+ * Screen buffer must be locked when this function is called
+ */
+inline NTSTATUS CsrpSetConsoleDeviceCursor(PCSRSS_SCREEN_BUFFER ScreenBuffer, SHORT X, SHORT Y)
+{
+ CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
+ IO_STATUS_BLOCK Iosb;
+
+ ScrInfo.dwCursorPosition.X = X;
+ ScrInfo.dwCursorPosition.Y = Y;
+ ScrInfo.wAttributes = ScreenBuffer->DefaultAttrib;
+
+ return NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
+}
+
+/*
+ * Region - Region of virtual screen buffer to draw onto the physical console
+ * Screen buffer must be locked when this function is called
+ */
+static VOID CsrpDrawRegion(
+ PCSRSS_SCREEN_BUFFER ScreenBuffer,
+ SMALL_RECT Region)
+{
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
+ CONSOLE_MODE Mode;
+ int i, y;
+ DWORD BytesPerLine;
+ DWORD SrcOffset;
+ DWORD SrcDelta;
+
+ Mode.dwMode = 0; /* clear ENABLE_PROCESSED_OUTPUT mode */
+ Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Failed to set console mode\n" );
+ return;
+ }
+
+ /* blast out buffer */
+ BytesPerLine = CsrpRectWidth(Region) * 2;
+ SrcOffset = (Region.Top * ScreenBuffer->MaxX + Region.Left) * 2;
+ SrcDelta = ScreenBuffer->MaxX * 2;
+ for( i = Region.Top - ScreenBuffer->ShowY, y = ScreenBuffer->ShowY;
+ i <= Region.Bottom - ScreenBuffer->ShowY; i++ )
+ {
+ /* Position the cursor correctly */
+ Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left - ScreenBuffer->ShowX, i);
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Failed to set console info\n" );
+ return;
+ }
+
+ Status = NtWriteFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ &ScreenBuffer->Buffer[ SrcOffset ],
+ BytesPerLine, 0, 0 );
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Write to console failed\n" );
+ return;
+ }
+
+ /* wrap back around the end of the buffer */
+ if( ++y == ScreenBuffer->MaxY )
+ y = 0;
+
+ SrcOffset += SrcDelta;
+ }
+ Mode.dwMode = ENABLE_PROCESSED_OUTPUT;
+ Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Failed to set console mode\n" );
+ return;
+ }
+ Status = CsrpSetConsoleDeviceCursor(
+ ScreenBuffer,
+ ScreenBuffer->CurrentX - ScreenBuffer->ShowX,
+ ((ScreenBuffer->CurrentY + ScreenBuffer->MaxY) - ScreenBuffer->ShowY) % ScreenBuffer->MaxY);
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Failed to set console info\n" );
+ return;
+ }
+ Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_SET_CURSOR_INFO, &ScreenBuffer->CursorInfo,
+ sizeof( ScreenBuffer->CursorInfo ), 0, 0 );
+ if( !NT_SUCCESS( Status ) )
+ {
+ DbgPrint( "CSR: Failed to set cursor info\n" );
+ return;
+ }
+}
+
+
CSR_API(CsrWriteConsole)
{
BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer;
sizeof(LPC_MESSAGE_HEADER);
LOCK;
- if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle, (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
+ if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.WriteConsoleRequest.ConsoleHandle,
+ (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
{
UNLOCK;
return Reply->Status = STATUS_INVALID_HANDLE;
Console->EchoCount = 0;
Console->Header.Type = CSRSS_CONSOLE_MAGIC;
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
- Console->InputEvents.Flink = Console->InputEvents.Blink = &Console->InputEvents;
+ InitializeListHead(&Console->InputEvents);
Status = NtCreateEvent( &Console->ActiveEvent, STANDARD_RIGHTS_ALL, 0, FALSE, FALSE );
if( !NT_SUCCESS( Status ) )
{
**************************************************************/
VOID STDCALL CsrDrawConsole( PCSRSS_SCREEN_BUFFER Buff )
{
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
- CONSOLE_MODE Mode;
- int i, y;
+ SMALL_RECT Region;
- /* first set position to 0,0 */
- ScrInfo.dwCursorPosition.X = 0;
- ScrInfo.dwCursorPosition.Y = 0;
- ScrInfo.wAttributes = Buff->DefaultAttrib;
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Failed to set console info\n" );
- return;
- }
- Mode.dwMode = 0; /* clear ENABLE_PROCESSED_OUTPUT mode */
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Failed to set console mode\n" );
- return;
- }
- /* blast out buffer */
- for( i = 0, y = Buff->ShowY; i < PhysicalConsoleSize.Y; i++ )
- {
- Status = NtWriteFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, &Buff->Buffer[ (Buff->ShowX * 2) + (y * Buff->MaxX * 2) ], PhysicalConsoleSize.X * 2, 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Write to console failed\n" );
- return;
- }
- /* wrap back around the end of the buffer */
- if( ++y == Buff->MaxY )
- y = 0;
- }
- Mode.dwMode = ENABLE_PROCESSED_OUTPUT;
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_MODE, &Mode, sizeof( Mode ), 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Failed to set console mode\n" );
- return;
- }
- ScrInfo.dwCursorPosition.X = Buff->CurrentX - Buff->ShowX;
- ScrInfo.dwCursorPosition.Y = ((Buff->CurrentY + Buff->MaxY) - Buff->ShowY) % Buff->MaxY;
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &ScrInfo, sizeof( ScrInfo ), 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Failed to set console info\n" );
- return;
- }
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_CURSOR_INFO, &Buff->CursorInfo, sizeof( Buff->CursorInfo ), 0, 0 );
- if( !NT_SUCCESS( Status ) )
- {
- DbgPrint( "CSR: Failed to set cursor info\n" );
- return;
- }
+ CsrpInitRect(
+ Region,
+ Buff->ShowY,
+ Buff->ShowX,
+ Buff->ShowY + PhysicalConsoleSize.Y - 1,
+ Buff->ShowX + PhysicalConsoleSize.X - 1);
+
+ CsrpDrawRegion(Buff, Region);
}
{
DbgPrint("CSR: Failed to open console. Expect problems.\n");
}
-// DbgPrint("CSR: ConsoleDeviceHandle %x\n", ConsoleDeviceHandle);
-
+
RtlInitUnicodeString(&DeviceName, L"\\??\\Keyboard");
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
continue;
}
KeyEventRecord->InputEvent.EventType = KEY_EVENT;
- Status = NtReadFile( KeyboardDeviceHandle, Events[0], NULL, NULL, &Iosb, &KeyEventRecord->InputEvent.Event.KeyEvent, sizeof( KEY_EVENT_RECORD ), NULL, 0 );
+ Status = NtReadFile( KeyboardDeviceHandle, Events[0], NULL, NULL, &Iosb,
+ &KeyEventRecord->InputEvent.Event.KeyEvent, sizeof( KEY_EVENT_RECORD ), NULL, 0 );
if( !NT_SUCCESS( Status ) )
{
DbgPrint( "CSR: ReadFile on keyboard device failed\n" );
else break;
}
}
- if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED )&& KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_TAB )
+ if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState &
+ ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED )&&
+ KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_TAB )
if( KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
{
ANSI_STRING Title;
UNLOCK;
}
- if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState & ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) && (KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP || KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) )
+ if( KeyEventRecord->InputEvent.Event.KeyEvent.dwControlKeyState &
+ ( RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED ) &&
+ ( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP ||
+ KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) )
{
if( KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE )
{
if( KeyEventRecord->InputEvent.Event.KeyEvent.wVirtualKeyCode == VK_UP )
{
/* only scroll up if there is room to scroll up into */
- if( ActiveConsole->ActiveBuffer->ShowY != ((ActiveConsole->ActiveBuffer->CurrentY + 1) % ActiveConsole->ActiveBuffer->MaxY) )
- ActiveConsole->ActiveBuffer->ShowY = (ActiveConsole->ActiveBuffer->ShowY + ActiveConsole->ActiveBuffer->MaxY - 1) % ActiveConsole->ActiveBuffer->MaxY;
+ if( ActiveConsole->ActiveBuffer->ShowY != ((ActiveConsole->ActiveBuffer->CurrentY + 1) %
+ ActiveConsole->ActiveBuffer->MaxY) )
+ ActiveConsole->ActiveBuffer->ShowY = (ActiveConsole->ActiveBuffer->ShowY +
+ ActiveConsole->ActiveBuffer->MaxY - 1) % ActiveConsole->ActiveBuffer->MaxY;
}
else if( ActiveConsole->ActiveBuffer->ShowY != ActiveConsole->ActiveBuffer->CurrentY )
/* only scroll down if there is room to scroll down into */
- if( ActiveConsole->ActiveBuffer->ShowY % ActiveConsole->ActiveBuffer->MaxY != ActiveConsole->ActiveBuffer->CurrentY )
- if( ((ActiveConsole->ActiveBuffer->CurrentY + 1) % ActiveConsole->ActiveBuffer->MaxY) != (ActiveConsole->ActiveBuffer->ShowY + PhysicalConsoleSize.Y) % ActiveConsole->ActiveBuffer->MaxY )
- ActiveConsole->ActiveBuffer->ShowY = (ActiveConsole->ActiveBuffer->ShowY + 1) % ActiveConsole->ActiveBuffer->MaxY;
+ if( ActiveConsole->ActiveBuffer->ShowY % ActiveConsole->ActiveBuffer->MaxY !=
+ ActiveConsole->ActiveBuffer->CurrentY )
+
+ if( ((ActiveConsole->ActiveBuffer->CurrentY + 1) % ActiveConsole->ActiveBuffer->MaxY) !=
+ (ActiveConsole->ActiveBuffer->ShowY + PhysicalConsoleSize.Y) % ActiveConsole->ActiveBuffer->MaxY )
+ ActiveConsole->ActiveBuffer->ShowY = (ActiveConsole->ActiveBuffer->ShowY + 1) %
+ ActiveConsole->ActiveBuffer->MaxY;
CsrDrawConsole( ActiveConsole->ActiveBuffer );
UNLOCK;
}
updown = KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown;
KeyEventRecord->Echoed = FALSE;
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\r';
- KeyEventRecord->ListEntry.Flink = &ActiveConsole->InputEvents;
- KeyEventRecord->ListEntry.Blink = ActiveConsole->InputEvents.Blink;
- ActiveConsole->InputEvents.Blink->Flink = &KeyEventRecord->ListEntry;
- ActiveConsole->InputEvents.Blink = &KeyEventRecord->ListEntry;
+ InsertTailList(&ActiveConsole->InputEvents, &KeyEventRecord->ListEntry);
ActiveConsole->WaitingChars++;
KeyEventRecord = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( ConsoleInput ) );
if( !KeyEventRecord )
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar = '\n';
}
// add event to the queue
- KeyEventRecord->ListEntry.Flink = &ActiveConsole->InputEvents;
- KeyEventRecord->ListEntry.Blink = ActiveConsole->InputEvents.Blink;
- ActiveConsole->InputEvents.Blink->Flink = &KeyEventRecord->ListEntry;
- ActiveConsole->InputEvents.Blink = &KeyEventRecord->ListEntry;
+ InsertTailList(&ActiveConsole->InputEvents, &KeyEventRecord->ListEntry);
// if line input mode is enabled, only wake the client on enter key down
if( !(ActiveConsole->Mode & ENABLE_LINE_INPUT ) ||
( KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' &&
{
// walk the input queue looking for a char to backspace
for( TempInput = (ConsoleInput *)ActiveConsole->InputEvents.Blink;
- TempInput != (ConsoleInput *)&ActiveConsole->InputEvents &&
- (TempInput->InputEvent.EventType != KEY_EVENT ||
- TempInput->InputEvent.Event.KeyEvent.bKeyDown == FALSE ||
- TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\b' );
- TempInput = (ConsoleInput *)TempInput->ListEntry.Blink );
+ TempInput != (ConsoleInput *)&ActiveConsole->InputEvents &&
+ (TempInput->InputEvent.EventType != KEY_EVENT ||
+ TempInput->InputEvent.Event.KeyEvent.bKeyDown == FALSE ||
+ TempInput->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\b' );
+ TempInput = (ConsoleInput *)TempInput->ListEntry.Blink );
// if we found one, delete it, otherwise, wake the client
if( TempInput != (ConsoleInput *)&ActiveConsole->InputEvents )
{
// delete previous key in queue, maybe echo backspace to screen, and do not place backspace on queue
- TempInput->ListEntry.Blink->Flink = TempInput->ListEntry.Flink;
- TempInput->ListEntry.Flink->Blink = TempInput->ListEntry.Blink;
+ RemoveEntryList(&TempInput->ListEntry);
if( TempInput->Echoed )
CsrpWriteConsole( ActiveConsole->ActiveBuffer, &KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar, 1, TRUE );
RtlFreeHeap( CsrssApiHeap, 0, TempInput );
- KeyEventRecord->ListEntry.Blink->Flink = KeyEventRecord->ListEntry.Flink;
- KeyEventRecord->ListEntry.Flink->Blink = KeyEventRecord->ListEntry.Blink;
+ RemoveEntryList(&KeyEventRecord->ListEntry);
RtlFreeHeap( CsrssApiHeap, 0, KeyEventRecord );
ActiveConsole->WaitingChars -= 2;
}
else NtSetEvent( ActiveConsole->ActiveEvent, 0 );
- }
+ }
else {
// echo chars if we are supposed to and client is waiting for some
- if( ActiveConsole->Mode & ENABLE_ECHO_INPUT && ActiveConsole->EchoCount &&
+ if( ( ActiveConsole->Mode & ENABLE_ECHO_INPUT ) && ActiveConsole->EchoCount &&
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar &&
KeyEventRecord->InputEvent.Event.KeyEvent.bKeyDown == TRUE &&
KeyEventRecord->InputEvent.Event.KeyEvent.uChar.AsciiChar != '\r' )
sizeof(LPC_MESSAGE_HEADER);
LOCK;
- if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle, (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
+ if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.ScreenBufferInfoRequest.ConsoleHandle,
+ (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
{
UNLOCK;
return Reply->Status = STATUS_INVALID_HANDLE;
pInfo = &Reply->Data.ScreenBufferInfoReply.Info;
if( Buff == ActiveConsole->ActiveBuffer )
{
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, 0, 0, pInfo, sizeof( *pInfo ) );
+ Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO, 0, 0, pInfo, sizeof( *pInfo ) );
if( !NT_SUCCESS( Status ) )
DbgPrint( "CSR: Failed to get console info, expect trouble\n" );
Reply->Status = Status;
sizeof(LPC_MESSAGE_HEADER);
LOCK;
- if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.SetCursorRequest.ConsoleHandle, (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
+ if( !NT_SUCCESS( CsrGetObject( ProcessData, Request->Data.SetCursorRequest.ConsoleHandle,
+ (Object_t **)&Buff ) ) || Buff->Header.Type != CSRSS_SCREEN_BUFFER_MAGIC )
{
UNLOCK;
return Reply->Status = STATUS_INVALID_HANDLE;
Info.wAttributes = Buff->DefaultAttrib;
if( Buff == ActiveConsole->ActiveBuffer )
{
- Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &Info, sizeof( Info ), 0, 0 );
+ Status = NtDeviceIoControlFile( ConsoleDeviceHandle, NULL, NULL, NULL, &Iosb,
+ IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO, &Info, sizeof( Info ), 0, 0 );
if( !NT_SUCCESS( Status ) )
DbgPrint( "CSR: Failed to set console info, expect trouble\n" );
}
+
Buff->CurrentX = Info.dwCursorPosition.X + Buff->ShowX;
Buff->CurrentY = (Info.dwCursorPosition.Y + Buff->ShowY) % Buff->MaxY;
UNLOCK;
CSR_API(CsrReadInputEvent)
{
+ PLIST_ENTRY CurrentEntry;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
ConsoleInput *Input;
UNLOCK;
return Status;
}
+
// only get input if there is input, and we are not in line input mode, or if we are, if we have a whole line
- if( Console->InputEvents.Flink != &Console->InputEvents &&
- ( !Console->Mode & ENABLE_LINE_INPUT || Console->WaitingLines ) )
+ if( ( Console->InputEvents.Flink != &Console->InputEvents ) &&
+ ( !( Console->Mode & ENABLE_LINE_INPUT ) || ( Console->WaitingLines > 0 ) ) )
{
- Input = (ConsoleInput *)Console->InputEvents.Flink;
- Input->ListEntry.Blink->Flink = Input->ListEntry.Flink;
- Input->ListEntry.Flink->Blink = Input->ListEntry.Blink;
+ CurrentEntry = RemoveHeadList(&Console->InputEvents);
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
Reply->Data.ReadInputReply.Input = Input->InputEvent;
- if( Console->Mode & ENABLE_LINE_INPUT &&
+
+ if( Console->Mode & ENABLE_LINE_INPUT &&
Input->InputEvent.Event.KeyEvent.bKeyDown == FALSE &&
Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' )
Console->WaitingLines--;
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) -
sizeof(LPC_MESSAGE_HEADER);
LOCK;
- Status = CsrGetObject( ProcessData, Request->Data.SetCursorInfoRequest.ConsoleHandle, (Object_t **)&Buff );
+ Status = CsrGetObject( ProcessData,
+ Request->Data.SetCursorInfoRequest.ConsoleHandle, (Object_t **)&Buff );
+
if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CSRSS_SCREEN_BUFFER_MAGIC ? 0 : STATUS_INVALID_HANDLE ))
{
Reply->Status = Status;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE_HEADER);
LOCK;
- Status = CsrGetObject( ProcessData, Request->Data.SetConsoleModeRequest.ConsoleHandle, (Object_t **)&Console );
+ Status = CsrGetObject( ProcessData,
+ Request->Data.SetConsoleModeRequest.ConsoleHandle,
+ (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
UNLOCK;
return Status;
}
+
Buff = (PCSRSS_SCREEN_BUFFER)Console;
if( Console->Header.Type == CSRSS_CONSOLE_MAGIC )
Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE_HEADER);
LOCK;
- Status = CsrGetObject( ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle, (Object_t **)&Console );
+ Status = CsrGetObject( ProcessData,
+ Request->Data.GetConsoleModeRequest.ConsoleHandle,
+ (Object_t **)&Console );
if( !NT_SUCCESS( Status ) )
{
Reply->Status = Status;
}
Reply->Status = STATUS_SUCCESS;
Buff = (PCSRSS_SCREEN_BUFFER)Console;
- if( Console->Header.Type = CSRSS_CONSOLE_MAGIC )
+ if( Console->Header.Type == CSRSS_CONSOLE_MAGIC )
Reply->Data.GetConsoleModeReply.ConsoleMode = Console->Mode;
- else if( Buff->Header.Type = CSRSS_SCREEN_BUFFER_MAGIC )
+ else if( Buff->Header.Type == CSRSS_SCREEN_BUFFER_MAGIC )
Reply->Data.GetConsoleModeReply.ConsoleMode = Buff->Mode;
else Status = STATUS_INVALID_HANDLE;
UNLOCK;
return Reply->Status;
}
+CSR_API(CsrWriteConsoleOutput)
+{
+ SHORT i, X, Y, SizeX, SizeY;
+ PCSRSS_SCREEN_BUFFER Buff;
+ SMALL_RECT ScreenBuffer;
+ CHAR_INFO* CurCharInfo;
+ SMALL_RECT WriteRegion;
+ CHAR_INFO* CharInfo;
+ COORD BufferCoord;
+ COORD BufferSize;
+ NTSTATUS Status;
+ DWORD Offset;
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE_HEADER);
+ LOCK;
+ Status = CsrGetObject( ProcessData, Request->Data.WriteConsoleOutputRequest.ConsoleHandle, (Object_t **)&Buff );
+ if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CSRSS_SCREEN_BUFFER_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
+ {
+ Reply->Status = Status;
+ UNLOCK;
+ return Status;
+ }
+
+ BufferSize = Request->Data.WriteConsoleOutputRequest.BufferSize;
+ BufferCoord = Request->Data.WriteConsoleOutputRequest.BufferCoord;
+ CharInfo = (CHAR_INFO*)&Request->Data.WriteConsoleOutputRequest.CharInfo;
+ WriteRegion = Request->Data.WriteConsoleOutputRequest.WriteRegion;
+
+ SizeY = RtlMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(WriteRegion));
+ SizeX = RtlMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(WriteRegion));
+ WriteRegion.Bottom = WriteRegion.Top + SizeY;
+ WriteRegion.Right = WriteRegion.Left + SizeX;
+
+ /* Make sure WriteRegion is inside the screen buffer */
+ CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
+ if (!CsrpGetIntersection(&WriteRegion, ScreenBuffer, WriteRegion))
+ {
+ UNLOCK;
+ /* It is okay to have a WriteRegion completely outside the screen buffer.
+ No data is written then. */
+ return (Reply->Status = STATUS_SUCCESS);
+ }
+
+ for ( i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++ )
+ {
+ CurCharInfo = CharInfo + (i * BufferSize.Y);
+ Offset = (Y * Buff->MaxX + WriteRegion.Left) * 2;
+ for ( X = WriteRegion.Left; X <= WriteRegion.Right; X++ )
+ {
+ SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes);
+ CurCharInfo++;
+ }
+ }
+
+ if( Buff == ActiveConsole->ActiveBuffer )
+ {
+ CsrpDrawRegion( ActiveConsole->ActiveBuffer, WriteRegion );
+ }
+
+ UNLOCK;
+ Reply->Data.WriteConsoleOutputReply.WriteRegion.Right = WriteRegion.Left + SizeX - 1;
+ Reply->Data.WriteConsoleOutputReply.WriteRegion.Bottom = WriteRegion.Top + SizeY - 1;
+ return (Reply->Status = STATUS_SUCCESS);
+}
+
+CSR_API(CsrFlushInputBuffer)
+{
+ PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry;
+ PCSRSS_CONSOLE Console;
+ ConsoleInput* Input;
+ NTSTATUS Status;
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE_HEADER);
+ LOCK;
+ Status = CsrGetObject( ProcessData, Request->Data.FlushInputBufferRequest.ConsoleInput, (Object_t **)&Console );
+ if( !NT_SUCCESS( Status ) || (Status = Console->Header.Type == CSRSS_CONSOLE_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
+ {
+ Reply->Status = Status;
+ UNLOCK;
+ return Status;
+ }
+
+ /* Discard all entries in the input event queue */
+ CurrentEntry = Console->InputEvents.Flink;
+ while (IsListEmpty(&Console->InputEvents))
+ {
+ NextEntry = CurrentEntry->Flink;
+ Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
+ /* Destroy the event */
+ Console->WaitingChars--;
+ RtlFreeHeap( CsrssApiHeap, 0, Input );
+ CurrentEntry = NextEntry;
+ }
+ UNLOCK;
+
+ return (Reply->Status = STATUS_SUCCESS);
+}
+
+CSR_API(CsrScrollConsoleScreenBuffer)
+{
+ SHORT i, X, Y, SizeX, SizeY;
+ PCSRSS_SCREEN_BUFFER Buff;
+ SMALL_RECT ScreenBuffer;
+ SMALL_RECT SrcRegion;
+ SMALL_RECT DstRegion;
+ SMALL_RECT FillRegion;
+ IO_STATUS_BLOCK Iosb;
+ CHAR_INFO* CharInfo;
+ NTSTATUS Status;
+ DWORD SrcOffset;
+ DWORD DstOffset;
+ BOOLEAN DoFill;
+
+ ALIAS(ConsoleHandle,Request->Data.ScrollConsoleScreenBufferRequest.ConsoleHandle);
+ ALIAS(ScrollRectangle,Request->Data.ScrollConsoleScreenBufferRequest.ScrollRectangle);
+ ALIAS(UseClipRectangle,Request->Data.ScrollConsoleScreenBufferRequest.UseClipRectangle);
+ ALIAS(ClipRectangle,Request->Data.ScrollConsoleScreenBufferRequest.ClipRectangle);
+ ALIAS(DestinationOrigin,Request->Data.ScrollConsoleScreenBufferRequest.DestinationOrigin);
+ ALIAS(Fill,Request->Data.ScrollConsoleScreenBufferRequest.Fill);
+
+ Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+ Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE_HEADER);
+ LOCK;
+ Status = CsrGetObject( ProcessData, ConsoleHandle, (Object_t **)&Buff );
+ if( !NT_SUCCESS( Status ) || (Status = Buff->Header.Type == CSRSS_SCREEN_BUFFER_MAGIC ? STATUS_SUCCESS : STATUS_INVALID_HANDLE ))
+ {
+ Reply->Status = Status;
+ UNLOCK;
+ return Status;
+ }
+
+ /* Make sure source rectangle is inside the screen buffer */
+ CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1);
+ if (!CsrpGetIntersection(&SrcRegion, ScreenBuffer, ScrollRectangle))
+ {
+ UNLOCK;
+ return (Reply->Status = STATUS_INVALID_PARAMETER);
+ }
+
+ if (UseClipRectangle)
+ {
+ if (!CsrpGetIntersection(&SrcRegion, SrcRegion, ClipRectangle))
+ {
+ UNLOCK;
+ return (Reply->Status = STATUS_SUCCESS);
+ }
+ }
+
+
+ CsrpInitRect(
+ DstRegion,
+ DestinationOrigin.Y,
+ DestinationOrigin.X,
+ DestinationOrigin.Y + CsrpRectHeight(ScrollRectangle) - 1,
+ DestinationOrigin.X + CsrpRectWidth(ScrollRectangle) - 1)
+
+ /* Make sure destination rectangle is inside the screen buffer */
+ if (!CsrpGetIntersection(&DstRegion, DstRegion, ScreenBuffer))
+ {
+ UNLOCK;
+ return (Reply->Status = STATUS_INVALID_PARAMETER);
+ }
+
+ CsrpCopyRegion(Buff, SrcRegion, DstRegion);
+
+
+ /* Get the region that should be filled with the specified character and attributes */
+
+ DoFill = FALSE;
+
+ CsrpGetUnion(&FillRegion, SrcRegion, DstRegion);
+
+ if (CsrpSubtractRect(&FillRegion, FillRegion, DstRegion))
+ {
+ /* FIXME: The subtracted rectangle is off by one line */
+ FillRegion.Top += 1;
+
+ CsrpFillRegion(Buff, FillRegion, Fill);
+ DoFill = TRUE;
+ }
+
+ if( Buff == ActiveConsole->ActiveBuffer )
+ {
+ /* Draw destination region */
+ CsrpDrawRegion(ActiveConsole->ActiveBuffer, DstRegion);
+
+ if (DoFill)
+ {
+ /* Draw filled region */
+ CsrpDrawRegion(ActiveConsole->ActiveBuffer, FillRegion);
+ }
+ }
+
+ UNLOCK;
+ return (Reply->Status = STATUS_SUCCESS);
+}
+
/* EOF */
-/* $Id: process.c,v 1.13 2001/08/14 12:57:16 ea Exp $
+/* $Id: process.c,v 1.14 2001/09/01 15:36:45 chorns Exp $
*
* reactos/subsys/csrss/api/process.c
*
NewProcessData->Console = ProcessData->Console;
InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
}
-
+ DbgPrint("Before type\n");
if( NewProcessData->Console )
{
CLIENT_ID ClientId;
&Reply->Data.CreateProcessReply.InputHandle,
(Object_t *)NewProcessData->Console);
RtlEnterCriticalSection( &ActiveConsoleLock );
- CsrInsertObject( NewProcessData, &Reply->Data.CreateProcessReply.OutputHandle, &(NewProcessData->Console->ActiveBuffer->Header) );
+ CsrInsertObject( NewProcessData,
+ &Reply->Data.CreateProcessReply.OutputHandle,
+ &(NewProcessData->Console->ActiveBuffer->Header) );
+
+
+ DbgPrint("OutputHandle %x\n", Reply->Data.CreateProcessReply.OutputHandle);
+ DbgPrint("Console %x\n", NewProcessData->Console);
+ DbgPrint("Console->ActiveBuffer %x\n", NewProcessData->Console->ActiveBuffer);
+ DbgPrint("Type %x\n", NewProcessData->Console->ActiveBuffer->Header.Type);
+
+
RtlLeaveCriticalSection( &ActiveConsoleLock );
ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
-/* $Id: wapi.c,v 1.14 2001/08/14 12:57:16 ea Exp $
+/* $Id: wapi.c,v 1.15 2001/09/01 15:36:45 chorns Exp $
*
* reactos/subsys/csrss/api/wapi.c
*
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h>
+#include <windows.h>
#include <ntdll/rtl.h>
#include <csrss/csrss.h>
#include <debug.h>
CsrSetScreenBuffer,
CsrSetTitle,
CsrGetTitle,
+ CsrWriteConsoleOutput,
+ CsrFlushInputBuffer,
+ CsrScrollConsoleScreenBuffer,
0 };
static void Thread_Api2(HANDLE ServerPort)