windows-nt/Source/XPSP1/NT/ds/security/gina/userenv/main/globals.c
2020-09-26 16:20:57 +08:00

645 lines
21 KiB
C

//*************************************************************
//
// Global Variables
//
// Microsoft Confidential
// Copyright (c) Microsoft Corporation 1995
// All rights reserved
//
//*************************************************************
#include "uenv.h"
#include <winfoldr.h>
HINSTANCE g_hDllInstance;
DWORD g_dwBuildNumber;
NTPRODUCTTYPE g_ProductType;
HANDLE g_hProfileSetup = NULL;
DWORD g_dwNumShellFolders;
DWORD g_dwNumCommonShellFolders;
HANDLE g_hPolicyCritMutexMach = NULL;
HANDLE g_hPolicyCritMutexUser = NULL;
HANDLE g_hPolicyNotifyEventMach = NULL;
HANDLE g_hPolicyNotifyEventUser = NULL;
HANDLE g_hPolicyNeedFGEventMach = NULL;
HANDLE g_hPolicyNeedFGEventUser = NULL;
HANDLE g_hPolicyDoneEventMach = NULL;
HANDLE g_hPolicyDoneEventUser = NULL;
HANDLE g_hPolicyForegroundDoneEventMach = 0;
HANDLE g_hPolicyForegroundDoneEventUser = 0;
const TCHAR c_szStarDotStar[] = TEXT("*.*");
const TCHAR c_szSlash[] = TEXT("\\");
const TCHAR c_szDot[] = TEXT(".");
const TCHAR c_szDotDot[] = TEXT("..");
const TCHAR c_szMAN[] = TEXT(".man");
const TCHAR c_szUSR[] = TEXT(".usr");
const TCHAR c_szLog[] = TEXT(".log");
const TCHAR c_szPDS[] = TEXT(".pds");
const TCHAR c_szPDM[] = TEXT(".pdm");
const TCHAR c_szLNK[] = TEXT(".lnk");
const TCHAR c_szBAK[] = TEXT(".bak");
const TCHAR c_szNTUserTmp[] = TEXT("ntuser.tmp");
const TCHAR c_szNTUserMan[] = TEXT("ntuser.man");
const TCHAR c_szNTUserDat[] = TEXT("ntuser.dat");
const TCHAR c_szNTUserIni[] = TEXT("ntuser.ini");
const TCHAR c_szRegistryPol[] = TEXT("registry.pol");
const TCHAR c_szNTUserStar[] = TEXT("ntuser.*");
const TCHAR c_szUserStar[] = TEXT("user.*");
const TCHAR c_szSpace[] = TEXT(" ");
const TCHAR c_szDotPif[] = TEXT(".pif");
const TCHAR c_szNULL[] = TEXT("");
const TCHAR c_szCommonGroupsLocation[] = TEXT("Software\\Program Groups");
TCHAR c_szRegistryExtName[64];
//
// Registry Extension guid
//
GUID guidRegistryExt = REGISTRY_EXTENSION_GUID;
//
// Special folders
//
FOLDER_INFO c_ShellFolders[] =
{
//Hidden Local Add New Within Folder Folder Folder Folder Folder
// Dir? Dir CSIDl? NT5? Local Resource ID Name Location Resource Resource
// Settings DLL ID
{TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_APPDATA, TEXT("AppData"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_APP_DATA}, // AppData
{TRUE, FALSE, TRUE, TRUE, FALSE, IDS_SH_COOKIES, TEXT("Cookies"), {0}, TEXT("shell32.dll"), 0}, // Cookies
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_DESKTOP, TEXT("Desktop"), {0}, TEXT("shell32.dll"), 0}, // Desktop
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_FAVORITES, TEXT("Favorites"), {0}, TEXT("shell32.dll"), 0}, // Favorites
{TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_NETHOOD, TEXT("NetHood"), {0}, TEXT("shell32.dll"), 0}, // NetHood
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PERSONAL, TEXT("Personal"), {0}, TEXT("shell32.dll"), 0}, // My Documents
{TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PRINTHOOD, TEXT("PrintHood"), {0}, TEXT("shell32.dll"), 0}, // PrintHood
{TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_RECENT, TEXT("Recent"), {0}, TEXT("shell32.dll"), 0}, // Recent
{TRUE, FALSE, TRUE, FALSE, FALSE, IDS_SH_SENDTO, TEXT("SendTo"), {0}, TEXT("shell32.dll"), 0}, // SendTo
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_STARTMENU, TEXT("Start Menu"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_START_MENU}, // Start Menu
{TRUE, FALSE, TRUE, TRUE, FALSE, IDS_SH_TEMPLATES, TEXT("Templates"), {0}, TEXT("shell32.dll"), 0}, // Templates
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_PROGRAMS, TEXT("Programs"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_PROGRAMS}, // Programs
{FALSE, FALSE, TRUE, FALSE, FALSE, IDS_SH_STARTUP, TEXT("Startup"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_STARTUP}, // Startup
{TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_LOCALSETTINGS, TEXT("Local Settings"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_LOCALSETTINGS}, // Local Settings
{TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_LOCALAPPDATA, TEXT("Local AppData"), {0}, TEXT("shell32.dll"), 0}, // Local AppData
{TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_CACHE, TEXT("Cache"), {0}, TEXT("shell32.dll"), 0}, // Temporary Internet Files
{TRUE, TRUE, TRUE, TRUE, TRUE, IDS_SH_HISTORY, TEXT("History"), {0}, TEXT("shell32.dll"), 0}, // History
{FALSE, TRUE, FALSE, TRUE, TRUE, IDS_SH_TEMP, TEXT("Temp"), {0}, TEXT("shell32.dll"), 0}, // Temp
};
FOLDER_INFO c_CommonShellFolders[] =
{
{FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_DESKTOP, TEXT("Common Desktop"), {0}, TEXT("shell32.dll"), 0}, // Common Desktop
{FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_STARTMENU, TEXT("Common Start Menu"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_START_MENU}, // Common Start Menu
{FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_PROGRAMS, TEXT("Common Programs"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_PROGRAMS}, // Common Programs
{FALSE, TRUE, TRUE, FALSE, FALSE, IDS_SH_STARTUP, TEXT("Common Startup"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_STARTUP}, // Common Startup
{TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_APPDATA, TEXT("Common AppData"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_APP_DATA}, // Common Application Data
{TRUE, TRUE, TRUE, TRUE, FALSE, IDS_SH_TEMPLATES, TEXT("Common Templates"), {0}, TEXT("shell32.dll"), 0}, // Common Templates
{FALSE, TRUE, TRUE, TRUE, FALSE, IDS_SH_FAVORITES, TEXT("Common Favorites"), {0}, TEXT("shell32.dll"), 0}, // Common Favorites
{FALSE, TRUE, TRUE, TRUE, FALSE, IDS_SH_SHAREDDOCS, TEXT("Common Documents"), {0}, TEXT("shell32.dll"), IDS_LOCALGDN_FLD_SHARED_DOC}, // Common Documents
};
//
// Function proto-types
//
void InitializeProductType (void);
BOOL DetermineLocalSettingsLocation(LPTSTR szLocalSettings);
//*************************************************************
//
// PatchLocalSettings()
//
// Purpose: Initializes the LocalSettingsFolder correctly
//
// Parameters: hInstance - DLL instance handle
//
// Return: void
//
// Comments:
//
// History: Date Author Comment
// 10/13/95 ushaji Created
//
//
// Comments:
// Should remove this post NT5 and restructure to take care of the
// NT4 Localisation Problems
//
//*************************************************************
void PatchLocalAppData(HANDLE hToken)
{
TCHAR szLocalSettingsPath[MAX_PATH];
TCHAR szLocalAppData[MAX_PATH];
LPTSTR lpEnd = NULL, lpLocalAppDataFolder;
HANDLE hTokenOld=NULL;
HKEY hKeyRoot, hKey;
DWORD dwIndex;
if (!ImpersonateUser (hToken, &hTokenOld))
return;
if (RegOpenCurrentUser(KEY_READ, &hKeyRoot) == ERROR_SUCCESS) {
if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueEx (hKey, TEXT("Local AppData"), NULL, NULL,
NULL, NULL) == ERROR_SUCCESS) {
RegCloseKey(hKey);
RegCloseKey(hKeyRoot);
RevertToUser(&hTokenOld);
return;
}
RegCloseKey(hKey);
}
RegCloseKey(hKeyRoot);
}
//
// Impersonate and determine the user's localsettings
//
DetermineLocalSettingsLocation(szLocalSettingsPath);
RevertToUser(&hTokenOld);
lstrcpy(szLocalAppData, TEXT("%userprofile%"));
//
// Set the Local AppData Folder after %userprofile% so that we
// we can update the global variable below.
//
lpEnd = lpLocalAppDataFolder = CheckSlash(szLocalAppData);
lstrcat(szLocalAppData, szLocalSettingsPath);
lpEnd = CheckSlash(szLocalAppData);
LoadString(g_hDllInstance, IDS_SH_LOCALAPPDATA, lpEnd, MAX_FOLDER_SIZE);
//
// Construct the path and let it be set.
//
SetFolderPath(CSIDL_LOCAL_APPDATA | CSIDL_FLAG_DONT_UNEXPAND, hToken, szLocalAppData);
//
// the global variable should be reset by the time it gets used.
// No Need to reset it here, but let us be safer.
//
for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++)
if (c_ShellFolders[dwIndex].iFolderID == IDS_SH_LOCALAPPDATA)
lstrcpy(c_ShellFolders[dwIndex].szFolderLocation, lpLocalAppDataFolder);
}
//*************************************************************
//
// InitializeGlobals()
//
// Purpose: Initializes all the globals variables
// at DLL load time.
//
// Parameters: hInstance - DLL instance handle
//
// Return: void
//
// Comments:
//
// History: Date Author Comment
// 10/13/95 ericflo Created
//
//*************************************************************
void InitializeGlobals (HINSTANCE hInstance)
{
OSVERSIONINFO ver;
DWORD dwIndex, dwSize, dwType;
HKEY hKey, hKeyRoot;
TCHAR szTemp[MAX_PATH];
TCHAR szTemp2[MAX_PATH];
TCHAR szTemp3[MAX_PATH];
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
LPTSTR lpEnd;
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
PACL pAcl = NULL;
PSID pSidAdmin = NULL, pSidSystem = NULL;
DWORD cbAcl;
BOOL bDefaultSecurity = FALSE;
//
// Save the instance handle
//
g_hDllInstance = hInstance;
//
// Save the number of shell folders
//
g_dwNumShellFolders = ARRAYSIZE(c_ShellFolders);
g_dwNumCommonShellFolders = ARRAYSIZE(c_CommonShellFolders);
//
// Query the build number
//
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ver);
g_dwBuildNumber = (DWORD) LOWORD(ver.dwBuildNumber);
//
// Initialize the product type
//
InitializeProductType ();
//
// Open the user profile setup event. This event is set to non-signalled
// anytime the default user profile is being updated. This blocks
// LoadUserProfile until the update is finished.
//
if (!g_hProfileSetup) {
//
// Get the system sid
//
if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, &pSidSystem)) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize system sid. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
//
// Get the Admin sid
//
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
0, 0, 0, 0, &pSidAdmin)) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize admin sid. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
cbAcl = (GetLengthSid (pSidSystem)) +
(GetLengthSid (pSidAdmin)) +
sizeof(ACL) +
(2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
if (!pAcl) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to allocate memory for acl. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to initialize acl. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSidSystem)) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to add system ace. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSidAdmin)) {
DebugMsg((DM_WARNING, TEXT("InitializeGlobals: Failed to add builtin admin ace. Error = %d"), GetLastError()));
bDefaultSecurity = TRUE;
goto DefaultSecurity;
}
//
// Put together the security descriptor
//
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl (
&sd,
TRUE, // Dacl present
pAcl, // Dacl
FALSE // Not defaulted
);
DefaultSecurity:
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
if (bDefaultSecurity) {
sa.lpSecurityDescriptor = NULL;
}
else {
sa.lpSecurityDescriptor = &sd;
}
g_hProfileSetup = CreateEvent (&sa, TRUE, TRUE, USER_PROFILE_SETUP_EVENT);
if (!g_hProfileSetup) {
DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: Failed to create profile setup event with %d"), GetLastError()));
}
if (pAcl) {
GlobalFree (pAcl);
}
if (pSidSystem) {
FreeSid(pSidSystem);
}
if (pSidAdmin) {
FreeSid(pSidAdmin);
}
}
//
// Now load the directory names that match
// the special folders
//
for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++) {
LoadString(hInstance, c_ShellFolders[dwIndex].iFolderID,
c_ShellFolders[dwIndex].szFolderLocation, MAX_FOLDER_SIZE);
}
for (dwIndex = 0; dwIndex < g_dwNumCommonShellFolders; dwIndex++) {
LoadString(hInstance, c_CommonShellFolders[dwIndex].iFolderID,
c_CommonShellFolders[dwIndex].szFolderLocation, MAX_FOLDER_SIZE);
}
//
// Special case for the Personal / My Documents folder. NT4 used a folder
// called "Personal" for document storage. NT5 renamed this folder to
// My Documents. In the upgrade case from NT4 to NT5, if the user already
// had information in "Personal", that name was preserved (for compatibility
// reasons) and the My Pictures folder is created inside of Personal.
// We need to make sure and fix up the My Documents and My Pictures entries
// in the global array so they have the correct directory names.
//
if (RegOpenCurrentUser(KEY_READ, &hKeyRoot) == ERROR_SUCCESS) {
if (RegOpenKeyEx (hKeyRoot, USER_SHELL_FOLDERS,
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
dwSize = sizeof(szTemp3);
szTemp3[0] = TEXT('\0');
if (RegQueryValueEx (hKey, TEXT("Personal"), NULL, &dwType,
(LPBYTE) szTemp3, &dwSize) == ERROR_SUCCESS) {
LoadString (g_hDllInstance, IDS_SH_PERSONAL2, szTemp2, ARRAYSIZE(szTemp2));
lstrcpy (szTemp, TEXT("%USERPROFILE%\\"));
lstrcat (szTemp, szTemp2);
if (lstrcmpi(szTemp, szTemp3) == 0) {
LoadString(hInstance, IDS_SH_PERSONAL2,
c_ShellFolders[5].szFolderLocation, MAX_FOLDER_SIZE);
}
}
//
// Special Case for Local Settings.
// Due to localisations LocalSettings can be pointing to different places in nt4 and rc might
// not be in sync with the current value. Read the LocalSettings value first and then
// update everything else afterwards.
//
dwSize = sizeof(szTemp2);
*szTemp = *szTemp2 = TEXT('\0');
//
// Read the value from the registry if it is available
//
if (RegQueryValueEx (hKey, TEXT("Local Settings"), NULL, &dwType,
(LPBYTE) szTemp2, &dwSize) != ERROR_SUCCESS) {
//
// if the value is not present load it from the rc file
//
LoadString(hInstance, IDS_SH_LOCALSETTINGS, szTemp, MAX_FOLDER_SIZE);
DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder from the rc is %s"), szTemp));
}
else {
//
// The registry value read from the registry is the full unexpanded path.
//
if (lstrlen(szTemp2) > lstrlen(TEXT("%userprofile%"))) {
lstrcpy(szTemp, szTemp2+(lstrlen(TEXT("%userprofile%"))+1));
DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder from the reigtry is %s"), szTemp));
}
else {
LoadString(hInstance, IDS_SH_LOCALSETTINGS, szTemp, MAX_FOLDER_SIZE);
DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: local settings folder(2) from the rc is %s"), szTemp));
}
}
lpEnd = CheckSlash(szTemp);
for (dwIndex = 0; dwIndex < g_dwNumShellFolders; dwIndex++) {
//
// Fix up all LocalSettings related shfolders
//
if (lstrcmpi(c_ShellFolders[dwIndex].lpFolderName, TEXT("Local Settings")) == 0) {
*lpEnd = TEXT('\0');
//
// Don't copy the final slash
//
lstrcpyn(c_ShellFolders[dwIndex].szFolderLocation, szTemp, lstrlen(szTemp));
}
if (c_ShellFolders[dwIndex].bLocalSettings) {
LoadString(hInstance, c_ShellFolders[dwIndex].iFolderID,
szTemp3, MAX_FOLDER_SIZE);
//
// Append localsetting value read above to the end of %userprofile%
// before putting on the shell folder itself
//
lstrcpy(lpEnd, szTemp3);
lstrcpy(c_ShellFolders[dwIndex].szFolderLocation, szTemp);
DebugMsg((DM_VERBOSE, TEXT("InitializeGlobals: Shell folder %s is %s"), c_ShellFolders[dwIndex].lpFolderName,
c_ShellFolders[dwIndex].szFolderLocation));
}
}
RegCloseKey (hKey);
}
RegCloseKey (hKeyRoot);
}
//
// Get string version of registry extension guid
//
GuidToString( &guidRegistryExt, c_szRegistryExtName );
}
//*************************************************************
//
// InitializeProductType()
//
// Purpose: Determines the current product type and
// sets the g_ProductType global variable.
//
// Parameters: void
//
// Return: void
//
// Comments:
//
// History: Date Author Comment
// 4/08/96 ericflo Created
//
//*************************************************************
void InitializeProductType (void)
{
#ifdef WINNT
HKEY hkey;
LONG lResult;
TCHAR szProductType[50];
DWORD dwType, dwSize;
//
// Default product type is workstation.
//
g_ProductType = PT_WORKSTATION;
//
// Query the registry for the product type.
//
lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\ProductOptions"),
0,
KEY_READ,
&hkey);
if (lResult != ERROR_SUCCESS) {
DebugMsg((DM_WARNING, TEXT("InitializeProductType: Failed to open registry (%d)"), lResult));
goto Exit;
}
dwSize = 50;
szProductType[0] = TEXT('\0');
lResult = RegQueryValueEx (hkey,
TEXT("ProductType"),
NULL,
&dwType,
(LPBYTE) szProductType,
&dwSize);
RegCloseKey (hkey);
if (lResult != ERROR_SUCCESS) {
DebugMsg((DM_WARNING, TEXT("InitializeProductType: Failed to query product type (%d)"), lResult));
goto Exit;
}
//
// Map the product type string to the enumeration value.
//
if (!lstrcmpi (szProductType, TEXT("WinNT"))) {
g_ProductType = PT_WORKSTATION;
} else if (!lstrcmpi (szProductType, TEXT("ServerNT"))) {
g_ProductType = PT_SERVER;
} else if (!lstrcmpi (szProductType, TEXT("LanmanNT"))) {
g_ProductType = PT_DC;
} else {
DebugMsg((DM_WARNING, TEXT("InitializeProductType: Unknown product type! <%s>"), szProductType));
}
Exit:
DebugMsg((DM_VERBOSE, TEXT("InitializeProductType: Product Type: %d"), g_ProductType));
#else // WINNT
//
// Windows only has 1 product type
//
g_ProductType = PT_WINDOWS;
#endif
}