隐藏api的磁盘数据移动程序

#ifndef BITMAP_H
#define BITMAP_H

#define _WIN32_WINNT 0x600
#include "windows.h"
#include "winioctl.h"
#include <vector>
#include <map>
using namespace std;

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

#endif

#include "bitmap.h"
#include <iostream>
#include <bitset>
#include <fstream>

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;
    __w64 unsigned int/*ULONGLONG*/ size = 0;
    for (__w64 unsigned int/*ULONGLONG*/ i = 0; i < vecOfBit.size();)
    {
        size = 0;
        if (vecOfBit[i] == 0)
        {
            add = i;
            __w64 unsigned int/*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 (__w64 unsigned int/*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 <start cluster number, free space size>" << endl;
    for (map<ULONGLONG, ULONGLONG>::const_iterator cit = mapListOfFree.begin(); cit != mapListOfFree.end(); ++cit)
    {
        cout << "address: " << ULONG((*cit).first) << "/tsize: " << ULONG((*cit).second) << endl;
    }
}

const map<ULONGLONG, ULONGLONG>&  BitMap::returnMaplist() const
{
    return mapListOfFree;
}

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

#ifndef MOVFLE_H
#define NOVFLE_H

#include <string>
#include <map>
using namespace std;
#define _WIN32_WINNT 0x600
#include "windows.h"
#include "winioctl.h"
#include "ddk.h"

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

#endif

#include "movfle.h"

#include <vector>
#include <utility>
#include<fstream>
#include <iostream>

BOOL MovFle::init(string str_fileFullPathName, MyNtFsControlFile ptr)
{
    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*/FILE_FLAG_NO_BUFFERING, 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)
        {
            m_mptr = ptr;
            return TRUE;
        }
        return FALSE;
    }

    m_mptr = ptr;
    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<pair<pair<ULONGLONG, ULONGLONG>, ULONGLONG> > vecFileBlock;

    //<<startVcn, Lcn>, 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)));
            }
        }
    }
   
    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<ULONGLONG, ULONGLONG>::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<ULONGLONG,ULONGLONG> &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<ULONGLONG, ULONGLONG>::iterator ite = rmapList.begin();
   
    for (map<ULONGLONG, ULONGLONG>::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;
                    
                    //dbg
                    cout << "now mov clusters : " << endl;
                    cout << "ClusterCount : "<< mfd.ClusterCount << endl;
                    cout << "StartingVcn : "<< mfd.StartingVcn.QuadPart << endl;
                    cout << "StartingLcn : "<< mfd.StartingLcn.QuadPart << endl;

                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                                            NULL, 0, &dwReturnBytes, NULL);
                    if (!bIsOk)    
                    {
                        rerCod = GetLastError();

                        //dbg
                        cout << "error : " << endl;
                        cout << "ClusterCount : "<< mfd.ClusterCount << endl;
                        cout << "StartingVcn : "<< mfd.StartingVcn.QuadPart << endl;
                        cout << "StartingLcn : "<< mfd.StartingLcn.QuadPart << endl;
                        cout << "errcod : " << rerCod << endl;

                        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;

                    //dbg
                    cout << "now mov clusters : " << endl;;
                    cout << "ClusterCount : "<< mfd.ClusterCount << endl;
                    cout << "StartingVcn : "<< mfd.StartingVcn.QuadPart << endl;
                    cout << "StartingLcn : "<< mfd.StartingLcn.QuadPart << endl;

                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                        NULL, 0, &dwReturnBytes, NULL);
                    if (!bIsOk)    
                    {
                        rerCod = GetLastError();

                        //dbg
                        cout << "error : " << endl;
                        cout << "ClusterCount : "<< mfd.ClusterCount << endl;
                        cout << "StartingVcn : "<< mfd.StartingVcn.QuadPart << endl;
                        cout << "StartingLcn : "<< mfd.StartingLcn.QuadPart << endl;
                        cout << "errcod : " << rerCod << endl;

                        return FALSE;
                    }
                    else
                    {
                        pair<ULONGLONG, ULONGLONG> 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;
}
*/

