Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
multiusr.cpp
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 55k
Category:
Windows Kernel
Development Platform:
Visual C++
- /*******************************************************
- MultiUsr.cpp
- Code for handling multiple user functionality in IE
- and friends
- Initially by Christopher Evans (cevans) 4/28/98
- ********************************************************/
- #define DONT_WANT_SHELLDEBUG
- #include "private.h"
- #include "resource.h"
- #include "multiusr.h"
- #include <assert.h>
- #include "multiutl.h"
- #include "strconst.h"
- #include "Shlwapi.h"
- #include "multiui.h"
- #include <shlobj.h>
- #include "mluisup.h"
- #include <lmwksta.h>
- TCHAR g_szRegRoot[MAX_PATH] = "";
- extern HINSTANCE g_hInst;
- static void _CreateIdentitiesFolder();
- // add a backslash to a qualified path
- //
- // in:
- // lpszPath path (A:, C:foo, etc)
- //
- // out:
- // lpszPath A:, C:foo ;
- //
- // returns:
- // pointer to the NULL that terminates the path
- // this is here to avoid a dependancy on shlwapi.dll
- #define CH_WHACK TEXT('\')
- STDAPI_(LPTSTR)
- _PathAddBackslash(
- LPTSTR lpszPath)
- {
- LPTSTR lpszEnd;
- // perf: avoid lstrlen call for guys who pass in ptr to end
- // of buffer (or rather, EOB - 1).
- // note that such callers need to check for overflow themselves.
- int ichPath = (*lpszPath && !*(lpszPath + 1)) ? 1 : lstrlen(lpszPath);
- // try to keep us from tromping over MAX_PATH in size.
- // if we find these cases, return NULL. Note: We need to
- // check those places that call us to handle their GP fault
- // if they try to use the NULL!
- if (ichPath >= (MAX_PATH - 1))
- {
- Assert(FALSE); // Let the caller know!
- return(NULL);
- }
- lpszEnd = lpszPath + ichPath;
- // this is really an error, caller shouldn't pass
- // an empty string
- if (!*lpszPath)
- return lpszEnd;
- /* Get the end of the source directory
- */
- switch(*CharPrev(lpszPath, lpszEnd)) {
- case CH_WHACK:
- break;
- default:
- *lpszEnd++ = CH_WHACK;
- *lpszEnd = TEXT('');
- }
- return lpszEnd;
- }
- STDAPI_(DWORD)
- _SHGetValueA(
- IN HKEY hkey,
- IN LPCSTR pszSubKey, OPTIONAL
- IN LPCSTR pszValue, OPTIONAL
- OUT LPDWORD pdwType, OPTIONAL
- OUT LPVOID pvData, OPTIONAL
- OUT LPDWORD pcbData) OPTIONAL
- {
- DWORD dwRet;
- HKEY hkeyNew;
- dwRet = RegOpenKeyExA(hkey, pszSubKey, 0, KEY_QUERY_VALUE, &hkeyNew);
- if (NO_ERROR == dwRet)
- {
- dwRet = RegQueryValueEx(hkeyNew, pszValue, NULL, pdwType, (LPBYTE)pvData, pcbData);
- RegCloseKey(hkeyNew);
- }
- else if (pcbData)
- *pcbData = 0;
- return dwRet;
- }
- /*----------------------------------------------------------
- Purpose: Recursively delete the key, including all child values
- and keys. Mimics what RegDeleteKey does in Win95.
- Returns:
- Cond: --
- */
- DWORD
- _DeleteKeyRecursively(
- IN HKEY hkey,
- IN LPCSTR pszSubKey)
- {
- DWORD dwRet;
- HKEY hkSubKey;
- // Open the subkey so we can enumerate any children
- dwRet = RegOpenKeyExA(hkey, pszSubKey, 0, MAXIMUM_ALLOWED, &hkSubKey);
- if (ERROR_SUCCESS == dwRet)
- {
- DWORD dwIndex;
- CHAR szSubKeyName[MAX_PATH + 1];
- DWORD cchSubKeyName = ARRAYSIZE(szSubKeyName);
- CHAR szClass[MAX_PATH];
- DWORD cbClass = ARRAYSIZE(szClass);
- // I can't just call RegEnumKey with an ever-increasing index, because
- // I'm deleting the subkeys as I go, which alters the indices of the
- // remaining subkeys in an implementation-dependent way. In order to
- // be safe, I have to count backwards while deleting the subkeys.
- // Find out how many subkeys there are
- dwRet = RegQueryInfoKeyA(hkSubKey,
- szClass,
- &cbClass,
- NULL,
- &dwIndex, // The # of subkeys -- all we need
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- if (NO_ERROR == dwRet)
- {
- // dwIndex is now the count of subkeys, but it needs to be
- // zero-based for RegEnumKey, so I'll pre-decrement, rather
- // than post-decrement.
- while (ERROR_SUCCESS == RegEnumKeyA(hkSubKey, --dwIndex, szSubKeyName, cchSubKeyName))
- {
- _DeleteKeyRecursively(hkSubKey, szSubKeyName);
- }
- }
- RegCloseKey(hkSubKey);
- dwRet = RegDeleteKeyA(hkey, pszSubKey);
- }
- return dwRet;
- }
- // ****************************************************************************************************
- // C S T R I N G L I S T C L A S S
- //
- // A really basic string list class. Actually, its a string array class, but you don't need to know
- // that. It could do so much more, but for now, it only maintains an array of C strings.
- //
- CStringList::CStringList()
- {
- m_count = 0;
- m_ptrCount = 0;
- m_strings = NULL;
- }
- /*
- CStringList::~CStringList
- Clean up any memory that was allocated in the CStringList object
- */
- CStringList::~CStringList()
- {
- if (m_strings)
- {
- for (int i = 0; i < m_count; i++)
- {
- if (m_strings[i])
- {
- MemFree(m_strings[i]);
- m_strings[i] = NULL;
- }
- }
- MemFree(m_strings);
- m_strings = NULL;
- m_count = 0;
- }
- }
- /*
- CStringList::AddString
- Add a string to the end of the string list.
- */
- void CStringList::AddString(TCHAR* lpszInString)
- {
- // make more room for pointers, if necessary
- if (m_ptrCount == m_count)
- {
- m_ptrCount += 5;
- if (!MemRealloc((void **)&m_strings, sizeof(TCHAR *) * m_ptrCount))
- {
- m_ptrCount -= 5;
- Assert(false);
- return;
- }
- // initialize the new strings to nil
- for (int i = m_count; i < m_ptrCount; i++)
- m_strings[i] = NULL;
- }
- //now put the string in the next location
- int iNewIndex = m_count++;
- if(MemAlloc((void **)&m_strings[iNewIndex], sizeof(TCHAR) * lstrlen(lpszInString)+1))
- {
- lstrcpy(m_strings[iNewIndex], lpszInString);
- }
- else
- {
- // couldn't allocate space for the string. Don't count that spot as filled
- m_count--;
- }
- }
- /*
- CStringList::RemoveString
- Remove a string at zero based index iIndex
- */
- void CStringList::RemoveString(int iIndex)
- {
- int iCopySize;
- iCopySize = ((m_count - iIndex) - 1) * 4;
- // free the memory for the string
- if (m_strings[iIndex])
- {
- MemFree(m_strings[iIndex]);
- m_strings[iIndex] = NULL;
- }
- // move the other strings down
- if (iCopySize)
- {
- memmove(&(m_strings[iIndex]), &(m_strings[iIndex+1]), iCopySize);
- }
- // null out the last item in the list and decrement the counter.
- m_strings[--m_count] = NULL;
- }
- /*
- CStringList::GetString
- Return the pointer to the string at zero based index iIndex.
- Return the string at the given index. Note that the TCHAR pointer
- is still owned by the string list and should not be deleted.
- */
- TCHAR *CStringList::GetString(int iIndex)
- {
- if (iIndex < m_count && iIndex >= 0)
- return m_strings[iIndex];
- else
- return NULL;
- }
- int __cdecl _CSL_Compare(const void *p1, const void *p2)
- {
- TCHAR *psz1, *psz2;
- psz1 = *((TCHAR **)p1);
- psz2 = *((TCHAR **)p2);
- return lstrcmpi(psz1, psz2);
- }
- /*
- CStringList::Sort
- Sort the strings in the list
- */
- void CStringList::Sort()
- {
- qsort(m_strings, m_count, sizeof(TCHAR *), _CSL_Compare);
- }
- /*
- MU_Init
- Initialize the memory allocator and make sure that there is
- at least one user in the registry.
- */
- static BOOL g_inited = FALSE;
- EXTERN_C void MU_Init()
- {
- CStringList* pList;
- if (!g_inited)
- {
- MemInit();
- pList = MU_GetUsernameList();
- if (!pList || pList->GetLength() == 0)
- {
- _MakeDefaultFirstUser();
- }
- if (pList)
- delete pList;
- g_inited = TRUE;
- }
- }
- /*
- MU_GetUsernameList
- Build a CStringList with all of the names of the users
- stored in HKLM
- */
- #define MAXKEYNAME 256
- CStringList* MU_GetUsernameList(void)
- {
- CStringList* vList = NULL;
- HKEY hSourceSubKey;
- DWORD dwEnumIndex = 0, dwStatus, dwSize, dwType;
- int cb;
- TCHAR szKeyNameBuffer[MAXKEYNAME];
- vList = new CStringList;
- Assert(vList);
- if (vList)
- {
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
- {
- while (TRUE)
- {
- HKEY hkUserKey;
- if (RegEnumKey(hSourceSubKey, dwEnumIndex++, szKeyNameBuffer,MAXKEYNAME)
- != ERROR_SUCCESS)
- break;
- cb = lstrlen(szKeyNameBuffer);
- if (RegOpenKey(hSourceSubKey, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(szKeyNameBuffer);
- dwStatus = RegQueryValueEx(hkUserKey, c_szUsername, NULL, &dwType, (LPBYTE)&szKeyNameBuffer, &dwSize);
- Assert(ERROR_SUCCESS == dwStatus);
- Assert(*szKeyNameBuffer != 0);
- //filter names that begin with _ to hide things like "_Outlook News"
- if (ERROR_SUCCESS == dwStatus && *szKeyNameBuffer != '_')
- vList->AddString(szKeyNameBuffer);
- RegCloseKey(hkUserKey);
- }
- else
- AssertSz(FALSE, "Couldn't open user's Key");
- }
- RegCloseKey(hSourceSubKey);
- }
- else
- AssertSz(FALSE, "Couldn't open user profiles root Key");
- }
- return vList;
- }
- /*
- MU_UsernameToUserId
- Given a username, find its user id and return it. Returns E_FAIL if it can't
- find the given username.
- */
- HRESULT MU_UsernameToUserId(TCHAR *lpszUsername, GUID *puidID)
- {
- HKEY hSourceSubKey;
- ULONG ulEnumIndex = 0;
- DWORD dwStatus, dwSize, dwType;
- TCHAR szKeyNameBuffer[MAXKEYNAME];
- BOOL fFound = FALSE;
- TCHAR szUid[255];
- ZeroMemory(puidID, sizeof(GUID));
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
- {
- while (!fFound)
- {
- HKEY hkUserKey;
- if (RegEnumKey(hSourceSubKey, ulEnumIndex++, szKeyNameBuffer,MAXKEYNAME)
- != ERROR_SUCCESS)
- break;
- if (RegOpenKey(hSourceSubKey, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(szKeyNameBuffer);
- dwStatus = RegQueryValueEx(hkUserKey, c_szUsername, NULL, &dwType, (LPBYTE)&szKeyNameBuffer, &dwSize);
- if (ERROR_SUCCESS == dwStatus && lstrcmpi(lpszUsername, szKeyNameBuffer) == 0)
- {
- dwSize = sizeof(szUid);
- dwStatus = RegQueryValueEx(hkUserKey, c_szUserID, NULL, &dwType, (LPBYTE)&szUid, &dwSize);
- fFound = (dwStatus == ERROR_SUCCESS);
- if (fFound)
- fFound = SUCCEEDED(GUIDFromAString(szUid, puidID));
- }
- RegCloseKey(hkUserKey);
- }
- }
- RegCloseKey(hSourceSubKey);
- }
- return (fFound ? S_OK : E_FAIL);
- }
- /*
- MU_GetPasswordForUsername
- Get the password for the provided user and return it in szOutPassword. Return in
- pfUsePassword if password is enabled and false if it is disabled.
- Function returns true if the password data could be found, false otherwise
- */
- BOOL MU_GetPasswordForUsername(TCHAR *lpszInUsername, TCHAR *szOutPassword, BOOL *pfUsePassword)
- {
- #ifdef IDENTITY_PASSWORDS
- TCHAR szPath[MAX_PATH];
- TCHAR szPassword[255] = "";
- HKEY hDestinationSubKey;
- DWORD dwSize, dwStatus, dwType;
- DWORD dwPWEnabled = 0;
- GUID uidUserID;
- HRESULT hr;
- PASSWORD_STORE pwStore;
- hr = MU_UsernameToUserId(lpszInUsername, &uidUserID);
- Assert(SUCCEEDED(hr));
- if (uidUserID == GUID_NULL)
- {
- *pfUsePassword = FALSE;
- return TRUE;
- }
- if (SUCCEEDED(hr = ReadIdentityPassword(&uidUserID, &pwStore)))
- {
- lstrcpy(szOutPassword, pwStore.szPassword);
- *pfUsePassword = pwStore.fUsePassword;
- return TRUE;
- }
- else
- {
- BOOL fFoundPassword = FALSE;
- //build the user level key.
- MU_GetRegRootForUserID(&uidUserID, szPath);
- if (RegCreateKey(HKEY_CURRENT_USER, szPath, &hDestinationSubKey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(dwPWEnabled);
- dwStatus = RegQueryValueEx(hDestinationSubKey, c_szUsePassword, NULL, &dwType, (LPBYTE)&dwPWEnabled, &dwSize);
- if (ERROR_SUCCESS == dwStatus && 0 != dwPWEnabled)
- {
- dwSize = sizeof(szPassword);
- dwStatus = RegQueryValueEx(hDestinationSubKey, c_szPassword, NULL, &dwType, (LPBYTE)&szPassword, &dwSize);
- if (ERROR_SUCCESS == dwStatus)
- {
- ULONG cbSize;
- fFoundPassword = TRUE;
- cbSize = dwSize;
- if (cbSize > 1)
- {
- DecodeUserPassword(szPassword, &cbSize);
- strcpy(szOutPassword, szPassword);
- }
- else
- {
- *szOutPassword = 0;
- }
- }
- }
- RegCloseKey(hDestinationSubKey);
- }
- // Herein lies the suck. We can't count on being able to access any
- // given pstore from any given profile on Win9x. If you log on with
- // a blank password, or hit escape (not much difference to a user)
- // you will have a different pstore. If we store our passwords in the
- // registry, they can be whacked pretty simply. If we can't find the
- // password, we will disable it for now and say there is none. It
- // seems that most people don't put passwords on identities now
- // anyway, though this will change.
- if (!fFoundPassword)
- {
- fFoundPassword = TRUE;
- dwPWEnabled = 0;
- }
- // Here ends the suck
- *pfUsePassword = (dwPWEnabled != 0);
- return fFoundPassword;
- }
- #else
- *pfUsePassword = FALSE;
- return TRUE;
- #endif //IDENTITY_PASSWORDS
- }
- /*
- _FillListBoxWithUsernames
- Fill a listbox with the names of the users, Adds (Default)
- to the default user.
- */
- BOOL _FillListBoxWithUsernames(HWND hListbox)
- {
- CStringList *lpCStringList;
- GUID uidDefault;
- GUID uidUser;
- lpCStringList = MU_GetUsernameList();
- MU_GetDefaultUserID(&uidDefault);
- SendMessage(hListbox, LB_RESETCONTENT, 0, 0);
- lpCStringList->Sort();
- if (lpCStringList)
- {
- for(int i = 0; i < lpCStringList->GetLength(); i++)
- {
- if (lpCStringList->GetString(i))
- {
- SendMessage(hListbox, LB_ADDSTRING, 0, (LPARAM)lpCStringList->GetString(i));
- }
- }
- delete lpCStringList;
- return true;
- }
- return false;
- }
- BOOL _FillComboBoxWithUsernames(HWND hCombobox, HWND hListbox)
- {
- TCHAR szRes[128];
- DWORD_PTR cIndex, dwCount = SendMessage(hListbox, LB_GETCOUNT, 0, 0);
- SendMessage(hCombobox, CB_RESETCONTENT, 0, 0);
- for (cIndex = 0; cIndex < dwCount; cIndex++)
- {
- SendMessage(hListbox, LB_GETTEXT, cIndex, (LPARAM)szRes);
- SendMessage(hCombobox, CB_ADDSTRING, 0, (LPARAM)szRes);
- }
- return true;
- }
- /*
- MU_UsernameExists
- Does the given name already exist as a username?
- */
- BOOL MU_UsernameExists(TCHAR* lpszUsername)
- {
- GUID uidID;
- return SUCCEEDED(MU_UsernameToUserId(lpszUsername, &uidID));
- }
- /*
- MU_GetUserInfo
- Fill in the user info structure with current values
- */
- BOOL MU_GetUserInfo(GUID *puidUserID, LPUSERINFO lpUserInfo)
- {
- TCHAR szPWBuffer[255];
- TCHAR szRegPath[MAX_PATH];
- HKEY hKey;
- BOOL bResult = false;
- LONG lValue;
- DWORD dwStatus, dwType, dwSize;
- GUID uidUser;
- TCHAR szUid[255];
- HRESULT hr;
- PASSWORD_STORE pwStore;
- lpUserInfo->fPasswordValid = FALSE;
- if( puidUserID == NULL)
- {
- MU_GetCurrentUserID(&uidUser);
- if (uidUser == GUID_NULL)
- return FALSE;
- }
- else
- uidUser = *puidUserID;
- MU_GetRegRootForUserID(&uidUser, szRegPath);
- if (RegOpenKey(HKEY_CURRENT_USER, szRegPath, &hKey) == ERROR_SUCCESS)
- {
- *lpUserInfo->szPassword = 0;
- lpUserInfo->fUsePassword = false;
- ZeroMemory(&lpUserInfo->uidUserID, sizeof(GUID));
- dwSize = sizeof(lpUserInfo->szUsername);
- if ((dwStatus = RegQueryValueEx(hKey, c_szUsername, NULL, &dwType, (LPBYTE)lpUserInfo->szUsername, &dwSize)) == ERROR_SUCCESS &&
- (0 != *lpUserInfo->szUsername))
- {
- //we have the username, that is the only required part. The others are optional.
- bResult = true;
- #ifdef IDENTITY_PASSWORDS
- lpUserInfo->fPasswordValid = FALSE;
- if (SUCCEEDED(hr = ReadIdentityPassword(&uidUser, &pwStore)))
- {
- lstrcpy(lpUserInfo->szPassword, pwStore.szPassword);
- lpUserInfo->fUsePassword = pwStore.fUsePassword;
- lpUserInfo->fPasswordValid = TRUE;
- }
- else
- {
- dwSize = sizeof(lValue);
- if ((dwStatus = RegQueryValueEx(hKey, c_szUsePassword, NULL, &dwType, (LPBYTE)&lValue, &dwSize)) == ERROR_SUCCESS)
- {
- lpUserInfo->fUsePassword = (lValue != 0);
- }
- dwSize = sizeof(szPWBuffer);
- dwStatus = RegQueryValueEx(hKey, c_szPassword, NULL, &dwType, (LPBYTE)szPWBuffer, &dwSize);
- ULONG cbSize;
- lpUserInfo->fPasswordValid = (ERROR_SUCCESS == dwStatus);
- // Herein lies the suck (Volume 2). We can't count on being able to access any
- // given pstore from any given profile on Win9x. If you log on with
- // a blank password, or hit escape (not much difference to a user)
- // you will have a different pstore. If we store our passwords in the
- // registry, they can be whacked pretty simply. If we can't find the
- // password, we will disable it for now and say there is none. It
- // seems that most people don't put passwords on identities now
- // anyway, though this will change.
- if (!lpUserInfo->fPasswordValid)
- {
- lpUserInfo->fPasswordValid = TRUE;
- lpUserInfo->fUsePassword = FALSE;
- }
- // Here ends the suck
- cbSize = dwSize;
- if (ERROR_SUCCESS == dwStatus && cbSize > 1)
- {
- DecodeUserPassword(szPWBuffer, &cbSize);
- strcpy(lpUserInfo->szPassword, szPWBuffer);
- }
- else
- *lpUserInfo->szPassword = 0;
- }
- #endif
- dwSize = sizeof(szUid);
- if ((dwStatus = RegQueryValueEx(hKey, c_szUserID, NULL, &dwType, (LPBYTE)&szUid, &dwSize)) == ERROR_SUCCESS)
- {
- hr = GUIDFromAString(szUid, &lpUserInfo->uidUserID);
- Assert(hr);
- }
- }
- RegCloseKey(hKey);
- }
- return bResult;
- }
- /*
- MU_SetUserInfo
- Save the user info structure with the user values
- */
- BOOL MU_SetUserInfo(LPUSERINFO lpUserInfo)
- {
- DWORD dwType, dwSize, dwValue, dwStatus;
- HKEY hkCurrUser;
- TCHAR szPath[MAX_PATH];
- WCHAR szwPath[MAX_PATH];
- TCHAR szUid[255];
- BOOL fNewIdentity = FALSE;
- PASSWORD_STORE pwStore;
- HRESULT hr;
- MU_GetRegRootForUserID(&lpUserInfo->uidUserID, szPath);
- Assert(pszRegPath && *pszRegPath);
- Assert(lpUserInfo->uidUserID != GUID_NULL);
- if ((dwStatus = RegCreateKey(HKEY_CURRENT_USER, szPath, &hkCurrUser)) == ERROR_SUCCESS)
- {
- ULONG cbSize;
- TCHAR szBuffer[255];
- // write out the correct values
- dwType = REG_SZ;
- dwSize = lstrlen(lpUserInfo->szUsername) + 1;
- RegSetValueEx(hkCurrUser, c_szUsername, 0, dwType, (LPBYTE)lpUserInfo->szUsername, dwSize);
- dwSize = sizeof(DWORD);
- if ((dwStatus = RegQueryValueEx(hkCurrUser, c_szDirName, NULL, &dwType, (LPBYTE)&dwValue, &dwSize)) != ERROR_SUCCESS)
- {
- dwValue = MU_GenerateDirectoryNameForIdentity(&lpUserInfo->uidUserID);
- dwType = REG_DWORD;
- dwSize = sizeof(dwValue);
- RegSetValueEx(hkCurrUser, c_szDirName, 0, dwType, (LPBYTE)&dwValue, dwSize);
- fNewIdentity = TRUE;
- }
- #ifdef IDENTITY_PASSWORDS
- lstrcpy(pwStore.szPassword, lpUserInfo->szPassword);
- pwStore.fUsePassword = lpUserInfo->fUsePassword;
- if (FAILED(hr = WriteIdentityPassword(&lpUserInfo->uidUserID, &pwStore)))
- {
- dwType = REG_BINARY ;
- cbSize = strlen(lpUserInfo->szPassword) + 1;
- lstrcpy(szBuffer, lpUserInfo->szPassword);
- EncodeUserPassword(szBuffer, &cbSize);
- dwSize = cbSize;
- RegSetValueEx(hkCurrUser, c_szPassword, 0, dwType, (LPBYTE)szBuffer, dwSize);
- dwType = REG_DWORD;
- dwValue = (lpUserInfo->fUsePassword ? 1 : 0);
- dwSize = sizeof(dwValue);
- RegSetValueEx(hkCurrUser, c_szUsePassword, 0, dwType, (LPBYTE)&dwValue, dwSize);
- }
- else
- {
- //don't keep the registry values if we could save it to the pstore.
- RegDeleteValue(hkCurrUser, c_szPassword);
- RegDeleteValue(hkCurrUser, c_szUsePassword);
- }
- #endif //IDENTITY_PASSWORDS
- Assert(lpUserInfo->uidUserID != GUID_NULL);
- AStringFromGUID(&lpUserInfo->uidUserID, szUid, 255);
- dwType = REG_SZ;
- dwSize = lstrlen(szUid) + 1;
- RegSetValueEx(hkCurrUser, c_szUserID, 0, dwType, (LPBYTE)&szUid, dwSize);
- RegCloseKey(hkCurrUser);
- if (fNewIdentity)
- {
- if (SUCCEEDED(MU_GetUserDirectoryRoot(&lpUserInfo->uidUserID, GIF_ROAMING_FOLDER, szwPath, MAX_PATH)))
- {
- if (!CreateDirectoryWrapW(szwPath,NULL))
- {
- _CreateIdentitiesFolder();
- CreateDirectoryWrapW(szwPath,NULL);
- }
- }
- if (SUCCEEDED(MU_GetUserDirectoryRoot(&lpUserInfo->uidUserID, GIF_NON_ROAMING_FOLDER, szwPath, MAX_PATH)))
- {
- if (!CreateDirectoryWrapW(szwPath,NULL))
- {
- _CreateIdentitiesFolder();
- CreateDirectoryWrapW(szwPath,NULL);
- }
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- /*
- MU_SwitchToUser
- Currently, this just saves the last user's info.
- */
- HRESULT MU_SwitchToUser(TCHAR *lpszUsername)
- {
- GUID uidUserID;
- TCHAR szUid[255];
- HRESULT hr;
- Assert(lpszUsername);
- if (*lpszUsername == 0) // null string means null guid
- {
- uidUserID = GUID_NULL;
- }
- else
- {
- hr = MU_UsernameToUserId(lpszUsername, &uidUserID);
- if (FAILED(hr))
- return hr;
- }
- AStringFromGUID(&uidUserID, szUid, 255);
- Assert(uidUserID != GUID_NULL || (*lpszUsername == 0));
- wsprintf(g_szRegRoot, "%.100s\%.40s", c_szRegRoot, szUid);
- // remember who we last switched to
- HKEY hkey;
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- DWORD dwType, dwSize;
- dwType = REG_SZ;
- dwSize = lstrlen(lpszUsername) + 1;
- RegSetValueEx(hkey, c_szLastUserName, 0, dwType, (LPBYTE)lpszUsername, dwSize);
- dwType = REG_SZ;
- dwSize = lstrlen(szUid) + 1;
- RegSetValueEx(hkey, c_szLastUserID, 0, dwType, (LPBYTE)szUid, dwSize);
- RegCloseKey(hkey);
- }
- return S_OK;
- }
- /*
- MU_SwitchToLastUser
- Makes the last user current, if there is no
- last user, it switches to the first user it can
- find. If there are no users, it creates a
- user called "Main User"
- */
- void MU_SwitchToLastUser()
- {
- HKEY hkey;
- TCHAR szUserUid[255];
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH + 1];
- BOOL fSwitched = FALSE;
- GUID uidUserId;
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- DWORD dwType, dwStatus, dwSize;
- dwSize = sizeof(szUserUid);
- dwStatus = RegQueryValueEx(hkey, c_szLastUserID, NULL, &dwType, (LPBYTE)szUserUid, &dwSize);
- RegCloseKey(hkey);
- if (ERROR_SUCCESS == dwStatus && SUCCEEDED(GUIDFromAString(szUserUid, &uidUserId)) &&
- SUCCEEDED(MU_UserIdToUsername(&uidUserId, szUsername, CCH_USERNAME_MAX_LENGTH)))
- {
- MU_SwitchToUser(szUsername);
- fSwitched = true;
- }
- }
- if (!fSwitched)
- {
- LPSTR pszName;
- CStringList* pList = MU_GetUsernameList();
- if (pList)
- {
- DWORD dwIndex, dwLen = pList->GetLength();
- // find the first non hidden user and switch to them
- for (dwIndex = 0; dwIndex < dwLen; dwIndex++)
- {
- pszName = pList->GetString(dwIndex);
- if (pszName && *pszName && *pszName != '_')
- {
- MU_SwitchToUser(pszName);
- fSwitched = TRUE;
- break;
- }
- }
- delete pList;
- }
- }
- if (!fSwitched)
- {
- _MakeDefaultFirstUser();
- CStringList* pList = MU_GetUsernameList();
- if (pList && pList->GetLength() > 0)
- MU_SwitchToUser(pList->GetString(0));
- if (pList)
- delete pList;
- }
- }
- /*
- _CreateIdentitiesFolder
- Create the parent folder of all of the identities folders.
- */
- static void _CreateIdentitiesFolder()
- {
- HRESULT hr;
- TCHAR szAppDir[MAX_PATH], szSubDir[MAX_PATH], *psz;
- DWORD dw, type;
- hr = E_FAIL;
- dw = MAX_PATH;
- if (ERROR_SUCCESS == _SHGetValueA(HKEY_CURRENT_USER, c_szRegFolders, c_szValueAppData, &type, (LPBYTE)szAppDir, &dw))
- {
- lstrcpy(szSubDir, c_szIdentitiesFolderName);
- psz = _PathAddBackslash(szSubDir);
- psz = _PathAddBackslash(szAppDir);
- lstrcpy(psz, szSubDir);
- psz = _PathAddBackslash(szAppDir);
- CreateDirectory(szAppDir, NULL);
- }
- }
- /*
- MU_GetCurrentUserDirectoryRoot
- Return the path to the top of the current user's root directory.
- This is the directory where the mail store should be located.
- It is in a subfolder the App Data folder.
- lpszUserRoot is a pointer to a character buffer that is cch chars
- in size.
- */
- HRESULT MU_GetUserDirectoryRoot(GUID *uidUserID, DWORD dwFlags, WCHAR *lpszwUserRoot, int cch)
- {
- HRESULT hr;
- WCHAR szwSubDir[MAX_PATH], *pszw, szwUid[255];
- int cb;
- DWORD type, dwDirId;
- LPITEMIDLIST pidl = NULL;
- IShellFolder *psf = NULL;
- STRRET str;
- IMalloc *pMalloc = NULL;
- BOOL fNeedHelp = FALSE;
- Assert(lpszUserRoot != NULL);
- Assert(uidUserID);
- Assert(cch >= MAX_PATH);
- Assert((dwFlags & (GIF_NON_ROAMING_FOLDER | GIF_ROAMING_FOLDER)));
- hr = MU_GetDirectoryIdForIdentity(uidUserID, &dwDirId);
- StringFromGUID2(*uidUserID, szwUid, 255);
- if (FAILED(hr))
- return hr;
- hr = SHGetMalloc(&pMalloc);
- Assert(pMalloc);
- if (!pMalloc)
- return E_OUTOFMEMORY;
- hr = E_FAIL;
- if (!!(dwFlags & GIF_NON_ROAMING_FOLDER))
- {
- hr = SHGetSpecialFolderLocation(GetDesktopWindow(), CSIDL_LOCAL_APPDATA, &pidl);
- if (FAILED(hr) || pidl == 0)
- hr = SHGetSpecialFolderLocation(GetDesktopWindow(), CSIDL_APPDATA, &pidl);
- if (FAILED(hr))
- fNeedHelp = TRUE;
- }
- else if (!!(dwFlags & GIF_ROAMING_FOLDER))
- {
- hr = SHGetSpecialFolderLocation(GetDesktopWindow(), CSIDL_APPDATA, &pidl);
- if (FAILED(hr))
- fNeedHelp = TRUE;
- }
- else
- hr = E_INVALIDARG;
- *lpszwUserRoot = 0;
- if (SUCCEEDED(hr) && pidl)
- {
- if (FAILED(hr = SHGetDesktopFolder(&psf)))
- goto exit;
- if (FAILED(hr = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &str)))
- goto exit;
- switch(str.uType)
- {
- case STRRET_WSTR:
- lstrcpyW(lpszwUserRoot, str.pOleStr);
- pMalloc->Free(str.pOleStr);
- break;
- case STRRET_OFFSET:
- MultiByteToWideChar(CP_ACP, 0, (LPSTR)pidl+str.uOffset, -1, lpszwUserRoot, cch-11);
- break;
- case STRRET_CSTR:
- MultiByteToWideChar(CP_ACP, 0, (LPSTR)str.cStr, -1, lpszwUserRoot, cch-11);
- break;
- default:
- Assert(FALSE);
- goto exit;
- }
- pszw = PathAddBackslashW(lpszwUserRoot);
- if (lstrlenW(lpszwUserRoot) < cch - 10)
- {
- StrCatW(pszw, L"Identities\");
- StrCatW(pszw, szwUid);
- StrCatW(pszw, L"\");
- }
- else
- {
- hr = E_OUTOFMEMORY;
- *lpszwUserRoot = 0;
- }
- }
- else if (fNeedHelp)
- {
- // $$$Review: NEIL QFE
- // SHGetSpecialFolderLocation(GetDesktopWindow(), CSIDL_APPDATA, &pidl) fails on non-SI OSR2.
- HKEY hkeySrc;
- DWORD cb;
- if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",
- 0, KEY_QUERY_VALUE, &hkeySrc))
- {
- // -1 for the backslash we may add
- cb = cch - 1;
- if (ERROR_SUCCESS == RegQueryValueExWrapW(hkeySrc, L"AppData", 0, NULL, (LPBYTE)lpszwUserRoot, &cb))
- {
- pszw = PathAddBackslashW(lpszwUserRoot);
- if (lstrlenW(lpszwUserRoot) < cch - 10)
- {
- StrCatW(pszw, L"Identities\");
- StrCatW(pszw, szwUid);
- StrCatW(pszw, L"\");
- hr = S_OK;
- }
- else
- {
- hr = E_OUTOFMEMORY;
- *lpszwUserRoot = 0;
- }
- }
- RegCloseKey(hkeySrc);
- }
- }
- exit:
- Assert(lstrlenW(lpszwUserRoot) > 0);
- SafeRelease(psf);
- pMalloc->Free(pidl);
- SafeRelease(pMalloc);
- return hr;
- }
- /*
- _ClaimNextUserId
- Get the next available user id. Currently this means starting
- with the CURRENT_USER GUID and changing the first DWORD of it
- until it is unique.
- */
- HRESULT _ClaimNextUserId(GUID *puidId)
- {
- ULONG ulValue = 1;
- DWORD dwType, dwSize, dwStatus;
- HKEY hkeyProfiles;
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1];
- GUID uid;
- FILETIME ft;
- if (FAILED(CoCreateGuid(&uid)))
- {
- uid = UID_GIBC_CURRENT_USER;
- GetSystemTimeAsFileTime(&ft);
- uid.Data1 = ft.dwLowDateTime;
- //make sure it hasn't been used
- while (MU_UserIdToUsername(&uid, szUsername, CCH_USERNAME_MAX_LENGTH))
- uid.Data1 ++;
- }
- *puidId = uid;
- return S_OK;
- }
- BOOL MU_GetCurrentUserID(GUID *puidUserID)
- {
- BOOL fFound = FALSE;
- HKEY hkey;
- GUID uidUserId;
- TCHAR szUid[255];
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- DWORD dwSize;
- dwSize = 255;
- fFound = (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szLastUserID, 0, NULL, (LPBYTE)szUid, &dwSize));
- if (fFound)
- fFound = SUCCEEDED(GUIDFromAString(szUid, puidUserID));
- if (fFound && *puidUserID == GUID_NULL)
- fFound = false;
- RegCloseKey(hkey);
- }
- #ifdef DEBUG
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1];
- Assert(MU_UserIdToUsername(puidUserID, szUsername, CCH_USERNAME_MAX_LENGTH));
- #endif
- return fFound;
- }
- /*
- MU_UserIdToUsername
- Return the user name for the user whose user id is passed in. Returns
- whether or not the user was found.
- */
- BOOL MU_UserIdToUsername(GUID *puidUserID, TCHAR *lpszUsername, ULONG cch)
- {
- HKEY hkey;
- TCHAR szPath[MAX_PATH];
- BOOL fFound = FALSE;
- Assert(lpszUsername);
- lpszUsername[0] = 0;
- MU_GetRegRootForUserID(puidUserID, szPath);
- Assert(*szPath);
- if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szPath, 0, KEY_QUERY_VALUE, &hkey))
- {
- fFound = (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szUsername, 0, NULL, (LPBYTE)lpszUsername, &cch));
- RegCloseKey(hkey);
- }
- return fFound;
- }
- /*
- MU_CountUsers
- Returns the number of users currently configured.
- */
- ULONG MU_CountUsers(void)
- {
- CStringList *psList;
- ULONG ulCount = 0;
- psList = MU_GetUsernameList();
- if (psList)
- {
- ulCount = psList->GetLength();
- delete psList;
- }
- return ulCount;
- }
- /*
- MU_GetRegRootForUserid
- Get the reg root path for a given user id.
- */
- HRESULT MU_GetRegRootForUserID(GUID *puidUserID, LPSTR pszPath)
- {
- TCHAR szUid[255];
- Assert(pszPath);
- Assert(puidUserID);
- AStringFromGUID(puidUserID, szUid, 255);
- wsprintf(pszPath, "%.100s\%.40s", c_szRegRoot, szUid);
- return S_OK;
- }
- /*
- MU_GetDefaultUserID
- Get the user id for the user who is currently marked as the default user.
- Returns true if the proper user was found, false if not.
- */
- BOOL MU_GetDefaultUserID(GUID *puidUserID)
- {
- BOOL fFound = FALSE;
- HKEY hkey;
- TCHAR szUid[255];
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- DWORD dwSize;
- dwSize = sizeof(szUid);
- fFound = (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szDefaultUserID, 0, NULL, (LPBYTE)szUid, &dwSize));
- if (fFound)
- fFound = SUCCEEDED(GUIDFromAString(szUid, puidUserID));
- RegCloseKey(hkey);
- }
- #ifdef DEBUG
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1];
- Assert(MU_UserIdToUsername(ulUserID, szUsername, CCH_USERNAME_MAX_LENGTH));
- #endif
- return fFound;
- }
- /*
- MU_MakeDefaultUser
- Set the user referenced by id ulUserID to be the default user.
- The default user is referenced by certain applications which
- can only deal with one user. MS Phone is a good example.
- */
- HRESULT MU_MakeDefaultUser(GUID *puidUserID)
- {
- HRESULT hr = E_FAIL;
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH+1];
- TCHAR szUid[255];
- HKEY hkey;
- // make sure the user exists and get their name to put in the
- // Default Username reg key
- AStringFromGUID(puidUserID, szUid, 255);
- Assert(*puidUserID != GUID_NULL);
- if (MU_UserIdToUsername(puidUserID, szUsername, CCH_USERNAME_MAX_LENGTH))
- {
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- DWORD dwType, dwSize;
- LONG lError;
- dwType = REG_SZ;
- dwSize = lstrlen(szUid) + 1;
- lError = RegSetValueEx(hkey, c_szDefaultUserID, 0, dwType, (LPBYTE)szUid, dwSize);
- if (lError)
- {
- hr = E_FAIL;
- goto error;
- }
- hr = S_OK;
- error:
- RegCloseKey(hkey);
- }
- }
- return hr;
- }
- /*
- MU_DeleteUser
- Remove a user from the registry. This does not delete
- anything in the user's folder, but it does blow away
- their reg settings.
- */
- HRESULT MU_DeleteUser(GUID *puidUserID)
- {
- GUID uidDefault, uidCurrent;
- TCHAR szPath[MAX_PATH];
- MU_GetCurrentUserID(&uidCurrent);
- MU_GetDefaultUserID(&uidDefault);
- // Can't delete the current user
- if (*puidUserID == uidCurrent)
- return E_FAIL;
- // Can't delete the default user if current user is null
- if (GUID_NULL == uidCurrent && *puidUserID == uidDefault)
- return E_FAIL;
- // If they are deleting the default user,
- // make the current user the default
- if (*puidUserID == uidDefault)
- MU_MakeDefaultUser(&uidCurrent);
- MU_GetRegRootForUserID(puidUserID, szPath);
- _DeleteKeyRecursively(HKEY_CURRENT_USER, szPath);
- // don't delete the directory since the user may need
- // data out of it.
- PostMessage(HWND_BROADCAST, WM_IDENTITY_INFO_CHANGED, 0, IIC_IDENTITY_DELETED);
- return S_OK;
- }
- /*
- MU_CreateUser
- Create a user with the user info passed in. This includes
- creating their spot in the registry and their directory in the
- identities folder.
- */
- HRESULT MU_CreateUser(LPUSERINFO lpUserInfo)
- {
- TCHAR szPath[MAX_PATH], szBuffer[MAX_PATH], szUid[255];
- WCHAR szwPath[MAX_PATH];
- HKEY hkey;
- HRESULT hr = S_OK;
- DWORD dwType, dwSize, cbSize, dwValue;
- PASSWORD_STORE pwStore;
- MU_GetRegRootForUserID(&lpUserInfo->uidUserID, szPath);
- Assert(*szPath && *szAcctPath);
- AStringFromGUID(&lpUserInfo->uidUserID, szUid, 255);
- Assert(lpUserInfo->uidUserID != GUID_NULL);
- if (RegCreateKey(HKEY_CURRENT_USER, szPath, &hkey) == ERROR_SUCCESS)
- {
- // write out the correct values
- dwType = REG_SZ;
- dwSize = lstrlen(lpUserInfo->szUsername) + 1;
- RegSetValueEx(hkey, c_szUsername, 0, dwType, (LPBYTE)lpUserInfo->szUsername, dwSize);
- #ifdef IDENTITY_PASSWORDS
- lstrcpy(pwStore.szPassword, lpUserInfo->szPassword);
- pwStore.fUsePassword = lpUserInfo->fUsePassword;
- if (FAILED(hr = WriteIdentityPassword(&lpUserInfo->uidUserID, &pwStore)))
- {
- dwType = REG_BINARY ;
- cbSize = strlen(lpUserInfo->szPassword) + 1;
- lstrcpy(szBuffer, lpUserInfo->szPassword);
- EncodeUserPassword(szBuffer, &cbSize);
- dwSize = cbSize;
- RegSetValueEx(hkey, c_szPassword, 0, dwType, (LPBYTE)szBuffer, dwSize);
- dwType = REG_DWORD;
- dwValue = (lpUserInfo->fUsePassword ? 1 : 0);
- dwSize = sizeof(dwValue);
- RegSetValueEx(hkey, c_szUsePassword, 0, dwType, (LPBYTE)&dwValue, dwSize);
- }
- #endif //IDENTITY_PASSWORDS
- dwType = REG_SZ;
- dwSize = lstrlen(szUid) + 1;
- RegSetValueEx(hkey, c_szUserID, 0, dwType, (LPBYTE)&szUid, dwSize);
- RegCloseKey(hkey);
- if (SUCCEEDED(MU_GetUserDirectoryRoot(&lpUserInfo->uidUserID, GIF_ROAMING_FOLDER, szwPath, MAX_PATH)))
- if (!CreateDirectoryWrapW(szwPath,NULL))
- {
- _CreateIdentitiesFolder();
- CreateDirectoryWrapW(szwPath,NULL);
- }
- if (SUCCEEDED(MU_GetUserDirectoryRoot(&lpUserInfo->uidUserID, GIF_NON_ROAMING_FOLDER, szwPath, MAX_PATH)))
- if (!CreateDirectoryWrapW(szwPath,NULL))
- {
- _CreateIdentitiesFolder();
- CreateDirectoryWrapW(szwPath,NULL);
- }
- }
- else
- hr = E_FAIL;
- return hr;
- }
- /*
- MU_GetRegRoot
- Returns a pointer to a string containing the location
- in HKEY_CURRENT_USER for the current user.
- */
- LPCTSTR MU_GetRegRoot()
- {
- if (*g_szRegRoot)
- return g_szRegRoot;
- else
- {
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH + 1];
- if (MU_Login(NULL, 0, szUsername))
- {
- GUID uidUserId;
- TCHAR szUid[255];
- MU_UsernameToUserId(szUsername, &uidUserId);
- AStringFromGUID(&uidUserId, szUid, 255);
- wsprintf(g_szRegRoot, "%.100s\%.40s", c_szRegRoot, szUid);
- return g_szRegRoot;
- }
- else
- {
- Assert(FALSE);
- }
- }
- return NULL;
- }
- void _MakeDefaultFirstUser()
- {
- USERINFO nuInfo;
- TCHAR szUid[255];
- MLLoadStringA(idsMainUser, nuInfo.szUsername, CCH_USERNAME_MAX_LENGTH);
- if (nuInfo.szUsername[0] == 0)
- {
- lstrcpy(nuInfo.szUsername, TEXT("Main Identity"));
- }
- *nuInfo.szPassword = 0;
- nuInfo.fUsePassword = false;
- nuInfo.fPasswordValid = true;
- _ClaimNextUserId(&nuInfo.uidUserID);
- MU_CreateUser(&nuInfo);
- MU_MakeDefaultUser(&nuInfo.uidUserID);
- MU_SwitchToUser(nuInfo.szUsername);
- AStringFromGUID(&nuInfo.uidUserID, szUid, 255);
- wsprintf(g_szRegRoot, "%.100s\%.40s", c_szRegRoot, szUid);
- }
- void FixMissingIdentityNames()
- {
- HKEY hSourceSubKey;
- ULONG ulEnumIndex = 0;
- DWORD dwStatus, dwSize, dwType, dwValue;
- BOOL fFound = FALSE;
- TCHAR szKeyNameBuffer[MAX_PATH];
- TCHAR szUsername[CCH_USERNAME_MAX_LENGTH];
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
- {
- while (!fFound)
- {
- HKEY hkUserKey;
- if (RegEnumKey(hSourceSubKey, ulEnumIndex++, szKeyNameBuffer,MAXKEYNAME)
- != ERROR_SUCCESS)
- break;
- if (RegOpenKey(hSourceSubKey, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(szUsername);
- dwStatus = RegQueryValueEx(hkUserKey, c_szUsername, NULL, &dwType, (LPBYTE)szUsername, &dwSize);
- if (ERROR_SUCCESS != dwStatus || 0 == szUsername[0])
- {
- lstrcpy(szUsername, "Main Identity");
- dwStatus = RegSetValueEx(hkUserKey, c_szUsername, 0, REG_SZ, (LPBYTE)szUsername, lstrlen(szUsername)+1);
- }
- RegCloseKey(hkUserKey);
- }
- }
- RegCloseKey(hSourceSubKey);
- }
- }
- typedef DWORD (STDAPICALLTYPE *PNetWkstaUserGetInfo)
- (LPWSTR reserved, DWORD level, LPBYTE *bufptr);
- #if 0
- /*
- _DomainControllerPresent
- Identities are disabled when the machine they are running on is part of a domain, unless
- there is a policy to explicitly allow them. This function checks to see if the machine
- is joined to a domain.
- */
- BOOL _DomainControllerPresent()
- {
- static BOOL fInDomain = FALSE;
- static BOOL fValid = FALSE;
- HINSTANCE hInst;
- PNetWkstaUserGetInfo pNetWkstaUserGetInfo;
- _WKSTA_USER_INFO_1 *pwui1;
- if (!fValid)
- {
- fValid = TRUE;
- hInst = LoadLibrary(TEXT("NETAPI32.DLL"));
- if (hInst)
- {
- pNetWkstaUserGetInfo = (PNetWkstaUserGetInfo)GetProcAddress(hInst, TEXT("NetWkstaUserGetInfo"));
- if (pNetWkstaUserGetInfo && (pNetWkstaUserGetInfo(NULL, 1, (LPBYTE*)&pwui1) == NOERROR))
- {
- if (pwui1->wkui1_logon_domain && pwui1->wkui1_logon_server && lstrcmpW(pwui1->wkui1_logon_server, pwui1->wkui1_logon_domain) != 0)
- {
- fInDomain = TRUE;
- }
- }
- FreeLibrary(hInst);
- }
- }
- return fInDomain;
- }
- #endif
- /*
- MU_IdentitiesDisabled
- Returns if identities is disabled due to a policy
- or whatever.
- */
- BOOL MU_IdentitiesDisabled()
- {
- TCHAR szPolicyPath[] = "Software\Policies\Microsoft\Windows\CurrentVersion\Identities";
- HKEY hkey;
- DWORD dwValue, dwSize;
- BOOL fLockedDown = FALSE;
- if (RegOpenKey(HKEY_LOCAL_MACHINE, szPolicyPath, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szPolicyKey, 0, NULL, (LPBYTE)&dwValue, &dwSize) && 1 == dwValue)
- fLockedDown = TRUE;
- RegCloseKey(hkey);
- }
- if (!fLockedDown && RegOpenKey(HKEY_CURRENT_USER, szPolicyPath, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szPolicyKey, 0, NULL, (LPBYTE)&dwValue, &dwSize) && 1 == dwValue)
- fLockedDown = TRUE;
- RegCloseKey(hkey);
- }
- #if 0
- // turned off for now, pending determination of whether we even want to
- // have this policy
- if (!fLockedDown && _DomainControllerPresent())
- {
- fLockedDown = TRUE;
- if (RegOpenKey(HKEY_LOCAL_MACHINE, szPolicyPath, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szEnableDCPolicyKey, 0, NULL, (LPBYTE)&dwValue, &dwSize) && 1 == dwValue)
- fLockedDown = FALSE;
- RegCloseKey(hkey);
- }
- if (fLockedDown && RegOpenKey(HKEY_CURRENT_USER, szPolicyPath, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szEnableDCPolicyKey, 0, NULL, (LPBYTE)&dwValue, &dwSize) && 1 == dwValue)
- fLockedDown = FALSE;
- RegCloseKey(hkey);
- }
- }
- #endif
- return fLockedDown;
- }
- static GUID g_uidLoginOption;
- static BOOLEAN g_uidLoginOptionSet;
- void _ResetRememberedLoginOption(void)
- {
- g_uidLoginOption = GUID_NULL;
- g_uidLoginOptionSet = FALSE;
- }
- void _RememberLoginOption(HWND hwndCombo)
- {
- LRESULT dFoundItem;
- TCHAR szUsername[CCH_IDENTITY_NAME_MAX_LENGTH * 2];
- GUID uidUser;
- *szUsername = 0;
- g_uidLoginOptionSet = TRUE;
- dFoundItem = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
- SendMessage(hwndCombo, CB_GETLBTEXT, dFoundItem, (LPARAM)szUsername);
- if (FAILED(MU_UsernameToUserId(szUsername, &uidUser)))
- g_uidLoginOption = GUID_NULL;
- else
- g_uidLoginOption = uidUser;
- }
- DWORD MU_GetDefaultOptionIndex(HWND hwndCombo)
- {
- GUID uidStart, uidDefault;
- USERINFO uiDefault;
- DWORD dwResult = 0;
- if (MU_GetDefaultUserID(&uidDefault))
- {
- MU_GetUserInfo(&uidDefault, &uiDefault);
- if (uiDefault.szUsername[0])
- {
- dwResult = (DWORD)SendMessage(hwndCombo, CB_FINDSTRING, 0, (LPARAM)uiDefault.szUsername);
- }
- }
- return dwResult;
- }
- DWORD MU_GetLoginOptionIndex(HWND hwndCombo)
- {
- GUID uidStart, uidDefault;
- USERINFO uiLogin;
- DWORD dwResult = ASK_BEFORE_LOGIN;
- if (GUID_NULL == g_uidLoginOption)
- {
- if (g_uidLoginOptionSet)
- goto exit;
- MU_GetLoginOption(&uidStart);
- }
- else
- uidStart = g_uidLoginOption;
- if (uidStart == GUID_NULL)
- goto exit;
- if(!MU_GetUserInfo(&uidStart, &uiLogin))
- goto exit;
- dwResult = (DWORD)SendMessage(hwndCombo, CB_FINDSTRING, 0, (LPARAM)uiLogin.szUsername);
- exit:
- return dwResult;
- }
- /*
- MU_GetLoginOption
- return the user's choice for what should happen when there is no current
- user
- */
- void MU_GetLoginOption(GUID *puidStartAs)
- {
- HKEY hkey;
- DWORD dwSize;
- TCHAR szUid[255];
- GUID uidUser;
- ZeroMemory(puidStartAs, sizeof(GUID));
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(szUid);
- if (ERROR_SUCCESS != RegQueryValueEx(hkey, c_szLoginAs, 0, NULL, (LPBYTE)szUid, &dwSize))
- MU_GetDefaultUserID(puidStartAs);
- else
- GUIDFromAString(szUid, puidStartAs);
- RegCloseKey(hkey);
- }
- }
- /*
- MU_SetLoginOption
- return the user's choice for what should happen when there is no current
- user
- */
- BOOL MU_SetLoginOption(HWND hwndCombo, LRESULT dOption)
- {
- HKEY hkey;
- BOOL fResult = FALSE;
- TCHAR szUsername[CCH_IDENTITY_NAME_MAX_LENGTH * 2];
- TCHAR szUid[255];
- GUID uidUser;
- SendMessage(hwndCombo, CB_GETLBTEXT, dOption, (LPARAM)szUsername);
- if (dOption == (LRESULT)ASK_BEFORE_LOGIN || FAILED(MU_UsernameToUserId(szUsername, &uidUser)))
- {
- ZeroMemory(&uidUser, sizeof(uidUser));
- }
- AStringFromGUID(&uidUser, szUid, sizeof(szUid));
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hkey) == ERROR_SUCCESS)
- {
- fResult = (ERROR_SUCCESS == RegSetValueEx(hkey, c_szLoginAs, 0, REG_SZ, (LPBYTE)szUid, lstrlen(szUid)+1));
- RegCloseKey(hkey);
- }
- return TRUE;
- }
- /*
- MU_CanEditIdentity
- Is the current identity allowed to edit the indicated identity's settings?
- */
- BOOL MU_CanEditIdentity(HWND hwndParent, GUID *puidIdentityId)
- {
- #ifndef IDENTITY_PASSWORDS
- return TRUE;
- #else
- USERINFO uiCurrent, uiQuery;
- TCHAR szBuffer[255]; // really ought to be big enough
- LPTSTR lpString = NULL;
- TCHAR* rgsz[1] = {uiQuery.szUsername};
- BOOL fResult = FALSE;
- PASSWORD_STORE pwStore;
- ZeroMemory(&uiQuery, sizeof(USERINFO));
- if (MU_GetUserInfo(puidIdentityId, &uiQuery))
- {
- if (!uiQuery.fPasswordValid)
- {
- MU_ShowErrorMessage(hwndParent, idsPwdNotFound, idsPwdError);
- return FALSE;
- }
- if (uiQuery.szPassword[0] == 0)
- {
- return TRUE;
- }
- if (MU_GetUserInfo(NULL, &uiCurrent))
- {
- if (uiCurrent.uidUserID == uiQuery.uidUserID)
- return TRUE;
- }
- }
- else
- return FALSE;
- MLLoadStringA(idsConfirmEdit, szBuffer, sizeof(szBuffer));
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_STRING |
- FORMAT_MESSAGE_ARGUMENT_ARRAY,
- szBuffer,
- 0, 0,
- (LPTSTR)&lpString, 0, (va_list *)rgsz);
- if (lpString)
- {
- fResult = MU_ConfirmUserPassword(hwndParent, lpString, uiQuery.szPassword);
- LocalFree(lpString);
- }
- return fResult;
- #endif //IDENTITY_PASSWORDS
- }
- static BOOL _DirectoryIdInUse(DWORD dwId)
- {
- HKEY hSourceSubKey;
- ULONG ulEnumIndex = 0;
- DWORD dwStatus, dwSize, dwType, dwValue;
- BOOL fFound = FALSE;
- TCHAR szKeyNameBuffer[MAX_PATH];
- if (RegCreateKey(HKEY_CURRENT_USER, c_szRegRoot, &hSourceSubKey) == ERROR_SUCCESS)
- {
- while (!fFound)
- {
- HKEY hkUserKey;
- if (RegEnumKey(hSourceSubKey, ulEnumIndex++, szKeyNameBuffer,MAXKEYNAME)
- != ERROR_SUCCESS)
- break;
- if (RegOpenKey(hSourceSubKey, szKeyNameBuffer, &hkUserKey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(dwValue);
- dwStatus = RegQueryValueEx(hkUserKey, c_szDirName, NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
- if (ERROR_SUCCESS == dwStatus && dwValue == dwId)
- {
- fFound = TRUE;
- RegCloseKey(hkUserKey);
- break;
- }
- RegCloseKey(hkUserKey);
- }
- }
- RegCloseKey(hSourceSubKey);
- }
- return fFound;
- }
- DWORD MU_GenerateDirectoryNameForIdentity(GUID *puidIdentityId)
- {
- DWORD dwId, dwRegValue;
- dwId = puidIdentityId->Data1;
- while (_DirectoryIdInUse(dwId))
- dwId++;
- return dwId;
- }
- HRESULT MU_GetDirectoryIdForIdentity(GUID *puidIdentityId, DWORD *pdwDirId)
- {
- TCHAR szRegPath[MAX_PATH];
- HKEY hkey;
- HRESULT hr = E_FAIL;
- DWORD dwSize, dwStatus, dwValue, dwType;
- MU_GetRegRootForUserID(puidIdentityId, szRegPath);
- if (RegOpenKey(HKEY_CURRENT_USER, szRegPath, &hkey) == ERROR_SUCCESS)
- {
- dwSize = sizeof(dwValue);
- dwStatus = RegQueryValueEx(hkey, c_szDirName, NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
- if (ERROR_SUCCESS == dwStatus)
- {
- *pdwDirId = dwValue;
- hr = S_OK;
- }
- else
- {
- // try to generate one
- dwValue = MU_GenerateDirectoryNameForIdentity(puidIdentityId);
- dwType = REG_DWORD;
- dwSize = sizeof(dwValue);
- dwStatus = RegSetValueEx(hkey, c_szDirName, 0, dwType, (LPBYTE)&dwValue, dwSize);
- if (ERROR_SUCCESS == dwStatus)
- {
- *pdwDirId = dwValue;
- hr = S_OK;
- }
- }
- RegCloseKey(hkey);
- }
- return hr;
- }
- void _MigratePasswords()
- {
- CStringList *psList;
- int i, iCount = 0;
- USERINFO uiUser;
- DWORD dwStatus, dwValue, dwType, dwSize;
- dwType = REG_DWORD;
- dwSize = sizeof(DWORD);
- dwStatus = SHGetValue(HKEY_CURRENT_USER, c_szRegRoot, c_szMigrated5, &dwType, &dwValue, &dwSize);
- if (dwStatus == ERROR_SUCCESS && dwValue == 1)
- return;
- psList = MU_GetUsernameList();
- if (psList)
- {
- iCount = psList->GetLength();
- for (i = 0; i < iCount; i++)
- {
- GUID uidUser;
- if (SUCCEEDED(MU_UsernameToUserId(psList->GetString(i), &uidUser))
- && MU_GetUserInfo(&uidUser, &uiUser))
- {
- if (!uiUser.fPasswordValid)
- {
- uiUser.fUsePassword = false;
- *uiUser.szPassword = 0;
- MU_SetUserInfo(&uiUser);
- }
- }
- }
- delete psList;
- }
- dwValue = 1;
- SHSetValue(HKEY_CURRENT_USER, c_szRegRoot, c_szMigrated5, REG_DWORD, &dwValue, sizeof(DWORD));
- }