移动数据例程

#ifndef BITMAP_H
#define BITMAP_H

#define _WIN32_WINNT 0x600

#include "windows.h"
#include "winioctl.h"
#include
#include
using namespace std;

class BitMap
{
public:
    void getMapList(const VOLUME_BITMAP_BUFFER *pInBuff);
    void dispalyMapListOfFree() const;
    void showVecOfBit() const;
    const map & returnMaplist() const;
    const vector & returnBitVec() const;
private:
    map mapListOfFree;
    vector vecOfBit;
};

#endif


================================ ================

#include "bitmap.h"
#include
#include
#include

void BitMap::getMapList(const VOLUME_BITMAP_BUFFER *pInBuff)
{
    ULONGLONG count_size = 0;
    ULONGLONG size_clusterarray = (pInBuff -> BitmapSize.QuadPart + 7) / 8;
    while (count_size != size_clusterarray)
    {
        bitset<8> bit(*(pInBuff -> Buffer + count_size));
        for (int i = 0; i != 8; ++i)
        {
            vecOfBit.push_back(bit[i]);
        }
        count_size++;
    }
    if (vecOfBit.size() != pInBuff -> BitmapSize.QuadPart)
    {
        ULONGLONG popnum = vecOfBit.size() - pInBuff -> BitmapSize.QuadPart;
        for (ULONGLONG i = 0; i < popnum; ++i)
        {
            vecOfBit.pop_back();
        }
    }

    ULONGLONG add = 0;
    ULONGLONG size = 0;
    for (ULONGLONG i = 0; i < vecOfBit.size();)
    {
        size = 0;
        if (vecOfBit[i] == 0)
        {
            add = i;
            ULONGLONG idx = i;
            while ((idx < vecOfBit.size()) && !vecOfBit[idx]) //
            {
                size ++;
                idx++;
            }
            i += size;
            mapListOfFree.insert(make_pair(add, size));
        }
        else
        {
            i++;
            continue;
        }
    }
}

void BitMap::showVecOfBit() const
{
    fstream vecbit("bitmap.txt", ios_base::out);
    if (!vecbit) return;
    for (ULONGLONG i = 0; i < vecOfBit.size(); ++i)
    {
        if (i % 32 == 0)
        {
            vecbit << endl;
        }
        vecbit << (DWORD)vecOfBit[i] << " ";
    }
    vecbit.close();
}

void BitMap::dispalyMapListOfFree() const
{
    cout << "Free Space List " << endl;
    for (map::const_iterator cit = mapListOfFree.begin(); cit != mapListOfFree.end(); ++cit)
    {
        cout << "address: " << ULONG((*cit).first) << "/tsize: " << ULONG((*cit).second) << endl;
    }
}

const map&  BitMap::returnMaplist() const
{
    return mapListOfFree;
}

const vector& BitMap::returnBitVec() const
{
    return vecOfBit;
}


=================================================

#ifndef MOVFLE_H
#define NOVFLE_H

#include
#include
using namespace std;
#define _WIN32_WINNT 0x600
#include "windows.h"
#include "winioctl.h"

class MovFle
{
public:
    BOOL init(string str_fileFullPathName);
    BOOL analysis(ULONGLONG ull_usedClusters, DWORD &rerCod);
    BOOL move(HANDLE hVolum, map &rmapList, DWORD &rerCod); //pair free space
    void displayFileMapList() const;
    ~MovFle();
private:
    HANDLE m_hFle;
    map m_mapAnalysised; //file should move
    string m_strFileName;
};

#endif


=================================================

#include "movfle.h"

#include
#include
#include
#include

