|
|
//
// ident.cpp - implementation of CIdentity class
//
#include "private.h"
#include "multiusr.h"
#include "multiui.h"
#include "strconst.h"
#include "resource.h"
#include "mluisup.h"
extern HINSTANCE g_hInst; BOOL g_fReleasedMutex = true;
//
// Constructor / destructor
//
CUserIdentityManager::CUserIdentityManager() { m_cRef = 1; m_fWndRegistered = FALSE; m_hwnd = NULL; m_pAdviseRegistry = NULL; InitializeCriticalSection(&m_rCritSect); DllAddRef(); }
CUserIdentityManager::~CUserIdentityManager() { if (m_pAdviseRegistry) m_pAdviseRegistry->Release(); DeleteCriticalSection(&m_rCritSect); DllRelease(); }
//
// IUnknown members
//
STDMETHODIMP CUserIdentityManager::QueryInterface( REFIID riid, void **ppv) { if (NULL == ppv) { return E_INVALIDARG; } *ppv=NULL;
// Validate requested interface
if (IID_IUnknown == riid) { *ppv = (IUserIdentityManager *)this; } else if (IID_IUserIdentityManager == riid) { *ppv = (IUserIdentityManager *)this; } else if (IID_IConnectionPoint == riid) { *ppv = (IConnectionPoint *)this; } else if (IID_IPrivateIdentityManager == riid) { *ppv = (IPrivateIdentityManager *)this; } else if (IID_IPrivateIdentityManager2 == riid) { *ppv = (IPrivateIdentityManager2 *)this; }
// Addref through the interface
if (NULL != *ppv) { ((LPUNKNOWN)*ppv)->AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDMETHODIMP_(ULONG) CUserIdentityManager::AddRef() { return ++m_cRef; }
STDMETHODIMP_(ULONG) CUserIdentityManager::Release() { if (0L != --m_cRef) return m_cRef;
delete this; return 0L; }
STDMETHODIMP CUserIdentityManager::CreateIdentity(WCHAR *pszName, IUserIdentity **ppIdentity) { return CreateIdentity2(pszName, NULL, ppIdentity); }
STDMETHODIMP CUserIdentityManager::CreateIdentity2(WCHAR *pszName, WCHAR *pszPassword, IUserIdentity **ppIdentity) { CUserIdentity *pIdentity; HRESULT hr; TCHAR szName[CCH_IDENTITY_NAME_MAX_LENGTH+1];
*ppIdentity = NULL;
if (MU_IdentitiesDisabled()) return E_IDENTITIES_DISABLED;
if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, szName, CCH_IDENTITY_NAME_MAX_LENGTH, NULL, NULL) == 0) return GetLastError();
if (MU_UsernameExists(szName)) return E_IDENTITY_EXISTS;
pIdentity = new CUserIdentity; Assert(pIdentity);
if (!pIdentity) return E_OUTOFMEMORY;
hr = pIdentity->SetName(pszName); if (SUCCEEDED(hr)) { if (pszPassword) { hr = pIdentity->SetPassword(pszPassword); } }
if (SUCCEEDED(hr)) { *ppIdentity = pIdentity; } else { pIdentity->Release(); }
PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, IIC_IDENTITY_ADDED);
return hr; }
STDMETHODIMP CUserIdentityManager::ConfirmPassword(GUID *uidCookie, WCHAR *pszPassword) { TCHAR szPwd[CCH_USERPASSWORD_MAX_LENGTH+1]; HRESULT hr = E_FAIL; USERINFO userInfo;
if (WideCharToMultiByte(CP_ACP, 0, pszPassword, -1, szPwd, CCH_USERPASSWORD_MAX_LENGTH, NULL, NULL) == 0) return E_FAIL;
if (MU_GetUserInfo(uidCookie, &userInfo)) { if (userInfo.fPasswordValid) { if (!userInfo.fUsePassword) userInfo.szPassword[0] = 0;
if (lstrcmp(szPwd, userInfo.szPassword) == 0) hr = S_OK; else hr = E_FAIL; } else { hr = E_FAIL; } }
return hr; }
STDMETHODIMP CUserIdentityManager::DestroyIdentity(GUID *uidCookie) { if (MU_IdentitiesDisabled()) return E_IDENTITIES_DISABLED; return MU_DeleteUser(uidCookie); }
STDMETHODIMP CUserIdentityManager::EnumIdentities(IEnumUserIdentity **ppEnumIdentity) { CEnumUserIdentity *pEnumIdentity;
*ppEnumIdentity = NULL;
pEnumIdentity = new CEnumUserIdentity;
if (!pEnumIdentity) return E_OUTOFMEMORY;
*ppEnumIdentity = pEnumIdentity;
return S_OK; }
STDMETHODIMP CUserIdentityManager::SetDefaultIdentity(GUID *puidCookie) { if (MU_IdentitiesDisabled()) return E_IDENTITIES_DISABLED;
return MU_MakeDefaultUser(puidCookie); }
STDMETHODIMP CUserIdentityManager::GetDefaultIdentity(GUID *puidCookie) { if (MU_IdentitiesDisabled()) return E_IDENTITIES_DISABLED;
return MU_GetDefaultUserID(puidCookie) ? S_OK : S_FALSE; }
STDMETHODIMP CUserIdentityManager::ManageIdentities(HWND hwndParent, DWORD dwFlags) { TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1];
if (MU_IdentitiesDisabled()) return E_IDENTITIES_DISABLED; *szUsername = 0;
MU_ManageUsers(hwndParent, szUsername, dwFlags); // if the user created a new user and said they want to switch to them now,
// we should do so.
if (*szUsername) { BOOL fGotUser; USERINFO rUser; GUID uidUserID; HRESULT hr;
fGotUser = MU_GetUserInfo(NULL, &rUser); if (!fGotUser) { *rUser.szUsername = 0; ZeroMemory(&rUser.uidUserID, sizeof(GUID)); } MU_UsernameToUserId(szUsername, &uidUserID);
if (FAILED(hr = _SwitchToUser(&rUser.uidUserID, &uidUserID))) { SetForegroundWindow(hwndParent); if (hr != E_USER_CANCELLED) MU_ShowErrorMessage(hwndParent, idsSwitchCancelled, idsSwitchCancelCaption); } } return S_OK; }
STDMETHODIMP CUserIdentityManager::_PersistChangingIdentities() { HRESULT hr = E_FAIL; HKEY hKeyIdentities = NULL;
if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, c_szRegRoot, &hKeyIdentities)) { goto exit; }
if (ERROR_SUCCESS != RegSetValueEx(hKeyIdentities, c_szOutgoingID, 0, REG_BINARY, (LPBYTE)&g_uidOldUserId, sizeof(GUID))) { goto exit; } if (ERROR_SUCCESS != RegSetValueEx(hKeyIdentities, c_szIncomingID, 0, REG_BINARY, (LPBYTE)&g_uidNewUserId, sizeof(GUID))) { goto exit; } if (ERROR_SUCCESS != RegSetValueEx(hKeyIdentities, c_szChanging, 0, REG_BINARY, (LPBYTE)&g_fNotifyComplete, sizeof(g_fNotifyComplete))) { goto exit; }
hr = S_OK; exit: if (hKeyIdentities) { RegCloseKey(hKeyIdentities); } return hr; }
STDMETHODIMP CUserIdentityManager::_LoadChangingIdentities() { HRESULT hr = E_FAIL; HKEY hKeyIdentities = NULL; DWORD dwType, dwSize;
if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, c_szRegRoot, &hKeyIdentities)) { goto exit; }
dwType = REG_BINARY; dwSize = sizeof(GUID); if (ERROR_SUCCESS != RegQueryValueEx(hKeyIdentities, c_szOutgoingID, 0, &dwType, (LPBYTE)&g_uidOldUserId, &dwSize)) { goto exit; } dwSize = sizeof(GUID); if (ERROR_SUCCESS != RegQueryValueEx(hKeyIdentities, c_szIncomingID, 0, &dwType, (LPBYTE)&g_uidNewUserId, &dwSize)) { goto exit; }
dwSize = sizeof(g_fNotifyComplete); if (ERROR_SUCCESS != RegQueryValueEx(hKeyIdentities, c_szChanging, 0, &dwType, (LPBYTE)&g_fNotifyComplete, &dwSize)) { goto exit; }
hr = S_OK; exit: if (FAILED(hr)) { g_uidOldUserId = GUID_NULL; g_uidNewUserId = GUID_NULL; g_fNotifyComplete = TRUE; } if (hKeyIdentities) { RegCloseKey(hKeyIdentities); } return hr; }
STDMETHODIMP CUserIdentityManager::ClearChangingIdentities() { HRESULT hr = E_FAIL; HKEY hKeyIdentities = NULL;
if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, c_szRegRoot, &hKeyIdentities)) { goto exit; }
RegDeleteValue(hKeyIdentities, c_szChanging); RegDeleteValue(hKeyIdentities, c_szIncomingID); RegDeleteValue(hKeyIdentities, c_szOutgoingID);
hr = S_OK; exit: if (hKeyIdentities) { RegCloseKey(hKeyIdentities); } return hr;
}
STDMETHODIMP CUserIdentityManager::Logon(HWND hwndParent, DWORD dwFlags, IUserIdentity **ppIdentity) { CUserIdentity *pIdentity; HRESULT hr = E_FAIL; USERINFO rUser; GUID uidUserID, uidNewUserID; BOOL fGotUser; TCHAR szOldUsername[CCH_USERNAME_MAX_LENGTH+1], szLogoffName[CCH_USERNAME_MAX_LENGTH+1]; TCHAR szRes[MAX_PATH];
// if identities are disabled, always return the default identity.
// if they are forcing the UI, return an error, otherwise succeed and
// send the message back that identities are disabled.
if (MU_IdentitiesDisabled()) { if (!!(dwFlags & UIL_FORCE_UI)) return E_IDENTITIES_DISABLED;
hr = GetIdentityByCookie((GUID *)&UID_GIBC_DEFAULT_USER, ppIdentity); return (SUCCEEDED(hr) ? S_IDENTITIES_DISABLED : hr); }
if (!g_hMutex) return E_UNEXPECTED;
_LoadChangingIdentities();
if (g_uidOldUserId != GUID_NULL || g_uidNewUserId != GUID_NULL) { // we are in the middle of a switch
if (!g_fNotifyComplete) { // and we are not done checking to see if a switch is ok.
if (!!(dwFlags & UIL_FORCE_UI)) //if its a force ui, then just fail.
return E_IDENTITY_CHANGING;
//otherwise, we need to do something here, but since they could be
//calling Login from the notifier proc, this could create a deadlock,
//but returning either the old or the new could be wrong. Return the
//same error here unless we can come up with a better solution.
return E_IDENTITY_CHANGING; } }
DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(g_hMutex, 5000); g_fReleasedMutex = false; if (dwWaitResult == WAIT_TIMEOUT) { char szMsg[255], szTitle[63];
// someone else seems to have a login dialog up. Notify the user
// about this problem and bail.
if (!!(dwFlags & UIL_FORCE_UI)) { MLLoadStringA(idsSwitchInProgressSwitch, szMsg, ARRAYSIZE(szMsg)); MLLoadStringA(idsSwitchIdentities, szTitle, ARRAYSIZE(szTitle)); } else { MLLoadStringA(idsSwitchInProgressLaunch, szMsg, ARRAYSIZE(szMsg)); MLLoadStringA(idsIdentityLogin, szTitle, ARRAYSIZE(szTitle)); }
MessageBox(hwndParent, szMsg, szTitle, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
return E_UNEXPECTED; }
*ppIdentity = NULL; fGotUser = MU_GetUserInfo(NULL, &rUser); if (!fGotUser) { *rUser.szUsername = 0; ZeroMemory(&rUser.uidUserID, sizeof(GUID)); } lstrcpy(szOldUsername, rUser.szUsername);
// if we don't have to do the UI and there is a current
// user, then just return that identity
if (!(dwFlags & UIL_FORCE_UI) && fGotUser) { pIdentity = new CUserIdentity; if (!pIdentity) hr = E_OUTOFMEMORY;
if (pIdentity && SUCCEEDED(hr = pIdentity->InitFromUsername(rUser.szUsername))) *ppIdentity = pIdentity; } else { if (0 == *rUser.szUsername) { GUID uidStart;
MU_GetLoginOption(&uidStart); if (GUID_NULL != uidStart) { MU_GetUserInfo(&uidStart, &rUser); rUser.uidUserID = GUID_NULL; } }
if (MU_Login(hwndParent, dwFlags, rUser.szUsername)) { MLLoadStringA(idsLogoff, szLogoffName, sizeof(szLogoffName)); if (lstrcmp(szLogoffName, rUser.szUsername) == 0) { MLLoadStringA(idsConfirmLogoff, szRes, sizeof(szRes));
if (MessageBox(hwndParent, szRes, szLogoffName, MB_YESNO) == IDYES) { ReleaseMutex(g_hMutex); g_fReleasedMutex = true; Logoff(hwndParent); } } else { pIdentity = new CUserIdentity; if (pIdentity) { hr = pIdentity->InitFromUsername(rUser.szUsername);
if (SUCCEEDED(hr)) { pIdentity->GetCookie(&uidNewUserID);
hr = _SwitchToUser(&rUser.uidUserID, &uidNewUserID); *ppIdentity = pIdentity; }
if (FAILED(hr)) { UINT iMsgId = idsSwitchCancelled;
pIdentity->Release(); *ppIdentity = NULL;
SetForegroundWindow(hwndParent); // could switch on some error codes to set iMsgId to
// other error messages. For now, skip showing the
// message if a user did the cancelling
if (hr != E_USER_CANCELLED) MU_ShowErrorMessage(hwndParent, iMsgId, idsSwitchCancelCaption); } } } } else hr = E_USER_CANCELLED; }
if (!g_fReleasedMutex) ReleaseMutex(g_hMutex);
return hr; }
STDMETHODIMP CUserIdentityManager::Logoff(HWND hwndParent) { GUID uidToID = GUID_NULL; HRESULT hr; USERINFO rUser; BOOL fGotUser;
if (!g_hMutex) return E_UNEXPECTED;
DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(g_hMutex, INFINITE); if (dwWaitResult != WAIT_OBJECT_0) return E_UNEXPECTED;
fGotUser = MU_GetUserInfo(NULL, &rUser); if (!fGotUser) rUser.uidUserID = GUID_NULL;
// switch to the null user
hr = _SwitchToUser(&rUser.uidUserID, &uidToID);
if (FAILED(hr)) { UINT iMsgId = idsLogoutCancelled;
SetForegroundWindow(hwndParent); // could switch on some error codes to set iMsgId to
// other error messages. For now, skip showing the
// message if a user did the cancelling
if (hr != E_USER_CANCELLED) MU_ShowErrorMessage(hwndParent, iMsgId, idsSwitchCancelCaption); }
ReleaseMutex(g_hMutex);
return hr; }
STDMETHODIMP CUserIdentityManager::_SwitchToUser(GUID *puidFromUser, GUID *puidToUser) { TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1] = ""; HRESULT hr;
// switching to the same user is automatically OK.
if (*puidFromUser == *puidToUser) return S_OK;
// Set up the from and to users
g_uidOldUserId = *puidFromUser; g_uidNewUserId = *puidToUser; g_fNotifyComplete = FALSE; _PersistChangingIdentities(); if (*puidToUser != GUID_NULL) MU_UserIdToUsername(puidToUser, szUsername, CCH_USERNAME_MAX_LENGTH); // Notify window's that a switch is coming
if (SUCCEEDED(hr = _QueryProcessesCanSwitch())) { if (SUCCEEDED(hr = MU_SwitchToUser(szUsername))) { if (!g_fReleasedMutex) { g_fReleasedMutex = true; g_fNotifyComplete = true; ReleaseMutex(g_hMutex); } _NotifyIdentitiesSwitched(); } } g_fNotifyComplete = TRUE;
// clear these back out again
g_uidOldUserId = GUID_NULL; g_uidNewUserId = GUID_NULL; ClearChangingIdentities();
return hr; }
STDMETHODIMP CUserIdentityManager::GetIdentityByCookie(GUID *uidCookie, IUserIdentity **ppIdentity) { CUserIdentity *pIdentity; HRESULT hr = E_IDENTITY_NOT_FOUND; GUID uidUserCookie = *uidCookie;
*ppIdentity = NULL;
if (MU_IdentitiesDisabled()) { // if disabled, they can only get the default identity.
// if asking for the current, they will get the defalt.
// if asking for default by the constant or the default's guid, then succeed.
// otherwise return an error.
if (!MU_GetDefaultUserID(&uidUserCookie)) return E_IDENTITY_NOT_FOUND; if (UID_GIBC_CURRENT_USER == uidUserCookie) uidUserCookie = UID_GIBC_DEFAULT_USER;
if (!(uidUserCookie == uidUserCookie || UID_GIBC_DEFAULT_USER == uidUserCookie)) return E_IDENTITIES_DISABLED; }
if (uidUserCookie == UID_GIBC_DEFAULT_USER) { if (!MU_GetDefaultUserID(&uidUserCookie)) return E_IDENTITY_NOT_FOUND; } else if (uidUserCookie == UID_GIBC_CURRENT_USER) { if (!MU_GetCurrentUserID(&uidUserCookie)) return E_NO_CURRENT_IDENTITY; } else if (uidUserCookie == UID_GIBC_OUTGOING_USER) { _LoadChangingIdentities(); if (g_uidOldUserId == GUID_NULL) return E_IDENTITY_NOT_FOUND; else uidUserCookie = g_uidOldUserId; } else if (uidUserCookie == UID_GIBC_INCOMING_USER) { _LoadChangingIdentities(); if (g_uidNewUserId == GUID_NULL) return E_IDENTITY_NOT_FOUND; else uidUserCookie = g_uidNewUserId; }
pIdentity = new CUserIdentity; if (pIdentity) { hr = pIdentity->InitFromCookie(&uidUserCookie);
if (SUCCEEDED(hr)) *ppIdentity = pIdentity; else { // Cleanup
delete pIdentity; } }
return hr; }
STDMETHODIMP CUserIdentityManager::GetConnectionInterface(IID *pIID) { return E_NOTIMPL; }
STDMETHODIMP CUserIdentityManager::GetConnectionPointContainer(IConnectionPointContainer **ppCPC) { *ppCPC = NULL; return E_NOTIMPL; }
STDMETHODIMP CUserIdentityManager::Advise(IUnknown *pUnkSink, DWORD *pdwCookie) { HRESULT hr; EnterCriticalSection(&m_rCritSect);
AddRef();
if (!m_pAdviseRegistry) m_pAdviseRegistry = new CNotifierList; Assert(m_pAdviseRegistry);
if (m_pAdviseRegistry) { if (!m_fWndRegistered) _CreateWindowClass();
hr = m_pAdviseRegistry->Add(pUnkSink, pdwCookie); } else hr = E_OUTOFMEMORY;
LeaveCriticalSection(&m_rCritSect); return hr; }
STDMETHODIMP CUserIdentityManager::Unadvise(DWORD dwCookie) { HRESULT hr;
EnterCriticalSection(&m_rCritSect); if (m_pAdviseRegistry) { hr = m_pAdviseRegistry->RemoveCookie(dwCookie); } else hr = E_FAIL;
LeaveCriticalSection(&m_rCritSect);
Release(); return hr; } STDMETHODIMP CUserIdentityManager::EnumConnections(IEnumConnections **ppEnum) { *ppEnum = NULL; return E_NOTIMPL; }
STDMETHODIMP CUserIdentityManager::QuerySwitchIdentities() { HRESULT hr = S_OK; DWORD dwLength, dwIndex;
if (!m_pAdviseRegistry) return S_OK;
TraceCall("Identity - CUserIdentityManager::QuerySwitchIdentities");
dwLength = m_pAdviseRegistry->GetLength();
for (dwIndex = 0; dwIndex < dwLength; dwIndex++) { IUnknown *punk; IIdentityChangeNotify *pICNotify; if (SUCCEEDED(m_pAdviseRegistry->GetAtIndex(dwIndex, &punk)) && punk) { if (SUCCEEDED(punk->QueryInterface(IID_IIdentityChangeNotify, (void **)&pICNotify)) && pICNotify) { if (FAILED(hr = pICNotify->QuerySwitchIdentities())) { punk->Release(); pICNotify->Release(); goto exit; } pICNotify->Release(); } punk->Release(); } } exit: return hr; }
STDMETHODIMP CUserIdentityManager::NotifySwitchIdentities() { HRESULT hr = S_OK; DWORD dwLength, dwIndex;
if (!m_pAdviseRegistry) return S_OK;
TraceCall("Identity - CUserIdentityManager::NotifySwitchIdentities");
dwLength = m_pAdviseRegistry->GetLength();
for (dwIndex = 0; dwIndex < dwLength; dwIndex++) { IUnknown *punk; IIdentityChangeNotify *pICNotify; if (SUCCEEDED(m_pAdviseRegistry->GetAtIndex(dwIndex, &punk)) && punk) { if (SUCCEEDED(punk->QueryInterface(IID_IIdentityChangeNotify, (void **)&pICNotify)) && pICNotify) { if (FAILED(hr = pICNotify->SwitchIdentities())) { punk->Release(); pICNotify->Release(); goto exit; } pICNotify->Release(); } punk->Release(); } } exit: return hr; }
STDMETHODIMP CUserIdentityManager::_QueryProcessesCanSwitch() { HWND hWnd, hNextWnd = NULL; LRESULT lResult; HWND *prghwnd = NULL; DWORD chwnd = 0, cAllocHwnd = 0, dw; HRESULT hr;
TraceCall("Identity - CUserIdentityManager::_QueryProcessesCanSwitch");
cAllocHwnd = 10; if (!MemAlloc((LPVOID*)(&prghwnd), cAllocHwnd * sizeof(HWND))) return E_OUTOFMEMORY;
hWnd = GetTopWindow(NULL); while (hWnd) { hNextWnd = GetNextWindow(hWnd, GW_HWNDNEXT); if (!IsWindowVisible(hWnd)) { TCHAR szWndClassName[255];
GetClassName(hWnd, szWndClassName, sizeof(szWndClassName)); if (lstrcmp(szWndClassName, c_szNotifyWindowClass) == 0) { if (chwnd == cAllocHwnd) { cAllocHwnd += 10; if (!MemRealloc((LPVOID*)(&prghwnd), cAllocHwnd * sizeof(HWND))) { hr = E_OUTOFMEMORY; goto exit; } } prghwnd[chwnd++] = hWnd; } }
hWnd = hNextWnd; } hr = S_OK; for (dw = 0; dw < chwnd; dw++) { if (IsWindow(prghwnd[dw])) { lResult = SendMessage(prghwnd[dw], WM_QUERY_IDENTITY_CHANGE, 0, 0); if (FAILED((HRESULT)lResult)) { hr = (HRESULT)lResult; goto exit; } } } exit: MemFree(prghwnd); prghwnd = NULL; return hr; }
STDMETHODIMP CUserIdentityManager::_NotifyIdentitiesSwitched() { HWND hWnd, hNextWnd = NULL; LRESULT lResult; HWND *prghwnd = NULL; DWORD chwnd = 0, cAllocHwnd = 0, dw;
TraceCall("Identity - CUserIdentityManager::_NotifyIdentitiesSwitched");
cAllocHwnd = 10; if (!MemAlloc((LPVOID*)(&prghwnd), cAllocHwnd * sizeof(HWND))) return E_OUTOFMEMORY;
hWnd = GetTopWindow(NULL); while (hWnd) { hNextWnd = GetNextWindow(hWnd, GW_HWNDNEXT); if (!IsWindowVisible(hWnd)) { TCHAR szWndClassName[255];
GetClassName(hWnd, szWndClassName, sizeof(szWndClassName)); if (lstrcmp(szWndClassName, c_szNotifyWindowClass) == 0) { if (chwnd == cAllocHwnd) { cAllocHwnd += 10; if (!MemRealloc((LPVOID*)(&prghwnd), cAllocHwnd * sizeof(HWND))) goto exit; } prghwnd[chwnd++] = hWnd; } }
hWnd = hNextWnd; } for (dw = 0; dw < chwnd; dw++) { DWORD_PTR dwResult; if (IsWindow(prghwnd[dw])) // lResult = PostMessage(prghwnd[dw], WM_IDENTITY_CHANGED, 0, 0); //Raid 48054
SendMessageTimeout(prghwnd[dw], WM_IDENTITY_CHANGED, 0, 0, SMTO_ABORTIFHUNG | SMTO_NORMAL, 1500, &dwResult); } exit: MemFree(prghwnd); prghwnd = NULL; return S_OK; }
STDMETHODIMP CUserIdentityManager::_CreateWindowClass() { WNDCLASS wc; if (!m_fWndRegistered) /*set up window class and register it */ { wc.lpszClassName = c_szNotifyWindowClass; wc.hInstance = g_hInst; wc.lpfnWndProc = CUserIdentityManager::WndProc; wc.hCursor = NULL; wc.hIcon = NULL; wc.lpszMenuName = NULL; wc.hbrBackground = NULL; wc.style = CS_DBLCLKS; wc.cbClsExtra = 0; wc.cbWndExtra = 0;
if (!RegisterClassA(&wc)) return E_FAIL;
m_fWndRegistered = TRUE; }
return S_OK; }
LRESULT CALLBACK CUserIdentityManager::WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam) { CNotifierList *pList = NULL; HRESULT hr;
if (messg == WM_QUERY_IDENTITY_CHANGE || messg == WM_IDENTITY_CHANGED || messg == WM_IDENTITY_INFO_CHANGED) { #if defined(DEBUG)
DebugStrf("Identity - CUserIdentityManager::WndProc() called for notification.\r\n"); #endif
pList = (CNotifierList *)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (pList) { hr = pList->SendNotification(messg, (DWORD)lParam); return hr; } } else { switch(messg) { case WM_CREATE: LPCREATESTRUCT pcs;
pcs = (LPCREATESTRUCT)lParam; SetWindowLongPtr(hWnd, GWLP_USERDATA, (LRESULT)pcs->lpCreateParams); return(DefWindowProc(hWnd, messg, wParam, lParam)); break; /*
case WM_QUERY_IDENTITY_CHANGE: case WM_IDENTITY_CHANGED: case WM_IDENTITY_INFO_CHANGED: DebugStrf("Identity - CUserIdentityManager::WndProc() called for notification.\r\n"); pList = (CNotifierList *)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (pList) { hr = pList->SendNotification(messg, (DWORD)lParam); return hr; } break; */ case WM_CLOSE: SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); return(DefWindowProc(hWnd, messg, wParam, lParam)); break;
default: return(DefWindowProc(hWnd, messg, wParam, lParam)); } } return 0; }
//----------------------------------------------------------------------------
// Logon the specified user.
// - Checks password
//----------------------------------------------------------------------------
STDMETHODIMP CUserIdentityManager::LogonAs(WCHAR *pszName, WCHAR *pszPassword, IUserIdentity **ppIdentity) { CUserIdentity *pIdentity; HRESULT hr = E_FAIL; USERINFO rUser; GUID uidNewUserID; BOOL fGotUser; TCHAR szName[CCH_USERNAME_MAX_LENGTH+1];
if (WideCharToMultiByte(CP_ACP, 0, pszName, -1, szName, CCH_USERNAME_MAX_LENGTH, NULL, NULL) == 0) { return E_FAIL; }
// if identities are disabled, always return the default identity.
if (MU_IdentitiesDisabled()) { hr = GetIdentityByCookie((GUID *)&UID_GIBC_DEFAULT_USER, ppIdentity); return (SUCCEEDED(hr) ? S_IDENTITIES_DISABLED : hr); }
if (!g_hMutex) return E_UNEXPECTED;
if (g_uidOldUserId != GUID_NULL || g_uidOldUserId != GUID_NULL) { // we are in the middle of a switch
if (!g_fNotifyComplete) { return E_IDENTITY_CHANGING; } }
*ppIdentity = NULL;
//
// Grab info on the current user
//
fGotUser = MU_GetUserInfo(NULL, &rUser); if (!fGotUser) { *rUser.szUsername = 0; ZeroMemory(&rUser.uidUserID, sizeof(GUID)); }
if (0 == *rUser.szUsername) { GUID uidStart;
MU_GetLoginOption(&uidStart); if (GUID_NULL != uidStart) { MU_GetUserInfo(&uidStart, &rUser); rUser.uidUserID = GUID_NULL; } }
pIdentity = new CUserIdentity; if (pIdentity) { hr = pIdentity->InitFromUsername(szName); if (SUCCEEDED(hr)) { pIdentity->GetCookie(&uidNewUserID); hr= ConfirmPassword(&uidNewUserID, pszPassword); if (SUCCEEDED(hr)) { hr = _SwitchToUser(&rUser.uidUserID, &uidNewUserID);
if (SUCCEEDED(hr)) { *ppIdentity = pIdentity; } else { UINT iMsgId = idsSwitchCancelled;
pIdentity->Release(); *ppIdentity = NULL;
// could switch on some error codes to set iMsgId to
// other error messages. For now, skip showing the
// message if a user did the cancelling
if (hr != E_USER_CANCELLED) MU_ShowErrorMessage(NULL, iMsgId, idsSwitchCancelCaption); } } // ConfirmPassword()
} // InitFromUsername()
}
if (!g_fReleasedMutex) ReleaseMutex(g_hMutex);
return hr; }
|