BOOL MovFle::move(HANDLE hVolum, std::map<ULONGLONG,ULONGLONG> &rmapList, DWORD &rerCod)
{
    if (!m_mptr)
    {
        cout << "null function pointer" << endl;
        return FALSE;
    }

    MOVEFILE_DESCRIPTOR    mfd;
    mfd.FileHandle = m_hFle;
    DWORD    status = 0;
    IO_STATUS_BLOCK ioStatus;

    BOOL bIsOk = TRUE;
    DWORD dwReturnBytes = 0;

    ULONGLONG ull_startVcnInBlock = 0;

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

    map<ULONGLONG, ULONGLONG>::iterator ite = rmapList.begin();

    for (map<ULONGLONG, ULONGLONG>::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.NumVcns = ite -> second;
                    mfd.StartVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                    mfd.TargetLcn.QuadPart = ite -> first;

                    /*
                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                        NULL, 0, &dwReturnBytes, NULL);
                    */

                    status = m_mptr( hVolum, NULL, NULL, 0, &ioStatus,
                        FSCTLMOVEFILE,
                        &mfd, sizeof(mfd),
                        NULL, 0 );

                    //
                    // If the operation is pending, wait for it to finish
                    //
                    if( status == STATUS_PENDING ) {

                        WaitForSingleObject(m_hFle, INFINITE);
                        status = ioStatus.Status;
                    }

                    if (status != STATUS_SUCCESS)    
                    {
                        rerCod = status;
                        return FALSE;
                    }
                    else
                    {
                        rmapList.erase(ite);
                    }
                }
                else    //<
                {
                    mfd.NumVcns = ull_vcnInBlock - ull_dealedVcnInBlock;
                    mfd.StartVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                    mfd.TargetLcn.QuadPart = ite -> first;

                    /*
                    bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                        NULL, 0, &dwReturnBytes, NULL);
                    */

                    status = m_mptr( hVolum, NULL, NULL, 0, &ioStatus,
                                            FSCTLMOVEFILE,
                                            &mfd, sizeof(mfd),
                                            NULL, 0 );
                    if( status == STATUS_PENDING ) {

                        WaitForSingleObject(m_hFle, INFINITE);
                        status = ioStatus.Status;
                    }

                    if (status != STATUS_SUCCESS)    
                    {
                        rerCod = status;
                        return FALSE;
                    }
                    else
                    {
                        pair<ULONGLONG, ULONGLONG> tmppar = *ite;
                        rmapList.erase(ite);
                        rmapList.insert(make_pair(tmppar.first + mfd.NumVcns, tmppar.second - mfd.NumVcns));
                    }
                }
            }
            else    //>    space is not enough
            {
                mfd.NumVcns = ite -> second;
                mfd.StartVcn.QuadPart = ull_startVcnInBlock + ull_dealedVcnInBlock;
                mfd.TargetLcn.QuadPart = ite -> first;

                /*
                bIsOk = DeviceIoControl(m_hFle, FSCTL_MOVE_FILE, &mfd, sizeof(MOVE_FILE_DATA),
                    NULL, 0, &dwReturnBytes, NULL);
                */
                status = m_mptr( hVolum, NULL, NULL, 0, &ioStatus,
                                          FSCTLMOVEFILE,
                                          &mfd, sizeof(mfd),
                                          NULL, 0 );

                //
                // If the operation is pending, wait for it to finish
                //
                if( status == STATUS_PENDING ) {

                    WaitForSingleObject(m_hFle, INFINITE);
                    status = ioStatus.Status;
                }

                if (status != STATUS_SUCCESS)    
                {
                    rerCod = status;
                    return FALSE;
                }
                else
                {
                    rmapList.erase(ite);
                }
            }

            ull_dealedVcnInBlock += mfd.NumVcns;
        }    //while

    }    //for

    return TRUE;
}

#ifndef VOLTDY_H
#define VOLTDY_H

#include "bitmap.h"
#include <string>
#include <algorithm>
#include <fstream>
using namespace std;
#include "windows.h"
#include "ddk.h"

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

#endif

#include "voltdy.h"
#include <iostream>
#include "movfle.h"

