Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

950 lines
29 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
sgmutil.c
Abstract:
Implements basic utilities used for source data gathering.
Author:
Jim Schmidt (jimschm) 14-May-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "v1p.h"
#define DBG_FOO "Foo"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
// None
//
// Globals
//
// None
//
// Macro expansion list
//
#define USER_SHELL_FOLDERS \
DEFMAC(CSIDL_APPDATA, TEXT("AppData"), TEXT("CSIDL_APPDATA")) \
DEFMAC(CSIDL_APPDATA, TEXT("AppData"), TEXT("APPDATA")) \
DEFMAC(CSIDL_ADMINTOOLS, TEXT("Administrative Tools"), TEXT("CSIDL_ADMINTOOLS")) \
DEFMAC(CSIDL_ALTSTARTUP, TEXT("AltStartup"), TEXT("CSIDL_ALTSTARTUP")) \
DEFMAC(CSIDL_BITBUCKET, TEXT("RecycleBinFolder"), TEXT("CSIDL_BITBUCKET")) \
DEFMAC(CSIDL_CONTROLS, TEXT("ControlPanelFolder"), TEXT("CSIDL_CONTROLS")) \
DEFMAC(CSIDL_COOKIES, TEXT("Cookies"), TEXT("CSIDL_COOKIES")) \
DEFMAC(CSIDL_DESKTOP, TEXT("Desktop"), TEXT("CSIDL_DESKTOP")) \
DEFMAC(CSIDL_DESKTOPDIRECTORY, TEXT("Desktop"), TEXT("CSIDL_DESKTOPDIRECTORY")) \
DEFMAC(CSIDL_DRIVES, TEXT("DriveFolder"), TEXT("CSIDL_DRIVES")) \
DEFMAC(CSIDL_FAVORITES, TEXT("Favorites"), TEXT("CSIDL_FAVORITES")) \
DEFMAC(CSIDL_FONTS, TEXT("Fonts"), TEXT("CSIDL_FONTS")) \
DEFMAC(CSIDL_HISTORY, TEXT("History"), TEXT("CSIDL_HISTORY")) \
DEFMAC(CSIDL_INTERNET, TEXT("InternetFolder"), TEXT("CSIDL_INTERNET")) \
DEFMAC(CSIDL_INTERNET_CACHE, TEXT("Cache"), TEXT("CSIDL_INTERNET_CACHE")) \
DEFMAC(CSIDL_LOCAL_APPDATA, TEXT("Local AppData"), TEXT("CSIDL_LOCAL_APPDATA")) \
DEFMAC(CSIDL_MYPICTURES, TEXT("My Pictures"), TEXT("CSIDL_MYPICTURES")) \
DEFMAC(CSIDL_NETHOOD, TEXT("NetHood"), TEXT("CSIDL_NETHOOD")) \
DEFMAC(CSIDL_NETWORK, TEXT("NetworkFolder"), TEXT("CSIDL_NETWORK")) \
DEFMAC(CSIDL_PERSONAL, TEXT("Personal"), TEXT("CSIDL_PERSONAL")) \
DEFMAC(CSIDL_PROFILE, TEXT("Profile"), TEXT("CSIDL_PROFILE")) \
DEFMAC(CSIDL_PROGRAM_FILES, TEXT("ProgramFiles"), TEXT("CSIDL_PROGRAM_FILES")) \
DEFMAC(CSIDL_PROGRAM_FILES, TEXT("ProgramFiles"), TEXT("PROGRAMFILES")) \
DEFMAC(CSIDL_PROGRAM_FILES_COMMON, TEXT("CommonProgramFiles"), TEXT("CSIDL_PROGRAM_FILES_COMMON")) \
DEFMAC(CSIDL_PROGRAM_FILES_COMMON, TEXT("CommonProgramFiles"), TEXT("COMMONPROGRAMFILES")) \
DEFMAC(CSIDL_PROGRAMS, TEXT("Programs"), TEXT("CSIDL_PROGRAMS")) \
DEFMAC(CSIDL_RECENT, TEXT("Recent"), TEXT("CSIDL_RECENT")) \
DEFMAC(CSIDL_SENDTO, TEXT("SendTo"), TEXT("CSIDL_SENDTO")) \
DEFMAC(CSIDL_STARTMENU, TEXT("Start Menu"), TEXT("CSIDL_STARTMENU")) \
DEFMAC(CSIDL_STARTUP, TEXT("Startup"), TEXT("CSIDL_STARTUP")) \
DEFMAC(CSIDL_SYSTEM, TEXT("System"), TEXT("CSIDL_SYSTEM")) \
DEFMAC(CSIDL_TEMPLATES, TEXT("Templates"), TEXT("CSIDL_TEMPLATES")) \
DEFMAC(CSIDL_WINDOWS, TEXT("Windows"), TEXT("CSIDL_WINDOWS")) \
DEFMAC(CSIDL_MYDOCUMENTS, TEXT("My Documents"), TEXT("CSIDL_MYDOCUMENTS")) \
DEFMAC(CSIDL_MYMUSIC, TEXT("My Music"), TEXT("CSIDL_MYMUSIC")) \
DEFMAC(CSIDL_MYVIDEO, TEXT("My Video"), TEXT("CSIDL_MYVIDEO")) \
DEFMAC(CSIDL_SYSTEMX86, TEXT("SystemX86"), TEXT("CSIDL_SYSTEMX86")) \
DEFMAC(CSIDL_PROGRAM_FILESX86, TEXT("ProgramFilesX86"), TEXT("CSIDL_PROGRAM_FILESX86")) \
DEFMAC(CSIDL_PROGRAM_FILES_COMMONX86, TEXT("CommonProgramFilesX86"), TEXT("CSIDL_PROGRAM_FILES_COMMONX86")) \
DEFMAC(CSIDL_CONNECTIONS, TEXT("ConnectionsFolder"), TEXT("CSIDL_CONNECTIONS")) \
#define COMMON_SHELL_FOLDERS \
DEFMAC(CSIDL_COMMON_ADMINTOOLS, TEXT("Common Administrative Tools"), TEXT("CSIDL_COMMON_ADMINTOOLS")) \
DEFMAC(CSIDL_COMMON_ALTSTARTUP, TEXT("Common AltStartup"), TEXT("CSIDL_COMMON_ALTSTARTUP")) \
DEFMAC(CSIDL_COMMON_APPDATA, TEXT("Common AppData"), TEXT("CSIDL_COMMON_APPDATA")) \
DEFMAC(CSIDL_COMMON_DESKTOPDIRECTORY, TEXT("Common Desktop"), TEXT("CSIDL_COMMON_DESKTOPDIRECTORY")) \
DEFMAC(CSIDL_COMMON_DOCUMENTS, TEXT("Common Documents"), TEXT("CSIDL_COMMON_DOCUMENTS")) \
DEFMAC(CSIDL_COMMON_FAVORITES, TEXT("Common Favorites"), TEXT("CSIDL_COMMON_FAVORITES")) \
DEFMAC(CSIDL_COMMON_PROGRAMS, TEXT("Common Programs"), TEXT("CSIDL_COMMON_PROGRAMS")) \
DEFMAC(CSIDL_COMMON_STARTMENU, TEXT("Common Start Menu"), TEXT("CSIDL_COMMON_STARTMENU")) \
DEFMAC(CSIDL_COMMON_STARTUP, TEXT("Common Startup"), TEXT("CSIDL_COMMON_STARTUP")) \
DEFMAC(CSIDL_COMMON_TEMPLATES, TEXT("Common Templates"), TEXT("CSIDL_COMMON_TEMPLATES")) \
#define ENVIRONMENT_VARIABLES \
DEFMAC(TEXT("WINDIR")) \
DEFMAC(TEXT("SYSTEMROOT")) \
DEFMAC(TEXT("SYSTEM16")) \
DEFMAC(TEXT("SYSTEM32")) \
DEFMAC(TEXT("SYSTEM")) \
DEFMAC(TEXT("ALLUSERSPROFILE")) \
DEFMAC(TEXT("USERPROFILE")) \
DEFMAC(TEXT("PROFILESFOLDER")) \
DEFMAC(TEXT("APPDATA")) \
DEFMAC(TEXT("CSIDL_APPDATA")) \
DEFMAC(TEXT("CSIDL_ADMINTOOLS")) \
DEFMAC(TEXT("CSIDL_ALTSTARTUP")) \
DEFMAC(TEXT("CSIDL_BITBUCKET")) \
DEFMAC(TEXT("CSIDL_COMMON_ADMINTOOLS")) \
DEFMAC(TEXT("CSIDL_COMMON_ALTSTARTUP")) \
DEFMAC(TEXT("CSIDL_COMMON_APPDATA")) \
DEFMAC(TEXT("CSIDL_COMMON_DESKTOPDIRECTORY")) \
DEFMAC(TEXT("CSIDL_COMMON_DOCUMENTS")) \
DEFMAC(TEXT("CSIDL_COMMON_FAVORITES")) \
DEFMAC(TEXT("CSIDL_COMMON_PROGRAMS")) \
DEFMAC(TEXT("CSIDL_COMMON_STARTMENU")) \
DEFMAC(TEXT("CSIDL_COMMON_STARTUP")) \
DEFMAC(TEXT("CSIDL_COMMON_TEMPLATES")) \
DEFMAC(TEXT("CSIDL_CONTROLS")) \
DEFMAC(TEXT("CSIDL_COOKIES")) \
DEFMAC(TEXT("CSIDL_DESKTOP")) \
DEFMAC(TEXT("CSIDL_DESKTOPDIRECTORY")) \
DEFMAC(TEXT("CSIDL_DRIVES")) \
DEFMAC(TEXT("CSIDL_FAVORITES")) \
DEFMAC(TEXT("CSIDL_FONTS")) \
DEFMAC(TEXT("CSIDL_HISTORY")) \
DEFMAC(TEXT("CSIDL_INTERNET")) \
DEFMAC(TEXT("CSIDL_INTERNET_CACHE")) \
DEFMAC(TEXT("CSIDL_LOCAL_APPDATA")) \
DEFMAC(TEXT("CSIDL_MYPICTURES")) \
DEFMAC(TEXT("CSIDL_NETHOOD")) \
DEFMAC(TEXT("CSIDL_NETWORK")) \
DEFMAC(TEXT("CSIDL_PERSONAL")) \
DEFMAC(TEXT("CSIDL_PRINTERS")) \
DEFMAC(TEXT("CSIDL_PRINTHOOD")) \
DEFMAC(TEXT("CSIDL_PROFILE")) \
DEFMAC(TEXT("CSIDL_PROGRAM_FILES")) \
DEFMAC(TEXT("ProgramFiles")) \
DEFMAC(TEXT("CSIDL_PROGRAM_FILES_COMMON")) \
DEFMAC(TEXT("CommonProgramFiles")) \
DEFMAC(TEXT("CSIDL_PROGRAMS")) \
DEFMAC(TEXT("CSIDL_RECENT")) \
DEFMAC(TEXT("CSIDL_SENDTO")) \
DEFMAC(TEXT("CSIDL_STARTMENU")) \
DEFMAC(TEXT("CSIDL_STARTUP")) \
DEFMAC(TEXT("CSIDL_SYSTEM")) \
DEFMAC(TEXT("CSIDL_TEMPLATES")) \
DEFMAC(TEXT("CSIDL_WINDOWS")) \
DEFMAC(TEXT("CSIDL_MYDOCUMENTS")) \
DEFMAC(TEXT("CSIDL_MYMUSIC")) \
DEFMAC(TEXT("CSIDL_MYVIDEO")) \
DEFMAC(TEXT("CSIDL_SYSTEMX86")) \
DEFMAC(TEXT("CSIDL_PROGRAM_FILESX86")) \
DEFMAC(TEXT("CSIDL_PROGRAM_FILES_COMMONX86")) \
DEFMAC(TEXT("CSIDL_CONNECTIONS")) \
DEFMAC(TEXT("TEMP")) \
DEFMAC(TEXT("TMP")) \
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
/*++
The shell folder functions here are duplicates of the RAS code. This is not
a good solution (we have two copies of the same code), but the designed
solution requires engine scope support. Scopes are the mechanism in which
major groups of data are separated from each other, such as the separation
of multiple users. A scope provides properties that affect objects within
the scope. For example, a user scope has properties such as domain name,
profile path, sid, and so on.
In order not to duplicate this code but still maintain modularity and system
independence, a scope module is needed for users. So instead of the code
below, the code would be something like
property = IsmGetScopeProperty ("userprofile");
This will be implemented if we want to (A) support multiple scopes, (B)
eliminate physical system access in non-type modules, or (C) clean up this
duplicated code.
--*/
typedef HRESULT (WINAPI SHGETFOLDERPATH)(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, PTSTR pszPath);
typedef SHGETFOLDERPATH * PSHGETFOLDERPATH;
HANDLE
pGetShFolderLib (
VOID
)
{
static HANDLE lib;
if (lib) {
return lib;
}
lib = LoadLibrary (TEXT("shfolder.dll"));
if (!lib) {
LOG ((LOG_ERROR, (PCSTR) MSG_SHFOLDER_LOAD_ERROR));
}
return lib;
}
PTSTR
pFindSfPath (
IN PCTSTR FolderStr,
IN BOOL UserFolder
)
{
HKEY key;
REGSAM prevMode;
PCTSTR data;
PCTSTR result = NULL;
if (!result) {
if (UserFolder) {
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"));
SetRegOpenAccessMode (prevMode);
} else {
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"));
SetRegOpenAccessMode (prevMode);
}
if (key) {
data = GetRegValueString (key, FolderStr);
if (data) {
result = DuplicatePathString (data, 0);
FreeAlloc (data);
}
CloseRegKey (key);
}
}
if (!result) {
if (UserFolder) {
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"));
SetRegOpenAccessMode (prevMode);
} else {
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"));
SetRegOpenAccessMode (prevMode);
}
if (key) {
data = GetRegValueString (key, FolderStr);
if (data) {
result = DuplicatePathString (data, 0);
FreeAlloc (data);
}
CloseRegKey (key);
}
}
return (PTSTR) result;
}
PCTSTR
GetShellFolderPath (
IN INT Folder,
IN PCTSTR FolderStr,
IN BOOL UserFolder,
OUT PTSTR Buffer
)
{
HRESULT result;
LPITEMIDLIST pidl;
BOOL b;
LPMALLOC mallocFn;
HANDLE lib;
PSHGETFOLDERPATH shGetFolderPath;
PCTSTR sfPath = NULL;
PCTSTR expandedPath = NULL;
PTSTR endPtr = NULL;
TCHAR currUserProfile[MAX_TCHAR_PATH];
MIG_USERDATA userData;
result = SHGetMalloc (&mallocFn);
if (result != S_OK) {
return NULL;
}
if (FolderStr) {
//
// First try to find this in Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
//
sfPath = pFindSfPath (FolderStr, UserFolder);
if (sfPath && *sfPath) {
//
// We found it.
//
StringCopyTcharCount (Buffer, sfPath, MAX_PATH);
expandedPath = IsmExpandEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, sfPath, NULL);
FreePathString (sfPath);
sfPath = NULL;
if (expandedPath && *expandedPath) {
StringCopyTcharCount (Buffer, expandedPath, MAX_PATH);
}
if (expandedPath) {
IsmReleaseMemory (expandedPath);
}
if (IsmGetMappedUserData (&userData)) {
// we have a mapped user, try to build it's default shell folder location
GetUserProfileRootPath (currUserProfile);
if (StringIMatch (currUserProfile, Buffer)) {
StringCopyTcharCount (Buffer, userData.UserProfileRoot, MAX_PATH);
} else {
AppendWack (currUserProfile);
if (StringIMatchTcharCount (currUserProfile, Buffer, TcharCount (currUserProfile))) {
endPtr = Buffer + TcharCount (currUserProfile);
sfPath = JoinPaths (userData.UserProfileRoot, endPtr);
StringCopyTcharCount (Buffer, sfPath, MAX_PATH);
FreePathString (sfPath);
}
}
}
return Buffer;
}
if (sfPath) {
FreePathString (sfPath);
}
lib = pGetShFolderLib ();
if (lib) {
#ifdef UNICODE
(FARPROC) shGetFolderPath = GetProcAddress (lib, "SHGetFolderPathW");
#else
(FARPROC) shGetFolderPath = GetProcAddress (lib, "SHGetFolderPathA");
#endif
if (shGetFolderPath) {
result = shGetFolderPath (NULL, Folder, NULL, 1, Buffer);
if (result != S_OK) {
return NULL;
}
expandedPath = IsmExpandEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, Buffer, NULL);
if (expandedPath && *expandedPath) {
StringCopyTcharCount (Buffer, expandedPath, MAX_PATH);
}
if (expandedPath) {
IsmReleaseMemory (expandedPath);
expandedPath = NULL;
}
if (IsmGetMappedUserData (&userData)) {
// we have a mapped user, try to build it's default shell folder location
GetUserProfileRootPath (currUserProfile);
if (StringIMatch (currUserProfile, Buffer)) {
StringCopyTcharCount (Buffer, userData.UserProfileRoot, MAX_PATH);
} else {
AppendWack (currUserProfile);
if (StringIMatchTcharCount (currUserProfile, Buffer, TcharCount (currUserProfile))) {
endPtr = Buffer + TcharCount (currUserProfile);
sfPath = JoinPaths (userData.UserProfileRoot, endPtr);
StringCopyTcharCount (Buffer, sfPath, MAX_PATH);
FreePathString (sfPath);
}
}
return Buffer;
} else {
// no mapped user, use the current user's path
result = shGetFolderPath (NULL, Folder, NULL, 0, Buffer);
}
if (result != S_OK) {
return NULL;
}
expandedPath = IsmExpandEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, Buffer, NULL);
if (expandedPath && *expandedPath) {
StringCopyTcharCount (Buffer, expandedPath, MAX_PATH);
}
if (expandedPath) {
IsmReleaseMemory (expandedPath);
expandedPath = NULL;
}
return Buffer;
} else {
result = SHGetSpecialFolderLocation (NULL, Folder, &pidl);
}
} else {
result = SHGetSpecialFolderLocation (NULL, Folder, &pidl);
}
if (result != S_OK) {
return NULL;
}
b = SHGetPathFromIDList (pidl, Buffer);
} else {
result = SHGetSpecialFolderLocation (NULL, Folder, &pidl);
if (result != S_OK) {
return NULL;
}
b = SHGetPathFromIDList (pidl, Buffer);
}
IMalloc_Free (mallocFn, pidl);
return b ? Buffer : NULL;
}
PCTSTR
GetAllUsersProfilePath (
OUT PTSTR Buffer
)
{
HKEY key;
REGSAM prevMode;
PCTSTR data;
PCTSTR expData;
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"));
SetRegOpenAccessMode (prevMode);
if (key) {
data = GetRegValueString (key, TEXT("ProfilesDirectory"));
if (data) {
expData = IsmExpandEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, data, NULL);
StringCopyByteCount (Buffer, expData, MAX_PATH);
IsmReleaseMemory (expData);
FreeAlloc (data);
} else {
GetWindowsDirectory (Buffer, MAX_PATH);
StringCopy (AppendWack (Buffer), TEXT("Profiles"));
}
data = GetRegValueString (key, TEXT("AllUsersProfile"));
if (data) {
StringCopy (AppendWack (Buffer), data);
FreeAlloc (data);
} else {
StringCopy (AppendWack (Buffer), TEXT("All Users"));
}
CloseRegKey (key);
return Buffer;
}
GetWindowsDirectory (Buffer, MAX_PATH);
return Buffer;
}
PCTSTR
GetProfilesFolderPath (
OUT PTSTR Buffer
)
{
HKEY key;
REGSAM prevMode;
PCTSTR data;
PCTSTR expData;
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"));
SetRegOpenAccessMode (prevMode);
if (key) {
data = GetRegValueString (key, TEXT("ProfilesDirectory"));
if (data) {
expData = IsmExpandEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, data, NULL);
StringCopyByteCount (Buffer, expData, MAX_PATH);
IsmReleaseMemory (expData);
FreeAlloc (data);
} else {
GetWindowsDirectory (Buffer, MAX_PATH);
StringCopy (AppendWack (Buffer), TEXT("Profiles"));
}
CloseRegKey (key);
return Buffer;
}
GetWindowsDirectory (Buffer, MAX_PATH);
return Buffer;
}
PCTSTR
GetUserProfileRootPath (
OUT PTSTR Buffer
)
{
HKEY key;
REGSAM prevMode;
PDWORD data;
DWORD size;
//
// For Win2k and higher, use the shell
//
if (GetShellFolderPath (CSIDL_PROFILE, NULL, FALSE, Buffer)) {
return Buffer;
}
//
// For NT 4, use the environment
//
if (GetEnvironmentVariable (TEXT("USERPROFILE"), Buffer, MAX_PATH)) {
return Buffer;
}
//
// For Win9x, are profiles enabled? If so, return %windir%\profiles\%user%.
// If not, return %windir%.
//
GetWindowsDirectory (Buffer, MAX_PATH);
prevMode = SetRegOpenAccessMode (KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS);
key = OpenRegKeyStr (TEXT("HKLM\\Network\\Logon"));
SetRegOpenAccessMode (prevMode);
if (key) {
data = GetRegValueDword (key, TEXT("UserProfiles"));
if (data && *data) {
StringCat (Buffer, TEXT("\\Profiles\\"));
size = MAX_PATH;
GetUserName (GetEndOfString (Buffer), &size);
FreeAlloc (data);
}
CloseRegKey (key);
}
return Buffer;
}
PCTSTR
IsValidUncPath (
IN PCTSTR Path
)
{
BOOL needNonWack = FALSE;
BOOL wackRequired = TRUE;
INT wacks = 0;
while (*Path) {
if (_tcsnextc (Path) == TEXT('\\')) {
if (needNonWack) {
break;
}
wacks++;
if (wacks != 1) {
needNonWack = TRUE;
wackRequired = FALSE;
}
Path++;
} else {
//
// Note: it would be nice to validate the non-wack characters against the
// legal unc charset
//
if (needNonWack) {
if (wacks == 3) {
//
// Found \\x\x syntax; it's a UNC path
//
do {
Path = _tcsinc (Path);
} while (*Path && _tcsnextc (Path) != TEXT('\\'));
MYASSERT (*Path == 0 || *Path == TEXT('\\'));
return Path;
}
needNonWack = FALSE;
}
if (wackRequired) {
break;
}
Path = _tcsinc (Path);
}
}
return NULL;
}
BOOL
IsValidFileSpec (
IN PCTSTR FileSpec
)
{
CHARTYPE ch;
BOOL result = TRUE;
for (;;) {
ch = (CHARTYPE) _tcsnextc (FileSpec);
if (ch == TEXT('*')) {
//
// Really can't say what the validity is!
//
break;
}
if (!_istalpha (ch) && ch != TEXT('?')) {
result = FALSE;
break;
}
ch = (CHARTYPE) _tcsnextc (FileSpec + 1);
if (ch == TEXT('*')) {
break;
}
if (ch != TEXT(':') && ch != TEXT('?')) {
result = FALSE;
break;
}
ch = (CHARTYPE) _tcsnextc (FileSpec + 2);
if (ch == 0) {
// this is something like "d:", it's valid
break;
}
if (ch == TEXT('*')) {
break;
}
if (ch != TEXT('\\') && ch != TEXT('?')) {
result = FALSE;
break;
}
break;
}
if (!result) {
result = (IsValidUncPath (FileSpec) != NULL);
}
return result;
}
VOID
pSetEnvironmentVar (
IN PMAPSTRUCT Map,
IN PMAPSTRUCT UndefMap, OPTIONAL
IN BOOL MapSourceToDest,
IN PCTSTR VariableName,
IN PCTSTR VariableData OPTIONAL
)
{
TCHAR encodedVariableName[128];
TCHAR buffer[MAX_TCHAR_PATH];
PCTSTR undefText;
//
// VariableData is NULL when VariableName is not present on the machine
//
if (MapSourceToDest) {
//
// MapSourceToDest tells us to map a source path (c:\windows) to
// a destination path (d:\winnt).
//
if (VariableData) {
if (IsmGetEnvironmentString (
PLATFORM_SOURCE,
S_SYSENVVAR_GROUP,
VariableName,
buffer,
ARRAYSIZE(buffer),
NULL
)) {
AddStringMappingPair (Map, buffer, VariableData);
}
}
return;
}
//
// MapSourceToDest is FALSE when we want to map environment variables
// to the actual path.
//
//
// VariableName length is hard-coded, so we know it does not exceed our
// buffer
//
wsprintf (encodedVariableName, TEXT("%%%s%%"), VariableName);
if (VariableData) {
IsmSetEnvironmentString (IsmGetRealPlatform (), S_SYSENVVAR_GROUP, VariableName, VariableData);
AddStringMappingPair (Map, encodedVariableName, VariableData);
} else if (UndefMap) {
//
// If no variable data, then put environment variable in the
// "undefined" variable mapping
//
undefText = JoinTextEx (NULL, TEXT("--> "), TEXT(" <--"), encodedVariableName, 0, NULL);
AddStringMappingPair (UndefMap, encodedVariableName, undefText);
FreeText (undefText);
}
}
VOID
AddRemappingEnvVar (
IN PMAPSTRUCT Map,
IN PMAPSTRUCT ReMap,
IN PMAPSTRUCT UndefMap, OPTIONAL
IN PCTSTR VariableName,
IN PCTSTR VariableData
)
{
pSetEnvironmentVar (Map, UndefMap, FALSE, VariableName, VariableData);
pSetEnvironmentVar (ReMap, UndefMap, TRUE, VariableName, VariableData);
}
VOID
SetIsmEnvironmentFromPhysicalMachine (
IN PMAPSTRUCT Map,
IN BOOL MapSourceToDest,
IN PMAPSTRUCT UndefMap OPTIONAL
)
{
TCHAR dir[MAX_TCHAR_PATH];
PCTSTR path;
PTSTR p;
MIG_USERDATA userData;
BOOL mappedUser = FALSE;
mappedUser = IsmGetMappedUserData (&userData);
//
// Prepare ISM environment variables. The ones added last have the highest priority when
// two or more variables map to the same path.
//
//
// ...user profile
//
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("ALLUSERSPROFILE"), GetAllUsersProfilePath (dir));
if (mappedUser) {
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("USERPROFILE"), userData.UserProfileRoot);
} else {
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("USERPROFILE"), GetUserProfileRootPath (dir));
}
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("PROFILESFOLDER"), GetProfilesFolderPath (dir));
//
// ...temp dir
//
if (GetTempPath (MAX_PATH, dir)) {
p = (PTSTR) FindLastWack (dir);
if (p) {
if (p[1] == 0) {
*p = 0;
}
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("TEMP"), dir);
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("TMP"), dir);
}
}
//
// ...windows directory env variable
//
GetWindowsDirectory (dir, ARRAYSIZE(dir));
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("WINDIR"), dir);
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("SYSTEMROOT"), dir);
//
// ...16-bit system directory. We invent SYSTEM16 and SYSTEM32 for use
// in scripts.
//
path = JoinPaths (dir, TEXT("system"));
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("SYSTEM16"), path);
FreePathString (path);
path = JoinPaths (dir, TEXT("system32"));
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("SYSTEM32"), path);
FreePathString (path);
//
// ...platform-specific system directory
//
GetSystemDirectory (dir, ARRAYSIZE(dir));
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, TEXT("SYSTEM"), dir);
//
// ...shell folders -- we invent all variables with the CSIDL_ prefix
//
#define DEFMAC(id,folder_str,var_name) \
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, var_name, \
GetShellFolderPath (id, folder_str, TRUE, dir));
USER_SHELL_FOLDERS
#undef DEFMAC
#define DEFMAC(id,folder_str,var_name) \
pSetEnvironmentVar (Map, UndefMap, MapSourceToDest, var_name, \
GetShellFolderPath (id, folder_str, FALSE, dir));
COMMON_SHELL_FOLDERS
#undef DEFMAC
}
VOID
pTransferEnvPath (
IN PCTSTR IsmVariableName,
IN PMAPSTRUCT DirectMap,
IN PMAPSTRUCT ReverseMap,
IN PMAPSTRUCT UndefMap
)
{
TCHAR dir[MAX_TCHAR_PATH];
TCHAR encodedVariableName[128];
PCTSTR undefText;
wsprintf (encodedVariableName, TEXT("%%%s%%"), IsmVariableName);
if (IsmGetEnvironmentString (PLATFORM_SOURCE, S_SYSENVVAR_GROUP, IsmVariableName, dir, sizeof(dir)/sizeof((dir)[0]), NULL)) {
if (DirectMap) {
AddStringMappingPair (DirectMap, encodedVariableName, dir);
}
if (ReverseMap) {
AddStringMappingPair (ReverseMap, dir, encodedVariableName);
}
} else {
undefText = JoinTextEx (NULL, TEXT("--> "), TEXT(" <--"), encodedVariableName, 0, NULL);
if (UndefMap) {
AddStringMappingPair (UndefMap, encodedVariableName, undefText);
}
FreeText (undefText);
}
}
VOID
SetIsmEnvironmentFromVirtualMachine (
IN PMAPSTRUCT DirectMap,
IN PMAPSTRUCT ReverseMap,
IN PMAPSTRUCT UndefMap
)
{
//
// Need to transfer ISM environment into our string mapping
//
#define DEFMAC(name) pTransferEnvPath(name, DirectMap, ReverseMap, UndefMap);
ENVIRONMENT_VARIABLES
#undef DEFMAC
}