[REACTOS]

Here is all the deprecated code: the old CSR as well as the new one which wasn't included; the ReactOS-specific win32csr and the csr module of win32k.

svn path=/trunk/; revision=58771
This commit is contained in:
Hermès Bélusca-Maïto
2013-04-15 19:46:07 +00:00
parent 599a7affa3
commit fdceea406e
80 changed files with 26384 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Interface to csrss
* FILE: subsys/win32k/ntuser/csr.c
* PROGRAMER: Ge van Geldorp ([email protected])
*/
#include <win32k.h>
static HANDLE WindowsApiPort = NULL;
PEPROCESS CsrProcess = NULL;
NTSTATUS FASTCALL
CsrInit(void)
{
NTSTATUS Status;
UNICODE_STRING PortName;
ULONG ConnectInfoLength;
SECURITY_QUALITY_OF_SERVICE Qos;
RtlInitUnicodeString(&PortName, L"\\Windows\\ApiPort");
ConnectInfoLength = 0;
Qos.Length = sizeof(Qos);
Qos.ImpersonationLevel = SecurityDelegation;
Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
Qos.EffectiveOnly = FALSE;
Status = ZwConnectPort(&WindowsApiPort,
&PortName,
&Qos,
NULL,
NULL,
NULL,
NULL,
&ConnectInfoLength);
if (! NT_SUCCESS(Status))
{
return Status;
}
CsrProcess = PsGetCurrentProcess();
return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
co_CsrNotify(PCSR_API_MESSAGE Request)
{
NTSTATUS Status;
PEPROCESS OldProcess;
if (NULL == CsrProcess)
{
return STATUS_INVALID_PORT_HANDLE;
}
Request->Header.u2.ZeroInit = 0;
Request->Header.u1.s1.DataLength = sizeof(CSR_API_MESSAGE) - sizeof(PORT_MESSAGE);
Request->Header.u1.s1.TotalLength = sizeof(CSR_API_MESSAGE);
/* Switch to the process in which the WindowsApiPort handle is valid */
OldProcess = PsGetCurrentProcess();
if (CsrProcess != OldProcess)
{
KeAttachProcess(&CsrProcess->Pcb);
}
UserLeaveCo();
Status = ZwRequestWaitReplyPort(WindowsApiPort,
&Request->Header,
&Request->Header);
UserEnterCo();
if (CsrProcess != OldProcess)
{
KeDetachProcess();
}
if (NT_SUCCESS(Status))
{
Status = Request->Status;
}
return Status;
}
/* EOF */
+20
View File
@@ -0,0 +1,20 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Interface to csrss
* FILE: subsys/win32k/include/csr.h
* PROGRAMER: Ge van Geldorp ([email protected])
*/
#pragma once
extern PEPROCESS CsrProcess;
NTSTATUS FASTCALL CsrInit(void);
NTSTATUS FASTCALL co_CsrNotify(PCSR_API_MESSAGE Request);
NTSTATUS FASTCALL CsrCloseHandle(HANDLE Handle);
NTSTATUS WINAPI CsrInsertObject(HANDLE ObjectHandle,
ACCESS_MASK DesiredAccess,
PHANDLE Handle);
/* EOF */
+16
View File
@@ -0,0 +1,16 @@
include_directories(
include
${REACTOS_SOURCE_DIR}/include/reactos/subsys
${REACTOS_SOURCE_DIR}/include/reactos/drivers)
add_executable(csrss2 main.c csr.rc)
set_module_type(csrss2 nativecui)
target_link_libraries(csrss2 nt)
add_importlibs(csrss2 ntdll csrsrv2)
add_dependencies(csrss2 psdk bugcodes)
add_cd_file(TARGET csrss2 DESTINATION reactos/system32 FOR all)
add_subdirectory(csrsrv)
+4
View File
@@ -0,0 +1,4 @@
#define REACTOS_STR_FILE_DESCRIPTION "Client/Server Runtime Process\0"
#define REACTOS_STR_INTERNAL_NAME "csrss\0"
#define REACTOS_STR_ORIGINAL_FILENAME "csrss.exe\0"
#include <reactos/version.rc>
@@ -0,0 +1,30 @@
include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
spec2def(csrsrv2.dll csrsrv2.spec ADD_IMPORTLIB)
list(APPEND SOURCE
api.c
init.c
process.c
server.c
session.c
thread.c
wait.c
csrsrv.rc
${CMAKE_CURRENT_BINARY_DIR}/csrsrv2.def)
add_library(csrsrv2 SHARED ${SOURCE})
target_link_libraries(csrsrv2 ${PSEH_LIB} smlib)
set_module_type(csrsrv2 nativedll)
add_importlibs(csrsrv2 ntdll)
add_pch(csrsrv2 srv.h)
add_dependencies(csrsrv2 psdk bugcodes)
add_cd_file(TARGET csrsrv2 DESTINATION reactos/system32 FOR all)
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS CSR Core Server\0"
#define REACTOS_STR_INTERNAL_NAME "csrsrv\0"
#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0"
#include <reactos/version.rc>
@@ -0,0 +1,35 @@
@ stdcall CsrAddStaticServerThread(ptr ptr long)
@ stdcall CsrCallServerFromServer(ptr ptr)
@ stdcall CsrConnectToUser()
@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
@ stdcall CsrCreateRemoteThread(ptr ptr)
@ stdcall CsrCreateThread(ptr ptr ptr long)
@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
@ stdcall CsrDebugProcess(ptr)
@ stdcall CsrDebugProcessStop(ptr)
@ stdcall CsrDereferenceProcess(ptr)
@ stdcall CsrDereferenceThread(ptr)
@ stdcall CsrDereferenceWait(ptr)
@ stdcall CsrDestroyProcess(ptr long)
@ stdcall CsrDestroyThread(ptr)
@ stdcall CsrExecServerThread(ptr long)
@ stdcall CsrGetProcessLuid(ptr ptr)
@ stdcall CsrImpersonateClient(ptr)
@ stdcall CsrLockProcessByClientId(ptr ptr)
@ stdcall CsrLockThreadByClientId(ptr ptr)
@ stdcall CsrMoveSatisfiedWait(ptr ptr)
@ stdcall CsrNotifyWait(ptr long ptr ptr)
@ stdcall CsrPopulateDosDevices()
@ stdcall CsrQueryApiPort()
@ stdcall CsrReferenceThread(ptr)
@ stdcall CsrRevertToSelf()
@ stdcall CsrServerInitialization(long ptr)
@ stdcall CsrSetBackgroundPriority(ptr)
@ stdcall CsrSetCallingSpooler(long)
@ stdcall CsrSetForegroundPriority(ptr)
@ stdcall CsrShutdownProcesses(ptr long)
@ stdcall CsrUnhandledExceptionFilter(ptr)
@ stdcall CsrUnlockProcess(ptr)
@ stdcall CsrUnlockThread(ptr)
@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
@ stdcall CsrValidateMessageString(ptr ptr)
+988
View File
@@ -0,0 +1,988 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/init.c
* PURPOSE: CSR Server DLL Initialization
* PROGRAMMERS: Alex Ionescu ([email protected])
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
HANDLE CsrObjectDirectory;
ULONG SessionId;
BOOLEAN CsrProfileControl;
UNICODE_STRING CsrDirectoryName;
HANDLE CsrHeap;
HANDLE BNOLinksDirectory;
HANDLE SessionObjectDirectory;
HANDLE DosDevicesDirectory;
HANDLE CsrInitializationEvent;
SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
ULONG CsrDebug;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrParseServerCommandLine
*
* The CsrParseServerCommandLine routine parses the CSRSS command-line in the
* registry and performs operations for each entry found.
*
* @param ArgumentCount
* Number of arguments on the command line.
*
* @param Arguments
* Array of arguments.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
FASTCALL
CsrParseServerCommandLine(IN ULONG ArgumentCount,
IN PCHAR Arguments[])
{
NTSTATUS Status;
PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
ULONG i, DllIndex;
ANSI_STRING AnsiString;
OBJECT_ATTRIBUTES ObjectAttributes;
/* Set the Defaults */
CsrTotalPerProcessDataLength = 0;
CsrObjectDirectory = 0;
CsrMaxApiRequestThreads = 16;
/* Save our Session ID, and create a Directory for it */
SessionId = NtCurrentPeb()->SessionId;
Status = CsrCreateSessionObjectDirectory(SessionId);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
Status);
/* It's not fatal if the session ID isn't zero */
if (SessionId) return Status;
ASSERT(NT_SUCCESS(Status));
}
/* Loop through every argument */
for (i = 1; i < ArgumentCount; i++)
{
/* Split Name and Value */
ParameterName = Arguments[i];
ParameterValue = NULL;
ParameterValue = strchr(ParameterName, '=');
if (ParameterValue) *ParameterValue++ = ANSI_NULL;
DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);
/* Check for Object Directory */
if (!_stricmp(ParameterName, "ObjectDirectory"))
{
/* Check if a session ID is specified */
if (SessionId)
{
DPRINT1("Sessions not yet implemented\n");
ASSERT(SessionId);
}
/* Initialize the directory name */
RtlInitAnsiString(&AnsiString, ParameterValue);
Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
&AnsiString,
TRUE);
ASSERT(NT_SUCCESS(Status) || SessionId != 0);
if (!NT_SUCCESS(Status)) return Status;
/* Create it */
InitializeObjectAttributes(&ObjectAttributes,
&CsrDirectoryName,
OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
NULL);
Status = NtCreateDirectoryObject(&CsrObjectDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) return Status;
/* Secure it */
Status = CsrSetDirectorySecurity(CsrObjectDirectory);
if (!NT_SUCCESS(Status)) return Status;
}
else if (!_stricmp(ParameterName, "SubSystemType"))
{
/* Ignored */
}
else if (!_stricmp(ParameterName, "MaxRequestThreads"))
{
Status = RtlCharToInteger(ParameterValue,
0,
&CsrMaxApiRequestThreads);
}
else if (!_stricmp(ParameterName, "RequestThreads"))
{
/* Ignored */
Status = STATUS_SUCCESS;
}
else if (!_stricmp(ParameterName, "ProfileControl"))
{
/* Ignored */
}
else if (!_stricmp(ParameterName, "SharedSection"))
{
/* Craete the Section */
Status = CsrSrvCreateSharedSection(ParameterValue);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
ParameterName, ParameterValue, Status);
return Status;
}
/* Load us */
Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
}
else if (!_stricmp(ParameterName, "ServerDLL"))
{
/* Loop the command line */
EntryPoint = NULL;
Status = STATUS_INVALID_PARAMETER;
ServerString = ParameterValue;
while (*ServerString)
{
/* Check for the Entry Point */
if ((*ServerString == ':') && (!EntryPoint))
{
/* Found it. Add a nullchar and save it */
*ServerString++ = ANSI_NULL;
EntryPoint = ServerString;
}
/* Check for the Dll Index */
if (*ServerString++ == ',') break;
}
/* Did we find something to load? */
if (!*ServerString)
{
DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
ParameterValue, Status);
return Status;
}
/* Convert it to a ULONG */
Status = RtlCharToInteger(ServerString, 10, &DllIndex);
/* Add a null char if it was valid */
if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
/* Load it */
if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
ParameterValue, Status);
return Status;
}
}
else if (!_stricmp(ParameterName, "Windows"))
{
/* Ignored */
}
else
{
/* Invalid parameter on the command line */
Status = STATUS_INVALID_PARAMETER;
}
}
/* Return status */
return Status;
}
/*++
* @name CsrCreateLocalSystemSD
*
* The CsrCreateLocalSystemSD routine creates a Security Descriptor for
* the local account with PORT_ALL_ACCESS.
*
* @param LocalSystemSd
* Pointer to a pointer to the security descriptor to create.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
{
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID SystemSid;
ULONG Length;
PSECURITY_DESCRIPTOR SystemSd;
PACL Dacl;
NTSTATUS Status;
/* Initialize the System SID */
RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&SystemSid);
/* Get the length of the SID */
Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
/* Set the pointer to the DACL */
Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Create the DACL for it*/
RtlCreateAcl(Dacl, Length, ACL_REVISION2);
/* Create the ACE */
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Clear the DACL in the SD */
Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Free the SID and return*/
RtlFreeSid(SystemSid);
*LocalSystemSd = SystemSd;
return Status;
}
/*++
* @name GetDosDevicesProtection
*
* The GetDosDevicesProtection creates a security descriptor for the DOS Devices
* Object Directory.
*
* @param DosDevicesSd
* Pointer to the Security Descriptor to return.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks Depending on the DOS Devices Protection Mode (set in the registry),
* regular users may or may not have full access to the directory.
*
*--*/
NTSTATUS
NTAPI
GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
{
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID WorldSid, CreatorSid, AdminSid, SystemSid;
UCHAR KeyValueBuffer[0x40];
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
UNICODE_STRING KeyName;
ULONG ProtectionMode = 0;
OBJECT_ATTRIBUTES ObjectAttributes;
PACL Dacl;
PACCESS_ALLOWED_ACE Ace;
HANDLE hKey;
NTSTATUS Status;
ULONG ResultLength, SidLength, AclLength;
/* Create the SD */
Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
ASSERT(NT_SUCCESS(Status));
/* Initialize the System SID */
Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&SystemSid);
ASSERT(NT_SUCCESS(Status));
/* Initialize the World SID */
Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&WorldSid);
ASSERT(NT_SUCCESS(Status));
/* Initialize the Admin SID */
Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdminSid);
ASSERT(NT_SUCCESS(Status));
/* Initialize the Creator SID */
Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
SECURITY_CREATOR_OWNER_RID,
0, 0, 0, 0, 0, 0, 0,
&CreatorSid);
ASSERT(NT_SUCCESS(Status));
/* Open the Session Manager Key */
RtlInitUnicodeString(&KeyName, SM_REG_KEY);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Read the key value */
RtlInitUnicodeString(&KeyName, L"ProtectionMode");
Status = NtQueryValueKey(hKey,
&KeyName,
KeyValuePartialInformation,
KeyValueBuffer,
sizeof(KeyValueBuffer),
&ResultLength);
/* Make sure it's what we expect it to be */
KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
(*(PULONG)KeyValuePartialInfo->Data))
{
/* Save the Protection Mode */
ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
}
/* Close the handle */
NtClose(hKey);
}
/* Check the Protection Mode */
if (ProtectionMode & 3)
{
/* Calculate SID Lengths */
SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
RtlLengthSid(AdminSid);
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
/* Allocate memory for the DACL */
Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
ASSERT(Dacl != NULL);
/* Build the ACL and add 3 ACEs */
Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
ASSERT(NT_SUCCESS(Status));
/* Edit the ACEs to make them inheritable */
Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
ASSERT(NT_SUCCESS(Status));
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
ASSERT(NT_SUCCESS(Status));
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
ASSERT(NT_SUCCESS(Status));
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
/* Set this DACL with the SD */
Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
ASSERT(NT_SUCCESS(Status));
goto Quickie;
}
else
{
/* Calculate SID Lengths */
SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
/* Allocate memory for the DACL */
Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
ASSERT(Dacl != NULL);
/* Build the ACL and add 3 ACEs */
Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
ASSERT(NT_SUCCESS(Status));
Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
ASSERT(NT_SUCCESS(Status));
/* Edit the last ACE to make it inheritable */
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
ASSERT(NT_SUCCESS(Status));
Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
/* Set this DACL with the SD */
Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
ASSERT(NT_SUCCESS(Status));
goto Quickie;
}
/* FIXME: failure cases! Fail: */
/* Free the memory */
RtlFreeHeap(CsrHeap, 0, Dacl);
/* FIXME: semi-failure cases! Quickie: */
Quickie:
/* Free the SIDs */
RtlFreeSid(SystemSid);
RtlFreeSid(WorldSid);
RtlFreeSid(AdminSid);
RtlFreeSid(CreatorSid);
/* Return */
return Status;
}
/*++
* @name FreeDosDevicesProtection
*
* The FreeDosDevicesProtection frees the security descriptor that was created
* by GetDosDevicesProtection
*
* @param DosDevicesSd
* Pointer to the security descriptor to free.
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
{
PACL Dacl;
BOOLEAN Present, Default;
NTSTATUS Status;
/* Get the DACL corresponding to this SD */
Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
ASSERT(NT_SUCCESS(Status));
ASSERT(Present);
ASSERT(Dacl != NULL);
/* Free it */
if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
}
/*++
* @name CsrCreateSessionObjectDirectory
*
* The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects,
* Session and Dos Devices directories for the specified session.
*
* @param Session
* Session ID for which to create the directories.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateSessionObjectDirectory(IN ULONG Session)
{
WCHAR SessionBuffer[512], BnoBuffer[512];
UNICODE_STRING SessionString, BnoString;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE BnoHandle;
SECURITY_DESCRIPTOR DosDevicesSd;
NTSTATUS Status;
/* Generate the Session BNOLINKS Directory name */
swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
RtlInitUnicodeString(&SessionString, SessionBuffer);
/* Create it */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateDirectoryObject(&BNOLinksDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
return Status;
}
/* Now add the Session ID */
swprintf(SessionBuffer, L"%ld", Session);
RtlInitUnicodeString(&SessionString, SessionBuffer);
/* Check if this is the first Session */
if (Session)
{
/* Not the first, so the name will be slighly more complex */
swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
RtlInitUnicodeString(&BnoString, BnoBuffer);
}
else
{
/* Use the direct name */
RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
}
/* Create the symlink */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
BNOLinksDirectory,
NULL);
Status = NtCreateSymbolicLinkObject(&BnoHandle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
&BnoString);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
return Status;
}
/* Create the \DosDevices Security Descriptor */
Status = GetDosDevicesProtection(&DosDevicesSd);
if (!NT_SUCCESS(Status)) return Status;
/* Now create a directory for this session */
swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
RtlInitUnicodeString(&SessionString, SessionBuffer);
/* Create the directory */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
0,
&DosDevicesSd);
Status = NtCreateDirectoryObject(&SessionObjectDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
FreeDosDevicesProtection(&DosDevicesSd);
return Status;
}
/* Next, create a directory for this session's DOS Devices */
RtlInitUnicodeString(&SessionString, L"DosDevices");
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
OBJ_CASE_INSENSITIVE,
SessionObjectDirectory,
&DosDevicesSd);
Status = NtCreateDirectoryObject(&DosDevicesDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
"CsrCreateSessionObjectDirectory - status = %lx\n", Status);
}
/* Release the Security Descriptor */
FreeDosDevicesProtection(&DosDevicesSd);
/* Return */
return Status;
}
/*++
* @name CsrSetProcessSecurity
*
* The CsrSetProcessSecurity routine protects access to the CSRSS process
* from unauthorized tampering.
*
* @param None.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSetProcessSecurity(VOID)
{
NTSTATUS Status;
HANDLE hToken, hProcess = NtCurrentProcess();
ULONG ReturnLength, Length;
PTOKEN_USER TokenInfo = NULL;
PSECURITY_DESCRIPTOR ProcSd = NULL;
PACL Dacl;
PSID UserSid;
/* Open our token */
Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Get the Token User Length */
NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
/* Allocate space for it */
TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
if (!TokenInfo)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Now query the data */
Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
NtClose(hToken);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Now check the SID Length */
UserSid = TokenInfo->User.Sid;
ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
if (!ProcSd)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Set the pointer to the DACL */
Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Create the DACL for it*/
RtlCreateAcl(Dacl, Length, ACL_REVISION2);
/* Create the ACE */
Status = RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
PROCESS_VM_READ | PROCESS_VM_WRITE |
PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
PROCESS_QUERY_INFORMATION | READ_CONTROL,
UserSid);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Clear the DACL in the SD */
Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
if (!NT_SUCCESS(Status)) goto Quickie;
/* Write the SD into the Process */
Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
/* Free the memory and return */
Quickie:
if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
RtlFreeHeap(CsrHeap, 0, TokenInfo);
return Status;
}
/*++
* @name CsrSetDirectorySecurity
*
* The CsrSetDirectorySecurity routine sets the security descriptor for the
* specified Object Directory.
*
* @param ObjectDirectory
* Handle fo the Object Directory to protect.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSetDirectorySecurity(IN HANDLE ObjectDirectory)
{
/* FIXME: Implement */
return STATUS_SUCCESS;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name CsrServerInitialization
* @implemented NT4
*
* The CsrServerInitialization routine is the native (not Server) entrypoint
* of this Server DLL. It serves as the entrypoint for csrss.
*
* @param ArgumentCount
* Number of arguments on the command line.
*
* @param Arguments
* Array of arguments from the command line.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrServerInitialization(IN ULONG ArgumentCount,
IN PCHAR Arguments[])
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG i = 0;
PVOID ProcessData;
PCSR_SERVER_DLL ServerDll;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Create the Init Event */
Status = NtCreateEvent(&CsrInitializationEvent,
EVENT_ALL_ACCESS,
NULL,
SynchronizationEvent,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Cache System Basic Information so we don't always request it */
Status = NtQuerySystemInformation(SystemBasicInformation,
&CsrNtSysInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Save our Heap */
CsrHeap = RtlGetProcessHeap();
/* Set our Security Descriptor to protect the process */
Status = CsrSetProcessSecurity();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Set up Session Support */
Status = CsrInitializeNtSessionList();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Set up Process Support */
Status = CsrInitializeProcessStructure();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Parse the command line */
Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* All Server DLLs are now loaded, allocate a heap for the Root Process */
ProcessData = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY,
CsrTotalPerProcessDataLength);
if (!ProcessData)
{
DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
__FUNCTION__, STATUS_NO_MEMORY);
return STATUS_NO_MEMORY;
}
/*
* Our Root Process was never officially initalized, so write the data
* for each Server DLL manually.
*/
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
/* Is it loaded, and does it have per process data? */
if ((ServerDll) && (ServerDll->SizeOfProcessData))
{
/* It does, give it part of our allocated heap */
CsrRootProcess->ServerData[i] = ProcessData;
/* Move to the next heap position */
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
ServerDll->SizeOfProcessData);
}
else
{
/* Nothing for this Server DLL */
CsrRootProcess->ServerData[i] = NULL;
}
}
/* Now initialize the Root Process manually as well */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
/* Is it loaded, and does it a callback for new processes? */
if ((ServerDll) && (ServerDll->NewProcessCallback))
{
/* Call the callback */
ServerDll->NewProcessCallback(NULL, CsrRootProcess);
}
}
/* Now initialize our API Port */
Status = CsrApiPortInitialize();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Initialize the API Port for SM communication */
Status = CsrSbApiPortInitialize();
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* We're all set! Connect to SM! */
Status = SmConnectToSm(&CsrSbApiPortName,
CsrSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_GUI,
&CsrSmApiPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Finito! Signal the event */
Status = NtSetEvent(CsrInitializationEvent, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Close the event handle now */
NtClose(CsrInitializationEvent);
/* Have us handle Hard Errors */
Status = NtSetDefaultHardErrorPort(CsrApiPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Return status */
return Status;
}
/*++
* @name CsrPopulateDosDevices
* @unimplemented NT5.1
*
* The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
* to populate the Dos Devices Object Directory for the session.
*
* @param None.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrPopulateDosDevices(VOID)
{
DPRINT1("Deprecated API\n");
return;
}
BOOL
NTAPI
DllMain(IN HANDLE hDll,
IN DWORD dwReason,
IN LPVOID lpReserved)
{
/* We don't do much */
UNREFERENCED_PARAMETER(hDll);
UNREFERENCED_PARAMETER(dwReason);
UNREFERENCED_PARAMETER(lpReserved);
return TRUE;
}
/* EOF */
File diff suppressed because it is too large Load Diff
+687
View File
@@ -0,0 +1,687 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/server.c
* PURPOSE: CSR Server DLL Server Functions
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
PCSR_API_ROUTINE CsrServerApiDispatchTable[5] =
{
CsrSrvClientConnect,
CsrSrvUnusedFunction,
CsrSrvUnusedFunction,
CsrSrvIdentifyAlertableThread,
CsrSrvSetPriorityClass
};
BOOLEAN CsrServerApiServerValidTable[5] =
{
TRUE,
FALSE,
TRUE,
TRUE,
TRUE
};
PCHAR CsrServerApiNameTable[5] =
{
"ClientConnect",
"ThreadConnect",
"ProfileControl",
"IdentifyAlertableThread",
"SetPriorityClass"
};
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
PVOID CsrSrvSharedSectionHeap;
PVOID CsrSrvSharedSectionBase;
PVOID *CsrSrvSharedStaticServerData;
ULONG CsrSrvSharedSectionSize;
HANDLE CsrSrvSharedSection;
/* PRIVATE FUNCTIONS**********************************************************/
/*++
* @name CsrLoadServerDll
* @implemented NT4
*
* The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint
*
* @param DllString
* Pointer to the CSR Server DLL to load and call.
*
* @param EntryPoint
* Pointer to the name of the server's initialization function. If
* this parameter is NULL, the default ServerDllInitialize will be
* assumed.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrLoadServerDll(IN PCHAR DllString,
IN PCHAR EntryPoint OPTIONAL,
IN ULONG ServerId)
{
NTSTATUS Status;
ANSI_STRING DllName;
UNICODE_STRING TempString, ErrorString;
ULONG_PTR Parameters[2];
HANDLE hServerDll = NULL;
ULONG Size;
PCSR_SERVER_DLL ServerDll;
STRING EntryPointString;
PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
ULONG Response;
/* Check if it's beyond the maximum we support */
if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
/* Check if it's already been loaded */
if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER;
/* Convert the name to Unicode */
ASSERT(DllString != NULL);
RtlInitAnsiString(&DllName, DllString);
Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* If we are loading ourselves, don't actually load us */
if (ServerId != CSR_SRV_SERVER)
{
/* Load the DLL */
Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);
if (!NT_SUCCESS(Status))
{
/* Setup error parameters */
Parameters[0] = (ULONG_PTR)&TempString;
Parameters[1] = (ULONG_PTR)&ErrorString;
RtlInitUnicodeString(&ErrorString, L"Default Load Path");
/* Send a hard error */
NtRaiseHardError(Status,
2,
3,
Parameters,
OptionOk,
&Response);
}
/* Get rid of the string */
RtlFreeUnicodeString(&TempString);
if (!NT_SUCCESS(Status)) return Status;
}
/* Allocate a CSR DLL Object */
Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
if (!ServerDll)
{
if (hServerDll) LdrUnloadDll(hServerDll);
return STATUS_NO_MEMORY;
}
/* Set up the Object */
ServerDll->Length = Size;
ServerDll->SharedSection = CsrSrvSharedSectionHeap;
ServerDll->Event = CsrInitializationEvent;
ServerDll->Name.Length = DllName.Length;
ServerDll->Name.MaximumLength = DllName.MaximumLength;
ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1);
if (DllName.Length)
{
strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length);
}
ServerDll->ServerId = ServerId;
ServerDll->ServerHandle = hServerDll;
/* Now get the entrypoint */
if (hServerDll)
{
/* Initialize a string for the entrypoint, or use the default */
RtlInitAnsiString(&EntryPointString,
!(EntryPoint) ? "ServerDllInitialization" :
EntryPoint);
/* Get a pointer to it */
Status = LdrGetProcedureAddress(hServerDll,
&EntryPointString,
0,
(PVOID)&ServerDllInitProcedure);
}
else
{
/* No handle, so we are loading ourselves */
ServerDllInitProcedure = CsrServerDllInitialization;
Status = STATUS_SUCCESS;
}
/* Check if we got the pointer, and call it */
if (NT_SUCCESS(Status))
{
/* Get the result from the Server DLL */
Status = ServerDllInitProcedure(ServerDll);
/* Check for Success */
if (NT_SUCCESS(Status))
{
/*
* Add this Server's Per-Process Data Size to the total that each
* process will need.
*/
CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData;
/* Save the pointer in our list */
CsrLoadedServerDll[ServerDll->ServerId] = ServerDll;
/* Does it use our generic heap? */
if (ServerDll->SharedSection != CsrSrvSharedSectionHeap)
{
/* No, save the pointer to its shared section in our list */
CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
}
}
else
{
/* Use shared failure code */
goto LoadFailed;
}
}
else
{
LoadFailed:
/* Server Init failed, unload it */
if (hServerDll) LdrUnloadDll(hServerDll);
/* Delete the Object */
RtlFreeHeap(CsrHeap, 0, ServerDll);
}
/* Return to caller */
return Status;
}
/*++
* @name CsrServerDllInitialization
* @implemented NT4
*
* The CsrServerDllInitialization is the initialization routine for
* the this Server DLL.
*
* @param LoadedServerDll
* Pointer to the CSR Server DLL structure representing this Server DLL.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll)
{
/* Setup the DLL Object */
LoadedServerDll->ApiBase = 0;
LoadedServerDll->HighestApiSupported = 5;
LoadedServerDll->DispatchTable = CsrServerApiDispatchTable;
LoadedServerDll->ValidTable = CsrServerApiServerValidTable;
LoadedServerDll->NameTable = CsrServerApiNameTable;
LoadedServerDll->SizeOfProcessData = 0;
LoadedServerDll->ConnectCallback = NULL;
LoadedServerDll->DisconnectCallback = NULL;
/* All done */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvClientConnect
*
* The CsrSrvClientConnect CSR API handles a new connection to a server DLL.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Optional reply to this request.
*
* @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER
* or STATUS_TOO_MANY_NAMES in case of failure.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply OPTIONAL)
{
NTSTATUS Status;
PCSR_CLIENT_CONNECT ClientConnect;
PCSR_SERVER_DLL ServerDll;
PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process;
/* Load the Message, set default reply */
ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
*Reply = 0;
/* Validate the ServerID */
if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX)
{
return STATUS_TOO_MANY_NAMES;
}
else if (!CsrLoadedServerDll[ClientConnect->ServerId])
{
return STATUS_INVALID_PARAMETER;
}
/* Validate the Message Buffer */
if (!(CsrValidateMessageBuffer(ApiMessage,
ClientConnect->ConnectionInfo,
ClientConnect->ConnectionInfoSize,
1)))
{
/* Fail due to buffer overflow or other invalid buffer */
return STATUS_INVALID_PARAMETER;
}
/* Load the Server DLL */
ServerDll = CsrLoadedServerDll[ClientConnect->ServerId];
/* Check if it has a Connect Callback */
if (ServerDll->ConnectCallback)
{
/* Call the callback */
Status = ServerDll->ConnectCallback(CurrentProcess,
ClientConnect->ConnectionInfo,
&ClientConnect->ConnectionInfoSize);
}
else
{
/* Assume success */
Status = STATUS_SUCCESS;
}
/* Return status */
return Status;
}
/*++
* @name CsrSrvCreateSharedSection
*
* The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
* DLLs and Clients can use to share data.
*
* @param ParameterValue
* Specially formatted string from our registry command-line which
* specifies various arguments for the shared section.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
{
PCHAR SizeValue = ParameterValue;
ULONG Size;
NTSTATUS Status;
LARGE_INTEGER SectionSize;
ULONG ViewSize = 0;
PPEB Peb = NtCurrentPeb();
/* If there's no parameter, fail */
if (!ParameterValue) return STATUS_INVALID_PARAMETER;
/* Find the first comma, and null terminate */
while (*SizeValue)
{
if (*SizeValue == ',')
{
*SizeValue++ = ANSI_NULL;
break;
}
else
{
SizeValue++;
}
}
/* Make sure it's valid */
if (!*SizeValue) return STATUS_INVALID_PARAMETER;
/* Convert it to an integer */
Status = RtlCharToInteger(SizeValue, 0, &Size);
if (!NT_SUCCESS(Status)) return Status;
/* Multiply by 1024 entries and round to page size */
CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
/* Create the Secion */
SectionSize.LowPart = CsrSrvSharedSectionSize;
SectionSize.HighPart = 0;
Status = NtCreateSection(&CsrSrvSharedSection,
SECTION_ALL_ACCESS,
NULL,
&SectionSize,
PAGE_EXECUTE_READWRITE,
SEC_BASED | SEC_RESERVE,
NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Map the section */
Status = NtMapViewOfSection(CsrSrvSharedSection,
NtCurrentProcess(),
&CsrSrvSharedSectionBase,
0,
0,
NULL,
&ViewSize,
ViewUnmap,
MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(CsrSrvSharedSection);
return Status;
}
/* FIXME: Write the value to registry */
/* The Heap is the same place as the Base */
CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
/* Create the heap */
if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7,
CsrSrvSharedSectionHeap,
CsrSrvSharedSectionSize,
PAGE_SIZE,
0,
0)))
{
/* Failure, unmap section and return */
NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase);
NtClose(CsrSrvSharedSection);
return STATUS_NO_MEMORY;
}
/* Now allocate space from the heap for the Shared Data */
CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
0,
CSR_SERVER_DLL_MAX *
sizeof(PVOID));
if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
/* Write the values to the PEB */
Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData;
/* Return */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvAttachSharedSection
*
* The CsrSrvAttachSharedSection maps the CSR Shared Section into a new
* CSR Process' address space, and returns the pointers to the section
* through the Connection Info structure.
*
* @param CsrProcess
* Pointer to the CSR Process that is attempting a connection.
*
* @param ConnectInfo
* Pointer to the CSR Connection Info structure for the incoming
* connection.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
OUT PCSR_CONNECTION_INFO ConnectInfo)
{
NTSTATUS Status;
ULONG ViewSize = 0;
/* Check if we have a process */
if (CsrProcess)
{
/* Map the sectio into this process */
Status = NtMapViewOfSection(CsrSrvSharedSection,
CsrProcess->ProcessHandle,
&CsrSrvSharedSectionBase,
0,
0,
NULL,
&ViewSize,
ViewUnmap,
SEC_NO_CHANGE,
PAGE_EXECUTE_READ);
if (!NT_SUCCESS(Status)) return Status;
}
/* Write the values in the Connection Info structure */
ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase;
ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap;
ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData;
/* Return success */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvIdentifyAlertableThread
* @implemented NT4
*
* The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
/* Set the alertable flag */
CsrThread->Flags |= CsrThreadAltertable;
/* Return success */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvSetPriorityClass
* @implemented NT4
*
* The CsrSrvSetPriorityClass CSR API is deprecated.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
/* Deprecated */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvUnusedFunction
* @implemented NT4
*
* The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs.
*
* The CsrSrvSetPriorityClass CSR API is deprecated.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_INVALID_PARAMETER.
*
* @remarks CsrSrvSetPriorityClass does not use this stub because it must
* return success.
*
*--*/
NTSTATUS
NTAPI
CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
/* Deprecated */
return STATUS_INVALID_PARAMETER;
}
/* PUBLIC FUNCTIONS***********************************************************/
/*++
* @name CsrSetCallingSpooler
* @implemented NT4
*
* the CsrSetCallingSpooler routine is deprecated.
*
* @param Reserved
* Deprecated
*
* @return None.
*
* @remarks This routine was used in archaic versions of NT for Printer Drivers.
*
*--*/
VOID
NTAPI
CsrSetCallingSpooler(ULONG Reserved)
{
/* Deprecated */
return;
}
/*++
* @name CsrUnhandledExceptionFilter
* @implemented NT5
*
* The CsrUnhandledExceptionFilter routine handles all exceptions
* within SEH-protected blocks.
*
* @param ExceptionPointers
* System-defined Argument.
*
* @return EXCEPTION_EXECUTE_HANDLER.
*
* @remarks None.
*
*--*/
LONG
NTAPI
CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
{
SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo;
EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER;
BOOLEAN OldValue;
NTSTATUS Status;
UNICODE_STRING ErrorSource;
ULONG_PTR ErrorParameters[4];
ULONG Response;
/* Check if a debugger is installed */
Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
&DebuggerInfo,
sizeof(DebuggerInfo),
NULL);
/* Check if this is Session 0, and the Debugger is Enabled */
if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) &&
(DebuggerInfo.KernelDebuggerEnabled))
{
/* Call the Unhandled Exception Filter */
if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
EXCEPTION_CONTINUE_EXECUTION)
{
/* We're going to raise an error. Get Shutdown Privilege first */
Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
TRUE,
TRUE,
&OldValue);
/* Use the Process token if that failed */
if (Status == STATUS_NO_TOKEN)
{
Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
TRUE,
FALSE,
&OldValue);
}
/* Initialize our Name String */
RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem");
/* Set the parameters */
ErrorParameters[0] = (ULONG_PTR)&ErrorSource;
ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
/* Bugcheck */
Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
4,
1,
ErrorParameters,
OptionShutdownSystem,
&Response);
}
/* Just terminate us */
NtTerminateProcess(NtCurrentProcess(),
ExceptionInfo->ExceptionRecord->ExceptionCode);
}
return Result;
}
/* EOF */
+407
View File
@@ -0,0 +1,407 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/session.c
* PURPOSE: CSR Server DLL Session Implementation
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
RTL_CRITICAL_SECTION CsrNtSessionLock;
LIST_ENTRY CsrNtSessionList;
HANDLE CsrSmApiPort;
PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
{
CsrSbCreateSession,
CsrSbTerminateSession,
CsrSbForeignSessionComplete,
CsrSbCreateProcess,
NULL
};
PCHAR CsrServerSbApiName[5] =
{
"SbCreateSession",
"SbTerminateSession",
"SbForeignSessionComplete",
"SbCreateProcess",
"Unknown Csr Sb Api Number"
};
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrInitializeNtSessionList
*
* The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
*
* @param None
*
* @return None
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrInitializeNtSessionList(VOID)
{
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Initialize the Session List */
InitializeListHead(&CsrNtSessionList);
/* Initialize the Session Lock */
return RtlInitializeCriticalSection(&CsrNtSessionLock);
}
/*++
* @name CsrAllocateNtSession
*
* The CsrAllocateNtSession routine allocates a new CSR NT Session.
*
* @param SessionId
* Session ID of the CSR NT Session to allocate.
*
* @return Pointer to the newly allocated CSR NT Session.
*
* @remarks None.
*
*--*/
PCSR_NT_SESSION
NTAPI
CsrAllocateNtSession(IN ULONG SessionId)
{
PCSR_NT_SESSION NtSession;
/* Allocate an NT Session Object */
NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
if (NtSession)
{
/* Setup the Session Object */
NtSession->SessionId = SessionId;
NtSession->ReferenceCount = 1;
/* Insert it into the Session List */
CsrAcquireNtSessionLock();
InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
CsrReleaseNtSessionLock();
}
else
{
ASSERT(NtSession != NULL);
}
/* Return the Session (or NULL) */
return NtSession;
}
/*++
* @name CsrReferenceNtSession
*
* The CsrReferenceNtSession increases the reference count of a CSR NT Session.
*
* @param Session
* Pointer to the CSR NT Session to reference.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
/* Sanity checks */
ASSERT(!IsListEmpty(&Session->SessionLink));
ASSERT(Session->SessionId != 0);
ASSERT(Session->ReferenceCount != 0);
/* Increase the reference count */
Session->ReferenceCount++;
/* Release the lock */
CsrReleaseNtSessionLock();
}
/*++
* @name CsrDereferenceNtSession
*
* The CsrDereferenceNtSession decreases the reference count of a
* CSR NT Session.
*
* @param Session
* Pointer to the CSR NT Session to reference.
*
* @param ExitStatus
* If this is the last reference to the session, this argument
* specifies the exit status.
*
* @return None.
*
* @remarks CsrDereferenceNtSession will complete the session if
* the last reference to it has been closed.
*
*--*/
VOID
NTAPI
CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
IN NTSTATUS ExitStatus)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
/* Sanity checks */
ASSERT(!IsListEmpty(&Session->SessionLink));
ASSERT(Session->SessionId != 0);
ASSERT(Session->ReferenceCount != 0);
/* Dereference the Session Object */
if (!(--Session->ReferenceCount))
{
/* Remove it from the list */
RemoveEntryList(&Session->SessionLink);
/* Release the lock */
CsrReleaseNtSessionLock();
/* Tell SM that we're done here */
SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
/* Free the Session Object */
RtlFreeHeap(CsrHeap, 0, Session);
}
else
{
/* Release the lock, the Session is still active */
CsrReleaseNtSessionLock();
}
}
/* SESSION MANAGER FUNCTIONS**************************************************/
/*++
* @name CsrSbCreateSession
*
* The CsrSbCreateSession API is called by the Session Manager whenever a new
* session is created.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbCreateSession routine will initialize a new CSR NT
* Session and allocate a new CSR Process for the subsystem process.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{
PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
HANDLE hProcess, hThread;
PCSR_PROCESS CsrProcess;
NTSTATUS Status;
KERNEL_USER_TIMES KernelTimes;
PCSR_THREAD CsrThread;
PVOID ProcessData;
ULONG i;
/* Save the Process and Thread Handles */
hProcess = CreateSession->ProcessInfo.ProcessHandle;
hThread = CreateSession->ProcessInfo.ThreadHandle;
/* Lock the Processes */
CsrAcquireProcessLock();
/* Allocate a new process */
CsrProcess = CsrAllocateProcess();
if (!CsrProcess)
{
/* Fail */
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
/* Set the exception port */
Status = NtSetInformationProcess(hProcess,
ProcessExceptionPort,
&CsrApiPort,
sizeof(HANDLE));
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
/* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)STATUS_NO_MEMORY;
}
/* Get the Create Time */
Status = NtQueryInformationThread(hThread,
ThreadTimes,
&KernelTimes,
sizeof(KERNEL_USER_TIMES),
NULL);
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
/* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)Status;
}
/* Allocate a new Thread */
CsrThread = CsrAllocateThread(CsrProcess);
if (!CsrThread)
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
/* Setup the Thread Object */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
CsrThread->ThreadHandle = hThread;
ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert it into the Process List */
CsrInsertThread(CsrProcess, CsrThread);
/* Setup Process Data */
CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
CsrProcess->ProcessHandle = hProcess;
CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
/* Set the Process Priority */
CsrSetBackgroundPriority(CsrProcess);
/* Get the first data location */
ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
/* Loop every DLL */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Check if the DLL is loaded and has Process Data */
if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
{
/* Write the pointer to the data */
CsrProcess->ServerData[i] = ProcessData;
/* Move to the next data location */
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
CsrLoadedServerDll[i]->SizeOfProcessData);
}
else
{
/* Nothing for this Process */
CsrProcess->ServerData[i] = NULL;
}
}
/* Insert the Process */
CsrInsertProcess(NULL, NULL, CsrProcess);
/* Activate the Thread */
ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
/* Release lock and return */
CsrReleaseProcessLock();
return TRUE;
}
/*++
* @name CsrSbForeignSessionComplete
*
* The CsrSbForeignSessionComplete API is called by the Session Manager
* whenever a foreign session is completed (ie: terminated).
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbForeignSessionComplete API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
{
/* Deprecated/Unimplemented in NT */
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbTerminateSession
*
* The CsrSbTerminateSession API is called by the Session Manager
* whenever a foreign session should be destroyed.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbTerminateSession API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbCreateProcess
*
* The CsrSbCreateProcess API is called by the Session Manager
* whenever a foreign session is created and a new process should be started.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks The CsrSbCreateProcess API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/* EOF */
+395
View File
@@ -0,0 +1,395 @@
#ifndef _SRV_H
#define _SRV_H
/* PSDK/NDK Headers */
#define NTOS_MODE_USER
#include <stdio.h>
#define WIN32_NO_STATUS
#include <windows.h>
#include <winnt.h>
#include <ndk/ntndk.h>
/* CSR Header */
#include <csr/server.h>
#include <sm/smmsg.h>
/* PSEH for SEH Support */
#include <pseh/pseh2.h>
/* DEFINES *******************************************************************/
#define CSR_SERVER_DLL_MAX 4
#define CsrAcquireProcessLock() \
RtlEnterCriticalSection(&CsrProcessLock);
#define CsrReleaseProcessLock() \
RtlLeaveCriticalSection(&CsrProcessLock);
#define CsrAcquireWaitLock() \
RtlEnterCriticalSection(&CsrWaitListsLock);
#define CsrReleaseWaitLock() \
RtlLeaveCriticalSection(&CsrWaitListsLock);
#define CsrAcquireNtSessionLock() \
RtlEnterCriticalSection(&CsrNtSessionLock)
#define CsrReleaseNtSessionLock() \
RtlLeaveCriticalSection(&CsrNtSessionLock)
#define CsrHashThread(t) \
(HandleToUlong(t)&(256 - 1))
#define ProcessStructureListLocked() \
(CsrProcessLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
#define SM_REG_KEY \
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager"
#define SESSION_ROOT L"\\Sessions"
#define GLOBAL_ROOT L"\\GLOBAL??"
#define SYMLINK_NAME L"SymbolicLink"
#define SB_PORT_NAME L"SbAbiPort"
#define CSR_PORT_NAME L"ApiPort"
#define UNICODE_PATH_SEP L"\\"
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
/* DATA **********************************************************************/
extern ULONG CsrTotalPerProcessDataLength;
extern ULONG CsrMaxApiRequestThreads;
extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
extern PCSR_PROCESS CsrRootProcess;
extern UNICODE_STRING CsrSbApiPortName;
extern UNICODE_STRING CsrApiPortName;
extern HANDLE CsrSbApiPort;
extern HANDLE CsrSmApiPort;
extern HANDLE CsrApiPort;
extern HANDLE CsrHeap;
extern RTL_CRITICAL_SECTION CsrProcessLock;
extern RTL_CRITICAL_SECTION CsrWaitListsLock;
extern LIST_ENTRY CsrThreadHashTable[256];
extern HANDLE CsrInitializationEvent;
extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
extern UNICODE_STRING CsrDirectoryName;
extern HANDLE CsrObjectDirectory;
extern PSB_API_ROUTINE CsrServerSbApiDispatch[5];
extern ULONG CsrDebug;
/* FUNCTIONS *****************************************************************/
/* FIXME: Public APIs should go in the CSR Server Include */
BOOLEAN
NTAPI
CsrCaptureArguments(
IN PCSR_THREAD CsrThread,
IN PCSR_API_MESSAGE ApiMessage
);
NTSTATUS
NTAPI
CsrLoadServerDll(
IN PCHAR DllString,
IN PCHAR EntryPoint,
IN ULONG ServerId
);
NTSTATUS
NTAPI
CsrServerInitialization(
ULONG ArgumentCount,
PCHAR Arguments[]
);
BOOLEAN
NTAPI
UnProtectHandle(IN HANDLE ObjectHandle);
VOID
NTAPI
CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrLockedReferenceThread(IN PCSR_THREAD CsrThread);
NTSTATUS
NTAPI
CsrCreateSessionObjectDirectory(IN ULONG SessionId);
NTSTATUS
NTAPI
CsrCreateObjectDirectory(IN PCHAR ObjectDirectory);
NTSTATUS
NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
NTSTATUS
NTAPI
CsrInitializeNtSessionList(VOID);
NTSTATUS
NTAPI
CsrInitializeProcessStructure(VOID);
NTSTATUS
NTAPI
CsrApiPortInitialize(VOID);
NTSTATUS
NTAPI
CsrSbApiPortInitialize(VOID);
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
CsrSbTerminateSession(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
CsrSbCreateProcess(IN PSB_API_MSG ApiMessage);
PCSR_PROCESS
NTAPI
CsrAllocateProcess(VOID);
PCSR_THREAD
NTAPI
CsrAllocateThread(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrInsertThread(
IN PCSR_PROCESS Process,
IN PCSR_THREAD Thread
);
VOID
NTAPI
CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess);
NTSTATUS
NTAPI
CsrGetProcessLuid(
HANDLE hProcess,
PLUID Luid
);
BOOLEAN
NTAPI
CsrImpersonateClient(IN PCSR_THREAD CsrThread);
BOOLEAN
NTAPI
CsrRevertToSelf(VOID);
PCSR_THREAD
NTAPI
CsrLocateThreadByClientId(
OUT PCSR_PROCESS *Process,
IN PCLIENT_ID ClientId
);
VOID
NTAPI
CsrDereferenceNtSession(
IN PCSR_NT_SESSION Session,
NTSTATUS ExitStatus
);
VOID
NTAPI
CsrReferenceNtSession(PCSR_NT_SESSION Session);
VOID
NTAPI
CsrLockedDereferenceThread(PCSR_THREAD CsrThread);
VOID
NTAPI
CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess);
NTSTATUS
NTAPI
CsrLockProcessByClientId(
IN HANDLE Pid,
OUT PCSR_PROCESS *CsrProcess OPTIONAL
);
NTSTATUS
NTAPI
CsrUnlockProcess(PCSR_PROCESS CsrProcess);
NTSTATUS
NTAPI
CsrSrvClientConnect(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvUnusedFunction(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvIdentifyAlertableThread(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvSetPriorityClass(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll);
VOID
NTAPI
CsrDereferenceThread(PCSR_THREAD CsrThread);
VOID
NTAPI
CsrSbApiRequestThread(IN PVOID Parameter);
NTSTATUS
NTAPI
CsrApiRequestThread(IN PVOID Parameter);
BOOLEAN
NTAPI
ProtectHandle(IN HANDLE ObjectHandle);
PCSR_THREAD
NTAPI
CsrAddStaticServerThread(
IN HANDLE hThread,
IN PCLIENT_ID ClientId,
IN ULONG ThreadFlags
);
PCSR_THREAD
NTAPI
CsrConnectToUser(VOID);
PCSR_THREAD
NTAPI
CsrLocateThreadInProcess(
IN PCSR_PROCESS CsrProcess OPTIONAL,
IN PCLIENT_ID Cid
);
NTSTATUS
NTAPI
CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message);
NTSTATUS
NTAPI
CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage);
NTSTATUS
NTAPI
CsrSrvAttachSharedSection(
IN PCSR_PROCESS CsrProcess OPTIONAL,
OUT PCSR_CONNECTION_INFO ConnectInfo
);
VOID
NTAPI
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
BOOLEAN
NTAPI
CsrNotifyWaitBlock(
IN PCSR_WAIT_BLOCK WaitBlock,
IN PLIST_ENTRY WaitList,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags,
IN BOOLEAN DereferenceThread
);
VOID
NTAPI
CsrDereferenceProcess(PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrInsertProcess(
IN PCSR_PROCESS Parent OPTIONAL,
IN PCSR_PROCESS CurrentProcess OPTIONAL,
IN PCSR_PROCESS CsrProcess
);
NTSTATUS
NTAPI
CsrPopulateDosDevicesDirectory(
IN HANDLE DosDevicesDirectory,
IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap
);
BOOLEAN
NTAPI
CsrValidateMessageBuffer(
IN PCSR_API_MESSAGE ApiMessage,
IN PVOID *Buffer,
IN ULONG ArgumentSize,
IN ULONG ArgumentCount
);
NTSTATUS
NTAPI
CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd);
NTSTATUS
NTAPI
CsrDestroyThread(IN PCLIENT_ID Cid);
NTSTATUS
NTAPI
CsrDestroyProcess(
IN PCLIENT_ID Cid,
IN NTSTATUS ExitStatus
);
LONG
NTAPI
CsrUnhandledExceptionFilter(
IN PEXCEPTION_POINTERS ExceptionInfo
);
VOID
NTAPI
CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
NTSTATUS
NTAPI
CsrSetDirectorySecurity(IN HANDLE ObjectDirectory);
#endif
+111
View File
@@ -0,0 +1,111 @@
/*
* CSRSRV Status
*/
/* Organization
*
* api.c - Handles the LPC Reply/Request Threads which wait on Sb and Csr APIs.
* Also in charge of creating those threads and setting up the ports.
* Finally, it provides external APIs for validating the API buffers
* and doing server-to-server API calls.
*
* init.c - Handles initialization of CSRSRV, including command-line parsing,
* loading the Server DLLs, creating the Session Directories, setting
* up the DosDevices Object Directory, and initializing each component.
*
* process.c - Handles all internal functions dealing with the CSR Process Object,
* including de/allocation, de/referencing, un/locking, prority, and
* lookups. Also handles all external APIs which touch the CSR Process Object.
*
* server.c - Handles all internal functions related to loading and managing Server
* DLLs, as well as the routines handling the Shared Static Memory Section.
* Holds the API Dispatch/Valid/Name Tables and the public CSR_SERVER API
* interface. Also home of the SEH handler.
*
* session.c - Handles all internal functions dealing with the CSR Session Object,
* including de/allocation, de/referencing, and un/locking. Holds the SB API
* Dispatch/Name Tables and the public CsrSv API Interface for commmunication
* with the Session Manager.
*
* thread.c - Handles all internal functions dealing with the CSR Thread Object,
* including de/allocation, de/referencing, un/locking, impersonation, and
* lookups. Also handles all external APIs which touch the CSR Thread Object.
*
* wait.c - Handles all internal functions dealing with the CSR Wait Object,
* including de/allocation, de/referencing and un/locking. Also implements
* the external Wait API for creating, removing and/or notifying waits.
*/
/* Exported APIs, their location, and their status
* CsrAddStaticServerThread 753E679E 1 - server.c - IMPLEMENTED
* CsrCallServerFromServer 753E4FD9 2 - api.c - IMPLEMENTED
* CsrConnectToUser 753E4E48 3 - api.c - IMPLEMENTED
* CsrCreateProcess 753E6FD3 4 - process.c - IMPLEMENTED
* CsrCreateRemoteThread 753E73BD 5 - thread.c - IMPLEMENTED
* CsrCreateThread 753E72DA 6 - thread.c - IMPLEMENTED
* CsrCreateWait 753E770E 7 - wait.c - IMPLEMENTED
* CsrDebugProcess 753E7682 8 - process.c - IMPLEMENTED
* CsrDebugProcessStop 753E768A 9 - process.c - IMPLEMENTED
* CsrDereferenceProcess 753E6281 10 - process.c - IMPLEMENTED
* CsrDereferenceThread 753E6964 11 - thread.c - IMPLEMENTED
* CsrDereferenceWait 753E7886 12 - wait.c - IMPLEMENTED
* CsrDestroyProcess 753E7225 13 - process.c - IMPLEMENTED
* CsrDestroyThread 753E7478 14 - thread.c - IMPLEMENTED
* CsrExecServerThread 753E6841 15 - thread.c - IMPLEMENTED
* CsrGetProcessLuid 753E632F 16 - process.c - IMPLEMENTED
* CsrImpersonateClient 753E60F8 17 - thread.c - IMPLEMENTED
* CsrLockProcessByClientId 753E668F 18 - process.c - IMPLEMENTED
* CsrLockThreadByClientId 753E6719 19 - thread.c - IMPLEMENTED
* CsrMoveSatisfiedWait 753E7909 20 - wait.c - IMPLEMENTED
* CsrNotifyWait 753E782F 21 - wait.c - IMPLEMENTED
* CsrPopulateDosDevices 753E37A5 22 - init.c - IMPLEMENTED
* CsrQueryApiPort 753E4E42 23 - api.c - IMPLEMENTED
* CsrReferenceThread 753E61E5 24 - thread.c - IMPLEMENTED
* CsrRevertToSelf 753E615A 25 - thread.c - IMPLEMENTED
* CsrServerInitialization 753E3D75 26 - server.c - IMPLEMENTED
* CsrSetBackgroundPriority 753E5E87 27 - process.c - IMPLEMENTED
* CsrSetCallingSpooler 753E6425 28 - server.c - IMPLEMENTED
* CsrSetForegroundPriority 753E5E67 29 - process.c - IMPLEMENTED
* CsrShutdownProcesses 753E7547 30 - process.c - IMPLEMENTED
* CsrUnhandledExceptionFilter 753E3FE3 31 - server.c - IMPLEMENTED
* CsrUnlockProcess 753E66FD 32 - process.c - IMPLEMENTED
* CsrUnlockThread 753E7503 33 - thread.c - IMPLEMENTED
* CsrValidateMessageBuffer 753E528D 34 - api.c - IMPLEMENTED
* CsrValidateMessageString 753E5323 35 - api.c - UNIMPLEMENTED
*/
/* Public CSR API Interface Status (server.c)
* CsrSrvClientConnect - IMPLEMENTED
* CsrSrvUnusedFunction - IMPLEMENTED
* CsrSrvIdentifyAlertableThread - IMPLEMENTED
* CsrSrvSetPriorityClass - IMPLEMENTED
*/
/* Public SB API Interface Status (session.c)
* CsrSbCreateSession - IMPLEMENTED
* CsrSbForeignSessionComplete - IMPLEMENTED
* CsrSbTerminateSession - UNIMPLEMENTED
* CsrSbCreateProcess - UNIMPLEMENTED
*/
/* What's missing:
*
* - SMSS needs to be partly re-written to match some things done here.
* Among other things, SmConnectToSm, SmCompleteSession and the other
* Sm* Exported APIs have to be properly implemented, as well as the
* callback calling and SM LPC APIs. [DONE!]
*
* - NTDLL needs to get the Csr* routines properly implemented. [DONE!]
*
* - KERNEL32, USER32 need to register with their servers properly.
* Additionally, user32 needs to have ClientThreadStartup implemented
* properly and do the syscall NtUserInitialize (I think) which also
* needs to be implemented in win32k.sys. All this should be less then
* 100 lines of code. [KERNEL32 50% DONE, USER32 NOT DONE]
*
* - The skeleton code for winsrv and basesrv which connects with CSR/CSRSRV
* needs to be written. [NOT DONE]
*
* - The kernel's LPC implementation needs to be made compatible. [DONE!]
*/
File diff suppressed because it is too large Load Diff
+449
View File
@@ -0,0 +1,449 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrsrv/wait.c
* PURPOSE: CSR Server DLL Wait Implementation
* PROGRAMMERS: Emanuele Aliberti
* Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
RTL_CRITICAL_SECTION CsrWaitListsLock;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrInitializeWait
*
* The CsrInitializeWait routine initializes a CSR Wait Object.
*
* @param WaitFunction
* Pointer to the function that will handle this wait.
*
* @param CsrWaitThread
* Pointer to the CSR Thread that will perform the wait.
*
* @param WaitApiMessage
* Pointer to the CSR API Message associated to this wait.
*
* @param WaitContext
* Pointer to a user-defined parameter associated to this wait.
*
* @param NewWaitBlock
* Pointed to the initialized CSR Wait Block for this wait.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
IN PCSR_THREAD CsrWaitThread,
IN OUT PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
OUT PCSR_WAIT_BLOCK *NewWaitBlock)
{
ULONG Size;
PCSR_WAIT_BLOCK WaitBlock;
/* Calculate the size of the wait block */
Size = sizeof(CSR_WAIT_BLOCK) -
sizeof(WaitBlock->WaitApiMessage) +
WaitApiMessage->Header.u1.s1.TotalLength;
/* Allocate the Wait Block */
WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
if (!WaitBlock)
{
/* Fail */
WaitApiMessage->Status = STATUS_NO_MEMORY;
return FALSE;
}
/* Initialize it */
WaitBlock->Size = Size;
WaitBlock->WaitThread = CsrWaitThread;
WaitBlock->WaitContext = WaitContext;
WaitBlock->WaitFunction = WaitFunction;
WaitBlock->UserWaitList.Flink = NULL;
WaitBlock->UserWaitList.Blink = NULL;
WaitBlock->WaitList = WaitBlock->UserWaitList;
/* Copy the message */
RtlMoveMemory(&WaitBlock->WaitApiMessage,
WaitApiMessage,
WaitApiMessage->Header.u1.s1.TotalLength);
/* Return the block */
*NewWaitBlock = WaitBlock;
return TRUE;
}
/*++
* @name CsrNotifyWaitBlock
*
* The CsrNotifyWaitBlock routine calls the wait function for a registered
* CSR Wait Block, and replies to the attached CSR API Message, if any.
*
* @param WaitBlock
* Pointer to the CSR Wait Block
*
* @param WaitList
* Pointer to the wait list for this wait.
*
* @param WaitArgument[1-2]
* User-defined values to pass to the wait function.
*
* @param WaitFlags
* Wait flags for this wait.
*
* @param DereferenceThread
* Specifies whether the CSR Thread should be dereferenced at the
* end of this wait.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks After a wait block is notified, the wait function becomes invalid.
*
*--*/
BOOLEAN
NTAPI
CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
IN PLIST_ENTRY WaitList,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags,
IN BOOLEAN DereferenceThread)
{
/* Call the wait function */
if ((WaitBlock->WaitFunction)(WaitList,
WaitBlock->WaitThread,
&WaitBlock->WaitApiMessage,
WaitBlock->WaitContext,
WaitArgument1,
WaitArgument2,
WaitFlags))
{
/* The wait is done, clear the block */
WaitBlock->WaitThread->WaitBlock = NULL;
/* Check for captured arguments */
if (WaitBlock->WaitApiMessage.CsrCaptureData)
{
/* Release them */
CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
}
/* Reply to the port */
NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
(PPORT_MESSAGE)&WaitBlock->WaitApiMessage);
/* Check if we should dereference the thread */
if (DereferenceThread)
{
/* Remove it from the Wait List */
if (WaitBlock->WaitList.Flink)
{
RemoveEntryList(&WaitBlock->WaitList);
}
/* Remove it from the User Wait List */
if (WaitBlock->UserWaitList.Flink)
{
RemoveEntryList(&WaitBlock->UserWaitList);
}
/* Dereference teh thread */
CsrDereferenceThread(WaitBlock->WaitThread);
/* Free the wait block */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
}
else
{
/* The wait is complete, but the thread is being kept alive */
WaitBlock->WaitFunction = NULL;
}
/* The wait suceeded */
return TRUE;
}
/* The wait failed */
return FALSE;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name CsrCreateWait
* @implemented NT4
*
* The CsrCreateWait routine creates a CSR Wait.
*
* @param WaitList
* Pointer to a list entry of the waits to associate.
*
* @param WaitFunction
* Pointer to the function that will handle this wait.
*
* @param CsrWaitThread
* Pointer to the CSR Thread that will perform the wait.
*
* @param WaitApiMessage
* Pointer to the CSR API Message associated to this wait.
*
* @param WaitContext
* Pointer to a user-defined parameter associated to this wait.
*
* @param UserWaitList
* Pointer to a list entry of the user-defined waits to associate.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrCreateWait(IN PLIST_ENTRY WaitList,
IN CSR_WAIT_FUNCTION WaitFunction,
IN PCSR_THREAD CsrWaitThread,
IN OUT PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
IN PLIST_ENTRY UserWaitList OPTIONAL)
{
PCSR_WAIT_BLOCK WaitBlock;
/* Initialize the wait */
if (!CsrInitializeWait(WaitFunction,
CsrWaitThread,
WaitApiMessage,
WaitContext,
&WaitBlock))
{
return FALSE;
}
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Make sure the thread wasn't destroyed */
if (CsrWaitThread->Flags & CsrThreadTerminated)
{
/* Fail the wait */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
CsrReleaseWaitLock();
return FALSE;
}
/* Insert the wait in the queue */
InsertTailList(WaitList, &WaitBlock->WaitList);
/* Insert the User Wait too, if one was given */
if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);
/* Return */
CsrReleaseWaitLock();
return TRUE;
}
/*++
* @name CsrDereferenceWait
* @implemented NT4
*
* The CsrDereferenceWait routine derefences a CSR Wait Block.
*
* @param WaitList
* Pointer to the Wait List associated to the wait.
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrDereferenceWait(IN PLIST_ENTRY WaitList)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Process and Wait Locks */
CsrAcquireProcessLock();
CsrAcquireWaitLock();
/* Set the list pointers */
NextEntry = WaitList->Flink;
/* Start the loop */
while (NextEntry != WaitList)
{
/* Get the wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Move to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there's no Wait Routine */
if (!WaitBlock->WaitFunction)
{
/* Remove it from the Wait List */
if (WaitBlock->WaitList.Flink)
{
RemoveEntryList(&WaitBlock->WaitList);
}
/* Remove it from the User Wait List */
if (WaitBlock->UserWaitList.Flink)
{
RemoveEntryList(&WaitBlock->UserWaitList);
}
/* Dereference the thread waiting on it */
CsrDereferenceThread(WaitBlock->WaitThread);
/* Free the block */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
}
}
/* Release the locks */
CsrReleaseWaitLock();
CsrReleaseProcessLock();
}
/*++
* @name CsrMoveSatisfiedWait
* @implemented NT5
*
* The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
* to another list entry.
*
* @param NewEntry
* Pointer to a list entry where the satisfied waits will be added.
*
* @param WaitList
* Pointer to a list entry to analyze for satisfied waits.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
IN PLIST_ENTRY WaitList)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Set the List pointers */
NextEntry = WaitList->Flink;
/* Start looping */
while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Go to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there is a Wait Callback */
if (WaitBlock->WaitFunction)
{
/* Remove it from the Wait Block Queue */
RemoveEntryList(&WaitBlock->WaitList);
/* Insert the new entry */
InsertTailList(&WaitBlock->WaitList, NewEntry);
}
}
/* Release the wait lock */
CsrReleaseWaitLock();
}
/*++
* @name CsrNotifyWait
* @implemented NT4
*
* The CsrNotifyWait notifies a CSR Wait Block.
*
* @param WaitList
* Pointer to the list entry for this wait.
*
* @param WaitType
* Type of the wait to perform, either WaitAny or WaitAll.
*
* @param WaitArgument[1-2]
* User-defined argument to pass on to the wait function.
*
* @return TRUE in case of success, FALSE othwerwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrNotifyWait(IN PLIST_ENTRY WaitList,
IN ULONG WaitType,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
BOOLEAN NotifySuccess = FALSE;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Set the List pointers */
NextEntry = WaitList->Flink;
/* Start looping */
while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Go to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there is a Wait Callback */
if (WaitBlock->WaitFunction)
{
/* Notify the Waiter */
NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
WaitList,
WaitArgument1,
WaitArgument2,
0,
FALSE);
/* We've already done a wait, so leave unless this is a Wait All */
if (WaitType != WaitAll) break;
}
}
/* Release the wait lock and return */
CsrReleaseWaitLock();
return NotifySuccess;
}
/* EOF */
+97
View File
@@ -0,0 +1,97 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsys/csr/csrss.c
* PURPOSE: CSR Executable
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include <csr/server.h>
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
CsrpSetDefaultProcessHardErrorMode (VOID)
{
ULONG DefaultHardErrorMode = 0;
/* Disable hard errors */
NtSetInformationProcess(NtCurrentProcess(),
ProcessDefaultHardErrorMode,
&DefaultHardErrorMode,
sizeof(DefaultHardErrorMode));
}
/*
* Note: Standard entrypoint for Native C Programs.
* The OS backend (NtProcessStartup) which calls this routine is
* implemented in a CRT-like static library (much like mainCRTStartup).
* Do NOT manually add the NtProcessStartup entrypoint or anything else.
*/
int
_cdecl
_main(int argc,
char *argv[],
char *envp[],
int DebugFlag)
{
KPRIORITY BasePriority = (8 + 1) + 4;
NTSTATUS Status;
ULONG Response;
UNREFERENCED_PARAMETER(envp);
UNREFERENCED_PARAMETER(DebugFlag);
/* Set the Priority */
NtSetInformationProcess(NtCurrentProcess(),
ProcessBasePriority,
&BasePriority,
sizeof(KPRIORITY));
/* Give us IOPL so that we can access the VGA registers */
Status = NtSetInformationProcess(NtCurrentProcess(),
ProcessUserModeIOPL,
NULL,
0);
if (!NT_SUCCESS(Status))
{
/* Raise a hard error */
DPRINT1("CSRSS: Could not raise IOPL: %x\n", Status);
Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED,
0,
0,
NULL,
OptionOk,
&Response);
}
/* Initialize CSR through CSRSRV */
Status = CsrServerInitialization(argc, argv);
if (!NT_SUCCESS(Status))
{
/* Kill us */
DPRINT1("CSRSS: CsrServerInitialization failed:% lx\n", Status);
NtTerminateProcess(NtCurrentProcess(), Status);
}
/* Disable errors */
CsrpSetDefaultProcessHardErrorMode();
/* If this is Session 0, make sure killing us bugchecks the system */
if (!NtCurrentPeb()->SessionId) RtlSetProcessIsCritical(TRUE, NULL, FALSE);
/* Kill this thread. CSRSRV keeps us going */
NtTerminateThread(NtCurrentThread(), Status);
return 0;
}
/* EOF */
+31
View File
@@ -0,0 +1,31 @@
include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
spec2def(csrsrv.dll csrsrv.spec ADD_IMPORTLIB)
list(APPEND SOURCE
api/process.c
api/user.c
api/wapi.c
procsup.c
thredsup.c
init.c
wait.c
session.c
server.c
${CMAKE_CURRENT_BINARY_DIR}/csrsrv.def)
add_library(csrsrv SHARED ${SOURCE})
target_link_libraries(csrsrv ${PSEH_LIB} smlib)
set_module_type(csrsrv nativedll)
add_importlibs(csrsrv ntdll smdll)
add_pch(csrsrv srv.h)
add_dependencies(csrsrv psdk bugcodes)
add_cd_file(TARGET csrsrv DESTINATION reactos/system32 FOR all)
+229
View File
@@ -0,0 +1,229 @@
/*
* subsystems/win32/csrss/csrsrv/api/process.c
*
* "\windows\ApiPort" port process management functions
*
* ReactOS Operating System
*/
/* INCLUDES ******************************************************************/
#include <srv.h>
#define NDEBUG
#include <debug.h>
extern NTSTATUS CallProcessCreated(PCSR_PROCESS, PCSR_PROCESS);
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
/**********************************************************************
* CSRSS API
*********************************************************************/
CSR_API(CsrSrvCreateProcess)
{
NTSTATUS Status;
HANDLE ProcessHandle, ThreadHandle;
PCSR_THREAD CsrThread;
PCSR_PROCESS NewProcessData;
ULONG Flags, VdmPower = 0, DebugFlags = 0;
/* Get the current client thread */
CsrThread = NtCurrentTeb()->CsrClientThread;
ASSERT(CsrThread != NULL);
/* Extract the flags out of the process handle */
Flags = (ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & 3;
Request->Data.CreateProcessRequest.ProcessHandle = (HANDLE)((ULONG_PTR)Request->Data.CreateProcessRequest.ProcessHandle & ~3);
/* Duplicate the process handle */
Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
Request->Data.CreateProcessRequest.ProcessHandle,
NtCurrentProcess(),
&ProcessHandle,
0,
0,
DUPLICATE_SAME_ACCESS);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to duplicate process handle\n");
return Status;
}
/* Duplicate the thread handle */
Status = NtDuplicateObject(CsrThread->Process->ProcessHandle,
Request->Data.CreateProcessRequest.ThreadHandle,
NtCurrentProcess(),
&ThreadHandle,
0,
0,
DUPLICATE_SAME_ACCESS);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to duplicate process handle\n");
NtClose(ProcessHandle);
return Status;
}
/* See if this is a VDM process */
if (VdmPower)
{
/* Request VDM powers */
Status = NtSetInformationProcess(ProcessHandle,
ProcessWx86Information,
&VdmPower,
sizeof(VdmPower));
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get VDM powers\n");
NtClose(ProcessHandle);
NtClose(ThreadHandle);
return Status;
}
}
/* Convert some flags. FIXME: More need conversion */
if (Request->Data.CreateProcessRequest.CreationFlags & CREATE_NEW_PROCESS_GROUP)
{
DebugFlags |= CsrProcessCreateNewGroup;
}
/* FIXME: SxS Stuff */
/* Call CSRSRV to create the CSR_PROCESS structure and the first CSR_THREAD */
Status = CsrCreateProcess(ProcessHandle,
ThreadHandle,
&Request->Data.CreateProcessRequest.ClientId,
CsrThread->Process->NtSession,
DebugFlags,
NULL);
if (Status == STATUS_THREAD_IS_TERMINATING)
{
DPRINT1("Thread already dead\n");
return Status;
}
/* Check for other failures */
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create process/thread structures: %lx\n", Status);
return Status;
}
/* FIXME: Should notify user32 */
/* FIXME: VDM vodoo */
/* ReactOS Compatibility */
Status = CsrLockProcessByClientId(Request->Data.CreateProcessRequest.ClientId.UniqueProcess, &NewProcessData);
ASSERT(Status == STATUS_SUCCESS);
if (!(Request->Data.CreateProcessRequest.CreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
{
NewProcessData->ParentConsole = ProcessData->Console;
NewProcessData->bInheritHandles = Request->Data.CreateProcessRequest.bInheritHandles;
}
RtlInitializeCriticalSection(&NewProcessData->HandleTableLock);
CallProcessCreated(ProcessData, NewProcessData);
CsrUnlockProcess(NewProcessData);
/* Return the result of this operation */
return Status;
}
CSR_API(CsrSrvCreateThread)
{
PCSR_THREAD CurrentThread;
HANDLE ThreadHandle;
NTSTATUS Status;
PCSR_PROCESS CsrProcess;
/* Get the current CSR thread */
CurrentThread = NtCurrentTeb()->CsrClientThread;
if (!CurrentThread)
{
DPRINT1("Server Thread TID: [%lx.%lx]\n",
Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
Request->Data.CreateThreadRequest.ClientId.UniqueThread);
return STATUS_SUCCESS; // server-to-server
}
/* Get the CSR Process for this request */
CsrProcess = CurrentThread->Process;
if (CsrProcess->ClientId.UniqueProcess !=
Request->Data.CreateThreadRequest.ClientId.UniqueProcess)
{
/* This is a remote thread request -- is it within the server itself? */
if (Request->Data.CreateThreadRequest.ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess)
{
/* Accept this without any further work */
return STATUS_SUCCESS;
}
/* Get the real CSR Process for the remote thread's process */
Status = CsrLockProcessByClientId(Request->Data.CreateThreadRequest.ClientId.UniqueProcess,
&CsrProcess);
if (!NT_SUCCESS(Status)) return Status;
}
/* Duplicate the thread handle so we can own it */
Status = NtDuplicateObject(CurrentThread->Process->ProcessHandle,
Request->Data.CreateThreadRequest.ThreadHandle,
NtCurrentProcess(),
&ThreadHandle,
0,
0,
DUPLICATE_SAME_ACCESS);
if (NT_SUCCESS(Status))
{
/* Call CSRSRV to tell it about the new thread */
Status = CsrCreateThread(CsrProcess,
ThreadHandle,
&Request->Data.CreateThreadRequest.ClientId);
}
/* Unlock the process and return */
if (CsrProcess != CurrentThread->Process) CsrUnlockProcess(CsrProcess);
return Status;
}
CSR_API(CsrTerminateProcess)
{
PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
ASSERT(CsrThread != NULL);
/* Set magic flag so we don't reply this message back */
Request->Type = 0xBABE;
/* Remove the CSR_THREADs and CSR_PROCESS */
return CsrDestroyProcess(&CsrThread->ClientId,
(NTSTATUS)Request->Data.TerminateProcessRequest.uExitCode);
}
CSR_API(CsrConnectProcess)
{
return(STATUS_SUCCESS);
}
CSR_API(CsrGetShutdownParameters)
{
Request->Data.GetShutdownParametersRequest.Level = ProcessData->ShutdownLevel;
Request->Data.GetShutdownParametersRequest.Flags = ProcessData->ShutdownFlags;
return(STATUS_SUCCESS);
}
CSR_API(CsrSetShutdownParameters)
{
ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level;
ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags;
return(STATUS_SUCCESS);
}
/* EOF */
+41
View File
@@ -0,0 +1,41 @@
/*
* subsystems/win32/csrss/csrsrv/api/user.c
*
* User functions
*
* ReactOS Operating System
*
* PROGRAMMER: Eric Kohl
*/
/* INCLUDES ******************************************************************/
#include <srv.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
static BOOLEAN ServicesProcessIdValid = FALSE;
static ULONG_PTR ServicesProcessId;
/* FUNCTIONS *****************************************************************/
CSR_API(CsrRegisterServicesProcess)
{
if (ServicesProcessIdValid == TRUE)
{
/* Only accept a single call */
return STATUS_INVALID_PARAMETER;
}
else
{
ServicesProcessId = (ULONG_PTR)Request->Data.RegisterServicesProcessRequest.ProcessId;
ServicesProcessIdValid = TRUE;
return STATUS_SUCCESS;
}
}
/* EOF */
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "Client/Server Runtime SubSystem Process\0"
#define REACTOS_STR_INTERNAL_NAME "csrsrv\0"
#define REACTOS_STR_ORIGINAL_FILENAME "csrsrv.dll\0"
#include <reactos/version.rc>
+36
View File
@@ -0,0 +1,36 @@
@ stdcall CsrAddStaticServerThread(ptr ptr long)
@ stdcall CsrCallServerFromServer(ptr ptr)
;@ stdcall CsrConnectToUser()
;@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
@ stdcall CsrCreateRemoteThread(ptr ptr)
@ stdcall CsrCreateThread(ptr ptr ptr)
;@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
;@ stdcall CsrDebugProcess(ptr)
;@ stdcall CsrDebugProcessStop(ptr)
;@ stdcall CsrDereferenceProcess(ptr)
;@ stdcall CsrDereferenceThread(ptr)
;@ stdcall CsrDereferenceWait(ptr)
;@ stdcall CsrDestroyProcess(ptr long)
;@ stdcall CsrDestroyThread(ptr)
@ stdcall CsrEnumProcesses(ptr ptr) ; Temporary hack
;@ stdcall CsrExecServerThread(ptr long)
@ stdcall CsrGetProcessLuid(ptr ptr)
@ stdcall CsrImpersonateClient(ptr)
@ stdcall CsrLockProcessByClientId(ptr ptr)
;@ stdcall CsrLockThreadByClientId(ptr ptr)
;@ stdcall CsrMoveSatisfiedWait(ptr ptr)
;@ stdcall CsrNotifyWait(ptr long ptr ptr)
;@ stdcall CsrPopulateDosDevices()
;@ stdcall CsrQueryApiPort()
;@ stdcall CsrReferenceThread(ptr)
@ stdcall CsrRevertToSelf()
@ stdcall CsrServerInitialization(long ptr)
;@ stdcall CsrSetBackgroundPriority(ptr)
;@ stdcall CsrSetCallingSpooler(long)
;@ stdcall CsrSetForegroundPriority(ptr)
;@ stdcall CsrShutdownProcesses(ptr long)
;@ stdcall CsrUnhandledExceptionFilter(ptr)
@ stdcall CsrUnlockProcess(ptr)
;@ stdcall CsrUnlockThread(ptr)
;@ stdcall CsrValidateMessageBuffer(ptr ptr long long)
;@ stdcall CsrValidateMessageString(ptr ptr)
+467
View File
@@ -0,0 +1,467 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/include/api.h
* PURPOSE: CSRSS API interface
*/
#pragma once
#define NTOS_MODE_USER
#include <ndk/psfuncs.h>
#include <ndk/rtlfuncs.h>
#include <csrss/csrss.h>
#define CSR_SRV_SERVER 0
#define CSR_SERVER_DLL_MAX 4
#define LOCK RtlEnterCriticalSection(&ProcessDataLock)
#define UNLOCK RtlLeaveCriticalSection(&ProcessDataLock)
#define CsrAcquireProcessLock() LOCK
#define CsrReleaseProcessLock() UNLOCK
#define ProcessStructureListLocked() \
(ProcessDataLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
#define CsrAcquireWaitLock() \
RtlEnterCriticalSection(&CsrWaitListsLock);
#define CsrReleaseWaitLock() \
RtlLeaveCriticalSection(&CsrWaitListsLock);
#define CsrAcquireNtSessionLock() \
RtlEnterCriticalSection(&CsrNtSessionLock);
#define CsrReleaseNtSessionLock() \
RtlLeaveCriticalSection(&CsrNtSessionLock);
typedef enum _CSR_THREAD_FLAGS
{
CsrThreadAltertable = 0x1,
CsrThreadInTermination = 0x2,
CsrThreadTerminated = 0x4,
CsrThreadIsServerThread = 0x10
} CSR_THREAD_FLAGS, *PCSR_THREAD_FLAGS;
typedef enum _SHUTDOWN_RESULT
{
CsrShutdownCsrProcess = 1,
CsrShutdownNonCsrProcess,
CsrShutdownCancelled
} SHUTDOWN_RESULT, *PSHUTDOWN_RESULT;
typedef enum _CSR_SHUTDOWN_FLAGS
{
CsrShutdownSystem = 4,
CsrShutdownOther = 8
} CSR_SHUTDOWN_FLAGS, *PCSR_SHUTDOWN_FLAGS;
typedef enum _CSR_DEBUG_FLAGS
{
CsrDebugOnlyThisProcess = 1,
CsrDebugProcessChildren = 2
} CSR_PROCESS_DEBUG_FLAGS, *PCSR_PROCESS_DEBUG_FLAGS;
typedef enum _CSR_PROCESS_FLAGS
{
CsrProcessTerminating = 0x1,
CsrProcessSkipShutdown = 0x2,
CsrProcessNormalPriority = 0x10,
CsrProcessIdlePriority = 0x20,
CsrProcessHighPriority = 0x40,
CsrProcessRealtimePriority = 0x80,
CsrProcessCreateNewGroup = 0x100,
CsrProcessTerminated = 0x200,
CsrProcessLastThreadTerminated = 0x400,
CsrProcessIsConsoleApp = 0x800
} CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS;
#define CsrProcessPriorityFlags (CsrProcessNormalPriority | \
CsrProcessIdlePriority | \
CsrProcessHighPriority | \
CsrProcessRealtimePriority)
typedef struct _CSRSS_CON_PROCESS_DATA
{
HANDLE ConsoleEvent;
struct tagCSRSS_CONSOLE *Console;
struct tagCSRSS_CONSOLE *ParentConsole;
BOOL bInheritHandles;
RTL_CRITICAL_SECTION HandleTableLock;
ULONG HandleTableSize;
struct _CSRSS_HANDLE *HandleTable;
PCONTROLDISPATCHER CtrlDispatcher;
LIST_ENTRY ConsoleLink;
} CSRSS_CON_PROCESS_DATA, *PCSRSS_CON_PROCESS_DATA;
typedef struct _CSR_NT_SESSION
{
ULONG ReferenceCount;
LIST_ENTRY SessionLink;
ULONG SessionId;
} CSR_NT_SESSION, *PCSR_NT_SESSION;
typedef struct _CSR_PROCESS
{
CLIENT_ID ClientId;
LIST_ENTRY ListLink;
LIST_ENTRY ThreadList;
struct _CSR_PROCESS *Parent;
PCSR_NT_SESSION NtSession;
ULONG ExpectedVersion;
HANDLE ClientPort;
ULONG_PTR ClientViewBase;
ULONG_PTR ClientViewBounds;
HANDLE ProcessHandle;
ULONG SequenceNumber;
ULONG Flags;
ULONG DebugFlags;
CLIENT_ID DebugCid;
ULONG ReferenceCount;
ULONG ProcessGroupId;
ULONG ProcessGroupSequence;
ULONG fVDM;
ULONG ThreadCount;
ULONG PriorityClass;
ULONG Reserved;
ULONG ShutdownLevel;
ULONG ShutdownFlags;
// PVOID ServerData[ANYSIZE_ARRAY];
CSRSS_CON_PROCESS_DATA;
} CSR_PROCESS, *PCSR_PROCESS;
typedef struct _CSR_THREAD
{
LARGE_INTEGER CreateTime;
LIST_ENTRY Link;
LIST_ENTRY HashLinks;
CLIENT_ID ClientId;
PCSR_PROCESS Process;
struct _CSR_WAIT_BLOCK *WaitBlock;
HANDLE ThreadHandle;
ULONG Flags;
ULONG ReferenceCount;
ULONG ImpersonationCount;
} CSR_THREAD, *PCSR_THREAD;
typedef
BOOLEAN
(*CSR_WAIT_FUNCTION)(
IN PLIST_ENTRY WaitList,
IN PCSR_THREAD WaitThread,
IN PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags
);
typedef struct _CSR_WAIT_BLOCK
{
ULONG Size;
LIST_ENTRY WaitList;
LIST_ENTRY UserWaitList;
PVOID WaitContext;
PCSR_THREAD WaitThread;
CSR_WAIT_FUNCTION WaitFunction;
CSR_API_MESSAGE WaitApiMessage;
} CSR_WAIT_BLOCK, *PCSR_WAIT_BLOCK;
typedef
NTSTATUS
(NTAPI *PCSR_CONNECT_CALLBACK)(
IN PCSR_PROCESS CsrProcess,
IN OUT PVOID ConnectionInfo,
IN OUT PULONG ConnectionInfoLength
);
typedef
VOID
(NTAPI *PCSR_DISCONNECT_CALLBACK)(IN PCSR_PROCESS CsrProcess);
typedef
NTSTATUS
(NTAPI *PCSR_NEWPROCESS_CALLBACK)(
IN PCSR_PROCESS Parent,
IN PCSR_PROCESS CsrProcess
);
typedef
VOID
(NTAPI *PCSR_HARDERROR_CALLBACK)(
IN PCSR_THREAD CsrThread,
IN PHARDERROR_MSG HardErrorMessage
);
typedef
ULONG
(NTAPI *PCSR_SHUTDOWNPROCESS_CALLBACK)(
IN PCSR_PROCESS CsrProcess,
IN ULONG Flags,
IN BOOLEAN FirstPhase
);
typedef
NTSTATUS
(NTAPI *PCSR_API_ROUTINE)(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
typedef struct _CSR_SERVER_DLL
{
ULONG Length;
HANDLE Event;
ANSI_STRING Name;
HANDLE ServerHandle;
ULONG ServerId;
ULONG Unknown;
ULONG ApiBase;
ULONG HighestApiSupported;
PCSR_API_ROUTINE *DispatchTable;
PBOOLEAN ValidTable;
PCHAR *NameTable;
ULONG SizeOfProcessData;
PCSR_CONNECT_CALLBACK ConnectCallback;
PCSR_DISCONNECT_CALLBACK DisconnectCallback;
PCSR_HARDERROR_CALLBACK HardErrorCallback;
PVOID SharedSection;
PCSR_NEWPROCESS_CALLBACK NewProcessCallback;
PCSR_SHUTDOWNPROCESS_CALLBACK ShutdownProcessCallback;
ULONG Unknown2[3];
} CSR_SERVER_DLL, *PCSR_SERVER_DLL;
typedef
NTSTATUS
(NTAPI *PCSR_SERVER_DLL_INIT_CALLBACK)(IN PCSR_SERVER_DLL ServerDll);
typedef NTSTATUS (WINAPI *CSRSS_API_PROC)(PCSR_PROCESS ProcessData,
PCSR_API_MESSAGE Request);
typedef struct _CSRSS_API_DEFINITION
{
ULONG Type;
ULONG MinRequestSize;
CSRSS_API_PROC Handler;
} CSRSS_API_DEFINITION, *PCSRSS_API_DEFINITION;
#define CSRSS_DEFINE_API(Func, Handler) \
{ Func, sizeof(CSRSS_##Func), Handler }
typedef struct _CSRSS_LISTEN_DATA
{
HANDLE ApiPortHandle;
ULONG ApiDefinitionsCount;
PCSRSS_API_DEFINITION *ApiDefinitions;
} CSRSS_LISTEN_DATA, *PCSRSS_LISTEN_DATA;
#define CSR_API(n) NTSTATUS WINAPI n ( \
PCSR_PROCESS ProcessData, \
PCSR_API_MESSAGE Request)
/* init.c */
extern HANDLE hBootstrapOk;
NTSTATUS NTAPI CsrServerInitialization(ULONG ArgumentCount, PCHAR Arguments[]);
/* api/process.c */
CSR_API(CsrConnectProcess);
CSR_API(CsrSrvCreateProcess);
CSR_API(CsrTerminateProcess);
CSR_API(CsrSrvCreateThread);
CSR_API(CsrGetShutdownParameters);
CSR_API(CsrSetShutdownParameters);
VOID
NTAPI
CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess);
PCSR_THREAD
NTAPI
CsrAllocateThread(IN PCSR_PROCESS CsrProcess);
PCSR_PROCESS
NTAPI
CsrAllocateProcess(VOID);
VOID
NTAPI
CsrDeallocateProcess(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrRemoveProcess(IN PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrDereferenceThread(IN PCSR_THREAD CsrThread);
VOID
NTAPI
CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
IN PCSR_PROCESS CurrentProcess OPTIONAL,
IN PCSR_PROCESS CsrProcess);
/* api/wapi.c */
NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions);
VOID FASTCALL CsrApiCallHandler(PCSR_PROCESS ProcessData,
PCSR_API_MESSAGE Request);
VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
VOID
NTAPI
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage);
extern HANDLE CsrApiPort;
extern HANDLE CsrSmApiPort;
extern HANDLE CsrSbApiPort;
extern LIST_ENTRY CsrThreadHashTable[256];
extern PCSR_PROCESS CsrRootProcess;
extern RTL_CRITICAL_SECTION ProcessDataLock, CsrWaitListsLock;
extern UNICODE_STRING CsrDirectoryName;
extern ULONG CsrDebug;
extern ULONG CsrTotalPerProcessDataLength;
extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
extern PVOID CsrSrvSharedSectionHeap;
extern PVOID *CsrSrvSharedStaticServerData;
extern HANDLE CsrInitializationEvent;
extern PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
extern ULONG CsrMaxApiRequestThreads;
NTSTATUS
NTAPI
CsrApiPortInitialize(VOID);
NTSTATUS
NTAPI
CsrCreateProcess(IN HANDLE hProcess,
IN HANDLE hThread,
IN PCLIENT_ID ClientId,
IN PCSR_NT_SESSION NtSession,
IN ULONG Flags,
IN PCLIENT_ID DebugCid);
BOOLEAN
NTAPI
ProtectHandle(IN HANDLE ObjectHandle);
VOID
NTAPI
CsrInsertThread(IN PCSR_PROCESS Process,
IN PCSR_THREAD Thread);
VOID
NTAPI
CsrLockedReferenceThread(IN PCSR_THREAD CsrThread);
/* api/process.c */
typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSR_PROCESS ProcessData,
PVOID Context);
NTSTATUS WINAPI CsrInitializeProcessStructure(VOID);
NTSTATUS WINAPI CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc, PVOID Context);
PCSR_THREAD NTAPI CsrAddStaticServerThread(IN HANDLE hThread, IN PCLIENT_ID ClientId, IN ULONG ThreadFlags);
PCSR_THREAD NTAPI CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, IN PCLIENT_ID Cid);
PCSR_THREAD NTAPI CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL, IN PCLIENT_ID ClientId);
NTSTATUS NTAPI CsrLockProcessByClientId(IN HANDLE Pid, OUT PCSR_PROCESS *CsrProcess OPTIONAL);
NTSTATUS NTAPI CsrCreateThread(IN PCSR_PROCESS CsrProcess, IN HANDLE hThread, IN PCLIENT_ID ClientId);
NTSTATUS NTAPI CsrUnlockProcess(IN PCSR_PROCESS CsrProcess);
//hack
VOID NTAPI CsrThreadRefcountZero(IN PCSR_THREAD CsrThread);
NTSTATUS
NTAPI
CsrInitializeNtSessionList(VOID);
NTSTATUS
NTAPI
CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
OUT PCSR_CONNECTION_INFO ConnectInfo);
NTSTATUS
NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
NTSTATUS
NTAPI
CsrSrvClientConnect(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvUnusedFunction(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvIdentifyAlertableThread(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrSrvSetPriorityClass(
IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply
);
NTSTATUS
NTAPI
CsrDestroyProcess(IN PCLIENT_ID Cid,
IN NTSTATUS ExitStatus);
NTSTATUS
NTAPI
CsrDestroyThread(IN PCLIENT_ID Cid);
VOID
NTAPI
CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread);
BOOLEAN
NTAPI
CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
IN PLIST_ENTRY WaitList,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags,
IN BOOLEAN DereferenceThread);
VOID
NTAPI
CsrReferenceNtSession(IN PCSR_NT_SESSION Session);
LONG
NTAPI
CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo);
VOID
NTAPI
CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
IN NTSTATUS ExitStatus);
VOID
NTAPI
CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess);
VOID
NTAPI
CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess);
NTSTATUS
NTAPI
CsrLoadServerDll(IN PCHAR DllString,
IN PCHAR EntryPoint OPTIONAL,
IN ULONG ServerId);
/* api/user.c */
CSR_API(CsrRegisterServicesProcess);
/* EOF */
@@ -0,0 +1,51 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/include/csrplugin.h
* PURPOSE: CSRSS plugin interface
*/
/*
* CSRSS is a native application and can only implicitly link against native
* DLLs. Since e.g. user32.dll and gdi32.dll are win32 DLLs and not native
* DLLs it is not possible to call functions in those DLLs directly from
* CSRSS.
* However, it is possible to explicitly load a non-native DLL. Such a DLL
* can then in turn be implicitly linked against other DLLs in its own
* subsystem.
*/
#pragma once
#include "api.h"
typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESSES_PROC)(CSRSS_ENUM_PROCESS_PROC EnumProc,
PVOID Context);
typedef struct tagCSRSS_EXPORTED_FUNCS
{
CSRSS_ENUM_PROCESSES_PROC CsrEnumProcessesProc;
} CSRSS_EXPORTED_FUNCS, *PCSRSS_EXPORTED_FUNCS;
typedef BOOL (WINAPI *CSRPLUGIN_INIT_COMPLETE_PROC)(void);
typedef VOID (WINAPI *CSRPLUGIN_HARDERROR_PROC)(IN PCSR_THREAD ThreadData,
IN PHARDERROR_MSG HardErrorMessage);
typedef NTSTATUS (WINAPI *CSRPLUGIN_PROCESS_INHERIT_PROC)(IN PCSR_PROCESS SourceProcessData,
IN PCSR_PROCESS TargetProcessData);
typedef ULONG (WINAPI *CSRPLUGIN_PROCESS_DELETED_PROC)(IN PCSR_PROCESS ProcessData, IN ULONG Unused, IN BOOLEAN Flag);
typedef struct tagCSRSS_SERVER_PROCS
{
CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
CSRPLUGIN_HARDERROR_PROC HardErrorProc;
CSRPLUGIN_PROCESS_INHERIT_PROC ProcessInheritProc;
CSRPLUGIN_PROCESS_DELETED_PROC ProcessDeletedProc;
} CSRPLUGIN_SERVER_PROCS, *PCSRPLUGIN_SERVER_PROCS;
typedef BOOL (WINAPI *CSRPLUGIN_INITIALIZE_PROC)(PCSRSS_API_DEFINITION *ApiDefinitions,
PCSRPLUGIN_SERVER_PROCS ServerProcs);
/* EOF */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+698
View File
@@ -0,0 +1,698 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsystems/win32/csrss/csrsrv/server.c
* PURPOSE: CSR Server DLL Server Functions
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
PCSR_API_ROUTINE CsrServerApiDispatchTable[5] =
{
CsrSrvClientConnect,
CsrSrvUnusedFunction,
CsrSrvUnusedFunction,
CsrSrvIdentifyAlertableThread,
CsrSrvSetPriorityClass
};
BOOLEAN CsrServerApiServerValidTable[5] =
{
TRUE,
FALSE,
TRUE,
TRUE,
TRUE
};
PCHAR CsrServerApiNameTable[5] =
{
"ClientConnect",
"ThreadConnect",
"ProfileControl",
"IdentifyAlertableThread",
"SetPriorityClass"
};
PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX];
PVOID CsrSrvSharedSectionHeap;
PVOID CsrSrvSharedSectionBase;
PVOID *CsrSrvSharedStaticServerData;
ULONG CsrSrvSharedSectionSize;
HANDLE CsrSrvSharedSection;
/* PRIVATE FUNCTIONS**********************************************************/
/*++
* @name CsrServerDllInitialization
* @implemented NT4
*
* The CsrServerDllInitialization is the initialization routine for
* the this Server DLL.
*
* @param LoadedServerDll
* Pointer to the CSR Server DLL structure representing this Server DLL.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll)
{
/* Setup the DLL Object */
LoadedServerDll->ApiBase = 0;
LoadedServerDll->HighestApiSupported = CsrpMaxApiNumber;
LoadedServerDll->DispatchTable = CsrServerApiDispatchTable;
LoadedServerDll->ValidTable = CsrServerApiServerValidTable;
LoadedServerDll->NameTable = CsrServerApiNameTable;
LoadedServerDll->SizeOfProcessData = 0;
LoadedServerDll->ConnectCallback = NULL;
LoadedServerDll->DisconnectCallback = NULL;
/* All done */
return STATUS_SUCCESS;
}
/*++
* @name CsrLoadServerDll
* @implemented NT4
*
* The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint
*
* @param DllString
* Pointer to the CSR Server DLL to load and call.
*
* @param EntryPoint
* Pointer to the name of the server's initialization function. If
* this parameter is NULL, the default ServerDllInitialize will be
* assumed.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrLoadServerDll(IN PCHAR DllString,
IN PCHAR EntryPoint OPTIONAL,
IN ULONG ServerId)
{
NTSTATUS Status;
ANSI_STRING DllName;
UNICODE_STRING TempString, ErrorString;
ULONG_PTR Parameters[2];
HANDLE hServerDll = NULL;
ULONG Size;
PCSR_SERVER_DLL ServerDll;
STRING EntryPointString;
PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
ULONG Response;
/* Check if it's beyond the maximum we support */
if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
/* Check if it's already been loaded */
if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER;
/* Convert the name to Unicode */
ASSERT(DllString != NULL);
RtlInitAnsiString(&DllName, DllString);
Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);
if (!NT_SUCCESS(Status)) return Status;
/* If we are loading ourselves, don't actually load us */
if (ServerId != CSR_SRV_SERVER)
{
/* Load the DLL */
Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);
if (!NT_SUCCESS(Status))
{
/* Setup error parameters */
Parameters[0] = (ULONG_PTR)&TempString;
Parameters[1] = (ULONG_PTR)&ErrorString;
RtlInitUnicodeString(&ErrorString, L"Default Load Path");
/* Send a hard error */
NtRaiseHardError(Status,
2,
3,
Parameters,
OptionOk,
&Response);
}
/* Get rid of the string */
RtlFreeUnicodeString(&TempString);
if (!NT_SUCCESS(Status)) return Status;
}
/* Allocate a CSR DLL Object */
Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
if (!ServerDll)
{
if (hServerDll) LdrUnloadDll(hServerDll);
return STATUS_NO_MEMORY;
}
/* Set up the Object */
ServerDll->Length = Size;
ServerDll->SharedSection = CsrSrvSharedSectionHeap;
ServerDll->Event = CsrInitializationEvent;
ServerDll->Name.Length = DllName.Length;
ServerDll->Name.MaximumLength = DllName.MaximumLength;
ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1);
if (DllName.Length)
{
strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length);
}
ServerDll->ServerId = ServerId;
ServerDll->ServerHandle = hServerDll;
/* Now get the entrypoint */
if (hServerDll)
{
/* Initialize a string for the entrypoint, or use the default */
RtlInitAnsiString(&EntryPointString,
!(EntryPoint) ? "ServerDllInitialization" :
EntryPoint);
/* Get a pointer to it */
Status = LdrGetProcedureAddress(hServerDll,
&EntryPointString,
0,
(PVOID)&ServerDllInitProcedure);
}
else
{
/* No handle, so we are loading ourselves */
ServerDllInitProcedure = CsrServerDllInitialization;
Status = STATUS_SUCCESS;
}
/* Check if we got the pointer, and call it */
if (NT_SUCCESS(Status))
{
/* Get the result from the Server DLL */
Status = ServerDllInitProcedure(ServerDll);
/* Check for Success */
if (NT_SUCCESS(Status))
{
/*
* Add this Server's Per-Process Data Size to the total that each
* process will need.
*/
CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData;
/* Save the pointer in our list */
CsrLoadedServerDll[ServerDll->ServerId] = ServerDll;
/* Does it use our generic heap? */
if (ServerDll->SharedSection != CsrSrvSharedSectionHeap)
{
/* No, save the pointer to its shared section in our list */
CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection;
}
/* ReactOS Specific hax */
if (ServerDll->HighestApiSupported == 0xDEADBABE)
{
Status = CsrApiRegisterDefinitions((PVOID)ServerDll->DispatchTable);
}
}
else
{
/* Use shared failure code */
goto LoadFailed;
}
}
else
{
LoadFailed:
/* Server Init failed, unload it */
if (hServerDll) LdrUnloadDll(hServerDll);
/* Delete the Object */
RtlFreeHeap(CsrHeap, 0, ServerDll);
}
/* Return to caller */
return Status;
}
/*++
* @name CsrSrvClientConnect
*
* The CsrSrvClientConnect CSR API handles a new connection to a server DLL.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Optional reply to this request.
*
* @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER
* or STATUS_TOO_MANY_NAMES in case of failure.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply OPTIONAL)
{
/* Hack */
return STATUS_SUCCESS;
#if 0
NTSTATUS Status;
PCSR_CLIENT_CONNECT ClientConnect;
PCSR_SERVER_DLL ServerDll;
PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process;
/* Load the Message, set default reply */
ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
*Reply = 0;
/* Validate the ServerID */
if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX)
{
return STATUS_TOO_MANY_NAMES;
}
else if (!CsrLoadedServerDll[ClientConnect->ServerId])
{
return STATUS_INVALID_PARAMETER;
}
/* Validate the Message Buffer */
if (!(CsrValidateMessageBuffer(ApiMessage,
ClientConnect->ConnectionInfo,
ClientConnect->ConnectionInfoSize,
1)))
{
/* Fail due to buffer overflow or other invalid buffer */
return STATUS_INVALID_PARAMETER;
}
/* Load the Server DLL */
ServerDll = CsrLoadedServerDll[ClientConnect->ServerId];
/* Check if it has a Connect Callback */
if (ServerDll->ConnectCallback)
{
/* Call the callback */
Status = ServerDll->ConnectCallback(CurrentProcess,
ClientConnect->ConnectionInfo,
&ClientConnect->ConnectionInfoSize);
}
else
{
/* Assume success */
Status = STATUS_SUCCESS;
}
/* Return status */
return Status;
#endif
}
/*++
* @name CsrSrvCreateSharedSection
*
* The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server
* DLLs and Clients can use to share data.
*
* @param ParameterValue
* Specially formatted string from our registry command-line which
* specifies various arguments for the shared section.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
{
PCHAR SizeValue = ParameterValue;
ULONG Size;
NTSTATUS Status;
LARGE_INTEGER SectionSize;
ULONG ViewSize = 0;
PPEB Peb = NtCurrentPeb();
/* If there's no parameter, fail */
if (!ParameterValue) return STATUS_INVALID_PARAMETER;
/* Find the first comma, and null terminate */
while (*SizeValue)
{
if (*SizeValue == ',')
{
*SizeValue++ = ANSI_NULL;
break;
}
else
{
SizeValue++;
}
}
/* Make sure it's valid */
if (!*SizeValue) return STATUS_INVALID_PARAMETER;
/* Convert it to an integer */
Status = RtlCharToInteger(SizeValue, 0, &Size);
if (!NT_SUCCESS(Status)) return Status;
/* Multiply by 1024 entries and round to page size */
CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
/* Create the Secion */
SectionSize.LowPart = CsrSrvSharedSectionSize;
SectionSize.HighPart = 0;
Status = NtCreateSection(&CsrSrvSharedSection,
SECTION_ALL_ACCESS,
NULL,
&SectionSize,
PAGE_EXECUTE_READWRITE,
SEC_BASED | SEC_RESERVE,
NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Map the section */
Status = NtMapViewOfSection(CsrSrvSharedSection,
NtCurrentProcess(),
&CsrSrvSharedSectionBase,
0,
0,
NULL,
&ViewSize,
ViewUnmap,
MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(CsrSrvSharedSection);
return Status;
}
/* FIXME: Write the value to registry */
/* The Heap is the same place as the Base */
CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
/* Create the heap */
if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7,
CsrSrvSharedSectionHeap,
CsrSrvSharedSectionSize,
PAGE_SIZE,
0,
0)))
{
/* Failure, unmap section and return */
NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase);
NtClose(CsrSrvSharedSection);
return STATUS_NO_MEMORY;
}
/* Now allocate space from the heap for the Shared Data */
CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap,
0,
CSR_SERVER_DLL_MAX *
sizeof(PVOID));
if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
/* Write the values to the PEB */
Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap;
Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData;
/* Return */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvAttachSharedSection
*
* The CsrSrvAttachSharedSection maps the CSR Shared Section into a new
* CSR Process' address space, and returns the pointers to the section
* through the Connection Info structure.
*
* @param CsrProcess
* Pointer to the CSR Process that is attempting a connection.
*
* @param ConnectInfo
* Pointer to the CSR Connection Info structure for the incoming
* connection.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL,
OUT PCSR_CONNECTION_INFO ConnectInfo)
{
NTSTATUS Status;
ULONG ViewSize = 0;
/* Check if we have a process */
if (CsrProcess)
{
/* Map the section into this process */
DPRINT("CSR Process Handle: %p. CSR Process: %p\n", CsrProcess->ProcessHandle, CsrProcess);
Status = NtMapViewOfSection(CsrSrvSharedSection,
CsrProcess->ProcessHandle,
&CsrSrvSharedSectionBase,
0,
0,
NULL,
&ViewSize,
ViewUnmap,
SEC_NO_CHANGE,
PAGE_EXECUTE_READ);
if (!NT_SUCCESS(Status)) return Status;
}
/* Write the values in the Connection Info structure */
ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase;
ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap;
ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData;
/* Return success */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvIdentifyAlertableThread
* @implemented NT4
*
* The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread;
/* Set the alertable flag */
CsrThread->Flags |= CsrThreadAltertable;
/* Return success */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvSetPriorityClass
* @implemented NT4
*
* The CsrSrvSetPriorityClass CSR API is deprecated.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_SUCCESS.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
/* Deprecated */
return STATUS_SUCCESS;
}
/*++
* @name CsrSrvUnusedFunction
* @implemented NT4
*
* The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs.
*
* The CsrSrvSetPriorityClass CSR API is deprecated.
*
* @param ApiMessage
* Pointer to the CSR API Message for this request.
*
* @param Reply
* Pointer to an optional reply to this request.
*
* @return STATUS_INVALID_PARAMETER.
*
* @remarks CsrSrvSetPriorityClass does not use this stub because it must
* return success.
*
*--*/
NTSTATUS
NTAPI
CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage,
IN OUT PULONG Reply)
{
/* Deprecated */
return STATUS_INVALID_PARAMETER;
}
/* PUBLIC FUNCTIONS***********************************************************/
/*++
* @name CsrSetCallingSpooler
* @implemented NT4
*
* the CsrSetCallingSpooler routine is deprecated.
*
* @param Reserved
* Deprecated
*
* @return None.
*
* @remarks This routine was used in archaic versions of NT for Printer Drivers.
*
*--*/
VOID
NTAPI
CsrSetCallingSpooler(ULONG Reserved)
{
/* Deprecated */
return;
}
/*++
* @name CsrUnhandledExceptionFilter
* @implemented NT5
*
* The CsrUnhandledExceptionFilter routine handles all exceptions
* within SEH-protected blocks.
*
* @param ExceptionPointers
* System-defined Argument.
*
* @return EXCEPTION_EXECUTE_HANDLER.
*
* @remarks None.
*
*--*/
LONG
NTAPI
CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
{
SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo;
EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER;
BOOLEAN OldValue;
NTSTATUS Status;
UNICODE_STRING ErrorSource;
ULONG_PTR ErrorParameters[4];
ULONG Response;
/* Check if a debugger is installed */
Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
&DebuggerInfo,
sizeof(DebuggerInfo),
NULL);
/* Check if this is Session 0, and the Debugger is Enabled */
if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) &&
(DebuggerInfo.KernelDebuggerEnabled))
{
/* Call the Unhandled Exception Filter */
if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
EXCEPTION_CONTINUE_EXECUTION)
{
/* We're going to raise an error. Get Shutdown Privilege first */
Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
TRUE,
TRUE,
&OldValue);
/* Use the Process token if that failed */
if (Status == STATUS_NO_TOKEN)
{
Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
TRUE,
FALSE,
&OldValue);
}
/* Initialize our Name String */
RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem");
/* Set the parameters */
ErrorParameters[0] = (ULONG_PTR)&ErrorSource;
ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode;
ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord;
/* Bugcheck */
Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
4,
1,
ErrorParameters,
OptionShutdownSystem,
&Response);
}
/* Just terminate us */
NtTerminateProcess(NtCurrentProcess(),
ExceptionInfo->ExceptionRecord->ExceptionCode);
}
return Result;
}
/* EOF */
+568
View File
@@ -0,0 +1,568 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsystems/win32/csrss/csrsrv/session.c
* PURPOSE: CSR Server DLL Session Implementation
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
RTL_CRITICAL_SECTION CsrNtSessionLock;
LIST_ENTRY CsrNtSessionList;
PCHAR CsrServerSbApiName[5] =
{
"SbCreateSession",
"SbTerminateSession",
"SbForeignSessionComplete",
"SbCreateProcess",
"Unknown Csr Sb Api Number"
};
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrInitializeNtSessionList
*
* The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
*
* @param None
*
* @return None
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrInitializeNtSessionList(VOID)
{
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Initialize the Session List */
InitializeListHead(&CsrNtSessionList);
/* Initialize the Session Lock */
return RtlInitializeCriticalSection(&CsrNtSessionLock);
}
/*++
* @name CsrAllocateNtSession
*
* The CsrAllocateNtSession routine allocates a new CSR NT Session.
*
* @param SessionId
* Session ID of the CSR NT Session to allocate.
*
* @return Pointer to the newly allocated CSR NT Session.
*
* @remarks None.
*
*--*/
PCSR_NT_SESSION
NTAPI
CsrAllocateNtSession(IN ULONG SessionId)
{
PCSR_NT_SESSION NtSession;
/* Allocate an NT Session Object */
NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
if (NtSession)
{
/* Setup the Session Object */
NtSession->SessionId = SessionId;
NtSession->ReferenceCount = 1;
/* Insert it into the Session List */
CsrAcquireNtSessionLock();
InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
CsrReleaseNtSessionLock();
}
else
{
ASSERT(NtSession != NULL);
}
/* Return the Session (or NULL) */
return NtSession;
}
/*++
* @name CsrReferenceNtSession
*
* The CsrReferenceNtSession increases the reference count of a CSR NT Session.
*
* @param Session
* Pointer to the CSR NT Session to reference.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
/* Sanity checks */
ASSERT(!IsListEmpty(&Session->SessionLink));
ASSERT(Session->SessionId != 0);
ASSERT(Session->ReferenceCount != 0);
/* Increase the reference count */
Session->ReferenceCount++;
/* Release the lock */
CsrReleaseNtSessionLock();
}
/*++
* @name CsrDereferenceNtSession
*
* The CsrDereferenceNtSession decreases the reference count of a
* CSR NT Session.
*
* @param Session
* Pointer to the CSR NT Session to reference.
*
* @param ExitStatus
* If this is the last reference to the session, this argument
* specifies the exit status.
*
* @return None.
*
* @remarks CsrDereferenceNtSession will complete the session if
* the last reference to it has been closed.
*
*--*/
VOID
NTAPI
CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
IN NTSTATUS ExitStatus)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
/* Sanity checks */
ASSERT(!IsListEmpty(&Session->SessionLink));
ASSERT(Session->SessionId != 0);
ASSERT(Session->ReferenceCount != 0);
/* Dereference the Session Object */
if (!(--Session->ReferenceCount))
{
/* Remove it from the list */
RemoveEntryList(&Session->SessionLink);
/* Release the lock */
CsrReleaseNtSessionLock();
/* Tell SM that we're done here */
SmSessionComplete(CsrSmApiPort, Session->SessionId, ExitStatus);
/* Free the Session Object */
RtlFreeHeap(CsrHeap, 0, Session);
}
else
{
/* Release the lock, the Session is still active */
CsrReleaseNtSessionLock();
}
}
/* SESSION MANAGER FUNCTIONS**************************************************/
/*++
* @name CsrSbCreateSession
*
* The CsrSbCreateSession API is called by the Session Manager whenever a new
* session is created.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks The CsrSbCreateSession routine will initialize a new CSR NT
* Session and allocate a new CSR Process for the subsystem process.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{
PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
HANDLE hProcess, hThread;
PCSR_PROCESS CsrProcess;
NTSTATUS Status;
KERNEL_USER_TIMES KernelTimes;
PCSR_THREAD CsrThread;
//PVOID ProcessData;
//ULONG i;
/* Save the Process and Thread Handles */
hProcess = CreateSession->ProcessInfo.ProcessHandle;
hThread = CreateSession->ProcessInfo.ThreadHandle;
/* Lock the Processes */
CsrAcquireProcessLock();
/* Allocate a new process */
CsrProcess = CsrAllocateProcess();
if (!CsrProcess)
{
/* Fail */
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
/* Set the exception port */
Status = NtSetInformationProcess(hProcess,
ProcessExceptionPort,
&CsrApiPort,
sizeof(HANDLE));
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
/* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)STATUS_NO_MEMORY;
}
/* Get the Create Time */
Status = NtQueryInformationThread(hThread,
ThreadTimes,
&KernelTimes,
sizeof(KERNEL_USER_TIMES),
NULL);
/* Check for success */
if (!NT_SUCCESS(Status))
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
/* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)Status;
}
/* Allocate a new Thread */
CsrThread = CsrAllocateThread(CsrProcess);
if (!CsrThread)
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
ApiMessage->ReturnValue = STATUS_NO_MEMORY;
return TRUE;
}
/* Setup the Thread Object */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
CsrThread->ThreadHandle = hThread;
ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert it into the Process List */
CsrInsertThread(CsrProcess, CsrThread);
/* Setup Process Data */
CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
CsrProcess->ProcessHandle = hProcess;
CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
/* Set the Process Priority */
CsrSetBackgroundPriority(CsrProcess);
#if 0
/* Get the first data location */
ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
/* Loop every DLL */
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Check if the DLL is loaded and has Process Data */
if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
{
/* Write the pointer to the data */
CsrProcess->ServerData[i] = ProcessData;
/* Move to the next data location */
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
CsrLoadedServerDll[i]->SizeOfProcessData);
}
else
{
/* Nothing for this Process */
CsrProcess->ServerData[i] = NULL;
}
}
#else
/* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */
RtlInitializeCriticalSection(&CsrProcess->HandleTableLock);
#endif
/* Insert the Process */
CsrInsertProcess(NULL, NULL, CsrProcess);
/* Activate the Thread */
ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
/* Release lock and return */
CsrReleaseProcessLock();
return TRUE;
}
/*++
* @name CsrSbForeignSessionComplete
*
* The CsrSbForeignSessionComplete API is called by the Session Manager
* whenever a foreign session is completed (ie: terminated).
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks The CsrSbForeignSessionComplete API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
{
/* Deprecated/Unimplemented in NT */
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbTerminateSession
*
* The CsrSbTerminateSession API is called by the Session Manager
* whenever a foreign session should be destroyed.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks The CsrSbTerminateSession API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
/*++
* @name CsrSbCreateProcess
*
* The CsrSbCreateProcess API is called by the Session Manager
* whenever a foreign session is created and a new process should be started.
*
* @param ApiMessage
* Pointer to the Session Manager API Message.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks The CsrSbCreateProcess API is not yet implemented.
*
*--*/
BOOLEAN
NTAPI
CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
{
ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
{
CsrSbCreateSession,
CsrSbTerminateSession,
CsrSbForeignSessionComplete,
CsrSbCreateProcess,
NULL
};
/*++
* @name CsrSbApiHandleConnectionRequest
*
* The CsrSbApiHandleConnectionRequest routine handles and accepts a new
* connection request to the SM API LPC Port.
*
* @param ApiMessage
* Pointer to the incoming CSR API Message which contains the
* connection request.
*
* @return STATUS_SUCCESS in case of success, or status code which caused
* the routine to error.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
{
NTSTATUS Status;
REMOTE_PORT_VIEW RemotePortView;
HANDLE hPort;
/* Set the Port View Structure Length */
RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
/* Accept the connection */
Status = NtAcceptConnectPort(&hPort,
NULL,
(PPORT_MESSAGE)Message,
TRUE,
NULL,
&RemotePortView);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
return Status;
}
/* Complete the Connection */
Status = NtCompleteConnectPort(hPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
}
/* Return status */
return Status;
}
/*++
* @name CsrSbApiRequestThread
*
* The CsrSbApiRequestThread routine handles incoming messages or connection
* requests on the SM API LPC Port.
*
* @param Parameter
* System-default user-defined parameter. Unused.
*
* @return The thread exit code, if the thread is terminated.
*
* @remarks Before listening on the port, the routine will first attempt
* to connect to the user subsystem.
*
*--*/
VOID
NTAPI
CsrSbApiRequestThread(IN PVOID Parameter)
{
NTSTATUS Status;
SB_API_MSG ReceiveMsg;
PSB_API_MSG ReplyMsg = NULL;
PVOID PortContext;
ULONG MessageType;
/* Start the loop */
while (TRUE)
{
/* Wait for a message to come in */
Status = NtReplyWaitReceivePort(CsrSbApiPort,
&PortContext,
&ReplyMsg->h,
&ReceiveMsg.h);
/* Check if we didn't get success */
if (Status != STATUS_SUCCESS)
{
/* If we only got a warning, keep going */
if (NT_SUCCESS(Status)) continue;
/* We failed big time, so start out fresh */
ReplyMsg = NULL;
DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
continue;
}
/* Save the message type */
MessageType = ReceiveMsg.h.u2.s2.Type;
/* Check if this is a connection request */
if (MessageType == LPC_CONNECTION_REQUEST)
{
/* Handle connection request */
CsrSbApiHandleConnectionRequest(&ReceiveMsg);
/* Start over */
ReplyMsg = NULL;
continue;
}
/* Check if the port died */
if (MessageType == LPC_PORT_CLOSED)
{
/* Close the handle if we have one */
if (PortContext) NtClose((HANDLE)PortContext);
/* Client died, start over */
ReplyMsg = NULL;
continue;
}
else if (MessageType == LPC_CLIENT_DIED)
{
/* Client died, start over */
ReplyMsg = NULL;
continue;
}
/*
* It's an API Message, check if it's within limits. If it's not, the
* NT Behaviour is to set this to the Maximum API.
*/
if (ReceiveMsg.ApiNumber > SbpMaxApiNumber)
{
ReceiveMsg.ApiNumber = SbpMaxApiNumber;
DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber);
}
/* Reuse the message */
ReplyMsg = &ReceiveMsg;
/* Make sure that the message is supported */
if (ReceiveMsg.ApiNumber < SbpMaxApiNumber)
{
/* Call the API */
if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
{
/* It failed, so return nothing */
ReplyMsg = NULL;
}
}
else
{
/* We don't support this API Number */
ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
}
}
}
/* EOF */
+54
View File
@@ -0,0 +1,54 @@
#ifndef _SRV_H
#define _SRV_H
/* PSDK/NDK Headers */
#define NTOS_MODE_USER
#include <stdio.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <wincon.h>
#include <winreg.h>
#include <ndk/setypes.h>
#include <ndk/sefuncs.h>
#include <ndk/exfuncs.h>
#include <ndk/cmfuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/lpctypes.h>
#include <ndk/lpcfuncs.h>
#include <ndk/kefuncs.h>
#include <ndk/dbgktypes.h>
#include <ndk/mmfuncs.h>
#include <ndk/umfuncs.h>
/* CSR Header */
//#include <csr/server.h>
/* PSEH for SEH Support */
#include <pseh/pseh2.h>
/* Subsystem Manager Header */
#include <sm/helper.h>
#include <sm/smmsg.h>
/* Internal CSRSS Headers */
#include <api.h>
#include <csrplugin.h>
extern HANDLE CsrHeap;
#define SM_REG_KEY \
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager"
#define SESSION_ROOT L"\\Sessions"
#define GLOBAL_ROOT L"\\GLOBAL??"
#define SYMLINK_NAME L"SymbolicLink"
#define SB_PORT_NAME L"SbAbiPort"
#define CSR_PORT_NAME L"ApiPort"
#define UNICODE_PATH_SEP L"\\"
/* Defines */
#define ROUND_UP(n, align) ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
#define ROUND_DOWN(n, align) (((ULONG)n) & ~((align) - 1l))
#endif
+819
View File
@@ -0,0 +1,819 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsystems/win32/csrss/csrsrv/thredsup.c
* PURPOSE: CSR Server DLL Thread Implementation
* PROGRAMMERS: ReactOS Portable Systems Group
* Alex Ionescu
*/
/* INCLUDES *******************************************************************/
#include <srv.h>
#define NDEBUG
#include <debug.h>
#define CsrHashThread(t) \
(HandleToUlong(t)&(256 - 1))
/* GLOBALS ********************************************************************/
LIST_ENTRY CsrThreadHashTable[256];
/* FUNCTIONS ******************************************************************/
/*++
* @name ProtectHandle
* @implemented NT5.2
*
* The ProtectHandle routine protects an object handle against closure.
*
* @return TRUE or FALSE.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
ProtectHandle(IN HANDLE ObjectHandle)
{
NTSTATUS Status;
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
/* Query current state */
Status = NtQueryObject(ObjectHandle,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(HandleInfo),
NULL);
if (NT_SUCCESS(Status))
{
/* Enable protect from close */
HandleInfo.ProtectFromClose = TRUE;
Status = NtSetInformationObject(ObjectHandle,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(HandleInfo));
if (NT_SUCCESS(Status)) return TRUE;
}
/* We failed to or set the state */
return FALSE;
}
/*++
* @name UnProtectHandle
* @implemented NT5.2
*
* The UnProtectHandle routine unprotects an object handle against closure.
*
* @return TRUE or FALSE.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
UnProtectHandle(IN HANDLE ObjectHandle)
{
NTSTATUS Status;
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
/* Query current state */
Status = NtQueryObject(ObjectHandle,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(HandleInfo),
NULL);
if (NT_SUCCESS(Status))
{
/* Disable protect from close */
HandleInfo.ProtectFromClose = FALSE;
Status = NtSetInformationObject(ObjectHandle,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(HandleInfo));
if (NT_SUCCESS(Status)) return TRUE;
}
/* We failed to or set the state */
return FALSE;
}
/*++
* @name CsrAllocateThread
*
* The CsrAllocateThread routine allocates a new CSR Thread object.
*
* @param CsrProcess
* Pointer to the CSR Process which will contain this CSR Thread.
*
* @return Pointer to the newly allocated CSR Thread.
*
* @remarks None.
*
*--*/
PCSR_THREAD
NTAPI
CsrAllocateThread(IN PCSR_PROCESS CsrProcess)
{
PCSR_THREAD CsrThread;
/* Allocate the structure */
CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
if (!CsrThread) return(NULL);
/* Reference the Thread and Process */
CsrThread->ReferenceCount++;
CsrProcess->ReferenceCount++;
/* Set the Parent Process */
CsrThread->Process = CsrProcess;
/* Return Thread */
return CsrThread;
}
/*++
* @name CsrLockedReferenceThread
*
* The CsrLockedReferenceThread references a CSR Thread while the
* Process Lock is already being held.
*
* @param CsrThread
* Pointer to the CSR Thread to be referenced.
*
* @return None.
*
* @remarks This routine will return with the Process Lock held.
*
*--*/
VOID
NTAPI
CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
{
/* Increment the reference count */
++CsrThread->ReferenceCount;
}
/*++
* @name CsrLocateThreadByClientId
*
* The CsrLocateThreadByClientId routine locates the CSR Thread and,
* optionally, its parent CSR Process, corresponding to a Client ID.
*
* @param Process
* Optional pointer to a CSR Process pointer which will contain
* the CSR Thread's parent.
*
* @param ClientId
* Pointer to a Client ID structure containing the Unique Thread ID
* to look up.
*
* @return Pointer to the CSR Thread corresponding to this CID, or NULL if
* none was found.
*
* @remarks None.
*
*--*/
PCSR_THREAD
NTAPI
CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
IN PCLIENT_ID ClientId)
{
ULONG i;
PLIST_ENTRY ListHead, NextEntry;
PCSR_THREAD FoundThread;
// ASSERT(ProcessStructureListLocked());
/* Hash the Thread */
i = CsrHashThread(ClientId->UniqueThread);
/* Set the list pointers */
ListHead = &CsrThreadHashTable[i];
NextEntry = ListHead->Flink;
/* Star the loop */
while (NextEntry != ListHead)
{
/* Get the thread */
FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
/* Compare the CID */
if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
{
/* Match found, return the process */
*Process = FoundThread->Process;
/* Return thread too */
// DPRINT1("Found: %p %p\n", FoundThread, FoundThread->Process);
return FoundThread;
}
/* Next */
NextEntry = NextEntry->Flink;
}
/* Nothing found */
return NULL;
}
/*++
* @name CsrLocateThreadInProcess
*
* The CsrLocateThreadInProcess routine locates the CSR Thread
* corresponding to a Client ID inside a specific CSR Process.
*
* @param Process
* Optional pointer to the CSR Process which contains the CSR Thread
* that will be looked up.
*
* @param ClientId
* Pointer to a Client ID structure containing the Unique Thread ID
* to look up.
*
* @return Pointer to the CSR Thread corresponding to this CID, or NULL if
* none was found.
*
* @remarks If the CsrProcess argument is NULL, the lookup will be done inside
* CsrRootProcess.
*
*--*/
PCSR_THREAD
NTAPI
CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL,
IN PCLIENT_ID Cid)
{
PLIST_ENTRY ListHead, NextEntry;
PCSR_THREAD FoundThread = NULL;
/* Use the Root Process if none was specified */
if (!CsrProcess) CsrProcess = CsrRootProcess;
/* Save the List pointers */
// DPRINT1("Searching in: %p %d\n", CsrProcess, CsrProcess->ThreadCount);
ListHead = &CsrProcess->ThreadList;
NextEntry = ListHead->Flink;
/* Start the Loop */
while (NextEntry != ListHead)
{
/* Get Thread Entry */
FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
/* Check for TID Match */
if (FoundThread->ClientId.UniqueThread == Cid->UniqueThread) break;
/* Next entry */
NextEntry = NextEntry->Flink;
}
/* Return what we found */
// DPRINT1("Found: %p\n", FoundThread);
return FoundThread;
}
/*++
* @name CsrInsertThread
*
* The CsrInsertThread routine inserts a CSR Thread into its parent's
* Thread List and into the Thread Hash Table.
*
* @param Process
* Pointer to the CSR Process containing this CSR Thread.
*
* @param Thread
* Pointer to the CSR Thread to be inserted.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrInsertThread(IN PCSR_PROCESS Process,
IN PCSR_THREAD Thread)
{
ULONG i;
// ASSERT(ProcessStructureListLocked());
/* Insert it into the Regular List */
InsertTailList(&Process->ThreadList, &Thread->Link);
/* Increase Thread Count */
Process->ThreadCount++;
/* Hash the Thread */
i = CsrHashThread(Thread->ClientId.UniqueThread);
// DPRINT1("TID %lx HASH: %lx\n", Thread->ClientId.UniqueThread, i);
/* Insert it there too */
InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks);
}
/*++
* @name CsrDeallocateThread
*
* The CsrDeallocateThread frees the memory associated with a CSR Thread.
*
* @param CsrThread
* Pointer to the CSR Thread to be freed.
*
* @return None.
*
* @remarks Do not call this routine. It is reserved for the internal
* thread management routines when a CSR Thread has been cleanly
* dereferenced and killed.
*
*--*/
VOID
NTAPI
CsrDeallocateThread(IN PCSR_THREAD CsrThread)
{
/* Free the process object from the heap */
// ASSERT(CsrThread->WaitBlock == NULL);
RtlFreeHeap(CsrHeap, 0, CsrThread);
}
/*++
* @name CsrRemoveThread
*
* The CsrRemoveThread function undoes a CsrInsertThread operation and
* removes the CSR Thread from the the Hash Table and Thread List.
*
* @param CsrThread
* Pointer to the CSR Thread to remove.
*
* @return None.
*
* @remarks If this CSR Thread is the last one inside a CSR Process, the
* parent will be dereferenced and the CsrProcessLastThreadTerminated
* flag will be set.
*
* After executing this routine, the CSR Thread will have the
* CsrThreadInTermination flag set.
*
*--*/
VOID
NTAPI
CsrRemoveThread(IN PCSR_THREAD CsrThread)
{
ASSERT(ProcessStructureListLocked());
/* Remove it from the List */
RemoveEntryList(&CsrThread->Link);
/* Decreate the thread count of the process */
CsrThread->Process->ThreadCount--;
/* Remove it from the Hash List as well */
if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
/* Check if this is the last Thread */
if (!CsrThread->Process->ThreadCount)
{
/* Check if it's not already been marked for deletion */
if (!(CsrThread->Process->Flags & CsrProcessLastThreadTerminated))
{
/* Let everyone know this process is about to lose the thread */
CsrThread->Process->Flags |= CsrProcessLastThreadTerminated;
/* Reference the Process */
CsrLockedDereferenceProcess(CsrThread->Process);
}
}
/* Mark the thread for deletion */
CsrThread->Flags |= CsrThreadInTermination;
}
/*++
* @name CsrCreateRemoteThread
* @implemented NT4
*
* The CsrCreateRemoteThread routine creates a CSR Thread object for
* an NT Thread which is not part of the current NT Process.
*
* @param hThread
* Handle to an existing NT Thread to which to associate this
* CSR Thread.
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
* with this CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateRemoteThread(IN HANDLE hThread,
IN PCLIENT_ID ClientId)
{
NTSTATUS Status;
HANDLE ThreadHandle;
PCSR_THREAD CsrThread;
PCSR_PROCESS CsrProcess;
KERNEL_USER_TIMES KernelTimes;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Get the Thread Create Time */
Status = NtQueryInformationThread(hThread,
ThreadTimes,
&KernelTimes,
sizeof(KernelTimes),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to query thread times: %lx\n", Status);
return Status;
}
/* Lock the Owner Process */
Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("No known process for %lx\n", ClientId->UniqueProcess);
return Status;
}
/* Make sure the thread didn't terminate */
if (KernelTimes.ExitTime.QuadPart)
{
/* Unlock the process and return */
CsrUnlockProcess(CsrProcess);
DPRINT1("Dead thread: %I64x\n", KernelTimes.ExitTime.QuadPart);
return STATUS_THREAD_IS_TERMINATING;
}
/* Allocate a CSR Thread Structure */
CsrThread = CsrAllocateThread(CsrProcess);
if (!CsrThread)
{
DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
CsrUnlockProcess(CsrProcess);
return STATUS_NO_MEMORY;
}
/* Duplicate the Thread Handle */
Status = NtDuplicateObject(NtCurrentProcess(),
hThread,
NtCurrentProcess(),
&ThreadHandle,
0,
0,
DUPLICATE_SAME_ACCESS);
/* Allow failure */
if (!NT_SUCCESS(Status))
{
DPRINT1("Thread duplication failed: %lx\n", Status);
ThreadHandle = hThread;
}
/* Save the data we have */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = ThreadHandle;
ProtectHandle(ThreadHandle);
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
CsrInsertThread(CsrProcess, CsrThread);
/* Release the lock and return */
CsrUnlockProcess(CsrProcess);
return STATUS_SUCCESS;
}
/*++
* @name CsrThreadRefcountZero
*
* The CsrThreadRefcountZero routine is executed when a CSR Thread has lost
* all its active references. It removes and de-allocates the CSR Thread.
*
* @param CsrThread
* Pointer to the CSR Thread that is to be deleted.
*
* @return None.
*
* @remarks Do not call this routine. It is reserved for the internal
* thread management routines when a CSR Thread has lost all
* its references.
*
* This routine is called with the Process Lock held.
*
*--*/
VOID
NTAPI
CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
{
PCSR_PROCESS CsrProcess = CsrThread->Process;
NTSTATUS Status;
ASSERT(ProcessStructureListLocked());
/* Remove this thread */
CsrRemoveThread(CsrThread);
/* Release the Process Lock */
CsrReleaseProcessLock();
/* Close the NT Thread Handle */
if (CsrThread->ThreadHandle)
{
UnProtectHandle(CsrThread->ThreadHandle);
Status = NtClose(CsrThread->ThreadHandle);
ASSERT(NT_SUCCESS(Status));
}
/* De-allocate the CSR Thread Object */
CsrDeallocateThread(CsrThread);
/* Remove a reference from the process */
CsrDereferenceProcess(CsrProcess);
}
/*++
* @name CsrDestroyThread
* @implemented NT4
*
* The CsrDestroyThread routine destroys the CSR Thread corresponding to
* a given Thread ID.
*
* @param Cid
* Pointer to the Client ID Structure corresponding to the CSR
* Thread which is about to be destroyed.
*
* @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
* if the CSR Thread is already terminating.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrDestroyThread(IN PCLIENT_ID Cid)
{
CLIENT_ID ClientId = *Cid;
PCSR_THREAD CsrThread;
PCSR_PROCESS CsrProcess;
/* Acquire lock */
CsrAcquireProcessLock();
/* Find the thread */
CsrThread = CsrLocateThreadByClientId(&CsrProcess,
&ClientId);
/* Make sure we got one back, and that it's not already gone */
if (!CsrThread || CsrThread->Flags & CsrThreadTerminated)
{
/* Release the lock and return failure */
CsrReleaseProcessLock();
return STATUS_THREAD_IS_TERMINATING;
}
/* Set the terminated flag */
CsrThread->Flags |= CsrThreadTerminated;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Do we have an active wait block? */
if (CsrThread->WaitBlock)
{
/* Notify waiters of termination */
CsrNotifyWaitBlock(CsrThread->WaitBlock,
NULL,
NULL,
NULL,
CsrProcessTerminating,
TRUE);
}
/* Release the Wait Lock */
CsrReleaseWaitLock();
/* Dereference the thread */
CsrLockedDereferenceThread(CsrThread);
/* Release the Process Lock and return success */
CsrReleaseProcessLock();
return STATUS_SUCCESS;
}
/*++
* @name CsrLockedDereferenceThread
*
* The CsrLockedDereferenceThread dereferences a CSR Thread while the
* Process Lock is already being held.
*
* @param CsrThread
* Pointer to the CSR Thread to be dereferenced.
*
* @return None.
*
* @remarks This routine will return with the Process Lock held.
*
*--*/
VOID
NTAPI
CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
{
LONG LockCount;
/* Decrease reference count */
LockCount = --CsrThread->ReferenceCount;
ASSERT(LockCount >= 0);
if (!LockCount)
{
/* Call the generic cleanup code */
CsrThreadRefcountZero(CsrThread);
CsrAcquireProcessLock();
}
}
/*++
* @name CsrCreateThread
* @implemented NT4
*
* The CsrCreateThread routine creates a CSR Thread object for an NT Thread.
*
* @param CsrProcess
* Pointer to the CSR Process which will contain the CSR Thread.
*
* @param hThread
* Handle to an existing NT Thread to which to associate this
* CSR Thread.
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
* with this CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* otherwise.
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
CsrCreateThread(IN PCSR_PROCESS CsrProcess,
IN HANDLE hThread,
IN PCLIENT_ID ClientId)
{
PCSR_THREAD CsrThread;
PCSR_PROCESS CurrentProcess;
PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
CLIENT_ID CurrentCid;
KERNEL_USER_TIMES KernelTimes;
/* Get the current thread and CID */
CurrentCid = CurrentThread->ClientId;
/* Acquire the Process Lock */
CsrAcquireProcessLock();
/* Get the current Process and make sure the Thread is valid with this CID */
CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
&CurrentCid);
/* Something is wrong if we get an empty thread back */
if (!CurrentThread)
{
DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
CsrReleaseProcessLock();
return STATUS_THREAD_IS_TERMINATING;
}
/* Get the Thread Create Time */
NtQueryInformationThread(hThread,
ThreadTimes,
(PVOID)&KernelTimes,
sizeof(KernelTimes),
NULL);
/* Allocate a CSR Thread Structure */
if (!(CsrThread = CsrAllocateThread(CsrProcess)))
{
DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
CsrReleaseProcessLock();
return STATUS_NO_MEMORY;
}
/* Save the data we have */
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = hThread;
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
CsrInsertThread(CsrProcess, CsrThread);
/* Release the lock and return */
CsrReleaseProcessLock();
return STATUS_SUCCESS;
}
/*++
* @name CsrAddStaticServerThread
* @implemented NT4
*
* The CsrAddStaticServerThread routine adds a new CSR Thread to the
* CSR Server Process (CsrRootProcess).
*
* @param hThread
* Handle to an existing NT Thread to which to associate this
* CSR Thread.
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
* with this CSR Thread.
*
* @param ThreadFlags
* Initial CSR Thread Flags to associate to this CSR Thread. Usually
* CsrThreadIsServerThread.
*
* @return Pointer to the newly allocated CSR Thread.
*
* @remarks None.
*
*--*/
PCSR_THREAD
NTAPI
CsrAddStaticServerThread(IN HANDLE hThread,
IN PCLIENT_ID ClientId,
IN ULONG ThreadFlags)
{
PCSR_THREAD CsrThread;
/* Get the Lock */
CsrAcquireProcessLock();
/* Allocate the Server Thread */
CsrThread = CsrAllocateThread(CsrRootProcess);
if (CsrThread)
{
/* Setup the Object */
CsrThread->ThreadHandle = hThread;
ProtectHandle(hThread);
CsrThread->ClientId = *ClientId;
CsrThread->Flags = ThreadFlags;
/* Insert it into the Thread List */
InsertTailList(&CsrRootProcess->ThreadList, &CsrThread->Link);
/* Increment the thread count */
CsrRootProcess->ThreadCount++;
}
else
{
DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
}
/* Release the Process Lock and return */
CsrReleaseProcessLock();
return CsrThread;
}
/*++
* @name CsrDereferenceThread
* @implemented NT4
*
* The CsrDereferenceThread routine removes a reference from a CSR Thread.
*
* @param CsrThread
* Pointer to the CSR Thread to dereference.
*
* @return None.
*
* @remarks If the reference count has reached zero (ie: the CSR Thread has
* no more active references), it will be deleted.
*
*--*/
VOID
NTAPI
CsrDereferenceThread(IN PCSR_THREAD CsrThread)
{
/* Acquire process lock */
CsrAcquireProcessLock();
/* Decrease reference count */
ASSERT(CsrThread->ReferenceCount > 0);
if (!(--CsrThread->ReferenceCount))
{
/* Call the generic cleanup code */
CsrThreadRefcountZero(CsrThread);
}
else
{
/* Just release the lock */
CsrReleaseProcessLock();
}
}
/* EOF */
+449
View File
@@ -0,0 +1,449 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System
* FILE: subsystems/win32/csrss/csrsrv/wait.c
* PURPOSE: CSR Server DLL Wait Implementation
* PROGRAMMERS: Emanuele Aliberti
* Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include "srv.h"
#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
RTL_CRITICAL_SECTION CsrWaitListsLock;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
* @name CsrInitializeWait
*
* The CsrInitializeWait routine initializes a CSR Wait Object.
*
* @param WaitFunction
* Pointer to the function that will handle this wait.
*
* @param CsrWaitThread
* Pointer to the CSR Thread that will perform the wait.
*
* @param WaitApiMessage
* Pointer to the CSR API Message associated to this wait.
*
* @param WaitContext
* Pointer to a user-defined parameter associated to this wait.
*
* @param NewWaitBlock
* Pointed to the initialized CSR Wait Block for this wait.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
IN PCSR_THREAD CsrWaitThread,
IN OUT PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
OUT PCSR_WAIT_BLOCK *NewWaitBlock)
{
ULONG Size;
PCSR_WAIT_BLOCK WaitBlock;
/* Calculate the size of the wait block */
Size = sizeof(CSR_WAIT_BLOCK) -
sizeof(WaitBlock->WaitApiMessage) +
WaitApiMessage->Header.u1.s1.TotalLength;
/* Allocate the Wait Block */
WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
if (!WaitBlock)
{
/* Fail */
WaitApiMessage->Status = STATUS_NO_MEMORY;
return FALSE;
}
/* Initialize it */
WaitBlock->Size = Size;
WaitBlock->WaitThread = CsrWaitThread;
WaitBlock->WaitContext = WaitContext;
WaitBlock->WaitFunction = WaitFunction;
WaitBlock->UserWaitList.Flink = NULL;
WaitBlock->UserWaitList.Blink = NULL;
WaitBlock->WaitList = WaitBlock->UserWaitList;
/* Copy the message */
RtlMoveMemory(&WaitBlock->WaitApiMessage,
WaitApiMessage,
WaitApiMessage->Header.u1.s1.TotalLength);
/* Return the block */
*NewWaitBlock = WaitBlock;
return TRUE;
}
/*++
* @name CsrNotifyWaitBlock
*
* The CsrNotifyWaitBlock routine calls the wait function for a registered
* CSR Wait Block, and replies to the attached CSR API Message, if any.
*
* @param WaitBlock
* Pointer to the CSR Wait Block
*
* @param WaitList
* Pointer to the wait list for this wait.
*
* @param WaitArgument[1-2]
* User-defined values to pass to the wait function.
*
* @param WaitFlags
* Wait flags for this wait.
*
* @param DereferenceThread
* Specifies whether the CSR Thread should be dereferenced at the
* end of this wait.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks After a wait block is notified, the wait function becomes invalid.
*
*--*/
BOOLEAN
NTAPI
CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
IN PLIST_ENTRY WaitList,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2,
IN ULONG WaitFlags,
IN BOOLEAN DereferenceThread)
{
/* Call the wait function */
if ((WaitBlock->WaitFunction)(WaitList,
WaitBlock->WaitThread,
&WaitBlock->WaitApiMessage,
WaitBlock->WaitContext,
WaitArgument1,
WaitArgument2,
WaitFlags))
{
/* The wait is done, clear the block */
WaitBlock->WaitThread->WaitBlock = NULL;
/* Check for captured arguments */
if (WaitBlock->WaitApiMessage.CsrCaptureData)
{
/* Release them */
CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
}
/* Reply to the port */
NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
(PPORT_MESSAGE)&WaitBlock->WaitApiMessage);
/* Check if we should dereference the thread */
if (DereferenceThread)
{
/* Remove it from the Wait List */
if (WaitBlock->WaitList.Flink)
{
RemoveEntryList(&WaitBlock->WaitList);
}
/* Remove it from the User Wait List */
if (WaitBlock->UserWaitList.Flink)
{
RemoveEntryList(&WaitBlock->UserWaitList);
}
/* Dereference teh thread */
CsrDereferenceThread(WaitBlock->WaitThread);
/* Free the wait block */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
}
else
{
/* The wait is complete, but the thread is being kept alive */
WaitBlock->WaitFunction = NULL;
}
/* The wait suceeded */
return TRUE;
}
/* The wait failed */
return FALSE;
}
/* PUBLIC FUNCTIONS **********************************************************/
/*++
* @name CsrCreateWait
* @implemented NT4
*
* The CsrCreateWait routine creates a CSR Wait.
*
* @param WaitList
* Pointer to a list entry of the waits to associate.
*
* @param WaitFunction
* Pointer to the function that will handle this wait.
*
* @param CsrWaitThread
* Pointer to the CSR Thread that will perform the wait.
*
* @param WaitApiMessage
* Pointer to the CSR API Message associated to this wait.
*
* @param WaitContext
* Pointer to a user-defined parameter associated to this wait.
*
* @param UserWaitList
* Pointer to a list entry of the user-defined waits to associate.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrCreateWait(IN PLIST_ENTRY WaitList,
IN CSR_WAIT_FUNCTION WaitFunction,
IN PCSR_THREAD CsrWaitThread,
IN OUT PCSR_API_MESSAGE WaitApiMessage,
IN PVOID WaitContext,
IN PLIST_ENTRY UserWaitList OPTIONAL)
{
PCSR_WAIT_BLOCK WaitBlock;
/* Initialize the wait */
if (!CsrInitializeWait(WaitFunction,
CsrWaitThread,
WaitApiMessage,
WaitContext,
&WaitBlock))
{
return FALSE;
}
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Make sure the thread wasn't destroyed */
if (CsrWaitThread->Flags & CsrThreadTerminated)
{
/* Fail the wait */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
CsrReleaseWaitLock();
return FALSE;
}
/* Insert the wait in the queue */
InsertTailList(WaitList, &WaitBlock->WaitList);
/* Insert the User Wait too, if one was given */
if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);
/* Return */
CsrReleaseWaitLock();
return TRUE;
}
/*++
* @name CsrDereferenceWait
* @implemented NT4
*
* The CsrDereferenceWait routine dereferences a CSR Wait Block.
*
* @param WaitList
* Pointer to the Wait List associated to the wait.
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrDereferenceWait(IN PLIST_ENTRY WaitList)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Process and Wait Locks */
CsrAcquireProcessLock();
CsrAcquireWaitLock();
/* Set the list pointers */
NextEntry = WaitList->Flink;
/* Start the loop */
while (NextEntry != WaitList)
{
/* Get the wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Move to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there's no Wait Routine */
if (!WaitBlock->WaitFunction)
{
/* Remove it from the Wait List */
if (WaitBlock->WaitList.Flink)
{
RemoveEntryList(&WaitBlock->WaitList);
}
/* Remove it from the User Wait List */
if (WaitBlock->UserWaitList.Flink)
{
RemoveEntryList(&WaitBlock->UserWaitList);
}
/* Dereference the thread waiting on it */
CsrDereferenceThread(WaitBlock->WaitThread);
/* Free the block */
RtlFreeHeap(CsrHeap, 0, WaitBlock);
}
}
/* Release the locks */
CsrReleaseWaitLock();
CsrReleaseProcessLock();
}
/*++
* @name CsrMoveSatisfiedWait
* @implemented NT5
*
* The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
* to another list entry.
*
* @param NewEntry
* Pointer to a list entry where the satisfied waits will be added.
*
* @param WaitList
* Pointer to a list entry to analyze for satisfied waits.
*
* @return None.
*
* @remarks None.
*
*--*/
VOID
NTAPI
CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
IN PLIST_ENTRY WaitList)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Set the List pointers */
NextEntry = WaitList->Flink;
/* Start looping */
while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Go to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there is a Wait Callback */
if (WaitBlock->WaitFunction)
{
/* Remove it from the Wait Block Queue */
RemoveEntryList(&WaitBlock->WaitList);
/* Insert the new entry */
InsertTailList(&WaitBlock->WaitList, NewEntry);
}
}
/* Release the wait lock */
CsrReleaseWaitLock();
}
/*++
* @name CsrNotifyWait
* @implemented NT4
*
* The CsrNotifyWait notifies a CSR Wait Block.
*
* @param WaitList
* Pointer to the list entry for this wait.
*
* @param WaitType
* Type of the wait to perform, either WaitAny or WaitAll.
*
* @param WaitArgument[1-2]
* User-defined argument to pass on to the wait function.
*
* @return TRUE in case of success, FALSE otherwise.
*
* @remarks None.
*
*--*/
BOOLEAN
NTAPI
CsrNotifyWait(IN PLIST_ENTRY WaitList,
IN ULONG WaitType,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2)
{
PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
BOOLEAN NotifySuccess = FALSE;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Set the List pointers */
NextEntry = WaitList->Flink;
/* Start looping */
while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
/* Go to the next entry */
NextEntry = NextEntry->Flink;
/* Check if there is a Wait Callback */
if (WaitBlock->WaitFunction)
{
/* Notify the Waiter */
NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
WaitList,
WaitArgument1,
WaitArgument2,
0,
FALSE);
/* We've already done a wait, so leave unless this is a Wait All */
if (WaitType != WaitAll) break;
}
}
/* Release the wait lock and return */
CsrReleaseWaitLock();
return NotifySuccess;
}
/* EOF */
@@ -0,0 +1,36 @@
include_directories(
BEFORE .
${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include
${REACTOS_SOURCE_DIR}/include/reactos/subsys
${REACTOS_SOURCE_DIR}/include/reactos/drivers
${REACTOS_SOURCE_DIR}/dll/cpl/console
${REACTOS_SOURCE_DIR}/win32ss/include)
spec2def(win32csr.dll win32csr.spec)
list(APPEND SOURCE
alias.c
coninput.c
conoutput.c
console.c
desktopbg.c
dllmain.c
exitros.c
file.c
guiconsole.c
handle.c
harderror.c
lineinput.c
tuiconsole.c
win32csr.rc
${CMAKE_CURRENT_BINARY_DIR}/win32csr.def)
add_library(win32csr SHARED ${SOURCE})
target_link_libraries(win32csr win32ksys ${PSEH_LIB})
set_module_type(win32csr win32dll)
add_importlibs(win32csr psapi msvcrt kernel32 ntdll csrsrv)
add_delay_importlibs(win32csr user32 gdi32 advapi32)
add_pch(win32csr w32csr.h)
add_dependencies(win32csr bugcodes)
add_cd_file(TARGET win32csr DESTINATION reactos/system32 FOR all)
+552
View File
@@ -0,0 +1,552 @@
/*
* PROJECT: ReactOS CSRSS
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/csrss/api/alias.c
* PURPOSE: CSRSS alias support functions
* COPYRIGHT: Christoph Wittich
* Johannes Anderwald
*
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
typedef struct tagALIAS_ENTRY
{
LPCWSTR lpSource;
LPCWSTR lpTarget;
struct tagALIAS_ENTRY * Next;
} ALIAS_ENTRY, *PALIAS_ENTRY;
typedef struct tagALIAS_HEADER
{
LPCWSTR lpExeName;
PALIAS_ENTRY Data;
struct tagALIAS_HEADER * Next;
} ALIAS_HEADER, *PALIAS_HEADER;
static
PALIAS_HEADER
IntFindAliasHeader(PALIAS_HEADER RootHeader, LPCWSTR lpExeName)
{
while(RootHeader)
{
INT diff = _wcsicmp(RootHeader->lpExeName, lpExeName);
if (!diff)
return RootHeader;
if (diff > 0)
break;
RootHeader = RootHeader->Next;
}
return NULL;
}
PALIAS_HEADER
IntCreateAliasHeader(LPCWSTR lpExeName)
{
PALIAS_HEADER Entry;
UINT dwLength = wcslen(lpExeName) + 1;
Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_HEADER) + sizeof(WCHAR) * dwLength);
if (!Entry)
return Entry;
Entry->lpExeName = (LPCWSTR)(Entry + 1);
wcscpy((WCHAR*)Entry->lpExeName, lpExeName);
Entry->Data = NULL;
Entry->Next = NULL;
return Entry;
}
VOID
IntInsertAliasHeader(PALIAS_HEADER * RootHeader, PALIAS_HEADER NewHeader)
{
PALIAS_HEADER CurrentHeader;
PALIAS_HEADER *LastLink = RootHeader;
while ((CurrentHeader = *LastLink) != NULL)
{
INT Diff = _wcsicmp(NewHeader->lpExeName, CurrentHeader->lpExeName);
if (Diff < 0)
{
break;
}
LastLink = &CurrentHeader->Next;
}
*LastLink = NewHeader;
NewHeader->Next = CurrentHeader;
}
PALIAS_ENTRY
IntGetAliasEntry(PALIAS_HEADER Header, LPCWSTR lpSrcName)
{
PALIAS_ENTRY RootHeader;
if (Header == NULL)
return NULL;
RootHeader = Header->Data;
while(RootHeader)
{
INT diff;
DPRINT("IntGetAliasEntry>lpSource %S\n", RootHeader->lpSource);
diff = _wcsicmp(RootHeader->lpSource, lpSrcName);
if (!diff)
return RootHeader;
if (diff > 0)
break;
RootHeader = RootHeader->Next;
}
return NULL;
}
VOID
IntInsertAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY NewEntry)
{
PALIAS_ENTRY CurrentEntry;
PALIAS_ENTRY *LastLink = &Header->Data;
while ((CurrentEntry = *LastLink) != NULL)
{
INT Diff = _wcsicmp(NewEntry->lpSource, CurrentEntry->lpSource);
if (Diff < 0)
{
break;
}
LastLink = &CurrentEntry->Next;
}
*LastLink = NewEntry;
NewEntry->Next = CurrentEntry;
}
PALIAS_ENTRY
IntCreateAliasEntry(LPCWSTR lpSource, LPCWSTR lpTarget)
{
UINT dwSource;
UINT dwTarget;
PALIAS_ENTRY Entry;
dwSource = wcslen(lpSource) + 1;
dwTarget = wcslen(lpTarget) + 1;
Entry = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ALIAS_ENTRY) + sizeof(WCHAR) * (dwSource + dwTarget));
if (!Entry)
return Entry;
Entry->lpSource = (LPCWSTR)(Entry + 1);
wcscpy((LPWSTR)Entry->lpSource, lpSource);
Entry->lpTarget = Entry->lpSource + dwSource;
wcscpy((LPWSTR)Entry->lpTarget, lpTarget);
Entry->Next = NULL;
return Entry;
}
UINT
IntGetConsoleAliasesExesLength(PALIAS_HEADER RootHeader)
{
UINT length = 0;
while(RootHeader)
{
length += (wcslen(RootHeader->lpExeName) + 1) * sizeof(WCHAR);
RootHeader = RootHeader->Next;
}
if (length)
length += sizeof(WCHAR); // last entry entry is terminated with 2 zero bytes
return length;
}
UINT
IntGetConsoleAliasesExes(PALIAS_HEADER RootHeader, LPWSTR TargetBuffer, UINT TargetBufferSize)
{
UINT Offset = 0;
UINT Length;
TargetBufferSize /= sizeof(WCHAR);
while(RootHeader)
{
Length = wcslen(RootHeader->lpExeName) + 1;
if (TargetBufferSize > Offset + Length)
{
wcscpy(&TargetBuffer[Offset], RootHeader->lpExeName);
Offset += Length;
}
else
{
break;
}
RootHeader = RootHeader->Next;
}
Length = min(Offset+1, TargetBufferSize);
TargetBuffer[Length] = L'\0';
return Length * sizeof(WCHAR);
}
UINT
IntGetAllConsoleAliasesLength(PALIAS_HEADER Header)
{
UINT Length = 0;
PALIAS_ENTRY CurEntry = Header->Data;
while(CurEntry)
{
Length += wcslen(CurEntry->lpSource);
Length += wcslen(CurEntry->lpTarget);
Length += 2; // zero byte and '='
CurEntry = CurEntry->Next;
}
if (Length)
{
return (Length+1) * sizeof(WCHAR);
}
return 0;
}
UINT
IntGetAllConsoleAliases(PALIAS_HEADER Header, LPWSTR TargetBuffer, UINT TargetBufferLength)
{
PALIAS_ENTRY CurEntry = Header->Data;
UINT Offset = 0;
UINT SrcLength, TargetLength;
TargetBufferLength /= sizeof(WCHAR);
while(CurEntry)
{
SrcLength = wcslen(CurEntry->lpSource) + 1;
TargetLength = wcslen(CurEntry->lpTarget) + 1;
if (Offset + TargetLength + SrcLength >= TargetBufferLength)
break;
wcscpy(&TargetBuffer[Offset], CurEntry->lpSource);
Offset += SrcLength;
TargetBuffer[Offset] = L'=';
wcscpy(&TargetBuffer[Offset], CurEntry->lpTarget);
Offset += TargetLength;
CurEntry = CurEntry->Next;
}
TargetBuffer[Offset] = L'\0';
return Offset * sizeof(WCHAR);
}
VOID
IntDeleteAliasEntry(PALIAS_HEADER Header, PALIAS_ENTRY Entry)
{
PALIAS_ENTRY *LastLink = &Header->Data;
PALIAS_ENTRY CurEntry;
while ((CurEntry = *LastLink) != NULL)
{
if (CurEntry == Entry)
{
*LastLink = Entry->Next;
RtlFreeHeap(Win32CsrApiHeap, 0, Entry);
return;
}
LastLink = &CurEntry->Next;
}
}
VOID
IntDeleteAllAliases(PALIAS_HEADER RootHeader)
{
PALIAS_HEADER Header, NextHeader;
PALIAS_ENTRY Entry, NextEntry;
for (Header = RootHeader; Header; Header = NextHeader)
{
NextHeader = Header->Next;
for (Entry = Header->Data; Entry; Entry = NextEntry)
{
NextEntry = Entry->Next;
RtlFreeHeap(Win32CsrApiHeap, 0, Entry);
}
RtlFreeHeap(Win32CsrApiHeap, 0, Header);
}
}
CSR_API(CsrAddConsoleAlias)
{
PCSRSS_CONSOLE Console;
PALIAS_HEADER Header;
PALIAS_ENTRY Entry;
WCHAR * lpExeName;
WCHAR * lpSource;
WCHAR * lpTarget;
//ULONG TotalLength;
//WCHAR * Ptr;
//TotalLength = Request->Data.AddConsoleAlias.SourceLength + Request->Data.AddConsoleAlias.ExeLength + Request->Data.AddConsoleAlias.TargetLength;
//Ptr = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
lpSource = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
lpExeName = (WCHAR*)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE) + Request->Data.AddConsoleAlias.SourceLength * sizeof(WCHAR));
lpTarget = (Request->Data.AddConsoleAlias.TargetLength != 0 ? lpExeName + Request->Data.AddConsoleAlias.ExeLength : NULL);
DPRINT("CsrAddConsoleAlias entered Request %p lpSource %p lpExeName %p lpTarget %p\n", Request, lpSource, lpExeName, lpTarget);
if (lpExeName == NULL || lpSource == NULL)
{
return STATUS_INVALID_PARAMETER;
}
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (!NT_SUCCESS(Request->Status))
{
return Request->Status;
}
Header = IntFindAliasHeader(Console->Aliases, lpExeName);
if (!Header && lpTarget != NULL)
{
Header = IntCreateAliasHeader(lpExeName);
if (!Header)
{
ConioUnlockConsole(Console);
return STATUS_INSUFFICIENT_RESOURCES;
}
IntInsertAliasHeader(&Console->Aliases, Header);
}
if (lpTarget == NULL) // delete the entry
{
Entry = IntGetAliasEntry(Header, lpSource);
if (Entry)
{
IntDeleteAliasEntry(Header, Entry);
Request->Status = STATUS_SUCCESS;
}
else
{
Request->Status = STATUS_INVALID_PARAMETER;
}
ConioUnlockConsole(Console);
return Request->Status;
}
Entry = IntCreateAliasEntry(lpSource, lpTarget);
if (!Entry)
{
ConioUnlockConsole(Console);
return STATUS_INSUFFICIENT_RESOURCES;
}
IntInsertAliasEntry(Header, Entry);
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetConsoleAlias)
{
PCSRSS_CONSOLE Console;
PALIAS_HEADER Header;
PALIAS_ENTRY Entry;
UINT Length;
WCHAR * lpExeName;
WCHAR * lpSource;
WCHAR * lpTarget;
lpSource = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
lpExeName = lpSource + Request->Data.GetConsoleAlias.SourceLength;
lpTarget = Request->Data.GetConsoleAlias.TargetBuffer;
DPRINT("CsrGetConsoleAlias entered lpExeName %p lpSource %p TargetBuffer %p TargetBufferLength %u\n",
lpExeName, lpSource, lpTarget, Request->Data.GetConsoleAlias.TargetBufferLength);
if (Request->Data.GetConsoleAlias.ExeLength == 0 || lpTarget == NULL ||
Request->Data.GetConsoleAlias.TargetBufferLength == 0 || Request->Data.GetConsoleAlias.SourceLength == 0)
{
return STATUS_INVALID_PARAMETER;
}
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (!NT_SUCCESS(Request->Status))
{
return Request->Status;
}
Header = IntFindAliasHeader(Console->Aliases, lpExeName);
if (!Header)
{
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
Entry = IntGetAliasEntry(Header, lpSource);
if (!Entry)
{
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
Length = (wcslen(Entry->lpTarget)+1) * sizeof(WCHAR);
if (Length > Request->Data.GetConsoleAlias.TargetBufferLength)
{
ConioUnlockConsole(Console);
return STATUS_BUFFER_TOO_SMALL;
}
if (!Win32CsrValidateBuffer(ProcessData, lpTarget,
Request->Data.GetConsoleAlias.TargetBufferLength, 1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
wcscpy(lpTarget, Entry->lpTarget);
Request->Data.GetConsoleAlias.BytesWritten = Length;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetAllConsoleAliases)
{
PCSRSS_CONSOLE Console;
ULONG BytesWritten;
PALIAS_HEADER Header;
if (Request->Data.GetAllConsoleAlias.lpExeName == NULL)
{
return STATUS_INVALID_PARAMETER;
}
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (!NT_SUCCESS(Request->Status))
{
return Request->Status;
}
Header = IntFindAliasHeader(Console->Aliases, Request->Data.GetAllConsoleAlias.lpExeName);
if (!Header)
{
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
if (IntGetAllConsoleAliasesLength(Header) > Request->Data.GetAllConsoleAlias.AliasBufferLength)
{
ConioUnlockConsole(Console);
return STATUS_BUFFER_OVERFLOW;
}
if (!Win32CsrValidateBuffer(ProcessData,
Request->Data.GetAllConsoleAlias.AliasBuffer,
Request->Data.GetAllConsoleAlias.AliasBufferLength,
1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
BytesWritten = IntGetAllConsoleAliases(Header,
Request->Data.GetAllConsoleAlias.AliasBuffer,
Request->Data.GetAllConsoleAlias.AliasBufferLength);
Request->Data.GetAllConsoleAlias.BytesWritten = BytesWritten;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetAllConsoleAliasesLength)
{
PCSRSS_CONSOLE Console;
PALIAS_HEADER Header;
UINT Length;
if (Request->Data.GetAllConsoleAliasesLength.lpExeName == NULL)
{
return STATUS_INVALID_PARAMETER;
}
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (!NT_SUCCESS(Request->Status))
{
return Request->Status;
}
Header = IntFindAliasHeader(Console->Aliases, Request->Data.GetAllConsoleAliasesLength.lpExeName);
if (!Header)
{
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
Length = IntGetAllConsoleAliasesLength(Header);
Request->Data.GetAllConsoleAliasesLength.Length = Length;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetConsoleAliasesExes)
{
PCSRSS_CONSOLE Console;
UINT BytesWritten;
UINT ExesLength;
DPRINT("CsrGetConsoleAliasesExes entered\n");
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (!NT_SUCCESS(Request->Status))
{
return Request->Status;
}
ExesLength = IntGetConsoleAliasesExesLength(Console->Aliases);
if (ExesLength > Request->Data.GetConsoleAliasesExes.Length)
{
ConioUnlockConsole(Console);
return STATUS_BUFFER_OVERFLOW;
}
if (Request->Data.GetConsoleAliasesExes.ExeNames == NULL)
{
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
if (!Win32CsrValidateBuffer(ProcessData,
Request->Data.GetConsoleAliasesExes.ExeNames,
Request->Data.GetConsoleAliasesExes.Length,
1))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
BytesWritten = IntGetConsoleAliasesExes(Console->Aliases,
Request->Data.GetConsoleAliasesExes.ExeNames,
Request->Data.GetConsoleAliasesExes.Length);
Request->Data.GetConsoleAliasesExes.BytesWritten = BytesWritten;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetConsoleAliasesExesLength)
{
PCSRSS_CONSOLE Console;
DPRINT("CsrGetConsoleAliasesExesLength entered\n");
Request->Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Request->Status))
{
Request->Data.GetConsoleAliasesExesLength.Length = IntGetConsoleAliasesExesLength(Console->Aliases);
ConioUnlockConsole(Console);
}
return Request->Status;
}
+651
View File
@@ -0,0 +1,651 @@
/*
* reactos/subsys/csrss/win32csr/conio.c
*
* Console I/O functions
*
* ReactOS Operating System
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
/* GLOBALS *******************************************************************/
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
WideCharToMultiByte((Console)->CodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->CodePage, 0, (sChar), 1, (dWChar), 1)
/* FUNCTIONS *****************************************************************/
CSR_API(CsrReadConsole)
{
PLIST_ENTRY CurrentEntry;
ConsoleInput *Input;
PCHAR Buffer;
PWCHAR UnicodeBuffer;
ULONG i = 0;
ULONG nNumberOfCharsToRead, CharSize;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrReadConsole\n");
CharSize = (Request->Data.ReadConsoleRequest.Unicode ? sizeof(WCHAR) : sizeof(CHAR));
nNumberOfCharsToRead = Request->Data.ReadConsoleRequest.NrCharactersToRead;
Buffer = (PCHAR)Request->Data.ReadConsoleRequest.Buffer;
UnicodeBuffer = (PWCHAR)Buffer;
if (!Win32CsrValidateBuffer(ProcessData, Buffer, nNumberOfCharsToRead, CharSize))
return STATUS_ACCESS_VIOLATION;
if (Request->Data.ReadConsoleRequest.NrCharactersRead * sizeof(WCHAR) > nNumberOfCharsToRead * CharSize)
return STATUS_INVALID_PARAMETER;
Status = ConioLockConsole(ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle,
&Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Status;
}
Request->Data.ReadConsoleRequest.EventHandle = ProcessData->ConsoleEvent;
Status = STATUS_PENDING; /* we haven't read anything (yet) */
if (Console->Mode & ENABLE_LINE_INPUT)
{
if (Console->LineBuffer == NULL)
{
/* Starting a new line */
Console->LineMaxSize = max(256, nNumberOfCharsToRead);
Console->LineBuffer = HeapAlloc(Win32CsrApiHeap, 0, Console->LineMaxSize * sizeof(WCHAR));
if (Console->LineBuffer == NULL)
{
Status = STATUS_NO_MEMORY;
goto done;
}
Console->LineComplete = FALSE;
Console->LineUpPressed = FALSE;
Console->LineInsertToggle = 0;
Console->LineWakeupMask = Request->Data.ReadConsoleRequest.CtrlWakeupMask;
Console->LineSize = Request->Data.ReadConsoleRequest.NrCharactersRead;
Console->LinePos = Console->LineSize;
/* pre-filling the buffer is only allowed in the Unicode API,
* so we don't need to worry about conversion */
memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
if (Console->LineSize == Console->LineMaxSize)
{
Console->LineComplete = TRUE;
Console->LinePos = 0;
}
}
/* If we don't have a complete line yet, process the pending input */
while (!Console->LineComplete && !IsListEmpty(&Console->InputEvents))
{
/* remove input event from queue */
CurrentEntry = RemoveHeadList(&Console->InputEvents);
if (IsListEmpty(&Console->InputEvents))
{
ResetEvent(Console->ActiveEvent);
}
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
/* only pay attention to key down */
if (KEY_EVENT == Input->InputEvent.EventType
&& Input->InputEvent.Event.KeyEvent.bKeyDown)
{
LineInputKeyDown(Console, &Input->InputEvent.Event.KeyEvent);
Request->Data.ReadConsoleRequest.ControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
}
HeapFree(Win32CsrApiHeap, 0, Input);
}
/* Check if we have a complete line to read from */
if (Console->LineComplete)
{
while (i < nNumberOfCharsToRead && Console->LinePos != Console->LineSize)
{
WCHAR Char = Console->LineBuffer[Console->LinePos++];
if (Request->Data.ReadConsoleRequest.Unicode)
UnicodeBuffer[i++] = Char;
else
ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
}
if (Console->LinePos == Console->LineSize)
{
/* Entire line has been read */
HeapFree(Win32CsrApiHeap, 0, Console->LineBuffer);
Console->LineBuffer = NULL;
}
Status = STATUS_SUCCESS;
}
}
else
{
/* Character input */
while (i < nNumberOfCharsToRead && !IsListEmpty(&Console->InputEvents))
{
/* remove input event from queue */
CurrentEntry = RemoveHeadList(&Console->InputEvents);
if (IsListEmpty(&Console->InputEvents))
{
ResetEvent(Console->ActiveEvent);
}
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
/* only pay attention to valid ascii chars, on key down */
if (KEY_EVENT == Input->InputEvent.EventType
&& Input->InputEvent.Event.KeyEvent.bKeyDown
&& Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
{
WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
if (Request->Data.ReadConsoleRequest.Unicode)
UnicodeBuffer[i++] = Char;
else
ConsoleInputUnicodeCharToAnsiChar(Console, &Buffer[i++], &Char);
Status = STATUS_SUCCESS; /* did read something */
}
HeapFree(Win32CsrApiHeap, 0, Input);
}
}
done:
Request->Data.ReadConsoleRequest.NrCharactersRead = i;
ConioUnlockConsole(Console);
return Status;
}
static VOID FASTCALL
ConioInputEventToAnsi(PCSRSS_CONSOLE Console, PINPUT_RECORD InputEvent)
{
if (InputEvent->EventType == KEY_EVENT)
{
WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
ConsoleInputUnicodeCharToAnsiChar(Console,
&InputEvent->Event.KeyEvent.uChar.AsciiChar,
&UnicodeChar);
}
}
static NTSTATUS FASTCALL
ConioProcessChar(PCSRSS_CONSOLE Console,
PINPUT_RECORD InputEvent)
{
ConsoleInput *ConInRec;
/* Check for pause or unpause */
if (InputEvent->EventType == KEY_EVENT && InputEvent->Event.KeyEvent.bKeyDown)
{
WORD vk = InputEvent->Event.KeyEvent.wVirtualKeyCode;
if (!(Console->PauseFlags & PAUSED_FROM_KEYBOARD))
{
DWORD cks = InputEvent->Event.KeyEvent.dwControlKeyState;
if (Console->Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
else
{
if ((vk < VK_SHIFT || vk > VK_CAPITAL) && vk != VK_LWIN &&
vk != VK_RWIN && vk != VK_NUMLOCK && vk != VK_SCROLL)
{
ConioUnpause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
}
}
}
/* add event to the queue */
ConInRec = RtlAllocateHeap(Win32CsrApiHeap, 0, sizeof(ConsoleInput));
if (ConInRec == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
ConInRec->InputEvent = *InputEvent;
InsertTailList(&Console->InputEvents, &ConInRec->ListEntry);
SetEvent(Console->ActiveEvent);
return STATUS_SUCCESS;
}
static DWORD FASTCALL
ConioGetShiftState(PBYTE KeyState)
{
DWORD ssOut = 0;
if (KeyState[VK_CAPITAL] & 1)
ssOut |= CAPSLOCK_ON;
if (KeyState[VK_NUMLOCK] & 1)
ssOut |= NUMLOCK_ON;
if (KeyState[VK_SCROLL] & 1)
ssOut |= SCROLLLOCK_ON;
if (KeyState[VK_SHIFT] & 0x80)
ssOut |= SHIFT_PRESSED;
if (KeyState[VK_LCONTROL] & 0x80)
ssOut |= LEFT_CTRL_PRESSED;
if (KeyState[VK_RCONTROL] & 0x80)
ssOut |= RIGHT_CTRL_PRESSED;
if (KeyState[VK_LMENU] & 0x80)
ssOut |= LEFT_ALT_PRESSED;
if (KeyState[VK_RMENU] & 0x80)
ssOut |= RIGHT_ALT_PRESSED;
return ssOut;
}
VOID WINAPI
ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
{
static BYTE KeyState[256] = { 0 };
/* MSDN mentions that you should use the last virtual key code received
* when putting a virtual key identity to a WM_CHAR message since multiple
* or translated keys may be involved. */
static UINT LastVirtualKey = 0;
DWORD ShiftState;
UINT RepeatCount;
WCHAR UnicodeChar;
UINT VirtualKeyCode;
UINT VirtualScanCode;
BOOL Down = FALSE;
INPUT_RECORD er;
BOOLEAN Fake; // synthesized, not a real event
BOOLEAN NotChar; // message should not be used to return a character
RepeatCount = 1;
VirtualScanCode = (msg->lParam >> 16) & 0xff;
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
GetKeyboardState(KeyState);
ShiftState = ConioGetShiftState(KeyState);
if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
{
VirtualKeyCode = LastVirtualKey;
UnicodeChar = msg->wParam;
}
else
{
WCHAR Chars[2];
INT RetChars = 0;
VirtualKeyCode = msg->wParam;
RetChars = ToUnicodeEx(VirtualKeyCode,
VirtualScanCode,
KeyState,
Chars,
2,
0,
0);
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = RepeatCount;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
if (TextMode)
{
if (0 != (ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
&& VK_TAB == VirtualKeyCode)
{
if (Down)
{
TuiSwapConsole(ShiftState & SHIFT_PRESSED ? -1 : 1);
}
return;
}
else if (VK_MENU == VirtualKeyCode && ! Down)
{
if (TuiSwapConsole(0))
{
return;
}
}
}
else
{
if ((ShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED) || KeyState[VK_MENU] & 0x80) &&
(VirtualKeyCode == VK_ESCAPE || VirtualKeyCode == VK_TAB || VirtualKeyCode == VK_SPACE))
{
DefWindowProcW( msg->hwnd, msg->message, msg->wParam, msg->lParam);
return;
}
}
if (NULL == Console)
{
DPRINT1("No Active Console!\n");
return;
}
Fake = UnicodeChar &&
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
if (NotChar)
LastVirtualKey = msg->wParam;
DPRINT ("csrss: %s %s %s %s %02x %02x '%lc' %04x\n",
Down ? "down" : "up ",
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
"char" : "key ",
Fake ? "fake" : "real",
NotChar ? "notc" : "char",
VirtualScanCode,
VirtualKeyCode,
(UnicodeChar >= L' ') ? UnicodeChar : L'.',
ShiftState);
if (Fake)
return;
/* process Ctrl-C and Ctrl-Break */
if (Console->Mode & ENABLE_PROCESSED_INPUT &&
er.Event.KeyEvent.bKeyDown &&
((er.Event.KeyEvent.wVirtualKeyCode == VK_PAUSE) ||
(er.Event.KeyEvent.wVirtualKeyCode == 'C')) &&
(er.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80))
{
PCSR_PROCESS current;
PLIST_ENTRY current_entry;
DPRINT1("Console_Api Ctrl-C\n");
current_entry = Console->ProcessList.Flink;
while (current_entry != &Console->ProcessList)
{
current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
current_entry = current_entry->Flink;
ConioConsoleCtrlEvent((DWORD)CTRL_C_EVENT, current);
}
if (Console->LineBuffer && !Console->LineComplete)
{
/* Line input is in progress; end it */
Console->LinePos = Console->LineSize = 0;
Console->LineComplete = TRUE;
}
return;
}
if (0 != (er.Event.KeyEvent.dwControlKeyState
& (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
&& (VK_UP == er.Event.KeyEvent.wVirtualKeyCode
|| VK_DOWN == er.Event.KeyEvent.wVirtualKeyCode))
{
if (er.Event.KeyEvent.bKeyDown)
{
/* scroll up or down */
if (VK_UP == er.Event.KeyEvent.wVirtualKeyCode)
{
/* only scroll up if there is room to scroll up into */
if (Console->ActiveBuffer->CurrentY != Console->ActiveBuffer->MaxY - 1)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY +
Console->ActiveBuffer->MaxY - 1) %
Console->ActiveBuffer->MaxY;
Console->ActiveBuffer->CurrentY++;
}
}
else
{
/* only scroll down if there is room to scroll down into */
if (Console->ActiveBuffer->CurrentY != 0)
{
Console->ActiveBuffer->VirtualY = (Console->ActiveBuffer->VirtualY + 1) %
Console->ActiveBuffer->MaxY;
Console->ActiveBuffer->CurrentY--;
}
}
ConioDrawConsole(Console);
}
return;
}
ConioProcessChar(Console, &er);
}
CSR_API(CsrReadInputEvent)
{
PLIST_ENTRY CurrentEntry;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
BOOLEAN Done = FALSE;
ConsoleInput *Input;
DPRINT("CsrReadInputEvent\n");
Request->Data.ReadInputRequest.Event = ProcessData->ConsoleEvent;
Status = ConioLockConsole(ProcessData, Request->Data.ReadInputRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Status;
}
/* only get input if there is any */
CurrentEntry = Console->InputEvents.Flink;
while (CurrentEntry != &Console->InputEvents)
{
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
CurrentEntry = CurrentEntry->Flink;
if (Done)
{
Request->Data.ReadInputRequest.MoreEvents = TRUE;
break;
}
RemoveEntryList(&Input->ListEntry);
if (!Done)
{
Request->Data.ReadInputRequest.Input = Input->InputEvent;
if (Request->Data.ReadInputRequest.Unicode == FALSE)
{
ConioInputEventToAnsi(Console, &Request->Data.ReadInputRequest.Input);
}
Done = TRUE;
}
HeapFree(Win32CsrApiHeap, 0, Input);
}
if (Done)
Status = STATUS_SUCCESS;
else
Status = STATUS_PENDING;
if (IsListEmpty(&Console->InputEvents))
{
ResetEvent(Console->ActiveEvent);
}
ConioUnlockConsole(Console);
return Status;
}
CSR_API(CsrFlushInputBuffer)
{
PLIST_ENTRY CurrentEntry;
PCSRSS_CONSOLE Console;
ConsoleInput* Input;
NTSTATUS Status;
DPRINT("CsrFlushInputBuffer\n");
Status = ConioLockConsole(ProcessData,
Request->Data.FlushInputBufferRequest.ConsoleInput,
&Console,
GENERIC_WRITE);
if(! NT_SUCCESS(Status))
{
return Status;
}
/* Discard all entries in the input event queue */
while (!IsListEmpty(&Console->InputEvents))
{
CurrentEntry = RemoveHeadList(&Console->InputEvents);
Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
/* Destroy the event */
HeapFree(Win32CsrApiHeap, 0, Input);
}
ResetEvent(Console->ActiveEvent);
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrGetNumberOfConsoleInputEvents)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PLIST_ENTRY CurrentItem;
DWORD NumEvents;
DPRINT("CsrGetNumberOfConsoleInputEvents\n");
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if (! NT_SUCCESS(Status))
{
return Status;
}
CurrentItem = Console->InputEvents.Flink;
NumEvents = 0;
/* If there are any events ... */
while (CurrentItem != &Console->InputEvents)
{
CurrentItem = CurrentItem->Flink;
NumEvents++;
}
ConioUnlockConsole(Console);
Request->Data.GetNumInputEventsRequest.NumInputEvents = NumEvents;
return STATUS_SUCCESS;
}
CSR_API(CsrPeekConsoleInput)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
DWORD Length;
PLIST_ENTRY CurrentItem;
PINPUT_RECORD InputRecord;
ConsoleInput* Item;
UINT NumItems;
DPRINT("CsrPeekConsoleInput\n");
Status = ConioLockConsole(ProcessData, Request->Data.GetNumInputEventsRequest.ConsoleHandle, &Console, GENERIC_READ);
if(! NT_SUCCESS(Status))
{
return Status;
}
InputRecord = Request->Data.PeekConsoleInputRequest.InputRecord;
Length = Request->Data.PeekConsoleInputRequest.Length;
if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
NumItems = 0;
if (! IsListEmpty(&Console->InputEvents))
{
CurrentItem = Console->InputEvents.Flink;
while (CurrentItem != &Console->InputEvents && NumItems < Length)
{
Item = CONTAINING_RECORD(CurrentItem, ConsoleInput, ListEntry);
++NumItems;
*InputRecord = Item->InputEvent;
if (Request->Data.PeekConsoleInputRequest.Unicode == FALSE)
{
ConioInputEventToAnsi(Console, InputRecord);
}
InputRecord++;
CurrentItem = CurrentItem->Flink;
}
}
ConioUnlockConsole(Console);
Request->Data.PeekConsoleInputRequest.Length = NumItems;
return STATUS_SUCCESS;
}
CSR_API(CsrWriteConsoleInput)
{
PINPUT_RECORD InputRecord;
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DWORD Length;
DWORD i;
DPRINT("CsrWriteConsoleInput\n");
Status = ConioLockConsole(ProcessData, Request->Data.WriteConsoleInputRequest.ConsoleHandle, &Console, GENERIC_WRITE);
if (! NT_SUCCESS(Status))
{
return Status;
}
InputRecord = Request->Data.WriteConsoleInputRequest.InputRecord;
Length = Request->Data.WriteConsoleInputRequest.Length;
if (!Win32CsrValidateBuffer(ProcessData, InputRecord, Length, sizeof(INPUT_RECORD)))
{
ConioUnlockConsole(Console);
return STATUS_ACCESS_VIOLATION;
}
for (i = 0; i < Length && NT_SUCCESS(Status); i++)
{
if (!Request->Data.WriteConsoleInputRequest.Unicode &&
InputRecord->EventType == KEY_EVENT)
{
CHAR AsciiChar = InputRecord->Event.KeyEvent.uChar.AsciiChar;
ConsoleInputAnsiCharToUnicodeChar(Console,
&InputRecord->Event.KeyEvent.uChar.UnicodeChar,
&AsciiChar);
}
Status = ConioProcessChar(Console, InputRecord++);
}
ConioUnlockConsole(Console);
Request->Data.WriteConsoleInputRequest.Length = i;
return Status;
}
/* EOF */
+237
View File
@@ -0,0 +1,237 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/include/conio.h
* PURPOSE: CSRSS internal console I/O interface
*/
#pragma once
#include "api.h"
#include "win32csr.h"
#define CSR_DEFAULT_CURSOR_SIZE 25
/* Object type magic numbers */
#define CONIO_CONSOLE_MAGIC 0x00000001
#define CONIO_SCREEN_BUFFER_MAGIC 0x00000002
/************************************************************************
* Screen buffer structure represents the win32 screen buffer object. *
* Internally, the portion of the buffer being shown CAN loop past the *
* bottom of the virtual buffer and wrap around to the top. Win32 does *
* not do this. I decided to do this because it eliminates the need to *
* do a massive memcpy() to scroll the contents of the buffer up to *
* scroll the screen on output, instead I just shift down the position *
* to be displayed, and let it wrap around to the top again. *
* The VirtualY member keeps track of the top Y coord that win32 *
* clients THINK is currently being displayed, because they think that *
* when the display reaches the bottom of the buffer and another line *
* being printed causes another line to scroll down, that the buffer IS *
* memcpy()'s up, and the bottom of the buffer is still displayed, but *
* internally, I just wrap back to the top of the buffer. *
***********************************************************************/
typedef struct tagCSRSS_SCREEN_BUFFER
{
Object_t Header; /* Object header */
BYTE *Buffer; /* pointer to screen buffer */
USHORT MaxX, MaxY; /* size of the entire scrollback buffer */
USHORT ShowX, ShowY; /* beginning offset for the actual display area */
ULONG CurrentX; /* Current X cursor position */
ULONG CurrentY; /* Current Y cursor position */
WORD DefaultAttrib; /* default char attribute */
USHORT VirtualY; /* top row of buffer being displayed, reported to callers */
CONSOLE_CURSOR_INFO CursorInfo;
USHORT Mode;
LIST_ENTRY ListEntry; /* entry in console's list of buffers */
} CSRSS_SCREEN_BUFFER, *PCSRSS_SCREEN_BUFFER;
typedef struct tagCSRSS_CONSOLE *PCSRSS_CONSOLE;
typedef struct tagCSRSS_CONSOLE_VTBL
{
VOID (WINAPI *InitScreenBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
VOID (WINAPI *WriteStream)(PCSRSS_CONSOLE Console, SMALL_RECT *Block, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length);
VOID (WINAPI *DrawRegion)(PCSRSS_CONSOLE Console, SMALL_RECT *Region);
BOOL (WINAPI *SetCursorInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
BOOL (WINAPI *SetScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer,
UINT OldCursorX, UINT OldCursorY);
BOOL (WINAPI *UpdateScreenInfo)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer);
BOOL (WINAPI *ChangeTitle)(PCSRSS_CONSOLE Console);
VOID (WINAPI *CleanupConsole)(PCSRSS_CONSOLE Console);
BOOL (WINAPI *ChangeIcon)(PCSRSS_CONSOLE Console, HICON hWindowIcon);
NTSTATUS (WINAPI *ResizeBuffer)(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size);
} CSRSS_CONSOLE_VTBL, *PCSRSS_CONSOLE_VTBL;
typedef struct tagCSRSS_CONSOLE
{
Object_t Header; /* Object header */
LONG ReferenceCount;
CRITICAL_SECTION Lock;
PCSRSS_CONSOLE Prev, Next; /* Next and Prev consoles in console wheel */
HANDLE ActiveEvent;
LIST_ENTRY InputEvents; /* List head for input event queue */
PWCHAR LineBuffer; /* current line being input, in line buffered mode */
WORD LineMaxSize; /* maximum size of line in characters (including CR+LF) */
WORD LineSize; /* current size of line */
WORD LinePos; /* current position within line */
BOOLEAN LineComplete; /* user pressed enter, ready to send back to client */
BOOLEAN LineUpPressed;
BOOLEAN LineInsertToggle; /* replace character over cursor instead of inserting */
ULONG LineWakeupMask; /* bitmap of which control characters will end line input */
LIST_ENTRY HistoryBuffers;
WORD HistoryBufferSize; /* size for newly created history buffers */
WORD NumberOfHistoryBuffers; /* maximum number of history buffers allowed */
BOOLEAN HistoryNoDup; /* remove old duplicate history entries */
LIST_ENTRY BufferList; /* List of all screen buffers for this console */
PCSRSS_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */
WORD Mode; /* Console mode flags */
UNICODE_STRING Title; /* Title of console */
DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */
HWND hWindow;
COORD Size;
PVOID PrivateData;
UINT CodePage;
UINT OutputCodePage;
PCSRSS_CONSOLE_VTBL Vtbl;
LIST_ENTRY ProcessList;
struct tagALIAS_HEADER *Aliases;
CONSOLE_SELECTION_INFO Selection;
BYTE PauseFlags;
HANDLE UnpauseEvent;
} CSRSS_CONSOLE;
typedef struct ConsoleInput_t
{
LIST_ENTRY ListEntry;
INPUT_RECORD InputEvent;
} ConsoleInput;
/* CONSOLE_SELECTION_INFO dwFlags values */
#define CONSOLE_NO_SELECTION 0x0
#define CONSOLE_SELECTION_IN_PROGRESS 0x1
#define CONSOLE_SELECTION_NOT_EMPTY 0x2
#define CONSOLE_MOUSE_SELECTION 0x4
#define CONSOLE_MOUSE_DOWN 0x8
/* HistoryFlags values */
#define HISTORY_NO_DUP_FLAG 0x1
/* PauseFlags values (internal only) */
#define PAUSED_FROM_KEYBOARD 0x1
#define PAUSED_FROM_SCROLLBAR 0x2
#define PAUSED_FROM_SELECTION 0x4
#define ConioInitScreenBuffer(Console, Buff) (Console)->Vtbl->InitScreenBuffer((Console), (Buff))
#define ConioDrawRegion(Console, Region) (Console)->Vtbl->DrawRegion((Console), (Region))
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
(Console)->Vtbl->WriteStream((Console), (Block), (CurStartX), (CurStartY), \
(ScrolledLines), (Buffer), (Length))
#define ConioSetCursorInfo(Console, Buff) (Console)->Vtbl->SetCursorInfo((Console), (Buff))
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
(Console)->Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
#define ConioUpdateScreenInfo(Console, Buff) \
(Console)->Vtbl->UpdateScreenInfo(Console, Buff)
#define ConioChangeTitle(Console) (Console)->Vtbl->ChangeTitle(Console)
#define ConioCleanupConsole(Console) (Console)->Vtbl->CleanupConsole(Console)
#define ConioChangeIcon(Console, hWindowIcon) (Console)->Vtbl->ChangeIcon(Console, hWindowIcon)
#define ConioResizeBuffer(Console, Buff, Size) (Console)->Vtbl->ResizeBuffer(Console, Buff, Size)
/* console.c */
NTSTATUS FASTCALL ConioConsoleFromProcessData(PCSR_PROCESS ProcessData, PCSRSS_CONSOLE *Console);
VOID WINAPI ConioDeleteConsole(Object_t *Object);
VOID WINAPI CsrInitConsoleSupport(VOID);
VOID FASTCALL ConioPause(PCSRSS_CONSOLE Console, UINT Flags);
VOID FASTCALL ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags);
VOID FASTCALL ConioConsoleCtrlEvent(DWORD Event, PCSR_PROCESS ProcessData);
VOID FASTCALL ConioConsoleCtrlEventTimeout(DWORD Event, PCSR_PROCESS ProcessData,
DWORD Timeout);
CSR_API(CsrAllocConsole);
CSR_API(CsrFreeConsole);
CSR_API(CsrSetConsoleMode);
CSR_API(CsrGetConsoleMode);
CSR_API(CsrSetTitle);
CSR_API(CsrGetTitle);
CSR_API(CsrHardwareStateProperty);
CSR_API(CsrGetConsoleWindow);
CSR_API(CsrSetConsoleIcon);
CSR_API(CsrGetConsoleCodePage);
CSR_API(CsrSetConsoleCodePage);
CSR_API(CsrGetConsoleOutputCodePage);
CSR_API(CsrSetConsoleOutputCodePage);
CSR_API(CsrGetProcessList);
CSR_API(CsrGenerateCtrlEvent);
CSR_API(CsrGetConsoleSelectionInfo);
/* coninput.c */
#define ConioLockConsole(ProcessData, Handle, Ptr, Access) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_CONSOLE_MAGIC)
#define ConioUnlockConsole(Console) \
Win32CsrUnlockObject((Object_t *) Console)
void WINAPI ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode);
CSR_API(CsrReadConsole);
CSR_API(CsrReadInputEvent);
CSR_API(CsrFlushInputBuffer);
CSR_API(CsrGetNumberOfConsoleInputEvents);
CSR_API(CsrPeekConsoleInput);
CSR_API(CsrWriteConsoleInput);
/* conoutput.c */
#define ConioRectHeight(Rect) \
(((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
#define ConioRectWidth(Rect) \
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
#define ConioLockScreenBuffer(ProcessData, Handle, Ptr, Access) \
Win32CsrLockObject((ProcessData), (Handle), (Object_t **)(Ptr), Access, CONIO_SCREEN_BUFFER_MAGIC)
#define ConioUnlockScreenBuffer(Buff) \
Win32CsrUnlockObject((Object_t *) Buff)
PBYTE FASTCALL ConioCoordToPointer(PCSRSS_SCREEN_BUFFER Buf, ULONG X, ULONG Y);
VOID FASTCALL ConioDrawConsole(PCSRSS_CONSOLE Console);
NTSTATUS FASTCALL ConioWriteConsole(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff,
CHAR *Buffer, DWORD Length, BOOL Attrib);
NTSTATUS FASTCALL CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer);
VOID WINAPI ConioDeleteScreenBuffer(PCSRSS_SCREEN_BUFFER Buffer);
DWORD FASTCALL ConioEffectiveCursorSize(PCSRSS_CONSOLE Console, DWORD Scale);
CSR_API(CsrWriteConsole);
CSR_API(CsrGetScreenBufferInfo);
CSR_API(CsrSetCursor);
CSR_API(CsrWriteConsoleOutputChar);
CSR_API(CsrFillOutputChar);
CSR_API(CsrWriteConsoleOutputAttrib);
CSR_API(CsrFillOutputAttrib);
CSR_API(CsrGetCursorInfo);
CSR_API(CsrSetCursorInfo);
CSR_API(CsrSetTextAttrib);
CSR_API(CsrCreateScreenBuffer);
CSR_API(CsrSetScreenBuffer);
CSR_API(CsrWriteConsoleOutput);
CSR_API(CsrScrollConsoleScreenBuffer);
CSR_API(CsrReadConsoleOutputChar);
CSR_API(CsrReadConsoleOutputAttrib);
CSR_API(CsrReadConsoleOutput);
CSR_API(CsrSetScreenBufferSize);
/* alias.c */
VOID IntDeleteAllAliases(struct tagALIAS_HEADER *RootHeader);
CSR_API(CsrAddConsoleAlias);
CSR_API(CsrGetConsoleAlias);
CSR_API(CsrGetAllConsoleAliases);
CSR_API(CsrGetAllConsoleAliasesLength);
CSR_API(CsrGetConsoleAliasesExes);
CSR_API(CsrGetConsoleAliasesExesLength);
/* lineinput.c */
struct tagHISTORY_BUFFER;
VOID FASTCALL HistoryDeleteBuffer(struct tagHISTORY_BUFFER *Hist);
CSR_API(CsrGetCommandHistoryLength);
CSR_API(CsrGetCommandHistory);
CSR_API(CsrExpungeCommandHistory);
CSR_API(CsrSetHistoryNumberCommands);
CSR_API(CsrGetHistoryInfo);
CSR_API(CsrSetHistoryInfo);
VOID FASTCALL LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent);
/* EOF */
File diff suppressed because it is too large Load Diff
+832
View File
@@ -0,0 +1,832 @@
/*
* reactos/subsys/csrss/win32csr/conio.c
*
* Console I/O functions
*
* ReactOS Operating System
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
ConioConsoleFromProcessData(PCSR_PROCESS ProcessData, PCSRSS_CONSOLE *Console)
{
PCSRSS_CONSOLE ProcessConsole;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
ProcessConsole = ProcessData->Console;
if (!ProcessConsole)
{
*Console = NULL;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
InterlockedIncrement(&ProcessConsole->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
EnterCriticalSection(&(ProcessConsole->Lock));
*Console = ProcessConsole;
return STATUS_SUCCESS;
}
VOID FASTCALL
ConioConsoleCtrlEventTimeout(DWORD Event, PCSR_PROCESS ProcessData, DWORD Timeout)
{
HANDLE Thread;
DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->ClientId.UniqueProcess);
if (ProcessData->CtrlDispatcher)
{
Thread = CreateRemoteThread(ProcessData->ProcessHandle, NULL, 0,
(LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
UlongToPtr(Event), 0, NULL);
if (NULL == Thread)
{
DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
return;
}
WaitForSingleObject(Thread, Timeout);
CloseHandle(Thread);
}
}
VOID FASTCALL
ConioConsoleCtrlEvent(DWORD Event, PCSR_PROCESS ProcessData)
{
ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
}
static NTSTATUS WINAPI
CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
PCSRSS_SCREEN_BUFFER NewBuffer;
BOOL GuiMode;
WCHAR Title[255];
HINSTANCE hInst;
Console->Title.MaximumLength = Console->Title.Length = 0;
Console->Title.Buffer = NULL;
hInst = GetModuleHandleW(L"win32csr");
if (LoadStringW(hInst,IDS_COMMAND_PROMPT,Title,sizeof(Title)/sizeof(Title[0])))
{
RtlCreateUnicodeString(&Console->Title, Title);
}
else
{
RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
}
Console->ReferenceCount = 0;
Console->LineBuffer = NULL;
Console->Header.Type = CONIO_CONSOLE_MAGIC;
Console->Header.Console = Console;
Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
InitializeListHead(&Console->BufferList);
Console->ActiveBuffer = NULL;
InitializeListHead(&Console->InputEvents);
InitializeListHead(&Console->HistoryBuffers);
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = NULL;
SecurityAttributes.bInheritHandle = TRUE;
Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
if (NULL == Console->ActiveEvent)
{
RtlFreeUnicodeString(&Console->Title);
return STATUS_UNSUCCESSFUL;
}
Console->PrivateData = NULL;
InitializeCriticalSection(&Console->Lock);
GuiMode = DtbgIsDesktopVisible();
/* allocate console screen buffer */
NewBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
if (NULL == NewBuffer)
{
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* init screen buffer with defaults */
NewBuffer->CursorInfo.bVisible = TRUE;
NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
/* make console active, and insert into console list */
Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
/*
* If we are not in GUI-mode, start the text-mode console. If we fail,
* try to start the GUI-mode console (win32k will automatically switch
* to graphical mode, therefore no additional code is needed).
*/
if (!GuiMode)
{
DPRINT1("WIN32CSR: Opening text-mode console\n");
Status = TuiInitConsole(Console);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
GuiMode = TRUE;
}
}
/*
* Try to open the GUI-mode console. Two cases are possible:
* - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
* failed and we start GUI-mode console.
* - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
* succeeded BUT we failed at starting text-mode console. Then GuiMode
* was switched to TRUE in order to try to open the console in GUI-mode.
*/
if (GuiMode)
{
DPRINT1("WIN32CSR: Opening GUI-mode console\n");
Status = GuiInitConsole(Console, ShowCmd);
if (!NT_SUCCESS(Status))
{
HeapFree(Win32CsrApiHeap,0, NewBuffer);
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
return Status;
}
}
Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
if (!NT_SUCCESS(Status))
{
ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title);
DeleteCriticalSection(&Console->Lock);
CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
return Status;
}
/* copy buffer contents to screen */
ConioDrawConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrAllocConsole)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN NewConsole = FALSE;
DPRINT("CsrAllocConsole\n");
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console)
{
DPRINT1("Process already has a console\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
/* If we don't need a console, then get out of here */
if (!Request->Data.AllocConsoleRequest.ConsoleNeeded)
{
DPRINT("No console needed\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
/* If we already have one, then don't create a new one... */
if (!Request->Data.AllocConsoleRequest.Console ||
Request->Data.AllocConsoleRequest.Console != ProcessData->ParentConsole)
{
/* Allocate a console structure */
NewConsole = TRUE;
Console = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
if (NULL == Console)
{
DPRINT1("Not enough memory for console\n");
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_NO_MEMORY;
}
/* initialize list head */
InitializeListHead(&Console->ProcessList);
/* insert process data required for GUI initialization */
InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
/* Initialize the Console */
Status = CsrInitConsole(Console, Request->Data.AllocConsoleRequest.ShowCmd);
if (!NT_SUCCESS(Status))
{
DPRINT1("Console init failed\n");
HeapFree(Win32CsrApiHeap, 0, Console);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
}
else
{
/* Reuse our current console */
Console = Request->Data.AllocConsoleRequest.Console;
}
/* Set the Process Console */
ProcessData->Console = Console;
/* Return it to the caller */
Request->Data.AllocConsoleRequest.Console = Console;
/* Add a reference count because the process is tied to the console */
_InterlockedIncrement(&Console->ReferenceCount);
if (NewConsole || !ProcessData->bInheritHandles)
{
/* Insert the Objects */
Status = Win32CsrInsertObject(ProcessData,
&Request->Data.AllocConsoleRequest.InputHandle,
&Console->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
ConioDeleteConsole((Object_t *) Console);
ProcessData->Console = 0;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
Status = Win32CsrInsertObject(ProcessData,
&Request->Data.AllocConsoleRequest.OutputHandle,
&Console->ActiveBuffer->Header,
GENERIC_READ | GENERIC_WRITE,
TRUE,
FILE_SHARE_READ | FILE_SHARE_WRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to insert object\n");
ConioDeleteConsole((Object_t *) Console);
Win32CsrReleaseObject(ProcessData,
Request->Data.AllocConsoleRequest.InputHandle);
ProcessData->Console = 0;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
}
/* Duplicate the Event */
if (!DuplicateHandle(GetCurrentProcess(),
ProcessData->Console->ActiveEvent,
ProcessData->ProcessHandle,
&ProcessData->ConsoleEvent,
EVENT_ALL_ACCESS,
FALSE,
0))
{
DPRINT1("DuplicateHandle() failed: %lu\n", GetLastError());
ConioDeleteConsole((Object_t *) Console);
if (NewConsole || !ProcessData->bInheritHandles)
{
Win32CsrReleaseObject(ProcessData,
Request->Data.AllocConsoleRequest.OutputHandle);
Win32CsrReleaseObject(ProcessData,
Request->Data.AllocConsoleRequest.InputHandle);
}
ProcessData->Console = 0;
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
/* Set the Ctrl Dispatcher */
ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
if (!NewConsole)
{
/* Insert into the list if it has not been added */
InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
CSR_API(CsrFreeConsole)
{
Win32CsrReleaseConsole(ProcessData);
return STATUS_SUCCESS;
}
VOID WINAPI
ConioDeleteConsole(Object_t *Object)
{
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
ConsoleInput *Event;
DPRINT("ConioDeleteConsole\n");
/* Drain input event queue */
while (Console->InputEvents.Flink != &Console->InputEvents)
{
Event = (ConsoleInput *) Console->InputEvents.Flink;
Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
HeapFree(Win32CsrApiHeap, 0, Event);
}
ConioCleanupConsole(Console);
if (Console->LineBuffer)
RtlFreeHeap(Win32CsrApiHeap, 0, Console->LineBuffer);
while (!IsListEmpty(&Console->HistoryBuffers))
HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
ConioDeleteScreenBuffer(Console->ActiveBuffer);
if (!IsListEmpty(&Console->BufferList))
{
DPRINT1("BUG: screen buffer list not empty\n");
}
CloseHandle(Console->ActiveEvent);
if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
DeleteCriticalSection(&Console->Lock);
RtlFreeUnicodeString(&Console->Title);
IntDeleteAllAliases(Console->Aliases);
HeapFree(Win32CsrApiHeap, 0, Console);
}
VOID WINAPI
CsrInitConsoleSupport(VOID)
{
DPRINT("CSR: CsrInitConsoleSupport()\n");
/* Should call LoadKeyboardLayout */
}
VOID FASTCALL
ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
{
Console->PauseFlags |= Flags;
if (!Console->UnpauseEvent)
Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
VOID FASTCALL
ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
{
Console->PauseFlags &= ~Flags;
if (Console->PauseFlags == 0 && Console->UnpauseEvent)
{
SetEvent(Console->UnpauseEvent);
CloseHandle(Console->UnpauseEvent);
Console->UnpauseEvent = NULL;
}
}
CSR_API(CsrSetConsoleMode)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff;
DPRINT("CsrSetConsoleMode\n");
Status = Win32CsrLockObject(ProcessData,
Request->Data.SetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console, GENERIC_WRITE, 0);
if (! NT_SUCCESS(Status))
{
return Status;
}
Buff = (PCSRSS_SCREEN_BUFFER)Console;
if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
{
Console->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_INPUT_MODE_VALID;
}
else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
{
Buff->Mode = Request->Data.SetConsoleModeRequest.Mode & CONSOLE_OUTPUT_MODE_VALID;
}
else
{
Status = STATUS_INVALID_HANDLE;
}
Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
CSR_API(CsrGetConsoleMode)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PCSRSS_SCREEN_BUFFER Buff; /* gee, I really wish I could use an anonymous union here */
DPRINT("CsrGetConsoleMode\n");
Status = Win32CsrLockObject(ProcessData, Request->Data.GetConsoleModeRequest.ConsoleHandle,
(Object_t **) &Console, GENERIC_READ, 0);
if (! NT_SUCCESS(Status))
{
return Status;
}
Status = STATUS_SUCCESS;
Buff = (PCSRSS_SCREEN_BUFFER) Console;
if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
{
Request->Data.GetConsoleModeRequest.ConsoleMode = Console->Mode;
}
else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
{
Request->Data.GetConsoleModeRequest.ConsoleMode = Buff->Mode;
}
else
{
Status = STATUS_INVALID_HANDLE;
}
Win32CsrUnlockObject((Object_t *)Console);
return Status;
}
CSR_API(CsrSetTitle)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
PWCHAR Buffer;
DPRINT("CsrSetTitle\n");
if (!Win32CsrValidateBuffer(ProcessData, Request->Data.SetTitleRequest.Title,
Request->Data.SetTitleRequest.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if(NT_SUCCESS(Status))
{
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Request->Data.SetTitleRequest.Length);
if (Buffer)
{
/* copy title to console */
RtlFreeUnicodeString(&Console->Title);
Console->Title.Buffer = Buffer;
Console->Title.Length = Console->Title.MaximumLength = Request->Data.SetTitleRequest.Length;
memcpy(Console->Title.Buffer, Request->Data.SetTitleRequest.Title, Console->Title.Length);
if (! ConioChangeTitle(Console))
{
Status = STATUS_UNSUCCESSFUL;
}
else
{
Status = STATUS_SUCCESS;
}
}
else
{
Status = STATUS_NO_MEMORY;
}
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrGetTitle)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
DWORD Length;
DPRINT("CsrGetTitle\n");
if (!Win32CsrValidateBuffer(ProcessData, Request->Data.GetTitleRequest.Title,
Request->Data.GetTitleRequest.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
DPRINT1("Can't get console\n");
return Status;
}
/* Copy title of the console to the user title buffer */
if (Request->Data.GetTitleRequest.Length >= sizeof(WCHAR))
{
Length = min(Request->Data.GetTitleRequest.Length - sizeof(WCHAR), Console->Title.Length);
memcpy(Request->Data.GetTitleRequest.Title, Console->Title.Buffer, Length);
Request->Data.GetTitleRequest.Title[Length / sizeof(WCHAR)] = L'\0';
}
Request->Data.GetTitleRequest.Length = Console->Title.Length;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
/**********************************************************************
* HardwareStateProperty
*
* DESCRIPTION
* Set/Get the value of the HardwareState and switch
* between direct video buffer ouput and GDI windowed
* output.
* ARGUMENTS
* Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
* object. We use the same object to Request.
* NOTE
* ConsoleHwState has the correct size to be compatible
* with NT's, but values are not.
*/
static NTSTATUS FASTCALL
SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
{
DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
{
if (Console->HardwareState != ConsoleHwState)
{
/* TODO: implement switching from full screen to windowed mode */
/* TODO: or back; now simply store the hardware state */
Console->HardwareState = ConsoleHwState;
}
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
}
CSR_API(CsrHardwareStateProperty)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrHardwareStateProperty\n");
Status = ConioLockConsole(ProcessData,
Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
&Console,
GENERIC_READ);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to get console handle in SetConsoleHardwareState\n");
return Status;
}
switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
{
case CONSOLE_HARDWARE_STATE_GET:
Request->Data.ConsoleHardwareStateRequest.State = Console->HardwareState;
break;
case CONSOLE_HARDWARE_STATE_SET:
DPRINT("Setting console hardware state.\n");
Status = SetConsoleHardwareState(Console, Request->Data.ConsoleHardwareStateRequest.State);
break;
default:
Status = STATUS_INVALID_PARAMETER_2; /* Client: (handle, [set_get], mode) */
break;
}
ConioUnlockConsole(Console);
return Status;
}
CSR_API(CsrGetConsoleWindow)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrGetConsoleWindow\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
Request->Data.GetConsoleWindowRequest.WindowHandle = Console->hWindow;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleIcon)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrSetConsoleIcon\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
Status = (ConioChangeIcon(Console, Request->Data.SetConsoleIconRequest.WindowIcon)
? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
ConioUnlockConsole(Console);
return Status;
}
CSR_API(CsrGetConsoleCodePage)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrGetConsoleCodePage\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
Request->Data.GetConsoleCodePage.CodePage = Console->CodePage;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleCodePage)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrSetConsoleCodePage\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
if (IsValidCodePage(Request->Data.SetConsoleCodePage.CodePage))
{
Console->CodePage = Request->Data.SetConsoleCodePage.CodePage;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
CSR_API(CsrGetConsoleOutputCodePage)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrGetConsoleOutputCodePage\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
Request->Data.GetConsoleOutputCodePage.CodePage = Console->OutputCodePage;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
CSR_API(CsrSetConsoleOutputCodePage)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
DPRINT("CsrSetConsoleOutputCodePage\n");
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
if (IsValidCodePage(Request->Data.SetConsoleOutputCodePage.CodePage))
{
Console->OutputCodePage = Request->Data.SetConsoleOutputCodePage.CodePage;
ConioUnlockConsole(Console);
return STATUS_SUCCESS;
}
ConioUnlockConsole(Console);
return STATUS_INVALID_PARAMETER;
}
CSR_API(CsrGetProcessList)
{
PDWORD Buffer;
PCSRSS_CONSOLE Console;
PCSR_PROCESS current;
PLIST_ENTRY current_entry;
ULONG nItems = 0;
NTSTATUS Status;
DPRINT("CsrGetProcessList\n");
Buffer = Request->Data.GetProcessListRequest.ProcessId;
if (!Win32CsrValidateBuffer(ProcessData, Buffer, Request->Data.GetProcessListRequest.nMaxIds, sizeof(DWORD)))
return STATUS_ACCESS_VIOLATION;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
for (current_entry = Console->ProcessList.Flink;
current_entry != &Console->ProcessList;
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
if (++nItems <= Request->Data.GetProcessListRequest.nMaxIds)
{
*Buffer++ = HandleToUlong(current->ClientId.UniqueProcess);
}
}
ConioUnlockConsole(Console);
Request->Data.GetProcessListRequest.nProcessIdsTotal = nItems;
return STATUS_SUCCESS;
}
CSR_API(CsrGenerateCtrlEvent)
{
PCSRSS_CONSOLE Console;
PCSR_PROCESS current;
PLIST_ENTRY current_entry;
DWORD Group;
NTSTATUS Status;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (! NT_SUCCESS(Status))
{
return Status;
}
Group = Request->Data.GenerateCtrlEvent.ProcessGroup;
Status = STATUS_INVALID_PARAMETER;
for (current_entry = Console->ProcessList.Flink;
current_entry != &Console->ProcessList;
current_entry = current_entry->Flink)
{
current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink);
if (Group == 0 || current->ProcessGroupId == Group)
{
ConioConsoleCtrlEvent(Request->Data.GenerateCtrlEvent.Event, current);
Status = STATUS_SUCCESS;
}
}
ConioUnlockConsole(Console);
return Status;
}
CSR_API(CsrGetConsoleSelectionInfo)
{
NTSTATUS Status;
PCSRSS_CONSOLE Console;
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
memset(&Request->Data.GetConsoleSelectionInfo.Info, 0, sizeof(CONSOLE_SELECTION_INFO));
if (Console->Selection.dwFlags != 0)
Request->Data.GetConsoleSelectionInfo.Info = Console->Selection;
ConioUnlockConsole(Console);
}
return Status;
}
/* EOF */
+27
View File
@@ -0,0 +1,27 @@
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
CSR_API(CsrCreateDesktop)
{
return STATUS_SUCCESS;
}
CSR_API(CsrShowDesktop)
{
return STATUS_SUCCESS;
}
CSR_API(CsrHideDesktop)
{
return STATUS_SUCCESS;
}
BOOL
FASTCALL DtbgIsDesktopVisible(VOID)
{
return !((BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_ISCONSOLEMODE));
}
/* EOF */
+20
View File
@@ -0,0 +1,20 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/include/destkopbg.h
* PURPOSE: CSRSS internal desktop background window interface
*/
#pragma once
#include "api.h"
/* Api functions */
CSR_API(CsrCreateDesktop);
CSR_API(CsrShowDesktop);
CSR_API(CsrHideDesktop);
CSR_API(CsrRegisterSystemClasses);
BOOL FASTCALL DtbgIsDesktopVisible(VOID);
/* EOF */
+372
View File
@@ -0,0 +1,372 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/dllmain.c
* PURPOSE: Initialization
* PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include "file.h"
#include <debug.h>
/* Not defined in any header file */
extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
extern LIST_ENTRY DosDeviceHistory;
extern RTL_CRITICAL_SECTION Win32CsrDefineDosDeviceCritSec;
/* GLOBALS *******************************************************************/
HANDLE Win32CsrApiHeap;
HINSTANCE Win32CsrDllHandle = NULL;
static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] =
{
CSRSS_DEFINE_API(GET_INPUT_HANDLE, CsrGetHandle),
CSRSS_DEFINE_API(GET_OUTPUT_HANDLE, CsrGetHandle),
CSRSS_DEFINE_API(CLOSE_HANDLE, CsrCloseHandle),
CSRSS_DEFINE_API(VERIFY_HANDLE, CsrVerifyHandle),
CSRSS_DEFINE_API(DUPLICATE_HANDLE, CsrDuplicateHandle),
CSRSS_DEFINE_API(GET_INPUT_WAIT_HANDLE, CsrGetInputWaitHandle),
CSRSS_DEFINE_API(WRITE_CONSOLE, CsrWriteConsole),
CSRSS_DEFINE_API(READ_CONSOLE, CsrReadConsole),
CSRSS_DEFINE_API(ALLOC_CONSOLE, CsrAllocConsole),
CSRSS_DEFINE_API(FREE_CONSOLE, CsrFreeConsole),
CSRSS_DEFINE_API(SCREEN_BUFFER_INFO, CsrGetScreenBufferInfo),
CSRSS_DEFINE_API(SET_CURSOR, CsrSetCursor),
CSRSS_DEFINE_API(FILL_OUTPUT, CsrFillOutputChar),
CSRSS_DEFINE_API(READ_INPUT, CsrReadInputEvent),
CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_CHAR, CsrWriteConsoleOutputChar),
CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CsrWriteConsoleOutputAttrib),
CSRSS_DEFINE_API(FILL_OUTPUT_ATTRIB, CsrFillOutputAttrib),
CSRSS_DEFINE_API(GET_CURSOR_INFO, CsrGetCursorInfo),
CSRSS_DEFINE_API(SET_CURSOR_INFO, CsrSetCursorInfo),
CSRSS_DEFINE_API(SET_ATTRIB, CsrSetTextAttrib),
CSRSS_DEFINE_API(GET_CONSOLE_MODE, CsrGetConsoleMode),
CSRSS_DEFINE_API(SET_CONSOLE_MODE, CsrSetConsoleMode),
CSRSS_DEFINE_API(CREATE_SCREEN_BUFFER, CsrCreateScreenBuffer),
CSRSS_DEFINE_API(SET_SCREEN_BUFFER, CsrSetScreenBuffer),
CSRSS_DEFINE_API(SET_TITLE, CsrSetTitle),
CSRSS_DEFINE_API(GET_TITLE, CsrGetTitle),
CSRSS_DEFINE_API(WRITE_CONSOLE_OUTPUT, CsrWriteConsoleOutput),
CSRSS_DEFINE_API(FLUSH_INPUT_BUFFER, CsrFlushInputBuffer),
CSRSS_DEFINE_API(SCROLL_CONSOLE_SCREEN_BUFFER, CsrScrollConsoleScreenBuffer),
CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_CHAR, CsrReadConsoleOutputChar),
CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT_ATTRIB, CsrReadConsoleOutputAttrib),
CSRSS_DEFINE_API(GET_NUM_INPUT_EVENTS, CsrGetNumberOfConsoleInputEvents),
CSRSS_DEFINE_API(EXIT_REACTOS, CsrExitReactos),
CSRSS_DEFINE_API(PEEK_CONSOLE_INPUT, CsrPeekConsoleInput),
CSRSS_DEFINE_API(READ_CONSOLE_OUTPUT, CsrReadConsoleOutput),
CSRSS_DEFINE_API(WRITE_CONSOLE_INPUT, CsrWriteConsoleInput),
CSRSS_DEFINE_API(SETGET_CONSOLE_HW_STATE, CsrHardwareStateProperty),
CSRSS_DEFINE_API(GET_CONSOLE_WINDOW, CsrGetConsoleWindow),
CSRSS_DEFINE_API(CREATE_DESKTOP, CsrCreateDesktop),
CSRSS_DEFINE_API(SHOW_DESKTOP, CsrShowDesktop),
CSRSS_DEFINE_API(HIDE_DESKTOP, CsrHideDesktop),
CSRSS_DEFINE_API(SET_CONSOLE_ICON, CsrSetConsoleIcon),
CSRSS_DEFINE_API(SET_LOGON_NOTIFY_WINDOW, CsrSetLogonNotifyWindow),
CSRSS_DEFINE_API(REGISTER_LOGON_PROCESS, CsrRegisterLogonProcess),
CSRSS_DEFINE_API(GET_CONSOLE_CP, CsrGetConsoleCodePage),
CSRSS_DEFINE_API(SET_CONSOLE_CP, CsrSetConsoleCodePage),
CSRSS_DEFINE_API(GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage),
CSRSS_DEFINE_API(SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage),
CSRSS_DEFINE_API(GET_PROCESS_LIST, CsrGetProcessList),
CSRSS_DEFINE_API(ADD_CONSOLE_ALIAS, CsrAddConsoleAlias),
CSRSS_DEFINE_API(GET_CONSOLE_ALIAS, CsrGetConsoleAlias),
CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES, CsrGetAllConsoleAliases),
CSRSS_DEFINE_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CsrGetAllConsoleAliasesLength),
CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES, CsrGetConsoleAliasesExes),
CSRSS_DEFINE_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CsrGetConsoleAliasesExesLength),
CSRSS_DEFINE_API(GENERATE_CTRL_EVENT, CsrGenerateCtrlEvent),
CSRSS_DEFINE_API(SET_SCREEN_BUFFER_SIZE, CsrSetScreenBufferSize),
CSRSS_DEFINE_API(GET_CONSOLE_SELECTION_INFO, CsrGetConsoleSelectionInfo),
CSRSS_DEFINE_API(GET_COMMAND_HISTORY_LENGTH, CsrGetCommandHistoryLength),
CSRSS_DEFINE_API(GET_COMMAND_HISTORY, CsrGetCommandHistory),
CSRSS_DEFINE_API(EXPUNGE_COMMAND_HISTORY, CsrExpungeCommandHistory),
CSRSS_DEFINE_API(SET_HISTORY_NUMBER_COMMANDS, CsrSetHistoryNumberCommands),
CSRSS_DEFINE_API(GET_HISTORY_INFO, CsrGetHistoryInfo),
CSRSS_DEFINE_API(SET_HISTORY_INFO, CsrSetHistoryInfo),
CSRSS_DEFINE_API(GET_TEMP_FILE, CsrGetTempFile),
CSRSS_DEFINE_API(DEFINE_DOS_DEVICE, CsrDefineDosDevice),
CSRSS_DEFINE_API(SOUND_SENTRY, CsrSoundSentry),
{ 0, 0, NULL }
};
static HHOOK hhk = NULL;
/* FUNCTIONS *****************************************************************/
LRESULT
CALLBACK
KeyboardHookProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
return CallNextHookEx(hhk, nCode, wParam, lParam);
}
ULONG
InitializeVideoAddressSpace(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
NTSTATUS Status;
HANDLE PhysMemHandle;
PVOID BaseAddress;
LARGE_INTEGER Offset;
SIZE_T ViewSize;
CHAR IVTAndBda[1024+256];
/* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
BaseAddress = 0;
ViewSize = 1024 * 1024;
Status = ZwFreeVirtualMemory(NtCurrentProcess(),
&BaseAddress,
&ViewSize,
MEM_RELEASE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
return 0;
}
/* Open the physical memory section */
InitializeObjectAttributes(&ObjectAttributes,
&PhysMemName,
0,
NULL,
NULL);
Status = ZwOpenSection(&PhysMemHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
return 0;
}
/* Map the BIOS and device registers into the address space */
Offset.QuadPart = 0xa0000;
ViewSize = 0x100000 - 0xa0000;
BaseAddress = (PVOID)0xa0000;
Status = ZwMapViewOfSection(PhysMemHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&Offset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Couldn't map physical memory (%x)\n", Status);
ZwClose(PhysMemHandle);
return 0;
}
/* Close physical memory section handle */
ZwClose(PhysMemHandle);
if (BaseAddress != (PVOID)0xa0000)
{
DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
BaseAddress);
return 0;
}
/* Allocate some low memory to use for the non-BIOS
* parts of the v86 mode address space
*/
BaseAddress = (PVOID)0x1;
ViewSize = 0xa0000 - 0x1000;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&BaseAddress,
0,
&ViewSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
return 0;
}
if (BaseAddress != (PVOID)0x0)
{
DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
BaseAddress);
return 0;
}
/* Get the real mode IVT and BDA from the kernel */
Status = NtVdmControl(VdmInitialize, IVTAndBda);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtVdmControl failed (status %x)\n", Status);
return 0;
}
/* Return success */
return 1;
}
/**********************************************************************
* CsrpInitVideo/3
*
* TODO: we need a virtual device for sessions other than
* TODO: the console one
*/
NTSTATUS
CsrpInitVideo (VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
IO_STATUS_BLOCK Iosb;
HANDLE VideoHandle = (HANDLE) 0;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s called\n", __FUNCTION__);
InitializeVideoAddressSpace();
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);
Status = NtOpenFile(&VideoHandle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
0,
0);
if (NT_SUCCESS(Status))
{
NtClose(VideoHandle);
}
return Status;
}
BOOL WINAPI
DllMain(HANDLE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
if (DLL_PROCESS_ATTACH == dwReason)
{
Win32CsrDllHandle = hDll;
//
// HACK HACK HACK ReactOS to BOOT! Initialization BUG ALERT! See bug 5655.
//
hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, NULL, 0);
// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
}
if (DLL_PROCESS_DETACH == dwReason)
{
CsrCleanupDefineDosDevice();
}
return TRUE;
}
/* Ensure that a captured buffer is safe to access */
BOOL FASTCALL
Win32CsrValidateBuffer(PCSR_PROCESS ProcessData, PVOID Buffer,
SIZE_T NumElements, SIZE_T ElementSize)
{
/* Check that the following conditions are true:
* 1. The start of the buffer is somewhere within the process's
* shared memory section view.
* 2. The remaining space in the view is at least as large as the buffer.
* (NB: Please don't try to "optimize" this by using multiplication
* instead of division; remember that 2147483648 * 2 = 0.)
* 3. The buffer is DWORD-aligned.
*/
ULONG_PTR Offset = (BYTE *)Buffer - (BYTE *)ProcessData->ClientViewBase;
if (Offset >= ProcessData->ClientViewBounds
|| NumElements > (ProcessData->ClientViewBounds - Offset) / ElementSize
|| (Offset & (sizeof(DWORD) - 1)) != 0)
{
DPRINT1("Invalid buffer %p(%u*%u); section view is %p(%u)\n",
Buffer, NumElements, ElementSize,
ProcessData->ClientViewBase, ProcessData->ClientViewBounds);
return FALSE;
}
return TRUE;
}
NTSTATUS FASTCALL
Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
PVOID Context)
{
return CsrEnumProcesses(EnumProc, Context);
}
VOID
WINAPI
PrivateCsrssManualGuiCheck(LONG Check)
{
NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
}
DWORD
WINAPI
CreateSystemThreads(PVOID pParam)
{
NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
DPRINT1("This thread should not terminate!\n");
return 0;
}
NTSTATUS
WINAPI
Win32CsrInitialization(IN PCSR_SERVER_DLL ServerDll)
{
HANDLE ServerThread;
CLIENT_ID ClientId;
NTSTATUS Status;
UINT i;
Win32CsrApiHeap = RtlGetProcessHeap();
CsrpInitVideo();
NtUserInitialize(0, NULL, NULL);
PrivateCsrssManualGuiCheck(0);
CsrInitConsoleSupport();
/* HACK */
ServerDll->DispatchTable = (PVOID)Win32CsrApiDefinitions;
ServerDll->HighestApiSupported = 0xDEADBABE;
ServerDll->HardErrorCallback = Win32CsrHardError;
ServerDll->NewProcessCallback = Win32CsrDuplicateHandleTable;
ServerDll->DisconnectCallback = Win32CsrReleaseConsole;
RtlInitializeCriticalSection(&Win32CsrDefineDosDeviceCritSec);
InitializeListHead(&DosDeviceHistory);
/* Start the Raw Input Thread and the Desktop Thread */
for (i = 0; i < 2; ++i)
{
Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
if (NT_SUCCESS(Status))
{
NtResumeThread(ServerThread, NULL);
NtClose(ServerThread);
}
else
DPRINT1("Cannot start Raw Input Thread!\n");
}
return STATUS_SUCCESS;
}
/* EOF */
+912
View File
@@ -0,0 +1,912 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSRSS subsystem
* FILE: subsys/csrss/win32csr/exitros.c
* PURPOSE: Logout/shutdown
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <sddl.h>
#include "resource.h"
#include <debug.h>
static HANDLE LogonProcess = NULL;
CSR_API(CsrRegisterLogonProcess)
{
if (Request->Data.RegisterLogonProcessRequest.Register)
{
if (0 != LogonProcess)
{
return STATUS_LOGON_SESSION_EXISTS;
}
LogonProcess = Request->Data.RegisterLogonProcessRequest.ProcessId;
}
else
{
if (Request->Header.ClientId.UniqueProcess != LogonProcess)
{
DPRINT1("Current logon process 0x%x, can't deregister from process 0x%x\n",
LogonProcess, Request->Header.ClientId.UniqueProcess);
return STATUS_NOT_LOGON_PROCESS;
}
LogonProcess = 0;
}
return STATUS_SUCCESS;
}
CSR_API(CsrSetLogonNotifyWindow)
{
return STATUS_SUCCESS;
}
typedef struct tagSHUTDOWN_SETTINGS
{
BOOL AutoEndTasks;
DWORD HungAppTimeout;
DWORD WaitToKillAppTimeout;
} SHUTDOWN_SETTINGS, *PSHUTDOWN_SETTINGS;
#define DEFAULT_AUTO_END_TASKS FALSE
#define DEFAULT_HUNG_APP_TIMEOUT 5000
#define DEFAULT_WAIT_TO_KILL_APP_TIMEOUT 20000
typedef struct tagNOTIFY_CONTEXT
{
DWORD ProcessId;
UINT Msg;
WPARAM wParam;
LPARAM lParam;
HDESK Desktop;
HDESK OldDesktop;
DWORD StartTime;
DWORD QueryResult;
HWND Dlg;
DWORD EndNowResult;
BOOL ShowUI;
HANDLE UIThread;
HWND WndClient;
PSHUTDOWN_SETTINGS ShutdownSettings;
LPTHREAD_START_ROUTINE SendMessageProc;
} NOTIFY_CONTEXT, *PNOTIFY_CONTEXT;
#define QUERY_RESULT_ABORT 0
#define QUERY_RESULT_CONTINUE 1
#define QUERY_RESULT_TIMEOUT 2
#define QUERY_RESULT_ERROR 3
#define QUERY_RESULT_FORCE 4
static void FASTCALL
UpdateProgressBar(HWND ProgressBar, PNOTIFY_CONTEXT NotifyContext)
{
DWORD Passed;
Passed = GetTickCount() - NotifyContext->StartTime;
Passed -= NotifyContext->ShutdownSettings->HungAppTimeout;
if (NotifyContext->ShutdownSettings->WaitToKillAppTimeout < Passed)
{
Passed = NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
}
SendMessageW(ProgressBar, PBM_SETPOS, Passed / 2, 0);
}
static INT_PTR CALLBACK
EndNowDlgProc(HWND Dlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
INT_PTR Result;
PNOTIFY_CONTEXT NotifyContext;
HWND ProgressBar;
DWORD TitleLength;
int Len;
LPWSTR Title;
switch(Msg)
{
case WM_INITDIALOG:
NotifyContext = (PNOTIFY_CONTEXT) lParam;
NotifyContext->EndNowResult = QUERY_RESULT_ABORT;
SetWindowLongPtrW(Dlg, DWLP_USER, (LONG_PTR) lParam);
TitleLength = SendMessageW(NotifyContext->WndClient, WM_GETTEXTLENGTH,
0, 0) +
GetWindowTextLengthW(Dlg);
Title = HeapAlloc(Win32CsrApiHeap, 0, (TitleLength + 1) * sizeof(WCHAR));
if (NULL != Title)
{
Len = GetWindowTextW(Dlg, Title, TitleLength + 1);
SendMessageW(NotifyContext->WndClient, WM_GETTEXT,
TitleLength + 1 - Len, (LPARAM) (Title + Len));
SetWindowTextW(Dlg, Title);
HeapFree(Win32CsrApiHeap, 0, Title);
}
ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
SendMessageW(ProgressBar, PBM_SETRANGE32, 0,
NotifyContext->ShutdownSettings->WaitToKillAppTimeout / 2);
UpdateProgressBar(ProgressBar, NotifyContext);
SetTimer(Dlg, 0, 200, NULL);
Result = FALSE;
break;
case WM_TIMER:
NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
ProgressBar = GetDlgItem(Dlg, IDC_PROGRESS);
UpdateProgressBar(ProgressBar, NotifyContext);
Result = TRUE;
break;
case WM_COMMAND:
if (BN_CLICKED == HIWORD(wParam) && IDC_END_NOW == LOWORD(wParam))
{
NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
NotifyContext->EndNowResult = QUERY_RESULT_FORCE;
SendMessageW(Dlg, WM_CLOSE, 0, 0);
Result = TRUE;
}
else
{
Result = FALSE;
}
break;
case WM_CLOSE:
DestroyWindow(Dlg);
Result = TRUE;
break;
case WM_DESTROY:
NotifyContext = (PNOTIFY_CONTEXT) GetWindowLongPtrW(Dlg, DWLP_USER);
NotifyContext->Dlg = NULL;
KillTimer(Dlg, 0);
PostQuitMessage(NotifyContext->EndNowResult);
Result = TRUE;
break;
default:
Result = FALSE;
break;
}
return Result;
}
typedef void (WINAPI *INITCOMMONCONTROLS_PROC)(void);
static void
CallInitCommonControls()
{
static BOOL Initialized = FALSE;
HMODULE Lib;
INITCOMMONCONTROLS_PROC InitProc;
if (Initialized)
{
return;
}
Lib = LoadLibraryW(L"COMCTL32.DLL");
if (NULL == Lib)
{
return;
}
InitProc = (INITCOMMONCONTROLS_PROC) GetProcAddress(Lib, "InitCommonControls");
if (NULL == InitProc)
{
return;
}
(*InitProc)();
Initialized = TRUE;
}
static DWORD WINAPI
EndNowThreadProc(LPVOID Parameter)
{
PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) Parameter;
MSG Msg;
SetThreadDesktop(NotifyContext->Desktop);
SwitchDesktop(NotifyContext->Desktop);
CallInitCommonControls();
NotifyContext->Dlg = CreateDialogParam(GetModuleHandleW(L"win32csr"),
MAKEINTRESOURCE(IDD_END_NOW), NULL,
EndNowDlgProc, (LPARAM) NotifyContext);
if (NULL == NotifyContext->Dlg)
{
return 0;
}
ShowWindow(NotifyContext->Dlg, SW_SHOWNORMAL);
while (GetMessageW(&Msg, NULL, 0, 0))
{
if (! IsDialogMessage(NotifyContext->Dlg, &Msg))
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
return Msg.wParam;
}
typedef struct tagMESSAGE_CONTEXT
{
HWND Wnd;
UINT Msg;
WPARAM wParam;
LPARAM lParam;
DWORD Timeout;
} MESSAGE_CONTEXT, *PMESSAGE_CONTEXT;
static DWORD WINAPI
SendQueryEndSession(LPVOID Parameter)
{
PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter;
DWORD_PTR Result;
if (SendMessageTimeoutW(Context->Wnd, WM_QUERYENDSESSION, Context->wParam,
Context->lParam, SMTO_NORMAL, Context->Timeout,
&Result))
{
return Result ? QUERY_RESULT_CONTINUE : QUERY_RESULT_ABORT;
}
return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR;
}
static DWORD WINAPI
SendEndSession(LPVOID Parameter)
{
PMESSAGE_CONTEXT Context = (PMESSAGE_CONTEXT) Parameter;
DWORD_PTR Result;
if (Context->wParam)
{
if (SendMessageTimeoutW(Context->Wnd, WM_ENDSESSION, Context->wParam,
Context->lParam, SMTO_NORMAL, Context->Timeout,
&Result))
{
return QUERY_RESULT_CONTINUE;
}
return 0 == GetLastError() ? QUERY_RESULT_TIMEOUT : QUERY_RESULT_ERROR;
}
else
{
SendMessage(Context->Wnd, WM_ENDSESSION, Context->wParam,
Context->lParam);
return QUERY_RESULT_CONTINUE;
}
}
static BOOL CALLBACK
NotifyTopLevelEnum(HWND Wnd, LPARAM lParam)
{
PNOTIFY_CONTEXT NotifyContext = (PNOTIFY_CONTEXT) lParam;
MESSAGE_CONTEXT MessageContext;
DWORD Now, Passed;
DWORD Timeout, WaitStatus;
DWORD ProcessId;
HANDLE MessageThread;
HANDLE Threads[2];
if (0 == GetWindowThreadProcessId(Wnd, &ProcessId))
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
return FALSE;
}
if (ProcessId == NotifyContext->ProcessId)
{
Now = GetTickCount();
if (0 == NotifyContext->StartTime)
{
NotifyContext->StartTime = Now;
}
/* Note: Passed is computed correctly even when GetTickCount() wraps due
to unsigned arithmetic */
Passed = Now - NotifyContext->StartTime;
MessageContext.Wnd = Wnd;
MessageContext.Msg = NotifyContext->Msg;
MessageContext.wParam = NotifyContext->wParam;
MessageContext.lParam = NotifyContext->lParam;
MessageContext.Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
if (! NotifyContext->ShutdownSettings->AutoEndTasks)
{
MessageContext.Timeout += NotifyContext->ShutdownSettings->WaitToKillAppTimeout;
}
if (Passed < MessageContext.Timeout)
{
MessageContext.Timeout -= Passed;
MessageThread = CreateThread(NULL, 0, NotifyContext->SendMessageProc,
(LPVOID) &MessageContext, 0, NULL);
if (NULL == MessageThread)
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
return FALSE;
}
Timeout = NotifyContext->ShutdownSettings->HungAppTimeout;
if (Passed < Timeout)
{
Timeout -= Passed;
WaitStatus = WaitForSingleObjectEx(MessageThread, Timeout, FALSE);
}
else
{
WaitStatus = WAIT_TIMEOUT;
}
if (WAIT_TIMEOUT == WaitStatus)
{
NotifyContext->WndClient = Wnd;
if (NULL == NotifyContext->UIThread && NotifyContext->ShowUI)
{
NotifyContext->UIThread = CreateThread(NULL, 0,
EndNowThreadProc,
(LPVOID) NotifyContext,
0, NULL);
}
Threads[0] = MessageThread;
Threads[1] = NotifyContext->UIThread;
WaitStatus = WaitForMultipleObjectsEx(NULL == NotifyContext->UIThread ?
1 : 2,
Threads, FALSE, INFINITE,
FALSE);
if (WAIT_OBJECT_0 == WaitStatus)
{
if (! GetExitCodeThread(MessageThread, &NotifyContext->QueryResult))
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
}
}
else if (WAIT_OBJECT_0 + 1 == WaitStatus)
{
if (! GetExitCodeThread(NotifyContext->UIThread,
&NotifyContext->QueryResult))
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
}
}
else
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
}
if (WAIT_OBJECT_0 != WaitStatus)
{
TerminateThread(MessageThread, QUERY_RESULT_TIMEOUT);
}
}
else if (WAIT_OBJECT_0 == WaitStatus)
{
if (! GetExitCodeThread(MessageThread,
&NotifyContext->QueryResult))
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
}
}
else
{
NotifyContext->QueryResult = QUERY_RESULT_ERROR;
}
CloseHandle(MessageThread);
}
else
{
NotifyContext->QueryResult = QUERY_RESULT_TIMEOUT;
}
}
return QUERY_RESULT_CONTINUE == NotifyContext->QueryResult;
}
static BOOL CALLBACK
NotifyDesktopEnum(LPWSTR DesktopName, LPARAM lParam)
{
PNOTIFY_CONTEXT Context = (PNOTIFY_CONTEXT) lParam;
Context->Desktop = OpenDesktopW(DesktopName, 0, FALSE,
DESKTOP_ENUMERATE | DESKTOP_SWITCHDESKTOP);
if (NULL == Context->Desktop)
{
DPRINT1("OpenDesktop failed with error %d\n", GetLastError());
Context->QueryResult = QUERY_RESULT_ERROR;
return FALSE;
}
Context->OldDesktop = GetThreadDesktop(GetCurrentThreadId());
SwitchDesktop(Context->Desktop);
EnumDesktopWindows(Context->Desktop, NotifyTopLevelEnum, lParam);
SwitchDesktop(Context->OldDesktop);
CloseDesktop(Context->Desktop);
return QUERY_RESULT_CONTINUE == Context->QueryResult;
}
static BOOL FASTCALL
NotifyTopLevelWindows(PNOTIFY_CONTEXT Context)
{
HWINSTA WindowStation;
WindowStation = GetProcessWindowStation();
if (NULL == WindowStation)
{
DPRINT1("GetProcessWindowStation failed with error %d\n", GetLastError());
return TRUE;
}
EnumDesktopsW(WindowStation, NotifyDesktopEnum, (LPARAM) Context);
return TRUE;
}
static BOOL FASTCALL
NotifyAndTerminateProcess(PCSR_PROCESS ProcessData,
PSHUTDOWN_SETTINGS ShutdownSettings,
UINT Flags)
{
NOTIFY_CONTEXT Context;
HANDLE Process;
DWORD QueryResult = QUERY_RESULT_CONTINUE;
Context.QueryResult = QUERY_RESULT_CONTINUE;
if (0 == (Flags & EWX_FORCE))
{
if (NULL != ProcessData->Console)
{
ConioConsoleCtrlEventTimeout(CTRL_LOGOFF_EVENT, ProcessData,
ShutdownSettings->WaitToKillAppTimeout);
}
else
{
Context.ProcessId = (DWORD_PTR) ProcessData->ClientId.UniqueProcess;
Context.wParam = 0;
Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ?
ENDSESSION_LOGOFF : 0);
Context.StartTime = 0;
Context.UIThread = NULL;
Context.ShowUI = DtbgIsDesktopVisible();
Context.Dlg = NULL;
Context.ShutdownSettings = ShutdownSettings;
Context.SendMessageProc = SendQueryEndSession;
NotifyTopLevelWindows(&Context);
Context.wParam = (QUERY_RESULT_ABORT != Context.QueryResult);
Context.lParam = (0 != (Flags & EWX_INTERNAL_FLAG_LOGOFF) ?
ENDSESSION_LOGOFF : 0);
Context.SendMessageProc = SendEndSession;
Context.ShowUI = DtbgIsDesktopVisible() &&
(QUERY_RESULT_ABORT != Context.QueryResult);
QueryResult = Context.QueryResult;
Context.QueryResult = QUERY_RESULT_CONTINUE;
NotifyTopLevelWindows(&Context);
if (NULL != Context.UIThread)
{
if (NULL != Context.Dlg)
{
SendMessageW(Context.Dlg, WM_CLOSE, 0, 0);
}
else
{
TerminateThread(Context.UIThread, QUERY_RESULT_ERROR);
}
CloseHandle(Context.UIThread);
}
}
if (QUERY_RESULT_ABORT == QueryResult)
{
return FALSE;
}
}
/* Terminate this process */
Process = OpenProcess(PROCESS_TERMINATE, FALSE,
(DWORD_PTR) ProcessData->ClientId.UniqueProcess);
if (NULL == Process)
{
DPRINT1("Unable to open process %d, error %d\n", ProcessData->ClientId.UniqueProcess,
GetLastError());
return TRUE;
}
TerminateProcess(Process, 0);
CloseHandle(Process);
return TRUE;
}
typedef struct tagPROCESS_ENUM_CONTEXT
{
UINT ProcessCount;
PCSR_PROCESS *ProcessData;
TOKEN_ORIGIN TokenOrigin;
DWORD ShellProcess;
DWORD CsrssProcess;
} PROCESS_ENUM_CONTEXT, *PPROCESS_ENUM_CONTEXT;
static NTSTATUS WINAPI
ExitReactosProcessEnum(PCSR_PROCESS ProcessData, PVOID Data)
{
HANDLE Process;
HANDLE Token;
TOKEN_ORIGIN Origin;
DWORD ReturnLength;
PPROCESS_ENUM_CONTEXT Context = (PPROCESS_ENUM_CONTEXT) Data;
PCSR_PROCESS *NewData;
/* Do not kill winlogon or csrss */
if ((DWORD_PTR) ProcessData->ClientId.UniqueProcess == Context->CsrssProcess ||
ProcessData->ClientId.UniqueProcess == LogonProcess)
{
return STATUS_SUCCESS;
}
/* Get the login session of this process */
Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
(DWORD_PTR) ProcessData->ClientId.UniqueProcess);
if (NULL == Process)
{
DPRINT1("Unable to open process %d, error %d\n", ProcessData->ClientId.UniqueProcess,
GetLastError());
return STATUS_UNSUCCESSFUL;
}
if (! OpenProcessToken(Process, TOKEN_QUERY, &Token))
{
DPRINT1("Unable to open token for process %d, error %d\n",
ProcessData->ClientId.UniqueProcess, GetLastError());
CloseHandle(Process);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(Process);
if (! GetTokenInformation(Token, TokenOrigin, &Origin,
sizeof(TOKEN_ORIGIN), &ReturnLength))
{
DPRINT1("GetTokenInformation failed for process %d with error %d\n",
ProcessData->ClientId.UniqueProcess, GetLastError());
CloseHandle(Token);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(Token);
/* This process will be killed if it's in the correct logon session */
if (RtlEqualLuid(&(Context->TokenOrigin.OriginatingLogonSession),
&(Origin.OriginatingLogonSession)))
{
/* Kill the shell process last */
if ((DWORD_PTR) ProcessData->ClientId.UniqueProcess == Context->ShellProcess)
{
ProcessData->ShutdownLevel = 0;
}
NewData = HeapAlloc(Win32CsrApiHeap, 0, (Context->ProcessCount + 1)
* sizeof(PCSR_PROCESS));
if (NULL == NewData)
{
return STATUS_NO_MEMORY;
}
if (0 != Context->ProcessCount)
{
memcpy(NewData, Context->ProcessData,
Context->ProcessCount * sizeof(PCSR_PROCESS));
HeapFree(Win32CsrApiHeap, 0, Context->ProcessData);
}
Context->ProcessData = NewData;
Context->ProcessData[Context->ProcessCount] = ProcessData;
Context->ProcessCount++;
}
return STATUS_SUCCESS;
}
static int
ProcessDataCompare(const void *Elem1, const void *Elem2)
{
const PCSR_PROCESS *ProcessData1 = (PCSR_PROCESS *) Elem1;
const PCSR_PROCESS *ProcessData2 = (PCSR_PROCESS *) Elem2;
if ((*ProcessData1)->ShutdownLevel < (*ProcessData2)->ShutdownLevel)
{
return +1;
}
else if ((*ProcessData2)->ShutdownLevel < (*ProcessData1)->ShutdownLevel)
{
return -1;
}
else if ((*ProcessData1)->ClientId.UniqueProcess < (*ProcessData2)->ClientId.UniqueProcess)
{
return +1;
}
else if ((*ProcessData2)->ClientId.UniqueProcess < (*ProcessData1)->ClientId.UniqueProcess)
{
return -1;
}
return 0;
}
static DWORD FASTCALL
GetShutdownSetting(HKEY DesktopKey, LPCWSTR ValueName, DWORD DefaultValue)
{
BYTE ValueBuffer[16];
LONG ErrCode;
DWORD Type;
DWORD ValueSize;
UNICODE_STRING StringValue;
ULONG Value;
ValueSize = sizeof(ValueBuffer);
ErrCode = RegQueryValueExW(DesktopKey, ValueName, NULL, &Type, ValueBuffer,
&ValueSize);
if (ERROR_SUCCESS != ErrCode)
{
DPRINT("GetShutdownSetting for %S failed with error code %ld\n",
ValueName, ErrCode);
return DefaultValue;
}
if (REG_SZ == Type)
{
RtlInitUnicodeString(&StringValue, (LPCWSTR) ValueBuffer);
if (! NT_SUCCESS(RtlUnicodeStringToInteger(&StringValue, 10, &Value)))
{
DPRINT1("Unable to convert value %S for setting %S\n",
StringValue.Buffer, ValueName);
return DefaultValue;
}
return (DWORD) Value;
}
else if (REG_DWORD == Type)
{
return *((DWORD *) ValueBuffer);
}
DPRINT1("Unexpected registry type %d for setting %S\n", Type, ValueName);
return DefaultValue;
}
static void FASTCALL
LoadShutdownSettings(PSID Sid, PSHUTDOWN_SETTINGS ShutdownSettings)
{
static WCHAR Subkey[] = L"\\Control Panel\\Desktop";
LPWSTR StringSid;
WCHAR InitialKeyName[128];
LPWSTR KeyName;
HKEY DesktopKey;
LONG ErrCode;
ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS;
ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT;
ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT;
if (! ConvertSidToStringSidW(Sid, &StringSid))
{
DPRINT1("ConvertSidToStringSid failed with error %d, using default shutdown settings\n",
GetLastError());
return;
}
if (wcslen(StringSid) + wcslen(Subkey) + 1 <=
sizeof(InitialKeyName) / sizeof(WCHAR))
{
KeyName = InitialKeyName;
}
else
{
KeyName = HeapAlloc(Win32CsrApiHeap, 0,
(wcslen(StringSid) + wcslen(Subkey) + 1) *
sizeof(WCHAR));
if (NULL == KeyName)
{
DPRINT1("Failed to allocate memory, using default shutdown settings\n");
LocalFree(StringSid);
return;
}
}
wcscat(wcscpy(KeyName, StringSid), Subkey);
LocalFree(StringSid);
ErrCode = RegOpenKeyExW(HKEY_USERS, KeyName, 0, KEY_QUERY_VALUE, &DesktopKey);
if (KeyName != InitialKeyName)
{
HeapFree(Win32CsrApiHeap, 0, KeyName);
}
if (ERROR_SUCCESS != ErrCode)
{
DPRINT1("RegOpenKeyEx failed with error %ld, using default shutdown settings\n", ErrCode);
return;
}
ShutdownSettings->AutoEndTasks = (BOOL) GetShutdownSetting(DesktopKey, L"AutoEndTasks",
(DWORD) DEFAULT_AUTO_END_TASKS);
ShutdownSettings->HungAppTimeout = GetShutdownSetting(DesktopKey,
L"HungAppTimeout",
DEFAULT_HUNG_APP_TIMEOUT);
ShutdownSettings->WaitToKillAppTimeout = GetShutdownSetting(DesktopKey,
L"WaitToKillAppTimeout",
DEFAULT_WAIT_TO_KILL_APP_TIMEOUT);
RegCloseKey(DesktopKey);
}
static NTSTATUS FASTCALL
InternalExitReactos(DWORD ProcessId, DWORD ThreadId, UINT Flags)
{
HANDLE CallerThread;
HANDLE CallerToken;
NTSTATUS Status;
PROCESS_ENUM_CONTEXT Context;
DWORD ReturnLength;
HWND ShellWnd;
UINT ProcessIndex;
char FixedUserInfo[64];
TOKEN_USER *UserInfo;
SHUTDOWN_SETTINGS ShutdownSettings;
if (ProcessId != (DWORD_PTR) LogonProcess)
{
DPRINT1("Internal ExitWindowsEx call not from winlogon\n");
return STATUS_ACCESS_DENIED;
}
DPRINT1("FIXME: Need to close all user processes!\n");
return STATUS_SUCCESS;
CallerThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ThreadId);
if (NULL == CallerThread)
{
DPRINT1("OpenThread failed with error %d\n", GetLastError());
return STATUS_UNSUCCESSFUL;
}
if (! OpenThreadToken(CallerThread, TOKEN_QUERY, FALSE, &CallerToken))
{
DPRINT1("OpenThreadToken failed with error %d\n", GetLastError());
CloseHandle(CallerThread);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(CallerThread);
Context.ProcessCount = 0;
Context.ProcessData = NULL;
if (! GetTokenInformation(CallerToken, TokenOrigin, &Context.TokenOrigin,
sizeof(TOKEN_ORIGIN), &ReturnLength))
{
DPRINT1("GetTokenInformation failed with error %d\n", GetLastError());
CloseHandle(CallerToken);
return STATUS_UNSUCCESSFUL;
}
if (! GetTokenInformation(CallerToken, TokenUser, FixedUserInfo,
sizeof(FixedUserInfo), &ReturnLength))
{
if (sizeof(FixedUserInfo) < ReturnLength)
{
UserInfo = HeapAlloc(Win32CsrApiHeap, 0, ReturnLength);
if (NULL == UserInfo)
{
DPRINT1("Unable to allocate %u bytes for user info\n",
(unsigned) ReturnLength);
CloseHandle(CallerToken);
return STATUS_NO_MEMORY;
}
if (! GetTokenInformation(CallerToken, TokenUser, UserInfo,
ReturnLength, &ReturnLength))
{
DPRINT1("GetTokenInformation failed with error %d\n",
GetLastError());
HeapFree(Win32CsrApiHeap, 0, UserInfo);
CloseHandle(CallerToken);
return STATUS_UNSUCCESSFUL;
}
}
else
{
DPRINT1("GetTokenInformation failed with error %d\n", GetLastError());
CloseHandle(CallerToken);
return STATUS_UNSUCCESSFUL;
}
}
else
{
UserInfo = (TOKEN_USER *) FixedUserInfo;
}
CloseHandle(CallerToken);
LoadShutdownSettings(UserInfo->User.Sid, &ShutdownSettings);
if (UserInfo != (TOKEN_USER *) FixedUserInfo)
{
HeapFree(Win32CsrApiHeap, 0, UserInfo);
}
Context.CsrssProcess = GetCurrentProcessId();
ShellWnd = GetShellWindow();
if (NULL == ShellWnd)
{
DPRINT("No shell present\n");
Context.ShellProcess = 0;
}
else if (0 == GetWindowThreadProcessId(ShellWnd, &Context.ShellProcess))
{
DPRINT1("Can't get process id of shell window\n");
Context.ShellProcess = 0;
}
Status = Win32CsrEnumProcesses(ExitReactosProcessEnum, &Context);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to enumerate registered processes, status 0x%x\n",
Status);
if (NULL != Context.ProcessData)
{
HeapFree(Win32CsrApiHeap, 0, Context.ProcessData);
}
return Status;
}
qsort(Context.ProcessData, Context.ProcessCount, sizeof(PCSR_PROCESS),
ProcessDataCompare);
/* Terminate processes, stop if we find one kicking and screaming it doesn't
want to die */
Status = STATUS_SUCCESS;
for (ProcessIndex = 0;
ProcessIndex < Context.ProcessCount && NT_SUCCESS(Status);
ProcessIndex++)
{
if (! NotifyAndTerminateProcess(Context.ProcessData[ProcessIndex],
&ShutdownSettings, Flags))
{
Status = STATUS_REQUEST_ABORTED;
}
}
/* Cleanup */
if (NULL != Context.ProcessData)
{
HeapFree(Win32CsrApiHeap, 0, Context.ProcessData);
}
return Status;
}
static NTSTATUS FASTCALL
UserExitReactos(DWORD UserProcessId, UINT Flags)
{
NTSTATUS Status;
/* FIXME Inside 2000 says we should impersonate the caller here */
Status = NtUserCallTwoParam (UserProcessId, Flags, TWOPARAM_ROUTINE_EXITREACTOS);
/* If the message isn't handled, the return value is 0, so 0 doesn't indicate
success. Success is indicated by a 1 return value, if anything besides 0
or 1 it's a NTSTATUS value */
if (1 == Status)
{
Status = STATUS_SUCCESS;
}
else if (0 == Status)
{
Status = STATUS_NOT_IMPLEMENTED;
}
return Status;
}
CSR_API(CsrExitReactos)
{
if (0 == (Request->Data.ExitReactosRequest.Flags & EWX_INTERNAL_FLAG))
{
return UserExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess,
Request->Data.ExitReactosRequest.Flags);
}
else
{
return InternalExitReactos((DWORD_PTR) Request->Header.ClientId.UniqueProcess,
(DWORD_PTR) Request->Header.ClientId.UniqueThread,
Request->Data.ExitReactosRequest.Flags);
}
}
/* EOF */
+586
View File
@@ -0,0 +1,586 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/file.c
* PURPOSE: File handling
* PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
* NOTE: Belongs to basesrv.dll
*/
/* INCLUDES ******************************************************************/
#include <w32csr.h>
#define NDEBUG
#include <debug.h>
#include "file.h"
/* GLOBALS *******************************************************************/
typedef BOOL (WINAPI *PUSER_SOUND_SENTRY)(VOID);
BOOL
WINAPI
FirstSoundSentry(VOID);
UINT CsrGetTempFileUnique;
LIST_ENTRY DosDeviceHistory;
RTL_CRITICAL_SECTION Win32CsrDefineDosDeviceCritSec;
PUSER_SOUND_SENTRY _UserSoundSentry = FirstSoundSentry;
/* FUNCTIONS *****************************************************************/
BOOL
WINAPI
FailSoundSentry(VOID)
{
/* In case the function can't be found/is unimplemented */
return FALSE;
}
BOOL
WINAPI
FirstSoundSentry(VOID)
{
UNICODE_STRING DllString = RTL_CONSTANT_STRING(L"winsrv");
STRING FuncString = RTL_CONSTANT_STRING("_UserSoundSentry");
HANDLE DllHandle;
NTSTATUS Status;
PUSER_SOUND_SENTRY NewSoundSentry = FailSoundSentry;
/* Load winsrv manually */
Status = LdrGetDllHandle(NULL, NULL, &DllString, &DllHandle);
if (NT_SUCCESS(Status))
{
/* If it was found, get SoundSentry export */
Status = LdrGetProcedureAddress(DllHandle,
&FuncString,
0,
(PVOID*)&NewSoundSentry);
}
/* Set it as the callback for the future, and call it */
_UserSoundSentry = NewSoundSentry;
return _UserSoundSentry();
}
CSR_API(CsrSoundSentry)
{
/* Call the API and see if it suceeds */
return _UserSoundSentry() ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
}
CSR_API(CsrGetTempFile)
{
DPRINT("CsrGetTempFile entered\n");
/* Return 16-bits ID */
Request->Data.GetTempFile.UniqueID = (++CsrGetTempFileUnique & 0xFFFF);
DPRINT("Returning: %u\n", Request->Data.GetTempFile.UniqueID);
return STATUS_SUCCESS;
}
CSR_API(CsrDefineDosDevice)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE LinkHandle = NULL;
NTSTATUS Status;
UNICODE_STRING DeviceName = {0};
UNICODE_STRING RequestDeviceName = {0};
UNICODE_STRING LinkTarget = {0};
PUNICODE_STRING RequestLinkTarget;
ULONG Length;
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
PSECURITY_DESCRIPTOR SecurityDescriptor;
PACL Dacl;
PSID AdminSid;
PSID SystemSid;
PSID WorldSid;
ULONG SidLength;
PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
PLIST_ENTRY Entry;
PLIST_ENTRY ListHead;
BOOLEAN Matched, AddHistory;
DWORD dwFlags;
PWSTR lpBuffer;
DPRINT("CsrDefineDosDevice entered, Flags:%d, DeviceName:%wZ, TargetName:%wZ\n",
Request->Data.DefineDosDeviceRequest.dwFlags,
&Request->Data.DefineDosDeviceRequest.DeviceName,
&Request->Data.DefineDosDeviceRequest.TargetName);
Matched = AddHistory = FALSE;
HistoryEntry = NULL;
AdminSid = SystemSid = WorldSid = NULL;
SecurityDescriptor = NULL;
ListHead = &DosDeviceHistory;
dwFlags = Request->Data.DefineDosDeviceRequest.dwFlags;
/* Validate the flags */
if ( (dwFlags & 0xFFFFFFF0) ||
((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) &&
! (dwFlags & DDD_REMOVE_DEFINITION)) )
{
return STATUS_INVALID_PARAMETER;
}
Status = RtlEnterCriticalSection(&Win32CsrDefineDosDeviceCritSec);
if (! NT_SUCCESS(Status))
{
DPRINT1("RtlEnterCriticalSection() failed (Status %lx)\n",
Status);
return Status;
}
_SEH2_TRY
{
Status =
RtlUpcaseUnicodeString(&RequestDeviceName,
&Request->Data.DefineDosDeviceRequest.DeviceName,
TRUE);
if (! NT_SUCCESS(Status))
_SEH2_LEAVE;
RequestLinkTarget =
&Request->Data.DefineDosDeviceRequest.TargetName;
lpBuffer = (PWSTR) RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR));
if (! lpBuffer)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
swprintf(lpBuffer,
L"\\??\\%wZ",
&RequestDeviceName);
RtlInitUnicodeString(&DeviceName,
lpBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenSymbolicLinkObject(&LinkHandle,
DELETE | 0x1,
&ObjectAttributes);
if (NT_SUCCESS(Status))
{
Status = NtQuerySymbolicLinkObject(LinkHandle,
&LinkTarget,
&Length);
if (! NT_SUCCESS(Status) &&
Status == STATUS_BUFFER_TOO_SMALL)
{
LinkTarget.Length = 0;
LinkTarget.MaximumLength = Length;
LinkTarget.Buffer = (PWSTR)
RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
Length);
if (! LinkTarget.Buffer)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
Status = NtQuerySymbolicLinkObject(LinkHandle,
&LinkTarget,
&Length);
}
if (! NT_SUCCESS(Status))
{
DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed (Status %lx)\n",
&DeviceName, Status);
_SEH2_LEAVE;
}
if ((dwFlags & DDD_REMOVE_DEFINITION))
{
/* If no target name specified we remove the current symlink target */
if (RequestLinkTarget->Length == 0)
Matched = TRUE;
else
{
if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
Matched = ! RtlCompareUnicodeString(RequestLinkTarget,
&LinkTarget,
TRUE);
else
Matched = RtlPrefixUnicodeString(RequestLinkTarget,
&LinkTarget,
TRUE);
}
if (Matched && IsListEmpty(ListHead))
{
/* Current symlink target macthed and there is nothing to revert to */
RequestLinkTarget = NULL;
}
else if (Matched && ! IsListEmpty(ListHead))
{
/* Fetch the first history entry we come across for the device name */
/* This will become the current symlink target for the device name */
Matched = FALSE;
Entry = ListHead->Flink;
while (Entry != ListHead)
{
HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
CONTAINING_RECORD(Entry,
CSRSS_DOS_DEVICE_HISTORY_ENTRY,
Entry);
Matched =
! RtlCompareUnicodeString(&RequestDeviceName,
&HistoryEntry->Device,
FALSE);
if (Matched)
{
RemoveEntryList(&HistoryEntry->Entry);
RequestLinkTarget = &HistoryEntry->Target;
break;
}
Entry = Entry->Flink;
HistoryEntry = NULL;
}
/* Nothing to revert to so delete the symlink */
if (! Matched)
RequestLinkTarget = NULL;
}
else if (! Matched)
{
/* Locate a previous symlink target as we did not get a hit earlier */
/* If we find one we need to remove it */
Entry = ListHead->Flink;
while (Entry != ListHead)
{
HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
CONTAINING_RECORD(Entry,
CSRSS_DOS_DEVICE_HISTORY_ENTRY,
Entry);
Matched =
! RtlCompareUnicodeString(&RequestDeviceName,
&HistoryEntry->Device,
FALSE);
if (! Matched)
{
HistoryEntry = NULL;
Entry = Entry->Flink;
continue;
}
Matched = FALSE;
if (dwFlags & DDD_EXACT_MATCH_ON_REMOVE)
{
if (! RtlCompareUnicodeString(RequestLinkTarget,
&HistoryEntry->Target,
TRUE))
{
Matched = TRUE;
}
}
else if (RtlPrefixUnicodeString(RequestLinkTarget,
&HistoryEntry->Target,
TRUE))
{
Matched = TRUE;
}
if (Matched)
{
RemoveEntryList(&HistoryEntry->Entry);
break;
}
Entry = Entry->Flink;
HistoryEntry = NULL;
}
/* Leave existing symlink as is */
if (! Matched)
Status = STATUS_OBJECT_NAME_NOT_FOUND;
else
Status = STATUS_SUCCESS;
_SEH2_LEAVE;
}
}
else
{
AddHistory = TRUE;
}
Status = NtMakeTemporaryObject(LinkHandle);
if (! NT_SUCCESS(Status))
{
DPRINT1("NtMakeTemporaryObject(%wZ) failed (Status %lx)\n",
&DeviceName, Status);
_SEH2_LEAVE;
}
Status = NtClose(LinkHandle);
LinkHandle = NULL;
if (! NT_SUCCESS(Status))
{
DPRINT1("NtClose(%wZ) failed (Status %lx)\n",
&DeviceName, Status);
_SEH2_LEAVE;
}
}
/* Don't create symlink if we don't have a target */
if (! RequestLinkTarget || RequestLinkTarget->Length == 0)
_SEH2_LEAVE;
if (AddHistory)
{
HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
sizeof(CSRSS_DOS_DEVICE_HISTORY_ENTRY));
if (! HistoryEntry)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
HistoryEntry->Target.Buffer =
RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
LinkTarget.Length);
if (! HistoryEntry->Target.Buffer)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
HistoryEntry->Target.Length =
HistoryEntry->Target.MaximumLength =
LinkTarget.Length;
RtlCopyUnicodeString(&HistoryEntry->Target,
&LinkTarget);
HistoryEntry->Device.Buffer =
RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
RequestDeviceName.Length);
if (! HistoryEntry->Device.Buffer)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
HistoryEntry->Device.Length =
HistoryEntry->Device.MaximumLength =
RequestDeviceName.Length;
RtlCopyUnicodeString(&HistoryEntry->Device,
&RequestDeviceName);
/* Remember previous symlink target for this device */
InsertHeadList(ListHead,
&HistoryEntry->Entry);
HistoryEntry = NULL;
}
RtlAllocateAndInitializeSid(&WorldAuthority,
1,
SECURITY_WORLD_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
&WorldSid);
RtlAllocateAndInitializeSid(&SystemAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
&SystemSid);
RtlAllocateAndInitializeSid(&SystemAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
SECURITY_NULL_RID,
&AdminSid);
SidLength = RtlLengthSid(SystemSid) +
RtlLengthSid(AdminSid) +
RtlLengthSid(WorldSid);
Length = sizeof(ACL) + SidLength + 3 * sizeof(ACCESS_ALLOWED_ACE);
SecurityDescriptor = RtlAllocateHeap(Win32CsrApiHeap,
0,
SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
if (! SecurityDescriptor)
{
DPRINT1("Failed to allocate memory\n");
Status = STATUS_NO_MEMORY;
_SEH2_LEAVE;
}
Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
if (! NT_SUCCESS(Status))
{
DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n",
Status);
_SEH2_LEAVE;
}
Status = RtlCreateAcl(Dacl,
Length,
ACL_REVISION);
if (! NT_SUCCESS(Status))
{
DPRINT1("RtlCreateAcl() failed (Status %lx)\n",
Status);
_SEH2_LEAVE;
}
(void) RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_ALL,
SystemSid);
(void) RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_ALL,
AdminSid);
(void) RtlAddAccessAllowedAce(Dacl,
ACL_REVISION,
STANDARD_RIGHTS_READ,
WorldSid);
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
TRUE,
Dacl,
FALSE);
if (! NT_SUCCESS(Status))
{
DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n",
Status);
_SEH2_LEAVE;
}
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
OBJ_CASE_INSENSITIVE,
NULL,
SecurityDescriptor);
Status = NtCreateSymbolicLinkObject(&LinkHandle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
RequestLinkTarget);
if (NT_SUCCESS(Status))
{
Status = NtMakePermanentObject(LinkHandle);
if (! NT_SUCCESS(Status))
{
DPRINT1("NtMakePermanentObject(%wZ) failed (Status %lx)\n",
&DeviceName, Status);
}
}
else
{
DPRINT1("NtCreateSymbolicLinkObject(%wZ) failed (Status %lx)\n",
&DeviceName, Status);
}
}
_SEH2_FINALLY
{
(void) RtlLeaveCriticalSection(&Win32CsrDefineDosDeviceCritSec);
if (DeviceName.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
DeviceName.Buffer);
if (LinkTarget.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
LinkTarget.Buffer);
if (SecurityDescriptor)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
SecurityDescriptor);
if (LinkHandle)
(void) NtClose(LinkHandle);
if (SystemSid)
(void) RtlFreeSid(SystemSid);
if (AdminSid)
(void) RtlFreeSid(AdminSid);
if (WorldSid)
(void) RtlFreeSid(WorldSid);
RtlFreeUnicodeString(&RequestDeviceName);
if (HistoryEntry)
{
if (HistoryEntry->Target.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry->Target.Buffer);
if (HistoryEntry->Device.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry->Device.Buffer);
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry);
}
}
_SEH2_END
DPRINT("CsrDefineDosDevice Exit, Statux: 0x%x\n", Status);
return Status;
}
void CsrCleanupDefineDosDevice(void)
{
PLIST_ENTRY Entry, ListHead;
PCSRSS_DOS_DEVICE_HISTORY_ENTRY HistoryEntry;
(void) RtlDeleteCriticalSection(&Win32CsrDefineDosDeviceCritSec);
ListHead = &DosDeviceHistory;
Entry = ListHead->Flink;
while (Entry != ListHead)
{
HistoryEntry = (PCSRSS_DOS_DEVICE_HISTORY_ENTRY)
CONTAINING_RECORD(Entry,
CSRSS_DOS_DEVICE_HISTORY_ENTRY,
Entry);
Entry = Entry->Flink;
if (HistoryEntry)
{
if (HistoryEntry->Target.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry->Target.Buffer);
if (HistoryEntry->Device.Buffer)
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry->Device.Buffer);
(void) RtlFreeHeap(Win32CsrApiHeap,
0,
HistoryEntry);
}
}
}
/* EOF */
+28
View File
@@ -0,0 +1,28 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsystem/win32/csrss/win32csr/file.h
* PURPOSE: File handling
* PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
* NOTE: Belongs to basesrv.dll
*/
#pragma once
#include "api.h"
typedef struct tagCSRSS_DOS_DEVICE_HISTORY_ENTRY
{
UNICODE_STRING Device;
UNICODE_STRING Target;
LIST_ENTRY Entry;
} CSRSS_DOS_DEVICE_HISTORY_ENTRY, *PCSRSS_DOS_DEVICE_HISTORY_ENTRY;
/* Api functions */
CSR_API(CsrGetTempFile);
CSR_API(CsrDefineDosDevice);
/* functions */
void CsrCleanupDefineDosDevice();
/* EOF */
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/guiconsole.h
* PURPOSE: Interface to GUI consoles
*/
#include "api.h"
#define CONGUI_MIN_WIDTH 10
#define CONGUI_MIN_HEIGHT 10
#define CONGUI_UPDATE_TIME 0
#define CONGUI_UPDATE_TIMER 1
NTSTATUS FASTCALL GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible);
VOID FASTCALL GuiConsoleHandleScrollbarMenu(VOID);
/*EOF*/
+381
View File
@@ -0,0 +1,381 @@
/*
* reactos/subsys/csrss/api/handle.c
*
* CSRSS handle functions
*
* ReactOS Operating System
*/
/* INCLUDES ******************************************************************/
#include <w32csr.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
static
BOOL
CsrIsConsoleHandle(HANDLE Handle)
{
return ((ULONG_PTR)Handle & 0x10000003) == 0x3;
}
static INT
AdjustHandleCounts(PCSRSS_HANDLE Entry, INT Change)
{
Object_t *Object = Entry->Object;
if (Entry->Access & GENERIC_READ) Object->AccessRead += Change;
if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change;
if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change;
if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change;
Object->HandleCount += Change;
return Object->HandleCount;
}
static VOID
Win32CsrCreateHandleEntry(
PCSRSS_HANDLE Entry)
{
Object_t *Object = Entry->Object;
EnterCriticalSection(&Object->Console->Lock);
AdjustHandleCounts(Entry, +1);
LeaveCriticalSection(&Object->Console->Lock);
}
static VOID
Win32CsrCloseHandleEntry(
PCSRSS_HANDLE Entry)
{
Object_t *Object = Entry->Object;
if (Object != NULL)
{
PCSRSS_CONSOLE Console = Object->Console;
EnterCriticalSection(&Console->Lock);
/* If the last handle to a screen buffer is closed, delete it */
if (AdjustHandleCounts(Entry, -1) == 0
&& Object->Type == CONIO_SCREEN_BUFFER_MAGIC)
{
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER)Object;
/* ...unless it's the only buffer left. Windows allows deletion
* even of the last buffer, but having to deal with a lack of
* any active buffer might be error-prone. */
if (Buffer->ListEntry.Flink != Buffer->ListEntry.Blink)
ConioDeleteScreenBuffer(Buffer);
}
LeaveCriticalSection(&Console->Lock);
Entry->Object = NULL;
}
}
NTSTATUS
FASTCALL
Win32CsrReleaseObject(
PCSR_PROCESS ProcessData,
HANDLE Handle)
{
ULONG_PTR h = (ULONG_PTR)Handle >> 2;
Object_t *Object;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (h >= ProcessData->HandleTableSize
|| (Object = ProcessData->HandleTable[h].Object) == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[h]);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_SUCCESS;
}
NTSTATUS
FASTCALL
Win32CsrLockObject(PCSR_PROCESS ProcessData,
HANDLE Handle,
Object_t **Object,
DWORD Access,
LONG Type)
{
ULONG_PTR h = (ULONG_PTR)Handle >> 2;
DPRINT("CsrGetObject, Object: %x, %x, %x\n",
Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0);
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (!CsrIsConsoleHandle(Handle) || h >= ProcessData->HandleTableSize
|| (*Object = ProcessData->HandleTable[h].Object) == NULL
|| ~ProcessData->HandleTable[h].Access & Access
|| (Type != 0 && (*Object)->Type != Type))
{
DPRINT1("CsrGetObject returning invalid handle (%x)\n", Handle);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
_InterlockedIncrement(&(*Object)->Console->ReferenceCount);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
EnterCriticalSection(&((*Object)->Console->Lock));
return STATUS_SUCCESS;
}
VOID
FASTCALL
Win32CsrUnlockObject(Object_t *Object)
{
PCSRSS_CONSOLE Console = Object->Console;
LeaveCriticalSection(&Console->Lock);
/* dec ref count */
if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
ConioDeleteConsole(&Console->Header);
}
VOID
WINAPI
Win32CsrReleaseConsole(
PCSR_PROCESS ProcessData)
{
PCSRSS_CONSOLE Console;
ULONG i;
/* Close all console handles and detach process from console */
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
Win32CsrCloseHandleEntry(&ProcessData->HandleTable[i]);
ProcessData->HandleTableSize = 0;
RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = NULL;
Console = ProcessData->Console;
if (Console != NULL)
{
ProcessData->Console = NULL;
EnterCriticalSection(&Console->Lock);
RemoveEntryList(&ProcessData->ConsoleLink);
LeaveCriticalSection(&Console->Lock);
if (_InterlockedDecrement(&Console->ReferenceCount) == 0)
ConioDeleteConsole(&Console->Header);
//CloseHandle(ProcessData->ConsoleEvent);
//ProcessData->ConsoleEvent = NULL;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
}
NTSTATUS
FASTCALL
Win32CsrInsertObject(
PCSR_PROCESS ProcessData,
PHANDLE Handle,
Object_t *Object,
DWORD Access,
BOOL Inheritable,
DWORD ShareMode)
{
ULONG i;
PCSRSS_HANDLE Block;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
for (i = 0; i < ProcessData->HandleTableSize; i++)
{
if (ProcessData->HandleTable[i].Object == NULL)
{
break;
}
}
if (i >= ProcessData->HandleTableSize)
{
Block = RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
(ProcessData->HandleTableSize + 64) * sizeof(CSRSS_HANDLE));
if (Block == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_UNSUCCESSFUL);
}
RtlCopyMemory(Block,
ProcessData->HandleTable,
ProcessData->HandleTableSize * sizeof(CSRSS_HANDLE));
RtlFreeHeap(Win32CsrApiHeap, 0, ProcessData->HandleTable);
ProcessData->HandleTable = Block;
ProcessData->HandleTableSize += 64;
}
ProcessData->HandleTable[i].Object = Object;
ProcessData->HandleTable[i].Access = Access;
ProcessData->HandleTable[i].Inheritable = Inheritable;
ProcessData->HandleTable[i].ShareMode = ShareMode;
Win32CsrCreateHandleEntry(&ProcessData->HandleTable[i]);
*Handle = UlongToHandle((i << 2) | 0x3);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return(STATUS_SUCCESS);
}
NTSTATUS
WINAPI
Win32CsrDuplicateHandleTable(
PCSR_PROCESS SourceProcessData,
PCSR_PROCESS TargetProcessData)
{
ULONG i;
/* Only inherit if the flag was set */
if (!TargetProcessData->bInheritHandles) return STATUS_SUCCESS;
if (TargetProcessData->HandleTableSize)
{
return STATUS_INVALID_PARAMETER;
}
RtlEnterCriticalSection(&SourceProcessData->HandleTableLock);
/* we are called from CreateProcessData, it isn't necessary to lock the target process data */
TargetProcessData->HandleTable = RtlAllocateHeap(Win32CsrApiHeap,
HEAP_ZERO_MEMORY,
SourceProcessData->HandleTableSize
* sizeof(CSRSS_HANDLE));
if (TargetProcessData->HandleTable == NULL)
{
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
return(STATUS_UNSUCCESSFUL);
}
TargetProcessData->HandleTableSize = SourceProcessData->HandleTableSize;
for (i = 0; i < SourceProcessData->HandleTableSize; i++)
{
if (SourceProcessData->HandleTable[i].Object != NULL &&
SourceProcessData->HandleTable[i].Inheritable)
{
TargetProcessData->HandleTable[i] = SourceProcessData->HandleTable[i];
Win32CsrCreateHandleEntry(&TargetProcessData->HandleTable[i]);
}
}
RtlLeaveCriticalSection(&SourceProcessData->HandleTableLock);
return(STATUS_SUCCESS);
}
CSR_API(CsrGetHandle)
{
NTSTATUS Status = STATUS_SUCCESS;
Request->Data.GetInputHandleRequest.Handle = INVALID_HANDLE_VALUE;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (ProcessData->Console)
{
DWORD DesiredAccess = Request->Data.GetInputHandleRequest.Access;
DWORD ShareMode = Request->Data.GetInputHandleRequest.ShareMode;
PCSRSS_CONSOLE Console = ProcessData->Console;
Object_t *Object;
EnterCriticalSection(&Console->Lock);
if (Request->Type == GET_OUTPUT_HANDLE)
Object = &Console->ActiveBuffer->Header;
else
Object = &Console->Header;
if (((DesiredAccess & GENERIC_READ) && Object->ExclusiveRead != 0) ||
((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) ||
(!(ShareMode & FILE_SHARE_READ) && Object->AccessRead != 0) ||
(!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite != 0))
{
DPRINT1("Sharing violation\n");
Status = STATUS_SHARING_VIOLATION;
}
else
{
Status = Win32CsrInsertObject(ProcessData,
&Request->Data.GetInputHandleRequest.Handle,
Object,
DesiredAccess,
Request->Data.GetInputHandleRequest.Inheritable,
ShareMode);
}
LeaveCriticalSection(&Console->Lock);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
CSR_API(CsrCloseHandle)
{
return Win32CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle);
}
CSR_API(CsrVerifyHandle)
{
ULONG_PTR Index;
NTSTATUS Status = STATUS_SUCCESS;
Index = (ULONG_PTR)Request->Data.VerifyHandleRequest.Handle >> 2;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (Index >= ProcessData->HandleTableSize ||
ProcessData->HandleTable[Index].Object == NULL)
{
DPRINT("CsrVerifyObject failed\n");
Status = STATUS_INVALID_HANDLE;
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Status;
}
CSR_API(CsrDuplicateHandle)
{
ULONG_PTR Index;
PCSRSS_HANDLE Entry;
DWORD DesiredAccess;
Index = (ULONG_PTR)Request->Data.DuplicateHandleRequest.Handle >> 2;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
if (Index >= ProcessData->HandleTableSize
|| (Entry = &ProcessData->HandleTable[Index])->Object == NULL)
{
DPRINT1("Couldn't dup invalid handle %p\n", Request->Data.DuplicateHandleRequest.Handle);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
if (Request->Data.DuplicateHandleRequest.Options & DUPLICATE_SAME_ACCESS)
{
DesiredAccess = Entry->Access;
}
else
{
DesiredAccess = Request->Data.DuplicateHandleRequest.Access;
/* Make sure the source handle has all the desired flags */
if (~Entry->Access & DesiredAccess)
{
DPRINT1("Handle %p only has access %X; requested %X\n",
Request->Data.DuplicateHandleRequest.Handle, Entry->Access, DesiredAccess);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_PARAMETER;
}
}
Request->Status = Win32CsrInsertObject(ProcessData,
&Request->Data.DuplicateHandleRequest.Handle,
Entry->Object,
DesiredAccess,
Request->Data.DuplicateHandleRequest.Inheritable,
Entry->ShareMode);
if (NT_SUCCESS(Request->Status)
&& Request->Data.DuplicateHandleRequest.Options & DUPLICATE_CLOSE_SOURCE)
{
Win32CsrCloseHandleEntry(Entry);
}
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return Request->Status;
}
CSR_API(CsrGetInputWaitHandle)
{
Request->Data.GetConsoleInputWaitHandle.InputWaitHandle = ProcessData->ConsoleEvent;
return STATUS_SUCCESS;
}
/* EOF */
+578
View File
@@ -0,0 +1,578 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/dllmain.c
* PURPOSE: Initialization
* PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
* Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
#include <strsafe.h>
#define IDTRYAGAIN 10
#define IDCONTINUE 11
/* FUNCTIONS *****************************************************************/
static
NTSTATUS
CsrpGetClientFileName(
OUT PUNICODE_STRING ClientFileNameU,
HANDLE hProcess)
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_DATA_TABLE_ENTRY Module;
PPEB_LDR_DATA Ldr;
PROCESS_BASIC_INFORMATION ClientBasicInfo;
LDR_DATA_TABLE_ENTRY ModuleData;
PVOID ClientDllBase;
NTSTATUS Status;
PPEB Peb;
/* Initialize string */
ClientFileNameU->MaximumLength = 0;
ClientFileNameU->Length = 0;
ClientFileNameU->Buffer = NULL;
/* Query process information */
Status = NtQueryInformationProcess(hProcess,
ProcessBasicInformation,
&ClientBasicInfo,
sizeof(ClientBasicInfo),
NULL);
if (!NT_SUCCESS(Status)) return Status;
Peb = ClientBasicInfo.PebBaseAddress;
if (!Peb) return STATUS_UNSUCCESSFUL;
Status = NtReadVirtualMemory(hProcess, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL);
if (!NT_SUCCESS(Status)) return Status;
ModuleListHead = &Ldr->InLoadOrderModuleList;
Status = NtReadVirtualMemory(hProcess,
&ModuleListHead->Flink,
&Entry,
sizeof(Entry),
NULL);
if (!NT_SUCCESS(Status)) return Status;
if (Entry == ModuleListHead) return STATUS_UNSUCCESSFUL;
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
Status = NtReadVirtualMemory(hProcess,
Module,
&ModuleData,
sizeof(ModuleData),
NULL);
if (!NT_SUCCESS(Status)) return Status;
Status = NtReadVirtualMemory(hProcess,
&Peb->ImageBaseAddress,
&ClientDllBase,
sizeof(ClientDllBase),
NULL);
if (!NT_SUCCESS(Status)) return Status;
if (ClientDllBase != ModuleData.DllBase) return STATUS_UNSUCCESSFUL;
ClientFileNameU->MaximumLength = ModuleData.BaseDllName.MaximumLength;
ClientFileNameU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
ClientFileNameU->MaximumLength);
Status = NtReadVirtualMemory(hProcess,
ModuleData.BaseDllName.Buffer,
ClientFileNameU->Buffer,
ClientFileNameU->MaximumLength,
NULL);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, ClientFileNameU->Buffer);
ClientFileNameU->Buffer = NULL;
ClientFileNameU->MaximumLength = 0;
return Status;
}
ClientFileNameU->Length = wcslen(ClientFileNameU->Buffer)*sizeof(wchar_t);
DPRINT("ClientFileNameU=\'%wZ\'\n", &ClientFileNameU);
return STATUS_SUCCESS;
}
static
VOID
CsrpFreeStringParameters(
IN OUT PULONG_PTR Parameters,
IN PHARDERROR_MSG HardErrorMessage)
{
ULONG nParam;
/* Loop all parameters */
for (nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++)
{
/* Check if the current parameter is a string */
if (HardErrorMessage->UnicodeStringParameterMask & (1 << nParam) && Parameters[nParam])
{
/* Free the string buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, (PVOID)Parameters[nParam]);
}
}
}
static
NTSTATUS
CsrpCaptureStringParameters(
OUT PULONG_PTR Parameters,
OUT PULONG SizeOfAllUnicodeStrings,
IN PHARDERROR_MSG HardErrorMessage,
HANDLE hProcess)
{
ULONG nParam, Size = 0;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING TempStringU, ParamStringU;
ANSI_STRING TempStringA;
/* Read all strings from client space */
for (nParam = 0; nParam < HardErrorMessage->NumberOfParameters; nParam++)
{
Parameters[nParam] = 0;
/* Check if the current parameter is a unicode string */
if (HardErrorMessage->UnicodeStringParameterMask & (1 << nParam))
{
/* Read the UNICODE_STRING from the process memory */
Status = NtReadVirtualMemory(hProcess,
(PVOID)HardErrorMessage->Parameters[nParam],
&ParamStringU,
sizeof(ParamStringU),
NULL);
if (!NT_SUCCESS(Status))
break;
/* Allocate a buffer for the string */
TempStringU.MaximumLength = ParamStringU.Length;
TempStringU.Length = ParamStringU.Length;
TempStringU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
TempStringU.MaximumLength);
if (!TempStringU.Buffer)
{
DPRINT1("Cannot allocate memory %u\n", TempStringU.MaximumLength);
Status = STATUS_NO_MEMORY;
}
/* Read the string buffer from the process memory */
Status = NtReadVirtualMemory(hProcess,
ParamStringU.Buffer,
TempStringU.Buffer,
ParamStringU.Length,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtReadVirtualMemory failed with code: %lx\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
break;
}
DPRINT("ParamString=\'%wZ\'\n", &TempStringU);
/* Allocate a buffer for converted to ANSI string */
TempStringA.MaximumLength = RtlUnicodeStringToAnsiSize(&TempStringU);
TempStringA.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
TempStringA.MaximumLength);
if (!TempStringA.Buffer)
{
DPRINT1("Cannot allocate memory %u\n", TempStringA.MaximumLength);
RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
Status = STATUS_NO_MEMORY;
break;
}
/* Convert string to ANSI and free temporary buffer */
Status = RtlUnicodeStringToAnsiString(&TempStringA, &TempStringU, FALSE);
RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringU.Buffer);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(RtlGetProcessHeap(), 0, TempStringA.Buffer);
break;
}
/* Note: RtlUnicodeStringToAnsiString returns NULL terminated string */
Parameters[nParam] = (ULONG_PTR)TempStringA.Buffer;
Size += TempStringU.Length;
}
else
{
/* It's not a unicode string */
Parameters[nParam] = HardErrorMessage->Parameters[nParam];
}
}
if (!NT_SUCCESS(Status))
{
CsrpFreeStringParameters(Parameters, HardErrorMessage);
return Status;
}
*SizeOfAllUnicodeStrings = Size;
return Status;
}
static
NTSTATUS
CsrpFormatMessages(
OUT PUNICODE_STRING TextStringU,
OUT PUNICODE_STRING CaptionStringU,
IN PULONG_PTR Parameters,
IN ULONG SizeOfStrings,
IN PHARDERROR_MSG Message,
IN HANDLE hProcess)
{
NTSTATUS Status;
UNICODE_STRING FileNameU, TempStringU, FormatU;
ANSI_STRING FormatA;
PMESSAGE_RESOURCE_ENTRY MessageResource;
PWSTR FormatString;
ULONG Size, ExceptionCode;
/* Get the file name of the client process */
CsrpGetClientFileName(&FileNameU, hProcess);
/* Check if we have a file name */
if (!FileNameU.Buffer)
{
/* No, use system */
RtlInitUnicodeString(&FileNameU, L"System");
}
/* Get text string of the error code */
Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
(ULONG_PTR)RT_MESSAGETABLE,
LANG_NEUTRAL,
Message->Status,
&MessageResource);
if (NT_SUCCESS(Status))
{
if (MessageResource->Flags)
{
RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
FormatA.Buffer = NULL;
}
else
{
RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
}
}
else
{
/* Fall back to hardcoded value */
RtlInitUnicodeString(&FormatU, L"Unknown Hard Error");
FormatA.Buffer = NULL;
}
FormatString = FormatU.Buffer;
/* Check whether a caption exists */
if (FormatString[0] == L'{')
{
/* Set caption start */
TempStringU.Buffer = ++FormatString;
/* Get size of the caption */
for (Size = 0; *FormatString != 0 && *FormatString != L'}'; Size++)
FormatString++;
/* Skip '}', '\r', '\n' */
FormatString += 3;
TempStringU.Length = Size * sizeof(WCHAR);
TempStringU.MaximumLength = TempStringU.Length;
}
else
{
/* FIXME: Set string based on severity */
RtlInitUnicodeString(&TempStringU, L"Application Error");
}
/* Calculate buffer length for the caption */
CaptionStringU->MaximumLength = FileNameU.Length + TempStringU.Length +
4 * sizeof(WCHAR);
/* Allocate a buffer for the caption */
CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
CaptionStringU->MaximumLength);
/* Append the file name, seperator and the caption text */
CaptionStringU->Length = 0;
RtlAppendUnicodeStringToString(CaptionStringU, &FileNameU);
RtlAppendUnicodeToString(CaptionStringU, L" - ");
RtlAppendUnicodeStringToString(CaptionStringU, &TempStringU);
/* Zero terminate the buffer */
CaptionStringU->Buffer[CaptionStringU->Length / sizeof(WCHAR)] = 0;
/* Free the file name buffer */
RtlFreeUnicodeString(&FileNameU);
/* Check if this is an exception message */
if (Message->Status == STATUS_UNHANDLED_EXCEPTION)
{
ExceptionCode = Parameters[0];
/* Handle special cases */
if (ExceptionCode == STATUS_ACCESS_VIOLATION)
{
Parameters[0] = Parameters[1];
Parameters[1] = Parameters[3];
if (Parameters[2]) Parameters[2] = (ULONG_PTR)L"written";
else Parameters[2] = (ULONG_PTR)L"read";
MessageResource = NULL;
}
else if (ExceptionCode == STATUS_IN_PAGE_ERROR)
{
Parameters[0] = Parameters[1];
Parameters[1] = Parameters[3];
MessageResource = NULL;
}
else
{
/* Fall back to hardcoded value */
Parameters[2] = Parameters[1];
Parameters[1] = Parameters[0];
Parameters[0] = (ULONG_PTR)L"unknown software exception";
}
if (!MessageResource)
{
/* Get text string of the exception code */
Status = RtlFindMessage(GetModuleHandleW(L"ntdll"),
(ULONG_PTR)RT_MESSAGETABLE,
LANG_NEUTRAL,
ExceptionCode,
&MessageResource);
if (NT_SUCCESS(Status))
{
if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
if (MessageResource->Flags)
{
RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text);
FormatA.Buffer = NULL;
}
else
{
RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text);
RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE);
}
FormatString = FormatU.Buffer;
}
else
{
/* Fall back to hardcoded value */
Parameters[2] = Parameters[1];
Parameters[1] = Parameters[0];
Parameters[0] = (ULONG_PTR)L"unknown software exception";
}
}
}
/* Calculate length of text buffer */
TextStringU->MaximumLength = FormatU.Length + SizeOfStrings + 42 * sizeof(WCHAR);
/* Allocate a buffer for the text */
TextStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
TextStringU->MaximumLength);
/* Wrap in SEH to protect from invalid string parameters */
_SEH2_TRY
{
/* Print the string into the buffer */
StringCbPrintfW(TextStringU->Buffer,
TextStringU->MaximumLength,
FormatString,
Parameters[0],
Parameters[1],
Parameters[2],
Parameters[3]);
Status = STATUS_SUCCESS;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Set error and free buffers */
Status = _SEH2_GetExceptionCode();
RtlFreeHeap(RtlGetProcessHeap(), 0, TextStringU->Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, CaptionStringU->Buffer);
}
_SEH2_END
if (NT_SUCCESS(Status))
{
TextStringU->Length = wcslen(TextStringU->Buffer) * sizeof(WCHAR);
}
if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU);
return Status;
}
static
ULONG
CsrpMessageBox(
PWSTR Text,
PWSTR Caption,
ULONG ValidResponseOptions,
ULONG Severity)
{
ULONG Type, MessageBoxResponse;
/* Set the message box type */
switch (ValidResponseOptions)
{
case OptionAbortRetryIgnore:
Type = MB_ABORTRETRYIGNORE;
break;
case OptionOk:
Type = MB_OK;
break;
case OptionOkCancel:
Type = MB_OKCANCEL;
break;
case OptionRetryCancel:
Type = MB_RETRYCANCEL;
break;
case OptionYesNo:
Type = MB_YESNO;
break;
case OptionYesNoCancel:
Type = MB_YESNOCANCEL;
break;
case OptionShutdownSystem:
Type = MB_RETRYCANCEL; // FIXME???
break;
/* Anything else is invalid */
default:
return ResponseNotHandled;
}
/* Set severity */
if (Severity == STATUS_SEVERITY_INFORMATIONAL) Type |= MB_ICONINFORMATION;
else if (Severity == STATUS_SEVERITY_WARNING) Type |= MB_ICONWARNING;
else if (Severity == STATUS_SEVERITY_ERROR) Type |= MB_ICONERROR;
Type |= MB_SYSTEMMODAL | MB_SETFOREGROUND;
DPRINT("Text = '%S', Caption = '%S', Severity = %d, Type = 0x%lx\n",
Text, Caption, Severity, Type);
/* Display a message box */
MessageBoxResponse = MessageBoxW(0, Text, Caption, Type);
/* Return response value */
switch (MessageBoxResponse)
{
case IDOK: return ResponseOk;
case IDCANCEL: return ResponseCancel;
case IDYES: return ResponseYes;
case IDNO: return ResponseNo;
case IDABORT: return ResponseAbort;
case IDIGNORE: return ResponseIgnore;
case IDRETRY: return ResponseRetry;
case IDTRYAGAIN: return ResponseTryAgain;
case IDCONTINUE: return ResponseContinue;
}
return ResponseNotHandled;
}
VOID
WINAPI
Win32CsrHardError(
IN PCSR_THREAD ThreadData,
IN PHARDERROR_MSG Message)
{
#if DBG
PCSR_PROCESS ProcessData = ThreadData->Process;
#endif
ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING TextU, CaptionU;
NTSTATUS Status;
HANDLE hProcess;
ULONG Size;
/* Default to not handled */
ASSERT(ProcessData != NULL);
Message->Response = ResponseNotHandled;
/* Make sure we don't have too many parameters */
if (Message->NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS)
Message->NumberOfParameters = MAXIMUM_HARDERROR_PARAMETERS;
/* Initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
/* Open client process */
Status = NtOpenProcess(&hProcess,
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
&ObjectAttributes,
&Message->h.ClientId);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtOpenProcess failed with code: %lx\n", Status);
return;
}
/* Capture all string parameters from the process memory */
Status = CsrpCaptureStringParameters(Parameters, &Size, Message, hProcess);
if (!NT_SUCCESS(Status))
{
NtClose(hProcess);
return;
}
/* Format the caption and message box text */
Status = CsrpFormatMessages(&TextU,
&CaptionU,
Parameters,
Size,
Message,
hProcess);
/* Cleanup */
CsrpFreeStringParameters(Parameters, Message);
NtClose(hProcess);
if (!NT_SUCCESS(Status))
{
return;
}
/* Display the message box */
Message->Response = CsrpMessageBox(TextU.Buffer,
CaptionU.Buffer,
Message->ValidResponseOptions,
(ULONG)Message->Status >> 30);
RtlFreeUnicodeString(&TextU);
RtlFreeUnicodeString(&CaptionU);
return;
}
+64
View File
@@ -0,0 +1,64 @@
/*
* PROJECT: ReactOS CSRSS subsystem
* FILE: subsystems/win32/csrss/win32csr/lang/bg-BG.rc
* PURPOSE: Bulgarian resource file
*/
LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Прекратяване на приложение - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Прекратяване на приложението... Почакайте",IDC_STATIC,7,7,186,11
CONTROL "Ход",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Ако решите да затворите приложението веднага, ще изгубите всички незаписани данни. За да прекратите приложението веднага, натиснете „Прекратяване веднага„.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Прекратяване веднага",IDC_END_NOW,150,71,60,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Прекратяване на приложение - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Отказ",IDCANCEL,142,98,43,17
PUSHBUTTON "&Прекратяване веднага",IDC_END_NOW,150,71,60,17
LTEXT "Приложението не отговаря",IDC_STATIC,7,7,178,8
LTEXT "За да се върнете в РеактОС и да проверите състоянието на приложението, натиснете „Отказ“.",
IDC_STATIC,7,26,178,16
LTEXT "Ако решите да затворите приложението веднага, ще изгубите всички незаписани данни. За да прекратите приложението веднага, натиснете „Прекратяване веднага“.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Обработка"
IDS_MARK "Отбелязване"
IDS_COPY "Запомняне\tEnter"
IDS_PASTE "Поставяне"
IDS_SELECTALL "Избор на всичко"
IDS_SCROLL "Прелистване"
IDS_FIND "Търсене..."
IDS_DEFAULTS "Подразбирани"
IDS_PROPERTIES "Свойства"
IDS_SCROLLHERE "Прелистване тук"
IDS_SCROLLTOP "Прелистване до горе"
IDS_SCROLLBOTTOM "Прелистване до долу"
IDS_SCROLLPAGE_UP "Горна страница"
IDS_SCROLLPAGE_DOWN "Долна страница"
IDS_SCROLLUP "Прелистване нагоре"
IDS_SCROLLDOWN "Прелистване надолу"
IDS_COMMAND_PROMPT "Command Prompt"
END
+63
View File
@@ -0,0 +1,63 @@
/* FILE: subsystems/win32/csrss/win32csr/lang/cs-CZ.rc
* TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com)
* UPDATED: 2011-04-09
*/
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ukonèit program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Probíhá ukonèení programu... Èekejte, prosím",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "IPokud zvolíte okamžité ukonèení programu, všechna neuložená data budou ztracena. Kliknutím na Ukonèit okamžitì ukonèíte program.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Ukonèit okamžitì",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ukonèit program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Storno",IDCANCEL,142,98,43,17
PUSHBUTTON "&Ukonèit okamžitì",IDC_END_NOW,78,98,43,17
LTEXT "Tento program neodpovídá",IDC_STATIC,7,7,178,8
LTEXT "Kliknutím na Storno se lze vrátit do systému ReactOS a ovìøit stav programu",
IDC_STATIC,7,26,178,16
LTEXT "Pokud zvolíte okamžité ukonèení programu, všechna neuložená data budou ztracena. Kliknutím na Ukonèit okamžitì ukonèíte program.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Upravit"
IDS_MARK "Oznaèit"
IDS_COPY "Kopírovat\tEnter"
IDS_PASTE "Vložit"
IDS_SELECTALL "Oznaèit vše"
IDS_SCROLL "Posunout"
IDS_FIND "Najít..."
IDS_DEFAULTS "Výchozí"
IDS_PROPERTIES "Vlastnosti"
IDS_SCROLLHERE "Posunout sem"
IDS_SCROLLTOP "Posunout na zaèátek"
IDS_SCROLLBOTTOM "Posunout na konec"
IDS_SCROLLPAGE_UP "O stránku výše"
IDS_SCROLLPAGE_DOWN "O stránku níže"
IDS_SCROLLUP "Posunout nahoru"
IDS_SCROLLDOWN "Posunout dolù"
IDS_COMMAND_PROMPT "Pøíkazový øádek"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Programm beenden - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Programm wird beendet...",IDC_STATIC,7,7,186,11
CONTROL "Fortschritt",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Wenn Sie das Programm sofort beenden, werden Sie eventuell ungespeicherte Daten verlieren. Um das Programm zu beenden, wählen Sie Jetzt beenden.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "J&etzt beenden",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Programm beenden - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Abbechen",IDCANCEL,142,98,43,17
PUSHBUTTON "J&etzt beenden",IDC_END_NOW,78,98,43,17
LTEXT "Das Programm reagiert nicht",IDC_STATIC,7,7,178,8
LTEXT "Um zu ReactOS zurückzukehren und den Status der Anwendung zu überprüfen, wählen Sie Abbrechen.",
IDC_STATIC,7,26,178,16
LTEXT "Wenn Sie das Programm sofort beenden, werden Sie eventuell ungespeicherte Daten verlieren. Um das Programm zu beenden, wählen Sie Jetzt beenden.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Bearbeiten"
IDS_MARK "Markieren"
IDS_COPY "Kopieren\tEnter"
IDS_PASTE "Einfügen"
IDS_SELECTALL "Alles auswählen"
IDS_SCROLL "Scrollen"
IDS_FIND "Suchen..."
IDS_DEFAULTS "Standardwerte"
IDS_PROPERTIES "Eigenschaften"
IDS_SCROLLHERE "Hier scrollen"
IDS_SCROLLTOP "Ganz nach oben scrollen"
IDS_SCROLLBOTTOM "Ganz nach unten scrollen"
IDS_SCROLLPAGE_UP "Seite nach oben"
IDS_SCROLLPAGE_DOWN "Seite nach unten"
IDS_SCROLLUP "Nach oben scrollen"
IDS_SCROLLDOWN "Nach unten scrollen"
IDS_COMMAND_PROMPT "Eingabeaufforderung"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Êëåßóéìï ðñïãñÜììáôïò - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Êëåßóéìï ðñïãñÜììáôïò... Ðáñáêáëþ ðåñéìÝíåôå",IDC_STATIC,7,7,186,11
CONTROL "Ðñüïäïò",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Áí êëåßóåôå ôçí åöáñìïãÞ ôþñá , èá ÷Üóåôå üëá ôá ìç áðïèçêåõìÝíá äåäïìÝíá. Ãéá íá êëåßóåôå ôï ðñüãñáììá ôþñá, ðáôÞóôå 'Êëåßóéìï Ôþñá'.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Êëåßóéìï Ôþñá",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Êëåßóçìï ðñïãñÜììáôïò - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "¢êõñï",IDCANCEL,142,98,43,17
PUSHBUTTON "&Êëåßóéìï Ôþñá",IDC_END_NOW,78,98,43,17
LTEXT "Ôï ðñüãñáììá äåí áðïêñßíåôáé",IDC_STATIC,7,7,178,8
LTEXT "Ãéá íá åðéóôñÝøåôå óôï ReactOS êáé íá åëÝãîåôå ôçí êáôÜóôáóç ôïõ ðñïãñÜììáôïò, ðáôÞóôå '¢êõñï'",
IDC_STATIC,7,26,178,16
LTEXT "Áí êëåßóåôå ôçí åöáñìïãÞ ôþñá , èá ÷Üóåôå üëá ôá ìç áðïèçêåõìÝíá äåäïìÝíá. Ãéá íá êëåßóåôå ôï ðñüãñáììá ôþñá, ðáôÞóôå 'Êëåßóéìï Ôþñá'.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Åðåîåñãáóßá"
IDS_MARK "ÌáñêÜñéóìá"
IDS_COPY "ÁíôéãñáöÞ\tEnter"
IDS_PASTE "Åðéêüëëçóç"
IDS_SELECTALL "ÅðéëïãÞ üëùí"
IDS_SCROLL "Êýëéóç"
IDS_FIND "Åýñåóç..."
IDS_DEFAULTS "ÐñïåðéëïãÞ"
IDS_PROPERTIES "Éäéüôçôåò"
IDS_SCROLLHERE "Êýëéóç åäþ"
IDS_SCROLLTOP "Áñ÷Þ"
IDS_SCROLLBOTTOM "ÔÝëïò"
IDS_SCROLLPAGE_UP "Ðñïçãïýìåíç óåëßäá"
IDS_SCROLLPAGE_DOWN "Åðüìåíç óåëßäá"
IDS_SCROLLUP "Êýëéóç ðÜíù"
IDS_SCROLLDOWN "Êýëéóç êÜôù"
IDS_COMMAND_PROMPT "Command Prompt"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "End Program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Ending Program... Please wait",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&End Now",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "End Program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Cancel",IDCANCEL,142,98,43,17
PUSHBUTTON "&End Now",IDC_END_NOW,78,98,43,17
LTEXT "This program is not responding",IDC_STATIC,7,7,178,8
LTEXT "To return to ReactOS and check the status of the program, click Cancel",
IDC_STATIC,7,26,178,16
LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Edit"
IDS_MARK "Mark"
IDS_COPY "Copy\tEnter"
IDS_PASTE "Paste"
IDS_SELECTALL "Select All"
IDS_SCROLL "Scroll"
IDS_FIND "Find..."
IDS_DEFAULTS "Defaults"
IDS_PROPERTIES "Properties"
IDS_SCROLLHERE "Scroll here"
IDS_SCROLLTOP "Scroll top"
IDS_SCROLLBOTTOM "Scroll bottom"
IDS_SCROLLPAGE_UP "Page up"
IDS_SCROLLPAGE_DOWN "Page down"
IDS_SCROLLUP "Scroll up"
IDS_SCROLLDOWN "Scroll down"
IDS_COMMAND_PROMPT "Command Prompt"
END
+63
View File
@@ -0,0 +1,63 @@
/*
*Spanish Language resource file
* Traducido por: Javier Remacha 2008-26-01
*/
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Finalizar programa - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Finalizando programa... Por favor, espere",IDC_STATIC,7,7,186,11
CONTROL "Progreso",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Si elige finalizar el programa ahora, perderá todos los datos no guardados. Para finalizar el programa ahora, haga clic en Finalizar ahora.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Finalizar ahora",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Finalizar programa - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Cancelar",IDCANCEL,142,98,43,17
PUSHBUTTON "&Finalizar ahora",IDC_END_NOW,78,98,43,17
LTEXT "Este programa no responde",IDC_STATIC,7,7,178,8
LTEXT "Para volver a ReactOS y ver el estado del programa, haga clic en Cancelar",
IDC_STATIC,7,26,178,16
LTEXT "Si elige finalizar el programa ahora, perderá todos los datos no guardados. Para finalizar el programa ahora, haga clic en Finalizar ahora.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Editar"
IDS_MARK "Marcar"
IDS_COPY "Copiar\tIntroducir"
IDS_PASTE "Pegar"
IDS_SELECTALL "Seleccionar Todo"
IDS_SCROLL "Desplazar"
IDS_FIND "Buscar..."
IDS_DEFAULTS "Por defecto"
IDS_PROPERTIES "Propiedades"
IDS_SCROLLHERE "Desplazar aquí"
IDS_SCROLLTOP "Desplazar hasta arriba"
IDS_SCROLLBOTTOM "Desplazar hasta abajo"
IDS_SCROLLPAGE_UP "Subir página"
IDS_SCROLLPAGE_DOWN "Bajar página"
IDS_SCROLLUP "Desplazar arriba"
IDS_SCROLLDOWN "Desplazar abajo"
IDS_COMMAND_PROMPT "Command Prompt"
END
+60
View File
@@ -0,0 +1,60 @@
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Fin du programme - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Termine le programme... Veuillez patienter",IDC_STATIC,7,7,186,11
CONTROL "Avancement",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Si vous choisissez de terminer le programme immédiatement, vous perdrez toutes les données non sauvegardées. Pour terminer le programme maintenant, cliquez sur Terminer maintenant.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "T&erminer maintenant",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Fin du programme - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Annuler",IDCANCEL,142,98,43,17
PUSHBUTTON "T&erminer maintenant",IDC_END_NOW,78,98,43,17
LTEXT "Ce programme ne répond pas",IDC_STATIC,7,7,178,8
LTEXT "Pour retourner à ReactOS et vérifier l'état du programme, cliquez sur Annuler",
IDC_STATIC,7,26,178,16
LTEXT "Si vous choisissez de terminer le programme immédiatement, vous perdrez toutes les données non sauvegardées. Pour terminer le programme maintenant, cliquez sur Terminer maintenant",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
/* Fixme : Translation could be really improved, with context
La traduction pourrait réellement être améliorée grâce au contexte */
STRINGTABLE
BEGIN
IDS_EDIT "Éditer"
IDS_MARK "Marquer"
IDS_COPY "Copier\tEntrée"
IDS_PASTE "Coller"
IDS_SELECTALL "Tout sélectionner"
IDS_SCROLL "Défiler"
IDS_FIND "Trouver..."
IDS_DEFAULTS "Défauts"
IDS_PROPERTIES "Propriétés"
IDS_SCROLLHERE "Défiler ici"
IDS_SCROLLTOP "Défiler tout en haut"
IDS_SCROLLBOTTOM "Défiler tout en bas"
IDS_SCROLLPAGE_UP "Page précédente"
IDS_SCROLLPAGE_DOWN "Page suivante"
IDS_SCROLLUP "Défiler en haut"
IDS_SCROLLDOWN "Défiler en bas"
IDS_COMMAND_PROMPT "Command Prompt"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "סיום תכנית - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "מסיים תכנית... נא להמתין",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "סיים כעת",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "סיום תכנית - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "ביטול",IDCANCEL,142,98,43,17
PUSHBUTTON "סיים כעת",IDC_END_NOW,78,98,43,17
LTEXT "התכנית אינה מגיבה",IDC_STATIC,7,7,178,8
LTEXT "To return to ReactOS and check the status of the program, click Cancel",
IDC_STATIC,7,26,178,16
LTEXT "If you choose to end the program immediately, you will lose any unsaved data. To end the program now, click End Now",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "ערוך"
IDS_MARK "סמן"
IDS_COPY "העתק\tEnter"
IDS_PASTE "הדבק"
IDS_SELECTALL "בחר הכל"
IDS_SCROLL "גלול"
IDS_FIND "מצא..."
IDS_DEFAULTS "ברירת מחדל"
IDS_PROPERTIES "מאפיינים"
IDS_SCROLLHERE "גלול לכאן"
IDS_SCROLLTOP "גלול למעלה"
IDS_SCROLLBOTTOM "גלול למטה"
IDS_SCROLLPAGE_UP "עמוד מעלה"
IDS_SCROLLPAGE_DOWN "עמוד מטה"
IDS_SCROLLUP "גלול מעלה"
IDS_SCROLLDOWN "גלול מטה"
IDS_COMMAND_PROMPT "שורת הפקודה"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Akhir Program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Mengakhiri Program... Harap menunggu",IDC_STATIC,7,7,186,11
CONTROL "Progres",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Jika anda memilih untuk segera mengakhiri program, anda akan kehilangan data yang belum disimpan. Untuk mengakhiri program sekarang, klik Akhiri Sekarang.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Akhiri Sekarang",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Mengakhiri Program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Batal",IDCANCEL,142,98,43,17
PUSHBUTTON "&Akhiri Sekarang",IDC_END_NOW,78,98,43,17
LTEXT "Program ini tidak merespon",IDC_STATIC,7,7,178,8
LTEXT "Untuk kembali ke ReactOS dan memeriksa status program, klik Batal",
IDC_STATIC,7,26,178,16
LTEXT "Jika anda memilih untuk segera mengakhiri program, anda akan kehilangan data yang belum disimpan. Untuk mengakhiri program sekarang, klik Akhiri Sekarang.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Edit"
IDS_MARK "Tandai"
IDS_COPY "Copy\tEnter"
IDS_PASTE "Paste"
IDS_SELECTALL "Pilih Semua"
IDS_SCROLL "Gulung"
IDS_FIND "Cari..."
IDS_DEFAULTS "Standar"
IDS_PROPERTIES "Properti"
IDS_SCROLLHERE "Gulung ke Sini"
IDS_SCROLLTOP "Gulung ke Atas"
IDS_SCROLLBOTTOM "Gulung ke Bawah"
IDS_SCROLLPAGE_UP "Halaman Naik"
IDS_SCROLLPAGE_DOWN "Halaman Turun"
IDS_SCROLLUP "Gulung Naik"
IDS_SCROLLDOWN "Gulung Turun"
IDS_COMMAND_PROMPT "Command Prompt"
END
+67
View File
@@ -0,0 +1,67 @@
/*
* PROJECT: ReactOS Client/Server Runtime subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/csrss/win32csr/lang/it-IT.rc
* PURPOSE: Italian Translation of subsystems/win32/csrss/win32csr/lang/en-US.rc
* PROGRAMMERS:
* Copyright (C) 2007 Daniele Forsi (dforsi at gmail.com) Italian Translation
*/
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Arresto del programma - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Arresto del programma... Attendere",IDC_STATIC,7,7,186,11
CONTROL "Progresso",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "T&ermina ora",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Arresto del programma - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Annulla",IDCANCEL,142,98,43,17
PUSHBUTTON "T&ermina ora",IDC_END_NOW,78,98,43,17
LTEXT "Il programma non risponde",IDC_STATIC,7,7,178,8
LTEXT "Per tornare a ReactOS e controllare lo stato del programma, selezionare Annulla",
IDC_STATIC,7,26,178,16
LTEXT "Se si sceglie di terminare il programma immediatamente, si perderanno tutti i dati non salvati. Per terminare il programma ora, selezionare Termina ora.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Modifica"
IDS_MARK "Seleziona"
IDS_COPY "Copia\tInvio"
IDS_PASTE "Incolla"
IDS_SELECTALL "Seleziona tutto"
IDS_SCROLL "Scorri"
IDS_FIND "Trova..."
IDS_DEFAULTS "Impostazioni predefinite"
IDS_PROPERTIES "Proprietà"
IDS_SCROLLHERE "Scorri qui"
IDS_SCROLLTOP "Scorri in cima"
IDS_SCROLLBOTTOM "Scorri in fondo"
IDS_SCROLLPAGE_UP "Pagina sù"
IDS_SCROLLPAGE_DOWN "Pagina giù"
IDS_SCROLLUP "Scorri sù"
IDS_SCROLLDOWN "Scorri giù"
IDS_COMMAND_PROMPT "Prompt dei commandi"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "プログラムの終了 - "
FONT 9, "MS UI Gothic"
BEGIN
LTEXT "プログラムを終了しています... しばらくお待ちください",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "プログラムをすぐに終了させるよう選択した場合、保存されていないデータはすべて失われます。プログラムを終了するには[すぐに終了]をクリックしてください。",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "すぐに終了(&E)",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "プログラムの終了 - "
FONT 9, "MS UI Gothic"
BEGIN
DEFPUSHBUTTON "キャンセル",IDCANCEL,142,98,43,17
PUSHBUTTON "すぐに終了(&E)",IDC_END_NOW,78,98,43,17
LTEXT "このプログラムは応答していません",IDC_STATIC,7,7,178,8
LTEXT "ReactOS に戻ってプログラムの状態を確認するには[キャンセル]をクリックしてください",
IDC_STATIC,7,26,178,16
LTEXT "プログラムをすぐに終了させるよう選択した場合、保存されていないデータはすべて失われます。プログラムを直ちに終了するには[すぐに終了]をクリックしてください",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 9, "MS UI Gothic", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "編集"
IDS_MARK "範囲指定"
IDS_COPY "コピー\tEnter"
IDS_PASTE "貼\り付け"
IDS_SELECTALL "すべて選択"
IDS_SCROLL "スクロール"
IDS_FIND "検索..."
IDS_DEFAULTS "規定値"
IDS_PROPERTIES "プロパティ"
IDS_SCROLLHERE "ここにスクロール"
IDS_SCROLLTOP "一番上にスクロール"
IDS_SCROLLBOTTOM "一番下にスクロール"
IDS_SCROLLPAGE_UP "Page up"
IDS_SCROLLPAGE_DOWN "Page down"
IDS_SCROLLUP "上にスクロール"
IDS_SCROLLDOWN "下にスクロール"
IDS_COMMAND_PROMPT "Command Prompt"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Avslutt program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Avslutt Program... Vennligst vent",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Hvis du velger å avslutte programmet øyeblikkelig, vil du miste alt data som ikke er lagret. For å avslutte programmet nå, Trykk på Avslutt nå.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Avslutt nå",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Avslutt program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Avbryt",IDCANCEL,142,98,43,17
PUSHBUTTON "&Avslutt nå",IDC_END_NOW,78,98,43,17
LTEXT "Programmet svarer ikke",IDC_STATIC,7,7,178,8
LTEXT "For å returnere til ReactOS for å sjekke statusen på programmet, trykk på avbryt",
IDC_STATIC,7,26,178,16
LTEXT "Hvis du velger å avslutte programmet øyeblikkelig, vil du miste alt data som ikke er lagret. For å avslutte programmet nå, Trykk på Avslutt nå",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Rediger"
IDS_MARK "Merk"
IDS_COPY "Kopier\tEnter"
IDS_PASTE "Lim inn"
IDS_SELECTALL "Velg alt"
IDS_SCROLL "Rull"
IDS_FIND "Finn..."
IDS_DEFAULTS "Standard"
IDS_PROPERTIES "Egenskaper"
IDS_SCROLLHERE "Rull her"
IDS_SCROLLTOP "Rull til toppen"
IDS_SCROLLBOTTOM "Rull knapp"
IDS_SCROLLPAGE_UP "Side opp"
IDS_SCROLLPAGE_DOWN "Side ned"
IDS_SCROLLUP "Rull opp"
IDS_SCROLLDOWN "Rull ned"
IDS_COMMAND_PROMPT "Command Prompt"
END
+66
View File
@@ -0,0 +1,66 @@
/*
* translated by xrogers
* [email protected]
* https://sourceforge.net/projects/reactospl
* translation update by Olaf Siejka (Caemyr), Apr 2011
* UTF-8 conversion by Caemyr (May, 2011)
*/
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Zakończ program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Trwa zamykanie programu... Proszę czekać",IDC_STATIC,7,7,186,11
CONTROL "Postęp",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Jeśli zdecydujesz się zamknąć program natychmiastowo, utracisz wszelkie niezapisane dane. Aby zakończyć program, wciśnij Zakończ teraz.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Zakończ teraz",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Zakończ program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Anuluj",IDCANCEL,142,98,43,17
PUSHBUTTON "&Zakończ teraz",IDC_END_NOW,78,98,43,17
LTEXT "Wybrany program nie odpowiada",IDC_STATIC,7,7,178,8
LTEXT "Aby powrócić do ReactOS i sprawdzić status programu, kliknij Anuluj",
IDC_STATIC,7,26,178,16
LTEXT "Jeśli zdecydujesz się zamknąć program natychmiastowo, utracisz wszelkie niezapisane dane. Aby zakończyć program, wciśnij Zakończ teraz.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Edytuj"
IDS_MARK "Zaznacz"
IDS_COPY "Kopiuj\tWejdź"
IDS_PASTE "Wklej"
IDS_SELECTALL "Zaznacz wszystko"
IDS_SCROLL "Przewiń"
IDS_FIND "Znajdź..."
IDS_DEFAULTS "Ustawienia domyślne"
IDS_PROPERTIES "Właściwości"
IDS_SCROLLHERE "Przewiń tutaj"
IDS_SCROLLTOP "Przewiń na początek"
IDS_SCROLLBOTTOM "Przewiń na koniec"
IDS_SCROLLPAGE_UP "Poprzednia strona"
IDS_SCROLLPAGE_DOWN "Następna strona"
IDS_SCROLLUP "Przewiń do góry"
IDS_SCROLLDOWN "Przewiń na dół"
IDS_COMMAND_PROMPT "Wiersz polecenia"
END
+60
View File
@@ -0,0 +1,60 @@
/* Translation and UTF-8 Conversion by mkbu95 <[email protected]> (May, 2012) */
LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Finalizar Programa - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Finalizando Programa... Por favor aguarde",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Se você finalizar o programa imediatamente, você irá perder qualquer alteração não salva. Para finalizar o programa agora, pressione Finalizar Agora.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Finalizar Agora",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Finalizar Programa - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Cancelar",IDCANCEL,142,98,43,17
PUSHBUTTON "&Finalizar Agora",IDC_END_NOW,78,98,43,17
LTEXT "O programa não está respondendo",IDC_STATIC,7,7,178,8
LTEXT "Parar retornar ao ReactOS e verificar o estado do programa, pressione Cancelar",
IDC_STATIC,7,26,178,16
LTEXT "Se você finalizar o programa imediatamente, você irá perder qualquer alteração não salva. Para finalizar o programa agora, pressione Finalizar Agora",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Editar"
IDS_MARK "Marcar"
IDS_COPY "Copiar\tEnter"
IDS_PASTE "Colar"
IDS_SELECTALL "Selecionar Tudo"
IDS_SCROLL "Rolar"
IDS_FIND "Procurar..."
IDS_DEFAULTS "Padrões"
IDS_PROPERTIES "Propriedades"
IDS_SCROLLHERE "Rolar aqui"
IDS_SCROLLTOP "Rolar até o topo"
IDS_SCROLLBOTTOM "Rolar até o fim"
IDS_SCROLLPAGE_UP "Page up"
IDS_SCROLLPAGE_DOWN "Page down"
IDS_SCROLLUP "Scroll up"
IDS_SCROLLDOWN "Scroll down"
IDS_COMMAND_PROMPT "Prompt de Comando"
END
+65
View File
@@ -0,0 +1,65 @@
/*
* FILE: subsystems/win32/csrss/win32csr/lang/ro-RO.rc
* ReactOS Project (http://www.reactos.org)
* TRANSLATOR: Fulea Ștefan (PM on ReactOS Forum at fulea.stefan)
* CHANGE LOG: 2011-10-16 initial translation
*/
LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Terminare execuție - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Terminare execuție… așteptați",IDC_STATIC,7,7,186,11
CONTROL "Progress", IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Dacă alegeți închiderea forțată, riscați pierderi de date. Pentru a forța închiderea, apăsați „Termină forțat”.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "Termină &forțat",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Terminare execuție - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "A&nulează", IDCANCEL,142,98,43,17
PUSHBUTTON "Termină &forțat",IDC_END_NOW,78,98,43,17
LTEXT "Acest program nu răspunde",IDC_STATIC,7,7,178,8
LTEXT "Pentru a vă întoarce în ReactOS și a verifica starea programului, apăsați „Anulează”",
IDC_STATIC,7,26,178,16
LTEXT "Dacă alegeți închiderea imediată a programului, riscați pierderi de date. Pentru a forța închiderea, apăsați „Termină forțat”.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Editare"
IDS_MARK "Marchează"
IDS_COPY "Copiază\tEnter"
IDS_PASTE "Lipește"
IDS_SELECTALL "Selectează tot"
IDS_SCROLL "Derulează"
IDS_FIND "Găsire…"
IDS_DEFAULTS "Implicite"
IDS_PROPERTIES "Proprietăți"
IDS_SCROLLHERE "Derulează aici"
IDS_SCROLLTOP "Derulează la început"
IDS_SCROLLBOTTOM "Derulează la sfârșit"
IDS_SCROLLPAGE_UP "Pagina anterioară"
IDS_SCROLLPAGE_DOWN "Pagina următoare"
IDS_SCROLLUP "Derulează în sus"
IDS_SCROLLDOWN "Derulează în jos"
IDS_COMMAND_PROMPT "Linie de comandă"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Завершение программы - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Завершение программы... Пажалуйста подождите",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Если вы завершите программу сейчас, то вы можете потерять несохраненные данные. Чтобы завешить программу сейчас нажмите ""Завершить""",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Завешить",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Завершение программы - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Отмена",IDCANCEL,142,98,43,17
PUSHBUTTON "&Завершить",IDC_END_NOW,78,98,43,17
LTEXT "Эта программа не отвечает",IDC_STATIC,7,7,178,8
LTEXT "Для возврата в ReactOS и сохранения данных нажмите ""Отмена""",
IDC_STATIC,7,26,178,16
LTEXT "Если вы завершите программу сейчас, то вы можете потерять несохраненные данные. Чтобы завешить программу сейчас нажмите ""Завершить""",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Изменить"
IDS_MARK "Пометить"
IDS_COPY "Копировать\tEnter"
IDS_PASTE "Вставить"
IDS_SELECTALL "Выделить все"
IDS_SCROLL "Прокрутить"
IDS_FIND "Искать..."
IDS_DEFAULTS "Умолчания"
IDS_PROPERTIES "Свойства"
IDS_SCROLLHERE "Scroll Here"
IDS_SCROLLTOP "Scroll Top"
IDS_SCROLLBOTTOM "Прокрутить вниз"
IDS_SCROLLPAGE_UP "Вверх страницы"
IDS_SCROLLPAGE_DOWN "Вниз страницы"
IDS_SCROLLUP "Прокрутить вверх"
IDS_SCROLLDOWN "Scroll Down"
IDS_COMMAND_PROMPT "Command Prompt"
END
+63
View File
@@ -0,0 +1,63 @@
/* TRANSLATOR: Mário Kaèmár /Mario Kacmar/ aka Kario ([email protected])
* DATE OF TR: 29-05-2008
* LastChange: 12-04-2011
*/
LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ukonèenie programu - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Ukonèujem program... Poèkajte, prosím.",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Ak zvolíte okamžité ukonèenie programu, stratíte všetky neuložené údaje. Ak chcete program ukonèi okamžite, kliknite na tlaèidlo Ukonèi ihneï.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Ukonèi ihneï",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ukonèenie programu - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Zruši",IDCANCEL,142,98,43,17
PUSHBUTTON "&Ukonèi ihneï",IDC_END_NOW,78,98,43,17
LTEXT "Tento program neodpovedá.",IDC_STATIC,7,7,178,8
LTEXT "Pre návrat do systému ReactOS a overenie stavu programu kliknite na tlaèidlo Zruši.",
IDC_STATIC,7,26,178,16
LTEXT "Ak zvolíte okamžité ukonèenie programu, stratíte všetky neuložené údaje. Ak chcete program ukonèi okamžite, kliknite na tlaèidlo Ukonèi ihneï.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Upravi"
IDS_MARK "Oznaèi"
IDS_COPY "Kopírova\tEnter"
IDS_PASTE "Vloži"
IDS_SELECTALL "Vybra všetko"
IDS_SCROLL "Rolova"
IDS_FIND "Nájs..." //Find
IDS_DEFAULTS "Predvolené" //Defaults
IDS_PROPERTIES "Vlastnosti"
IDS_SCROLLHERE "Rolova sem"
IDS_SCROLLTOP "K hornému okraju"
IDS_SCROLLBOTTOM "K dolnému okraju"
IDS_SCROLLPAGE_UP "O stránku vyššie"
IDS_SCROLLPAGE_DOWN "O stránku nižšie"
IDS_SCROLLUP "Rolova nahor"
IDS_SCROLLDOWN "Rolova nadol"
IDS_COMMAND_PROMPT "Príkazový riadok"
END
+65
View File
@@ -0,0 +1,65 @@
/*
* PROJECT: ReactOS CSRSS subsystem
* FILE: subsystems/win32/csrss/win32csr/lang/sv-SE.rc
* PURPOSE: Swedish resource file
* Translation: Jaix Bly
*/
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "End Program - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Avsluta Program... Var vänlig vänta",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Om du väljer att avsluta programmet omedelbart kommer du att förlora all osparad data. För att avsluta programmet, klicka Avsluta nu.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Avsluta Nu",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Avsluta Program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Avbryt",IDCANCEL,142,98,43,17
PUSHBUTTON "&Avsluta Nu",IDC_END_NOW,78,98,43,17
LTEXT "Detta programmet svarar inte",IDC_STATIC,7,7,178,8
LTEXT "För att återgå till ReactOS och undersöka programmets status klicka Avbryt",
IDC_STATIC,7,26,178,16
LTEXT "m du väljer att avsluta programmet omedelbart kommer du att förlora all osparad data. För att avsluta programmet, klicka Avsluta nu.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Redigera"
IDS_MARK "Markera"
IDS_COPY "Kopiera\tEnter"
IDS_PASTE "Klistra in"
IDS_SELECTALL "Markera Allt"
IDS_SCROLL "Skrolla"
IDS_FIND "Sök..."
IDS_DEFAULTS "Ursprunglig"
IDS_PROPERTIES "Egenskaper"
IDS_SCROLLHERE "Skrolla hit"
IDS_SCROLLTOP "Skrolla till topp"
IDS_SCROLLBOTTOM "Skrolla till botten"
IDS_SCROLLPAGE_UP "Sida upp"
IDS_SCROLLPAGE_DOWN "Sida ner"
IDS_SCROLLUP "Skrolla upp"
IDS_SCROLLDOWN "Skrolla ner"
IDS_COMMAND_PROMPT "Command Prompt"
END
+78
View File
@@ -0,0 +1,78 @@
/*
* Turkish resources
*
* Copyright 2012 Arda Tanrikulu <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Programı Sonlandır - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Program Sonlandırılıyor... Lütfen bekleyin",IDC_STATIC,7,7,186,11
CONTROL "İşlem",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Programı hemen kapatmayı seçerseniz, kaydedilmemiş veriyi kaybedersiniz. Programdan şimdi çıkmak için Şimdi Sonlandır'ı tıklatın.",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Şimdi Sonlandır",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "End Program - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "İptal",IDCANCEL,142,98,43,17
PUSHBUTTON "Şimdi Sonlandır",IDC_END_NOW,78,98,43,17
LTEXT "Bu program yanıt vermiyor.",IDC_STATIC,7,7,178,8
LTEXT "ReactOS'a dönmek ve programın durumunu denetlemek için İptal'i tıklatın.",
IDC_STATIC,7,26,178,16
LTEXT "Programı hemen kapatmayı seçerseniz, kaydedilmemiş veriyi kaybedersiniz. Programdan şimdi çıkmak için Şimdi Sonlandır'ı tıklatın.",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Düzenle"
IDS_MARK "İşaretle"
IDS_COPY "Kopyala\tEnter"
IDS_PASTE "Yapıştır"
IDS_SELECTALL "Tümünü Seç"
IDS_SCROLL "Yuvarla"
IDS_FIND "Bul..."
IDS_DEFAULTS "Varsayılanlar"
IDS_PROPERTIES "Özellikler"
IDS_SCROLLHERE "Buraya yuvarla"
IDS_SCROLLTOP "Üste yuvarla"
IDS_SCROLLBOTTOM "Alta yuvarla"
IDS_SCROLLPAGE_UP "Sayfa yukarı"
IDS_SCROLLPAGE_DOWN "Sayfa aşağı"
IDS_SCROLLUP "Yukarı yuvarla"
IDS_SCROLLDOWN "Aşağı yuvarla"
IDS_COMMAND_PROMPT "Komut İstemi"
END
+66
View File
@@ -0,0 +1,66 @@
/*
* PROJECT: ReactOS CSRSS subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/csrss/win32csr/lang/uk-UA.rc
* PURPOSE: Ukraianian resource file
* TRANSLATOR: Artem Reznikov
*/
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Завершення програми - "
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Завершення програми... Зачекайте",IDC_STATIC,7,7,186,11
CONTROL "Прогрес",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "Якщо завершити програму негайно, то можна втратити всі незбережені дані. Щоб завершити програму зараз, натисніть 'Завершити зараз'",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "&Завершити зараз",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Завершення програми - "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Скасувати",IDCANCEL,142,98,43,17
PUSHBUTTON "&Завершити зараз",IDC_END_NOW,78,98,43,17
LTEXT "Ця програма не відповідає",IDC_STATIC,7,7,178,8
LTEXT "Щоб повернутися у ReactOS і перевірити стан програми, натисніть 'Скасувати'",
IDC_STATIC,7,26,178,16
LTEXT "Якщо завершити програму негайно, то можна втратити всі незбережені дані. Щоб завершити програму зараз, натисніть 'Завершити зараз'",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "Редагувати"
IDS_MARK "Виділити"
IDS_COPY "Копіювати\tEnter"
IDS_PASTE "Вставити"
IDS_SELECTALL "Виділити все"
IDS_SCROLL "Прокрутити"
IDS_FIND "Знайти..."
IDS_DEFAULTS "Замовчування"
IDS_PROPERTIES "Властивості"
IDS_SCROLLHERE "Прокрутити сюди"
IDS_SCROLLTOP "Прокрутити на початок"
IDS_SCROLLBOTTOM "Прокрутити на кінець"
IDS_SCROLLPAGE_UP "Попередня сотрінка"
IDS_SCROLLPAGE_DOWN "Наступна сторінка"
IDS_SCROLLUP "Прокрутити догори"
IDS_SCROLLDOWN "Прокрутити донизу"
IDS_COMMAND_PROMPT "Командний рядок"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "终止程序 - "
FONT 9, "MS Shell Dlg"
BEGIN
LTEXT "正在终止程序... 请等待",IDC_STATIC,7,7,186,11
CONTROL "进程",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "如果您选择立即终止程序,您将失去所有未保存的数据。若要立即结束程序,单击“立即终止”。",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "立即终止(&E)",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "终止程序 - "
FONT 9, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "取消",IDCANCEL,142,98,43,17
PUSHBUTTON "立即终止(&E)",IDC_END_NOW,78,98,43,17
LTEXT "此程序并未响应",IDC_STATIC,7,7,178,8
LTEXT "若要返回至 ReactOS 并检查该程序的状态,请点击“取消”。",
IDC_STATIC,7,26,178,16
LTEXT "如果您选择立即终止程序,您将失去所有未保存的数据。若要立即结束程序,单击“立即终止”。",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 9, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "编辑"
IDS_MARK "标记"
IDS_COPY "复制\tEnter"
IDS_PASTE "黏贴"
IDS_SELECTALL "全部选择"
IDS_SCROLL "滚动"
IDS_FIND "查找..."
IDS_DEFAULTS "默认"
IDS_PROPERTIES "属性"
IDS_SCROLLHERE "滚动到此"
IDS_SCROLLTOP "滚动至顶端"
IDS_SCROLLBOTTOM "滚动至末端"
IDS_SCROLLPAGE_UP "上一页"
IDS_SCROLLPAGE_DOWN "下一页"
IDS_SCROLLUP "向上滚动"
IDS_SCROLLDOWN "向下滚动"
IDS_COMMAND_PROMPT "Command Prompt"
END
+58
View File
@@ -0,0 +1,58 @@
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
IDD_END_NOW DIALOGEX DISCARDABLE 0, 0, 200, 95
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "結束程式"
FONT 9, "MS Shell Dlg"
BEGIN
LTEXT "正在結束程式... 請稍等",IDC_STATIC,7,7,186,11
CONTROL "Progress",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
7,20,186,13
LTEXT "如果您選擇立即結束程式,您將失去所有未儲存的資料。若要立即結束程式,請按下“立即結束”。",
IDC_STATIC,7,40,186,26
DEFPUSHBUTTON "立即結束(&E)",IDC_END_NOW,150,71,43,17
END
IDD_NOT_RESPONDING DIALOGEX DISCARDABLE 0, 0, 192, 122
STYLE DS_SHELLFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "結束程式 - "
FONT 9, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "取消",IDCANCEL,142,98,43,17
PUSHBUTTON "立即結束(&E) ",IDC_END_NOW,78,98,43,17
LTEXT "此程式並未響應",IDC_STATIC,7,7,178,8
LTEXT "若要返回至 ReactOS 並檢視程式的狀態,請按下“取消”",
IDC_STATIC,7,26,178,16
LTEXT "如果您選擇立即結束程式,您將失去所有未儲存的資料。若要立即結束程式,請按下“立即結束”。",
IDC_STATIC,7,53,178,26
END
IDD_SWITCH_APP DIALOGEX 90, 90, 265, 170
STYLE DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
FONT 9, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC_CUR_APP,39,139,204,16,SS_SUNKEN,WS_EX_STATICEDGE
END
STRINGTABLE
BEGIN
IDS_EDIT "編輯"
IDS_MARK "標記"
IDS_COPY "複製\tEnter"
IDS_PASTE "黏貼"
IDS_SELECTALL "全部選擇"
IDS_SCROLL "滾動"
IDS_FIND "尋找..."
IDS_DEFAULTS "預設"
IDS_PROPERTIES "屬性"
IDS_SCROLLHERE "滾動到此 "
IDS_SCROLLTOP "滾動到頂置"
IDS_SCROLLBOTTOM "滾動到末端"
IDS_SCROLLPAGE_UP "上一頁"
IDS_SCROLLPAGE_DOWN "下一頁"
IDS_SCROLLUP "向上滾動"
IDS_SCROLLDOWN "向下滾動"
IDS_COMMAND_PROMPT "Command Prompt"
END
+597
View File
@@ -0,0 +1,597 @@
/*
* PROJECT: ReactOS CSRSS
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/csrss/win32csr/lineinput.c
* PURPOSE: Console line input functions
* PROGRAMMERS: Jeffrey Morlan
*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
typedef struct tagHISTORY_BUFFER
{
LIST_ENTRY ListEntry;
WORD Position;
WORD MaxEntries;
WORD NumEntries;
PUNICODE_STRING Entries;
UNICODE_STRING ExeName;
} HISTORY_BUFFER, *PHISTORY_BUFFER;
/* FUNCTIONS *****************************************************************/
static PHISTORY_BUFFER
HistoryCurrentBuffer(PCSRSS_CONSOLE Console)
{
/* TODO: use actual EXE name sent from process that called ReadConsole */
UNICODE_STRING ExeName = { 14, 14, L"cmd.exe" };
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
PHISTORY_BUFFER Hist;
for (; Entry != &Console->HistoryBuffers; Entry = Entry->Flink)
{
Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
if (RtlEqualUnicodeString(&ExeName, &Hist->ExeName, FALSE))
return Hist;
}
/* Couldn't find the buffer, create a new one */
Hist = HeapAlloc(Win32CsrApiHeap, 0, sizeof(HISTORY_BUFFER) + ExeName.Length);
if (!Hist)
return NULL;
Hist->MaxEntries = Console->HistoryBufferSize;
Hist->NumEntries = 0;
Hist->Entries = HeapAlloc(Win32CsrApiHeap, 0, Hist->MaxEntries * sizeof(UNICODE_STRING));
if (!Hist->Entries)
{
HeapFree(Win32CsrApiHeap, 0, Hist);
return NULL;
}
Hist->ExeName.Length = Hist->ExeName.MaximumLength = ExeName.Length;
Hist->ExeName.Buffer = (PWCHAR)(Hist + 1);
memcpy(Hist->ExeName.Buffer, ExeName.Buffer, ExeName.Length);
InsertHeadList(&Console->HistoryBuffers, &Hist->ListEntry);
return Hist;
}
static VOID
HistoryAddEntry(PCSRSS_CONSOLE Console)
{
UNICODE_STRING NewEntry;
PHISTORY_BUFFER Hist;
INT i;
NewEntry.Length = NewEntry.MaximumLength = Console->LineSize * sizeof(WCHAR);
NewEntry.Buffer = Console->LineBuffer;
if (!(Hist = HistoryCurrentBuffer(Console)))
return;
/* Don't add blank or duplicate entries */
if (NewEntry.Length == 0 || Hist->MaxEntries == 0 ||
(Hist->NumEntries > 0 &&
RtlEqualUnicodeString(&Hist->Entries[Hist->NumEntries - 1], &NewEntry, FALSE)))
{
return;
}
if (Console->HistoryNoDup)
{
/* Check if this line has been entered before */
for (i = Hist->NumEntries - 1; i >= 0; i--)
{
if (RtlEqualUnicodeString(&Hist->Entries[i], &NewEntry, FALSE))
{
/* Just rotate the list to bring this entry to the end */
NewEntry = Hist->Entries[i];
memmove(&Hist->Entries[i], &Hist->Entries[i + 1],
(Hist->NumEntries - (i + 1)) * sizeof(UNICODE_STRING));
Hist->Entries[Hist->NumEntries - 1] = NewEntry;
Hist->Position = Hist->NumEntries - 1;
return;
}
}
}
if (Hist->NumEntries == Hist->MaxEntries)
{
/* List is full, remove oldest entry */
RtlFreeUnicodeString(&Hist->Entries[0]);
memmove(&Hist->Entries[0], &Hist->Entries[1],
--Hist->NumEntries * sizeof(UNICODE_STRING));
}
if (NT_SUCCESS(RtlDuplicateUnicodeString(0, &NewEntry, &Hist->Entries[Hist->NumEntries])))
Hist->NumEntries++;
Hist->Position = Hist->NumEntries - 1;
}
static VOID
HistoryGetCurrentEntry(PCSRSS_CONSOLE Console, PUNICODE_STRING Entry)
{
PHISTORY_BUFFER Hist;
if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
Entry->Length = 0;
else
*Entry = Hist->Entries[Hist->Position];
}
static PHISTORY_BUFFER
HistoryFindBuffer(PCSRSS_CONSOLE Console, PUNICODE_STRING ExeName)
{
PLIST_ENTRY Entry = Console->HistoryBuffers.Flink;
while (Entry != &Console->HistoryBuffers)
{
/* For the history APIs, the caller is allowed to give only part of the name */
PHISTORY_BUFFER Hist = CONTAINING_RECORD(Entry, HISTORY_BUFFER, ListEntry);
if (RtlPrefixUnicodeString(ExeName, &Hist->ExeName, TRUE))
return Hist;
Entry = Entry->Flink;
}
return NULL;
}
VOID FASTCALL
HistoryDeleteBuffer(PHISTORY_BUFFER Hist)
{
if (!Hist)
return;
while (Hist->NumEntries != 0)
RtlFreeUnicodeString(&Hist->Entries[--Hist->NumEntries]);
HeapFree(Win32CsrApiHeap, 0, Hist->Entries);
RemoveEntryList(&Hist->ListEntry);
HeapFree(Win32CsrApiHeap, 0, Hist);
}
CSR_API(CsrGetCommandHistoryLength)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
PHISTORY_BUFFER Hist;
ULONG Length = 0;
INT i;
if (!Win32CsrValidateBuffer(ProcessData,
Request->Data.GetCommandHistoryLength.ExeName.Buffer,
Request->Data.GetCommandHistoryLength.ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName);
if (Hist)
{
for (i = 0; i < Hist->NumEntries; i++)
Length += Hist->Entries[i].Length + sizeof(WCHAR);
}
Request->Data.GetCommandHistoryLength.Length = Length;
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrGetCommandHistory)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status;
PHISTORY_BUFFER Hist;
PBYTE Buffer = (PBYTE)Request->Data.GetCommandHistory.History;
ULONG BufferSize = Request->Data.GetCommandHistory.Length;
INT i;
if (!Win32CsrValidateBuffer(ProcessData, Buffer, BufferSize, 1) ||
!Win32CsrValidateBuffer(ProcessData,
Request->Data.GetCommandHistory.ExeName.Buffer,
Request->Data.GetCommandHistory.ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &Request->Data.GetCommandHistory.ExeName);
if (Hist)
{
for (i = 0; i < Hist->NumEntries; i++)
{
if (BufferSize < (Hist->Entries[i].Length + sizeof(WCHAR)))
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
memcpy(Buffer, Hist->Entries[i].Buffer, Hist->Entries[i].Length);
Buffer += Hist->Entries[i].Length;
*(PWCHAR)Buffer = L'\0';
Buffer += sizeof(WCHAR);
}
}
Request->Data.GetCommandHistory.Length = Buffer - (PBYTE)Request->Data.GetCommandHistory.History;
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrExpungeCommandHistory)
{
PCSRSS_CONSOLE Console;
PHISTORY_BUFFER Hist;
NTSTATUS Status;
if (!Win32CsrValidateBuffer(ProcessData,
Request->Data.ExpungeCommandHistory.ExeName.Buffer,
Request->Data.ExpungeCommandHistory.ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &Request->Data.ExpungeCommandHistory.ExeName);
HistoryDeleteBuffer(Hist);
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrSetHistoryNumberCommands)
{
PCSRSS_CONSOLE Console;
PHISTORY_BUFFER Hist;
NTSTATUS Status;
WORD MaxEntries = Request->Data.SetHistoryNumberCommands.NumCommands;
PUNICODE_STRING OldEntryList, NewEntryList;
if (!Win32CsrValidateBuffer(ProcessData,
Request->Data.SetHistoryNumberCommands.ExeName.Buffer,
Request->Data.SetHistoryNumberCommands.ExeName.Length, 1))
{
return STATUS_ACCESS_VIOLATION;
}
Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Hist = HistoryFindBuffer(Console, &Request->Data.SetHistoryNumberCommands.ExeName);
if (Hist)
{
OldEntryList = Hist->Entries;
NewEntryList = HeapAlloc(Win32CsrApiHeap, 0,
MaxEntries * sizeof(UNICODE_STRING));
if (!NewEntryList)
{
Status = STATUS_NO_MEMORY;
}
else
{
/* If necessary, shrink by removing oldest entries */
for (; Hist->NumEntries > MaxEntries; Hist->NumEntries--)
{
RtlFreeUnicodeString(Hist->Entries++);
Hist->Position += (Hist->Position == 0);
}
Hist->MaxEntries = MaxEntries;
Hist->Entries = memcpy(NewEntryList, Hist->Entries,
Hist->NumEntries * sizeof(UNICODE_STRING));
HeapFree(Win32CsrApiHeap, 0, OldEntryList);
}
}
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrGetHistoryInfo)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Request->Data.SetHistoryInfo.HistoryBufferSize = Console->HistoryBufferSize;
Request->Data.SetHistoryInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
Request->Data.SetHistoryInfo.dwFlags = Console->HistoryNoDup;
ConioUnlockConsole(Console);
}
return Status;
}
CSR_API(CsrSetHistoryInfo)
{
PCSRSS_CONSOLE Console;
NTSTATUS Status = ConioConsoleFromProcessData(ProcessData, &Console);
if (NT_SUCCESS(Status))
{
Console->HistoryBufferSize = (WORD)Request->Data.SetHistoryInfo.HistoryBufferSize;
Console->NumberOfHistoryBuffers = (WORD)Request->Data.SetHistoryInfo.NumberOfHistoryBuffers;
Console->HistoryNoDup = Request->Data.SetHistoryInfo.dwFlags & HISTORY_NO_DUP_FLAG;
ConioUnlockConsole(Console);
}
return Status;
}
static VOID
LineInputSetPos(PCSRSS_CONSOLE Console, UINT Pos)
{
if (Pos != Console->LinePos && Console->Mode & ENABLE_ECHO_INPUT)
{
PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
UINT OldCursorX = Buffer->CurrentX;
UINT OldCursorY = Buffer->CurrentY;
INT XY = OldCursorY * Buffer->MaxX + OldCursorX;
XY += (Pos - Console->LinePos);
if (XY < 0)
XY = 0;
else if (XY >= Buffer->MaxY * Buffer->MaxX)
XY = Buffer->MaxY * Buffer->MaxX - 1;
Buffer->CurrentX = XY % Buffer->MaxX;
Buffer->CurrentY = XY / Buffer->MaxX;
ConioSetScreenInfo(Console, Buffer, OldCursorX, OldCursorY);
}
Console->LinePos = Pos;
}
static VOID
LineInputEdit(PCSRSS_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
{
UINT Pos = Console->LinePos;
UINT NewSize = Console->LineSize - NumToDelete + NumToInsert;
INT i;
/* Make sure there's always enough room for ending \r\n */
if (NewSize + 2 > Console->LineMaxSize)
return;
memmove(&Console->LineBuffer[Pos + NumToInsert],
&Console->LineBuffer[Pos + NumToDelete],
(Console->LineSize - (Pos + NumToDelete)) * sizeof(WCHAR));
memcpy(&Console->LineBuffer[Pos], Insertion, NumToInsert * sizeof(WCHAR));
if (Console->Mode & ENABLE_ECHO_INPUT)
{
for (i = Pos; i < NewSize; i++)
{
CHAR AsciiChar;
WideCharToMultiByte(Console->OutputCodePage, 0,
&Console->LineBuffer[i], 1,
&AsciiChar, 1, NULL, NULL);
ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE);
}
for (; i < Console->LineSize; i++)
{
ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE);
}
Console->LinePos = i;
}
Console->LineSize = NewSize;
LineInputSetPos(Console, Pos + NumToInsert);
}
static VOID
LineInputRecallHistory(PCSRSS_CONSOLE Console, INT Offset)
{
PHISTORY_BUFFER Hist;
if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
return;
Offset += Hist->Position;
Offset = max(Offset, 0);
Offset = min(Offset, Hist->NumEntries - 1);
Hist->Position = Offset;
LineInputSetPos(Console, 0);
LineInputEdit(Console, Console->LineSize,
Hist->Entries[Offset].Length / sizeof(WCHAR),
Hist->Entries[Offset].Buffer);
}
VOID FASTCALL
LineInputKeyDown(PCSRSS_CONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
UINT Pos = Console->LinePos;
PHISTORY_BUFFER Hist;
UNICODE_STRING Entry;
INT HistPos;
switch (KeyEvent->wVirtualKeyCode)
{
case VK_ESCAPE:
/* Clear entire line */
LineInputSetPos(Console, 0);
LineInputEdit(Console, Console->LineSize, 0, NULL);
return;
case VK_HOME:
/* Move to start of line. With ctrl, erase everything left of cursor */
LineInputSetPos(Console, 0);
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
LineInputEdit(Console, Pos, 0, NULL);
return;
case VK_END:
/* Move to end of line. With ctrl, erase everything right of cursor */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
else
LineInputSetPos(Console, Console->LineSize);
return;
case VK_LEFT:
/* Move left. With ctrl, move to beginning of previous word */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
{
while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
}
else
{
Pos -= (Pos > 0);
}
LineInputSetPos(Console, Pos);
return;
case VK_RIGHT:
case VK_F1:
/* Move right. With ctrl, move to beginning of next word */
if (KeyEvent->dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
{
while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
LineInputSetPos(Console, Pos);
return;
}
else
{
/* Recall one character (but don't overwrite current line) */
HistoryGetCurrentEntry(Console, &Entry);
if (Pos < Console->LineSize)
LineInputSetPos(Console, Pos + 1);
else if (Pos * sizeof(WCHAR) < Entry.Length)
LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
}
return;
case VK_INSERT:
/* Toggle between insert and overstrike */
Console->LineInsertToggle = !Console->LineInsertToggle;
ConioSetCursorInfo(Console, Console->ActiveBuffer);
return;
case VK_DELETE:
/* Remove character to right of cursor */
if (Pos != Console->LineSize)
LineInputEdit(Console, 1, 0, NULL);
return;
case VK_PRIOR:
/* Recall first history entry */
LineInputRecallHistory(Console, -((WORD)-1));
return;
case VK_NEXT:
/* Recall last history entry */
LineInputRecallHistory(Console, +((WORD)-1));
return;
case VK_UP:
case VK_F5:
/* Recall previous history entry. On first time, actually recall the
* current (usually last) entry; on subsequent times go back. */
LineInputRecallHistory(Console, Console->LineUpPressed ? -1 : 0);
Console->LineUpPressed = TRUE;
return;
case VK_DOWN:
/* Recall next history entry */
LineInputRecallHistory(Console, +1);
return;
case VK_F3:
/* Recall remainder of current history entry */
HistoryGetCurrentEntry(Console, &Entry);
if (Pos * sizeof(WCHAR) < Entry.Length)
{
UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
}
return;
case VK_F6:
/* Insert a ^Z character */
KeyEvent->uChar.UnicodeChar = 26;
break;
case VK_F7:
if (KeyEvent->dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
HistoryDeleteBuffer(HistoryCurrentBuffer(Console));
return;
case VK_F8:
/* Search for history entries starting with input. */
if (!(Hist = HistoryCurrentBuffer(Console)) || Hist->NumEntries == 0)
return;
/* Like Up/F5, on first time start from current (usually last) entry,
* but on subsequent times start at previous entry. */
if (Console->LineUpPressed)
Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
Console->LineUpPressed = TRUE;
Entry.Length = Console->LinePos * sizeof(WCHAR);
Entry.Buffer = Console->LineBuffer;
/* Keep going backwards, even wrapping around to the end,
* until we get back to starting point */
HistPos = Hist->Position;
do
{
if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
{
Hist->Position = HistPos;
LineInputEdit(Console, Console->LineSize - Pos,
Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
&Hist->Entries[HistPos].Buffer[Pos]);
/* Cursor stays where it was */
LineInputSetPos(Console, Pos);
return;
}
if (--HistPos < 0) HistPos += Hist->NumEntries;
} while (HistPos != Hist->Position);
return;
}
if (KeyEvent->uChar.UnicodeChar == L'\b' && Console->Mode & ENABLE_PROCESSED_INPUT)
{
/* backspace handling - if processed input enabled then we handle it here
* otherwise we treat it like a normal char. */
if (Pos > 0)
{
LineInputSetPos(Console, Pos - 1);
LineInputEdit(Console, 1, 0, NULL);
}
}
else if (KeyEvent->uChar.UnicodeChar == L'\r')
{
HistoryAddEntry(Console);
/* TODO: Expand aliases */
LineInputSetPos(Console, Console->LineSize);
Console->LineBuffer[Console->LineSize++] = L'\r';
if (Console->Mode & ENABLE_ECHO_INPUT)
ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);
/* Add \n if processed input. There should usually be room for it,
* but an exception to the rule exists: the buffer could have been
* pre-filled with LineMaxSize - 1 characters. */
if (Console->Mode & ENABLE_PROCESSED_INPUT &&
Console->LineSize < Console->LineMaxSize)
{
Console->LineBuffer[Console->LineSize++] = L'\n';
if (Console->Mode & ENABLE_ECHO_INPUT)
ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE);
}
Console->LineComplete = TRUE;
Console->LinePos = 0;
}
else if (KeyEvent->uChar.UnicodeChar != L'\0')
{
if (KeyEvent->uChar.UnicodeChar < 0x20 &&
Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
{
/* Control key client wants to handle itself (e.g. for tab completion) */
Console->LineBuffer[Console->LineSize++] = L' ';
Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
Console->LineComplete = TRUE;
Console->LinePos = 0;
}
else
{
/* Normal character */
BOOL Overstrike = Console->LineInsertToggle && Console->LinePos != Console->LineSize;
LineInputEdit(Console, Overstrike, 1, &KeyEvent->uChar.UnicodeChar);
}
}
}
/* EOF */
Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

+52
View File
@@ -0,0 +1,52 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32 subsystem
* FILE: subsys/csrss/win32csr/resource.h
* PURPOSE: Resource #defines
*/
#pragma once
#define IDD_END_NOW 10
#define IDD_NOT_RESPONDING 11
#define IDD_SWITCH_APP 12
#define IDC_STATIC -1
#define IDC_PROGRESS 101
#define IDC_END_NOW 102
#define IDC_STATIC_CUR_APP 103
#define ID_SYSTEM_EDIT_MARK 1001
#define ID_SYSTEM_EDIT_COPY 1002
#define ID_SYSTEM_EDIT_PASTE 1003
#define ID_SYSTEM_EDIT_SELECTALL 1004
#define ID_SYSTEM_EDIT_SCROLL 1005
#define ID_SYSTEM_EDIT_FIND 1006
#define ID_SYSTEM_DEFAULTS 1007
#define ID_SYSTEM_PROPERTIES 1008
#define NCPOPUP_MENU 103
#define IDS_EDIT 204
#define IDS_MARK 205
#define IDS_COPY 206
#define IDS_PASTE 207
#define IDS_SELECTALL 208
#define IDS_SCROLL 209
#define IDS_FIND 210
#define IDS_DEFAULTS 211
#define IDS_PROPERTIES 212
//scrollbar resource ids
#define IDS_SCROLLHERE 304
#define IDS_SCROLLTOP 305
#define IDS_SCROLLBOTTOM 306
#define IDS_SCROLLPAGE_UP 307
#define IDS_SCROLLPAGE_DOWN 308
#define IDS_SCROLLUP 309
#define IDS_SCROLLDOWN 310
#define IDS_COMMAND_PROMPT 500
/* EOF */
+73
View File
@@ -0,0 +1,73 @@
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1 ICON DISCARDABLE res/terminal.ico
#ifdef LANGUAGE_BG_BG
#include "lang/bg-BG.rc"
#endif
#ifdef LANGUAGE_CS_CZ
#include "lang/cs-CZ.rc"
#endif
#ifdef LANGUAGE_DE_DE
#include "lang/de-DE.rc"
#endif
#ifdef LANGUAGE_EL_GR
#include "lang/el-GR.rc"
#endif
#ifdef LANGUAGE_EN_US
#include "lang/en-US.rc"
#endif
#ifdef LANGUAGE_ES_ES
#include "lang/es-ES.rc"
#endif
#ifdef LANGUAGE_FR_FR
#include "lang/fr-FR.rc"
#endif
#ifdef LANGUAGE_ID_ID
#include "lang/id-ID.rc"
#endif
#ifdef LANGUAGE_IT_IT
#include "lang/it-IT.rc"
#endif
#ifdef LANGUAGE_JA_JP
#include "lang/ja-JP.rc"
#endif
#ifdef LANGUAGE_NB_NO
#include "lang/no-NO.rc"
#endif
#ifdef LANGUAGE_SK_SK
#include "lang/sk-SK.rc"
#endif
#ifdef LANGUAGE_SV_SE
#include "lang/sv-SE.rc"
#endif
#ifdef LANGUAGE_ZH_CN
#include "lang/zh-CN.rc"
#endif
#ifdef LANGUAGE_ZH_TW
#include "lang/zh-TW.rc"
#endif
// UTF-8
#pragma code_page(65001)
#ifdef LANGUAGE_HE_IL
#include "lang/he-IL.rc"
#endif
#ifdef LANGUAGE_PL_PL
#include "lang/pl-PL.rc"
#endif
#ifdef LANGUAGE_PT_BR
#include "lang/pt-BR.rc"
#endif
#ifdef LANGUAGE_RO_RO
#include "lang/ro-RO.rc"
#endif
#ifdef LANGUAGE_RU_RU
#include "lang/ru-RU.rc"
#endif
#ifdef LANGUAGE_UK_UA
#include "lang/uk-UA.rc"
#endif
#ifdef LANGUAGE_TR_TR
#include "lang/tr-TR.rc"
#endif
+487
View File
@@ -0,0 +1,487 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/tuiconsole.c
* PURPOSE: Implementation of text-mode consoles
*/
#define NDEBUG
#include "w32csr.h"
#include <debug.h>
CRITICAL_SECTION ActiveConsoleLock;
static COORD PhysicalConsoleSize;
static HANDLE ConsoleDeviceHandle;
static PCSRSS_CONSOLE ActiveConsole;
static BOOL ConsInitialized = FALSE;
static LRESULT CALLBACK
TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_ACTIVATE)
{
if (LOWORD(wParam) != WA_INACTIVE)
{
SetFocus(hWnd);
ConioDrawConsole(ActiveConsole);
}
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
static BOOL FASTCALL
TuiStartService(LPCWSTR lpServiceName)
{
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
BOOL ret = FALSE;
hSCManager = OpenSCManagerW(NULL, NULL, 0);
if (hSCManager == NULL)
goto cleanup;
hService = OpenServiceW(hSCManager, lpServiceName, SERVICE_START);
if (hService == NULL)
goto cleanup;
ret = StartServiceW(hService, 0, NULL);
if (!ret)
goto cleanup;
ret = TRUE;
cleanup:
if (hSCManager != NULL)
CloseServiceHandle(hSCManager);
if (hService != NULL)
CloseServiceHandle(hService);
return ret;
}
static BOOL FASTCALL
TuiInit(DWORD OemCP)
{
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned;
WNDCLASSEXW wc;
USHORT TextAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
TuiStartService(L"Blue");
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == ConsoleDeviceHandle)
{
DPRINT1("Failed to open BlueScreen.\n");
return FALSE;
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_LOADFONT,
&OemCP, sizeof(OemCP), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to load the font for codepage %d\n", OemCP);
/* Let's suppose the font is good enough to continue */
}
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE,
&TextAttribute, sizeof(TextAttribute), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1("Failed to set text attribute\n");
}
ActiveConsole = NULL;
InitializeCriticalSection(&ActiveConsoleLock);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO,
NULL, 0, &ScrInfo, sizeof(ScrInfo), &BytesReturned, NULL))
{
DPRINT1("Failed to get console info\n");
return FALSE;
}
PhysicalConsoleSize = ScrInfo.dwSize;
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"TuiConsoleWindowClass";
wc.lpfnWndProc = TuiConsoleWndProc;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
if (RegisterClassExW(&wc) == 0)
{
DPRINT1("Failed to register console wndproc\n");
return FALSE;
}
return TRUE;
}
static VOID WINAPI
TuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
{
Buffer->DefaultAttrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
}
static void FASTCALL
TuiCopyRect(char *Dest, PCSRSS_SCREEN_BUFFER Buff, SMALL_RECT *Region)
{
UINT SrcDelta, DestDelta;
LONG i;
PBYTE Src, SrcEnd;
Src = ConioCoordToPointer(Buff, Region->Left, Region->Top);
SrcDelta = Buff->MaxX * 2;
SrcEnd = Buff->Buffer + Buff->MaxY * Buff->MaxX * 2;
DestDelta = ConioRectWidth(Region) * 2;
for (i = Region->Top; i <= Region->Bottom; i++)
{
memcpy(Dest, Src, DestDelta);
Src += SrcDelta;
if (SrcEnd <= Src)
{
Src -= Buff->MaxY * Buff->MaxX * 2;
}
Dest += DestDelta;
}
}
static VOID WINAPI
TuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
{
DWORD BytesReturned;
PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
PCONSOLE_DRAW ConsoleDraw;
UINT ConsoleDrawSize;
if (ActiveConsole != Console)
{
return;
}
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
ConsoleDraw = HeapAlloc(Win32CsrApiHeap, 0, ConsoleDrawSize);
if (NULL == ConsoleDraw)
{
DPRINT1("HeapAlloc failed\n");
return;
}
ConsoleDraw->X = Region->Left;
ConsoleDraw->Y = Region->Top;
ConsoleDraw->SizeX = ConioRectWidth(Region);
ConsoleDraw->SizeY = ConioRectHeight(Region);
ConsoleDraw->CursorX = Buff->CurrentX;
ConsoleDraw->CursorY = Buff->CurrentY;
TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
{
DPRINT1("Failed to draw console\n");
HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
return;
}
HeapFree(Win32CsrApiHeap, 0, ConsoleDraw);
}
static VOID WINAPI
TuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
DWORD BytesWritten;
PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
if (ActiveConsole->ActiveBuffer != Buff)
{
return;
}
if (! WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
}
static BOOL WINAPI
TuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
{
CONSOLE_CURSOR_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwSize = ConioEffectiveCursorSize(Console, 100);
Info.bVisible = Buff->CursorInfo.bVisible;
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_CURSOR_INFO,
&Info, sizeof(Info), NULL, 0, &BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor info\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
{
CONSOLE_SCREEN_BUFFER_INFO Info;
DWORD BytesReturned;
if (ActiveConsole->ActiveBuffer != Buff)
{
return TRUE;
}
Info.dwCursorPosition.X = Buff->CurrentX;
Info.dwCursorPosition.Y = Buff->CurrentY;
Info.wAttributes = Buff->DefaultAttrib;
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
&Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
&BytesReturned, NULL))
{
DPRINT1( "Failed to set cursor position\n" );
return FALSE;
}
return TRUE;
}
static BOOL WINAPI
TuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
{
return TRUE;
}
static BOOL WINAPI
TuiChangeTitle(PCSRSS_CONSOLE Console)
{
return TRUE;
}
static VOID WINAPI
TuiCleanupConsole(PCSRSS_CONSOLE Console)
{
DestroyWindow(Console->hWindow);
EnterCriticalSection(&ActiveConsoleLock);
/* Switch to next console */
if (ActiveConsole == Console)
{
ActiveConsole = Console->Next != Console ? Console->Next : NULL;
}
if (Console->Next != Console)
{
Console->Prev->Next = Console->Next;
Console->Next->Prev = Console->Prev;
}
LeaveCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
ConioDrawConsole(ActiveConsole);
}
}
static BOOL WINAPI
TuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
{
return TRUE;
}
static NTSTATUS WINAPI
TuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
DWORD WINAPI
TuiConsoleThread (PVOID Data)
{
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data;
HWND NewWindow;
MSG msg;
NewWindow = CreateWindowW(L"TuiConsoleWindowClass",
Console->Title.Buffer,
0,
-32000, -32000, 0, 0,
NULL, NULL,
(HINSTANCE) GetModuleHandleW(NULL),
(PVOID) Console);
Console->hWindow = NewWindow;
if (NULL == NewWindow)
{
DPRINT1("CSR: Unable to create console window\n");
return 1;
}
SetForegroundWindow(Console->hWindow);
while (TRUE)
{
GetMessageW(&msg, 0, 0, 0);
DispatchMessage(&msg);
TranslateMessage(&msg);
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
{
ConioProcessKey(&msg, Console, TRUE);
}
}
return 0;
}
static CSRSS_CONSOLE_VTBL TuiVtbl =
{
TuiInitScreenBuffer,
TuiWriteStream,
TuiDrawRegion,
TuiSetCursorInfo,
TuiSetScreenInfo,
TuiUpdateScreenInfo,
TuiChangeTitle,
TuiCleanupConsole,
TuiChangeIcon,
TuiResizeBuffer,
};
NTSTATUS FASTCALL
TuiInitConsole(PCSRSS_CONSOLE Console)
{
HANDLE ThreadHandle;
if (! ConsInitialized)
{
ConsInitialized = TRUE;
if (! TuiInit(Console->CodePage))
{
ConsInitialized = FALSE;
return STATUS_UNSUCCESSFUL;
}
}
Console->Vtbl = &TuiVtbl;
Console->hWindow = NULL;
Console->Size = PhysicalConsoleSize;
Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread,
Console, 0, NULL);
if (NULL == ThreadHandle)
{
DPRINT1("CSR: Unable to create console thread\n");
return STATUS_UNSUCCESSFUL;
}
CloseHandle(ThreadHandle);
EnterCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{
Console->Prev = ActiveConsole;
Console->Next = ActiveConsole->Next;
ActiveConsole->Next->Prev = Console;
ActiveConsole->Next = Console;
}
else
{
Console->Prev = Console;
Console->Next = Console;
}
ActiveConsole = Console;
LeaveCriticalSection(&ActiveConsoleLock);
return STATUS_SUCCESS;
}
PCSRSS_CONSOLE FASTCALL
TuiGetFocusConsole(VOID)
{
return ActiveConsole;
}
BOOL FASTCALL
TuiSwapConsole(int Next)
{
static PCSRSS_CONSOLE SwapConsole = NULL; /* console we are thinking about swapping with */
DWORD BytesReturned;
ANSI_STRING Title;
void * Buffer;
COORD *pos;
if (0 != Next)
{
/* alt-tab, swap consoles */
/* move SwapConsole to next console, and print its title */
EnterCriticalSection(&ActiveConsoleLock);
if (! SwapConsole)
{
SwapConsole = ActiveConsole;
}
SwapConsole = (0 < Next ? SwapConsole->Next : SwapConsole->Prev);
Title.MaximumLength = RtlUnicodeStringToAnsiSize(&SwapConsole->Title);
Title.Length = 0;
Buffer = HeapAlloc(Win32CsrApiHeap,
0,
sizeof(COORD) + Title.MaximumLength);
pos = (COORD *)Buffer;
Title.Buffer = (PVOID)((ULONG_PTR)Buffer + sizeof( COORD ));
RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE);
pos->Y = PhysicalConsoleSize.Y / 2;
pos->X = (PhysicalConsoleSize.X - Title.Length) / 2;
/* redraw the console to clear off old title */
ConioDrawConsole(ActiveConsole);
if (! DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER,
NULL, 0, Buffer, sizeof(COORD) + Title.Length,
&BytesReturned, NULL))
{
DPRINT1( "Error writing to console\n" );
}
HeapFree(Win32CsrApiHeap, 0, Buffer);
LeaveCriticalSection(&ActiveConsoleLock);
return TRUE;
}
else if (NULL != SwapConsole)
{
EnterCriticalSection(&ActiveConsoleLock);
if (SwapConsole != ActiveConsole)
{
/* first remove swapconsole from the list */
SwapConsole->Prev->Next = SwapConsole->Next;
SwapConsole->Next->Prev = SwapConsole->Prev;
/* now insert before activeconsole */
SwapConsole->Next = ActiveConsole;
SwapConsole->Prev = ActiveConsole->Prev;
ActiveConsole->Prev->Next = SwapConsole;
ActiveConsole->Prev = SwapConsole;
}
ActiveConsole = SwapConsole;
SwapConsole = NULL;
ConioDrawConsole(ActiveConsole);
LeaveCriticalSection(&ActiveConsoleLock);
return TRUE;
}
else
{
return FALSE;
}
}
/* EOF */
+14
View File
@@ -0,0 +1,14 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/tuiconsole.h
* PURPOSE: Interface to text-mode consoles
*/
#include "api.h"
extern NTSTATUS FASTCALL TuiInitConsole(PCSRSS_CONSOLE Console);
extern PCSRSS_CONSOLE FASTCALL TuiGetFocusConsole(VOID);
extern BOOL FASTCALL TuiSwapConsole(int Next);
/* EOF */
+46
View File
@@ -0,0 +1,46 @@
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#include <stdio.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winnls.h>
#include <winreg.h>
#include <winsvc.h>
#include <wincon.h>
#define NTOS_MODE_USER
#include <ndk/iofuncs.h>
#include <ndk/kefuncs.h>
#include <ndk/mmfuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/umfuncs.h>
#include <psapi.h>
/* External Winlogon Header */
#include <winlogon.h>
/* Internal CSRSS Headers */
#include <conio.h>
#include <csrplugin.h>
#include <desktopbg.h>
#include "guiconsole.h"
#include "tuiconsole.h"
/* Public Win32K Headers */
#include <ntuser.h>
#include "resource.h"
/* shared header with console.dll */
#include "console.h"
VOID
WINAPI
Win32CsrHardError(
IN PCSR_THREAD ThreadData,
IN PHARDERROR_MSG Message);
/* EOF */
+78
View File
@@ -0,0 +1,78 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: subsys/csrss/win32csr/win32csr.h
* PURPOSE: Interface to win32csr.dll
*/
#pragma once
#include <objbase.h>
extern HANDLE Win32CsrApiHeap;
extern HINSTANCE Win32CsrDllHandle;
typedef struct Object_tt
{
LONG Type;
struct tagCSRSS_CONSOLE *Console;
LONG AccessRead, AccessWrite;
LONG ExclusiveRead, ExclusiveWrite;
LONG HandleCount;
} Object_t;
typedef struct _CSRSS_HANDLE
{
Object_t *Object;
DWORD Access;
BOOL Inheritable;
DWORD ShareMode;
} CSRSS_HANDLE, *PCSRSS_HANDLE;
typedef VOID (WINAPI *CSR_CLEANUP_OBJECT_PROC)(Object_t *Object);
typedef struct tagCSRSS_OBJECT_DEFINITION
{
LONG Type;
CSR_CLEANUP_OBJECT_PROC CsrCleanupObjectProc;
} CSRSS_OBJECT_DEFINITION, *PCSRSS_OBJECT_DEFINITION;
/* handle.c */
NTSTATUS FASTCALL Win32CsrInsertObject(PCSR_PROCESS ProcessData,
PHANDLE Handle,
Object_t *Object,
DWORD Access,
BOOL Inheritable,
DWORD ShareMode);
NTSTATUS FASTCALL Win32CsrLockObject(PCSR_PROCESS ProcessData,
HANDLE Handle,
Object_t **Object,
DWORD Access,
long Type);
VOID FASTCALL Win32CsrUnlockObject(Object_t *Object);
NTSTATUS FASTCALL Win32CsrReleaseObject(PCSR_PROCESS ProcessData,
HANDLE Object);
VOID WINAPI Win32CsrReleaseConsole(PCSR_PROCESS ProcessData);
NTSTATUS WINAPI Win32CsrDuplicateHandleTable(PCSR_PROCESS SourceProcessData,
PCSR_PROCESS TargetProcessData);
CSR_API(CsrGetHandle);
CSR_API(CsrCloseHandle);
CSR_API(CsrVerifyHandle);
CSR_API(CsrDuplicateHandle);
CSR_API(CsrGetInputWaitHandle);
BOOL FASTCALL Win32CsrValidateBuffer(PCSR_PROCESS ProcessData,
PVOID Buffer,
SIZE_T NumElements,
SIZE_T ElementSize);
NTSTATUS FASTCALL Win32CsrEnumProcesses(CSRSS_ENUM_PROCESS_PROC EnumProc,
PVOID Context);
/* exitros.c */
CSR_API(CsrExitReactos);
CSR_API(CsrSetLogonNotifyWindow);
CSR_API(CsrRegisterLogonProcess);
CSR_API(CsrSoundSentry);
/* EOF */
+12
View File
@@ -0,0 +1,12 @@
#include <windef.h>
#include <winuser.h>
#include "resource.h"
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "CSRSS subsystem usermode code\0"
#define REACTOS_STR_INTERNAL_NAME "win32csr\0"
#define REACTOS_STR_ORIGINAL_FILENAME "win32csr.dll\0"
#include <reactos/version.rc>
#include "rsrc.rc"
@@ -0,0 +1 @@
@ stdcall Win32CsrInitialization(ptr)