windows-nt/Source/XPSP1/NT/windows/appcompat/shims/lua/utils.h
2020-09-26 16:20:57 +08:00

351 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);
}
// When using the Profile APIs, the returned buffer could contain multiple
// NULLs - one NULL after each string and 2 NULLs after the final string.
inline VOID
ConvertBufferForProfileAPIs(LPCWSTR pwsz, DWORD nSize, LPSTR psz)
{
if (pwsz && psz)
{
WideCharToMultiByte(CP_ACP, 0, pwsz, nSize, psz, nSize, 0, 0);
}
}
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_