ファイルを再起動時に削除 (CDeleteFileDelayUntilReboot)

(2004.12.02)
#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;
    }
};
一覧に戻る
© 2003 WAC.com All Right Reserved.