Cхема алгоритму програми з фрагментами програми
Перевірку на створення програмного вікна реалізовано завдяки умові:
if(wndMain.Create(NULL) == NULL)
{
ATLTRACE(_T("Main window creation failed!\n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);//вікно створене
НЖМД: якщо в комп'ютері кілька дисків, то спочатку потрібно вибрати той, який буде тестуватися. Для цього одержуємо атрибути пристрою через виклик GetDevice(): - фізичні характеристики – кількість голівок, циліндрів, секторів, розмір сектора й тип пристрою:
void CDisc::GetDevice() //функція для отримання системної інформації про носії
{
m_DeviseList.empty(); //повідомляємо про створення списку значень пристрою
DWORD dw = GetLogicalDriveStrings(0,NULL); //повідобляємо тип зміної функції
TCHAR *str; //повідомлення типу зміної
str = new TCHAR[dw]; // повідомлення створення дескриптору пристрою
GetLogicalDriveStrings(dw,str); //отримаємо характеристики пристрою
bool bSave = true; //задання зміної для перевірки
for(DWORD i=0;i<dw;i++) //цикл на перревірку значення дескриптору
{
if((str[i] == '\0')&&(str[i+1] == '\0')) //якщо значення дескриптору пусте
break; //преривання
if(bSave) //якщо значення відрізняється від \0
{
CString strD(&str[i]);//отримання текстове значення
if(GetDriveType(strD)==DRIVE_FIXED) //отримання типу пристрою
m_DeviseList.push_back(strD); //отримання значення списку пристрою
bSave = false; //якщо умога виконалася
}
if(str[i] == '\0') //перевірка значення дескриптору
bSave = true;
}
delete[] str; //очистка памяті
}
Потім за допомогою функції CheckDisc() перевіряємо на відкриття пристрою з перевіркою виконання:
int CDisc::CheckDisc(CString strDisc,LONG lBegin,LONG lEnd,CTestInterface* pInterface) //функція перевірки диску
{
if(strDisc[strDisc.GetLength()-1]=='\\') //перевірка на назву
strDisc.Delete(strDisc.GetLength()-1);//пристрою
CString str; //перенастроювання типу зміної
Визначаємо формат логічних розділів НЖМД.
str.Format(_T("\\\\.\\%s"),strDisc); //формат визначення диску
Визначаємо доступ до пристрою за допомогою функції CreateFile():
m_hFile=CreateFile(str,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL); //виконуємо відкриття пристрою з перевіркою виконання
CAutoVectorPtr<BYTE> pArray; //визначення типу масиву
pArray.Allocate(512); //задання розрядності
DWORD dwRead; //задаємо тип змінної
Перевіряємо значення яке отримано від дескриптору:
if(!ReadFile(m_hFile,pArray,512,&dwRead,NULL)) //перевірка значення отримане від функції
{
return 1; //повертає помилку
}
Якщо все гаразд, ReadFile повертає 0, ставимо показчик на позицію сектору:
SetFilePointer(m_hFile,80*512,NULL,FILE_BEGIN); //визначаємо показчик файлу на задану позицію
Функція SYSTEMTIME() використовуємо для отримання часу доступу до сектору:
SYSTEMTIME tBegin; //повідомляємо про отримання часовиїх характеристик
Встановлюємо час перед початком тестування сектору:
GetSystemTime(&tBegin); //отримаємо час початку
if(!ReadFile(m_hFile,pArray,512,&dwRead,NULL))//якщо функція повертає помилку
{
return 1;//повертаємо значення помилки
}
SYSTEMTIME tEnd;//отримання кінцевого часу
Після читання сектору визначаємо час закінчення:
GetSystemTime(&tEnd);//отримаємо час закінчення звертання до сектору
Преобразуємо отриманий час в зручний запис:
m_dwTime = (tEnd.wHour - tBegin.wHour)*60*60*1000+(tEnd.wMinute - tBegin.wMinute)*60*1000+(tEnd.wSecond - tBegin.wSecond)*1000+(tEnd.wMilliseconds - tBegin.wMilliseconds);
//встановлюємо час виконання
m_pInterface = pInterface;
m_lBegin = lBegin;
m_lEnd = lEnd;
_beginthread(RunThread,0,this); //показчик на створення нитки
return 0;
}
Функція реалізації тестування методом верифікації з випадковою адресою до секторів Test():
void CDisc::Test() //функція тестування НЖМД
{
srand(GetTickCount()); //час запуску системи
int rand_sec=0;//задаємо змінну початкувипадкової перевірки
Встановлюємо показчик в початок діапазону:
SetFilePointer(m_hFile,m_lBegin*512,NULL,FILE_BEGIN);//встановлюємо показчик в початок діапазону
LONG lPoint = m_lBegin; //визначаємо тип зміної, та передаємо значення
В циклі від початку діапазону до кінця проводимо верифікацію секторів:
for(;lPoint!=m_lEnd;lPoint++) //від початку до кінця
{
BYTE pArray[512]; //задаємо масив
DWORD dwRead;//визначаємо тип зміної
Щоб реалізувати випадковий алгоритм адресації к секторам використовуємо
функцію random(), яка перевіряє сектори на заданому користувачем діапазоні:
rand_sec = rand()%(m_lEnd-m_lBegin)+m_lBegin;//передаємо значення віпадкової позиції показчика
BYTE pRead[512]; //задаємо массив
Встановлюємо показчик на випадкову позицію:
SetFilePointer(m_hFile,rand_sec*512,NULL,FILE_BEGIN);//встановлюємо на потрібну випадкову позицію
Перевіряємо сектор на успішне звертання, якщо все гаразд, то статус сектора визначаємо = 0 та сектор справний, якщо 1 – сектор не читається, тобто пошкоджен.
int nStatus = 0; //задаємо статус по замовчуванню
if (ReadFile(m_hFile,pRead,512,&dwRead,NULL)==0)//перевірка на звертання к сектору
{
nStatus = 1;//отримаємо червоний статус - тобто помилка в секторі
}
Визначаємо на формі робочі або пошкоджені сектори:
m_pInterface->CallBack(m_lBegin,m_lEnd,rand_sec,nStatus); //підключаємо значення к інтерфейсу
}
m_pInterface->CallBack(m_lBegin,m_lEnd,lPoint,0);//усе гаразд, сектори прочитані без помилок
}
Перевірку на введених користувачем даних, тобто на можливо неправильно вказаний діапазон тестування за допомогою умови:
if(m_dwEnd>m_dwStart)
::SendMessage(GetParent(),WM_STARTSCAN,NULL,NULL);
Else
Якщо дані не правильні – виводиться повідомлення про помилку:
::MessageBox(m_hWnd,_T("Введите корректные данные"),0,0);
return 1;
Pезультат роботи програми TestDisk:
Рис.1. Запуск програми. Вибір носія та визначення характеристик
|
|
В процесі проектування був розроблений програмний продукт тестування НЖМД, який може виконувати наступні дії під Windows:
- визначає основні характеристики НЖМД: кількість секторів, голівок, циліндрів та загальний об’єм;
- матє вільний вибір діапазону тестування;
- виконує тестування алгоритмом – random;
- виконує перевірки працездатності секторів методом: - верифікації;
- визначє часові параметри тестування секторів.