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.

350 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. LUA_RedirectFS_Cleanup.cpp
  5. Abstract:
  6. Delete the redirected copies in every user's directory.
  7. Created:
  8. 02/12/2001 maonis
  9. Modified:
  10. --*/
  11. #ifndef _LUA_UTILS_H_
  12. #define _LUA_UTILS_H_
  13. //
  14. // Preserve the last error of the original API call.
  15. //
  16. #define LUA_GET_API_ERROR DWORD LUA_LAST_ERROR = GetLastError()
  17. #define LUA_SET_API_ERROR SetLastError(LUA_LAST_ERROR)
  18. //
  19. // Long file names need this prefix.
  20. //
  21. #define FILE_NAME_PREFIX L"\\\\?\\"
  22. // length doesn't include the terminating NULL.
  23. #define FILE_NAME_PREFIX_LEN (sizeof(FILE_NAME_PREFIX) / sizeof(WCHAR) - 1)
  24. //----------------
  25. // Dynamic array.
  26. //----------------
  27. template <typename TYPE>
  28. class CLUAArray
  29. {
  30. public:
  31. CLUAArray();
  32. ~CLUAArray();
  33. bool IsEmpty() const;
  34. DWORD GetSize() const;
  35. DWORD GetAllocSize() const;
  36. VOID SetSize(DWORD iNewSize);
  37. // Potentially growing the array
  38. VOID SetAtGrow(DWORD iIndex, TYPE newElement);
  39. // return the index of the new element.
  40. DWORD Add(TYPE newElement);
  41. DWORD Append(const CLUAArray& src);
  42. VOID RemoveAt(DWORD iIndex, DWORD nCount = 1);
  43. VOID Copy(const CLUAArray& src);
  44. const TYPE& operator[](DWORD iIndex) const;
  45. TYPE& operator[](DWORD iIndex);
  46. const TYPE& GetAt(DWORD iIndex) const;
  47. TYPE& GetAt(DWORD iIndex);
  48. private:
  49. VOID DestructElements(TYPE* pElements, DWORD nCount);
  50. VOID ConstructElements(TYPE* pElements, DWORD nCount);
  51. VOID CopyElements(TYPE* pDest, const TYPE* pSrc, DWORD nCount);
  52. TYPE* m_pData;
  53. DWORD m_cElements;
  54. DWORD m_cMax; // the max allocated.
  55. };
  56. #include "utils.inl"
  57. //
  58. // If the file is already in the user's directory, we don't
  59. // redirect or track it.
  60. //
  61. extern WCHAR g_wszUserProfile[MAX_PATH];
  62. extern DWORD g_cUserProfile;
  63. //
  64. // The PrivateProfile APIs look into the windows directory if
  65. // the filename doesn't contain a path.
  66. //
  67. extern WCHAR g_wszSystemRoot[MAX_PATH];
  68. extern DWORD g_cSystemRoot;
  69. BOOL
  70. IsUserDirectory(LPCWSTR pwszPath);
  71. DWORD
  72. GetSystemRootDirW();
  73. BOOL
  74. MakeFileNameForProfileAPIsW(LPCWSTR lpFileName, LPWSTR pwszFullPath);
  75. //----------------------------------
  76. // Unicode/ANSI conversion routines.
  77. //----------------------------------
  78. struct STRINGA2W
  79. {
  80. STRINGA2W(LPCSTR psz, BOOL fCopy = TRUE)
  81. {
  82. m_pwsz = NULL;
  83. m_fIsOutOfMemory = FALSE;
  84. if (psz)
  85. {
  86. // I realize I am using strlen here but this would only allocate enough or more
  87. // spaces than we need. And a STRINGA2W object only lives for a very short time.
  88. UINT cLen = strlen(psz) + 1;
  89. m_pwsz = new WCHAR [cLen];
  90. if (m_pwsz)
  91. {
  92. if (fCopy)
  93. {
  94. MultiByteToWideChar(CP_ACP, 0, psz, -1, m_pwsz, cLen);
  95. }
  96. }
  97. else
  98. {
  99. m_fIsOutOfMemory = TRUE;
  100. }
  101. }
  102. }
  103. ~STRINGA2W()
  104. {
  105. delete [] m_pwsz;
  106. }
  107. operator LPWSTR() const { return m_pwsz; }
  108. BOOL m_fIsOutOfMemory;
  109. private:
  110. LPWSTR m_pwsz;
  111. };
  112. // If we need to allocate buffer for the ansi string.
  113. inline LPSTR
  114. UnicodeToAnsi(LPCWSTR pwsz)
  115. {
  116. LPSTR psz = NULL;
  117. if (pwsz)
  118. {
  119. // Taking DBCS into consideration.
  120. UINT cLen = wcslen(pwsz) * 2 + 1;
  121. psz = new CHAR [cLen];
  122. if (psz)
  123. {
  124. WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, cLen, 0, 0);
  125. }
  126. }
  127. return psz;
  128. }
  129. // If we need to allocate buffer for the unicode string.
  130. inline LPWSTR
  131. AnsiToUnicode(LPCSTR psz)
  132. {
  133. LPWSTR pwsz = NULL;
  134. if (psz)
  135. {
  136. UINT cLen = strlen(psz) + 1;
  137. pwsz = new WCHAR [cLen];
  138. if (pwsz)
  139. {
  140. MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cLen);
  141. }
  142. }
  143. return pwsz;
  144. }
  145. // If we already have buffer allocated for the ansi string.
  146. inline VOID
  147. UnicodeToAnsi(LPCWSTR pwsz, LPSTR psz)
  148. {
  149. if (pwsz && psz)
  150. {
  151. WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, wcslen(pwsz) * 2 + 1, 0, 0);
  152. }
  153. }
  154. // If we already have buffer allocated for the ansi string.
  155. inline VOID
  156. AnsiToUnicode(LPCSTR psz, LPWSTR pwsz)
  157. {
  158. if (pwsz && psz)
  159. {
  160. MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, strlen(psz) + 1);
  161. }
  162. }
  163. //----------------
  164. // File utilities.
  165. //----------------
  166. inline VOID
  167. FindDataW2A(WIN32_FIND_DATAW* pfdw, WIN32_FIND_DATAA* pfda)
  168. {
  169. memcpy(pfda, pfdw, sizeof(WIN32_FIND_DATAA) - (MAX_PATH + 14) * sizeof(CHAR));
  170. UnicodeToAnsi(pfdw->cFileName, pfda->cFileName);
  171. UnicodeToAnsi(pfdw->cAlternateFileName, pfda->cAlternateFileName);
  172. }
  173. // When using the Profile APIs, the returned buffer could contain multiple
  174. // NULLs - one NULL after each string and 2 NULLs after the final string.
  175. inline VOID
  176. ConvertBufferForProfileAPIs(LPCWSTR pwsz, DWORD nSize, LPSTR psz)
  177. {
  178. if (pwsz && psz)
  179. {
  180. WideCharToMultiByte(CP_ACP, 0, pwsz, nSize, psz, nSize, 0, 0);
  181. }
  182. }
  183. inline BOOL
  184. IsErrorNotFound()
  185. {
  186. DWORD dwLastError = GetLastError();
  187. return (dwLastError == ERROR_FILE_NOT_FOUND || dwLastError == ERROR_PATH_NOT_FOUND);
  188. }
  189. // Each RITEM represents a file or a directory that the user wants to redirect.
  190. struct RITEM
  191. {
  192. WCHAR wszName[MAX_PATH];
  193. DWORD cLen;
  194. BOOL fHasWC; // Does this item have wildcards in it?
  195. BOOL fAllUser; // Should this item be redirected to the All User dir?
  196. };
  197. //---------------------
  198. // Registry utilities.
  199. //---------------------
  200. // This is where we store all the redirected registry keys.
  201. #define LUA_REG_REDIRECT_KEY L"Software\\Redirected"
  202. #define LUA_REG_REDIRECT_KEY_LEN (sizeof("Software\\Redirected") / sizeof(CHAR) - 1)
  203. #define LUA_SOFTWARE_CLASSES L"Software\\Classes"
  204. #define LUA_SOFTWARE_CLASSES_LEN (sizeof("Software\\Classes") / sizeof(CHAR) - 1)
  205. extern HKEY g_hkRedirectRoot;
  206. extern HKEY g_hkCurrentUserClasses;
  207. LONG
  208. GetRegRedirectKeys();
  209. BOOL
  210. IsPredefinedKey(
  211. IN HKEY hKey
  212. );
  213. //
  214. // Name matching utilities.
  215. //
  216. BOOL DoNamesMatch(
  217. IN LPCWSTR pwszNameL,
  218. IN LPCWSTR pwszName
  219. );
  220. BOOL DoNamesMatchWC(
  221. IN LPCWSTR pwszNameWC,
  222. IN LPCWSTR pwszName
  223. );
  224. BOOL
  225. DoesItemMatchRedirect(
  226. LPCWSTR pwszItem,
  227. const RITEM* pItem,
  228. BOOL fIsDirectory
  229. );
  230. //
  231. // Commandline utilities.
  232. // We only deal with file/dir names so we don't need to consider anything that
  233. // has invalid characters for filenames.
  234. //
  235. LPWSTR GetNextToken(LPWSTR pwsz);
  236. VOID TrimTrailingSpaces(LPWSTR pwsz);
  237. BOOL
  238. CreateDirectoryOnDemand(
  239. LPWSTR pwszDir
  240. );
  241. LPWSTR
  242. ExpandItem(
  243. LPCWSTR pwszItem,
  244. DWORD* pcItemExpand,
  245. BOOL fEnsureTrailingSlash,
  246. BOOL fCreateDirectory,
  247. BOOL fAddPrefix
  248. );
  249. DWORD
  250. GetItemsCount(
  251. LPCWSTR pwsz,
  252. WCHAR chDelimiter
  253. );
  254. BOOL LuaShouldApplyShim();
  255. //
  256. // Cleanup utilities.
  257. // Get the users on the local machine. So we can delete all the redirected stuff.
  258. //
  259. struct REDIRECTED_USER_PATH
  260. {
  261. LPWSTR pwszPath;
  262. DWORD cLen;
  263. };
  264. struct USER_HIVE_KEY
  265. {
  266. HKEY hkUser;
  267. HKEY hkUserClasses;
  268. };
  269. BOOL GetUsersFS(REDIRECTED_USER_PATH** ppRedirectUserPaths, DWORD* pcUsers);
  270. VOID FreeUsersFS(REDIRECTED_USER_PATH* pRedirectUserPaths);
  271. BOOL GetUsersReg(USER_HIVE_KEY** pphkUsers, DWORD* pcUsers);
  272. VOID FreeUsersReg(USER_HIVE_KEY* phkUsers, DWORD cUsers);
  273. #endif // _LUA_UTILS_H_