340 lines
7.2 KiB
C
340 lines
7.2 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
LUA_RedirectFS_Cleanup.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Delete the redirected copies in every user's directory.
|
||
|
|
||
|
Created:
|
||
|
|
||
|
02/12/2001 maonis
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
#ifndef _LUA_UTILS_H_
|
||
|
#define _LUA_UTILS_H_
|
||
|
|
||
|
//
|
||
|
// Preserve the last error of the original API call.
|
||
|
//
|
||
|
#define LUA_GET_API_ERROR DWORD LUA_LAST_ERROR = GetLastError()
|
||
|
#define LUA_SET_API_ERROR SetLastError(LUA_LAST_ERROR)
|
||
|
|
||
|
//
|
||
|
// Long file names need this prefix.
|
||
|
//
|
||
|
#define FILE_NAME_PREFIX L"\\\\?\\"
|
||
|
// length doesn't include the terminating NULL.
|
||
|
#define FILE_NAME_PREFIX_LEN (sizeof(FILE_NAME_PREFIX) / sizeof(WCHAR) - 1)
|
||
|
|
||
|
//----------------
|
||
|
// Dynamic array.
|
||
|
//----------------
|
||
|
template <typename TYPE>
|
||
|
class CLUAArray
|
||
|
{
|
||
|
public:
|
||
|
CLUAArray();
|
||
|
~CLUAArray();
|
||
|
|
||
|
bool IsEmpty() const;
|
||
|
DWORD GetSize() const;
|
||
|
DWORD GetAllocSize() const;
|
||
|
VOID SetSize(DWORD iNewSize);
|
||
|
|
||
|
// Potentially growing the array
|
||
|
VOID SetAtGrow(DWORD iIndex, TYPE newElement);
|
||
|
// return the index of the new element.
|
||
|
DWORD Add(TYPE newElement);
|
||
|
DWORD Append(const CLUAArray& src);
|
||
|
VOID RemoveAt(DWORD iIndex, DWORD nCount = 1);
|
||
|
VOID Copy(const CLUAArray& src);
|
||
|
|
||
|
const TYPE& operator[](DWORD iIndex) const;
|
||
|
TYPE& operator[](DWORD iIndex);
|
||
|
|
||
|
const TYPE& GetAt(DWORD iIndex) const;
|
||
|
TYPE& GetAt(DWORD iIndex);
|
||
|
|
||
|
private:
|
||
|
|
||
|
VOID DestructElements(TYPE* pElements, DWORD nCount);
|
||
|
VOID ConstructElements(TYPE* pElements, DWORD nCount);
|
||
|
VOID CopyElements(TYPE* pDest, const TYPE* pSrc, DWORD nCount);
|
||
|
|
||
|
TYPE* m_pData;
|
||
|
|
||
|
DWORD m_cElements;
|
||
|
DWORD m_cMax; // the max allocated.
|
||
|
};
|
||
|
|
||
|
#include "utils.inl"
|
||
|
|
||
|
//
|
||
|
// If the file is already in the user's directory, we don't
|
||
|
// redirect or track it.
|
||
|
//
|
||
|
extern WCHAR g_wszUserProfile[MAX_PATH];
|
||
|
extern DWORD g_cUserProfile;
|
||
|
|
||
|
//
|
||
|
// The PrivateProfile APIs look into the windows directory if
|
||
|
// the filename doesn't contain a path.
|
||
|
//
|
||
|
extern WCHAR g_wszSystemRoot[MAX_PATH];
|
||
|
extern DWORD g_cSystemRoot;
|
||
|
|
||
|
BOOL
|
||
|
IsUserDirectory(LPCWSTR pwszPath);
|
||
|
|
||
|
DWORD
|
||
|
GetSystemRootDirW();
|
||
|
|
||
|
BOOL
|
||
|
MakeFileNameForProfileAPIsW(LPCWSTR lpFileName, LPWSTR pwszFullPath);
|
||
|
|
||
|
//----------------------------------
|
||
|
// Unicode/ANSI conversion routines.
|
||
|
//----------------------------------
|
||
|
|
||
|
struct STRINGA2W
|
||
|
{
|
||
|
STRINGA2W(LPCSTR psz, BOOL fCopy = TRUE)
|
||
|
{
|
||
|
m_pwsz = NULL;
|
||
|
m_fIsOutOfMemory = FALSE;
|
||
|
|
||
|
if (psz)
|
||
|
{
|
||
|
// I realize I am using strlen here but this would only allocate enough or more
|
||
|
// spaces than we need. And a STRINGA2W object only lives for a very short time.
|
||
|
UINT cLen = strlen(psz) + 1;
|
||
|
|
||
|
m_pwsz = new WCHAR [cLen];
|
||
|
if (m_pwsz)
|
||
|
{
|
||
|
if (fCopy)
|
||
|
{
|
||
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, m_pwsz, cLen);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_fIsOutOfMemory = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
~STRINGA2W()
|
||
|
{
|
||
|
delete [] m_pwsz;
|
||
|
}
|
||
|
|
||
|
operator LPWSTR() const { return m_pwsz; }
|
||
|
|
||
|
BOOL m_fIsOutOfMemory;
|
||
|
|
||
|
private:
|
||
|
|
||
|
LPWSTR m_pwsz;
|
||
|
};
|
||
|
|
||
|
// If we need to allocate buffer for the ansi string.
|
||
|
inline LPSTR
|
||
|
UnicodeToAnsi(LPCWSTR pwsz)
|
||
|
{
|
||
|
LPSTR psz = NULL;
|
||
|
|
||
|
if (pwsz)
|
||
|
{
|
||
|
// Taking DBCS into consideration.
|
||
|
UINT cLen = wcslen(pwsz) * 2 + 1;
|
||
|
|
||
|
psz = new CHAR [cLen];
|
||
|
|
||
|
if (psz)
|
||
|
{
|
||
|
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cLen, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return psz;
|
||
|
}
|
||
|
|
||
|
// If we need to allocate buffer for the unicode string.
|
||
|
inline LPWSTR
|
||
|
AnsiToUnicode(LPCSTR psz)
|
||
|
{
|
||
|
LPWSTR pwsz = NULL;
|
||
|
|
||
|
if (psz)
|
||
|
{
|
||
|
UINT cLen = strlen(psz) + 1;
|
||
|
|
||
|
pwsz = new WCHAR [cLen];
|
||
|
|
||
|
if (pwsz)
|
||
|
{
|
||
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cLen);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return pwsz;
|
||
|
}
|
||
|
|
||
|
// If we already have buffer allocated for the ansi string.
|
||
|
inline VOID
|
||
|
UnicodeToAnsi(LPCWSTR pwsz, LPSTR psz)
|
||
|
{
|
||
|
if (pwsz && psz)
|
||
|
{
|
||
|
WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, wcslen(pwsz) * 2 + 1, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If we already have buffer allocated for the ansi string.
|
||
|
inline VOID
|
||
|
AnsiToUnicode(LPCSTR psz, LPWSTR pwsz)
|
||
|
{
|
||
|
if (pwsz && psz)
|
||
|
{
|
||
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, strlen(psz) + 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------
|
||
|
// File utilities.
|
||
|
//----------------
|
||
|
|
||
|
inline VOID
|
||
|
FindDataW2A(WIN32_FIND_DATAW* pfdw, WIN32_FIND_DATAA* pfda)
|
||
|
{
|
||
|
memcpy(pfda, pfdw, sizeof(WIN32_FIND_DATAA) - (MAX_PATH + 14) * sizeof(CHAR));
|
||
|
|
||
|
UnicodeToAnsi(pfdw->cFileName, pfda->cFileName);
|
||
|
UnicodeToAnsi(pfdw->cAlternateFileName, pfda->cAlternateFileName);
|
||
|
}
|
||
|
|
||
|
inline BOOL
|
||
|
IsErrorNotFound()
|
||
|
{
|
||
|
DWORD dwLastError = GetLastError();
|
||
|
return (dwLastError == ERROR_FILE_NOT_FOUND || dwLastError == ERROR_PATH_NOT_FOUND);
|
||
|
}
|
||
|
|
||
|
// Each RITEM represents a file or a directory that the user wants to redirect.
|
||
|
struct RITEM
|
||
|
{
|
||
|
WCHAR wszName[MAX_PATH];
|
||
|
DWORD cLen;
|
||
|
BOOL fHasWC; // Does this item have wildcards in it?
|
||
|
BOOL fAllUser; // Should this item be redirected to the All User dir?
|
||
|
};
|
||
|
|
||
|
//---------------------
|
||
|
// Registry utilities.
|
||
|
//---------------------
|
||
|
|
||
|
|
||
|
// This is where we store all the redirected registry keys.
|
||
|
#define LUA_REG_REDIRECT_KEY L"Software\\Redirected"
|
||
|
#define LUA_REG_REDIRECT_KEY_LEN (sizeof("Software\\Redirected") / sizeof(CHAR) - 1)
|
||
|
|
||
|
#define LUA_SOFTWARE_CLASSES L"Software\\Classes"
|
||
|
#define LUA_SOFTWARE_CLASSES_LEN (sizeof("Software\\Classes") / sizeof(CHAR) - 1)
|
||
|
|
||
|
extern HKEY g_hkRedirectRoot;
|
||
|
extern HKEY g_hkCurrentUserClasses;
|
||
|
|
||
|
LONG
|
||
|
GetRegRedirectKeys();
|
||
|
|
||
|
BOOL
|
||
|
IsPredefinedKey(
|
||
|
IN HKEY hKey
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Name matching utilities.
|
||
|
//
|
||
|
|
||
|
BOOL DoNamesMatch(
|
||
|
IN LPCWSTR pwszNameL,
|
||
|
IN LPCWSTR pwszName
|
||
|
);
|
||
|
|
||
|
BOOL DoNamesMatchWC(
|
||
|
IN LPCWSTR pwszNameWC,
|
||
|
IN LPCWSTR pwszName
|
||
|
);
|
||
|
|
||
|
BOOL
|
||
|
DoesItemMatchRedirect(
|
||
|
LPCWSTR pwszItem,
|
||
|
const RITEM* pItem,
|
||
|
BOOL fIsDirectory
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Commandline utilities.
|
||
|
// We only deal with file/dir names so we don't need to consider anything that
|
||
|
// has invalid characters for filenames.
|
||
|
//
|
||
|
|
||
|
LPWSTR GetNextToken(LPWSTR pwsz);
|
||
|
|
||
|
VOID TrimTrailingSpaces(LPWSTR pwsz);
|
||
|
|
||
|
BOOL
|
||
|
CreateDirectoryOnDemand(
|
||
|
LPWSTR pwszDir
|
||
|
);
|
||
|
|
||
|
LPWSTR
|
||
|
ExpandItem(
|
||
|
LPCWSTR pwszItem,
|
||
|
DWORD* pcItemExpand,
|
||
|
BOOL fEnsureTrailingSlash,
|
||
|
BOOL fCreateDirectory,
|
||
|
BOOL fAddPrefix
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
GetItemsCount(
|
||
|
LPCWSTR pwsz,
|
||
|
WCHAR chDelimiter
|
||
|
);
|
||
|
|
||
|
BOOL LuaShouldApplyShim();
|
||
|
|
||
|
//
|
||
|
// Cleanup utilities.
|
||
|
// Get the users on the local machine. So we can delete all the redirected stuff.
|
||
|
//
|
||
|
|
||
|
struct REDIRECTED_USER_PATH
|
||
|
{
|
||
|
LPWSTR pwszPath;
|
||
|
DWORD cLen;
|
||
|
};
|
||
|
|
||
|
struct USER_HIVE_KEY
|
||
|
{
|
||
|
HKEY hkUser;
|
||
|
HKEY hkUserClasses;
|
||
|
};
|
||
|
|
||
|
BOOL GetUsersFS(REDIRECTED_USER_PATH** ppRedirectUserPaths, DWORD* pcUsers);
|
||
|
VOID FreeUsersFS(REDIRECTED_USER_PATH* pRedirectUserPaths);
|
||
|
|
||
|
BOOL GetUsersReg(USER_HIVE_KEY** pphkUsers, DWORD* pcUsers);
|
||
|
VOID FreeUsersReg(USER_HIVE_KEY* phkUsers, DWORD cUsers);
|
||
|
|
||
|
#endif // _LUA_UTILS_H_
|