Leaked source code of windows server 2003
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.

239 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 2000-2002 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. 03/12/2002 robkenny Security review
  14. --*/
  15. #include "precomp.h"
  16. IMPLEMENT_SHIM_BEGIN(RemoveReadOnlyAttribute)
  17. #include "ShimHookMacro.h"
  18. APIHOOK_ENUM_BEGIN
  19. APIHOOK_ENUM_ENTRY(GetFileAttributesW)
  20. APIHOOK_ENUM_ENTRY(GetFileAttributesA)
  21. APIHOOK_ENUM_ENTRY(FindFirstFileW)
  22. APIHOOK_ENUM_ENTRY(FindFirstFileA)
  23. APIHOOK_ENUM_ENTRY(FindNextFileW)
  24. APIHOOK_ENUM_ENTRY(FindNextFileA)
  25. APIHOOK_ENUM_ENTRY(GetFileInformationByHandle)
  26. APIHOOK_ENUM_END
  27. /*++
  28. Remove read only attribute if it's a directory
  29. --*/
  30. DWORD
  31. APIHOOK(GetFileAttributesA)(LPCSTR lpFileName)
  32. {
  33. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesA)(lpFileName);
  34. // Check for READONLY and DIRECTORY attributes
  35. if ((dwFileAttributes != INT_PTR(-1)) &&
  36. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  37. (dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  38. {
  39. // Flip the read-only bit.
  40. LOGN( eDbgLevelWarning, "[GetFileAttributesA] Removing FILE_ATTRIBUTE_READONLY");
  41. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  42. }
  43. return dwFileAttributes;
  44. }
  45. /*++
  46. Remove read only attribute if it's a directory
  47. --*/
  48. DWORD
  49. APIHOOK(GetFileAttributesW)(LPCWSTR wcsFileName)
  50. {
  51. DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesW)(wcsFileName);
  52. // Check for READONLY and DIRECTORY attributes
  53. if ((dwFileAttributes != INT_PTR(-1)) &&
  54. (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  55. (dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  56. {
  57. // Flip the read-only bit.
  58. LOGN( eDbgLevelWarning, "[GetFileAttributesW] Removing FILE_ATTRIBUTE_READONLY");
  59. dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  60. }
  61. return dwFileAttributes;
  62. }
  63. /*++
  64. Remove read only attribute if it's a directory
  65. --*/
  66. HANDLE
  67. APIHOOK(FindFirstFileA)(
  68. LPCSTR lpFileName,
  69. LPWIN32_FIND_DATAA lpFindFileData
  70. )
  71. {
  72. HANDLE hFindFile = ORIGINAL_API(FindFirstFileA)(lpFileName, lpFindFileData);
  73. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  74. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  75. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  76. {
  77. // Flip the read-only bit
  78. LOGN( eDbgLevelWarning, "[FindFirstFileA] Removing FILE_ATTRIBUTE_READONLY");
  79. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  80. }
  81. return hFindFile;
  82. }
  83. /*++
  84. Remove read only attribute if it's a directory.
  85. --*/
  86. HANDLE
  87. APIHOOK(FindFirstFileW)(
  88. LPCWSTR wcsFileName,
  89. LPWIN32_FIND_DATAW lpFindFileData
  90. )
  91. {
  92. HANDLE hFindFile = ORIGINAL_API(FindFirstFileW)(wcsFileName, lpFindFileData);
  93. if ((hFindFile != INVALID_HANDLE_VALUE) &&
  94. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  95. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  96. {
  97. // It's a directory: flip the read-only bit
  98. LOGN( eDbgLevelInfo, "[FindFirstFileW] Removing FILE_ATTRIBUTE_READONLY");
  99. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  100. }
  101. return hFindFile;
  102. }
  103. /*++
  104. Remove read only attribute if it's a directory.
  105. --*/
  106. BOOL
  107. APIHOOK(FindNextFileA)(
  108. HANDLE hFindFile,
  109. LPWIN32_FIND_DATAA lpFindFileData
  110. )
  111. {
  112. BOOL bRet = ORIGINAL_API(FindNextFileA)(hFindFile, lpFindFileData);
  113. if (bRet &&
  114. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  115. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  116. {
  117. // Flip the read-only bit.
  118. LOGN( eDbgLevelWarning, "[FindNextFileA] Removing FILE_ATTRIBUTE_READONLY");
  119. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  120. }
  121. return bRet;
  122. }
  123. /*++
  124. Remove read only attribute if it's a directory.
  125. --*/
  126. BOOL
  127. APIHOOK(FindNextFileW)(
  128. HANDLE hFindFile,
  129. LPWIN32_FIND_DATAW lpFindFileData
  130. )
  131. {
  132. BOOL bRet = ORIGINAL_API(FindNextFileW)(hFindFile, lpFindFileData);
  133. if (bRet &&
  134. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  135. (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  136. {
  137. // Flip the read-only bit
  138. LOGN( eDbgLevelWarning, "[FindNextFileW] Removing FILE_ATTRIBUTE_READONLY");
  139. lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  140. }
  141. return bRet;
  142. }
  143. /*++
  144. Remove read only attribute if it's a directory.
  145. --*/
  146. BOOL
  147. APIHOOK(GetFileInformationByHandle)(
  148. HANDLE hFile,
  149. LPBY_HANDLE_FILE_INFORMATION lpFileInformation
  150. )
  151. {
  152. BOOL bRet = ORIGINAL_API(GetFileInformationByHandle)(hFile, lpFileInformation);
  153. if (bRet &&
  154. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  155. (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_READONLY))
  156. {
  157. // Flip the read-only bit.
  158. LOGN( eDbgLevelWarning, "[GetFileInformationByHandle] Removing FILE_ATTRIBUTE_READONLY");
  159. lpFileInformation->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY;
  160. }
  161. return bRet;
  162. }
  163. /*++
  164. Register hooked functions
  165. --*/
  166. HOOK_BEGIN
  167. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW);
  168. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA);
  169. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW);
  170. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA);
  171. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileW);
  172. APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileA);
  173. APIHOOK_ENTRY(KERNEL32.DLL, GetFileInformationByHandle);
  174. HOOK_END
  175. IMPLEMENT_SHIM_END