Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Прямой доступ к диску через Win32


Автор: Owner 31.5.2005, 21:41
Потерял роаздел NTFS с видео и фото. Очень жалко, хотелось бы его восстановить, но как оказалось с ПО по восстановлением информации тяжело. Присутствуют в Инете либо полностью коммерческие продукты по диким ценам, либо ублюдочные - типа DskProbe из NT Resource Kit. Как я понял, легче написать браузер самому, но не знаю, как получить доступ непосредственно к физическому диску. Прямо скажу - MSDN пока не читал. Нашел статью братьев Фроловых по восстановлению поврежденных разделов дисков, но выйти на их сайт в Глас-нете не удалось. Они пишут, что у них есть простенький браузер, но как его получить не пишут, видимо не заинтересованы в распространении.
Буду очень благодарен за полезную информацию.

Автор: bel_nikita 31.5.2005, 23:44
Owner
Плохо ищем smile
Покуда будешь писать свой recovery - уйдет много времени smile
R-Studio попробуй. Лечилку тож найти не проблема smile

Автор: Alastis 1.6.2005, 08:10
написать свой recovery проще чем найти готовый?smile ну нет.
Вот обрати внимание на EasyRecovery Professional, мне уже очень много раз помогала.

Автор: oleg1973 1.6.2005, 10:49
для НТФС написать самому оооочень сложно
ибо даже девелоперы линюха коекак написали дравер да и то только чтение )))))

Автор: Owner 4.6.2005, 09:19
Спасибо большое за науку. Скачал R-Studio, демо версию. Програмка классная, нашла все smile , но восстанавливать файлы больше 64К отказалась smile , хотя маленький файлик восстановила успешно. Нашел старую (2001 года) версию для NTFS, увы - сканер уже не тот. Стуктуру видит, но не нашел boot record, и восстанавливает полную чушь. Получить версию от производителей - как всегда, без их пластиковых денег невозможно.

EasyRecovery Professional еще не пробовал.

За драйвер Linux спасибо, надо взглянуть. Интересно, однако, люди же пишут под Win32 direct access, значит это кому-то можно! Причем пишут неплохо! smile

Автор: PGsoft 4.6.2005, 22:19
Прямой доступ к секторам диска в такой высокозащищённой системе, как WindowsNT/2000/XP получить не просто... а очень просто (!): с помощью обычной функции WIN32 API CreateFile(). Вместо имени файла указывается "\\.\<логический диск>" или "\\.\PHYSICALDRIVE<номер>", где <логический диск> - "A:", "B:", "C:" и т.д., <номер> - номер физического устройства начиная с 0. Windows95 не поддерживает обращение к логическим дискам. Дополнительные требования - указывать FILE_SHARE_READ/FILE_SHARE_WRITE, и читать/писать с/в кратных секторам смещениям (я читаю/пишу по 1 сектору - 512байт).

Информация о параметрах устройства и некоторые операции (в том числе, и опасные) - DeviceIoControl, куда передаётся полученый хендл.

Читая с физического устройства можно получить доступ и к MBR, и даже изменить её без каких-либо проблем и предупреждений даже в WindowsXP Professional (!!!) - достаточно лишь обладать правами администратора. Что уж говорить о доступе к NTFS и прочим вещам?!

Вот пример программы, выполняющей очень опасную smile) операцию (прошу прощения за кодировку - VC++ - но и так всё понятно):
Код

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int nShowCmd)
{
    char Sector[512];
    HANDLE hDrive=CreateFile("\\\\.\\PHYSICALDRIVE0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hDrive==INVALID_HANDLE_VALUE)
    {
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,Sector,511,NULL);
        MessageBox(NULL,Sector,"Îøèáêà äîñòóïà ê äèñêó",MB_OK);
        return 1;
    }
    //Çàòåì èñïîëüçóåì DeviceIoControl(hDrive,...) äëÿ ðàçëè÷íûõ äåéñòâèé (ïàðàìåòðû è ò.ï.)
    // ëèáî
    DWORD Reads;
    ReadFile(hDrive,Sector,512,&Reads,NULL);
    if(Reads!=512)
    {
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,Sector,511,NULL);
        MessageBox(NULL,Sector,"Îøèáêà äîñòóïà ê äèñêó",MB_OK);
        return 1;
    }
    WriteFile(hDrive,Sector,512,&Reads,NULL);
    if(Reads!=512)
    {
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,Sector,511,NULL);
        MessageBox(NULL,Sector,"Îøèáêà äîñòóïà ê äèñêó",MB_OK);
        return 1;
    }
    MessageBox(NULL,"×òåíèå è çàïèñü çàãðóçî÷íîãî ñåêòîðà ïðîèçâåäåíû óñïåøíî :-)","Ïîçäðàâëåíèå",MB_OK);
    return 0;
}
[font=arial][/font]


