#pragma once
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// '07.06.06 : コードの整備 (sha)
#include "MultiSzHelper.h"
#define SECTION_BUFFER_MAX 32767
/////////////////////////////////////////////////////////////////////////////
// CDeleteFileDelayUntilReboot
class CDeleteFileDelayUntilReboot
{
protected:
typedef CDeleteFileDelayUntilReboot thisClass;
protected:
CDeleteFileDelayUntilReboot(); // 実装しない
virtual ~CDeleteFileDelayUntilReboot();
public:
static HRESULT DeleteFiles(const std::vector<CString>& strFileNames)
{
HRESULT hr = S_OK;
int nError = 0;
for (int i = 0; i < (int)strFileNames.size(); i++)
{
CString strFileName = strFileNames[i];
hr = CDeleteFileDelayUntilReboot::DeleteFile(strFileName);
if (FAILED(hr))
{
nError++;
}
}
return (nError == 0) ? S_OK : E_FAIL;
}
static HRESULT DeleteFile(LPCTSTR szFileName)
{
HRESULT hr = S_OK;
OSVERSIONINFO version;
memset(&version, 0, sizeof(version));
version.dwOSVersionInfoSize = sizeof(version);
::GetVersionEx(&version);
if(version.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
hr = DeleteFileWinNT(szFileName);
if (FAILED(hr))
{
return hr;
}
}
else if(version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
hr = DeleteFileWin9x(szFileName);
if (FAILED(hr))
{
return hr;
}
}
return hr;
}
protected:
static HRESULT DeleteFileWinNT(LPCTSTR szFileName)
{
DWORD dwFlags = MOVEFILE_DELAY_UNTIL_REBOOT;
BOOL br = ::MoveFileEx(szFileName, NULL, dwFlags);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
return S_OK;
}
#if 0
// 以下は、ダメなコードです。
// → 2度目からは、前回登録したファイル名が消えてしまう。。
static HRESULT DeleteFileWin9x(LPCTSTR szFileName)
{
CString strWinInitIni = GetWindowsDirectory() + _T("WinInit.ini");
CString strShortFileName = GetShortPathName(szFileName);
BOOL br = ::WritePrivateProfileString(_T("rename"), _T("nul"), strShortFileName, strWinInitIni);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
return S_OK;
}
#else
static HRESULT DeleteFileWin9x(LPCTSTR szFileName)
{
HRESULT hr = S_OK;
CString strWinInitIni = GetWindowsDirectory() + _T("WinInit.ini");
// 95/98でGetPrivateProfileSectionや
// WritePrivateProfileSectionを使用して読み書きできるサイズは32Kまで
TCHAR szBuffer[SECTION_BUFFER_MAX];
DWORD dwBufferSize = ::GetPrivateProfileSection(_T("rename"), szBuffer, sizeof(szBuffer), strWinInitIni);
if (SECTION_BUFFER_MAX - 2 <= dwBufferSize + sizeof(szFileName))
{
return E_FAIL;
}
// ショートファイル名に変換
CString strShortFileName = GetShortPathName(szFileName);
if (strShortFileName.IsEmpty())
{
return E_FAIL;
}
// 最後に追加
CString strNewLine = _T("nul=") + strShortFileName;
hr = CMultiSzHelper::AddString(szBuffer, strNewLine);
if (FAILED(hr))
{
// 無視する。。
}
BOOL br = ::WritePrivateProfileSection(_T("rename"), szBuffer, strWinInitIni);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
// フラッシュする必要がある
br = ::WritePrivateProfileString(NULL, NULL, NULL, strWinInitIni);
if (br == 0)
{
DWORD dwError = ::GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
return S_OK;
}
#endif
protected:
// ShlwapiHelper.hよりコピー
static CString GetWindowsDirectory()
{
TCHAR szResult[MAX_PATH] = { 0 };
UINT nr = ::GetWindowsDirectory(szResult, _countof(szResult));
if (nr == 0)
{
return _T("");
}
::PathAddBackslash(szResult); // SHLWAPI 4.71
return szResult;
}
// FileHelper.hよりコピー
// Win95, WinNT3.5 or lator
static CString GetShortPathName(LPCTSTR szLongPath)
{
TCHAR szShortPath[_MAX_PATH] = { 0 };
DWORD dwResult = ::GetShortPathName(szLongPath, szShortPath, _countof(szShortPath));
if (dwResult == 0)
{
return _T("");
}
return szShortPath;
}
};