BOOL MovFle::init(string str_fileFullPathName)
{
    m_strFileName = str_fileFullPathName;
    m_hFle = CreateFile(str_fileFullPathName.c_str(), GENERIC_READ | GENERIC_WRITE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA| FILE_EXECUTE | FILE_READ_ATTRIBUTES,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == m_hFle)
    {
        //may be a directory name
        m_hFle = CreateFile (str_fileFullPathName.c_str(), GENERIC_READ | FILE_SHARE_WRITE,
                             FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                             NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
        if (INVALID_HANDLE_VALUE != m_hFle)
        {
            return TRUE;
        }
        return FALSE;
    }

    return TRUE;
}

MovFle::~MovFle()
{
    if (INVALID_HANDLE_VALUE != m_hFle)
    {
        CloseHandle(m_hFle);
    }
}

BOOL MovFle::analysis(ULONGLONG ull_usedClusters, DWORD &rerCod)
{
    STARTING_VCN_INPUT_BUFFER inbuff;
    inbuff.StartingVcn.QuadPart = 0;
    RETRIEVAL_POINTERS_BUFFER outbuf;
    ULONGLONG ull_DealedVcn = 0;
    BOOL bIsOk;
    DWORD dwReturnBytes = 0;
    vector, ULONGLONG> > vecFileBlock;

    //<, size>
    do
    {
        bIsOk = DeviceIoControl(m_hFle, FSCTL_GET_RETRIEVAL_POINTERS, &inbuff,
            sizeof(STARTING_VCN_INPUT_BUFFER), &outbuf, sizeof(RETRIEVAL_POINTERS_BUFFER), &dwReturnBytes, NULL);
        rerCod = GetLastError();

        //for dealing directory
        if (outbuf.ExtentCount == 0)
            break;

        vecFileBlock.push_back(make_pair(make_pair(outbuf.StartingVcn.QuadPart, outbuf.Extents[0].Lcn.QuadPart), outbuf.Extents[0].NextVcn.QuadPart - outbuf.StartingVcn.QuadPart));
        inbuff.StartingVcn.QuadPart = outbuf.Extents[0].NextVcn.QuadPart;
    } while((!bIsOk) && (rerCod == ERROR_MORE_DATA));

    //analysis and make   
    for (DWORD currentBlock = 0; currentBlock != vecFileBlock.size(); ++currentBlock)
    {
        if (vecFileBlock[currentBlock].first.second >= ull_usedClusters)
        {
            m_mapAnalysised.insert(make_pair(vecFileBlock[currentBlock].first.first, vecFileBlock[currentBlock].second));
        }
        else
        {
            if (vecFileBlock[currentBlock].first.second + vecFileBlock[currentBlock].second > ull_usedClusters)
            {
                m_mapAnalysised.insert(make_pair((vecFileBlock[currentBlock].first.first + (ull_usedClusters - vecFileBlock[currentBlock].first.second)),
                                                 (vecFileBlock[currentBlock].first.second + vecFileBlock[currentBlock].second - ull_usedClusters)));
            }
        }
    }

    //deal invalid data, temporary method
    /*
    if (m_mapAnalysised.size() == 1)
    {
        map::const_iterator cit = m_mapAnalysised.begin();
        if (cit -> second > ull_usedClusters)
        {
            m_mapAnalysised.clear();
            return FALSE;
        }
    }
    */
   
    if (m_mapAnalysised.size() != 0)
    {
        displayFileMapList();
    }

    BOOL result = (m_mapAnalysised.size() == 0) ? FALSE : TRUE;
    return result;
}

void MovFle::displayFileMapList() const
{
    cout << m_strFileName << "-> maplist : " << endl;
    map::const_iterator cit = m_mapAnalysised.begin();
    for (; cit != m_mapAnalysised.end(); ++cit)
    {
        cout << "startVcn : " << cit -> first << " " << "size : " << cit -> second << endl;
    }
    cout << endl;
}

BOOL MovFle::move(HANDLE hVolum, std::map &rmapList, DWORD &rerCod)
{
    MOVE_FILE_DATA mfd;
    mfd.FileHandle = m_hFle;
    BOOL bIsOk = TRUE;
    DWORD dwReturnBytes = 0;

    ULONGLONG ull_startVcnInBlock = 0;

    if (rmapList.empty())
    {
        return FALSE;
    }

    map::iterator ite = rmapList.begin();
   
    for (map::const_iterator cit = m_mapAnalysised.begin(); cit != m_mapAnalysised.end(); ++ cit)
    {
        //check rmaplist size
        if (rmapList.size() == 0)
        {
            return FALSE;
        }

        //deal each block
        ULONGLONG ull_vcnInBlock = cit -> second;
        ULONGLONG ull_dealedVcnInBlock = 0;
        ull_startVcnInBlock = cit -> first;

        while (ull_dealedVcnInBlock < ull_vcnInBlock)
        {
            //check rmapList size
            if (rmapList.size() == 0)
            {
                return FALSE;
            }

            ite = rmapList.begin();    //always points to the first item

            if (ull_vcnInBlock - ull_dealedVcnInBlock <= ite -> second)    //space is enough
            {
                if (ull_vcnInBlock - ull_dealedVcnInBlock == ite -> second)    //==
                {
                    mfd.ClusterCount = ite -> second;
                    mfd.StartingVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                    mfd.StartingLcn.QuadPart = ite -> first;
                   
                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                                            NULL, 0, &dwReturnBytes, NULL);
                    if (!bIsOk)   
                    {
                        rerCod = GetLastError();
                        return FALSE;
                    }
                    else
                    {
                        rmapList.erase(ite);
                    }
                }
                else    //<
                {
                    mfd.ClusterCount = ull_vcnInBlock - ull_dealedVcnInBlock;
                    mfd.StartingVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                    mfd.StartingLcn.QuadPart = ite -> first;

                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                        NULL, 0, &dwReturnBytes, NULL);
                    if (!bIsOk)   
                    {
                        rerCod = GetLastError();
                        return FALSE;
                    }
                    else
                    {
                        pair tmppar = *ite;
                        rmapList.erase(ite);
                        rmapList.insert(make_pair(tmppar.first + mfd.ClusterCount, tmppar.second - mfd.ClusterCount));
                    }
                }
            }
            else    //>    space is not enough
            {
                mfd.ClusterCount = ite -> second;
                mfd.StartingVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                mfd.StartingLcn.QuadPart = ite -> first;

                bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                                        NULL, 0, &dwReturnBytes, NULL);
                if (!bIsOk)   
                {
                    rerCod = GetLastError();
                    return FALSE;
                }
                else
                {
                    rmapList.erase(ite);
                }
            }

            ull_dealedVcnInBlock += mfd.ClusterCount;
        }    //while

    }    //for

    return TRUE;
}


