//************************************************************* // // Global Variables // // Microsoft Confidential // Copyright (c) Microsoft Corporation 1995 // All rights reserved // //************************************************************* #include "uenv.h" #include 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 }