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
1110 lines
31 KiB
//*************************************************************
|
|
//
|
|
// Events.c - Routines to handle the event log
|
|
//
|
|
// Microsoft Confidential
|
|
// Copyright (c) Microsoft Corporation 1995
|
|
// All rights reserved
|
|
//
|
|
//*************************************************************
|
|
|
|
#include "uenv.h"
|
|
#include "profmgr.hxx"
|
|
#include "strsafe.h"
|
|
|
|
extern CUserProfile cUserProfileManager;
|
|
|
|
HANDLE hEventLog = NULL;
|
|
TCHAR EventSourceName[] = TEXT("Userenv");
|
|
INT_PTR APIENTRY ErrorDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
BOOL GetShareName(LPTSTR lpDir, LPTSTR *lppShare);
|
|
|
|
//*************************************************************
|
|
//
|
|
// InitializeEvents()
|
|
//
|
|
// Purpose: Opens the event log
|
|
//
|
|
// Parameters: void
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 7/17/95 ericflo Created
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL InitializeEvents (void)
|
|
{
|
|
//
|
|
// Open the event source
|
|
//
|
|
|
|
hEventLog = RegisterEventSource(NULL, EventSourceName);
|
|
|
|
if (hEventLog) {
|
|
return TRUE;
|
|
}
|
|
|
|
DebugMsg((DM_WARNING, TEXT("InitializeEvents: Could not open event log. Error = %d"), GetLastError()));
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// Implementation of CEvents
|
|
//
|
|
//*************************************************************
|
|
|
|
|
|
|
|
//*************************************************************
|
|
// CEvents::CEvents
|
|
// Purpose: Constructor
|
|
//
|
|
// Parameters:
|
|
// dwFlags - Error, Warning or informational
|
|
// dwId - Id of the eventlog msg
|
|
//
|
|
//
|
|
// allocates a default sized array for the messages
|
|
//*************************************************************
|
|
|
|
#define DEF_ARG_SIZE 10
|
|
|
|
CEvents::CEvents(DWORD dwFlags, DWORD dwId ) :
|
|
m_cStrings(0), m_cAllocated(0), m_bInitialised(FALSE),
|
|
m_dwEventType(dwFlags), m_dwId(dwId), m_bFailed(TRUE)
|
|
{
|
|
XLastError xe;
|
|
//
|
|
// Allocate a default size for the message
|
|
//
|
|
|
|
m_xlpStrings = (LPTSTR *)LocalAlloc(LPTR, sizeof(LPTSTR)*DEF_ARG_SIZE);
|
|
m_cAllocated = DEF_ARG_SIZE;
|
|
if (!m_xlpStrings) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::CEvent Cannot log event, failed to allocate memory, error %d"), GetLastError()));
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// Initialise eventlog if it is not already initialised
|
|
//
|
|
|
|
if (!hEventLog) {
|
|
if (!InitializeEvents()) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::CEvent Cannot log event, no handle")));
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_bInitialised = TRUE;
|
|
m_bFailed = FALSE;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************
|
|
// CEvents::~CEvents()
|
|
//
|
|
// Purpose: Destructor
|
|
//
|
|
// Parameters: void
|
|
//
|
|
// frees the memory
|
|
//*************************************************************
|
|
|
|
CEvents::~CEvents()
|
|
{
|
|
XLastError xe;
|
|
for (int i = 0; i < m_cStrings; i++)
|
|
if (m_xlpStrings[i])
|
|
LocalFree(m_xlpStrings[i]);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::ReallocArgStrings
|
|
//
|
|
// Purpose: Reallocates the buffer for storing arguments in case
|
|
// the buffer runs out
|
|
//
|
|
// Parameters: void
|
|
//
|
|
// reallocates
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::ReallocArgStrings()
|
|
{
|
|
XPtrLF<LPTSTR> aStringsNew;
|
|
XLastError xe;
|
|
|
|
|
|
//
|
|
// first allocate a larger buffer
|
|
//
|
|
|
|
aStringsNew = (LPTSTR *)LocalAlloc(LPTR, sizeof(LPTSTR)*(m_cAllocated+DEF_ARG_SIZE));
|
|
|
|
if (!aStringsNew) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::ReallocArgStrings Cannot add memory, error = %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// copy the arguments
|
|
//
|
|
|
|
for (int i = 0; i < (m_cAllocated); i++) {
|
|
aStringsNew[i] = m_xlpStrings[i];
|
|
}
|
|
|
|
m_xlpStrings = aStringsNew.Acquire();
|
|
m_cAllocated+= DEF_ARG_SIZE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArg
|
|
//
|
|
// Purpose: Add arguments appropriately formatted
|
|
//
|
|
// Parameters:
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArg(LPTSTR szArg)
|
|
{
|
|
XLastError xe;
|
|
DWORD cchString;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed)) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_cStrings == m_cAllocated) {
|
|
if (!ReallocArgStrings())
|
|
return FALSE;
|
|
}
|
|
|
|
cchString = lstrlen(szArg)+1;
|
|
m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cchString);
|
|
|
|
if (!m_xlpStrings[m_cStrings]) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
StringCchCopy(m_xlpStrings[m_cStrings], cchString, szArg);
|
|
m_cStrings++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArg
|
|
//
|
|
// Purpose: Add arguments appropriately truncated
|
|
//
|
|
// Parameters: szArgFormat - sprintf format, e.g. %.500s
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArg(LPTSTR szArgFormat, LPTSTR szArg)
|
|
{
|
|
const DWORD cchString = 200;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed)) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_cStrings == m_cAllocated) {
|
|
if (!ReallocArgStrings())
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cchString);
|
|
|
|
if (!m_xlpStrings[m_cStrings]) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchPrintf(m_xlpStrings[m_cStrings], cchString, szArgFormat, szArg);
|
|
m_cStrings++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArg
|
|
//
|
|
// Purpose: Add arguments appropriately formatted
|
|
//
|
|
// Parameters:
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArg(DWORD dwArg)
|
|
{
|
|
XLastError xe;
|
|
const DWORD cchString = 20;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed)) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg(dw): Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_cStrings == m_cAllocated) {
|
|
if (!ReallocArgStrings())
|
|
return FALSE;
|
|
}
|
|
|
|
// 2^32 < 10^10
|
|
m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cchString);
|
|
|
|
if (!m_xlpStrings[m_cStrings]) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArg Cannot allocate memory, error = %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
StringCchPrintf(m_xlpStrings[m_cStrings], cchString, TEXT("%d"), dwArg);
|
|
m_cStrings++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArgHex
|
|
//
|
|
// Purpose: Add arguments appropriately formatted
|
|
//
|
|
// Parameters:
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArgHex(DWORD dwArg)
|
|
{
|
|
XLastError xe;
|
|
const DWORD cchString = 20;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed)) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArgHex: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_cStrings == m_cAllocated) {
|
|
if (!ReallocArgStrings())
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
m_xlpStrings[m_cStrings] = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * cchString);
|
|
|
|
if (!m_xlpStrings[m_cStrings]) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArgHex Cannot allocate memory, error = %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
StringCchPrintf(m_xlpStrings[m_cStrings], cchString, TEXT("%#x"), dwArg);
|
|
m_cStrings++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArgWin32Error
|
|
//
|
|
// Purpose: Add arguments appropriately formatted
|
|
//
|
|
// Parameters:
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArgWin32Error(DWORD dwArg)
|
|
{
|
|
XLastError xe;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed))
|
|
{
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArgWin32Error: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_cStrings == m_cAllocated)
|
|
{
|
|
if (!ReallocArgStrings())
|
|
return FALSE;
|
|
}
|
|
|
|
if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
0,
|
|
dwArg,
|
|
0,
|
|
(LPTSTR) &m_xlpStrings[m_cStrings],
|
|
1,
|
|
0 ) == 0 )
|
|
{
|
|
DebugMsg((DM_WARNING, TEXT("CEvent::AddArgWin32Error: Cannot log event, FormatMessage failed, %d"), GetLastError()));
|
|
m_bFailed = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
m_cStrings++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::AddArgLdapError
|
|
//
|
|
// Purpose: Add arguments appropriately formatted
|
|
//
|
|
// Parameters:
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::AddArgLdapError(DWORD dwArg)
|
|
{
|
|
XLastError xe;
|
|
PLDAP_API pLdap = LoadLDAP();
|
|
|
|
if ( pLdap )
|
|
{
|
|
return AddArg( pLdap->pfnldap_err2string( dwArg ) );
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// CEvents::Report
|
|
//
|
|
// Purpose: Actually collectes all the arguments and reports it to
|
|
// the eventlog
|
|
//
|
|
// Parameters: void
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL CEvents::Report()
|
|
{
|
|
XLastError xe;
|
|
XHandle xhToken;
|
|
PSID pSid = NULL;
|
|
WORD wType=0;
|
|
BOOL bResult = TRUE;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed))
|
|
{
|
|
DebugMsg((DM_WARNING, TEXT("CEvents::Report: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Get the caller's token
|
|
//
|
|
if (!OpenThreadToken (GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_READ | TOKEN_DUPLICATE,
|
|
TRUE, &xhToken))
|
|
{
|
|
OpenProcessToken(GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_READ | TOKEN_DUPLICATE,
|
|
&xhToken);
|
|
}
|
|
|
|
//
|
|
// Get the caller's sid
|
|
//
|
|
if (xhToken)
|
|
{
|
|
pSid = GetUserSid(xhToken);
|
|
|
|
if (!pSid)
|
|
{
|
|
DebugMsg((DM_WARNING, TEXT("CEvents::Report: Failed to get the sid")));
|
|
}
|
|
}
|
|
|
|
if (m_dwEventType & EVENT_INFO_TYPE)
|
|
{
|
|
wType = EVENTLOG_INFORMATION_TYPE;
|
|
}
|
|
else if (m_dwEventType & EVENT_WARNING_TYPE)
|
|
{
|
|
wType = EVENTLOG_WARNING_TYPE;
|
|
}
|
|
else
|
|
{
|
|
wType = EVENTLOG_ERROR_TYPE;
|
|
}
|
|
|
|
if ( !ReportEvent( hEventLog,
|
|
wType,
|
|
0,
|
|
m_dwId,
|
|
pSid,
|
|
m_cStrings,
|
|
0,
|
|
(LPCTSTR *)((LPTSTR *)m_xlpStrings),
|
|
0 ) )
|
|
{
|
|
DebugMsg((DM_WARNING, TEXT("CEvents::Report: ReportEvent failed. Error = %d"), GetLastError()));
|
|
bResult = FALSE;
|
|
}
|
|
|
|
if (pSid)
|
|
{
|
|
DeleteUserSid(pSid);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
LPTSTR CEvents::FormatString()
|
|
{
|
|
XLastError xe;
|
|
BOOL bResult = TRUE;
|
|
LPTSTR szMsg=NULL;
|
|
|
|
if ((!m_bInitialised) || (m_bFailed)) {
|
|
DebugMsg((DM_WARNING, TEXT("CEvents::Report: Cannot log event, not initialised or failed before")));
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_HMODULE |
|
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
g_hDllInstance,
|
|
m_dwId,
|
|
0,
|
|
(LPTSTR)&szMsg,
|
|
0, // min number of chars
|
|
(va_list *)(LPTSTR *)(m_xlpStrings))) {
|
|
|
|
DebugMsg((DM_WARNING, TEXT("CEvents::FormatString: ReportEvent failed. Error = %d"), GetLastError()));
|
|
return NULL;
|
|
}
|
|
|
|
|
|
return szMsg;
|
|
}
|
|
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// LogEvent()
|
|
//
|
|
// Purpose: Logs an event to the event log
|
|
//
|
|
// Parameters: dwFlags - Error, Warning or informational
|
|
// idMsg - Message id
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 2/5/98 ericflo Created
|
|
//
|
|
//*************************************************************
|
|
|
|
int LogEvent (DWORD dwFlags, UINT idMsg, ...)
|
|
{
|
|
XLastError xe;
|
|
TCHAR szMsg[MAX_PATH];
|
|
LPTSTR lpErrorMsg;
|
|
va_list marker;
|
|
CEvents ev(dwFlags, EVENT_ERROR);
|
|
DWORD cchErrorMsg;
|
|
|
|
//
|
|
// Load the message
|
|
//
|
|
|
|
if (idMsg != 0) {
|
|
if (!LoadString (g_hDllInstance, idMsg, szMsg, ARRAYSIZE(szMsg))) {
|
|
DebugMsg((DM_WARNING, TEXT("LogEvent: LoadString failed. Error = %d"), GetLastError()));
|
|
return -1;
|
|
}
|
|
|
|
} else {
|
|
StringCchCopy (szMsg, ARRAYSIZE(szMsg), TEXT("%s"));
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the error message
|
|
//
|
|
|
|
cchErrorMsg = 4 * MAX_PATH + 100;
|
|
lpErrorMsg = (LPTSTR) LocalAlloc (LPTR, cchErrorMsg * sizeof(TCHAR));
|
|
|
|
if (!lpErrorMsg) {
|
|
DebugMsg((DM_WARNING, TEXT("LogEvent: LocalAlloc failed. Error = %d"), GetLastError()));
|
|
return -1;
|
|
}
|
|
|
|
|
|
//
|
|
// Plug in the arguments
|
|
//
|
|
|
|
va_start(marker, idMsg);
|
|
|
|
StringCchVPrintf(lpErrorMsg, cchErrorMsg, szMsg, marker);
|
|
|
|
va_end(marker);
|
|
|
|
//
|
|
// Now add this string to the arg list
|
|
//
|
|
|
|
ev.AddArg(lpErrorMsg);
|
|
|
|
|
|
//
|
|
// report
|
|
//
|
|
|
|
ev.Report();
|
|
|
|
LocalFree (lpErrorMsg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// ShutdownEvents()
|
|
//
|
|
// Purpose: Stops the event log
|
|
//
|
|
// Parameters: void
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 7/17/95 ericflo Created
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL ShutdownEvents (void)
|
|
{
|
|
BOOL bRetVal = TRUE;
|
|
|
|
if (hEventLog) {
|
|
bRetVal = DeregisterEventSource(hEventLog);
|
|
hEventLog = NULL;
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// ReportError()
|
|
//
|
|
// Purpose: Displays an error message to the user and
|
|
// records it in the event log
|
|
//
|
|
// Parameters: dwFlags - Flags. Also indicates event type.
|
|
// Default is Error.
|
|
// dwCount - Number of string arguments
|
|
// idMsg - Error message id
|
|
// ... - String arguments
|
|
//
|
|
// Return: TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Comments: For EVENT_COPYERROR message we have to get the share
|
|
// name for the mapped drive.
|
|
// Be careful in future, if we add a new error message with
|
|
// dir name in it.
|
|
//
|
|
// History: Date Author Comment
|
|
// 7/18/95 ericflo Created
|
|
// 9/03/00 santanuc Modified to work for client
|
|
//
|
|
//*************************************************************
|
|
|
|
|
|
int ReportError (HANDLE hTokenUser, DWORD dwFlags, DWORD dwCount, UINT idMsg, ...)
|
|
{
|
|
TCHAR szMsg[MAX_PATH];
|
|
LPTSTR lpErrorMsg=NULL, szArg;
|
|
va_list marker;
|
|
INT iChars;
|
|
BOOL bImpersonated = FALSE;
|
|
HANDLE hOldToken;
|
|
LPTSTR szSidUser = NULL;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
handle_t hIfProfileDialog; // rpc explicit binding handle for IProfileDialog interface
|
|
LPTSTR lpRPCEndPoint = NULL; // RPCEndPoint for IProfileDialog interface registered in client side
|
|
RPC_ASYNC_STATE AsyncHnd; // Async handle for making async rpc interface calls
|
|
RPC_STATUS status = RPC_S_OK;
|
|
LPTSTR lpShare = NULL;
|
|
|
|
|
|
if (hTokenUser) {
|
|
if (!ImpersonateUser(hTokenUser, &hOldToken)) {
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: ImpersonateUser failed with error %d."), GetLastError()));
|
|
}
|
|
else {
|
|
bImpersonated = TRUE;
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: Impersonating user.")));
|
|
}
|
|
}
|
|
|
|
CEvents ev(dwFlags, idMsg);
|
|
|
|
//
|
|
// Plug in the arguments
|
|
//
|
|
|
|
va_start(marker, idMsg);
|
|
|
|
for (DWORD i = 0; i < dwCount; i++) {
|
|
szArg = va_arg(marker, LPTSTR);
|
|
|
|
//
|
|
// Only EVENT_COPYERROR has first two parameters as dir name. So try to replace
|
|
// the mapped drive with correct share name
|
|
//
|
|
|
|
if (idMsg == EVENT_COPYERROR && i < 2 && GetShareName(szArg, &lpShare)) {
|
|
ev.AddArg(lpShare);
|
|
LocalFree(lpShare);
|
|
}
|
|
else {
|
|
ev.AddArg(szArg);
|
|
}
|
|
}
|
|
|
|
va_end(marker);
|
|
|
|
|
|
|
|
if (!(dwFlags & PI_NOUI)) {
|
|
|
|
DWORD dwDlgTimeOut = PROFILE_DLG_TIMEOUT;
|
|
DWORD dwSize, dwType;
|
|
LONG lResult;
|
|
HKEY hKey;
|
|
|
|
//
|
|
// Find the dialog box timeout
|
|
//
|
|
|
|
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
WINLOGON_KEY,
|
|
0,
|
|
KEY_READ,
|
|
&hKey);
|
|
|
|
if (lResult == ERROR_SUCCESS) {
|
|
|
|
dwSize = sizeof(DWORD);
|
|
RegQueryValueEx (hKey,
|
|
TEXT("ProfileDlgTimeOut"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE) &dwDlgTimeOut,
|
|
&dwSize);
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
}
|
|
|
|
|
|
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
SYSTEM_POLICIES_KEY,
|
|
0,
|
|
KEY_READ,
|
|
&hKey);
|
|
|
|
if (lResult == ERROR_SUCCESS) {
|
|
|
|
dwSize = sizeof(DWORD);
|
|
RegQueryValueEx (hKey,
|
|
TEXT("ProfileDlgTimeOut"),
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE) &dwDlgTimeOut,
|
|
&dwSize);
|
|
|
|
|
|
RegCloseKey (hKey);
|
|
}
|
|
|
|
|
|
lpErrorMsg = ev.FormatString();
|
|
|
|
if (lpErrorMsg) {
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("ReportError: Logging Error <%s> \n"), lpErrorMsg));
|
|
|
|
//
|
|
// Display the message
|
|
//
|
|
|
|
szSidUser = GetSidString(hTokenUser);
|
|
if (szSidUser) {
|
|
|
|
BYTE* pbCookie = NULL;
|
|
DWORD cbCookie = 0;
|
|
|
|
//
|
|
// Get the registered interface explicit binding handle using RPCEndPoint
|
|
//
|
|
|
|
if (cUserProfileManager.IsConsoleWinlogon()) {
|
|
|
|
cUserProfileManager.GetRPCEndPointAndCookie(szSidUser, &lpRPCEndPoint, &pbCookie, &cbCookie);
|
|
|
|
}
|
|
if (lpRPCEndPoint && GetInterface(&hIfProfileDialog, lpRPCEndPoint)) {
|
|
DebugMsg((DM_VERBOSE, TEXT("ReportError: RPC End point %s"), lpRPCEndPoint));
|
|
|
|
status = RpcAsyncInitializeHandle(&AsyncHnd, sizeof(RPC_ASYNC_STATE));
|
|
if (status != RPC_S_OK) {
|
|
dwErr = status;
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: RpcAsyncInitializeHandle failed. err = %d"), dwErr));
|
|
}
|
|
else {
|
|
AsyncHnd.UserInfo = NULL; // App specific info, not req
|
|
AsyncHnd.NotificationType = RpcNotificationTypeEvent; // Init the notification event
|
|
AsyncHnd.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
|
|
if (AsyncHnd.u.hEvent) {
|
|
RpcTryExcept {
|
|
cliErrorDialog(&AsyncHnd, hIfProfileDialog, dwDlgTimeOut, lpErrorMsg, pbCookie, cbCookie);
|
|
dwErr = RPC_S_OK;
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) {
|
|
dwErr = RpcExceptionCode();
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: Calling ErrorDialog took exception. err = %d"), dwErr));
|
|
}
|
|
RpcEndExcept;
|
|
|
|
// In case of exception, the runtime will do the cleanup.
|
|
if (dwErr == RPC_S_OK) {
|
|
DebugMsg((DM_VERBOSE, TEXT("ReportError: waiting on rpc async event")));
|
|
if (WaitForSingleObject(AsyncHnd.u.hEvent, (dwDlgTimeOut + 10)*1000) == WAIT_OBJECT_0) {
|
|
status = RpcAsyncCompleteCall(&AsyncHnd, (PVOID)&dwErr);
|
|
}
|
|
else {
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: Timeout occurs. Client not responding")));
|
|
// Abortive cancle, should always succeed
|
|
status = RpcAsyncCancelCall(&AsyncHnd, TRUE);
|
|
DmAssert(status == RPC_S_OK);
|
|
// Now wait for RPC to take notice of the force abort
|
|
if (WaitForSingleObject(AsyncHnd.u.hEvent, INFINITE) != WAIT_OBJECT_0) {
|
|
DmAssert(FALSE && "WaitForSingleObject : Rpc async handle not signaled");
|
|
}
|
|
// Complete the Rpc aborted call.
|
|
status = RpcAsyncCompleteCall(&AsyncHnd, (PVOID)&dwErr);
|
|
}
|
|
DebugMsg((DM_VERBOSE, TEXT("RpcAsyncCompleteCall finished, status = %d"), status));
|
|
}
|
|
|
|
// Release the resource
|
|
CloseHandle(AsyncHnd.u.hEvent);
|
|
}
|
|
else {
|
|
dwErr = GetLastError();
|
|
DebugMsg((DM_VERBOSE, TEXT("ReportError: create event failed error %d"), dwErr));
|
|
}
|
|
}
|
|
|
|
if (dwErr != ERROR_SUCCESS) {
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: fail to show message error %d"), GetLastError()));
|
|
}
|
|
|
|
ReleaseInterface(&hIfProfileDialog); // Release the binding handle
|
|
}
|
|
DeleteSidString(szSidUser);
|
|
}
|
|
else {
|
|
DebugMsg((DM_WARNING, TEXT("ReportError: Unable to get SID string from token.")));
|
|
}
|
|
|
|
if (!lpRPCEndPoint) {
|
|
|
|
//
|
|
// This can happen in two case :
|
|
// 1. We are in console winlogon process.
|
|
// 2. ReportError get called from some public api which we expose.
|
|
//
|
|
|
|
ErrorDialogEx(dwDlgTimeOut, lpErrorMsg);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Report the event to the eventlog
|
|
//
|
|
|
|
ev.Report();
|
|
|
|
if (lpErrorMsg)
|
|
LocalFree (lpErrorMsg);
|
|
|
|
if (bImpersonated)
|
|
RevertToUser(&hOldToken);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// ErrorDialogEx()
|
|
//
|
|
// Purpose: Call Dialog box procedure for displaying error message
|
|
//
|
|
// Parameters: dwTimeOut - Timeout in secs
|
|
// lpErrMsg - Error Message
|
|
//
|
|
// Return: None
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 10/27/00 santanuc Created
|
|
//
|
|
//*************************************************************
|
|
void ErrorDialogEx(DWORD dwTimeOut, LPTSTR lpErrMsg)
|
|
{
|
|
ERRORSTRUCT es;
|
|
|
|
es.dwTimeOut = dwTimeOut;
|
|
es.lpErrorText = lpErrMsg;
|
|
|
|
DebugMsg((DM_VERBOSE, TEXT("ErrorDialogEx: Calling DialogBoxParam")));
|
|
DialogBoxParam (g_hDllInstance, MAKEINTRESOURCE(IDD_ERROR),
|
|
NULL, ErrorDlgProc, (LPARAM)&es);
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// ErrorDlgProc()
|
|
//
|
|
// Purpose: Dialog box procedure for the error dialog
|
|
//
|
|
// Parameters: hDlg - handle to the dialog box
|
|
// uMsg - window message
|
|
// wParam - wParam
|
|
// lParam - lParam
|
|
//
|
|
// Return: TRUE if message was processed
|
|
// FALSE if not
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 3/22/96 ericflo Created
|
|
//
|
|
//*************************************************************
|
|
|
|
INT_PTR APIENTRY ErrorDlgProc (HWND hDlg, UINT uMsg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
TCHAR szBuffer[10];
|
|
static DWORD dwErrorTime;
|
|
|
|
switch (uMsg) {
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
DebugMsg((DM_VERBOSE, TEXT("ErrorDlgProc:: DialogBoxParam")));
|
|
LPERRORSTRUCT lpES = (LPERRORSTRUCT) lParam;
|
|
|
|
SetForegroundWindow(hDlg);
|
|
CenterWindow (hDlg);
|
|
SetDlgItemText (hDlg, IDC_ERRORTEXT, lpES->lpErrorText);
|
|
|
|
dwErrorTime = lpES->dwTimeOut;
|
|
|
|
if (dwErrorTime > 0) {
|
|
StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), TEXT("%d"), dwErrorTime);
|
|
SetDlgItemText (hDlg, IDC_TIMEOUT, szBuffer);
|
|
SetTimer (hDlg, 1, 1000, NULL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_TIMER:
|
|
|
|
if (dwErrorTime >= 1) {
|
|
|
|
dwErrorTime--;
|
|
StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), TEXT("%d"), dwErrorTime);
|
|
SetDlgItemText (hDlg, IDC_TIMEOUT, szBuffer);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Time's up. Dismiss the dialog.
|
|
//
|
|
|
|
PostMessage (hDlg, WM_COMMAND, IDOK, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case IDOK:
|
|
if (HIWORD(wParam) == BN_KILLFOCUS) {
|
|
KillTimer (hDlg, 1);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_TIMEOUT), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_TIMETITLE), SW_HIDE);
|
|
|
|
} else if (HIWORD(wParam) == BN_CLICKED) {
|
|
KillTimer (hDlg, 1);
|
|
EndDialog(hDlg, TRUE);
|
|
}
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
KillTimer (hDlg, 1);
|
|
EndDialog(hDlg, FALSE);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// GetShareName()
|
|
//
|
|
// Purpose: Returns the complete share name by unmapping the
|
|
// drive letter in lpDir
|
|
//
|
|
// Parameters: lpDir - Dir name to be unmapped
|
|
// lppShare - Expanded dir name with share
|
|
//
|
|
// Return: TRUE : if success
|
|
// FALSE : otherwise
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 10/29/00 santanuc Created
|
|
//
|
|
//*************************************************************
|
|
BOOL GetShareName(LPTSTR lpDir, LPTSTR *lppShare)
|
|
{
|
|
PFNWNETGETCONNECTION pfnWNetGetConnection;
|
|
HMODULE hWNetLib = NULL;
|
|
TCHAR szDrive[3];
|
|
DWORD dwSize = 0, dwErr;
|
|
BOOL bRetVal = FALSE;
|
|
DWORD cchShare;
|
|
|
|
if (lpDir[1] != TEXT(':')) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!(hWNetLib = LoadLibrary(TEXT("mpr.dll")))) {
|
|
DebugMsg((DM_WARNING, TEXT("GetShareName: LoadLibrary failed with %d"), GetLastError()));
|
|
goto Exit;
|
|
}
|
|
pfnWNetGetConnection = (PFNWNETGETCONNECTION)GetProcAddress(hWNetLib, "WNetGetConnectionW");
|
|
if (!pfnWNetGetConnection) {
|
|
DebugMsg((DM_WARNING, TEXT("GetShareName: GetProcAddress failed with %d"), GetLastError()));
|
|
goto Exit;
|
|
}
|
|
|
|
szDrive[0] = lpDir[0];
|
|
szDrive[1] = TEXT(':');
|
|
szDrive[2] = TEXT('\0');
|
|
|
|
// First get the size required to hold the share name
|
|
dwErr = (*pfnWNetGetConnection)(szDrive, NULL, &dwSize);
|
|
|
|
if (dwErr == ERROR_MORE_DATA) {
|
|
dwSize += lstrlen(lpDir); // Add the size for rest of the path name
|
|
cchShare = dwSize;
|
|
*lppShare = (LPTSTR)LocalAlloc(LPTR, cchShare * sizeof(TCHAR));
|
|
if (!*lppShare) {
|
|
DebugMsg((DM_WARNING, TEXT("GetShareName: Failed to alloc memory with %d"), GetLastError()));
|
|
goto Exit;
|
|
}
|
|
dwErr = (*pfnWNetGetConnection)(szDrive, *lppShare, &dwSize);
|
|
if (dwErr == NO_ERROR) {
|
|
StringCchCat(*lppShare, cchShare, lpDir+2); // Add the rest of the path name
|
|
bRetVal = TRUE;
|
|
goto Exit;
|
|
}
|
|
else {
|
|
DebugMsg((DM_WARNING, TEXT("GetShareName: WNetGetConnection returned error %d"), dwErr));
|
|
}
|
|
|
|
LocalFree(*lppShare);
|
|
}
|
|
else {
|
|
DebugMsg((DM_VERBOSE, TEXT("GetShareName: WNetGetConnection initially returned error %d"), dwErr));
|
|
}
|
|
|
|
Exit:
|
|
|
|
if (hWNetLib) {
|
|
FreeLibrary(hWNetLib);
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|