Инструктаж перед боем Крис Касперски Спецвыпуск: Хакер, номер #058, стр. 058-018-6 // ПОДГОТОВКА SRB-блока SRB->SRB_Cmd = SC_EXEC_SCSI_CMD; // выполнить SCSI команду SRB->SRB_HaId = adapter_id; // ID адаптера SRB->SRB_Flags = SRB_DIR_IN|SRB_POSTING; // асинхр. чтение данных SRB->SRB_Target = read_id; // ID устройства SRB->SRB_BufPointer = buf; // сюда читаются данные SRB->SRB_BufLen = buf_len; // длина буфера SRB->SRB_SenseLen = SENSE_LEN; // длина SENSE-буфера SRB->SRB_CDBLen = 12; // размер ATAPI-пакета SRB->CDBByte [0] = MY_CMD; // ATAI-команда SRB->CDBByte [2] = HIBYTE(HIWORD(StartSector)); // номер первого сектора SRB->CDBByte [3] = LOBYTE(HIWORD(StartSector)); SRB->CDBByte [4] = HIBYTE(LOWORD(StartSector)); SRB->CDBByte [5] = LOBYTE(LOWORD(StartSector)); SRB->CDBByte [6] = HIBYTE(HIWORD(N_SECTOR)); // кол-во читаемых секторов SRB->CDBByte [7] = LOBYTE(HIWORD(N_SECTOR)); SRB->CDBByte [8] = HIBYTE(LOWORD(N_SECTOR)); SRB->CDBByte [8] = LOBYTE(LOWORD(N_SECTOR)); // адрес процедуры, которая будет получать уведомления SRB->SRB_PostProc = (void *) ASPI32Post; // посылаем SRB-запрос устройству SendASPI32Command(SRB); // возвращаемся из функции _до_ завершения выполнения запроса return 0; } //---------------------------------------------------------------------------- // эта callback-функция вызывается самим ASPI и получает управление при // при завершении выполнения запроса или же при возникновении ошибки. // в качестве параметра она получает указатель на экземпляр структуры // PSRB_ExecSCSICmd, содержащей всю необходимую информацию (статус, указатель // на буфер и т.д.) //---------------------------------------------------------------------------- void ASPI32Post (void *Srb) { FILE *f; // наш запрос выполнен успешно? if ((((PSRB_ExecSCSICmd) Srb)->SRB_Status) == SS_COMP) { // ЭТОТ КОД МОЖНО МОДИФИЦИРОВАТЬ ПО СВОЕМУ УСМОТРЕНИЮ //------------------------------------------------------- // записывает содержимое сектора в файл // внимание! PSRB_ExecSCSICmd) Srb)->SRB_BufLen содержит не актуальную // длину прочитанных данных, а размер самого буфера. если количество // байт, возвращенных устройством, окажется меньше размеров буфера, то // его хвост будет содержать мусор! здесь мы используем поле SRB_BufLen // только потому, что при вызове функции SendASPI32Command тщательно // следим за соответствием размера буфера количеству возвращаемой нам // информации if (f=fopen(F_NAME, "w")) { // записывает сектор в файл fwrite(((PSRB_ExecSCSICmd) Srb)->SRB_BufPointer,1, ((PSRB_ExecSCSICmd) Srb)->SRB_BufLen, f); fclose(f); } // кукарекаем и "размораживаем" поток, давая понять, что процедура // чтения закончилась MessageBeep(0); SetEvent(hEvent); //-------------------------------------------------------- } } main(int argc, char **argv) { void *p; int buf_len, TIME_OUT = 4000; if (argc<5) { fprintf(stderr,"USAGE:\n\tREAD.EXE adapter_id"\ ", read_id, StartSector, n_sec\n"); return 0; } // вычисляем длину буфера и выделяем для него память |