=================================================

#ifndef VOLTDY_H
#define VOLTDY_H

#include "bitmap.h"
#include
#include
#include
using namespace std;
#include "windows.h"

class VolTdy
{
public:
    BOOL initVolume(string str_volumeName);
    BOOL getMapLst(DWORD &rerCod);
    void beginBowse();
    ~VolTdy();
private:
    void browse(string strdir);
    map m_mapLst;
    HANDLE m_hVolum;
    string m_volumeName;
    ULONGLONG ull_usedClusters;
    fstream fleLog;
};

#endif


=================================================

#include "voltdy.h"
#include
#include "movfle.h"

BOOL VolTdy::initVolume(string str_volumeName)
{
    m_volumeName = str_volumeName[0];
    m_volumeName += ":";
    m_volumeName = "////.//" + m_volumeName;

    m_hVolum = CreateFile(m_volumeName.c_str(), FILE_READ_DATA | FILE_WRITE_DATA |FILE_APPEND_DATA | FILE_EXECUTE | FILE_READ_ATTRIBUTES | GENERIC_READ | GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == m_hVolum)
    {
        return FALSE;
    }

    //for browse use
    m_volumeName = str_volumeName[0];
    m_volumeName += "://*";

    ull_usedClusters = 0;
    return TRUE;
}

VolTdy::~VolTdy()
{
    if (m_hVolum != INVALID_HANDLE_VALUE)
    {
        CloseHandle(m_hVolum);
    }
}

