Windows2000/private/ntos/w32/ntuser/client/csrstubs.c
2020-09-30 17:12:32 +02:00

354 lines
9.7 KiB
C

/** Module Header **\
* Module Name: csrstubs.c
* Copyright (c) 1985 - 1999, Microsoft Corporation
* Routines to call CSR
* 02-27-95 JimA Created.
* Note: This file has been partitioned with #if defines so that the LPC
* marsheling code can be inside 64bit code when running under wow64(32bit on 64bit NT).
* In wow64, the system DLLs for 32bit processes are 32bit.
* The marsheling code can only be depedent on functions NTDLL.
*/
#include "precomp.h"
#pragma hdrstop
#include "csrmsg.h"
#include "dbt.h"
#include "csrhlpr.h"
#if defined(BUILD_CSRWOW64)
#undef RIPERR0
#undef RIPNTERR0
#undef RIPMSG0
#define RIPNTERR0(status, flags, szFmt) {if (NtCurrentTeb()) NtCurrentTeb()->LastErrorValue = RtlNtStatusToDosError(status);}
#define RIPERR0(idErr, flags, szFmt) {if (NtCurrentTeb()) NtCurrentTeb()->LastErrorValue = (idErr);}
#define RIPMSG0(flags, szFmt)
#endif
#define SET_LAST_ERROR_RETURNED() if (a->dwLastError) RIPERR0(a->dwLastError, RIP_VERBOSE, "")
#if !defined(BUILD_WOW6432)
NTSTATUS APIENTRY CallUserpExitWindowsEx(IN UINT uFlags, IN DWORD dwReserved, OUT PBOOL pfSuccess)
{
USER_API_MSG m;
PEXITWINDOWSEXMSG a = &m.u.ExitWindowsEx;
a->uFlags = uFlags;
a->dwReserved = dwReserved;
CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpExitWindowsEx), sizeof( *a ));
if (NT_SUCCESS( m.ReturnValue ) || m.ReturnValue == STATUS_CANT_WAIT) {
SET_LAST_ERROR_RETURNED();
*pfSuccess = a->fSuccess;
} else {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "");
*pfSuccess = FALSE;
}
return m.ReturnValue;
}
#endif
#if !defined(BUILD_CSRWOW64)
typedef struct _EXITWINDOWSDATA {
UINT uFlags;
DWORD dwReserved;
} EXITWINDOWSDATA, *PEXITWINDOWSDATA;
DWORD ExitWindowsThread(PVOID pvParam);
BOOL WINAPI ExitWindowsWorker(UINT uFlags, DWORD dwReserved, BOOL fSecondThread)
{
EXITWINDOWSDATA ewd;
HANDLE hThread;
DWORD dwThreadId;
DWORD dwExitCode;
DWORD idWait;
MSG msg;
BOOL fSuccess;
NTSTATUS Status;
/*
* Force a connection so apps will have a windowstation
* to log off of.
*/
if (PtiCurrent() == NULL)
return FALSE;
/*
* Check for UI restrictions
*/
if (!NtUserCallOneParam((ULONG_PTR)uFlags, SFI_PREPAREFORLOGOFF)) {
RIPMSG0(RIP_WARNING, "ExitWindows called by a restricted thread\n");
return FALSE;
}
Status = CallUserpExitWindowsEx(uFlags, dwReserved, &fSuccess);
if (NT_SUCCESS( Status )) {
return fSuccess;
} else if (Status == STATUS_CANT_WAIT && !fSecondThread) {
ewd.uFlags = uFlags;
ewd.dwReserved = dwReserved;
hThread = CreateThread(NULL, 0, ExitWindowsThread, &ewd, 0, &dwThreadId);
if (hThread == NULL) {
return FALSE;
}
while (1) {
idWait = MsgWaitForMultipleObjectsEx(1, &hThread, INFINITE, QS_ALLINPUT, 0);
/*
* If the thread was signaled, we're done.
*/
if (idWait == WAIT_OBJECT_0)
break;
/*
* Process any waiting messages
*/
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&msg);
}
GetExitCodeThread(hThread, &dwExitCode);
NtClose(hThread);
if (dwExitCode == ERROR_SUCCESS)
return TRUE;
else {
RIPERR0(dwExitCode, RIP_VERBOSE, "");
return FALSE;
}
} else {
RIPNTERR0(Status, RIP_VERBOSE, "");
return FALSE;
}
}
DWORD ExitWindowsThread(PVOID pvParam)
{
PEXITWINDOWSDATA pewd = pvParam;
DWORD dwExitCode;
if (ExitWindowsWorker(pewd->uFlags, pewd->dwReserved, TRUE))
dwExitCode = 0;
else
dwExitCode = GetLastError();
ExitThread(dwExitCode);
return 0;
}
BOOL WINAPI ExitWindowsEx(UINT uFlags, DWORD dwReserved)
{
return ExitWindowsWorker(uFlags, dwReserved, FALSE);
}
#endif
#if !defined(BUILD_WOW6432)
BOOL WINAPI EndTask(HWND hwnd, BOOL fShutdown, BOOL fForce)
{
USER_API_MSG m;
PENDTASKMSG a = &m.u.EndTask;
a->hwnd = hwnd;
a->fShutdown = fShutdown;
a->fForce = fForce;
CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpEndTask), sizeof( *a ));
if (NT_SUCCESS( m.ReturnValue )) {
SET_LAST_ERROR_RETURNED();
return a->fSuccess;
} else {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "");
return FALSE;
}
}
VOID APIENTRY Logon(BOOL fLogon)
{
USER_API_MSG m;
PLOGONMSG a = &m.u.Logon;
a->fLogon = fLogon;
CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpLogon), sizeof(*a));
}
NTSTATUS APIENTRY CallUserpRegisterLogonProcess(IN DWORD dwProcessId)
{
USER_API_MSG m;
PLOGONMSG a = &m.u.Logon;
NTSTATUS Status;
m.u.IdLogon = dwProcessId;
Status = CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpRegisterLogonProcess), sizeof(*a));
return Status;
}
#endif
#if !defined(BUILD_CSRWOW64)
extern BOOL gfLogonProcess;
BOOL RegisterLogonProcess(DWORD dwProcessId, BOOL fSecure)
{
gfLogonProcess = (BOOL)NtUserCallTwoParam(dwProcessId, fSecure, SFI__REGISTERLOGONPROCESS);
/*
* Now, register the logon process into winsrv.
*/
if (gfLogonProcess) {
CallUserpRegisterLogonProcess(dwProcessId);
}
return gfLogonProcess;
}
#endif
#if !defined(BUILD_WOW6432)
BOOL WINAPI RegisterServicesProcess(DWORD dwProcessId)
{
USER_API_MSG m;
PREGISTERSERVICESPROCESSMSG a = &m.u.RegisterServicesProcess;
a->dwProcessId = dwProcessId;
CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpRegisterServicesProcess), sizeof( *a ));
if (NT_SUCCESS( m.ReturnValue )) {
SET_LAST_ERROR_RETURNED();
return a->fSuccess;
} else {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "");
return FALSE;
}
}
HDESK WINAPI GetThreadDesktop(DWORD dwThreadId)
{
USER_API_MSG m;
PGETTHREADCONSOLEDESKTOPMSG a = &m.u.GetThreadConsoleDesktop;
a->dwThreadId = dwThreadId;
CsrClientCallServer( (PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX, UserpGetThreadConsoleDesktop), sizeof( *a ));
if (NT_SUCCESS( m.ReturnValue )) {
return NtUserGetThreadDesktop(dwThreadId, a->hdeskConsole);
} else {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "");
return NULL;
}
}
/*
* DeviceEventWorker
* This is a private (not publicly exported) interface that the user-mode
* pnp manager calls when it needs to send a WM_DEVICECHANGE message to a
* specific window handle. The user-mode pnp manager is a service within
* services.exe and as such is not on the interactive window station and
* active desktop, so it can't directly call SendMessage. For broadcasted
* messages (messages that go to all top-level windows), the user-mode pnp
* manager calls BroadcastSystemMessage directly.
* PaulaT 06/04/97
*/
ULONG WINAPI DeviceEventWorker(IN HWND hWnd, IN WPARAM wParam, IN LPARAM lParam, IN DWORD dwFlags, OUT PDWORD pdwResult)
{
USER_API_MSG m;
PDEVICEEVENTMSG a = &m.u.DeviceEvent;
PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
int cb = 0;
a->hWnd = hWnd;
a->wParam = wParam;
a->lParam = lParam;
a->dwFlags = dwFlags;
a->dwResult = 0;
// If lParam is specified, it must be marshalled (see the defines for this structure in dbt.h - the structure always starts with DEV_BROADCAST_HDR structure).
if (lParam) {
cb = ((PDEV_BROADCAST_HDR)lParam)->dbch_size;
CaptureBuffer = CsrAllocateCaptureBuffer(1, cb);
if (CaptureBuffer == NULL) {
return STATUS_NO_MEMORY;
}
CsrCaptureMessageBuffer(CaptureBuffer, (PCHAR)lParam, cb, (PVOID *)&a->lParam);
// This ends up calling SrvDeviceEvent routine in the server.
CsrClientCallServer((PCSR_API_MSG)&m, CaptureBuffer, CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpDeviceEvent), sizeof(*a));
CsrFreeCaptureBuffer(CaptureBuffer);
} else {
// This ends up calling SrvDeviceEvent routine in the server.
CsrClientCallServer((PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpDeviceEvent), sizeof(*a));
}
if (NT_SUCCESS(m.ReturnValue)) {
*pdwResult = (DWORD)a->dwResult;
} else {
RIPMSG0(RIP_WARNING, "DeviceEventWorker failed.");
}
return m.ReturnValue;
} // DeviceEventWorker
#if DBG
VOID APIENTRY CsrWin32HeapFail(IN DWORD dwFlags, IN BOOL bFail)
{
USER_API_MSG m;
PWIN32HEAPFAILMSG a = &m.u.Win32HeapFail;
a->dwFlags = dwFlags;
a->bFail = bFail;
CsrClientCallServer((PCSR_API_MSG)&m, NULL, CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpWin32HeapFail), sizeof(*a));
if (!NT_SUCCESS(m.ReturnValue)) {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "UserpWin32HeapFail failed");
}
}
UINT APIENTRY CsrWin32HeapStat(PDBGHEAPSTAT phs, DWORD dwLen)
{
USER_API_MSG m;
PWIN32HEAPSTATMSG a = &m.u.Win32HeapStat;
PCSR_CAPTURE_HEADER CaptureBuffer = NULL;
a->dwLen = dwLen;
CaptureBuffer = CsrAllocateCaptureBuffer(1, dwLen);
if (CaptureBuffer == NULL) {
return 0;
}
CsrCaptureMessageBuffer(CaptureBuffer, (PCHAR)phs, dwLen, (PVOID *)&a->phs);
CsrClientCallServer((PCSR_API_MSG)&m, CaptureBuffer, CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpWin32HeapStat), sizeof(*a));
if (!NT_SUCCESS(m.ReturnValue)) {
RIPNTERR0(m.ReturnValue, RIP_VERBOSE, "UserpWin32HeapStat failed");
a->dwMaxTag = 0;
goto ErrExit;
}
RtlMoveMemory(phs, a->phs, dwLen);
ErrExit:
CsrFreeCaptureBuffer(CaptureBuffer);
return a->dwMaxTag;
}
#endif // DBG
#endif