#1 19-09-2010 13:23

kostay scr
From: Беларусь
Registered: 25-05-2007
Posts: 176

Дефрагментатор.

Всем здрасте!
Я вот тут дефрагментатор и оптимизатор размещения файлов пишу, львиная доля кода уже готова, но анализ диска(составление списка файлов) был реализован через - FindFirstFile, FindNextFile - как вы уже наверное догадались не очень быстрые:)
Так вот решил просканировать $MFT с использование NTFSlib чтобы не писать уйму уже готового кода:)
Так вот процедура вроде отрабатывает корректно, но через секунду после её завершения получаем смачный Debug Assertion Failed: HEAP CORRUPTION DETECTED . Понятно что так дело не пойдёт, но в чём же проблема?Названия многих типов на русском потому-что я не люблю слэнг, а не потому-что не умею програмировать:)
Код .NET /clr .
Код процедуры:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
void analis_ntfs(Object^ drivee){
    String^ drive =static_cast <String^> (drivee);
    file_info^ MFT = gcnew file_info;
    LPWSTR drive_t = (LPWSTR) Marshal::StringToHGlobalAuto(drive).ToPointer();
    MFT->name = new wchar_t[7]; //c:\&mft + /0
    wcscpy(MFT->name,drive_t);
    wcscat(MFT->name,L"$MFT");
    MFT->type = tip_faila::MFT;
    if (!prpb(MFT)) return;
    LARGE_INTEGER dis;
    dis.QuadPart = 0;
    BYTE* buf = new BYTE[83886080]; //8mb
    ULONG64 atr = 8388608; //сколько считать
    ULONG64 dch = 0;//дополнительное чтение в следуйщем куске мфт, если тот фрагментирован
    BYTE* kdp;//куда дописывать инфу при дополнительном чтении
    BYTE* och = &buf[0];
    DWORD n;
    Volume->GetClusterSize();
    for (ULONG64 i = 0;i < MFT->file_frg->ExtentCount;i++)
    {
        dis.QuadPart = MFT->file_frg->Extents[i]->LCN*Volume->GetClusterSize();//позиция в байтах, а не кластерах
        if  (!SetFilePointerEx(Volume->hVolume,dis,NULL,FILE_BEGIN))return;
        if (dch)
        {
            och = kdp;
            atr = dch;
            dch = 0;
        }
        ULONG64 el = MFT->file_frg->Extents[i]->Len*Volume->ClusterSize;
        for (ULONG64 j = 0;j < el;j += 8388608) //8 mb
        {
            if (el-j < 8388608)
            {
                atr = el - j;
                dch = 8388608 - el - j; //сколько осталось в следуйщем куске
                kdp = &buf[atr];
                if (!SetFilePointerEx(Volume->hVolume,dis,NULL,FILE_BEGIN))return;
                if (!ReadFile(Volume->hVolume,och,atr,&n,NULL)) {
                    MessageBox::Show("Ошибка чтения MFT");
                    return;
                }
                //no-parse
            } else {
                if (!SetFilePointerEx(Volume->hVolume,dis,NULL,FILE_BEGIN))return;
                if (!ReadFile(Volume->hVolume,och,atr,&n,NULL)) {
                    MessageBox::Show("Ошибка чтения MFT");
                    return;
                }
                //parse
                parse_buffer(buf,8388608 / Volume->FileRecordSize);
            }
            atr = 8388608;
            dis.QuadPart += 8388608;
            och = &buf[0];
        }
    }
    if (dch)
    {
        //parse 8388608 - dch bytes
        parse_buffer(buf,(8388608 - dch) / Volume->FileRecordSize);
    }
    delete [] buf;
}

Определения типов:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public ref struct ExtentStruct{
    ULONG64 VCN;
    ULONG64 LCN;
    ULONG64 Len;
    ULONG64 ILen; //длина с избытком получающаюся при уборке VF - лучше чем лишний кусок и лишние расчёты
};
public ref struct file_fragments
{
    DWORD ExtentCount;
    array<ExtentStruct^>^ Extents;   
};
 
enum tip_faila {file,dir,reparse_point,MFT,system};
enum phase {nichego = -1,operation_completed,sost_spis_failov,anal_rasp_failov,podgotovka,defragmenting};
 
public ref struct file_info {
    ~file_info(){
        this->!file_info();
    }
    !file_info(){
        if (this->name != NULL)
        {
            delete [] this->name; //LongPointerToString , Long,PointedTCHARString = LPTSTR;LongPointerWideCharacterString = LPWSTR
        }      
    }
    file_fragments^ file_frg;
    LPWSTR name;
    //bool error;
    //bool unmovable; всё равно нельзя раскрасить
    tip_faila type;
};

Last edited by kostay scr (19-09-2010 14:05)


GTA VC - ЭТО НАСТОЯЩАЯ ГТА!

Offline

#2 20-09-2010 16:35

kostay scr
From: Беларусь
Registered: 25-05-2007
Posts: 176

Re: Дефрагментатор.

Интересно, что-ли никто не знает в чём проблема?
Правка:
Проблема была в том что под имя mft выделялось 7 wchar_t вместо 8 smile Поэтому мы хотели удалить лишний байт из защищённой памяти.
П.С. Хотелось бы узнать - кто здесь имеет опыт в сфере электронной комерции или просто програмит на цпп:).

Last edited by kostay scr (20-09-2010 17:08)


GTA VC - ЭТО НАСТОЯЩАЯ ГТА!

Offline

Board footer

Powered by FluxBB