645 lines
21 KiB
C
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
|
|
|
|
}
|