И вообще, если есть желающие пообщаться на тему NTFS/FAT: я как раз сейчас занимаюсь NTFS, есть кое-какие интересные наработки (будет программа для восстановления файлов и пр.).


ПРИМЕЧАНИЕ. Автор не несёт никакой ответственности за последствия применения указаной здесь информации, включая запуск приведённой программы! :-)))))

Автор: Owner 6.6.2005, 18:06
Да, все гениальное - просто. Еще и еще раз убеждаюсь в этом! smile

Желание пообщаться на тему NTFS есть, и большое. Правда времени творить - мало. Спасибо за очень ценную подсказку, PGsoft, не ожидал, что винды так просто отдают ресурсы. Надо поиграться, попробовать. Я сейчас занимаюсь восстановлением своих архивов. Как только закончу, попробую собрать для начала смотрелку разделов на предмет восстановления информации. Затем нужно применить рецепты братьев Фроловых. URL статьи:http://www.osp.ru/pcworld/1999/10/20.html. Видимо, там и появятся вопросы, так как я уже пытался их применить. Однако, ничего хорошего на диске не нашел, а этот паразит, R-Studio, находит!

Еще раз спасибо всем за советы - софт нашел посвежее. На горбунке продают хороший сборник по поводу восстановления: Работа с Жестким Диском называется, в синей обложке. smile

Автор: SHENDEL 10.6.2005, 14:35
Как руки чешуться испробовать этот архи-полезный код на ближнем своем smile

Автор: Owner 11.6.2005, 23:42
SHENDEL, там есть маленькая оговорочка:
Цитата(PGsoft @ 4.6.2005, 22:19)
достаточно лишь обладать правами администратора

Так что, если ближний не дурак, то испробовать этот код на нем не получится! smile

Кстати, ни один пакет, кроме R-Studio, так профессионально структуру поврежденных разелов не воспроизводит. EasyProf восстанавливает файлы без оглядки на содержимое, поэтому вылезает очень много мусора. Акронис и Paragon вообще ничего видят.

Почитал MSDN. Оказывается, там много полезной иформации! По структуре таблиц разделов, MBR, FAT, NTFS. В разделе NT Workstation Resources.smile

Автор: chaos 14.6.2005, 12:02
вот тоже пример, кагда-то было интересно)

Код

#include <windows.h>
#include <stdio.h>

DWORD dwSectPerClust = 0, dwBytesPerSect = 0, dwNumbFreeClust = 0, dwTotalNumbOfClust = 0;


typedef struct DIOCRegs { 
    DWORD   reg_EBX; 
    DWORD   reg_EDX; 
    DWORD   reg_ECX; 
    DWORD   reg_EAX; 
    DWORD   reg_EDI; 
    DWORD   reg_ESI; 
    DWORD   reg_Flags; 
} DIOC_REGISTERS;

void PrintError()
{
    char str[256];
    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
    );
    
    CharToOem((LPCSTR)lpMsgBuf, str);
    printf ("%s\n", str);

}

//////////////////////////
//
void PrintInfoDrive(LPCSTR lpDriveName = "a:\\")
{
    GetDiskFreeSpace(
        lpDriveName,
        &dwSectPerClust, 
        &dwBytesPerSect, 
        &dwNumbFreeClust, 
        &dwTotalNumbOfClust
    );

    printf("Drive name: %s\n", lpDriveName);
    printf("SectorsPerClustre: %d\n",    dwSectPerClust);
    printf("BytesPerSector: %d\n",        dwBytesPerSect);
    printf("NumberFreeOfCluster: %d\n",    dwNumbFreeClust);
    printf("TotalNumberOfCluster: %d\n",dwTotalNumbOfClust);
    printf("------------------------------------\n");

    DWORD dwTotalSize = dwBytesPerSect * dwNumbFreeClust;
    printf("Free space: %d kb\n", (dwTotalSize/1024));
}

