Leaked source code of windows server 2003
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.

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