BOOL VolTdy::initVolume(string str_volumeName, MyNtFsControlFile ptr)
{
    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*/ 0, NULL);
    if (INVALID_HANDLE_VALUE == m_hVolum)
    {
        return FALSE;
    }

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

    ull_usedClusters = 0;
    m_ptr = ptr;
    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 != ".."))
                {
                    string stedbg = wfd.cFileName;
                    str_fullName = strdir + stedbg;

                    //for desturctor run
                    {
                        MovFle mvf;
                        fleLog.open("volLog.txt", ios_base::app);

                        fleLog << str_fullName << endl;
                        if(mvf.init(str_fullName, m_ptr))
                        {
                            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
            {
                string stedbg = wfd.cFileName;
                str_fullName = strdir + stedbg;

                MovFle mvf;

                fleLog.open("volLog.txt", ios_base::app);
                fleLog << str_fullName << endl;
                if(mvf.init(str_fullName, m_ptr))
                {
                    errCod = 0;
                    if(mvf.analysis(ull_usedClusters, errCod))
                    {
                        errCod = 0;

                        //dbg
                        cout << "start mov " << str_fullName << endl;

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

#ifndef DDK_H
#define DDK_H

#define FSCTLMOVEFILE                    0x90074

//
// return code type
//
typedef UINT NTSTATUS;

//
// Error codes returned by NtFsControlFile (see NTSTATUS.H)
//
#define STATUS_SUCCESS                     ((NTSTATUS)0x00000000L)
#define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0x80000005L)
#define STATUS_INVALID_PARAMETER         ((NTSTATUS)0xC000000DL)
#define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)
#define STATUS_ALREADY_COMMITTED         ((NTSTATUS)0xC0000021L)
#define STATUS_INVALID_DEVICE_REQUEST    ((NTSTATUS)0xC0000010L)


//--------------------------------------------------------------------
//       F S C T L  S P E C I F I C   T Y P E D E F S 
//--------------------------------------------------------------------


//
// This is the definition for a VCN/LCN (virtual cluster/logical cluster)
// mapping pair that is returned in the buffer passed to
// FSCTL_GET_RETRIEVAL_POINTERS
//
typedef struct {
    ULONGLONG            Vcn;
    ULONGLONG            Lcn;
} MAPPING_PAIR, *PMAPPING_PAIR;

//
// This is the definition for the buffer that FSCTL_GET_RETRIEVAL_POINTERS
// returns. It consists of a header followed by mapping pairs
//
typedef struct {
    ULONG                NumberOfPairs;
    ULONGLONG            StartVcn;
    MAPPING_PAIR        Pair[1];
} GET_RETRIEVAL_DESCRIPTOR, *PGET_RETRIEVAL_DESCRIPTOR;


//
// This is the definition of the buffer that FSCTL_GET_VOLUME_BITMAP
// returns. It consists of a header followed by the actual bitmap data
//
typedef struct {
    ULONGLONG            StartLcn;
    ULONGLONG            ClustersToEndOfVol;
    BYTE                Map[1];
} BITMAP_DESCRIPTOR, *PBITMAP_DESCRIPTOR;


//
// This is the definition for the data structure that is passed in to
// FSCTL_MOVE_FILE
//
typedef struct {
    HANDLE            FileHandle;
    ULONG             Reserved;   
    LARGE_INTEGER     StartVcn;
    LARGE_INTEGER     TargetLcn;
    ULONG             NumVcns;
    ULONG             Reserved1;    
} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR;

/*
typedef struct {
    HANDLE            FileHandle;
    ULONGLONG             Reserved;   
    LARGE_INTEGER     StartVcn;
    LARGE_INTEGER     TargetLcn;
    ULONGLONG             NumVcns;
    ULONGLONG             Reserved1;    
} MOVEFILE_DESCRIPTOR, *PMOVEFILE_DESCRIPTOR;
*/


//--------------------------------------------------------------------
//     N T F S C O N T R O L F I L E   D E F I N I T I O N S
//--------------------------------------------------------------------

//
// Prototype for NtFsControlFile and data structures
// used in its definition
//

//
// Io Status block (see NTDDK.H)
//
typedef struct _IO_STATUS_BLOCK {
    NTSTATUS Status;
    ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;


//
// Apc Routine (see NTDDK.H)
//
typedef VOID (*PIO_APC_ROUTINE) (
                                 PVOID ApcContext,
                                 PIO_STATUS_BLOCK IoStatusBlock,
                                 ULONG Reserved
                                 );

//typedef int (*MYPROC)(LPTSTR);
typedef NTSTATUS (__stdcall *MyNtFsControlFile)(
                                      HANDLE FileHandle,
                                      HANDLE Event,                    // optional
                                      PIO_APC_ROUTINE ApcRoutine,        // optional
                                      PVOID ApcContext,                // optional
                                      PIO_STATUS_BLOCK IoStatusBlock,    
                                      ULONG FsControlCode,
                                      PVOID InputBuffer,                // optional
                                      ULONG InputBufferLength,
                                      PVOID OutputBuffer,                // optional
                                      ULONG OutputBufferLength
                                      );

#endif

#include "voltdy.h"
#include <iostream>
#include "windows.h"
#include "ddk.h"

int main(int argc, char **argv)
{
    DWORD dwTime = GetTickCount();

    //get ntfscontrolfile pointer
    MyNtFsControlFile ntp = NULL;
    ntp = (MyNtFsControlFile) GetProcAddress( GetModuleHandle("ntdll.dll"),"NtFsControlFile");
    if(!ntp)
    {
        cout << "Could not find NtFsControlFile entry point in NTDLL.DLL/n";
        return 1;
    }

    //clean log file
    fstream outfle("volLog.txt", ios_base::out);
    if (!outfle)
    {
        cout << "err clean log" << endl;
    }
    outfle.close();
   
    //choose the disk
    cout << "Please input disk : ";
    string strdic;
    cin >> strdic;

    //run
    VolTdy vtd;
    BOOL bIsOk = vtd.initVolume(strdic, ntp); //ok
    if (!bIsOk)
    {
        cout << "err initVolume function" << endl;
        return 1;
    }
   
    DWORD errCod = 0;
    bIsOk = vtd.getMapLst(errCod); //ok
    if (!bIsOk)
    {
        cout << "err getMapLst function" << endl;
        return 1;
    }

    vtd.beginBowse(); //ok

    cout<< GetTickCount() - dwTime<<endl;

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值