Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

256 lines
6.0 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
os2srv.c
Abstract:
This is the main startup module for the OS/2 Emulation Subsystem Server
Author:
Steve Wood (stevewo) 22-Aug-1989
Environment:
User Mode Only
Revision History:
--*/
#include "os2srv.h"
#include "os2win.h"
#define NTOS2_ONLY
#include "sesport.h"
#include <winerror.h>
ULONG
GetKeyboardRegistryChange(
VOID
);
HANDLE
CreateEventW(
PVOID lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCWSTR lpName
);
BOOL
SetEvent(
HANDLE hEvent
);
// Defined in <winbase.h> but we can't include it in this file
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
PVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
// Flag to let OS2SRV know whether or not to ignore LOGOFF (when started as a service)
BOOLEAN fService = FALSE;
int __cdecl
main(
IN ULONG argc,
IN PCH argv[],
IN PCH envp[],
IN ULONG DebugFlag OPTIONAL
)
{
LARGE_INTEGER TimeOut;
PLARGE_INTEGER pTimeOut;
NTSTATUS Status;
HANDLE SmPort;
UNICODE_STRING Os2Name;
SCREQUESTMSG Request;
ULONG Rc, i;
HANDLE InitialEventHandle;
SECURITY_ATTRIBUTES Sa;
CHAR localSecurityDescriptor[SECURITY_DESCRIPTOR_MIN_LENGTH];
if ((argc > 1) && (!_stricmp(argv[1], "/S")))
{
fService = TRUE;
}
// Check whether Os2SSService environment variable is set
if (!fService)
{
char TmpBuffer[256];
if (GetEnvironmentVariableA(
"Os2SSService",
&TmpBuffer[0],
256))
{
// non-zero return code means variable was found
fService = TRUE;
}
}
else
{
if (!SetEnvironmentVariableA(
"Os2SSService",
"1"))
{
#if DBG
KdPrint(("OS2SRV: failed to SetEnvironment variable Os2SSService, error=%x\n",
GetLastError()));
#endif
}
}
UNREFERENCED_PARAMETER(DebugFlag);
environ = envp;
//
// Create Win32 event to ensure that there is only one os2srv in system.
//
if (CreateEventW(
NULL,
TRUE, // Notification event
FALSE, // Nonsignaled
L"OS2SRVONLY1EVENT"
)) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
#if DBG
KdPrint(( "OS2SRV: Unable to initialize server. Another server exists\n"));
#endif
ExitProcess(1);
}
}
else {
#if DBG
KdPrint(( "OS2SRV: Unable to initialize server - failed to create first event, error=%d\n",
GetLastError()));
#endif
ExitProcess(1);
}
// Create security attribute record granting access to all
Sa.nLength = sizeof(Sa);
Sa.bInheritHandle = TRUE;
Status = RtlCreateSecurityDescriptor( (PSECURITY_DESCRIPTOR)
&localSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION );
if (!NT_SUCCESS( Status ))
{
#if DBG
KdPrint(("OS2SRV: failed at RtlCreateSecurityDescriptor %x\n", Status));
ASSERT(FALSE);
#endif
ExitProcess(1);
}
Status = RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR)
&localSecurityDescriptor,
(BOOLEAN)TRUE,
(PACL) NULL,
(BOOLEAN)FALSE );
if (!NT_SUCCESS( Status ))
{
#if DBG
KdPrint(("OS2SRV: failed at RtlSetDaclSecurityDescriptor %x\n", Status));
ASSERT(FALSE);
#endif
ExitProcess(1);
}
Sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR) &localSecurityDescriptor;
//
// Try to open handle to event that was created by the 1st client. If the
// server was invoked before clients it will create the event.
//
InitialEventHandle = CreateEventW(
&Sa,
TRUE, // Notification event
FALSE, // Nonsignaled
U_OS2_SS_INITIALIZATION_EVENT
);
if (!InitialEventHandle) {
#if DBG
KdPrint(("OS2SRV: Fail to open initialization event, error %d\n", GetLastError()));
#endif
ExitProcess(1);
}
Status = SmConnectToSm(NULL,NULL,0,&SmPort);
if ( NT_SUCCESS(Status) ) {
RtlInitUnicodeString(&Os2Name,L"Os2");
SmLoadDeferedSubsystem(SmPort,&Os2Name);
}
Status = Os2Initialize();
//
// Notify all clients that server is up and running.
//
if (!SetEvent(InitialEventHandle)) {
#if DBG
KdPrint(("OS2SRV: Fail to set initialization event, error %d\n", GetLastError()));
#endif
}
if (!NT_SUCCESS( Status )) {
#if DBG
KdPrint(( "OS2SRV: Unable to initialize server. Status == %X\n",
Status
));
#endif
NtTerminateProcess( NtCurrentProcess(), Status );
}
Request.Request = KbdRequest;
Request.d.Kbd.Request = KBDNewCountry;
PORT_MSG_TOTAL_LENGTH(Request) = sizeof(SCREQUESTMSG);
PORT_MSG_DATA_LENGTH(Request) = sizeof(SCREQUESTMSG) - sizeof(PORT_MESSAGE);
PORT_MSG_ZERO_INIT(Request) = 0L;
while ( TRUE )
{
Rc = GetKeyboardRegistryChange();
if (Rc == 0)
{
break;
}
Request.d.Kbd.d.CodePage = Rc;
for ( i = 1 ; (i < OS2_MAX_SESSION) ; i++ )
{
if (SessionTable[i].Session)
{
NtRequestPort(
((POS2_SESSION)SessionTable[i].Session)->ConsolePort,
(PPORT_MESSAGE) &Request
);
}
}
}
TimeOut.LowPart = 0x0;
TimeOut.HighPart = 0x80000000;
pTimeOut = &TimeOut;
rewait:
NtDelayExecution(TRUE, pTimeOut);
goto rewait;
return( 0 );
}