他人の空似自作物置場

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;
}