BOOL VolTdy::getMapLst(DWORD &rerCod)
{
    BOOL bIsOk;
    STARTING_LCN_INPUT_BUFFER start_lcn_buf;
    start_lcn_buf.StartingLcn.QuadPart = 0;
    VOLUME_BITMAP_BUFFER bitmap_buf_org;
    VOLUME_BITMAP_BUFFER *pbitmap_buf = 0;
    DWORD dwOutSize = 0;
    ULONGLONG ullNumClusters = 0;
    DWORD dwReturnBytes = 0;

    bIsOk = DeviceIoControl(m_hVolum, FSCTL_GET_VOLUME_BITMAP, &start_lcn_buf, sizeof(STARTING_LCN_INPUT_BUFFER),
                            &bitmap_buf_org, sizeof(VOLUME_BITMAP_BUFFER), &dwReturnBytes, NULL);
    if (!bIsOk && GetLastError() == ERROR_MORE_DATA)
    {
        //debug
        ullNumClusters = bitmap_buf_org.BitmapSize.QuadPart - bitmap_buf_org.StartingLcn.QuadPart;
        dwOutSize = ullNumClusters/sizeof(byte) + sizeof(VOLUME_BITMAP_BUFFER);
        pbitmap_buf = (VOLUME_BITMAP_BUFFER *)new byte[dwOutSize];
        if (!pbitmap_buf)    return FALSE;

        bIsOk = DeviceIoControl(m_hVolum, FSCTL_GET_VOLUME_BITMAP, &start_lcn_buf, sizeof(start_lcn_buf),
                                pbitmap_buf, dwOutSize, &dwReturnBytes, NULL);
        if (!bIsOk)
        {
            if (pbitmap_buf)
            {
                delete [] pbitmap_buf;
                pbitmap_buf = 0;
            }
            rerCod = GetLastError();
            return FALSE;
        }
    }
 
    BitMap bitmap;
    bitmap.getMapList(pbitmap_buf);

    delete [] pbitmap_buf;
    pbitmap_buf = 0;

    bitmap.dispalyMapListOfFree();
    m_mapLst = bitmap.returnMaplist();

    ull_usedClusters = count(bitmap.returnBitVec().begin(), bitmap.returnBitVec().end(), true);
    cout << ull_usedClusters << "ull_usedClusters" << endl;

    bitmap.showVecOfBit();

    return TRUE;
}

void VolTdy::browse(string strdir) //strdir, for directory, sample "F:/*"
{
    WIN32_FIND_DATAA wfd;
    HANDLE m_hFle = FindFirstFile(strdir.c_str(), &wfd);
    strdir.resize(strdir.size() - 1);

    DWORD errCod = 0;
    if (INVALID_HANDLE_VALUE != m_hFle)
    {
        do
        {
            string str_fullName;
            errCod = 0;

            //directory dealed code
            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                string tmp = wfd.cFileName;
                if ((tmp != ".") && (tmp != ".."))
                {
                    str_fullName = strdir + wfd.cFileName;

                    MovFle mvf;
                    fleLog.open("volLog.txt", ios_base::app);

                    fleLog << str_fullName << endl;
                    if(mvf.init(str_fullName))
                    {
                        errCod = 0;
                        if(mvf.analysis(ull_usedClusters, errCod))
                        {
                            errCod = 0;
                            if(mvf.move(m_hVolum, m_mapLst, errCod));
                            else fleLog << "  mov ->" << str_fullName << endl << "errCod" << " = " << errCod << endl;
                        }
                        else
                            fleLog << "  ana ->" << str_fullName << endl << "errCod" << " = " << errCod << endl;
                    }
                    else fleLog << "  ini ->" << str_fullName << endl;
                    fleLog.close();

                    str_fullName += "//*";
                    browse(str_fullName);
                }
            }
            //file dealed code
            else
            {
                str_fullName = strdir + wfd.cFileName;

                MovFle mvf;

                fleLog.open("volLog.txt", ios_base::app);
                fleLog << str_fullName << endl;
                if(mvf.init(str_fullName))
                {
                    errCod = 0;
                    if(mvf.analysis(ull_usedClusters, errCod))
                    {
                        errCod = 0;
                        if(mvf.move(m_hVolum, m_mapLst, errCod));
                        else fleLog << "  mov ->" << str_fullName << endl << "errCod" << " = " << errCod << endl;
                    }
                    else
                        fleLog << "  ana ->" << str_fullName << endl << "errCod" << " = " << errCod << endl;
                }
                else fleLog << "  ini ->" << str_fullName << endl;
                fleLog.close();
            }
        } while(FindNextFile(m_hFle, &wfd));
    }

    if (INVALID_HANDLE_VALUE != m_hFle)
    {
        FindClose(m_hFle);
    }
}

void VolTdy::beginBowse()
{
    browse(m_volumeName);
}

你可能感兴趣的:(学习笔记之C++)