|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
RemoveReadOnlyAttribute.cpp
Abstract:
Removes read only attributes from directories: used to fix some apps that aren't used to shell folders being read-only.
Notes:
This is a general purpose shim.
History:
01/03/2000 a-jamd Created 12/02/2000 linstev Separated functionality into 2 shims: this one and EmulateCDFS
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(RemoveReadOnlyAttribute) #include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN APIHOOK_ENUM_ENTRY(GetFileAttributesW) APIHOOK_ENUM_ENTRY(GetFileAttributesA) APIHOOK_ENUM_ENTRY(FindFirstFileW) APIHOOK_ENUM_ENTRY(FindFirstFileA) APIHOOK_ENUM_ENTRY(FindNextFileW) APIHOOK_ENUM_ENTRY(FindNextFileA) APIHOOK_ENUM_ENTRY(GetFileInformationByHandle) APIHOOK_ENUM_END
typedef struct _FINDFILE_HANDLE { HANDLE DirectoryHandle; PVOID FindBufferBase; PVOID FindBufferNext; ULONG FindBufferLength; ULONG FindBufferValidLength; RTL_CRITICAL_SECTION FindBufferLock; } FINDFILE_HANDLE, *PFINDFILE_HANDLE;
/*++
Remove read only attribute if it's a directory
--*/
DWORD APIHOOK(GetFileAttributesA)(LPCSTR lpFileName) { DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesA)(lpFileName); // Check for READONLY and DIRECTORY attributes
if ((dwFileAttributes != INT_PTR(-1)) && (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // Flip the read-only bit.
LOGN( eDbgLevelWarning, "[GetFileAttributesA] Removing FILE_ATTRIBUTE_READONLY"); dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return dwFileAttributes; }
/*++
Remove read only attribute if it's a directory
--*/
DWORD APIHOOK(GetFileAttributesW)(LPCWSTR wcsFileName) { DWORD dwFileAttributes = ORIGINAL_API(GetFileAttributesW)(wcsFileName); // Check for READONLY and DIRECTORY attributes
if ((dwFileAttributes != INT_PTR(-1)) && (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // Flip the read-only bit.
LOGN( eDbgLevelWarning, "[GetFileAttributesW] Removing FILE_ATTRIBUTE_READONLY"); dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return dwFileAttributes; }
/*++
Remove read only attribute if it's a directory
--*/
HANDLE APIHOOK(FindFirstFileA)( LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData ) { HANDLE hFindFile = ORIGINAL_API(FindFirstFileA)(lpFileName, lpFindFileData);
if ((hFindFile != INVALID_HANDLE_VALUE) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // Flip the read-only bit
LOGN( eDbgLevelWarning, "[FindFirstFileA] Removing FILE_ATTRIBUTE_READONLY"); lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return hFindFile; }
/*++
Remove read only attribute if it's a directory.
--*/
HANDLE APIHOOK(FindFirstFileW)( LPCWSTR wcsFileName, LPWIN32_FIND_DATAW lpFindFileData ) { HANDLE hFindFile = ORIGINAL_API(FindFirstFileW)(wcsFileName, lpFindFileData);
if ((hFindFile != INVALID_HANDLE_VALUE) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // It's a directory: flip the read-only bit
LOGN( eDbgLevelInfo, "[FindFirstFileW] Removing FILE_ATTRIBUTE_READONLY"); lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return hFindFile; }
/*++
Remove read only attribute if it's a directory.
--*/
BOOL APIHOOK(FindNextFileA( HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData ) { BOOL bRet = ORIGINAL_API(FindNextFileA)(hFindFile, lpFindFileData);
if (bRet && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // Flip the read-only bit.
LOGN( eDbgLevelWarning, "[FindNextFileA] Removing FILE_ATTRIBUTE_READONLY")); lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return bRet; }
/*++
Remove read only attribute if it's a directory.
--*/
BOOL APIHOOK(FindNextFileW)( HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData ) { BOOL bRet = ORIGINAL_API(FindNextFileW)(hFindFile, lpFindFileData);
if (bRet && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // Flip the read-only bit
LOGN( eDbgLevelWarning, "[FindNextFileW] Removing FILE_ATTRIBUTE_READONLY"); lpFindFileData->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return bRet; }
/*++
Remove read only attribute if it's a directory.
--*/
BOOL APIHOOK(GetFileInformationByHandle)( HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation ) { BOOL bRet = ORIGINAL_API(GetFileInformationByHandle)(hFile, lpFileInformation);
if (bRet && (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFileInformation->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { // It's a CDROM too. Flip the read-only bit.
LOGN( eDbgLevelWarning, "[GetFileInformationByHandle] Removing FILE_ATTRIBUTE_READONLY"); lpFileInformation->dwFileAttributes ^= FILE_ATTRIBUTE_READONLY; }
return bRet; }
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW); APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA); APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW); APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA); APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileW); APIHOOK_ENTRY(KERNEL32.DLL, FindNextFileA); APIHOOK_ENTRY(KERNEL32.DLL, GetFileInformationByHandle);
HOOK_END
IMPLEMENT_SHIM_END
|