383 lines
7.9 KiB
C
383 lines
7.9 KiB
C
|
||
/*++
|
||
|
||
Copyright (c) 1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
sessdev.c
|
||
|
||
Abstract:
|
||
|
||
Per Session Dos Device access routines
|
||
|
||
Author:
|
||
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "basedll.h"
|
||
|
||
|
||
#define SESSION0_ROOT L"GLOBALROOT"
|
||
#define SESSIONX_ROOT L"GLOBALROOT\\Sessions\\"
|
||
|
||
|
||
|
||
BOOL
|
||
WINAPI
|
||
DosPathToSessionPathA(
|
||
IN DWORD SessionId,
|
||
IN LPCSTR pInPath,
|
||
OUT LPSTR *ppOutPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Converts a DOS path relative to the current session to a DOS path
|
||
that allows access to a specific session.
|
||
|
||
Arguments:
|
||
|
||
SessionId - SessionId to access.
|
||
|
||
pInPath - WIN32 DOS path. Could be of the form "C:", "LPT1:",
|
||
"C:\file\path", etc.
|
||
|
||
ppOutPath - Output path that accesses the specified session.
|
||
If pIniPath is "C:" and SessionId is 6, the output would be
|
||
"GLOBALROOT\Sessions\6\DosDevices\C:".
|
||
|
||
Return Value:
|
||
|
||
TRUE - Path returned in *ppOutPath in newly allocated memory from
|
||
LocalAlloc.
|
||
FALSE - Call failed. Error code returned via GetLastError()
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL rc;
|
||
DWORD Len;
|
||
PCHAR Buf;
|
||
NTSTATUS Status;
|
||
PWCHAR pOutPath;
|
||
ANSI_STRING AnsiString;
|
||
UNICODE_STRING UnicodeString;
|
||
|
||
// if the input path is null or the pointer is a bad pointer, return
|
||
// an error.
|
||
|
||
if( (pInPath == 0) ||
|
||
(IsBadReadPtr( pInPath, sizeof( CHAR ))) ||
|
||
(IsBadWritePtr( ppOutPath, sizeof(LPSTR) )) ) {
|
||
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
return(FALSE);
|
||
}
|
||
|
||
try {
|
||
|
||
RtlInitAnsiString( &AnsiString, pInPath );
|
||
Status = RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, TRUE );
|
||
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
||
Status = GetExceptionCode();
|
||
}
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
BaseSetLastNTError( Status );
|
||
return FALSE;
|
||
}
|
||
|
||
rc = DosPathToSessionPathW(
|
||
SessionId,
|
||
UnicodeString.Buffer,
|
||
&pOutPath
|
||
);
|
||
|
||
RtlFreeUnicodeString( &UnicodeString );
|
||
|
||
if( !rc ) {
|
||
return( rc );
|
||
}
|
||
|
||
RtlInitUnicodeString( &UnicodeString, pOutPath );
|
||
Status = RtlUnicodeStringToAnsiString( &AnsiString, &UnicodeString, TRUE );
|
||
if (!NT_SUCCESS( Status )) {
|
||
BaseSetLastNTError( Status );
|
||
LocalFree( pOutPath );
|
||
return FALSE;
|
||
}
|
||
|
||
Len = strlen( AnsiString.Buffer ) + 1;
|
||
Buf = LocalAlloc(LMEM_FIXED, Len);
|
||
|
||
if( Buf == NULL ) {
|
||
LocalFree( pOutPath );
|
||
RtlFreeAnsiString( &AnsiString );
|
||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||
return(FALSE);
|
||
}
|
||
|
||
strcpy( Buf, AnsiString.Buffer );
|
||
|
||
*ppOutPath = Buf;
|
||
|
||
LocalFree( pOutPath );
|
||
RtlFreeAnsiString( &AnsiString );
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
BOOL
|
||
WINAPI
|
||
DosPathToSessionPathW(
|
||
IN DWORD SessionId,
|
||
IN LPCWSTR pInPath,
|
||
OUT LPWSTR *ppOutPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Converts a DOS path relative to the current session to a DOS path
|
||
that allows access to a specific session.
|
||
|
||
Arguments:
|
||
|
||
SessionId - SessionId to access.
|
||
|
||
pInPath - WIN32 DOS path. Could be of the form "C:", "LPT1:",
|
||
"C:\file\path", etc.
|
||
|
||
ppOutPath - Output path that accesses the specified session.
|
||
If pIniPath is "C:" and SessionId is 6, the output would be
|
||
"GLOBALROOT\Sessions\6\DosDevices\C:".
|
||
|
||
Return Value:
|
||
|
||
TRUE - Path returned in *ppOutPath in newly allocated memory from
|
||
LocalAlloc.
|
||
FALSE - Call failed. Error code returned via GetLastError()
|
||
|
||
--*/
|
||
|
||
{
|
||
PWCHAR Buf;
|
||
ULONG Len;
|
||
|
||
//
|
||
// SessionId 0 has no per session object directories.
|
||
//
|
||
if (BaseStaticServerData->LUIDDeviceMapsEnabled == TRUE) {
|
||
|
||
Len = 0;
|
||
|
||
} else {
|
||
|
||
if( SessionId == 0 ) {
|
||
Len = wcslen(SESSION0_ROOT);
|
||
}
|
||
else {
|
||
Len = wcslen(SESSIONX_ROOT);
|
||
Len += 10; // Max DWORD width
|
||
}
|
||
}
|
||
|
||
Len += 13; // \DosDevices\ ... <NULL>
|
||
|
||
// if the input path is null or the pointer is a bad pointer, return
|
||
// an error.
|
||
|
||
if( (pInPath == 0) ||
|
||
(IsBadReadPtr( pInPath, sizeof( WCHAR ))) ||
|
||
(IsBadWritePtr( ppOutPath, sizeof(LPWSTR) )) ) {
|
||
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
return(FALSE);
|
||
}
|
||
|
||
Len += wcslen(pInPath);
|
||
|
||
Buf = LocalAlloc(LMEM_FIXED, Len * sizeof(WCHAR));
|
||
if( Buf == NULL ) {
|
||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||
return(FALSE);
|
||
}
|
||
|
||
try {
|
||
if (BaseStaticServerData->LUIDDeviceMapsEnabled == TRUE) {
|
||
|
||
// C: -> C:
|
||
swprintf(
|
||
Buf,
|
||
L"%ws",
|
||
pInPath
|
||
);
|
||
|
||
} else {
|
||
|
||
if( SessionId == 0 ) {
|
||
// C: -> GLOBALROOT\DosDevices\C:
|
||
swprintf(
|
||
Buf,
|
||
L"%ws\\DosDevices\\%ws",
|
||
SESSION0_ROOT,
|
||
pInPath
|
||
);
|
||
}
|
||
else {
|
||
// C: -> GLOBALROOT\Sessions\6\DosDevices\C:
|
||
swprintf(
|
||
Buf,
|
||
L"%ws%u\\DosDevices\\%ws",
|
||
SESSIONX_ROOT,
|
||
SessionId,
|
||
pInPath
|
||
);
|
||
}
|
||
}
|
||
|
||
*ppOutPath = Buf;
|
||
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
||
BaseSetLastNTError(GetExceptionCode());
|
||
return(FALSE);
|
||
}
|
||
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
BOOL
|
||
WINAPI
|
||
ProcessIdToSessionId(
|
||
IN DWORD dwProcessId,
|
||
OUT DWORD *pSessionId
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Given a ProcessId, return the SessionId.
|
||
|
||
This is useful for services that impersonate a caller, and
|
||
redefine a drive letter for the caller. An example is the
|
||
workstation service. Transport specific routines allow the
|
||
ProcessId of the caller to be retrieved.
|
||
|
||
Arguments:
|
||
|
||
Process - Process identifies process to
|
||
return the SessionId for.
|
||
|
||
pSessionId - returned SessionId.
|
||
|
||
Return Value:
|
||
|
||
TRUE - SessionId returned in *pSessionId
|
||
FALSE - Call failed. Error code returned via GetLastError()
|
||
|
||
--*/
|
||
|
||
{
|
||
HANDLE Handle;
|
||
NTSTATUS Status;
|
||
CLIENT_ID ClientId;
|
||
OBJECT_ATTRIBUTES Obja;
|
||
PROCESS_SESSION_INFORMATION Info;
|
||
|
||
|
||
if( IsBadWritePtr( pSessionId, sizeof(DWORD) ) ) {
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
InitializeObjectAttributes(
|
||
&Obja,
|
||
NULL,
|
||
0,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
ClientId.UniqueProcess = (HANDLE) LongToHandle(dwProcessId);
|
||
ClientId.UniqueThread = (HANDLE)NULL;
|
||
|
||
Status = NtOpenProcess(
|
||
&Handle,
|
||
(ACCESS_MASK)PROCESS_QUERY_INFORMATION,
|
||
&Obja,
|
||
&ClientId
|
||
);
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
SetLastError(RtlNtStatusToDosError(Status));
|
||
return(FALSE);
|
||
}
|
||
|
||
Status = NtQueryInformationProcess(
|
||
Handle,
|
||
ProcessSessionInformation,
|
||
&Info,
|
||
sizeof(Info),
|
||
NULL
|
||
);
|
||
|
||
if( !NT_SUCCESS(Status) ) {
|
||
NtClose( Handle );
|
||
SetLastError(RtlNtStatusToDosError(Status));
|
||
return(FALSE);
|
||
}
|
||
|
||
*pSessionId = Info.SessionId;
|
||
|
||
NtClose( Handle );
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
WTSGetActiveConsoleSessionId ()
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
returns the Session ID for the session, attached to Console.
|
||
|
||
Arguments:
|
||
|
||
none
|
||
|
||
Return Value:
|
||
|
||
SessionID for the console (session attached to console not necessarily session 0 ) session.
|
||
return 0xFFFFFFFF if there is no session attached to console.
|
||
This could happen if session disconnect / connect is taking place
|
||
|
||
This is a session id for the session currently connected to console, it changes when
|
||
new session is connected at console. to keep track of the current console sesion, use
|
||
WTSRegisterSessionNotification
|
||
|
||
|
||
--*/
|
||
{
|
||
return (USER_SHARED_DATA->ActiveConsoleId);
|
||
|
||
}
|
||
|