Source code of Windows XP (NT5)
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.

1607 lines
47 KiB

  1. // --------------------------------------------------------------------------
  2. // Module Name: CWLogonStatus.cpp
  3. //
  4. // Copyright (c) 2000, Microsoft Corporation
  5. //
  6. // File that contains implementation for status UI hosting by an external
  7. // process.
  8. //
  9. // History: 2000-05-11 vtan created
  10. // --------------------------------------------------------------------------
  11. #include "StandardHeader.h"
  12. #include <msginaexports.h>
  13. #include "Access.h"
  14. #include "GinaIPC.h"
  15. #include "LogonWait.h"
  16. #include "SingleThreadedExecution.h"
  17. #include "StatusCode.h"
  18. #include "SystemSettings.h"
  19. #include "UIHost.h"
  20. // --------------------------------------------------------------------------
  21. // CLogonStatus
  22. //
  23. // Purpose: C++ class to handle logon status external process for consumer
  24. // windows.
  25. //
  26. // History: 2000-05-11 vtan created
  27. // --------------------------------------------------------------------------
  28. class CLogonStatus : public ILogonExternalProcess
  29. {
  30. private:
  31. CLogonStatus (void);
  32. public:
  33. CLogonStatus (const TCHAR *pszParameter);
  34. ~CLogonStatus (void);
  35. NTSTATUS Start (bool fWait);
  36. CUIHost* GetUIHost (void);
  37. static bool IsStatusWindow (HWND hwnd);
  38. bool WaitForUIHost (void);
  39. void ShowStatusMessage (const WCHAR *pszMessage);
  40. void SetStateStatus (int iCode);
  41. void SetStateLogon (int iCode);
  42. void SetStateLoggedOn (void);
  43. void SetStateHide (void);
  44. void SetStateEnd (bool fSendMessage);
  45. void NotifyWait (void);
  46. void NotifyNoAnimations (void);
  47. void SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain);
  48. void InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword);
  49. HANDLE ResetReadyEvent (void);
  50. bool IsSuspendAllowed (void) const;
  51. void ShowUIHost (void);
  52. void HideUIHost (void);
  53. bool IsUIHostHidden (void) const;
  54. public:
  55. virtual bool AllowTermination (DWORD dwExitCode);
  56. virtual NTSTATUS SignalAbnormalTermination (void);
  57. virtual NTSTATUS SignalRestart (void);
  58. virtual NTSTATUS LogonRestart (void);
  59. private:
  60. bool IsUIHostReady (void) const;
  61. void SendToUIHost (WPARAM wParam, LPARAM lParam);
  62. void UIHostReadySignal (void);
  63. static void CALLBACK CB_UIHostReadySignal (void *pV, BOOLEAN fTimerOrWaitFired);
  64. static void CALLBACK CB_UIHostAbnormalTermination (ULONG_PTR dwParam);
  65. private:
  66. DWORD _dwThreadID;
  67. bool _fRegisteredWait;
  68. HANDLE _hEvent;
  69. HANDLE _hWait;
  70. int _iState,
  71. _iCode,
  72. _iStatePending;
  73. WPARAM _waitWPARAM;
  74. LPARAM _waitLPARAM;
  75. CUIHost* _pUIHost;
  76. CLogonWait _logonWait;
  77. };
  78. CCriticalSection* g_pLogonStatusLock = NULL;
  79. CLogonStatus* g_pLogonStatus = NULL;
  80. // --------------------------------------------------------------------------
  81. // CLogonStatus::CLogonStatus
  82. //
  83. // Arguments: pszParameter = Parameter to pass to status UI host.
  84. //
  85. // Returns: <none>
  86. //
  87. // Purpose: Constructor for CLogonStatus. This gets the status UI host
  88. // from the registry and assigns the given parameter into the
  89. // object. Create a named event which SHGINA knows about and
  90. // will signal once the ILogonStatusHost class has been
  91. // instantiated.
  92. //
  93. // History: 2000-05-11 vtan created
  94. // --------------------------------------------------------------------------
  95. CLogonStatus::CLogonStatus (const TCHAR *pszParameter) :
  96. _dwThreadID(0),
  97. _fRegisteredWait(false),
  98. _hEvent(NULL),
  99. _hWait(NULL),
  100. _iState(UI_STATE_STATUS),
  101. _iCode(0),
  102. _iStatePending(0),
  103. _waitWPARAM(0),
  104. _waitLPARAM(0),
  105. _pUIHost(NULL)
  106. {
  107. TCHAR szRawHostCommandLine[MAX_PATH];
  108. if (ERROR_SUCCESS == CSystemSettings::GetUIHost(szRawHostCommandLine))
  109. {
  110. _pUIHost = new CUIHost(szRawHostCommandLine);
  111. if (_pUIHost != NULL)
  112. {
  113. _pUIHost->SetInterface(this);
  114. _pUIHost->SetParameter(pszParameter);
  115. }
  116. }
  117. SECURITY_ATTRIBUTES securityAttributes;
  118. // Build a security descriptor for the event that allows:
  119. // S-1-5-18 EVENT_ALL_ACCESS
  120. // S-1-5-32-544 SYNCHRONIZE | READ_CONTROL | EVENT_QUERY_STATE
  121. static SID_IDENTIFIER_AUTHORITY s_SecurityNTAuthority = SECURITY_NT_AUTHORITY;
  122. static const CSecurityDescriptor::ACCESS_CONTROL s_AccessControl[] =
  123. {
  124. {
  125. &s_SecurityNTAuthority,
  126. 1,
  127. SECURITY_LOCAL_SYSTEM_RID,
  128. 0, 0, 0, 0, 0, 0, 0,
  129. EVENT_ALL_ACCESS
  130. },
  131. {
  132. &s_SecurityNTAuthority,
  133. 2,
  134. SECURITY_BUILTIN_DOMAIN_RID,
  135. DOMAIN_ALIAS_RID_ADMINS,
  136. 0, 0, 0, 0, 0, 0,
  137. SYNCHRONIZE | READ_CONTROL | EVENT_QUERY_STATE
  138. }
  139. };
  140. securityAttributes.nLength = sizeof(securityAttributes);
  141. securityAttributes.lpSecurityDescriptor = CSecurityDescriptor::Create(ARRAYSIZE(s_AccessControl), s_AccessControl);
  142. securityAttributes.bInheritHandle = FALSE;
  143. _hEvent = CreateEvent(&securityAttributes, TRUE, FALSE, TEXT("msgina: StatusHostReadyEvent"));
  144. ReleaseMemory(securityAttributes.lpSecurityDescriptor);
  145. }
  146. // --------------------------------------------------------------------------
  147. // CLogonStatus::~CLogonStatus
  148. //
  149. // Arguments: <none>
  150. //
  151. // Returns: <none>
  152. //
  153. // Purpose: Destructor for CLogonStatus. Releases references.
  154. //
  155. // History: 2000-05-11 vtan created
  156. // --------------------------------------------------------------------------
  157. CLogonStatus::~CLogonStatus (void)
  158. {
  159. ASSERTMSG(_hWait == NULL, "Resend wait object not released in CLogonStatus::~CLogonStatus");
  160. ReleaseHandle(_hEvent);
  161. ASSERTMSG(_iState == UI_STATE_END, "State must be UI_STATE_END in CLogonStatus::~CLogonStatus");
  162. if (_pUIHost != NULL)
  163. {
  164. _pUIHost->Release();
  165. _pUIHost = NULL;
  166. }
  167. }
  168. // --------------------------------------------------------------------------
  169. // CLogonStatus::Start
  170. //
  171. // Arguments: fWait = Wait for status host to signal ready.
  172. //
  173. // Returns: NTSTATUS
  174. //
  175. // Purpose: Starts the status UI host. Don't wait for the UI host. There
  176. // is a mechanism that can queue a message if the UI host window
  177. // cannot be found.
  178. //
  179. // History: 2000-05-11 vtan created
  180. // --------------------------------------------------------------------------
  181. NTSTATUS CLogonStatus::Start (bool fWait)
  182. {
  183. NTSTATUS status;
  184. if (_pUIHost != NULL)
  185. {
  186. (HANDLE)ResetReadyEvent();
  187. status = _pUIHost->Start();
  188. if (NT_SUCCESS(status))
  189. {
  190. _dwThreadID = GetCurrentThreadId();
  191. if (fWait || _pUIHost->WaitRequired())
  192. {
  193. if (!WaitForUIHost())
  194. {
  195. status = STATUS_UNSUCCESSFUL;
  196. }
  197. }
  198. }
  199. }
  200. else
  201. {
  202. status = STATUS_UNSUCCESSFUL;
  203. }
  204. return(status);
  205. }
  206. // --------------------------------------------------------------------------
  207. // CLogonStatus::GetUIHost
  208. //
  209. // Arguments: <none>
  210. //
  211. // Returns: CUIHost*
  212. //
  213. // Purpose: Returns a reference to the UIHost object held internally.
  214. // The reference belongs to the caller and must be released.
  215. //
  216. // History: 2000-05-11 vtan created
  217. // --------------------------------------------------------------------------
  218. CUIHost* CLogonStatus::GetUIHost (void)
  219. {
  220. if (_pUIHost != NULL)
  221. {
  222. _pUIHost->AddRef();
  223. }
  224. return(_pUIHost);
  225. }
  226. // --------------------------------------------------------------------------
  227. // CLogonStatus::IsStatusWindow
  228. //
  229. // Arguments: hwnd = HWND to check.
  230. //
  231. // Returns: bool
  232. //
  233. // Purpose: Returns whether the given HWND is the status window.
  234. //
  235. // History: 2000-06-26 vtan created
  236. // --------------------------------------------------------------------------
  237. bool CLogonStatus::IsStatusWindow (HWND hwnd)
  238. {
  239. TCHAR szWindowClass[256];
  240. return((GetClassName(hwnd, szWindowClass, ARRAYSIZE(szWindowClass)) != 0) &&
  241. (lstrcmpi(STATUS_WINDOW_CLASS_NAME, szWindowClass) == 0));
  242. }
  243. // --------------------------------------------------------------------------
  244. // CLogonStatus::WaitForUIHost
  245. //
  246. // Arguments: <none>
  247. //
  248. // Returns: bool
  249. //
  250. // Purpose: Waits on the named event that the UI host signals when it's
  251. // initialized. Typically this happens very quickly but we don't
  252. // wait on it when starting up the UI host.
  253. //
  254. // History: 2000-09-10 vtan created
  255. // --------------------------------------------------------------------------
  256. bool CLogonStatus::WaitForUIHost (void)
  257. {
  258. bool fResult;
  259. fResult = true;
  260. ASSERTMSG(_hEvent != NULL, "No UI host named event to wait on in CLogonStatus::WaitForUIHost");
  261. if (!IsUIHostReady())
  262. {
  263. DWORD dwWaitResult;
  264. #ifdef DBG
  265. DWORD dwWaitStart, dwWaitEnd;
  266. dwWaitStart = (WAIT_TIMEOUT == WaitForSingleObject(_hEvent, 0)) ? GetTickCount() : 0;
  267. #endif /* DBG */
  268. do
  269. {
  270. dwWaitResult = WaitForSingleObject(_hEvent, 0);
  271. if (dwWaitResult != WAIT_OBJECT_0)
  272. {
  273. dwWaitResult = MsgWaitForMultipleObjectsEx(1, &_hEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE);
  274. if (dwWaitResult == WAIT_OBJECT_0 + 1)
  275. {
  276. MSG msg;
  277. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE)
  278. {
  279. (BOOL)TranslateMessage(&msg);
  280. (LRESULT)DispatchMessage(&msg);
  281. }
  282. }
  283. }
  284. } while ((dwWaitResult == WAIT_OBJECT_0 + 1) && (dwWaitResult != WAIT_IO_COMPLETION));
  285. #ifdef DBG
  286. dwWaitEnd = GetTickCount();
  287. if ((dwWaitStart != 0) && ((dwWaitEnd - dwWaitStart) != 0))
  288. {
  289. char szBuffer[256];
  290. wsprintfA(szBuffer, "waited %d ticks for UI host", dwWaitEnd - dwWaitStart);
  291. INFORMATIONMSG(szBuffer);
  292. }
  293. #endif /* DBG */
  294. fResult = (dwWaitResult != WAIT_IO_COMPLETION);
  295. }
  296. return(fResult);
  297. }
  298. // --------------------------------------------------------------------------
  299. // CLogonStatus::ShowStatusMessage
  300. //
  301. // Arguments: pszMessage = Unicode string message to display.
  302. //
  303. // Returns: <none>
  304. //
  305. // Purpose: Tells the UI host to display the given string message. Puts
  306. // the string directly inside the status host process and tells
  307. // the process where in its address space to find the string.
  308. // The string is limited to 256 characters.
  309. //
  310. // History: 2000-05-11 vtan created
  311. // --------------------------------------------------------------------------
  312. void CLogonStatus::ShowStatusMessage (const WCHAR *pszMessage)
  313. {
  314. if (NT_SUCCESS(_pUIHost->PutString(pszMessage)))
  315. {
  316. SendToUIHost(UI_DISPLAY_STATUS, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
  317. }
  318. }
  319. // --------------------------------------------------------------------------
  320. // CLogonStatus::SetStateStatus
  321. //
  322. // Arguments: iCode = Magic code number for lock.
  323. //
  324. // Returns: <none>
  325. //
  326. // Purpose: Tells the status UI host to go into status state.
  327. //
  328. // History: 2000-05-11 vtan created
  329. // --------------------------------------------------------------------------
  330. void CLogonStatus::SetStateStatus (int iCode)
  331. {
  332. _iStatePending = UI_STATE_STATUS;
  333. if (WaitForUIHost() && (_iState != UI_STATE_STATUS))
  334. {
  335. SendToUIHost(UI_STATE_STATUS, iCode);
  336. _iState = UI_STATE_STATUS;
  337. _iCode = iCode;
  338. }
  339. _iStatePending = UI_STATE_NONE;
  340. }
  341. // --------------------------------------------------------------------------
  342. // CLogonStatus::SetStateLogon
  343. //
  344. // Arguments: iCode = Magic code number for lock.
  345. //
  346. // Returns: <none>
  347. //
  348. // Purpose: Tells the status UI host to go into logon state.
  349. //
  350. // History: 2000-05-11 vtan created
  351. // --------------------------------------------------------------------------
  352. void CLogonStatus::SetStateLogon (int iCode)
  353. {
  354. _iStatePending = UI_STATE_LOGON;
  355. if (WaitForUIHost() && (iCode == _iCode))
  356. {
  357. SendToUIHost(UI_STATE_LOGON, iCode);
  358. _iState = UI_STATE_LOGON;
  359. _iCode = 0;
  360. }
  361. _iStatePending = UI_STATE_NONE;
  362. }
  363. // --------------------------------------------------------------------------
  364. // CLogonStatus::SetStateLoggedOn
  365. //
  366. // Arguments: <none>
  367. //
  368. // Returns: <none>
  369. //
  370. // Purpose: Tells the status UI host to go into logged on state.
  371. //
  372. // History: 2000-05-24 vtan created
  373. // --------------------------------------------------------------------------
  374. void CLogonStatus::SetStateLoggedOn (void)
  375. {
  376. _iStatePending = UI_STATE_STATUS;
  377. if (WaitForUIHost())
  378. {
  379. SendToUIHost(UI_STATE_LOGGEDON, 0);
  380. _iState = UI_STATE_STATUS;
  381. }
  382. _iStatePending = UI_STATE_NONE;
  383. }
  384. // --------------------------------------------------------------------------
  385. // CLogonStatus::SetStateHide
  386. //
  387. // Arguments: <none>
  388. //
  389. // Returns: <none>
  390. //
  391. // Purpose: Tells the status UI host to hide itself.
  392. //
  393. // History: 2001-01-08 vtan created
  394. // --------------------------------------------------------------------------
  395. void CLogonStatus::SetStateHide (void)
  396. {
  397. _iStatePending = UI_STATE_HIDE;
  398. if (WaitForUIHost())
  399. {
  400. SendToUIHost(UI_STATE_HIDE, 0);
  401. _iState = UI_STATE_HIDE;
  402. }
  403. _iStatePending = UI_STATE_NONE;
  404. }
  405. // --------------------------------------------------------------------------
  406. // CLogonStatus::SetStateEnd
  407. //
  408. // Arguments: fSendMessage = Send message to UI host or not.
  409. //
  410. // Returns: <none>
  411. //
  412. // Purpose: Tells the status UI host to end and terminate itself.
  413. //
  414. // History: 2000-05-11 vtan created
  415. // --------------------------------------------------------------------------
  416. void CLogonStatus::SetStateEnd (bool fSendMessage)
  417. {
  418. bool fHostAlive;
  419. HANDLE hWait;
  420. _iStatePending = UI_STATE_END;
  421. // When going into end mode if there's a wait registered then
  422. // unregister it. This will release an outstanding reference.
  423. // A re-register should never happen but this is set just in case.
  424. _fRegisteredWait = true;
  425. hWait = InterlockedExchangePointer(&_hWait, NULL);
  426. if (hWait != NULL)
  427. {
  428. if (UnregisterWait(hWait) != FALSE)
  429. {
  430. Release();
  431. }
  432. }
  433. if (fSendMessage)
  434. {
  435. fHostAlive = WaitForUIHost();
  436. }
  437. else
  438. {
  439. fHostAlive = true;
  440. }
  441. if (fHostAlive)
  442. {
  443. if (_pUIHost != NULL)
  444. {
  445. _pUIHost->SetInterface(NULL);
  446. }
  447. if (fSendMessage)
  448. {
  449. SendToUIHost(UI_STATE_END, 0);
  450. }
  451. _iState = UI_STATE_END;
  452. }
  453. _iStatePending = UI_STATE_NONE;
  454. }
  455. // --------------------------------------------------------------------------
  456. // CLogonStatus::NotifyWait
  457. //
  458. // Arguments: <none>
  459. //
  460. // Returns: <none>
  461. //
  462. // Purpose: Tells the status UI host to display a title that the system
  463. // is shutting down.
  464. //
  465. // History: 2000-07-14 vtan created
  466. // --------------------------------------------------------------------------
  467. void CLogonStatus::NotifyWait (void)
  468. {
  469. SendToUIHost(UI_NOTIFY_WAIT, 0);
  470. }
  471. // --------------------------------------------------------------------------
  472. // CLogonStatus::NotifyNoAnimations
  473. //
  474. // Arguments: <none>
  475. //
  476. // Returns: <none>
  477. //
  478. // Purpose: Tells the status UI host to no longer perform animations.
  479. //
  480. // History: 2001-03-21 vtan created
  481. // --------------------------------------------------------------------------
  482. void CLogonStatus::NotifyNoAnimations (void)
  483. {
  484. SendToUIHost(UI_SET_ANIMATIONS, 0);
  485. }
  486. // --------------------------------------------------------------------------
  487. // CLogonStatus::SelectUser
  488. //
  489. // Arguments: pszUsername = User name to select.
  490. //
  491. // Returns: <none>
  492. //
  493. // Purpose: Tells the status UI host to select the user by the given
  494. // logon name.
  495. //
  496. // History: 2001-01-10 vtan created
  497. // --------------------------------------------------------------------------
  498. void CLogonStatus::SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain)
  499. {
  500. LOGONIPC_USERID logonIPC;
  501. (WCHAR*)lstrcpyW(logonIPC.wszUsername, pszUsername);
  502. (WCHAR*)lstrcpyW(logonIPC.wszDomain, pszDomain);
  503. if (NT_SUCCESS(_pUIHost->PutData(&logonIPC, sizeof(logonIPC))))
  504. {
  505. SendToUIHost(UI_SELECT_USER, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
  506. }
  507. }
  508. // --------------------------------------------------------------------------
  509. // CLogonStatus::InteractiveLogon
  510. //
  511. // Arguments: pszUsername = Username to logon.
  512. // pszDomain = Domain to logon.
  513. // pszPassword = Password to use.
  514. //
  515. // Returns: <none>
  516. //
  517. // Purpose: Tell the status host to log the specified user on.
  518. //
  519. // History: 2001-01-12 vtan created
  520. // --------------------------------------------------------------------------
  521. void CLogonStatus::InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword)
  522. {
  523. LOGONIPC_CREDENTIALS logonIPCCredentials;
  524. (WCHAR*)lstrcpyW(logonIPCCredentials.userID.wszUsername, pszUsername);
  525. (WCHAR*)lstrcpyW(logonIPCCredentials.userID.wszDomain, pszDomain);
  526. (WCHAR*)lstrcpyW(logonIPCCredentials.wszPassword, pszPassword);
  527. ZeroMemory(pszPassword, (lstrlenW(pszPassword) + sizeof('\0'))* sizeof(WCHAR));
  528. if (NT_SUCCESS(_pUIHost->PutData(&logonIPCCredentials, sizeof(logonIPCCredentials))))
  529. {
  530. SendToUIHost(UI_INTERACTIVE_LOGON, reinterpret_cast<LONG_PTR>(_pUIHost->GetDataAddress()));
  531. }
  532. }
  533. // --------------------------------------------------------------------------
  534. // CLogonStatus::ResetReadyEvent
  535. //
  536. // Arguments: <none>
  537. //
  538. // Returns: HANDLE
  539. //
  540. // Purpose: Reset the UI host ready event. A new instance will set this
  541. // event. Use this in UI host failure.
  542. //
  543. // History: 2001-01-09 vtan created
  544. // --------------------------------------------------------------------------
  545. HANDLE CLogonStatus::ResetReadyEvent (void)
  546. {
  547. TBOOL(ResetEvent(_hEvent));
  548. return(_hEvent);
  549. }
  550. // --------------------------------------------------------------------------
  551. // CLogonStatus::IsSuspendAllowed
  552. //
  553. // Arguments: <none>
  554. //
  555. // Returns: bool
  556. //
  557. // Purpose: Returns whether the UI host allows suspending of the computer.
  558. // This is true if in the logon state or in the status (locked)
  559. // state.
  560. //
  561. // History: 2000-08-21 vtan created
  562. // --------------------------------------------------------------------------
  563. bool CLogonStatus::IsSuspendAllowed (void) const
  564. {
  565. return(((_iState == UI_STATE_STATUS) && (_iCode != 0)) ||
  566. (_iStatePending == UI_STATE_LOGON) ||
  567. (_iState == UI_STATE_LOGON) ||
  568. (_iState == UI_STATE_HIDE));
  569. }
  570. // --------------------------------------------------------------------------
  571. // CLogonStatus::ShowUIHost
  572. //
  573. // Arguments: <none>
  574. //
  575. // Returns: <none>
  576. //
  577. // Purpose: Shows the UI host.
  578. //
  579. // History: 2001-03-05 vtan created
  580. // --------------------------------------------------------------------------
  581. void CLogonStatus::ShowUIHost (void)
  582. {
  583. _pUIHost->Show();
  584. }
  585. // --------------------------------------------------------------------------
  586. // CLogonStatus::HideUIHost
  587. //
  588. // Arguments: <none>
  589. //
  590. // Returns: <none>
  591. //
  592. // Purpose: Hides the UI host.
  593. //
  594. // History: 2001-03-05 vtan created
  595. // --------------------------------------------------------------------------
  596. void CLogonStatus::HideUIHost (void)
  597. {
  598. _pUIHost->Hide();
  599. }
  600. // --------------------------------------------------------------------------
  601. // CLogonStatus::IsUIHostHidden
  602. //
  603. // Arguments: <none>
  604. //
  605. // Returns: <none>
  606. //
  607. // Purpose: Returns whether the UI host is hidden.
  608. //
  609. // History: 2001-03-05 vtan created
  610. // --------------------------------------------------------------------------
  611. bool CLogonStatus::IsUIHostHidden (void) const
  612. {
  613. return(_pUIHost->IsHidden());
  614. }
  615. // --------------------------------------------------------------------------
  616. // CLogonStatus::AllowTermination
  617. //
  618. // Arguments: dwExitCode = Exit code of host process.
  619. //
  620. // Returns: bool
  621. //
  622. // Purpose: Returns whether the host process is allowed to terminate
  623. // given the exit code passed in.
  624. //
  625. // Currently the host process is not allowed to terminate.
  626. //
  627. // History: 2000-05-11 vtan created
  628. // --------------------------------------------------------------------------
  629. bool CLogonStatus::AllowTermination (DWORD dwExitCode)
  630. {
  631. UNREFERENCED_PARAMETER(dwExitCode);
  632. return(false);
  633. }
  634. // --------------------------------------------------------------------------
  635. // CLogonStatus::SignalAbnormalTermination
  636. //
  637. // Arguments: <none>
  638. //
  639. // Returns: NTSTATUS
  640. //
  641. // Purpose: Handles abnormal termination of host process.
  642. //
  643. // History: 2000-05-11 vtan created
  644. // --------------------------------------------------------------------------
  645. NTSTATUS CLogonStatus::SignalAbnormalTermination (void)
  646. {
  647. HANDLE hThread;
  648. TSTATUS(_logonWait.Cancel());
  649. hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, _dwThreadID);
  650. if (hThread != NULL)
  651. {
  652. (BOOL)QueueUserAPC(CB_UIHostAbnormalTermination, hThread, reinterpret_cast<ULONG_PTR>(this));
  653. TBOOL(CloseHandle(hThread));
  654. }
  655. _Shell_LogonStatus_Destroy(HOST_END_FAILURE);
  656. return(STATUS_SUCCESS);
  657. }
  658. // --------------------------------------------------------------------------
  659. // CLogonStatus::SignalRestart
  660. //
  661. // Arguments: <none>
  662. //
  663. // Returns: NTSTATUS
  664. //
  665. // Purpose: Function to reset the ready event and set the UI host into
  666. // status state. This is invoked when the UI host is restarted
  667. // after a failure.
  668. //
  669. // History: 2001-01-09 vtan created
  670. // --------------------------------------------------------------------------
  671. NTSTATUS CLogonStatus::SignalRestart (void)
  672. {
  673. (HANDLE)ResetReadyEvent();
  674. return(_logonWait.Register(_hEvent, this));
  675. }
  676. // --------------------------------------------------------------------------
  677. // CLogonStatus::LogonRestart
  678. //
  679. // Arguments: <none>
  680. //
  681. // Returns: NTSTATUS
  682. //
  683. // Purpose:
  684. //
  685. // History: 2001-02-21 vtan created
  686. // --------------------------------------------------------------------------
  687. NTSTATUS CLogonStatus::LogonRestart (void)
  688. {
  689. SetStateStatus(0);
  690. return(STATUS_SUCCESS);
  691. }
  692. // --------------------------------------------------------------------------
  693. // CLogonStatus::IsUIHostReady
  694. //
  695. // Arguments: <none>
  696. //
  697. // Returns: bool
  698. //
  699. // Purpose: Returns whether the UI host is ready.
  700. //
  701. // History: 2000-09-11 vtan created
  702. // --------------------------------------------------------------------------
  703. bool CLogonStatus::IsUIHostReady (void) const
  704. {
  705. ASSERTMSG(_hEvent != NULL, "No UI host named event to wait on in CLogonStatus::IsUIHostReady");
  706. return(WAIT_OBJECT_0 == WaitForSingleObject(_hEvent, 0));
  707. }
  708. // --------------------------------------------------------------------------
  709. // CLogonStatus::SendToUIHost
  710. //
  711. // Arguments: wParam = WPARAM to send to UI host.
  712. // lParam = LPARAM to send to UI host.
  713. //
  714. // Returns: <none>
  715. //
  716. // Purpose: Finds the status window created by SHGINA and sends the
  717. // message to it. That window turns around and sends the message
  718. // to the UI host. This allows communication implemenation method
  719. // to change without forcing the UI host to be rebuilt.
  720. //
  721. // History: 2000-05-11 vtan created
  722. // 2000-09-11 vtan uses PostMessage not SendMessage
  723. // --------------------------------------------------------------------------
  724. void CLogonStatus::SendToUIHost (WPARAM wParam, LPARAM lParam)
  725. {
  726. HWND hwnd;
  727. if (IsUIHostReady())
  728. {
  729. hwnd = FindWindow(STATUS_WINDOW_CLASS_NAME, NULL);
  730. }
  731. else
  732. {
  733. hwnd = NULL;
  734. }
  735. if (hwnd != NULL)
  736. {
  737. HANDLE hWait;
  738. // Don't allow any registrations if we've found it.
  739. _fRegisteredWait = true;
  740. hWait = InterlockedExchangePointer(&_hWait, NULL);
  741. if (hWait != NULL)
  742. {
  743. if (UnregisterWait(hWait) != FALSE)
  744. {
  745. // If sucesssfully releasing the hWait we need to call release.
  746. Release();
  747. }
  748. }
  749. TBOOL(PostMessage(hwnd, WM_UISERVICEREQUEST, wParam, lParam));
  750. }
  751. else if (!_fRegisteredWait)
  752. {
  753. // Cannot find the UI host window. It's probably still getting
  754. // its act together. Queue this post message for a callback when
  755. // the event is signaled if a register has not already been
  756. // made. If one has then just change the parameters.
  757. // Add a reference here. The callback will release it. If the
  758. // register on the wait failed the release the reference.
  759. if (_hWait == NULL)
  760. {
  761. HANDLE hWait;
  762. AddRef();
  763. if (RegisterWaitForSingleObject(&hWait,
  764. _hEvent,
  765. CB_UIHostReadySignal,
  766. this,
  767. INFINITE,
  768. WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE) != FALSE)
  769. {
  770. if (InterlockedCompareExchangePointer(&_hWait, hWait, NULL) == NULL)
  771. {
  772. _fRegisteredWait = true;
  773. }
  774. else
  775. {
  776. // Someone else beat us to registering (should never happen)
  777. (BOOL)UnregisterWait(hWait);
  778. Release();
  779. }
  780. }
  781. else
  782. {
  783. Release();
  784. }
  785. }
  786. _waitWPARAM = wParam;
  787. _waitLPARAM = lParam;
  788. }
  789. }
  790. // --------------------------------------------------------------------------
  791. // CLogonStatus::UIHostReadySignal
  792. //
  793. // Arguments: <none>
  794. //
  795. // Returns: <none>
  796. //
  797. // Purpose: Callback invoked when the UI host signals it's ready. This
  798. // function unregisters the wait and resend the status message
  799. // to the UI host.
  800. //
  801. // History: 2000-09-10 vtan created
  802. // --------------------------------------------------------------------------
  803. void CLogonStatus::UIHostReadySignal (void)
  804. {
  805. HANDLE hWait;
  806. hWait = InterlockedExchangePointer(&_hWait, NULL);
  807. if (hWait != NULL)
  808. {
  809. TBOOL(UnregisterWait(hWait));
  810. }
  811. SendToUIHost(_waitWPARAM, _waitLPARAM);
  812. }
  813. // --------------------------------------------------------------------------
  814. // CLogonStatus::CB_UIHostReadySignal
  815. //
  816. // Arguments: See the platform SDK under WaitOrTimerCallback.
  817. //
  818. // Returns: <none>
  819. //
  820. // Purpose: Callback entry point for registered event wait.
  821. //
  822. // History: 2000-09-10 vtan created
  823. // --------------------------------------------------------------------------
  824. void CALLBACK CLogonStatus::CB_UIHostReadySignal (void *pV, BOOLEAN fTimerOrWaitFired)
  825. {
  826. UNREFERENCED_PARAMETER(fTimerOrWaitFired);
  827. CLogonStatus *pThis;
  828. pThis = reinterpret_cast<CLogonStatus*>(pV);
  829. if (pThis != NULL)
  830. {
  831. pThis->UIHostReadySignal();
  832. }
  833. pThis->Release();
  834. }
  835. // --------------------------------------------------------------------------
  836. // CLogonStatus::CB_UIHostAbnormalTermination
  837. //
  838. // Arguments: See the platform SDK under APCProc.
  839. //
  840. // Returns: <none>
  841. //
  842. // Purpose: Callback entry point for queued APC on abnormal termination.
  843. //
  844. // History: 2001-02-19 vtan created
  845. // --------------------------------------------------------------------------
  846. void CALLBACK CLogonStatus::CB_UIHostAbnormalTermination (ULONG_PTR dwParam)
  847. {
  848. UNREFERENCED_PARAMETER(dwParam);
  849. }
  850. // --------------------------------------------------------------------------
  851. // ::_Shell_LogonStatus_StaticInitialize
  852. //
  853. // Arguments: <none>
  854. //
  855. // Returns: NTSTATUS
  856. //
  857. // Purpose: Initialize the critical section for g_pLogonStatus.
  858. //
  859. // History: 2001-06-11 vtan created
  860. // --------------------------------------------------------------------------
  861. EXTERN_C NTSTATUS _Shell_LogonStatus_StaticInitialize (void)
  862. {
  863. NTSTATUS status;
  864. ASSERTMSG(g_pLogonStatusLock == NULL, "g_pLogonStatusLock already exists in _Shell_LogonStatus_StaticInitialize");
  865. g_pLogonStatusLock = new CCriticalSection;
  866. if (g_pLogonStatusLock != NULL)
  867. {
  868. status = g_pLogonStatusLock->Status();
  869. if (!NT_SUCCESS(status))
  870. {
  871. delete g_pLogonStatusLock;
  872. g_pLogonStatusLock = NULL;
  873. }
  874. }
  875. else
  876. {
  877. status = STATUS_NO_MEMORY;
  878. }
  879. return(status);
  880. }
  881. // --------------------------------------------------------------------------
  882. // ::_Shell_LogonStatus_StaticTerminate
  883. //
  884. // Arguments: <none>
  885. //
  886. // Returns: NTSTATUS
  887. //
  888. // Purpose: Delete the critical section for g_pLogonStatus.
  889. //
  890. // History: 2001-06-11 vtan created
  891. // --------------------------------------------------------------------------
  892. EXTERN_C NTSTATUS _Shell_LogonStatus_StaticTerminate (void)
  893. {
  894. if (g_pLogonStatusLock != NULL)
  895. {
  896. delete g_pLogonStatusLock;
  897. g_pLogonStatusLock = NULL;
  898. }
  899. return(STATUS_SUCCESS);
  900. }
  901. // --------------------------------------------------------------------------
  902. // ::_Shell_LogonStatus_Init
  903. //
  904. // Arguments: uiStartType = Start mode of status host.
  905. //
  906. // Returns: <none>
  907. //
  908. // Purpose: Creates the instance of CLogonStatus telling it to pass
  909. // "/status" as the parameter to the UI host. It then starts
  910. // the host if the object was created.
  911. //
  912. // The object is held globally.
  913. //
  914. // History: 2000-05-11 vtan created
  915. // 2000-07-13 vtan add shutdown parameter.
  916. // 2000-07-17 vtan changed to start type parameter.
  917. // --------------------------------------------------------------------------
  918. EXTERN_C void _Shell_LogonStatus_Init (UINT uiStartType)
  919. {
  920. bool fIsRemote, fIsSessionZero;
  921. fIsRemote = (GetSystemMetrics(SM_REMOTESESSION) != 0);
  922. fIsSessionZero = (NtCurrentPeb()->SessionId == 0);
  923. if ((!fIsRemote || fIsSessionZero || CSystemSettings::IsForceFriendlyUI()) && CSystemSettings::IsFriendlyUIActive())
  924. {
  925. bool fWait;
  926. TCHAR szParameter[256];
  927. if (g_pLogonStatusLock != NULL)
  928. {
  929. g_pLogonStatusLock->Acquire();
  930. if (g_pLogonStatus == NULL)
  931. {
  932. (TCHAR*)lstrcpy(szParameter, TEXT(" /status"));
  933. if (HOST_START_SHUTDOWN == uiStartType)
  934. {
  935. (TCHAR*)lstrcat(szParameter, TEXT(" /shutdown"));
  936. fWait = true;
  937. }
  938. else if (HOST_START_WAIT == uiStartType)
  939. {
  940. (TCHAR*)lstrcat(szParameter, TEXT(" /wait"));
  941. fWait = true;
  942. }
  943. else
  944. {
  945. fWait = false;
  946. }
  947. g_pLogonStatus = new CLogonStatus(szParameter);
  948. if (g_pLogonStatus != NULL)
  949. {
  950. NTSTATUS status;
  951. g_pLogonStatusLock->Release();
  952. status = g_pLogonStatus->Start(fWait);
  953. g_pLogonStatusLock->Acquire();
  954. if (!NT_SUCCESS(status) && (g_pLogonStatus != NULL))
  955. {
  956. g_pLogonStatus->Release();
  957. g_pLogonStatus = NULL;
  958. }
  959. }
  960. }
  961. else
  962. {
  963. g_pLogonStatus->SetStateStatus(0);
  964. if ((HOST_START_SHUTDOWN == uiStartType) || (HOST_START_WAIT == uiStartType))
  965. {
  966. g_pLogonStatus->NotifyWait();
  967. }
  968. }
  969. g_pLogonStatusLock->Release();
  970. }
  971. }
  972. }
  973. // --------------------------------------------------------------------------
  974. // ::_Shell_LogonStatus_Destroy
  975. //
  976. // Arguments: uiEndType = End mode of status host.
  977. //
  978. // Returns: <none>
  979. //
  980. // Purpose: If the end type is hide then tell the status host to hide.
  981. // Otherwise check the end type is terminate. In that case tell
  982. // the status host to go away.
  983. //
  984. // History: 2000-05-11 vtan created
  985. // 2001-01-09 vtan add end parameter
  986. // --------------------------------------------------------------------------
  987. EXTERN_C void _Shell_LogonStatus_Destroy (UINT uiEndType)
  988. {
  989. if (g_pLogonStatusLock != NULL)
  990. {
  991. CSingleThreadedExecution lock(*g_pLogonStatusLock);
  992. if (g_pLogonStatus != NULL)
  993. {
  994. switch (uiEndType)
  995. {
  996. case HOST_END_HIDE:
  997. // HOST_END_HIDE: Is the UI host static? If so then hide it.
  998. // Otherwise revert to start/stop mode (dynamic) and force the
  999. // UI host to terminate.
  1000. if (CSystemSettings::IsUIHostStatic())
  1001. {
  1002. g_pLogonStatus->SetStateHide();
  1003. break;
  1004. }
  1005. uiEndType = HOST_END_TERMINATE;
  1006. // If the the host is dynamic then set the type to
  1007. // HOST_END_TERMINATE and fall thru to this case so that
  1008. // the host is told to end.
  1009. case HOST_END_TERMINATE:
  1010. // HOST_END_TERMINATE: Force the UI host to terminate. This is
  1011. // used in circumstances where it must terminate such as we
  1012. // are terminating or the machine is shutting down.
  1013. g_pLogonStatus->SetStateEnd(true);
  1014. break;
  1015. case HOST_END_FAILURE:
  1016. // HOST_END_FAILURE: This is sent when the UI host failed to
  1017. // start and will not be restarted. This allows the interface
  1018. // reference to be deleted so that object reference count
  1019. // will reach zero and the memory will be released.
  1020. g_pLogonStatus->SetStateEnd(false);
  1021. uiEndType = HOST_END_TERMINATE;
  1022. break;
  1023. default:
  1024. DISPLAYMSG("Unknown uiEndType passed to _Shell_LogonStatus_Destroy");
  1025. break;
  1026. }
  1027. if (HOST_END_TERMINATE == uiEndType)
  1028. {
  1029. g_pLogonStatus->Release();
  1030. g_pLogonStatus = NULL;
  1031. }
  1032. }
  1033. }
  1034. }
  1035. // --------------------------------------------------------------------------
  1036. // ::_Shell_LogonStatus_Exists
  1037. //
  1038. // Arguments: <none>
  1039. //
  1040. // Returns: BOOL
  1041. //
  1042. // Purpose: Returns whether there is status host created.
  1043. //
  1044. // History: 2000-05-11 vtan created
  1045. // --------------------------------------------------------------------------
  1046. EXTERN_C BOOL _Shell_LogonStatus_Exists (void)
  1047. {
  1048. return(g_pLogonStatus != NULL);
  1049. }
  1050. // --------------------------------------------------------------------------
  1051. // ::_Shell_LogonStatus_IsStatusWindow
  1052. //
  1053. // Arguments: hwnd = HWND to check.
  1054. //
  1055. // Returns: BOOL
  1056. //
  1057. // Purpose: Returns whether the given HWND is the status HWND.
  1058. //
  1059. // History: 2000-06-26 vtan created
  1060. // --------------------------------------------------------------------------
  1061. EXTERN_C BOOL _Shell_LogonStatus_IsStatusWindow (HWND hwnd)
  1062. {
  1063. return(CLogonStatus::IsStatusWindow(hwnd));
  1064. }
  1065. // --------------------------------------------------------------------------
  1066. // ::_Shell_LogonStatus_IsSuspendAllowed
  1067. //
  1068. // Arguments: <none>
  1069. //
  1070. // Returns: BOOL
  1071. //
  1072. // Purpose: Ask the status host (if present) if suspend is allowed.
  1073. //
  1074. // History: 2000-08-18 vtan created
  1075. // --------------------------------------------------------------------------
  1076. EXTERN_C BOOL _Shell_LogonStatus_IsSuspendAllowed (void)
  1077. {
  1078. return((g_pLogonStatus == NULL) || g_pLogonStatus->IsSuspendAllowed());
  1079. }
  1080. // --------------------------------------------------------------------------
  1081. // ::_Shell_LogonStatus_WaitforUIHost
  1082. //
  1083. // Arguments: <none>
  1084. //
  1085. // Returns: BOOL
  1086. //
  1087. // Purpose: External C entry point to force the current thread to wait
  1088. // until the UI host signals it's ready. Returns whether the
  1089. // wait was successful or abandoned. Success is true. Abandoned
  1090. // or non-existant is false.
  1091. //
  1092. // History: 2000-09-10 vtan created
  1093. // 2001-02-19 vtan added return result
  1094. // --------------------------------------------------------------------------
  1095. EXTERN_C BOOL _Shell_LogonStatus_WaitForUIHost (void)
  1096. {
  1097. return((g_pLogonStatus != NULL) && g_pLogonStatus->WaitForUIHost());
  1098. }
  1099. // --------------------------------------------------------------------------
  1100. // ::_Shell_LogonStatus_ShowStatusMessage
  1101. //
  1102. // Arguments: pszMessage = Unicode string to display.
  1103. //
  1104. // Returns: <none>
  1105. //
  1106. // Purpose: External C entry point to pass display string to status host.
  1107. //
  1108. // History: 2000-05-11 vtan created
  1109. // --------------------------------------------------------------------------
  1110. EXTERN_C void _Shell_LogonStatus_ShowStatusMessage (const WCHAR *pszMessage)
  1111. {
  1112. if (g_pLogonStatus != NULL)
  1113. {
  1114. g_pLogonStatus->ShowStatusMessage(pszMessage);
  1115. }
  1116. }
  1117. // --------------------------------------------------------------------------
  1118. // ::_Shell_LogonStatus_SetStateStatus
  1119. //
  1120. // Arguments: <none>
  1121. //
  1122. // Returns: <none>
  1123. //
  1124. // Purpose: External C entry point to tell the status host to go to status
  1125. // state.
  1126. //
  1127. // History: 2000-05-11 vtan created
  1128. // --------------------------------------------------------------------------
  1129. EXTERN_C void _Shell_LogonStatus_SetStateStatus (int iCode)
  1130. {
  1131. if (g_pLogonStatus != NULL)
  1132. {
  1133. g_pLogonStatus->SetStateStatus(iCode);
  1134. }
  1135. }
  1136. // --------------------------------------------------------------------------
  1137. // ::_Shell_LogonStatus_SetStateLogon
  1138. //
  1139. // Arguments: <none>
  1140. //
  1141. // Returns: <none>
  1142. //
  1143. // Purpose: External C entry point to tell the status host to go to logon
  1144. // state.
  1145. //
  1146. // History: 2000-05-11 vtan created
  1147. // --------------------------------------------------------------------------
  1148. EXTERN_C void _Shell_LogonStatus_SetStateLogon (int iCode)
  1149. {
  1150. if (g_pLogonStatus != NULL)
  1151. {
  1152. g_pLogonStatus->SetStateLogon(iCode);
  1153. }
  1154. }
  1155. // --------------------------------------------------------------------------
  1156. // ::_Shell_LogonStatus_SetStateLoggedOn
  1157. //
  1158. // Arguments: <none>
  1159. //
  1160. // Returns: <none>
  1161. //
  1162. // Purpose: External C entry point to tell the status host to go to
  1163. // logged on state.
  1164. //
  1165. // History: 2000-05-24 vtan created
  1166. // --------------------------------------------------------------------------
  1167. EXTERN_C void _Shell_LogonStatus_SetStateLoggedOn (void)
  1168. {
  1169. if (g_pLogonStatus != NULL)
  1170. {
  1171. g_pLogonStatus->SetStateLoggedOn();
  1172. }
  1173. }
  1174. // --------------------------------------------------------------------------
  1175. // ::_Shell_LogonStatus_SetStateHide
  1176. //
  1177. // Arguments: <none>
  1178. //
  1179. // Returns: <none>
  1180. //
  1181. // Purpose: External C entry point to tell the status host to hide itself.
  1182. //
  1183. // History: 2001-01-08 vtan created
  1184. // --------------------------------------------------------------------------
  1185. EXTERN_C void _Shell_LogonStatus_SetStateHide (void)
  1186. {
  1187. if (g_pLogonStatus != NULL)
  1188. {
  1189. g_pLogonStatus->SetStateHide();
  1190. }
  1191. }
  1192. // --------------------------------------------------------------------------
  1193. // ::_Shell_LogonStatus_SetStateEnd
  1194. //
  1195. // Arguments: <none>
  1196. //
  1197. // Returns: <none>
  1198. //
  1199. // Purpose: External C entry point to tell the status host to terminate.
  1200. //
  1201. // History: 2000-05-11 vtan created
  1202. // --------------------------------------------------------------------------
  1203. EXTERN_C void _Shell_LogonStatus_SetStateEnd (void)
  1204. {
  1205. if (g_pLogonStatus != NULL)
  1206. {
  1207. g_pLogonStatus->SetStateEnd(true);
  1208. }
  1209. }
  1210. // --------------------------------------------------------------------------
  1211. // ::_Shell_LogonStatus_NotifyWait
  1212. //
  1213. // Arguments: <none>
  1214. //
  1215. // Returns: <none>
  1216. //
  1217. // Purpose: External C entry point to tell the status host to display a
  1218. // title stating the system is preparing to shut down.
  1219. //
  1220. // History: 2000-07-14 vtan created
  1221. // --------------------------------------------------------------------------
  1222. EXTERN_C void _Shell_LogonStatus_NotifyWait (void)
  1223. {
  1224. if (g_pLogonStatus != NULL)
  1225. {
  1226. g_pLogonStatus->NotifyWait();
  1227. }
  1228. }
  1229. // --------------------------------------------------------------------------
  1230. // ::_Shell_LogonStatus_NotifyNoAnimations
  1231. //
  1232. // Arguments: <none>
  1233. //
  1234. // Returns: <none>
  1235. //
  1236. // Purpose: External C entry point to tell the status host to no longer
  1237. // perform animations.
  1238. //
  1239. // History: 2001-03-21 vtan created
  1240. // --------------------------------------------------------------------------
  1241. EXTERN_C void _Shell_LogonStatus_NotifyNoAnimations (void)
  1242. {
  1243. if (g_pLogonStatus != NULL)
  1244. {
  1245. g_pLogonStatus->NotifyNoAnimations();
  1246. }
  1247. }
  1248. // --------------------------------------------------------------------------
  1249. // ::_Shell_LogonStatus_SelectUser
  1250. //
  1251. // Arguments: pszUsername = Username to select.
  1252. //
  1253. // Returns: <none>
  1254. //
  1255. // Purpose: External C entry point to tell the status host to select a
  1256. // specific user as being logged on.
  1257. //
  1258. // History: 2001-01-10 vtan created
  1259. // --------------------------------------------------------------------------
  1260. EXTERN_C void _Shell_LogonStatus_SelectUser (const WCHAR *pszUsername, const WCHAR *pszDomain)
  1261. {
  1262. if (g_pLogonStatus != NULL)
  1263. {
  1264. g_pLogonStatus->SelectUser(pszUsername, pszDomain);
  1265. }
  1266. }
  1267. // --------------------------------------------------------------------------
  1268. // ::_Shell_LogonStatus_InteractiveLogon
  1269. //
  1270. // Arguments: pszUsername = Username to logon.
  1271. // pszDomain = Domain to logon.
  1272. // pszPassword = Password to use.
  1273. //
  1274. // Returns: <none>
  1275. //
  1276. // Purpose: External C entry point to tell the status host to log the
  1277. // specified user on.
  1278. //
  1279. // History: 2001-01-12 vtan created
  1280. // --------------------------------------------------------------------------
  1281. EXTERN_C void _Shell_LogonStatus_InteractiveLogon (const WCHAR *pszUsername, const WCHAR *pszDomain, WCHAR *pszPassword)
  1282. {
  1283. if (g_pLogonStatus != NULL)
  1284. {
  1285. g_pLogonStatus->InteractiveLogon(pszUsername, pszDomain, pszPassword);
  1286. }
  1287. }
  1288. // --------------------------------------------------------------------------
  1289. // ::_Shell_LogonStatus_GetUIHost
  1290. //
  1291. // Arguments: <none>
  1292. //
  1293. // Returns: void*
  1294. //
  1295. // Purpose: External C entry point that returns a reference to the UI
  1296. // host object. This is returned as a void* because C doesn't
  1297. // understand C++ objects. The void* is cast to the appropriate
  1298. // type for use in CWLogonDialog.cpp so that it doesn't go and
  1299. // create a new instance of the object but increments the
  1300. // reference to this already existing object.
  1301. //
  1302. // History: 2000-05-11 vtan created
  1303. // --------------------------------------------------------------------------
  1304. EXTERN_C void* _Shell_LogonStatus_GetUIHost (void)
  1305. {
  1306. void *pResult;
  1307. if (g_pLogonStatus != NULL)
  1308. {
  1309. pResult = g_pLogonStatus->GetUIHost();
  1310. }
  1311. else
  1312. {
  1313. pResult = NULL;
  1314. }
  1315. return(pResult);
  1316. }
  1317. // --------------------------------------------------------------------------
  1318. // ::_Shell_LogonStatus_ResetReadyEvent
  1319. //
  1320. // Arguments: <none>
  1321. //
  1322. // Returns: HANDLE
  1323. //
  1324. // Purpose: Resets the ready event in case of UI host failure.
  1325. //
  1326. // History: 2001-01-09 vtan created
  1327. // --------------------------------------------------------------------------
  1328. EXTERN_C HANDLE _Shell_LogonStatus_ResetReadyEvent (void)
  1329. {
  1330. HANDLE hEvent;
  1331. if (g_pLogonStatus != NULL)
  1332. {
  1333. hEvent = g_pLogonStatus->ResetReadyEvent();
  1334. }
  1335. else
  1336. {
  1337. hEvent = NULL;
  1338. }
  1339. return(hEvent);
  1340. }
  1341. // --------------------------------------------------------------------------
  1342. // ::_Shell_LogonStatus_Show
  1343. //
  1344. // Arguments: <none>
  1345. //
  1346. // Returns: <none>
  1347. //
  1348. // Purpose: Shows the UI host.
  1349. //
  1350. // History: 2001-03-05 vtan created
  1351. // --------------------------------------------------------------------------
  1352. EXTERN_C void _Shell_LogonStatus_Show (void)
  1353. {
  1354. if (g_pLogonStatus != NULL)
  1355. {
  1356. g_pLogonStatus->ShowUIHost();
  1357. }
  1358. }
  1359. // --------------------------------------------------------------------------
  1360. // ::_Shell_LogonStatus_Hide
  1361. //
  1362. // Arguments: <none>
  1363. //
  1364. // Returns: <none>
  1365. //
  1366. // Purpose: Hides the UI host.
  1367. //
  1368. // History: 2001-03-05 vtan created
  1369. // --------------------------------------------------------------------------
  1370. EXTERN_C void _Shell_LogonStatus_Hide (void)
  1371. {
  1372. if (g_pLogonStatus != NULL)
  1373. {
  1374. g_pLogonStatus->HideUIHost();
  1375. }
  1376. }
  1377. // --------------------------------------------------------------------------
  1378. // ::_Shell_LogonStatus_IsHidden
  1379. //
  1380. // Arguments: <none>
  1381. //
  1382. // Returns: <none>
  1383. //
  1384. // Purpose: Returns whether the UI host is hidden.
  1385. //
  1386. // History: 2001-03-05 vtan created
  1387. // --------------------------------------------------------------------------
  1388. EXTERN_C BOOL _Shell_LogonStatus_IsHidden (void)
  1389. {
  1390. return((g_pLogonStatus != NULL) && g_pLogonStatus->IsUIHostHidden());
  1391. }