1608 lines
47 KiB
C++
1608 lines
47 KiB
C++
|
// --------------------------------------------------------------------------
|
||
|
// Module Name: CWLogonStatus.cpp
|
||
|
//
|
||
|
// Copyright (c) 2000, Microsoft Corporation
|
||
|
//
|
||
|
// File that contains implementation for status UI hosting by an external
|
||
|
// process.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
#include "StandardHeader.h"
|
||
|
#include <msginaexports.h>
|
||
|
|
||
|
#include "Access.h"
|
||
|
#include "GinaIPC.h"
|
||
|
#include "LogonWait.h"
|
||
|
#include "SingleThreadedExecution.h"
|
||
|
#include "StatusCode.h"
|
||
|
#include "SystemSettings.h"
|
||
|
#include "UIHost.h"
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus
|
||
|
//
|
||
|
// Purpose: C++ class to handle logon status external process for consumer
|
||
|
// windows.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
class CLogonStatus : public ILogonExternalProcess
|
||
|
{
|
||
|
private:
|
||
|
CLogonStatus (void);
|
||
|
public:
|
||
|
CLogonStatus (const TCHAR *pszParameter);
|
||
|
~CLogonStatus (void);
|
||
|
|
||
|
NTSTATUS Start (bool fWait);
|
||
|
CUIHost* GetUIHost (void);
|
||
|
static bool IsStatusWindow (HWND hwnd);
|
||
|
|
||
|
bool WaitForUIHost (void);
|
||
|
void ShowStatusMessage (const WCHAR *pszMessage);
|
||
|
void SetStateStatus (int iCode);
|
||
|
void SetStateLogon (int iCode);
|
||
|
void SetStateLoggedOn (void);
|
||
|
void SetStateHide (void);
|
||
|
void SetStateEnd (bool fSendMessage);
|
||
|
void NotifyWait (void);
|
||
|
void NotifyNoAnimations (void);
|
||
|
void SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain);
|
||
|
void InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword);
|
||
|
HANDLE ResetReadyEvent (void);
|
||
|
bool IsSuspendAllowed (void) const;
|
||
|
void ShowUIHost (void);
|
||
|
void HideUIHost (void);
|
||
|
bool IsUIHostHidden (void) const;
|
||
|
public:
|
||
|
virtual bool AllowTermination (DWORD dwExitCode);
|
||
|
virtual NTSTATUS SignalAbnormalTermination (void);
|
||
|
virtual NTSTATUS SignalRestart (void);
|
||
|
virtual NTSTATUS LogonRestart (void);
|
||
|
private:
|
||
|
bool IsUIHostReady (void) const;
|
||
|
void SendToUIHost (WPARAM wParam, LPARAM lParam);
|
||
|
void UIHostReadySignal (void);
|
||
|
static void CALLBACK CB_UIHostReadySignal (void *pV, BOOLEAN fTimerOrWaitFired);
|
||
|
static void CALLBACK CB_UIHostAbnormalTermination (ULONG_PTR dwParam);
|
||
|
private:
|
||
|
DWORD _dwThreadID;
|
||
|
bool _fRegisteredWait;
|
||
|
HANDLE _hEvent;
|
||
|
HANDLE _hWait;
|
||
|
int _iState,
|
||
|
_iCode,
|
||
|
_iStatePending;
|
||
|
WPARAM _waitWPARAM;
|
||
|
LPARAM _waitLPARAM;
|
||
|
CUIHost* _pUIHost;
|
||
|
CLogonWait _logonWait;
|
||
|
};
|
||
|
|
||
|
CCriticalSection* g_pLogonStatusLock = NULL;
|
||
|
CLogonStatus* g_pLogonStatus = NULL;
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::CLogonStatus
|
||
|
//
|
||
|
// Arguments: pszParameter = Parameter to pass to status UI host.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Constructor for CLogonStatus. This gets the status UI host
|
||
|
// from the registry and assigns the given parameter into the
|
||
|
// object. Create a named event which SHGINA knows about and
|
||
|
// will signal once the ILogonStatusHost class has been
|
||
|
// instantiated.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
CLogonStatus::CLogonStatus (const TCHAR *pszParameter) :
|
||
|
_dwThreadID(0),
|
||
|
_fRegisteredWait(false),
|
||
|
_hEvent(NULL),
|
||
|
_hWait(NULL),
|
||
|
_iState(UI_STATE_STATUS),
|
||
|
_iCode(0),
|
||
|
_iStatePending(0),
|
||
|
_waitWPARAM(0),
|
||
|
_waitLPARAM(0),
|
||
|
_pUIHost(NULL)
|
||
|
|
||
|
{
|
||
|
TCHAR szRawHostCommandLine[MAX_PATH];
|
||
|
|
||
|
if (ERROR_SUCCESS == CSystemSettings::GetUIHost(szRawHostCommandLine))
|
||
|
{
|
||
|
_pUIHost = new CUIHost(szRawHostCommandLine);
|
||
|
if (_pUIHost != NULL)
|
||
|
{
|
||
|
_pUIHost->SetInterface(this);
|
||
|
_pUIHost->SetParameter(pszParameter);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SECURITY_ATTRIBUTES securityAttributes;
|
||
|
|
||
|
// Build a security descriptor for the event that allows:
|
||
|
// S-1-5-18 EVENT_ALL_ACCESS
|
||
|
// S-1-5-32-544 SYNCHRONIZE | READ_CONTROL | EVENT_QUERY_STATE
|
||
|
|
||
|
static SID_IDENTIFIER_AUTHORITY s_SecurityNTAuthority = SECURITY_NT_AUTHORITY;
|
||
|
|
||
|
static const CSecurityDescriptor::ACCESS_CONTROL s_AccessControl[] =
|
||
|
{
|
||
|
{
|
||
|
&s_SecurityNTAuthority,
|
||
|
1,
|
||
|
SECURITY_LOCAL_SYSTEM_RID,
|
||
|
0, 0, 0, 0, 0, 0, 0,
|
||
|
EVENT_ALL_ACCESS
|
||
|
},
|
||
|
{
|
||
|
&s_SecurityNTAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_ADMINS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
SYNCHRONIZE | READ_CONTROL | EVENT_QUERY_STATE
|
||
|
}
|
||
|
};
|
||
|
|
||
|
securityAttributes.nLength = sizeof(securityAttributes);
|
||
|
securityAttributes.lpSecurityDescriptor = CSecurityDescriptor::Create(ARRAYSIZE(s_AccessControl), s_AccessControl);
|
||
|
securityAttributes.bInheritHandle = FALSE;
|
||
|
_hEvent = CreateEvent(&securityAttributes, TRUE, FALSE, TEXT("msgina: StatusHostReadyEvent"));
|
||
|
ReleaseMemory(securityAttributes.lpSecurityDescriptor);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::~CLogonStatus
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Destructor for CLogonStatus. Releases references.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
CLogonStatus::~CLogonStatus (void)
|
||
|
|
||
|
{
|
||
|
ASSERTMSG(_hWait == NULL, "Resend wait object not released in CLogonStatus::~CLogonStatus");
|
||
|
ReleaseHandle(_hEvent);
|
||
|
ASSERTMSG(_iState == UI_STATE_END, "State must be UI_STATE_END in CLogonStatus::~CLogonStatus");
|
||
|
if (_pUIHost != NULL)
|
||
|
{
|
||
|
_pUIHost->Release();
|
||
|
_pUIHost = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::Start
|
||
|
//
|
||
|
// Arguments: fWait = Wait for status host to signal ready.
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose: Starts the status UI host. Don't wait for the UI host. There
|
||
|
// is a mechanism that can queue a message if the UI host window
|
||
|
// cannot be found.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS CLogonStatus::Start (bool fWait)
|
||
|
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
if (_pUIHost != NULL)
|
||
|
{
|
||
|
(HANDLE)ResetReadyEvent();
|
||
|
status = _pUIHost->Start();
|
||
|
if (NT_SUCCESS(status))
|
||
|
{
|
||
|
_dwThreadID = GetCurrentThreadId();
|
||
|
if (fWait || _pUIHost->WaitRequired())
|
||
|
{
|
||
|
if (!WaitForUIHost())
|
||
|
{
|
||
|
status = STATUS_UNSUCCESSFUL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = STATUS_UNSUCCESSFUL;
|
||
|
}
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::GetUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: CUIHost*
|
||
|
//
|
||
|
// Purpose: Returns a reference to the UIHost object held internally.
|
||
|
// The reference belongs to the caller and must be released.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
CUIHost* CLogonStatus::GetUIHost (void)
|
||
|
|
||
|
{
|
||
|
if (_pUIHost != NULL)
|
||
|
{
|
||
|
_pUIHost->AddRef();
|
||
|
}
|
||
|
return(_pUIHost);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::IsStatusWindow
|
||
|
//
|
||
|
// Arguments: hwnd = HWND to check.
|
||
|
//
|
||
|
// Returns: bool
|
||
|
//
|
||
|
// Purpose: Returns whether the given HWND is the status window.
|
||
|
//
|
||
|
// History: 2000-06-26 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::IsStatusWindow (HWND hwnd)
|
||
|
|
||
|
{
|
||
|
TCHAR szWindowClass[256];
|
||
|
|
||
|
return((GetClassName(hwnd, szWindowClass, ARRAYSIZE(szWindowClass)) != 0) &&
|
||
|
(lstrcmpi(STATUS_WINDOW_CLASS_NAME, szWindowClass) == 0));
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::WaitForUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: bool
|
||
|
//
|
||
|
// Purpose: Waits on the named event that the UI host signals when it's
|
||
|
// initialized. Typically this happens very quickly but we don't
|
||
|
// wait on it when starting up the UI host.
|
||
|
//
|
||
|
// History: 2000-09-10 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::WaitForUIHost (void)
|
||
|
|
||
|
{
|
||
|
bool fResult;
|
||
|
|
||
|
fResult = true;
|
||
|
ASSERTMSG(_hEvent != NULL, "No UI host named event to wait on in CLogonStatus::WaitForUIHost");
|
||
|
if (!IsUIHostReady())
|
||
|
{
|
||
|
DWORD dwWaitResult;
|
||
|
|
||
|
#ifdef DBG
|
||
|
DWORD dwWaitStart, dwWaitEnd;
|
||
|
|
||
|
dwWaitStart = (WAIT_TIMEOUT == WaitForSingleObject(_hEvent, 0)) ? GetTickCount() : 0;
|
||
|
#endif /* DBG */
|
||
|
do
|
||
|
{
|
||
|
dwWaitResult = WaitForSingleObject(_hEvent, 0);
|
||
|
if (dwWaitResult != WAIT_OBJECT_0)
|
||
|
{
|
||
|
dwWaitResult = MsgWaitForMultipleObjectsEx(1, &_hEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
|
||
|
if (dwWaitResult == WAIT_OBJECT_0 + 1)
|
||
|
{
|
||
|
MSG msg;
|
||
|
|
||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE)
|
||
|
{
|
||
|
(BOOL)TranslateMessage(&msg);
|
||
|
(LRESULT)DispatchMessage(&msg);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} while ((dwWaitResult == WAIT_OBJECT_0 + 1) && (dwWaitResult != WAIT_IO_COMPLETION));
|
||
|
#ifdef DBG
|
||
|
dwWaitEnd = GetTickCount();
|
||
|
if ((dwWaitStart != 0) && ((dwWaitEnd - dwWaitStart) != 0))
|
||
|
{
|
||
|
char szBuffer[256];
|
||
|
|
||
|
wsprintfA(szBuffer, "waited %d ticks for UI host", dwWaitEnd - dwWaitStart);
|
||
|
INFORMATIONMSG(szBuffer);
|
||
|
}
|
||
|
#endif /* DBG */
|
||
|
fResult = (dwWaitResult != WAIT_IO_COMPLETION);
|
||
|
}
|
||
|
return(fResult);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::ShowStatusMessage
|
||
|
//
|
||
|
// Arguments: pszMessage = Unicode string message to display.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the UI host to display the given string message. Puts
|
||
|
// the string directly inside the status host process and tells
|
||
|
// the process where in its address space to find the string.
|
||
|
// The string is limited to 256 characters.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::ShowStatusMessage (const WCHAR *pszMessage)
|
||
|
|
||
|
{
|
||
|
if (NT_SUCCESS(_pUIHost->PutString(pszMessage)))
|
||
|
{
|
||
|
SendToUIHost(UI_DISPLAY_STATUS, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SetStateStatus
|
||
|
//
|
||
|
// Arguments: iCode = Magic code number for lock.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to go into status state.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SetStateStatus (int iCode)
|
||
|
|
||
|
{
|
||
|
_iStatePending = UI_STATE_STATUS;
|
||
|
if (WaitForUIHost() && (_iState != UI_STATE_STATUS))
|
||
|
{
|
||
|
SendToUIHost(UI_STATE_STATUS, iCode);
|
||
|
_iState = UI_STATE_STATUS;
|
||
|
_iCode = iCode;
|
||
|
}
|
||
|
_iStatePending = UI_STATE_NONE;
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SetStateLogon
|
||
|
//
|
||
|
// Arguments: iCode = Magic code number for lock.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to go into logon state.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SetStateLogon (int iCode)
|
||
|
|
||
|
{
|
||
|
_iStatePending = UI_STATE_LOGON;
|
||
|
if (WaitForUIHost() && (iCode == _iCode))
|
||
|
{
|
||
|
SendToUIHost(UI_STATE_LOGON, iCode);
|
||
|
_iState = UI_STATE_LOGON;
|
||
|
_iCode = 0;
|
||
|
}
|
||
|
_iStatePending = UI_STATE_NONE;
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SetStateLoggedOn
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to go into logged on state.
|
||
|
//
|
||
|
// History: 2000-05-24 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SetStateLoggedOn (void)
|
||
|
|
||
|
{
|
||
|
_iStatePending = UI_STATE_STATUS;
|
||
|
if (WaitForUIHost())
|
||
|
{
|
||
|
SendToUIHost(UI_STATE_LOGGEDON, 0);
|
||
|
_iState = UI_STATE_STATUS;
|
||
|
}
|
||
|
_iStatePending = UI_STATE_NONE;
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SetStateHide
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to hide itself.
|
||
|
//
|
||
|
// History: 2001-01-08 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SetStateHide (void)
|
||
|
|
||
|
{
|
||
|
_iStatePending = UI_STATE_HIDE;
|
||
|
if (WaitForUIHost())
|
||
|
{
|
||
|
SendToUIHost(UI_STATE_HIDE, 0);
|
||
|
_iState = UI_STATE_HIDE;
|
||
|
}
|
||
|
_iStatePending = UI_STATE_NONE;
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SetStateEnd
|
||
|
//
|
||
|
// Arguments: fSendMessage = Send message to UI host or not.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to end and terminate itself.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SetStateEnd (bool fSendMessage)
|
||
|
|
||
|
{
|
||
|
bool fHostAlive;
|
||
|
HANDLE hWait;
|
||
|
|
||
|
_iStatePending = UI_STATE_END;
|
||
|
|
||
|
// When going into end mode if there's a wait registered then
|
||
|
// unregister it. This will release an outstanding reference.
|
||
|
// A re-register should never happen but this is set just in case.
|
||
|
|
||
|
_fRegisteredWait = true;
|
||
|
hWait = InterlockedExchangePointer(&_hWait, NULL);
|
||
|
if (hWait != NULL)
|
||
|
{
|
||
|
if (UnregisterWait(hWait) != FALSE)
|
||
|
{
|
||
|
Release();
|
||
|
}
|
||
|
}
|
||
|
if (fSendMessage)
|
||
|
{
|
||
|
fHostAlive = WaitForUIHost();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fHostAlive = true;
|
||
|
}
|
||
|
if (fHostAlive)
|
||
|
{
|
||
|
if (_pUIHost != NULL)
|
||
|
{
|
||
|
_pUIHost->SetInterface(NULL);
|
||
|
}
|
||
|
if (fSendMessage)
|
||
|
{
|
||
|
SendToUIHost(UI_STATE_END, 0);
|
||
|
}
|
||
|
_iState = UI_STATE_END;
|
||
|
}
|
||
|
_iStatePending = UI_STATE_NONE;
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::NotifyWait
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to display a title that the system
|
||
|
// is shutting down.
|
||
|
//
|
||
|
// History: 2000-07-14 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::NotifyWait (void)
|
||
|
|
||
|
{
|
||
|
SendToUIHost(UI_NOTIFY_WAIT, 0);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::NotifyNoAnimations
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to no longer perform animations.
|
||
|
//
|
||
|
// History: 2001-03-21 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::NotifyNoAnimations (void)
|
||
|
|
||
|
{
|
||
|
SendToUIHost(UI_SET_ANIMATIONS, 0);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SelectUser
|
||
|
//
|
||
|
// Arguments: pszUsername = User name to select.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tells the status UI host to select the user by the given
|
||
|
// logon name.
|
||
|
//
|
||
|
// History: 2001-01-10 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain)
|
||
|
|
||
|
{
|
||
|
LOGONIPC_USERID logonIPC;
|
||
|
|
||
|
(WCHAR*)lstrcpyW(logonIPC.wszUsername, pszUsername);
|
||
|
(WCHAR*)lstrcpyW(logonIPC.wszDomain, pszDomain);
|
||
|
if (NT_SUCCESS(_pUIHost->PutData(&logonIPC, sizeof(logonIPC))))
|
||
|
{
|
||
|
SendToUIHost(UI_SELECT_USER, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::InteractiveLogon
|
||
|
//
|
||
|
// Arguments: pszUsername = Username to logon.
|
||
|
// pszDomain = Domain to logon.
|
||
|
// pszPassword = Password to use.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Tell the status host to log the specified user on.
|
||
|
//
|
||
|
// History: 2001-01-12 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword)
|
||
|
|
||
|
{
|
||
|
LOGONIPC_CREDENTIALS logonIPCCredentials;
|
||
|
|
||
|
(WCHAR*)lstrcpyW(logonIPCCredentials.userID.wszUsername, pszUsername);
|
||
|
(WCHAR*)lstrcpyW(logonIPCCredentials.userID.wszDomain, pszDomain);
|
||
|
(WCHAR*)lstrcpyW(logonIPCCredentials.wszPassword, pszPassword);
|
||
|
ZeroMemory(pszPassword, (lstrlenW(pszPassword) + sizeof('\0'))* sizeof(WCHAR));
|
||
|
if (NT_SUCCESS(_pUIHost->PutData(&logonIPCCredentials, sizeof(logonIPCCredentials))))
|
||
|
{
|
||
|
SendToUIHost(UI_INTERACTIVE_LOGON, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::ResetReadyEvent
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: HANDLE
|
||
|
//
|
||
|
// Purpose: Reset the UI host ready event. A new instance will set this
|
||
|
// event. Use this in UI host failure.
|
||
|
//
|
||
|
// History: 2001-01-09 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
HANDLE CLogonStatus::ResetReadyEvent (void)
|
||
|
|
||
|
{
|
||
|
TBOOL(ResetEvent(_hEvent));
|
||
|
return(_hEvent);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::IsSuspendAllowed
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: bool
|
||
|
//
|
||
|
// Purpose: Returns whether the UI host allows suspending of the computer.
|
||
|
// This is true if in the logon state or in the status (locked)
|
||
|
// state.
|
||
|
//
|
||
|
// History: 2000-08-21 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::IsSuspendAllowed (void) const
|
||
|
|
||
|
{
|
||
|
return(((_iState == UI_STATE_STATUS) && (_iCode != 0)) ||
|
||
|
(_iStatePending == UI_STATE_LOGON) ||
|
||
|
(_iState == UI_STATE_LOGON) ||
|
||
|
(_iState == UI_STATE_HIDE));
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::ShowUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Shows the UI host.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::ShowUIHost (void)
|
||
|
|
||
|
{
|
||
|
_pUIHost->Show();
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::HideUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Hides the UI host.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::HideUIHost (void)
|
||
|
|
||
|
{
|
||
|
_pUIHost->Hide();
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::IsUIHostHidden
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Returns whether the UI host is hidden.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::IsUIHostHidden (void) const
|
||
|
|
||
|
{
|
||
|
return(_pUIHost->IsHidden());
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::AllowTermination
|
||
|
//
|
||
|
// Arguments: dwExitCode = Exit code of host process.
|
||
|
//
|
||
|
// Returns: bool
|
||
|
//
|
||
|
// Purpose: Returns whether the host process is allowed to terminate
|
||
|
// given the exit code passed in.
|
||
|
//
|
||
|
// Currently the host process is not allowed to terminate.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::AllowTermination (DWORD dwExitCode)
|
||
|
|
||
|
{
|
||
|
UNREFERENCED_PARAMETER(dwExitCode);
|
||
|
|
||
|
return(false);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SignalAbnormalTermination
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose: Handles abnormal termination of host process.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS CLogonStatus::SignalAbnormalTermination (void)
|
||
|
|
||
|
{
|
||
|
HANDLE hThread;
|
||
|
|
||
|
TSTATUS(_logonWait.Cancel());
|
||
|
hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, _dwThreadID);
|
||
|
if (hThread != NULL)
|
||
|
{
|
||
|
(BOOL)QueueUserAPC(CB_UIHostAbnormalTermination, hThread, reinterpret_cast<ULONG_PTR>(this));
|
||
|
TBOOL(CloseHandle(hThread));
|
||
|
}
|
||
|
_Shell_LogonStatus_Destroy(HOST_END_FAILURE);
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SignalRestart
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose: Function to reset the ready event and set the UI host into
|
||
|
// status state. This is invoked when the UI host is restarted
|
||
|
// after a failure.
|
||
|
//
|
||
|
// History: 2001-01-09 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS CLogonStatus::SignalRestart (void)
|
||
|
|
||
|
{
|
||
|
(HANDLE)ResetReadyEvent();
|
||
|
return(_logonWait.Register(_hEvent, this));
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::LogonRestart
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// History: 2001-02-21 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS CLogonStatus::LogonRestart (void)
|
||
|
|
||
|
{
|
||
|
SetStateStatus(0);
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::IsUIHostReady
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: bool
|
||
|
//
|
||
|
// Purpose: Returns whether the UI host is ready.
|
||
|
//
|
||
|
// History: 2000-09-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
bool CLogonStatus::IsUIHostReady (void) const
|
||
|
|
||
|
{
|
||
|
ASSERTMSG(_hEvent != NULL, "No UI host named event to wait on in CLogonStatus::IsUIHostReady");
|
||
|
return(WAIT_OBJECT_0 == WaitForSingleObject(_hEvent, 0));
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::SendToUIHost
|
||
|
//
|
||
|
// Arguments: wParam = WPARAM to send to UI host.
|
||
|
// lParam = LPARAM to send to UI host.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Finds the status window created by SHGINA and sends the
|
||
|
// message to it. That window turns around and sends the message
|
||
|
// to the UI host. This allows communication implemenation method
|
||
|
// to change without forcing the UI host to be rebuilt.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// 2000-09-11 vtan uses PostMessage not SendMessage
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::SendToUIHost (WPARAM wParam, LPARAM lParam)
|
||
|
|
||
|
{
|
||
|
HWND hwnd;
|
||
|
|
||
|
if (IsUIHostReady())
|
||
|
{
|
||
|
hwnd = FindWindow(STATUS_WINDOW_CLASS_NAME, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hwnd = NULL;
|
||
|
}
|
||
|
|
||
|
if (hwnd != NULL)
|
||
|
{
|
||
|
HANDLE hWait;
|
||
|
|
||
|
// Don't allow any registrations if we've found it.
|
||
|
|
||
|
_fRegisteredWait = true;
|
||
|
hWait = InterlockedExchangePointer(&_hWait, NULL);
|
||
|
if (hWait != NULL)
|
||
|
{
|
||
|
if (UnregisterWait(hWait) != FALSE)
|
||
|
{
|
||
|
|
||
|
// If sucesssfully releasing the hWait we need to call release.
|
||
|
|
||
|
Release();
|
||
|
}
|
||
|
}
|
||
|
TBOOL(PostMessage(hwnd, WM_UISERVICEREQUEST, wParam, lParam));
|
||
|
}
|
||
|
else if (!_fRegisteredWait)
|
||
|
{
|
||
|
|
||
|
// Cannot find the UI host window. It's probably still getting
|
||
|
// its act together. Queue this post message for a callback when
|
||
|
// the event is signaled if a register has not already been
|
||
|
// made. If one has then just change the parameters.
|
||
|
// Add a reference here. The callback will release it. If the
|
||
|
// register on the wait failed the release the reference.
|
||
|
|
||
|
if (_hWait == NULL)
|
||
|
{
|
||
|
HANDLE hWait;
|
||
|
|
||
|
AddRef();
|
||
|
if (RegisterWaitForSingleObject(&hWait,
|
||
|
_hEvent,
|
||
|
CB_UIHostReadySignal,
|
||
|
this,
|
||
|
INFINITE,
|
||
|
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE) != FALSE)
|
||
|
{
|
||
|
if (InterlockedCompareExchangePointer(&_hWait, hWait, NULL) == NULL)
|
||
|
{
|
||
|
_fRegisteredWait = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
// Someone else beat us to registering (should never happen)
|
||
|
|
||
|
(BOOL)UnregisterWait(hWait);
|
||
|
Release();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Release();
|
||
|
}
|
||
|
}
|
||
|
_waitWPARAM = wParam;
|
||
|
_waitLPARAM = lParam;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::UIHostReadySignal
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Callback invoked when the UI host signals it's ready. This
|
||
|
// function unregisters the wait and resend the status message
|
||
|
// to the UI host.
|
||
|
//
|
||
|
// History: 2000-09-10 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CLogonStatus::UIHostReadySignal (void)
|
||
|
|
||
|
{
|
||
|
HANDLE hWait;
|
||
|
|
||
|
hWait = InterlockedExchangePointer(&_hWait, NULL);
|
||
|
if (hWait != NULL)
|
||
|
{
|
||
|
TBOOL(UnregisterWait(hWait));
|
||
|
}
|
||
|
SendToUIHost(_waitWPARAM, _waitLPARAM);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::CB_UIHostReadySignal
|
||
|
//
|
||
|
// Arguments: See the platform SDK under WaitOrTimerCallback.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Callback entry point for registered event wait.
|
||
|
//
|
||
|
// History: 2000-09-10 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CALLBACK CLogonStatus::CB_UIHostReadySignal (void *pV, BOOLEAN fTimerOrWaitFired)
|
||
|
|
||
|
{
|
||
|
UNREFERENCED_PARAMETER(fTimerOrWaitFired);
|
||
|
|
||
|
CLogonStatus *pThis;
|
||
|
|
||
|
pThis = reinterpret_cast<CLogonStatus*>(pV);
|
||
|
if (pThis != NULL)
|
||
|
{
|
||
|
pThis->UIHostReadySignal();
|
||
|
}
|
||
|
pThis->Release();
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// CLogonStatus::CB_UIHostAbnormalTermination
|
||
|
//
|
||
|
// Arguments: See the platform SDK under APCProc.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Callback entry point for queued APC on abnormal termination.
|
||
|
//
|
||
|
// History: 2001-02-19 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
void CALLBACK CLogonStatus::CB_UIHostAbnormalTermination (ULONG_PTR dwParam)
|
||
|
|
||
|
{
|
||
|
UNREFERENCED_PARAMETER(dwParam);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_StaticInitialize
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose: Initialize the critical section for g_pLogonStatus.
|
||
|
//
|
||
|
// History: 2001-06-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C NTSTATUS _Shell_LogonStatus_StaticInitialize (void)
|
||
|
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
ASSERTMSG(g_pLogonStatusLock == NULL, "g_pLogonStatusLock already exists in _Shell_LogonStatus_StaticInitialize");
|
||
|
g_pLogonStatusLock = new CCriticalSection;
|
||
|
if (g_pLogonStatusLock != NULL)
|
||
|
{
|
||
|
status = g_pLogonStatusLock->Status();
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
delete g_pLogonStatusLock;
|
||
|
g_pLogonStatusLock = NULL;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = STATUS_NO_MEMORY;
|
||
|
}
|
||
|
return(status);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_StaticTerminate
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: NTSTATUS
|
||
|
//
|
||
|
// Purpose: Delete the critical section for g_pLogonStatus.
|
||
|
//
|
||
|
// History: 2001-06-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C NTSTATUS _Shell_LogonStatus_StaticTerminate (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatusLock != NULL)
|
||
|
{
|
||
|
delete g_pLogonStatusLock;
|
||
|
g_pLogonStatusLock = NULL;
|
||
|
}
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_Init
|
||
|
//
|
||
|
// Arguments: uiStartType = Start mode of status host.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Creates the instance of CLogonStatus telling it to pass
|
||
|
// "/status" as the parameter to the UI host. It then starts
|
||
|
// the host if the object was created.
|
||
|
//
|
||
|
// The object is held globally.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// 2000-07-13 vtan add shutdown parameter.
|
||
|
// 2000-07-17 vtan changed to start type parameter.
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_Init (UINT uiStartType)
|
||
|
|
||
|
{
|
||
|
bool fIsRemote, fIsSessionZero;
|
||
|
|
||
|
fIsRemote = (GetSystemMetrics(SM_REMOTESESSION) != 0);
|
||
|
fIsSessionZero = (NtCurrentPeb()->SessionId == 0);
|
||
|
if ((!fIsRemote || fIsSessionZero || CSystemSettings::IsForceFriendlyUI()) && CSystemSettings::IsFriendlyUIActive())
|
||
|
{
|
||
|
bool fWait;
|
||
|
TCHAR szParameter[256];
|
||
|
|
||
|
if (g_pLogonStatusLock != NULL)
|
||
|
{
|
||
|
g_pLogonStatusLock->Acquire();
|
||
|
if (g_pLogonStatus == NULL)
|
||
|
{
|
||
|
(TCHAR*)lstrcpy(szParameter, TEXT(" /status"));
|
||
|
if (HOST_START_SHUTDOWN == uiStartType)
|
||
|
{
|
||
|
(TCHAR*)lstrcat(szParameter, TEXT(" /shutdown"));
|
||
|
fWait = true;
|
||
|
}
|
||
|
else if (HOST_START_WAIT == uiStartType)
|
||
|
{
|
||
|
(TCHAR*)lstrcat(szParameter, TEXT(" /wait"));
|
||
|
fWait = true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fWait = false;
|
||
|
}
|
||
|
g_pLogonStatus = new CLogonStatus(szParameter);
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
g_pLogonStatusLock->Release();
|
||
|
status = g_pLogonStatus->Start(fWait);
|
||
|
g_pLogonStatusLock->Acquire();
|
||
|
if (!NT_SUCCESS(status) && (g_pLogonStatus != NULL))
|
||
|
{
|
||
|
g_pLogonStatus->Release();
|
||
|
g_pLogonStatus = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_pLogonStatus->SetStateStatus(0);
|
||
|
if ((HOST_START_SHUTDOWN == uiStartType) || (HOST_START_WAIT == uiStartType))
|
||
|
{
|
||
|
g_pLogonStatus->NotifyWait();
|
||
|
}
|
||
|
}
|
||
|
g_pLogonStatusLock->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_Destroy
|
||
|
//
|
||
|
// Arguments: uiEndType = End mode of status host.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: If the end type is hide then tell the status host to hide.
|
||
|
// Otherwise check the end type is terminate. In that case tell
|
||
|
// the status host to go away.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// 2001-01-09 vtan add end parameter
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_Destroy (UINT uiEndType)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatusLock != NULL)
|
||
|
{
|
||
|
CSingleThreadedExecution lock(*g_pLogonStatusLock);
|
||
|
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
switch (uiEndType)
|
||
|
{
|
||
|
case HOST_END_HIDE:
|
||
|
|
||
|
// HOST_END_HIDE: Is the UI host static? If so then hide it.
|
||
|
// Otherwise revert to start/stop mode (dynamic) and force the
|
||
|
// UI host to terminate.
|
||
|
|
||
|
if (CSystemSettings::IsUIHostStatic())
|
||
|
{
|
||
|
g_pLogonStatus->SetStateHide();
|
||
|
break;
|
||
|
}
|
||
|
uiEndType = HOST_END_TERMINATE;
|
||
|
|
||
|
// If the the host is dynamic then set the type to
|
||
|
// HOST_END_TERMINATE and fall thru to this case so that
|
||
|
// the host is told to end.
|
||
|
|
||
|
case HOST_END_TERMINATE:
|
||
|
|
||
|
// HOST_END_TERMINATE: Force the UI host to terminate. This is
|
||
|
// used in circumstances where it must terminate such as we
|
||
|
// are terminating or the machine is shutting down.
|
||
|
|
||
|
g_pLogonStatus->SetStateEnd(true);
|
||
|
break;
|
||
|
case HOST_END_FAILURE:
|
||
|
|
||
|
// HOST_END_FAILURE: This is sent when the UI host failed to
|
||
|
// start and will not be restarted. This allows the interface
|
||
|
// reference to be deleted so that object reference count
|
||
|
// will reach zero and the memory will be released.
|
||
|
|
||
|
g_pLogonStatus->SetStateEnd(false);
|
||
|
uiEndType = HOST_END_TERMINATE;
|
||
|
break;
|
||
|
default:
|
||
|
DISPLAYMSG("Unknown uiEndType passed to _Shell_LogonStatus_Destroy");
|
||
|
break;
|
||
|
}
|
||
|
if (HOST_END_TERMINATE == uiEndType)
|
||
|
{
|
||
|
g_pLogonStatus->Release();
|
||
|
g_pLogonStatus = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_Exists
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: BOOL
|
||
|
//
|
||
|
// Purpose: Returns whether there is status host created.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C BOOL _Shell_LogonStatus_Exists (void)
|
||
|
|
||
|
{
|
||
|
return(g_pLogonStatus != NULL);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_IsStatusWindow
|
||
|
//
|
||
|
// Arguments: hwnd = HWND to check.
|
||
|
//
|
||
|
// Returns: BOOL
|
||
|
//
|
||
|
// Purpose: Returns whether the given HWND is the status HWND.
|
||
|
//
|
||
|
// History: 2000-06-26 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C BOOL _Shell_LogonStatus_IsStatusWindow (HWND hwnd)
|
||
|
|
||
|
{
|
||
|
return(CLogonStatus::IsStatusWindow(hwnd));
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_IsSuspendAllowed
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: BOOL
|
||
|
//
|
||
|
// Purpose: Ask the status host (if present) if suspend is allowed.
|
||
|
//
|
||
|
// History: 2000-08-18 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C BOOL _Shell_LogonStatus_IsSuspendAllowed (void)
|
||
|
|
||
|
{
|
||
|
return((g_pLogonStatus == NULL) || g_pLogonStatus->IsSuspendAllowed());
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_WaitforUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: BOOL
|
||
|
//
|
||
|
// Purpose: External C entry point to force the current thread to wait
|
||
|
// until the UI host signals it's ready. Returns whether the
|
||
|
// wait was successful or abandoned. Success is true. Abandoned
|
||
|
// or non-existant is false.
|
||
|
//
|
||
|
// History: 2000-09-10 vtan created
|
||
|
// 2001-02-19 vtan added return result
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C BOOL _Shell_LogonStatus_WaitForUIHost (void)
|
||
|
|
||
|
{
|
||
|
return((g_pLogonStatus != NULL) && g_pLogonStatus->WaitForUIHost());
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_ShowStatusMessage
|
||
|
//
|
||
|
// Arguments: pszMessage = Unicode string to display.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to pass display string to status host.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_ShowStatusMessage (const WCHAR *pszMessage)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->ShowStatusMessage(pszMessage);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SetStateStatus
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to go to status
|
||
|
// state.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SetStateStatus (int iCode)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SetStateStatus(iCode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SetStateLogon
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to go to logon
|
||
|
// state.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SetStateLogon (int iCode)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SetStateLogon(iCode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SetStateLoggedOn
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to go to
|
||
|
// logged on state.
|
||
|
//
|
||
|
// History: 2000-05-24 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SetStateLoggedOn (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SetStateLoggedOn();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SetStateHide
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to hide itself.
|
||
|
//
|
||
|
// History: 2001-01-08 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SetStateHide (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SetStateHide();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SetStateEnd
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to terminate.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SetStateEnd (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SetStateEnd(true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_NotifyWait
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to display a
|
||
|
// title stating the system is preparing to shut down.
|
||
|
//
|
||
|
// History: 2000-07-14 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_NotifyWait (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->NotifyWait();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_NotifyNoAnimations
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to no longer
|
||
|
// perform animations.
|
||
|
//
|
||
|
// History: 2001-03-21 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_NotifyNoAnimations (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->NotifyNoAnimations();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_SelectUser
|
||
|
//
|
||
|
// Arguments: pszUsername = Username to select.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to select a
|
||
|
// specific user as being logged on.
|
||
|
//
|
||
|
// History: 2001-01-10 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->SelectUser(pszUsername, pszDomain);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_InteractiveLogon
|
||
|
//
|
||
|
// Arguments: pszUsername = Username to logon.
|
||
|
// pszDomain = Domain to logon.
|
||
|
// pszPassword = Password to use.
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: External C entry point to tell the status host to log the
|
||
|
// specified user on.
|
||
|
//
|
||
|
// History: 2001-01-12 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->InteractiveLogon(pszUsername, pszDomain, pszPassword);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_GetUIHost
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: void*
|
||
|
//
|
||
|
// Purpose: External C entry point that returns a reference to the UI
|
||
|
// host object. This is returned as a void* because C doesn't
|
||
|
// understand C++ objects. The void* is cast to the appropriate
|
||
|
// type for use in CWLogonDialog.cpp so that it doesn't go and
|
||
|
// create a new instance of the object but increments the
|
||
|
// reference to this already existing object.
|
||
|
//
|
||
|
// History: 2000-05-11 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void* _Shell_LogonStatus_GetUIHost (void)
|
||
|
|
||
|
{
|
||
|
void *pResult;
|
||
|
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
pResult = g_pLogonStatus->GetUIHost();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pResult = NULL;
|
||
|
}
|
||
|
return(pResult);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_ResetReadyEvent
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: HANDLE
|
||
|
//
|
||
|
// Purpose: Resets the ready event in case of UI host failure.
|
||
|
//
|
||
|
// History: 2001-01-09 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C HANDLE _Shell_LogonStatus_ResetReadyEvent (void)
|
||
|
|
||
|
{
|
||
|
HANDLE hEvent;
|
||
|
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
hEvent = g_pLogonStatus->ResetReadyEvent();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hEvent = NULL;
|
||
|
}
|
||
|
return(hEvent);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_Show
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Shows the UI host.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_Show (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->ShowUIHost();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_Hide
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Hides the UI host.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C void _Shell_LogonStatus_Hide (void)
|
||
|
|
||
|
{
|
||
|
if (g_pLogonStatus != NULL)
|
||
|
{
|
||
|
g_pLogonStatus->HideUIHost();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ::_Shell_LogonStatus_IsHidden
|
||
|
//
|
||
|
// Arguments: <none>
|
||
|
//
|
||
|
// Returns: <none>
|
||
|
//
|
||
|
// Purpose: Returns whether the UI host is hidden.
|
||
|
//
|
||
|
// History: 2001-03-05 vtan created
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
EXTERN_C BOOL _Shell_LogonStatus_IsHidden (void)
|
||
|
|
||
|
{
|
||
|
return((g_pLogonStatus != NULL) && g_pLogonStatus->IsUIHostHidden());
|
||
|
}
|
||
|
|