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.
 
 
 
 
 
 

814 lines
21 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
dllsm.c
Abstract:
This module implements the OS/2 V2.0 Session Management API Calls
Author:
Steve Wood (stevewo) 20-Sep-1989
Revision History:
--*/
#define INCL_OS2V20_TASKING
#define INCL_OS2V20_SESSIONMGR
#define INCL_OS2V20_ERRORS
#define INCL_OS2V20_QUEUES
#include "os2dll.h"
#include "os2win.h"
extern HANDLE hOs2Srv;
VOID
Od2CloseSrvHandle(
IN ULONG HandleNumber,
IN HANDLE Handle1,
IN HANDLE Handle2,
IN HANDLE Handle3
);
VOID
Od2PrepareStdHandleRedirection(
IN ULONG EnableFlags,
OUT POS2_STDHANDLES StdStruc
);
VOID
Od2CleanupStdHandleRedirection(
IN POS2_STDHANDLES StdStruc
);
APIRET
DosShutdown(
ULONG ulReserved
)
{
UNREFERENCED_PARAMETER(ulReserved);
return( ERROR_INVALID_FUNCTION );
}
APIRET
DosStartSession(
IN PSTARTDATA StartData,
OUT PULONG SessionId,
OUT PPID ProcessId
)
{
OS2_API_MSG m;
POS2_DOSEXECPGM_MSG a = &m.u.DosStartSession.ExecPgmInformation;
POS2_DOSSTARTSESSION_INFO b = &m.u.DosStartSession.StartSessionInformation;
POS2_CAPTURE_HEADER CaptureBuffer;
APIRET rc;
PID whocares;
PSZ TmpObjectBuffer;
ULONG TmpObjectBuffLen, Length, Flags = EXEC_ASYNCRESULT;
ULONG PgmLength, ArgLength = 0;
ULONG dwProcessId;
USHORT TmpInheritOpt;
PSZ PgmInput = NULL;
PSZ PgmName = NULL;
PSZ VariablesBuffer, ArgumentsBuffer;
PSZ ExecFileName;
NTSTATUS Status, ExePgmFileType;
#if PMNT
ULONG IsPMApp;
#endif // PMNT
HANDLE hThread, hProcess, hRedirectedFile;
THREAD_BASIC_INFORMATION ThreadInfo;
OS2_STDHANDLES StdStruc;
BOOLEAN bSuccess;
#if DBG
PSZ RoutineName = "DosStartSession";
#endif
try
{
Od2ProbeForWrite((PVOID)ProcessId, sizeof(PID), 1);
Od2ProbeForWrite(SessionId, sizeof(ULONG), 1);
Length = StartData->Length;
Od2ProbeForRead(StartData, Length, 1);
}
except( EXCEPTION_EXECUTE_HANDLER )
{
Od2ExitGP();
}
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s: Pgm %s\n", RoutineName, StartData->PgmName);
}
#endif
if (Length < 18)
{
return ERROR_INVALID_PARAMETER;
}
if (Length > 50)
{
TmpObjectBuffer = StartData->ObjectBuffer;
TmpObjectBuffLen = StartData->ObjectBuffLen;
}
else
{
TmpObjectBuffer = (PSZ)NULL;
TmpObjectBuffLen = 0;
}
if (Length > 24)
{
TmpInheritOpt = StartData->InheritOpt;
} else
{
TmpInheritOpt = 0;
}
if( (StartData->PgmName != NULL) && (*(StartData->PgmName) != 0) )
{
PgmLength = strlen(StartData->PgmName);
if (StartData->PgmInputs != NULL)
{
ArgLength = strlen(StartData->PgmInputs);
}
PgmInput = (PSZ) RtlAllocateHeap( Od2Heap, 0, ArgLength + PgmLength + 2);
if (PgmInput == NULL)
{
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s cannot Allocate storage for PgmInput", RoutineName );
}
#endif
return( ERROR_NOT_ENOUGH_MEMORY );
}
RtlMoveMemory(PgmInput, StartData->PgmName, PgmLength);
PgmInput[PgmLength++] = ' ';
if (StartData->PgmInputs != NULL)
{
RtlMoveMemory(PgmInput + PgmLength, StartData->PgmInputs, ArgLength );
}
PgmInput[PgmLength + ArgLength] = '\0';
}
else
{
//
// default is "CMD.EXE"
//
PgmLength = strlen("CMD.EXE");
if (StartData->PgmInputs != NULL)
{
ArgLength = strlen(StartData->PgmInputs);
}
PgmInput = (PSZ) RtlAllocateHeap( Od2Heap, 0, ArgLength + PgmLength + 2);
if (PgmInput == NULL)
{
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s cannot Allocate storage for PgmInput", RoutineName );
}
#endif
return( ERROR_NOT_ENOUGH_MEMORY );
}
RtlMoveMemory(PgmInput, "CMD.EXE", PgmLength);
PgmInput[PgmLength++] = ' ';
if (StartData->PgmInputs != NULL)
{
RtlMoveMemory(PgmInput + PgmLength, StartData->PgmInputs, ArgLength );
}
PgmInput[PgmLength + ArgLength] = '\0';
PgmName = "CMD.EXE";
}
VariablesBuffer = (PSZ)StartData->Environment;
ArgumentsBuffer = (PgmInput) ? (PSZ)PgmInput : (PSZ)StartData->PgmInputs;
ExecFileName = PgmName ? PgmName : StartData->PgmName;
if (StartData->TraceOpt){
Flags = EXEC_TRACETREE;
}
rc = Od2FormatExecPgmMessage( a,
&CaptureBuffer,
&ExePgmFileType,
#if PMNT
&IsPMApp,
#endif // PMNT
TmpObjectBuffer,
TmpObjectBuffLen,
Flags | 0x80000000,
&VariablesBuffer,
&ArgumentsBuffer,
&ExecFileName
);
if (PgmInput != NULL)
{
RtlFreeHeap( Od2Heap, 0, PgmInput );
}
if (rc != NO_ERROR)
{
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s cannot FormatParms (%lu) for %s\n", RoutineName, rc, StartData->PgmName);
}
#endif
return( rc );
}
b->QueueHandleIndex = 0;
b->SessionType = (USHORT)((Length > 30 ) ? StartData->SessionType : 0);
if ( StartData->Related )
{
//
// if term queue supplied, then open the queue and pass handle
// to server.
//
if ( StartData->TermQ && (*(StartData->TermQ) != '\0'))
{
//
// YaronS: BUGBUG - the line below looks sloppy, because
// the QueueHandle that is opened is ignored - check later
//
rc = DosOpenQueue(&whocares,(PHQUEUE)(&b->QueueHandleIndex),StartData->TermQ);
if ( rc != NO_ERROR )
{
RtlFreeHeap( Od2Heap, 0, ArgumentsBuffer );
RtlFreeHeap( Od2Heap, 0, VariablesBuffer );
RtlFreeHeap( Od2Heap, 0, ExecFileName );
Od2FreeCaptureBuffer( CaptureBuffer );
NtClose(a->hRedirectedFile);
return ERROR_QUE_NAME_NOT_EXIST;
}
b->QueueHandleIndex |= 0x80000000;
}
}
//
// we don't want to make a copy of the file handle table so we don't
// have to lock it during the call to the server because the file handles
// could go away while we're trying to dup them.
//
AcquireFileLockShared(
#if DBG
RoutineName
#endif
);
a->FileSystemParameters.ParentHandleTable = HandleTable;
a->FileSystemParameters.ParentTableLength = HandleTableLength;
a->FileSystemParameters.CurrentDrive = Od2CurrentDisk;
//
// Create the Process, and wait to os2srv to get the results
// back to us by calling DosExecPgm
//
// ExePgmFileType comes from the call to Od2IsFileConsoleType (returned by Od2FormatExecPgmMessage)
if ((ExePgmFileType == STATUS_INVALID_IMAGE_NE_FORMAT) ||
(ExePgmFileType == STATUS_INVALID_IMAGE_FORMAT))
{
ExePgmFileType = STATUS_INVALID_IMAGE_NE_FORMAT;
} else if ((ExePgmFileType != STATUS_OBJECT_NAME_NOT_FOUND) &&
(ExePgmFileType != STATUS_OBJECT_PATH_NOT_FOUND))
{
#if DBG
DbgPrint( "OS2: Loading a Win 32-bit session - %s\n",
ExecFileName);
#endif
Flags |= EXEC_WINDOW_PROGRAM; // This bit set the CREATE_NEW_PROCESS_GROUP and does redirection
// set up redirection
if (a->hRedirectedFile) {
Od2PrepareStdHandleRedirection(STDFLAG_IN | STDFLAG_ERR, &StdStruc);
StdStruc.StdOut = a->hRedirectedFile;
StdStruc.Flags |= STDFLAG_OUT;
} else if (a->CmdLineFlag & REDIR_NUL) {
Od2PrepareStdHandleRedirection(STDFLAG_IN | STDFLAG_ERR, &StdStruc);
if ((StdStruc.StdOut = Ow2GetNulDeviceHandle()) != NULL) {
StdStruc.Flags |= STDFLAG_OUT;
}
} else {
Od2PrepareStdHandleRedirection(STDFLAG_ALL, &StdStruc);
}
} else
{
if (ExePgmFileType == STATUS_OBJECT_NAME_NOT_FOUND)
{
#if DBG
DbgPrint( "OS2(StartSession): EXE file not found - %s\n",
ExecFileName);
#endif
rc = ERROR_FILE_NOT_FOUND;
} else if (ExePgmFileType == STATUS_OBJECT_PATH_NOT_FOUND)
{
#if DBG
DbgPrint( "OS2(StartSession): Path to EXE file not found - %s\n",
ExecFileName);
#endif
rc = ERROR_PATH_NOT_FOUND;
} else
{
#if DBG
DbgPrint( "OS2(StartSession): Program can not be executed %s (%lx)\n",
ExecFileName, ExePgmFileType);
#endif
rc = Or2MapNtStatusToOs2Error(ExePgmFileType, ERROR_INVALID_PARAMETER);
}
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
RtlFreeHeap( Od2Heap, 0, ArgumentsBuffer );
RtlFreeHeap( Od2Heap, 0, VariablesBuffer );
RtlFreeHeap( Od2Heap, 0, ExecFileName );
Od2FreeCaptureBuffer( CaptureBuffer );
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
return(rc);
}
rc = Ow2ExecPgm(
Flags,
ArgumentsBuffer,
VariablesBuffer,
ExecFileName,
#if PMNT
IsPMApp,
#endif // PMNT
StartData,
&StdStruc, // will do the redirection if Win32 program
&hProcess,
&hThread,
&dwProcessId
);
//
// clean up redir stuff
//
if ((Flags & EXEC_WINDOW_PROGRAM) &&
(StdStruc.Flags & STDFLAG_CLOSEALL)) {
Od2CleanupStdHandleRedirection(&StdStruc);
}
RtlFreeHeap( Od2Heap, 0, ArgumentsBuffer );
RtlFreeHeap( Od2Heap, 0, VariablesBuffer );
RtlFreeHeap( Od2Heap, 0, ExecFileName );
if (rc != NO_ERROR)
{
#if DBG
DbgPrint("DosStartSession: error returned from Ow2ExecPgm %d\n", rc);
#endif
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
Od2FreeCaptureBuffer( CaptureBuffer );
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
NtClose(a->hRedirectedFile);
return(rc);
}
//
// 16 bit OS/2 program - Ow2execpgm creates it,
// Then we call os2srv to complete the job
//
if (((Flags & EXEC_WINDOW_PROGRAM) == 0) && a->hRedirectedFile)
{
hRedirectedFile = a->hRedirectedFile;
if(!DuplicateHandle(
GetCurrentProcess(),
a->hRedirectedFile,
hProcess,
&a->hRedirectedFile,
0,
FALSE,
DUPLICATE_SAME_ACCESS
))
{
#if DBG
DbgPrint( "DoStartSessionm: fail to duplicate Redirecd File %d\n",GetLastError());
#endif
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
Od2FreeCaptureBuffer( CaptureBuffer );
NtClose(hProcess);
NtClose(hThread);
NtClose(hRedirectedFile);
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
return(ERROR_ACCESS_DENIED);
}
}
if (a->hRedirectedFile) {
NtClose(a->hRedirectedFile);
}
//
// duplicate process and thread handles for os2srv
//
bSuccess = DuplicateHandle(
GetCurrentProcess(),
hProcess,
hOs2Srv,
&(a->hProcess),
0,
FALSE,
DUPLICATE_SAME_ACCESS
);
NtClose(hProcess);
if (!bSuccess)
{
#if DBG
DbgPrint( "DoStartSessionm: fail to duplicate process %d\n",GetLastError());
#endif
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
Od2FreeCaptureBuffer( CaptureBuffer );
NtClose(hThread);
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
return(ERROR_ACCESS_DENIED);
}
if (!DuplicateHandle(
GetCurrentProcess(),
hThread,
hOs2Srv,
&(a->hThread),
0,
FALSE,
DUPLICATE_SAME_ACCESS
))
{
#if DBG
DbgPrint( "DoStartSessionm: fail to duplicate Thread %d\n",GetLastError());
#endif
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
Od2FreeCaptureBuffer( CaptureBuffer );
NtClose(hThread);
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
Od2CloseSrvHandle(1, a->hProcess, NULL, NULL);
return(ERROR_ACCESS_DENIED);
}
Status = NtQueryInformationThread(hThread,
ThreadBasicInformation,
(PVOID)(&ThreadInfo),
sizeof(ThreadInfo),
NULL
);
NtClose(hThread);
if (!NT_SUCCESS(Status))
{
#if DBG
DbgPrint( "DoStartSessionm: fail to Query Information %lx\n",Status);
#endif
Od2FreeCaptureBuffer( CaptureBuffer );
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
if (b->QueueHandleIndex)
{
DosCloseQueue((HQUEUE)(b->QueueHandleIndex & ~0x80000000));
}
Od2CloseSrvHandle(2, a->hProcess, a->hThread, NULL);
return(Or2MapNtStatusToOs2Error(
Status,ERROR_ACCESS_DENIED));
}
a->ClientId = ThreadInfo.ClientId;
a->Flags = Flags;
b->Related = StartData->Related;
b->WinSession = (ExePgmFileType == STATUS_INVALID_IMAGE_NE_FORMAT) ? FALSE : TRUE;
b->FgBg = (BOOLEAN)StartData->FgBg;
b->dwProcessId = dwProcessId;
Od2CallSubsystem( &m, CaptureBuffer, Os2StartSession, sizeof( OS2_DOSSTARTSESSION_MSG ) );
ReleaseFileLockShared(
#if DBG
RoutineName
#endif
);
if ( StartData->Related )
{
*ProcessId = a->ResultProcessId;
*SessionId = b->ResultSessionId;
}
//if (m.ReturnedErrorValue == NO_ERROR)
//{
// *ResultCodes = a->ResultCodes;
//}
if (a->ErrorText.Length != 0)
{
if (((ULONG)(a->ErrorText.Length)) < StartData->ObjectBuffLen)
{
StartData->ObjectBuffLen = (ULONG)a->ErrorText.Length;
} else
{
StartData->ObjectBuffLen -= 1;
}
RtlMoveMemory( StartData->ObjectBuffer, a->ErrorText.Buffer, StartData->ObjectBuffLen );
StartData->ObjectBuffer[ StartData->ObjectBuffLen ] = '\0';
}
Od2FreeCaptureBuffer( CaptureBuffer );
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s complete (%lu) for %s, Session %lu, Process %lu\n",
RoutineName, m.ReturnedErrorValue, StartData->PgmName,
*SessionId, *ProcessId);
}
#endif
return( m.ReturnedErrorValue );
}
APIRET
DosSetSession(
IN ULONG SessionId,
IN PSTATUSDATA SessionStatusData
)
{
OS2_API_MSG m;
#if DBG
PSZ RoutineName = "DosSetSession";
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s: SessionId %lu, Select %u, Bond %u\n",
RoutineName, SessionId, SessionStatusData->SelectInd,
SessionStatusData->BondInd);
}
#endif
try
{
Od2ProbeForRead(SessionStatusData, sizeof(STATUSDATA), 1);
}
except( EXCEPTION_EXECUTE_HANDLER )
{
Od2ExitGP();
}
if ( SessionStatusData->Length != sizeof(STATUSDATA) )
{
return ERROR_SMG_INVALID_DATA_LENGTH;
}
if ( SessionStatusData->SelectInd > TARGET_NOT_SELECTABLE )
{
return ERROR_SMG_INVALID_SELECT_OPT;
}
if ( SessionStatusData->BondInd > BOND_NONE )
{
return ERROR_SMG_INVALID_BOND_OPTION;
}
m.u.DosSetSession.SessionId = SessionId;
m.u.DosSetSession.StatusData = *SessionStatusData;
Od2CallSubsystem( &m, NULL, Os2SetSession, sizeof( m.u.DosSetSession ) );
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s complete (%lu) for Session %lu\n",
RoutineName, m.ReturnedErrorValue, SessionId);
}
#endif
return( m.ReturnedErrorValue );
}
APIRET
DosSelectSession(
IN ULONG SessionId,
IN ULONG ulReserved
)
{
OS2_API_MSG m;
#if DBG
PSZ RoutineName = "DosSelectSession";
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s: SessionId %lu, Reserved %lu\n",
RoutineName, SessionId, ulReserved);
}
#endif
if (ulReserved)
{
return ERROR_SMG_BAD_RESERVE;
}
m.u.DosSelectSession.SessionId = SessionId;
Od2CallSubsystem( &m, NULL, Os2SelectSession, sizeof( m.u.DosSelectSession ) );
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s complete (%lu) for Session %lu\n",
RoutineName, m.ReturnedErrorValue, SessionId);
}
#endif
return( m.ReturnedErrorValue );
}
APIRET
DosStopSession(
IN ULONG StopTarget,
IN ULONG SessionId,
IN ULONG ulReserved
)
{
OS2_API_MSG m;
#if DBG
PSZ RoutineName = "DosStopSession";
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s: SessionId %lu, Target %lu, Reserved %lu\n",
RoutineName, SessionId, StopTarget, ulReserved);
}
#endif
if (ulReserved)
{
return ERROR_SMG_BAD_RESERVE;
}
if (( StopTarget != DSS_SESSION ) && ( StopTarget != DSS_ALL_SESSIONS ))
{
return ERROR_SMG_INVALID_STOP_OPTION;
}
m.u.DosStopSession.SessionId = SessionId;
m.u.DosStopSession.fScope = StopTarget;
Od2CallSubsystem( &m, NULL, Os2StopSession, sizeof( m.u.DosStopSession ) );
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s complete (%lu) for Session %lu\n",
RoutineName, m.ReturnedErrorValue, SessionId);
}
#endif
return( m.ReturnedErrorValue );
}
APIRET
DosSMSetTitle(
IN PCHAR Title
)
{
ULONG Length;
APIRET RetCode = 0;
//OS2_API_MSG m;
//POS2_CAPTURE_HEADER CaptureBuffer;
#if DBG
PSZ RoutineName = "DosSMSetTitle";
#endif
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s: Title, %s\n", Title);
}
#endif
try
{
Length = strlen(Title);
// Od2ProbeForRead(Title, Length, 1);
} except( EXCEPTION_EXECUTE_HANDLER )
{
Od2ExitGP();
}
//if ((CaptureBuffer = Od2AllocateCaptureBuffer( 1, 0, Length )) == NULL)
//{
// return( ERROR_NOT_ENOUGH_MEMORY );
//}
//
//Od2CaptureMessageString( CaptureBuffer,
// Title,
// Length,
// Length,
// &m.u.DosSmSetTitle.Title);
//
//Od2CallSubsystem( &m, CaptureBuffer, Os2SmSetTitle, sizeof( m.u.DosSmSetTitle ) );
//
//Od2FreeCaptureBuffer( CaptureBuffer );
//
//RetCode = m.ReturnedErrorValue;
if(!SetConsoleTitleA(Title))
{
RetCode = GetLastError();
}
#if DBG
IF_OD2_DEBUG( SESSIONMGR )
{
DbgPrint("%s complete (%lu)\n",
RoutineName, RetCode);
}
#endif
return(RetCode);
}
/* DosSMPMPresent and WinSetTitleAndIcon are stub APIs */
APIRET
DosSMPMPresent(
OUT USHORT *Flag
)
{
try
{
*Flag = 0;
}
except( EXCEPTION_EXECUTE_HANDLER )
{
Od2ExitGP();
}
return(NO_ERROR);
}
#ifndef PMNT
APIRET
WinSetTitleAndIcon(
IN PSZ szTitle,
IN PSZ szIconFilePath
)
{
UNREFERENCED_PARAMETER(szTitle);
UNREFERENCED_PARAMETER(szIconFilePath);
return(NO_ERROR);
}
#endif