////////////////////////////////////////////////
//
int ReadSector(UINT sector, LPCSTR lpDriveName = "\\\\.\\A:")
{
OSVERSIONINFO verInfo = {0};
    verInfo.dwOSVersionInfoSize = sizeof (verInfo);
    GetVersionEx(&verInfo);


    HANDLE hDrive;
    char *buf;
    DWORD dw, n;

    switch (verInfo.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
        hDrive = CreateFile(
            lpDriveName, 
            GENERIC_READ, 
            FILE_SHARE_READ, 
            NULL, 
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, 
            NULL
        );
        
        if (hDrive == INVALID_HANDLE_VALUE)
        {
            PrintError();
            return 1;
        }
        
        buf = new char[dwBytesPerSect];
        SetFilePointer(hDrive, (sector-1) * dwBytesPerSect, NULL, FILE_BEGIN); //c 1
        ReadFile(hDrive, (LPVOID)buf, dwBytesPerSect, &dw, NULL); 
        CloseHandle(hDrive); 

        for (n = 0; n < dw; n++)
            printf("%c", buf[n]);

        delete[] buf;

        break;

    case VER_PLATFORM_WIN32_WINDOWS:
        break;

    default:
        printf ("Error!!!\n");
        return 1;
    }
    
    
    
/*    HANDLE hDrive = CreateFile(
        lpDriveName, 
        GENERIC_READ, 
        FILE_SHARE_READ, 
        NULL, 
        OPEN_EXISTING,
        FILE_FLAG_DELETE_ON_CLOSE, 
        NULL
    );

    if (hDrive != INVALID_HANDLE_VALUE)
    {


        char *buf = new char[dwBytesPerSect];
        if (buf == NULL) return 1;

        DIOC_REGISTERS reg;
        reg.reg_EAX = 0;//A
        reg.reg_ECX = 1;
        reg.reg_EDX = 0;
        reg.reg_EBX = (DWORD)buf;

        #define VWIN32_DIOC_DOS_INT25 2
    
        DWORD dw;

        BOOL bResult = DeviceIoControl(
            hDrive, 
            VWIN32_DIOC_DOS_INT25, 
            &reg,
            sizeof(reg),
            &reg,
            sizeof(reg),
            &dw,
            0
        );

        if (bResult==0)
            PrintError();
        else
        {
            printf("%s", buf);
        }
    
        delete[] buf;
        CloseHandle(hDrive);
    }
    else
        PrintError();
*/
    return 0;
}

///////////////////////////////
//
int main()
{
    PrintInfoDrive();
    printf("------------------------------------\n");
    ReadSector(20);

    return 0;
}


Автор: Owner 3.7.2005, 20:48
PGsoft, я готов пообщаться по поводу NTFS и FAT, но прежде хотел бы разобраться с Boot Record и таблицами разделов. В MSDN описан формат записей таблицы, однако описание довольно старое, по крайней мере нет расшифровки кодов SystemID выше 0х0F, а такие есть, и много их.
Второй вопрос касается современных дисков, где количество цилиндров давно превысило число 1023.
В выдаче програмки Partinfo.exe из пакета PartMagic присутствует термин Large Drive Place holders. Что это и где его искать? Перевод мне понятен smile
Не понятно, где эти холдеры описаны и где находятся. Может есть ссылки на более свеженькую информацию?

Автор: 02077461 13.7.2005, 14:52
Кто может подсказать, как можно вести ОЧЕНЬ низкоуровневую запись на Flesh Stick.
Что - то типа того, что написал PGsoft олько для Flash.
Кто сможет сказать что внятное:
ICQ: 237242967
mail: [email protected]

Автор: oleg1973 13.7.2005, 16:02
что значит очень низкоуровневое?
по идее флешка рассматривается как ремовабиле девайс
тоесть типа флопи ) соответственно у нее есть файловая система
вывод работать с ней можно также как и с простым диском

Автор: Guest 17.7.2005, 21:07
Owner, естественно, надо первым делом MSDN смотреть :-) Вернее, нет - первым делом help по SDK, потом MSDN, и уж "если ничего не помогает" - DDK.

Насчёт ёмкости жёстких дисков - 1024 цилиндрами нас ограничивает BIOS, стандарт ATA позволяет обратиться к 65536 цилиндрам. Так что делай выводы smile - видимо, ты пытаешься работать через BIOS; и вообще, почему не используешь LBA? От себя могу добавить сведения о максимальной ёмкости дисков в соответствии со спецификациями интерфейсов (сектор всегда 512 байт):
ATA CHS - 16 бит цилиндры, 4 бита головки, 8 бит сектор - всего 28 бит, до 127.5 Гб;
ATA LBA - 28 бит адрес сектора - до 128 Гб;
SCSI - 32 бит адрес сектора - до 2 Тб.

Опять же, делай выводы :-)) Увеличить количество бит адресации для ATA - большая проблема; увеличение уже происходило нераз, и больше ресурсов (штырьков в разъёме smile ) нет. Раньше увеличивали за счёт управляющих и резервных бит: они закончились.

В любом случае, сейчас вводится стандарт SATA (причём на многих чипсетах - "коряво", на мой взгляд: ведь по регистрам он вроде как соответствует ATA, а многие ли ОС "видят" при установке жёсткий диск SATA?! Есть у кого-нибудь сведения по этому поводу?)

