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.

1109 lines
29 KiB

  1. //*************************************************************
  2. //
  3. // Events.c - Routines to handle the event log
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1995
  7. // All rights reserved
  8. //
  9. //*************************************************************
  10. #include "uenv.h"
  11. #include "profmgr.hxx"
  12. //
  13. // XPSP1 specific
  14. //
  15. #include "xpsp1res.h"
  16. extern CUserProfile cUserProfileManager;
  17. HANDLE hEventLog = NULL;
  18. TCHAR EventSourceName[] = TEXT("Userenv");
  19. INT_PTR APIENTRY ErrorDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  20. BOOL GetShareName(LPTSTR lpDir, LPTSTR *lppShare);
  21. //*************************************************************
  22. //
  23. // InitializeEvents()
  24. //
  25. // Purpose: Opens the event log
  26. //
  27. // Parameters: void
  28. //
  29. // Return: TRUE if successful
  30. // FALSE if an error occurs
  31. //
  32. // Comments:
  33. //
  34. // History: Date Author Comment
  35. // 7/17/95 ericflo Created
  36. //
  37. //*************************************************************
  38. BOOL InitializeEvents (void)
  39. {
  40. //
  41. // Open the event source
  42. //
  43. hEventLog = RegisterEventSource(NULL, EventSourceName);
  44. if (hEventLog) {
  45. return TRUE;
  46. }
  47. DebugMsg((DM_WARNING, TEXT("InitializeEvents: Could not open event log. Error = %d"), GetLastError()));
  48. return FALSE;
  49. }
  50. //*************************************************************
  51. //
  52. // Implementation of CEvents
  53. //
  54. //*************************************************************
  55. //*************************************************************
  56. // CEvents::CEvents
  57. // Purpose: Constructor
  58. //
  59. // Parameters:
  60. // dwFlags - Error, Warning or informational
  61. // dwId - Id of the eventlog msg
  62. //
  63. //
  64. // allocates a default sized array for the messages
  65. //*************************************************************
  66. #define DEF_ARG_SIZE 10
  67. CEvents::CEvents(DWORD dwFlags, DWORD dwId ) :
  68. m_cStrings(0), m_cAllocated(0), m_bInitialised(FALSE),
  69. m_dwEventType(dwFlags), m_dwId(dwId), m_bFailed(TRUE)
  70. {
  71. XLastError xe;
  72. //
  73. // Allocate a default size for the message
  74. //
  75. m_xlpStrings = (LPTSTR *)LocalAlloc(LPTR, sizeof(LPTSTR)*DEF_ARG_SIZE);
  76. m_cAllocated = DEF_ARG_SIZE;
  77. if (!m_xlpStrings) {
  78. DebugMsg((DM_WARNING, TEXT("CEvent::CEvent Cannot log event, failed to allocate memory, error %d"), GetLastError()));
  79. return;
  80. }
  81. //
  82. // Initialise eventlog if it is not already initialised
  83. //
  84. if (!hEventLog) {
  85. if (!InitializeEvents()) {
  86. DebugMsg((DM_WARNING, TEXT("CEvent::CEvent Cannot log event, no handle")));
  87. return;
  88. }
  89. }
  90. m_bInitialised = TRUE;
  91. m_bFailed = FALSE;
  92. }
  93. //*************************************************************
  94. // CEvents::~CEvents()
  95. //
  96. // Purpose: Destructor
  97. //
  98. // Parameters: void
  99. //
  100. // frees the memory
  101. //*************************************************************
  102. CEvents::~CEvents()
  103. {
  104. XLastError xe;
  105. for (int i = 0; i < m_cStrings; i++)
  106. if (m_xlpStrings[i])
  107. LocalFree(m_xlpStrings[i]);
  108. }
  109. //*************************************************************
  110. //
  111. // CEvents::ReallocArgStrings
  112. //
  113. // Purpose: Reallocates the buffer for storing arguments in case
  114. // the buffer runs out
  115. //
  116. // Parameters: void
  117. //
  118. // reallocates
  119. //*************************************************************
  120. BOOL CEvents::ReallocArgStrings()
  121. {
  122. XPtrLF<LPTSTR> aStringsNew;
  123. XLastError xe;
  124. //
  125. // first allocate a larger buffer
  126. //
  127. aStringsNew = (LPTSTR *)LocalAlloc(LPTR, sizeof(LPTSTR)*(m_cAllocated+DEF_ARG_SIZE));
  128. if (!aStringsNew) {
  129. DebugMsg((DM_WARNING, TEXT("CEvent::ReallocArgStrings Cannot add memory, error = %d"), GetLastError()));
  130. m_bFailed = TRUE;
  131. return FALSE;
  132. }
  133. //
  134. // copy the arguments
  135. //
  136. for (int i = 0; i < (m_cAllocated); i++) {
  137. aStringsNew[i] = m_xlpStrings[i];
  138. }
  139. m_xlpStrings = aStringsNew.Acquire();
  140. m_cAllocated+= DEF_ARG_SIZE;
  141. return TRUE;
  142. }
  143. //*************************************************************
  144. //
  145. // CEvents::AddArg
  146. //
  147. // Purpose: Add arguments appropriately formatted
  148. //
  149. // Parameters:
  150. //
  151. //*************************************************************
  152. BOOL CEvents::AddArg(LPTSTR szArg)
  153. {
  154. XLastError xe;
  155. if ((!m_bInitialised) || (m_bFailed)) {
  156. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg: Cannot log event, not initialised or failed before")));
  157. return FALSE;
  158. }
  159. if (m_cStrings == m_cAllocated) {
  160. if (!ReallocArgStrings())
  161. return FALSE;
  162. }
  163. m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(szArg)+1));
  164. if (!m_xlpStrings[m_cStrings]) {
  165. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
  166. m_bFailed = TRUE;
  167. return FALSE;
  168. }
  169. lstrcpy(m_xlpStrings[m_cStrings], szArg);
  170. m_cStrings++;
  171. return TRUE;
  172. }
  173. //*************************************************************
  174. //
  175. // CEvents::AddArg
  176. //
  177. // Purpose: Add arguments appropriately truncated
  178. //
  179. // Parameters: szArgFormat - sprintf format, e.g. %.500s
  180. //
  181. //*************************************************************
  182. BOOL CEvents::AddArg(LPTSTR szArgFormat, LPTSTR szArg)
  183. {
  184. if ((!m_bInitialised) || (m_bFailed)) {
  185. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg: Cannot log event, not initialised or failed before")));
  186. return FALSE;
  187. }
  188. if (m_cStrings == m_cAllocated) {
  189. if (!ReallocArgStrings())
  190. return FALSE;
  191. }
  192. m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(szArg)+1));
  193. if (!m_xlpStrings[m_cStrings]) {
  194. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
  195. m_bFailed = TRUE;
  196. return FALSE;
  197. }
  198. wsprintf(m_xlpStrings[m_cStrings], szArgFormat, szArg);
  199. m_cStrings++;
  200. return TRUE;
  201. }
  202. //*************************************************************
  203. //
  204. // CEvents::AddArg
  205. //
  206. // Purpose: Add arguments appropriately formatted
  207. //
  208. // Parameters:
  209. //
  210. //*************************************************************
  211. BOOL CEvents::AddArg(DWORD dwArg)
  212. {
  213. XLastError xe;
  214. if ((!m_bInitialised) || (m_bFailed)) {
  215. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg(dw): Cannot log event, not initialised or failed before")));
  216. return FALSE;
  217. }
  218. if (m_cStrings == m_cAllocated) {
  219. if (!ReallocArgStrings())
  220. return FALSE;
  221. }
  222. // 2^32 < 10^10
  223. m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*20);
  224. if (!m_xlpStrings[m_cStrings]) {
  225. DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
  226. m_bFailed = TRUE;
  227. return FALSE;
  228. }
  229. wsprintf(m_xlpStrings[m_cStrings], TEXT("%d"), dwArg);
  230. m_cStrings++;
  231. return TRUE;
  232. }
  233. //*************************************************************
  234. //
  235. // CEvents::AddArgHex
  236. //
  237. // Purpose: Add arguments appropriately formatted
  238. //
  239. // Parameters:
  240. //
  241. //*************************************************************
  242. BOOL CEvents::AddArgHex(DWORD dwArg)
  243. {
  244. XLastError xe;
  245. if ((!m_bInitialised) || (m_bFailed)) {
  246. DebugMsg((DM_WARNING, TEXT("CEvent::AddArgHex: Cannot log event, not initialised or failed before")));
  247. return FALSE;
  248. }
  249. if (m_cStrings == m_cAllocated) {
  250. if (!ReallocArgStrings())
  251. return FALSE;
  252. }
  253. m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*20);
  254. if (!m_xlpStrings[m_cStrings]) {
  255. DebugMsg((DM_WARNING, TEXT("CEvent::AddArgHex Cannot allocate memory, error = %d"), GetLastError()));
  256. m_bFailed = TRUE;
  257. return FALSE;
  258. }
  259. wsprintf(m_xlpStrings[m_cStrings], TEXT("%#x"), dwArg);
  260. m_cStrings++;
  261. return TRUE;
  262. }
  263. //*************************************************************
  264. //
  265. // CEvents::AddArgWin32Error
  266. //
  267. // Purpose: Add arguments appropriately formatted
  268. //
  269. // Parameters:
  270. //
  271. //*************************************************************
  272. BOOL CEvents::AddArgWin32Error(DWORD dwArg)
  273. {
  274. XLastError xe;
  275. if ((!m_bInitialised) || (m_bFailed))
  276. {
  277. DebugMsg((DM_WARNING, TEXT("CEvent::AddArgWin32Error: Cannot log event, not initialised or failed before")));
  278. return FALSE;
  279. }
  280. if (m_cStrings == m_cAllocated)
  281. {
  282. if (!ReallocArgStrings())
  283. return FALSE;
  284. }
  285. if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  286. 0,
  287. dwArg,
  288. 0,
  289. (LPTSTR) &m_xlpStrings[m_cStrings],
  290. 1,
  291. 0 ) == 0 )
  292. {
  293. DebugMsg((DM_WARNING, TEXT("CEvent::AddArgWin32Error: Cannot log event, FormatMessage failed, %d"), GetLastError()));
  294. m_bFailed = TRUE;
  295. return FALSE;
  296. }
  297. m_cStrings++;
  298. return TRUE;
  299. }
  300. //*************************************************************
  301. //
  302. // CEvents::AddArgLdapError
  303. //
  304. // Purpose: Add arguments appropriately formatted
  305. //
  306. // Parameters:
  307. //
  308. //*************************************************************
  309. BOOL CEvents::AddArgLdapError(DWORD dwArg)
  310. {
  311. XLastError xe;
  312. PLDAP_API pLdap = LoadLDAP();
  313. if ( pLdap )
  314. {
  315. return AddArg( pLdap->pfnldap_err2string( dwArg ) );
  316. }
  317. else
  318. {
  319. return FALSE;
  320. }
  321. }
  322. //*************************************************************
  323. //
  324. // CEvents::Report
  325. //
  326. // Purpose: Actually collectes all the arguments and reports it to
  327. // the eventlog
  328. //
  329. // Parameters: void
  330. //
  331. //*************************************************************
  332. BOOL CEvents::Report()
  333. {
  334. XLastError xe;
  335. XHandle xhToken;
  336. PSID pSid = NULL;
  337. WORD wType=0;
  338. BOOL bResult = TRUE;
  339. if ((!m_bInitialised) || (m_bFailed))
  340. {
  341. DebugMsg((DM_WARNING, TEXT("CEvents::Report: Cannot log event, not initialised or failed before")));
  342. return FALSE;
  343. }
  344. //
  345. // Get the caller's token
  346. //
  347. if (!OpenThreadToken (GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_READ | TOKEN_DUPLICATE,
  348. TRUE, &xhToken))
  349. {
  350. OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_READ | TOKEN_DUPLICATE,
  351. &xhToken);
  352. }
  353. //
  354. // Get the caller's sid
  355. //
  356. if (xhToken)
  357. {
  358. pSid = GetUserSid(xhToken);
  359. if (!pSid)
  360. {
  361. DebugMsg((DM_WARNING, TEXT("CEvents::Report: Failed to get the sid")));
  362. }
  363. }
  364. if (m_dwEventType & EVENT_INFO_TYPE)
  365. {
  366. wType = EVENTLOG_INFORMATION_TYPE;
  367. }
  368. else if (m_dwEventType & EVENT_WARNING_TYPE)
  369. {
  370. wType = EVENTLOG_WARNING_TYPE;
  371. }
  372. else
  373. {
  374. wType = EVENTLOG_ERROR_TYPE;
  375. }
  376. if ( !ReportEvent( hEventLog,
  377. wType,
  378. 0,
  379. m_dwId,
  380. pSid,
  381. m_cStrings,
  382. 0,
  383. (LPCTSTR *)((LPTSTR *)m_xlpStrings),
  384. 0 ) )
  385. {
  386. DebugMsg((DM_WARNING, TEXT("CEvents::Report: ReportEvent failed. Error = %d"), GetLastError()));
  387. bResult = FALSE;
  388. }
  389. if (pSid)
  390. {
  391. DeleteUserSid(pSid);
  392. }
  393. return bResult;
  394. }
  395. LPTSTR CEvents::FormatString()
  396. {
  397. LPTSTR szMsg=NULL;
  398. HINSTANCE hResSource = g_hDllInstance;
  399. if ((!m_bInitialised) || (m_bFailed)) {
  400. DebugMsg((DM_WARNING, TEXT("CEvents::Report: Cannot log event, not initialised or failed before")));
  401. goto Exit;
  402. }
  403. //
  404. // XPSP1 specific: New message in XPSP1, load it from xpsp1res.dll
  405. //
  406. if (m_dwId == EVENT_LOGON_RUP_NOT_SECURE)
  407. {
  408. hResSource = LoadLibraryEx(TEXT("xpsp1res.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE);
  409. if (!hResSource)
  410. {
  411. DebugMsg((DM_WARNING, TEXT("CEvents::FormatString: LoadLibraryEx failed with %d"), GetLastError()));
  412. goto Exit;
  413. }
  414. }
  415. if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  416. FORMAT_MESSAGE_FROM_HMODULE |
  417. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  418. hResSource,
  419. m_dwId,
  420. 0,
  421. (LPTSTR)&szMsg,
  422. 0, // min number of chars
  423. (va_list *)(LPTSTR *)(m_xlpStrings))) {
  424. DebugMsg((DM_WARNING, TEXT("CEvents::FormatString: FormatMessage failed. Error = %d"), GetLastError()));
  425. goto Exit;
  426. }
  427. Exit:
  428. if (hResSource && hResSource != g_hDllInstance)
  429. {
  430. if (!FreeLibrary(hResSource))
  431. {
  432. DebugMsg((DM_WARNING, TEXT("CEvents::FormatString: FreeLibrary failed with %d"), GetLastError()));
  433. }
  434. }
  435. return szMsg;
  436. }
  437. //*************************************************************
  438. //
  439. // LogEvent()
  440. //
  441. // Purpose: Logs an event to the event log
  442. //
  443. // Parameters: dwFlags - Error, Warning or informational
  444. // idMsg - Message id
  445. //
  446. // Return: TRUE if successful
  447. // FALSE if an error occurs
  448. //
  449. // Comments:
  450. //
  451. // History: Date Author Comment
  452. // 2/5/98 ericflo Created
  453. //
  454. //*************************************************************
  455. int LogEvent (DWORD dwFlags, UINT idMsg, ...)
  456. {
  457. XLastError xe;
  458. TCHAR szMsg[MAX_PATH];
  459. LPTSTR lpErrorMsg;
  460. va_list marker;
  461. INT iChars;
  462. CEvents ev(dwFlags, EVENT_ERROR);
  463. //
  464. // Load the message
  465. //
  466. if (idMsg != 0) {
  467. if (!LoadString (g_hDllInstance, idMsg, szMsg, ARRAYSIZE(szMsg))) {
  468. DebugMsg((DM_WARNING, TEXT("LogEvent: LoadString failed. Error = %d"), GetLastError()));
  469. return -1;
  470. }
  471. } else {
  472. lstrcpy (szMsg, TEXT("%s"));
  473. }
  474. //
  475. // Allocate space for the error message
  476. //
  477. lpErrorMsg = (LPTSTR) LocalAlloc (LPTR, (4 * MAX_PATH + 100) * sizeof(TCHAR));
  478. if (!lpErrorMsg) {
  479. DebugMsg((DM_WARNING, TEXT("LogEvent: LocalAlloc failed. Error = %d"), GetLastError()));
  480. return -1;
  481. }
  482. //
  483. // Plug in the arguments
  484. //
  485. va_start(marker, idMsg);
  486. iChars = wvsprintf(lpErrorMsg, szMsg, marker);
  487. DmAssert( iChars < (4 * MAX_PATH + 100));
  488. va_end(marker);
  489. //
  490. // Now add this string to the arg list
  491. //
  492. ev.AddArg(lpErrorMsg);
  493. //
  494. // report
  495. //
  496. ev.Report();
  497. LocalFree (lpErrorMsg);
  498. return 0;
  499. }
  500. //*************************************************************
  501. //
  502. // ShutdownEvents()
  503. //
  504. // Purpose: Stops the event log
  505. //
  506. // Parameters: void
  507. //
  508. // Return: TRUE if successful
  509. // FALSE if an error occurs
  510. //
  511. // Comments:
  512. //
  513. // History: Date Author Comment
  514. // 7/17/95 ericflo Created
  515. //
  516. //*************************************************************
  517. BOOL ShutdownEvents (void)
  518. {
  519. BOOL bRetVal = TRUE;
  520. if (hEventLog) {
  521. bRetVal = DeregisterEventSource(hEventLog);
  522. hEventLog = NULL;
  523. }
  524. return bRetVal;
  525. }
  526. //*************************************************************
  527. //
  528. // ReportError()
  529. //
  530. // Purpose: Displays an error message to the user and
  531. // records it in the event log
  532. //
  533. // Parameters: dwFlags - Flags. Also indicates event type.
  534. // Default is Error.
  535. // dwCount - Number of string arguments
  536. // idMsg - Error message id
  537. // ... - String arguments
  538. //
  539. // Return: TRUE if successful
  540. // FALSE if an error occurs
  541. //
  542. // Comments: For EVENT_COPYERROR message we have to get the share
  543. // name for the mapped drive.
  544. // Be careful in future, if we add a new error message with
  545. // dir name in it.
  546. //
  547. // History: Date Author Comment
  548. // 7/18/95 ericflo Created
  549. // 9/03/00 santanuc Modified to work for client
  550. //
  551. //*************************************************************
  552. int ReportError (HANDLE hTokenUser, DWORD dwFlags, DWORD dwCount, UINT idMsg, ...)
  553. {
  554. TCHAR szMsg[MAX_PATH];
  555. LPTSTR lpErrorMsg=NULL, szArg;
  556. va_list marker;
  557. INT iChars;
  558. BOOL bImpersonated = FALSE;
  559. HANDLE hOldToken;
  560. LPTSTR szSidUser = NULL;
  561. DWORD dwErr = ERROR_SUCCESS;
  562. handle_t hIfProfileDialog; // rpc explicit binding handle for IProfileDialog interface
  563. LPTSTR lpRPCEndPoint = NULL; // RPCEndPoint for IProfileDialog interface registered in client side
  564. RPC_ASYNC_STATE AsyncHnd; // Async handle for making async rpc interface calls
  565. RPC_STATUS status = RPC_S_OK;
  566. LPTSTR lpShare = NULL;
  567. if (hTokenUser) {
  568. if (!ImpersonateUser(hTokenUser, &hOldToken)) {
  569. DebugMsg((DM_WARNING, TEXT("ReportError: ImpersonateUser failed with error %d."), GetLastError()));
  570. }
  571. else {
  572. bImpersonated = TRUE;
  573. DebugMsg((DM_WARNING, TEXT("ReportError: Impersonating user.")));
  574. }
  575. }
  576. CEvents ev(dwFlags, idMsg);
  577. //
  578. // Plug in the arguments
  579. //
  580. va_start(marker, idMsg);
  581. for (DWORD i = 0; i < dwCount; i++) {
  582. szArg = va_arg(marker, LPTSTR);
  583. //
  584. // Only EVENT_COPYERROR has first two parameters as dir name. So try to replace
  585. // the mapped drive with correct share name
  586. //
  587. if (idMsg == EVENT_COPYERROR && i < 2 && GetShareName(szArg, &lpShare)) {
  588. ev.AddArg(lpShare);
  589. LocalFree(lpShare);
  590. }
  591. else {
  592. ev.AddArg(szArg);
  593. }
  594. }
  595. va_end(marker);
  596. if (!(dwFlags & PI_NOUI)) {
  597. DWORD dwDlgTimeOut = PROFILE_DLG_TIMEOUT;
  598. DWORD dwSize, dwType;
  599. LONG lResult;
  600. HKEY hKey;
  601. //
  602. // Find the dialog box timeout
  603. //
  604. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  605. WINLOGON_KEY,
  606. 0,
  607. KEY_READ,
  608. &hKey);
  609. if (lResult == ERROR_SUCCESS) {
  610. dwSize = sizeof(DWORD);
  611. RegQueryValueEx (hKey,
  612. TEXT("ProfileDlgTimeOut"),
  613. NULL,
  614. &dwType,
  615. (LPBYTE) &dwDlgTimeOut,
  616. &dwSize);
  617. RegCloseKey (hKey);
  618. }
  619. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  620. SYSTEM_POLICIES_KEY,
  621. 0,
  622. KEY_READ,
  623. &hKey);
  624. if (lResult == ERROR_SUCCESS) {
  625. dwSize = sizeof(DWORD);
  626. RegQueryValueEx (hKey,
  627. TEXT("ProfileDlgTimeOut"),
  628. NULL,
  629. &dwType,
  630. (LPBYTE) &dwDlgTimeOut,
  631. &dwSize);
  632. RegCloseKey (hKey);
  633. }
  634. lpErrorMsg = ev.FormatString();
  635. if (lpErrorMsg) {
  636. DebugMsg((DM_VERBOSE, TEXT("ReportError: Logging Error <%s> \n"), lpErrorMsg));
  637. //
  638. // Display the message
  639. //
  640. szSidUser = GetSidString(hTokenUser);
  641. if (szSidUser) {
  642. //
  643. // Get the registered interface explicit binding handle using RPCEndPoint
  644. //
  645. if (cUserProfileManager.IsConsoleWinlogon()) {
  646. lpRPCEndPoint = cUserProfileManager.GetRPCEndPoint(szSidUser);
  647. }
  648. if (lpRPCEndPoint && GetInterface(&hIfProfileDialog, lpRPCEndPoint)) {
  649. DebugMsg((DM_VERBOSE, TEXT("ReportError: RPC End point %s"), lpRPCEndPoint));
  650. status = RpcAsyncInitializeHandle(&AsyncHnd, sizeof(RPC_ASYNC_STATE));
  651. if (status != RPC_S_OK) {
  652. dwErr = status;
  653. DebugMsg((DM_WARNING, TEXT("ReportError: RpcAsyncInitializeHandle failed. err = %d"), dwErr));
  654. }
  655. else {
  656. AsyncHnd.UserInfo = NULL; // App specific info, not req
  657. AsyncHnd.NotificationType = RpcNotificationTypeEvent; // Init the notification event
  658. AsyncHnd.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  659. if (AsyncHnd.u.hEvent) {
  660. RpcTryExcept {
  661. cliErrorDialog(&AsyncHnd, hIfProfileDialog, dwDlgTimeOut, lpErrorMsg);
  662. }
  663. RpcExcept(1) {
  664. dwErr = RpcExceptionCode();
  665. DebugMsg((DM_WARNING, TEXT("ReportError: Calling ErrorDialog took exception. err = %d"), dwErr));
  666. }
  667. RpcEndExcept
  668. DebugMsg((DM_VERBOSE, TEXT("ReportError: waiting on rpc async event")));
  669. if (WaitForSingleObject(AsyncHnd.u.hEvent, (dwDlgTimeOut + 10)*1000) == WAIT_OBJECT_0) {
  670. RpcAsyncCompleteCall(&AsyncHnd, (PVOID)&dwErr);
  671. }
  672. else {
  673. dwErr = GetLastError();
  674. RpcAsyncCancelCall(&AsyncHnd, TRUE);
  675. DebugMsg((DM_WARNING, TEXT("ReportError: Timeout occurs. Client not responding"), dwErr));
  676. }
  677. // Release the resource
  678. CloseHandle(AsyncHnd.u.hEvent);
  679. }
  680. else {
  681. dwErr = GetLastError();
  682. DebugMsg((DM_VERBOSE, TEXT("ReportError: create event failed error %d"), dwErr));
  683. }
  684. }
  685. if (dwErr != ERROR_SUCCESS) {
  686. DebugMsg((DM_WARNING, TEXT("ReportError: fail to show message error %d"), GetLastError()));
  687. }
  688. ReleaseInterface(&hIfProfileDialog); // Release the binding handle
  689. }
  690. DeleteSidString(szSidUser);
  691. }
  692. else {
  693. DebugMsg((DM_WARNING, TEXT("ReportError: Unable to get SID string from token.")));
  694. }
  695. if (!lpRPCEndPoint) {
  696. //
  697. // This can happen in two case :
  698. // 1. We are in console winlogon process.
  699. // 2. ReportError get called from some public api which we expose.
  700. //
  701. ErrorDialogEx(dwDlgTimeOut, lpErrorMsg);
  702. }
  703. }
  704. }
  705. //
  706. // Report the event to the eventlog
  707. //
  708. ev.Report();
  709. if (lpErrorMsg)
  710. LocalFree (lpErrorMsg);
  711. if (bImpersonated)
  712. RevertToUser(&hOldToken);
  713. return 0;
  714. }
  715. //*************************************************************
  716. //
  717. // ErrorDialogEx()
  718. //
  719. // Purpose: Call Dialog box procedure for displaying error message
  720. //
  721. // Parameters: dwTimeOut - Timeout in secs
  722. // lpErrMsg - Error Message
  723. //
  724. // Return: None
  725. //
  726. // Comments:
  727. //
  728. // History: Date Author Comment
  729. // 10/27/00 santanuc Created
  730. //
  731. //*************************************************************
  732. void ErrorDialogEx(DWORD dwTimeOut, LPTSTR lpErrMsg)
  733. {
  734. ERRORSTRUCT es;
  735. es.dwTimeOut = dwTimeOut;
  736. es.lpErrorText = lpErrMsg;
  737. DebugMsg((DM_VERBOSE, TEXT("ErrorDialogEx: Calling DialogBoxParam")));
  738. DialogBoxParam (g_hDllInstance, MAKEINTRESOURCE(IDD_ERROR),
  739. NULL, ErrorDlgProc, (LPARAM)&es);
  740. }
  741. //*************************************************************
  742. //
  743. // ErrorDlgProc()
  744. //
  745. // Purpose: Dialog box procedure for the error dialog
  746. //
  747. // Parameters: hDlg - handle to the dialog box
  748. // uMsg - window message
  749. // wParam - wParam
  750. // lParam - lParam
  751. //
  752. // Return: TRUE if message was processed
  753. // FALSE if not
  754. //
  755. // Comments:
  756. //
  757. // History: Date Author Comment
  758. // 3/22/96 ericflo Created
  759. //
  760. //*************************************************************
  761. INT_PTR APIENTRY ErrorDlgProc (HWND hDlg, UINT uMsg,
  762. WPARAM wParam, LPARAM lParam)
  763. {
  764. TCHAR szBuffer[10];
  765. static DWORD dwErrorTime;
  766. switch (uMsg) {
  767. case WM_INITDIALOG:
  768. {
  769. DebugMsg((DM_VERBOSE, TEXT("ErrorDlgProc:: DialogBoxParam")));
  770. LPERRORSTRUCT lpES = (LPERRORSTRUCT) lParam;
  771. SetForegroundWindow(hDlg);
  772. CenterWindow (hDlg);
  773. SetDlgItemText (hDlg, IDC_ERRORTEXT, lpES->lpErrorText);
  774. dwErrorTime = lpES->dwTimeOut;
  775. if (dwErrorTime > 0) {
  776. wsprintf (szBuffer, TEXT("%d"), dwErrorTime);
  777. SetDlgItemText (hDlg, IDC_TIMEOUT, szBuffer);
  778. SetTimer (hDlg, 1, 1000, NULL);
  779. }
  780. return TRUE;
  781. }
  782. case WM_TIMER:
  783. if (dwErrorTime >= 1) {
  784. dwErrorTime--;
  785. wsprintf (szBuffer, TEXT("%d"), dwErrorTime);
  786. SetDlgItemText (hDlg, IDC_TIMEOUT, szBuffer);
  787. } else {
  788. //
  789. // Time's up. Dismiss the dialog.
  790. //
  791. PostMessage (hDlg, WM_COMMAND, IDOK, 0);
  792. }
  793. break;
  794. case WM_COMMAND:
  795. switch (LOWORD(wParam)) {
  796. case IDOK:
  797. if (HIWORD(wParam) == BN_KILLFOCUS) {
  798. KillTimer (hDlg, 1);
  799. ShowWindow(GetDlgItem(hDlg, IDC_TIMEOUT), SW_HIDE);
  800. ShowWindow(GetDlgItem(hDlg, IDC_TIMETITLE), SW_HIDE);
  801. } else if (HIWORD(wParam) == BN_CLICKED) {
  802. KillTimer (hDlg, 1);
  803. EndDialog(hDlg, TRUE);
  804. }
  805. break;
  806. case IDCANCEL:
  807. KillTimer (hDlg, 1);
  808. EndDialog(hDlg, FALSE);
  809. break;
  810. default:
  811. break;
  812. }
  813. break;
  814. }
  815. return FALSE;
  816. }
  817. //*************************************************************
  818. //
  819. // GetShareName()
  820. //
  821. // Purpose: Returns the complete share name by unmapping the
  822. // drive letter in lpDir
  823. //
  824. // Parameters: lpDir - Dir name to be unmapped
  825. // lppShare - Expanded dir name with share
  826. //
  827. // Return: TRUE : if success
  828. // FALSE : otherwise
  829. //
  830. // Comments:
  831. //
  832. // History: Date Author Comment
  833. // 10/29/00 santanuc Created
  834. //
  835. //*************************************************************
  836. BOOL GetShareName(LPTSTR lpDir, LPTSTR *lppShare)
  837. {
  838. PFNWNETGETCONNECTION pfnWNetGetConnection;
  839. HMODULE hWNetLib = NULL;
  840. TCHAR szDrive[3];
  841. DWORD dwSize = 0, dwErr;
  842. BOOL bRetVal = FALSE;
  843. if (lpDir[1] != TEXT(':')) {
  844. goto Exit;
  845. }
  846. if (!(hWNetLib = LoadLibrary(TEXT("mpr.dll")))) {
  847. DebugMsg((DM_WARNING, TEXT("GetShareName: LoadLibrary failed with %d"), GetLastError()));
  848. goto Exit;
  849. }
  850. pfnWNetGetConnection = (PFNWNETGETCONNECTION)GetProcAddress(hWNetLib, "WNetGetConnectionW");
  851. if (!pfnWNetGetConnection) {
  852. DebugMsg((DM_WARNING, TEXT("GetShareName: GetProcAddress failed with %d"), GetLastError()));
  853. goto Exit;
  854. }
  855. szDrive[0] = lpDir[0];
  856. szDrive[1] = TEXT(':');
  857. szDrive[2] = TEXT('\0');
  858. // First get the size required to hold the share name
  859. dwErr = (*pfnWNetGetConnection)(szDrive, NULL, &dwSize);
  860. if (dwErr == ERROR_MORE_DATA) {
  861. dwSize += lstrlen(lpDir); // Add the size for rest of the path name
  862. *lppShare = (LPTSTR)LocalAlloc(LPTR, dwSize*sizeof(TCHAR));
  863. if (!*lppShare) {
  864. DebugMsg((DM_WARNING, TEXT("GetShareName: Failed to alloc memory with %d"), GetLastError()));
  865. goto Exit;
  866. }
  867. dwErr = (*pfnWNetGetConnection)(szDrive, *lppShare, &dwSize);
  868. if (dwErr == NO_ERROR) {
  869. lstrcat(*lppShare, lpDir+2); // Add the rest of the path name
  870. bRetVal = TRUE;
  871. goto Exit;
  872. }
  873. else {
  874. DebugMsg((DM_WARNING, TEXT("GetShareName: WNetGetConnection returned error %d"), dwErr));
  875. }
  876. LocalFree(*lppShare);
  877. }
  878. else {
  879. DebugMsg((DM_VERBOSE, TEXT("GetShareName: WNetGetConnection initially returned error %d"), dwErr));
  880. }
  881. Exit:
  882. if (hWNetLib) {
  883. FreeLibrary(hWNetLib);
  884. }
  885. return bRetVal;
  886. }