CheckReadOnlyFile.zip/CheckReadOnlyFile.cpp
#include <string>
#include <memory>
#include <Windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
namespace {
bool MyGetModuleFileName(HMODULE module, wchar_t (&fileName)[_MAX_PATH]) {
if (::GetModuleFileNameW(module, fileName, _countof(fileName)) == 0) {
return false;
}
return true;
}
bool GetModuleFileDir(HMODULE module, wchar_t (&dirName)[_MAX_PATH]) {
if (!MyGetModuleFileName(module, dirName)) {
return false;
}
if (::PathRemoveFileSpecW(dirName) == 0) {
return false;
}
return true;
}
std::wstring GetBaseName(const wchar_t * const absPath) {
wchar_t result[_MAX_PATH];
::wcscpy_s(result, absPath);
if (::PathRemoveFileSpecW(result) == 0) {
return absPath;
}
return result;
}
std::wstring MyPathAppend(const std::wstring &left, const wchar_t * const right) {
wchar_t result[_MAX_PATH];
::wcscpy_s(result, left.c_str());
::PathAppendW(result, right);
return result;
}
bool CheckReadOnlyFileImpl() {
const wchar_t * const list[] = {
L"save\\SE.ans", L"data\\*.ans",
L"save\\save1\\*.ans", L"save\\save2\\*.ans", L"save\\save3\\*.ans"
};
::FindClose(INVALID_HANDLE_VALUE);
for(unsigned int i = 0; i < _countof(list); i++) {
WIN32_FIND_DATAW fileData;
std::tr1::shared_ptr<void> file(::FindFirstFileW(list[i], &fileData), ::FindClose);
if (file.get() == INVALID_HANDLE_VALUE) {
continue;
}
do {
if ((fileData.dwFileAttributes&FILE_ATTRIBUTE_READONLY) != 0) {
const std::wstring path = MyPathAppend(GetBaseName(list[i]), fileData.cFileName);
const unsigned int attrMask = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY;
if (::SetFileAttributesW(path.c_str(), fileData.dwFileAttributes & attrMask) == FALSE) {
return false;
}
}
} while(::FindNextFileW(file.get(), &fileData) != FALSE);
}
return true;
}
} // anonymous
bool CheckReadOnlyFile() {
wchar_t oldDir[_MAX_PATH];
if (::GetCurrentDirectoryW(_countof(oldDir), oldDir) == 0) {
return false;
}
wchar_t newDir[_MAX_PATH];
if (!GetModuleFileDir(NULL, newDir)) {
return false;
}
if (::SetCurrentDirectoryW(newDir) == 0) {
return false;
}
const bool result = CheckReadOnlyFileImpl();
if (::SetCurrentDirectoryW(oldDir) == 0) {
return false;
}
return result;
}