//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1993 - 1999. // // File: CLocalMachine.cpp // // Contents: implementation of CLocalMachine // //---------------------------------------------------------------------------- #include "priv.h" #include "UserOM.h" #include "LogonIPC.h" #include "CInteractiveLogon.h" #include "WinUser.h" #include "trayp.h" // for TM_REFRESH #include // for NetUserModalsGet #include // for NetApiBufferFree #include // for NERR_Success #include #include // // IUnknown Interface // ULONG CLocalMachine::AddRef() { _cRef++; return _cRef; } ULONG CLocalMachine::Release() { ASSERT(_cRef > 0); _cRef--; if (_cRef > 0) { return _cRef; } delete this; return 0; } HRESULT CLocalMachine::QueryInterface(REFIID riid, void **ppvObj) { static const QITAB qit[] = { QITABENT(CLocalMachine, IDispatch), QITABENT(CLocalMachine, ILocalMachine), {0}, }; return QISearch(this, qit, riid, ppvObj); } // // IDispatch Interface // STDMETHODIMP CLocalMachine::GetTypeInfoCount(UINT* pctinfo) { return CIDispatchHelper::GetTypeInfoCount(pctinfo); } STDMETHODIMP CLocalMachine::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return CIDispatchHelper::GetTypeInfo(itinfo, lcid, pptinfo); } STDMETHODIMP CLocalMachine::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { return CIDispatchHelper::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); } STDMETHODIMP CLocalMachine::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { return CIDispatchHelper::Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); } // // ILocalMachine Interface // STDMETHODIMP CLocalMachine::get_MachineName(VARIANT* pvar) { HRESULT hr; DWORD cch; WCHAR szMachineName[MAX_COMPUTERNAME_LENGTH+1]; if (pvar) { pvar->vt = VT_BSTR; cch = MAX_COMPUTERNAME_LENGTH+1; if (GetComputerNameW(szMachineName, &cch)) { pvar->bstrVal = SysAllocString(szMachineName); } else { pvar->bstrVal = SysAllocString(TEXT("")); } hr = S_OK; } else { hr = E_INVALIDARG; } return hr; } DWORD BuildAccountSidFromRid(LPCWSTR pszServer, DWORD dwRid, PSID* ppSid) { DWORD dwErr = ERROR_SUCCESS; PUSER_MODALS_INFO_2 umi2; NET_API_STATUS nasRet; // Get the account domain Sid on the target machine nasRet = NetUserModalsGet(pszServer, 2, (LPBYTE*)&umi2); if ( nasRet == NERR_Success ) { UCHAR cSubAuthorities; PSID pSid; cSubAuthorities = *GetSidSubAuthorityCount(umi2->usrmod2_domain_id); // Allocate storage for new the Sid (domain Sid + account Rid) pSid = (PSID)LocalAlloc(LPTR, GetSidLengthRequired((UCHAR)(cSubAuthorities+1))); if ( pSid != NULL ) { if ( InitializeSid(pSid, GetSidIdentifierAuthority(umi2->usrmod2_domain_id), (BYTE)(cSubAuthorities+1)) ) { // Copy existing subauthorities from domain Sid to new Sid for (UINT i = 0; i < cSubAuthorities; i++) { *GetSidSubAuthority(pSid, i) = *GetSidSubAuthority(umi2->usrmod2_domain_id, i); } // Append Rid to new Sid *GetSidSubAuthority(pSid, cSubAuthorities) = dwRid; *ppSid = pSid; } else { dwErr = GetLastError(); LocalFree(pSid); } } else { dwErr = GetLastError(); } NetApiBufferFree(umi2); } else { dwErr = nasRet; } return dwErr; } BYTE s_rgbGuestSid[sizeof(SID) + (SID_MAX_SUB_AUTHORITIES-1)*sizeof(ULONG)] = {0}; DWORD GetGuestSid(PSID* ppSid) { DWORD dwErr = ERROR_SUCCESS; if (0 == *GetSidSubAuthorityCount((PSID)s_rgbGuestSid)) { PSID pSid = NULL; dwErr = BuildAccountSidFromRid(NULL, DOMAIN_USER_RID_GUEST, &pSid); if (ERROR_SUCCESS == dwErr) { CopySid(sizeof(s_rgbGuestSid), (PSID)s_rgbGuestSid, pSid); LocalFree(pSid); } } // There is no need to free the returned PSID (static buffer) *ppSid = (PSID)s_rgbGuestSid; return dwErr; } WCHAR s_szGuest[UNLEN + sizeof('\0')] = L""; LPCWSTR GetGuestAccountName(void) { if (s_szGuest[0] == L'\0') { DWORD dwGuestSize, dwDomainSize; WCHAR szDomain[DNLEN + sizeof('\0')]; PSID pSID; SID_NAME_USE eUse; dwGuestSize = ARRAYSIZE(s_szGuest); dwDomainSize = ARRAYSIZE(szDomain); if ((ERROR_SUCCESS != GetGuestSid(&pSID)) || !LookupAccountSidW(NULL, pSID, s_szGuest, &dwGuestSize, szDomain, &dwDomainSize, &eUse)) { // Huh? No Guest account on this machine. Try English. lstrcpyW(s_szGuest, L"Guest"); // Try to go the other way and lookup the SID. // If this fails, we're SOL. *GetSidSubAuthorityCount((PSID)s_rgbGuestSid) = 0; dwGuestSize = sizeof(s_rgbGuestSid); dwDomainSize = ARRAYSIZE(szDomain); LookupAccountNameW(NULL, s_szGuest, (PSID)s_rgbGuestSid, &dwGuestSize, szDomain, &dwDomainSize, &eUse); } } return(s_szGuest); } STDMETHODIMP CLocalMachine::get_isGuestEnabled(ILM_GUEST_FLAGS flags, VARIANT_BOOL* pbEnabled) { HRESULT hr = S_OK; DWORD dwErr; BOOL bEnabled = FALSE; USER_INFO_1 *pusri1 = NULL; DWORD dwFlags = (DWORD)(flags & (ILM_GUEST_INTERACTIVE_LOGON | ILM_GUEST_NETWORK_LOGON)); if (NULL == pbEnabled) return E_POINTER; // First check to see if the guest account is truly enabled dwErr = NetUserGetInfo(NULL, GetGuestAccountName(), 1, (LPBYTE*)&pusri1); if ((ERROR_SUCCESS == dwErr) && ((pusri1->usri1_flags & UF_ACCOUNTDISABLE) == 0)) { // Guest is enabled bEnabled = TRUE; // Do they want to check the LSA logon rights? if (0 != dwFlags) { BOOL bDenyInteractiveLogon = FALSE; BOOL bDenyNetworkLogon = FALSE; LSA_HANDLE hLsa; LSA_OBJECT_ATTRIBUTES oa = {0}; oa.Length = sizeof(oa); dwErr = LsaNtStatusToWinError(LsaOpenPolicy(NULL, &oa, POLICY_LOOKUP_NAMES, &hLsa)); if (ERROR_SUCCESS == dwErr) { PSID pSid; dwErr = GetGuestSid(&pSid); if (ERROR_SUCCESS == dwErr) { PLSA_UNICODE_STRING pAccountRights; ULONG cRights; // Get the list of LSA rights assigned to the Guest account // // Note that SE_INTERACTIVE_LOGON_NAME is often inherited via // group membership, so its absence doesn't mean much. We could // bend over backwards and check group membership and such, but // Guest normally gets SE_INTERACTIVE_LOGON_NAME one way or // another, so we only check for SE_DENY_INTERACTIVE_LOGON_NAME // here. dwErr = LsaNtStatusToWinError(LsaEnumerateAccountRights(hLsa, pSid, &pAccountRights, &cRights)); if (ERROR_SUCCESS == dwErr) { PLSA_UNICODE_STRING pRight; for (pRight = pAccountRights; cRights > 0 && 0 != dwFlags; pRight++, cRights--) { if (0 != (dwFlags & ILM_GUEST_INTERACTIVE_LOGON) && CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, SE_DENY_INTERACTIVE_LOGON_NAME, -1, pRight->Buffer, pRight->Length/2)) { bDenyInteractiveLogon = TRUE; dwFlags &= ~ILM_GUEST_INTERACTIVE_LOGON; } else if (0 != (dwFlags & ILM_GUEST_NETWORK_LOGON) && CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, SE_DENY_NETWORK_LOGON_NAME, -1, pRight->Buffer, pRight->Length/2)) { bDenyNetworkLogon = TRUE; dwFlags &= ~ILM_GUEST_NETWORK_LOGON; } } LsaFreeMemory(pAccountRights); } else if (ERROR_FILE_NOT_FOUND == dwErr) { // Guest isn't in LSA's database, so we know it can't // have either of the deny logon rights. dwErr = ERROR_SUCCESS; } } LsaClose(hLsa); } if (bDenyInteractiveLogon || bDenyNetworkLogon) bEnabled = FALSE; } } if (NULL != pusri1) { (NET_API_STATUS)NetApiBufferFree(pusri1); } hr = HRESULT_FROM_WIN32(dwErr); *pbEnabled = bEnabled ? VARIANT_TRUE : VARIANT_FALSE; return hr; } STDMETHODIMP CLocalMachine::EnableGuest(ILM_GUEST_FLAGS flags) { DWORD dwErr; USER_INFO_1 *pusri1; DWORD dwFlags = (DWORD)(flags & (ILM_GUEST_INTERACTIVE_LOGON | ILM_GUEST_NETWORK_LOGON)); // First truly enable the guest account. Do this ALL the time. dwErr = NetUserGetInfo(NULL, GetGuestAccountName(), 1, (LPBYTE*)&pusri1); if (ERROR_SUCCESS == dwErr) { pusri1->usri1_flags &= ~UF_ACCOUNTDISABLE; dwErr = NetUserSetInfo(NULL, GetGuestAccountName(), 1, (LPBYTE)pusri1, NULL); if (ERROR_SUCCESS == dwErr && 0 != dwFlags) { LSA_HANDLE hLsa; LSA_OBJECT_ATTRIBUTES oa = {0}; oa.Length = sizeof(oa); dwErr = LsaNtStatusToWinError(LsaOpenPolicy(NULL, &oa, POLICY_LOOKUP_NAMES, &hLsa)); if (ERROR_SUCCESS == dwErr) { PSID pSid; dwErr = GetGuestSid(&pSid); if (ERROR_SUCCESS == dwErr) { if (0 != (dwFlags & ILM_GUEST_INTERACTIVE_LOGON)) { DECLARE_CONST_UNICODE_STRING(usDenyLogon, SE_DENY_INTERACTIVE_LOGON_NAME); NTSTATUS status = LsaRemoveAccountRights(hLsa, pSid, FALSE, (PLSA_UNICODE_STRING)&usDenyLogon, 1); dwErr = LsaNtStatusToWinError(status); } if (0 != (dwFlags & ILM_GUEST_NETWORK_LOGON)) { DECLARE_CONST_UNICODE_STRING(usDenyLogon, SE_DENY_NETWORK_LOGON_NAME); NTSTATUS status = LsaRemoveAccountRights(hLsa, pSid, FALSE, (PLSA_UNICODE_STRING)&usDenyLogon, 1); if (ERROR_SUCCESS == dwErr) dwErr = LsaNtStatusToWinError(status); } if (ERROR_FILE_NOT_FOUND == dwErr) { // // NTRAID#NTBUG9-396428-2001/05/16-jeffreys // // This means Guest isn't in LSA's database, so we know // it can't have either of the deny logon rights. Since // we were trying to remove one or both rights, count // this as success. // dwErr = ERROR_SUCCESS; } } LsaClose(hLsa); } } (NET_API_STATUS)NetApiBufferFree(pusri1); } return HRESULT_FROM_WIN32(dwErr); } STDMETHODIMP CLocalMachine::DisableGuest(ILM_GUEST_FLAGS flags) { DWORD dwErr = ERROR_SUCCESS; DWORD dwFlags = (DWORD)(flags & (ILM_GUEST_INTERACTIVE_LOGON | ILM_GUEST_NETWORK_LOGON)); if (0 != dwFlags) { LSA_HANDLE hLsa; LSA_OBJECT_ATTRIBUTES oa = {0}; // Turn on DenyInteractiveLogon and/or DenyNetworkLogon, but don't // necessarily change the enabled state of the guest account. oa.Length = sizeof(oa); dwErr = LsaNtStatusToWinError(LsaOpenPolicy(NULL, &oa, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &hLsa)); if (ERROR_SUCCESS == dwErr) { PSID pSid; dwErr = GetGuestSid(&pSid); if (ERROR_SUCCESS == dwErr) { if (0 != (dwFlags & ILM_GUEST_INTERACTIVE_LOGON)) { DECLARE_CONST_UNICODE_STRING(usDenyLogon, SE_DENY_INTERACTIVE_LOGON_NAME); NTSTATUS status = LsaAddAccountRights(hLsa, pSid, (PLSA_UNICODE_STRING)&usDenyLogon, 1); dwErr = LsaNtStatusToWinError(status); } if (0 != (dwFlags & ILM_GUEST_NETWORK_LOGON)) { DECLARE_CONST_UNICODE_STRING(usDenyLogon, SE_DENY_NETWORK_LOGON_NAME); NTSTATUS status = LsaAddAccountRights(hLsa, pSid, (PLSA_UNICODE_STRING)&usDenyLogon, 1); if (ERROR_SUCCESS == dwErr) dwErr = LsaNtStatusToWinError(status); } } LsaClose(hLsa); } if (ERROR_SUCCESS == dwErr) { // If both SE_DENY_INTERACTIVE_LOGON_NAME and SE_DENY_NETWORK_LOGON_NAME // are turned on, then we might as well disable the account altogether. if ((ILM_GUEST_INTERACTIVE_LOGON | ILM_GUEST_NETWORK_LOGON) == dwFlags) { // We just turned both on, so disable guest below dwFlags = 0; } else { VARIANT_BOOL bEnabled; if (ILM_GUEST_INTERACTIVE_LOGON == dwFlags) { // We just turned on SE_DENY_INTERACTIVE_LOGON_NAME, check // for SE_DENY_NETWORK_LOGON_NAME. flags = ILM_GUEST_NETWORK_LOGON; } else if (ILM_GUEST_NETWORK_LOGON == dwFlags) { // We just turned on SE_DENY_NETWORK_LOGON_NAME, check // for SE_DENY_INTERACTIVE_LOGON_NAME. flags = ILM_GUEST_INTERACTIVE_LOGON; } else { // Getting here implies that someone defined a new flag. // Setting flags to ILM_GUEST_ACCOUNT causes a benign // result in all cases (we only disable guest if guest // is already disabled). flags = ILM_GUEST_ACCOUNT; } if (SUCCEEDED(get_isGuestEnabled(flags, &bEnabled)) && (VARIANT_FALSE == bEnabled)) { // Both are on, so disable guest below dwFlags = 0; } } } } if (0 == dwFlags) { USER_INFO_1 *pusri1; // Truly disable the guest account. dwErr = NetUserGetInfo(NULL, GetGuestAccountName(), 1, (LPBYTE*)&pusri1); if (ERROR_SUCCESS == dwErr) { pusri1->usri1_flags |= UF_ACCOUNTDISABLE; dwErr = NetUserSetInfo(NULL, GetGuestAccountName(), 1, (LPBYTE)pusri1, NULL); (NET_API_STATUS)NetApiBufferFree(pusri1); } } return HRESULT_FROM_WIN32(dwErr); } STDMETHODIMP CLocalMachine::get_isFriendlyUIEnabled(VARIANT_BOOL* pbEnabled) { *pbEnabled = ShellIsFriendlyUIActive() ? VARIANT_TRUE : VARIANT_FALSE; return(S_OK); } STDMETHODIMP CLocalMachine::put_isFriendlyUIEnabled(VARIANT_BOOL bEnabled) { HRESULT hr; if (ShellEnableFriendlyUI(bEnabled != VARIANT_FALSE ? TRUE : FALSE) != FALSE) { RefreshStartMenu(); hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } return(hr); } STDMETHODIMP CLocalMachine::get_isMultipleUsersEnabled(VARIANT_BOOL* pbEnabled) { *pbEnabled = ShellIsMultipleUsersEnabled() ? VARIANT_TRUE : VARIANT_FALSE; return(S_OK); } STDMETHODIMP CLocalMachine::put_isMultipleUsersEnabled(VARIANT_BOOL bEnabled) { HRESULT hr; if (ShellEnableMultipleUsers(bEnabled != VARIANT_FALSE ? TRUE : FALSE) != FALSE) { RefreshStartMenu(); hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } return(hr); } STDMETHODIMP CLocalMachine::get_isRemoteConnectionsEnabled(VARIANT_BOOL* pbEnabled) { *pbEnabled = ShellIsRemoteConnectionsEnabled() ? VARIANT_TRUE : VARIANT_FALSE; return(S_OK); } STDMETHODIMP CLocalMachine::put_isRemoteConnectionsEnabled(VARIANT_BOOL bEnabled) { HRESULT hr; if (ShellEnableRemoteConnections(bEnabled != VARIANT_FALSE ? TRUE : FALSE) != FALSE) { RefreshStartMenu(); hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } return(hr); } BOOL _CanEject() { BOOL fEjectAllowed = FALSE; if(SHRestricted(REST_NOSMEJECTPC)) //Is there a policy restriction? return FALSE; CM_Is_Dock_Station_Present(&fEjectAllowed); return SHTestTokenPrivilege(NULL, SE_UNDOCK_NAME) && fEjectAllowed && !GetSystemMetrics(SM_REMOTESESSION); } STDMETHODIMP CLocalMachine::get_isUndockEnabled(VARIANT_BOOL* pbEnabled) { CLogonIPC objLogon; if (objLogon.IsLogonServiceAvailable()) { *pbEnabled = objLogon.TestEjectAllowed() ? VARIANT_TRUE : VARIANT_FALSE; } else { *pbEnabled = _CanEject() ? VARIANT_TRUE : VARIANT_FALSE; } return(S_OK); } STDMETHODIMP CLocalMachine::get_isShutdownAllowed(VARIANT_BOOL* pbShutdownAllowed) { CLogonIPC objLogon; if (objLogon.IsLogonServiceAvailable()) { *pbShutdownAllowed = objLogon.TestShutdownAllowed() ? VARIANT_TRUE : VARIANT_FALSE; } else { *pbShutdownAllowed = VARIANT_FALSE; } return(S_OK); } STDMETHODIMP CLocalMachine::get_isGuestAccessMode(VARIANT_BOOL* pbForceGuest) { *pbForceGuest = SUCCEEDED(_IsGuestAccessMode()) ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; } STDMETHODIMP CLocalMachine::get_isOfflineFilesEnabled(VARIANT_BOOL *pbEnabled) { HRESULT hr = S_OK; *pbEnabled = VARIANT_FALSE; HINSTANCE hInstCscdll = LoadLibrary(TEXT("cscdll.dll")); if (NULL != hInstCscdll) { typedef BOOL (WINAPI *LPCSCENABLED)(void); LPCSCENABLED pfnCscEnabled = (LPCSCENABLED)GetProcAddress(hInstCscdll, "CSCIsCSCEnabled"); if (NULL != pfnCscEnabled) { if ((*pfnCscEnabled)()) { *pbEnabled = VARIANT_TRUE; } } else { hr = ResultFromLastError(); } FreeLibrary(hInstCscdll); } else { hr = ResultFromLastError(); } return hr; } WCHAR s_szAdmin[UNLEN + sizeof('\0')] = L""; LPCWSTR GetAdminAccountName(void) { if (s_szAdmin[0] == L'\0') { BOOL bSuccess = FALSE; PSID pSid; if (ERROR_SUCCESS == BuildAccountSidFromRid(NULL, DOMAIN_USER_RID_ADMIN, &pSid)) { DWORD dwAdminSize, dwDomainSize; WCHAR szDomain[DNLEN + sizeof('\0')]; SID_NAME_USE eUse; dwAdminSize = ARRAYSIZE(s_szAdmin); dwDomainSize = ARRAYSIZE(szDomain); bSuccess = LookupAccountSidW(NULL, pSid, s_szAdmin, &dwAdminSize, szDomain, &dwDomainSize, &eUse); LocalFree(pSid); } if (!bSuccess) { lstrcpyW(s_szAdmin, L"Administrator"); } } return(s_szAdmin); } STDMETHODIMP CLocalMachine::get_AccountName(VARIANT varAccount, VARIANT* pvar) { DWORD dwRID = 0; LPCWSTR pszName = NULL; if (NULL == pvar) return E_POINTER; switch (varAccount.vt) { case VT_I4: case VT_UI4: dwRID = varAccount.ulVal; break; case VT_BSTR: if (0 == StrCmpIW(varAccount.bstrVal, L"Guest")) dwRID = DOMAIN_USER_RID_GUEST; else if (0 == StrCmpIW(varAccount.bstrVal, L"Administrator")) dwRID = DOMAIN_USER_RID_ADMIN; else return E_INVALIDARG; break; default: return E_INVALIDARG; } switch (dwRID) { case DOMAIN_USER_RID_GUEST: pszName = GetGuestAccountName(); break; case DOMAIN_USER_RID_ADMIN: pszName = GetAdminAccountName(); break; default: return E_INVALIDARG; } pvar->vt = VT_BSTR; pvar->bstrVal = SysAllocString(pszName); return(S_OK); } STDMETHODIMP CLocalMachine::TurnOffComputer() { HRESULT hr; CLogonIPC objLogon; if (!objLogon.IsLogonServiceAvailable()) { return E_FAIL; } if (objLogon.TurnOffComputer ()) hr = S_OK; else hr = E_FAIL; return hr; } STDMETHODIMP CLocalMachine::UndockComputer() { HRESULT hr; CLogonIPC objLogon; if (!objLogon.IsLogonServiceAvailable()) { return E_FAIL; } if (objLogon.EjectComputer()) hr = S_OK; else hr = E_FAIL; return hr; } STDMETHODIMP CLocalMachine::SignalUIHostFailure() { CLogonIPC objLogon; if (!objLogon.IsLogonServiceAvailable()) { return E_FAIL; } objLogon.SignalUIHostFailure (); return S_OK; } STDMETHODIMP CLocalMachine::AllowExternalCredentials() { CLogonIPC objLogon; if (!objLogon.IsLogonServiceAvailable()) { return E_FAIL; } if (!objLogon.AllowExternalCredentials ()) { return E_NOTIMPL; } else { return S_OK; } } STDMETHODIMP CLocalMachine::RequestExternalCredentials() { CLogonIPC objLogon; if (!objLogon.IsLogonServiceAvailable()) { return E_FAIL; } objLogon.RequestExternalCredentials (); return S_OK; } STDMETHODIMP CLocalMachine::LogonWithExternalCredentials(BSTR pstrUsername, BSTR pstrDomain, BSTR pstrPassword, VARIANT_BOOL* pbRet) { HRESULT hr; CLogonIPC objLogon; TCHAR szUsername[UNLEN + sizeof('\0')], szDomain[DNLEN + sizeof('\0')], szPassword[PWLEN + sizeof('\0')]; if (pstrUsername) { lstrcpyn(szUsername, pstrUsername, ARRAYSIZE(szUsername)); } else { szUsername[0] = TEXT('\0'); } if (pstrDomain) { lstrcpyn(szDomain, pstrDomain, ARRAYSIZE(szDomain)); } else { szDomain[0] = TEXT('\0'); } if (pstrPassword) { lstrcpyn(szPassword, pstrPassword, ARRAYSIZE(szPassword)); } else { szPassword[0] = TEXT('\0'); } if (!objLogon.IsLogonServiceAvailable()) { *pbRet = VARIANT_FALSE; return S_OK; } if (objLogon.LogUserOn (szUsername, szDomain, szPassword)) *pbRet = VARIANT_TRUE; else *pbRet = VARIANT_FALSE; if (*pbRet) { hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } return hr; } // -------------------------------------------------------------------------- // CLocalMachine::InitiateInteractiveLogon // // Arguments: pstrUsername = User name. // pstrDomain = Domain. // pstrPassword = Password (in clear text). // pbRet = Result (returned). // // Returns: HRESULT // // Purpose: Send a request for interactive logon using CInteractiveLogon. // It's magic. I don't care how it works. // // History: 2000-12-06 vtan created // -------------------------------------------------------------------------- STDMETHODIMP CLocalMachine::InitiateInteractiveLogon(BSTR pstrUsername, BSTR pstrDomain, BSTR pstrPassword, DWORD dwTimeout, VARIANT_BOOL* pbRet) { DWORD dwErrorCode; dwErrorCode = CInteractiveLogon::Initiate(pstrUsername, pstrDomain, pstrPassword, dwTimeout); *pbRet = (ERROR_SUCCESS == dwErrorCode) ? VARIANT_TRUE : VARIANT_FALSE; return(HRESULT_FROM_WIN32(dwErrorCode)); } // -------------------------------------------------------------------------- // CLocalMachine::RefreshStartMenu // // Arguments: // // Returns: // // Purpose: Finds the shell tray window and sends it a message to refresh // its contents. // // History: 2000-08-01 vtan created // -------------------------------------------------------------------------- void CLocalMachine::RefreshStartMenu (void) { HWND hwndTray; hwndTray = FindWindow(TEXT("Shell_TrayWnd"), NULL); if (hwndTray != NULL) { TBOOL(PostMessage(hwndTray, TM_REFRESH, 0, 0)); } } CLocalMachine::CLocalMachine() : _cRef(1), CIDispatchHelper(&IID_ILocalMachine, &LIBID_SHGINALib) { DllAddRef(); } CLocalMachine::~CLocalMachine() { ASSERT(_cRef == 0); DllRelease(); } STDAPI CLocalMachine_Create(REFIID riid, LPVOID* ppv) { HRESULT hr = E_OUTOFMEMORY; CLocalMachine* pLocalMachine = new CLocalMachine(); if (pLocalMachine) { hr = pLocalMachine->QueryInterface(riid, ppv); pLocalMachine->Release(); } return hr; }