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.

247 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. RemoveReadOnlyAttribute.cpp
  5. Abstract:
  6. Removes read only attributes from directories: used to fix some apps that
  7. aren't used to shell folders being read-only.
  8. Notes:
  9. This is a general purpose shim.
  10. History:
  11. 01/03/2000 a-jamd Created
  12. 12/02/2000 linstev Separated functionality into 2 shims: this one and EmulateCDFS
  13. --*/
  14. #include "precomp.h"
  15. IMPLEMENT_SHIM_BEGIN(RemoveReadOnlyAttribute)
  16. #include "ShimHookMacro.h"
  17. APIHOOK_ENUM_BEGIN
  18. APIHOOK_ENUM_ENTRY(GetFileAttributesW)
  19. APIHOOK_ENUM_ENTRY(GetFileAttributesA)
  20. APIHOOK_ENUM_ENTRY(FindFirstFileW)
  21. APIHOOK_ENUM_ENTRY(FindFirstFileA)
  22. APIHOOK_ENUM_ENTRY(FindNextFileW)
  23. APIHOOK_ENUM_ENTRY(FindNextFileA)
  24. APIHOOK_ENUM_ENTRY(GetFileInformationByHandle)
  25. APIHOOK_ENUM_END
  26. typedef struct _FINDFILE_HANDLE
  27. {
  28. HANDLE DirectoryHandle;
  29. PVOID FindBufferBase;
  30. PVOID FindBufferNext;
  31. ULONG FindBufferLength;
  32. ULONG FindBufferValidLength;
  33. RTL_CRITICAL_SECTION FindBufferLock;
  34. } FINDFILE_HANDLE, *PFINDFILE_HANDLE;
  35. /*++
  36. Remove read only attribute if it's a directory
  37. --*/
  38. DWORD
  39. APIHOOK(GetFileAttributesA)(LPCSTR lpFileName)
  40. {
  41. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesA)(lpFileName);
  42. // Check for READONLY and DIRECTORY attributes
  43. if ((dwFileAttributes != INT_PTR(-1)) &&
  44. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  45. (dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  46. {
  47. // Flip the read-only bit.
  48. LOGN( eDbgLevelWarning, "[GetFileAttributesA] Removing FILE_ATTRIBUTE_READONLY");
  49. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  50. }
  51. return dwFileAttributes;
  52. }
  53. /*++
  54. Remove read only attribute if it's a directory
  55. --*/
  56. DWORD
  57. APIHOOK(GetFileAttributesW)(LPCWSTR wcsFileName)
  58. {
  59. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesW)(wcsFileName);
  60. // Check for READONLY and DIRECTORY attributes
  61. if ((dwFileAttributes != INT_PTR(-1)) &&
  62. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  63. (dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  64. {
  65. // Flip the read-only bit.
  66. LOGN( eDbgLevelWarning, "[GetFileAttributesW] Removing FILE_ATTRIBUTE_READONLY");
  67. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  68. }
  69. return dwFileAttributes;
  70. }
  71. /*++
  72. Remove read only attribute if it's a directory
  73. --*/
  74. HANDLE
  75. APIHOOK(FindFirstFileA)(
  76. LPCSTR lpFileName,
  77. LPWIN32_FIND_DATAA lpFindFileData
  78. )
  79. {
  80. HANDLE hFindFile = ORIGINAL_API(FindFirstFileA)(lpFileName, lpFindFileData);
  81. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  82. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  83. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  84. {
  85. // Flip the read-only bit
  86. LOGN( eDbgLevelWarning, "[FindFirstFileA] Removing FILE_ATTRIBUTE_READONLY");
  87. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  88. }
  89. return hFindFile;
  90. }
  91. /*++
  92. Remove read only attribute if it's a directory.
  93. --*/
  94. HANDLE
  95. APIHOOK(FindFirstFileW)(
  96. LPCWSTR wcsFileName,
  97. LPWIN32_FIND_DATAW lpFindFileData
  98. )
  99. {
  100. HANDLE hFindFile = ORIGINAL_API(FindFirstFileW)(wcsFileName, lpFindFileData);
  101. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  102. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  103. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  104. {
  105. // It's a directory: flip the read-only bit
  106. LOGN( eDbgLevelInfo, "[FindFirstFileW] Removing FILE_ATTRIBUTE_READONLY");
  107. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  108. }
  109. return hFindFile;
  110. }
  111. /*++
  112. Remove read only attribute if it's a directory.
  113. --*/
  114. BOOL
  115. APIHOOK(FindNextFileA(
  116. HANDLE hFindFile,
  117. LPWIN32_FIND_DATAA lpFindFileData
  118. )
  119. {
  120. BOOL bRet = ORIGINAL_API(FindNextFileA)(hFindFile, lpFindFileData);
  121. if (bRet &&
  122. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  123. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  124. {
  125. // Flip the read-only bit.
  126. LOGN( eDbgLevelWarning, "[FindNextFileA] Removing FILE_ATTRIBUTE_READONLY"));
  127. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  128. }
  129. return bRet;
  130. }
  131. /*++
  132. Remove read only attribute if it's a directory.
  133. --*/
  134. BOOL
  135. APIHOOK(FindNextFileW)(
  136. HANDLE hFindFile,
  137. LPWIN32_FIND_DATAW lpFindFileData
  138. )
  139. {
  140. BOOL bRet = ORIGINAL_API(FindNextFileW)(hFindFile, lpFindFileData);
  141. if (bRet &&
  142. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  143. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  144. {
  145. // Flip the read-only bit
  146. LOGN( eDbgLevelWarning, "[FindNextFileW] Removing FILE_ATTRIBUTE_READONLY");
  147. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  148. }
  149. return bRet;
  150. }
  151. /*++
  152. Remove read only attribute if it's a directory.
  153. --*/
  154. BOOL
  155. APIHOOK(GetFileInformationByHandle)(
  156. HANDLE hFile,
  157. LPBY_HANDLE_FILE_INFORMATION lpFileInformation
  158. )
  159. {
  160. BOOL bRet = ORIGINAL_API(GetFileInformationByHandle)(hFile, lpFileInformation);
  161. if (bRet &&
  162. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  163. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  164. {
  165. // It's a CDROM too. Flip the read-only bit.
  166. LOGN( eDbgLevelWarning, "[GetFileInformationByHandle] Removing FILE_ATTRIBUTE_READONLY");
  167. lpFileInformation->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  168. }
  169. return bRet;
  170. }
  171. /*++
  172. Register hooked functions
  173. --*/
  174. HOOK_BEGIN
  175. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW);
  176. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA);
  177. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW);
  178. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA);
  179. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileW);
  180. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileA);
  181. APIHOOK_ENTRY(KERNEL32.DLL, GetFileInformationByHandle);
  182. HOOK_END
  183. IMPLEMENT_SHIM_END