И ещё один момент. Где же встречаются коды разделов более 0Fh? Ответ прост: там, где установлена другая ОС, не Microsoft. Опять же - делай выводы: в MSDN никогда и не будет кодов более 0Fh :-))))

Кстати, народ, есть идейка - кто-нибудь занимался написанием драйвера файловой системы? Пишите, будем сотрудничать :-)

Автор: PGsoft 17.7.2005, 21:11
Кстати, Guest - это я. Скачу между системами.

Автор: PGsoft 21.7.2005, 21:45
Кстати, многие вещи касательно файловой системы (в том числе и NTFS) описаны не в MSDN или DDK, а только в Microsoft IFS Kit. Он распространяется не бесплатно, а за несколько сотен долларов (см. сайт Microsoft). Кое-какие сведения имеются в файле "ntifs.h", распространяемым различными "исследователями" Windows NT... например, http://www.acc.umu.se/~bosse/

Если у кого-нибудь есть доступ к IFS Kit 98/2000/XP - кинте ссылку, пожалуйста. Или у кого-нибудь может на CD есть (на некоторых дисках вместе с Borland C/Visual C бывает DDK и IFS), не могли бы залить куда-нибудь в Интернет (или прислать мне по почте)? :-)

Автор: WERITAS 1.8.2005, 20:57
PGsoft

Испытал вашу "разрушительную" прогу. Сначала на ХР, потом на 2000. Пробовал не только на диске С, но и на диске А. Результата не дало НИКАКОГО! На диске А, ваще появилось сообщение, что он не могет найти устройство. По-моему данная прога будет работать тока на виндовсе НТ, на котором я это не испытывал.

P.S.
Ах да, вы уж пожалуста расшщифруйте ваши комментарии, а то я пытался по-разному их прочитать и никак не получилось

Автор: Ibragim 2.8.2005, 00:43
В программировании разбираюсь плоховато, но про накопители могу ответить все smile

1. Значит смотри - R-Studio NE, или R-Studio NTFS - лучший выбор однозначно. Не так уж сложно найти в нете и саму, и лекарство. Только показывай не на раздел, а на весь диск, правая кнопка мыши и Scan - тогда оно само найдет варианты NTFS Boot, выберешь, какой твой.

2. Совсем низкоуровневый доступ можно получить до порта, например с помощью драйверов smport.sys или подобных, и потом по стандарту ATA (www.t13.org) подавать на диск команды чтения сектора, и анализировать содержимое. Достаточно сложно, но необходимо, если на винте например бэд-блоки, и Windows просто говорит об ошибке и отказывается работать. Могу привести код по просьбе общественности (как инициализации и запуска драйвера, так чтения/запись в порт, так и команду чтения сектора) - только много получится, если никто не попросит - нечего форум засорять.


Автор: avek 16.8.2005, 13:18
Два замечания:
1) Под Windows 9x и на достаточно свежих материнках есть функции BIOS INT13h, AH=4xh, которые не ограничены 1024 цилиндрами и вообще адресуют диск через 64-битный LBA адрес.
2) В ATA уже давно гораздо больше 28 бит адреса (вроде 64, если я правильно помню), но это должны специально поддерживать драйвер диска и сам диск. Там есть команда, которая выдаётся перед нормальной командой чтения, записи и т.п. и устанавливает старшие биты адреса для следующей команды.
Короче, см. http://www.t13.org - точнее, чем там, на халяву не бывает.

Автор: Romikgy 16.8.2005, 14:11
Цитата(avek @ 16.8.2005, 13:18)
см. http://www.t13.org

Хороший ресурс smile
Только как , то что там описанно в исходник всунуть????

Автор: The Thing 10.9.2005, 14:16
У меня почему-то не работает:
Код

HANDLE hDrive=CreateFile("\\\\.\\c:",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);


в то время как
Код

HANDLE hDrive=CreateFile("\\\\.\\PHYSICALDRIVE0",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);


...работает...
???

Автор: PGsoft 10.9.2005, 15:58

The Thing, значит, у тебя Win9X smile См. MSDN/SDK.

Автор: The Thing 10.9.2005, 16:06
Win 2000

Автор: The Thing 11.9.2005, 15:57
нет... Я тут поковырялся... все верно.. доступ я получаю к физическому носителю PHYSICALDRIVE0 - мой жесткий диск, а c: или d: это уже логический диск.. и на прямую, как я понял, его получить нельзя.. на CreateFile(...) говорит, что уже занято иным процессом. Т.е. мне надо получить информацию о смещение до нужного логического диска... или как-то плясать через таблицу логических дисков. По идее должна быть фун возвращающая колонку, трек и сектор.. С которого начинается диск.

Нус... жду помощи!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)