Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Защита программ от несанкционированного копированияСодержание книги
Поиск на нашем сайте
В этой главе мы рассмотрим некоторые способы организации защиты программ от несанкционированного копирования. Практически все эти способы используют специальные методы работы с дисками, поэтому мы и расположили данный материал в книге, посвященной дисковой системе. Прежде чем начинать проектирование системы защиты от несанкционированного доступа, нужно совершенно четко себе представлять, что именно и от кого вы собираетесь защищать. Это необходимо для правильного выбора средств защиты. Не существует никаких "абсолютно надежных" методов защиты. Можно утверждать, что достаточно квалифицированные системные программисты, пользующиеся современными средствами анализа работы программного обеспечения (отладчики, дизассемблеры, перехватчики прерываний и т. д.), располагающие достаточным временем, смогут преодолеть практически любую защиту. Этому способствует "открытость" операционной системы MS-DOS, которая хорошо документирована и предоставляет любой программе доступ к любым программным и аппаратным ресурсам компьютера. Поэтому при проектировании системы защиты следует исходить из предположения, что рано или поздно эта защита окажется снятой. Целью проектирования, по мнению авторов книги, должен быть выбор такого способа защиты, который обеспечит невозможность несанкционированного копирования для заранее определенного круга лиц и в течение ограниченного времени. Например, если вы собираетесь защитить от копирования коммерческую версию вашей программы, вам необязательно защищать эту версию от копирования "навсегда" - стоимость такой защиты может превысить стоимость самой программы. Вполне достаточно, чтобы способ защиты было невозможно "разгадать" к моменту появления следующей версии вашей программы, так как в новой версии вы сможете изменить этот способ. Короче говоря, уровень защиты должен быть таким, чтобы было бы выгоднее купить программу, а не заниматься снятием защиты от копирования. Иногда защищать программы от копирования вообще нецелесообразно. Фирма Microsoft и многие другие фирмы не защищают свои программные продукты от копирования. Для привлечения покупателей эти фирмы устанавливают низкие цены на свои изделия и, что более важно, обеспечивают сопровождение на высоком уровне и высококачественную документацию. Новые версии программ продаются зарегистрированным пользователям со значительными скидками. Эти версии появляются достаточно быстро, поэтому имеет смысл покупать новые версии, а не копировать старые. Таким образом, для выбора способа организации защиты от копирования необходим индивидуальный подход в каждом конкретном случае. Все средства защиты можно разделить на аппаратные и программные. Аппаратные средства защиты могут быть реализованы в виде специальных модулей, устанавливаемых в слоты расширения материнской платы компьютера, либо подключаемых к последовательному или параллельному порту. Эти модули могут содержать однокристальные микро-ЭВМ или специальные заказные микросхемы, выполняющие обмен кодовыми последовательностями с программой. Можно также использовать специальные версии BIOS. В нашей книге мы будем рассматривать только программные средства защиты, так как они доступны, не требуют специального оборудования и вместе с тем дают неплохие результаты. Мы опишем способы защиты дискет от копирования, а также защиты от копирования программ, записанных на жестком диске. Кроме того, небольшой раздел этой главы посвящен вопросам защиты программ от отладки. Те участки программ, которые отвечают за защиту, желательно составлять таким образом, чтобы они работали по-разному в зависимости от того, выполняются они в реальном времени, или под управлением какого-либо отладчика. Приведенный в этой главе перечень способов защиты не претендует на полноту, мы продемонстрируем лишь основные приемы защиты и приведем некоторые программы. Проблема защиты информации неисчерпаема, приступая к ее решению, помните о вечной борьбе брони и снаряда. Защита дискет от копирования Дискета, предназначенная для установки защищенного от копирования программного обеспечения должна быть сама защищена от копирования. Копирование дискет можно выполнить как по файлам (с помощью команд операционной системы COPY или XCOPY), так и по секторам (командой DISKCOPY, программами PCTOOLS, PCSHELL и аналогичными). Кроме того, существуют программы, специально предназначенные для копирования дискет, защищенных от копирования, например COPY2PC, TeleDisk. Специальные программы могут копировать дискеты, содержащие только определенные защищенные программные пакеты, или они могут повторять структуру дорожек диска с точностью до бита. Наиболее просто обеспечить защиту от программ копирования дискет по секторам. Можно предложить следующие достаточно простые способы, использующие нестандартное форматирование отдельных дорожек дискеты:
Очевидно, что все эти способы непригодны для защиты от таких программ копирования, которые способны копировать битовую структуру дорожек диска. Что можно порекомендовать в этом случае? Можно использовать специальную аппаратуру при записи установочных дискет, которая позволяет записывать отдельные дорожки или секторы как бы с промежуточным уровнем записи. Эти участки дорожки будут читаться нестабильно. Если скопировать такую дискету на обычной аппаратуре (с использованием обычных НГМД и программ битового копирования) то все дорожки будут читаться стабильно. Если при многократном контрольном чтении указанных секторов или дорожек каждый раз будут получены разные данные - мы имеем дело с оригиналом, в противном случае - с незаконной копией. Однако дискеты с промежуточным уровнем записи все-таки могут быть скопированы с использованием специальной аппаратуры, копирующей содержимое дорожек "аналоговым" способом (как в бытовом магнитофоне). Для защиты от аналогового копирования можно использовать дискеты, на которых в некоторых местах искусственно созданы дефекты магнитного покрытия - выжженные лазером небольшие точки или просто царапины. Проверка основывается на том, что в дефектные места невозможно ничего записать. Если мы имеем дело с копией, то на месте дефектных секторов окажутся хорошие - копируется только информация, но не дефекты дискеты! Разумеется можно использовать комбинации различных методов защиты от копирования. При этом легко распознаваемые методы (нестандартный размер сектора и т. п.) можно использовать для маскировки какого-либо другого, более тонкого метода защиты. Более подробно мы остановимся на нестандартном форматировании, как на наиболее простом методе защиты от копирования, для использования которого не требуется ни специальной аппаратуры, ни специально подготовленных дискет с дефектами. Используя сведения о работе с диском на физическом уровне, приведенные в этой книге, вы сможете самостоятельно использовать метод дефектных дискет или дискет с промежуточным уровнем записи. Программа FMT256 Самое простое, что можно сделать для того чтобы защитить установочную дискету от копирования - изменить размер секторов на дорожке. Приведем простую программу FMT256 (листинг 5.1), которая форматирует двадцатую дорожку диска емкостью 1,44 Мбайт в устройстве A:, создавая на ней секторы размером 256 байт. После форматирования программа записывает в первый сектор нестандартной дорожки строку, введенную с клавиатуры. Затем для контроля содержимое этого сектора считывается и отображается на экране. Обратите внимание на изменения в таблице параметров дискеты - они необходимы для использования нестандартного размера сектора. Какую информацию можно записать в нестандартный сектор? Если вы делаете установочную (инсталляционную) дискету, которая рассчитана на ограниченное количество установок, нестандартный сектор - самое подходящее место для хранения счетчика установок. Даже такие программы, как Norton Disk Editor не помогут прочитать или изменить значение этого счетчика. В этот же сектор можно записать и другую информацию, необходимую для правильной установки защищенного программного обеспечения. Листинг 5.1. Файл fmt256\fmt256.cpp #include <stdio.h>#include <conio.h>#include <dos.h>#include <stdlib.h>#include <bios.h>#include <string.h> typedef struct _DPT _{ unsigned char srt_hut; unsigned char dma_hlt; unsigned char motor_w; unsigned char sec_size; unsigned char eot; unsigned char gap_rw; unsigned char dtl; unsigned char gap_f; unsigned char fill_char; unsigned char hst; unsigned char mot_start;} DPT; DPT far *get_dpt(void); // Номер форматируемой дорожки#define TRK 20 // Код размера сектора - 256 байт#define SEC_SIZE 1 union REGS inregs, outregs;char diskbuf[512];char diskbuf1[512];char buf[80]; int main(void){ struct diskinfo_t di; unsigned status; unsigned char old_sec_size, old_fill_char, old_eot; int i, j; DPT far *dpt_ptr; printf("\nПрограмма уничтожит содержимое" "\n20-й дорожки диска А:." "\nЖелаете продолжить? (Y,N)\n"); i = getch(); if((i!= 'y') && (i!= 'Y')) return(-1); // Получаем адрес таблицы параметров дискеты dpt_ptr = get_dpt(); // Сохраняем старые значения из таблицы параметров old_sec_size = dpt_ptr->sec_size; old_fill_char = dpt_ptr->fill_char; old_eot = dpt_ptr->eot; // Устанавливаем в таблице параметров дискеты // код размера сектора, символ заполнения при // форматировании, количество секторов на дорожке dpt_ptr->sec_size = SEC_SIZE; dpt_ptr->fill_char = 0x77; dpt_ptr->eot = 18; // Устанавливаем тип диска inregs.h.ah = 0x17; inregs.h.al = 3; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Устанавливаем среду для форматирования inregs.h.ah = 0x18; inregs.h.ch = TRK; inregs.h.cl = dpt_ptr->eot; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Подготавливаем параметры // для функции форматирования di.drive = 0; di.head = 0; di.track = TRK; di.sector = 1; di.nsectors = 18; di.buffer = diskbuf; // Подготавливаем буфер формата для 18 секторов for(i=0, j=1; j<19; i += 4, j++) { diskbuf[i] = TRK; diskbuf[i+1] = 0; diskbuf[i+2] = j; diskbuf[i+3] = SEC_SIZE; } // Вызываем функцию форматирования дорожки status = _bios_disk (_DISK_FORMAT, &di) >> 8; printf("\nФорматирование завершилось с кодом: %d", status); // Записываем информацию в нестандартный сектор printf("\nВведите строку для записи " "в нестандартный сектор," "\nдлина строки не должна превышать 80 байтов" "\n->"); gets(buf); strcpy(diskbuf,buf); di.drive = 0; di.head = 0; di.track = 20; di.sector = 1; di.nsectors = 1; di.buffer = diskbuf; status = _bios_disk (_DISK_WRITE, &di) >> 8; if(status) { printf("\nОшибка при записи в нестандартный сектор: %d", status); return(-1); } di.drive = 0; di.head = 0; di.track = 20; di.sector = 1; di.nsectors = 1; di.buffer = diskbuf1; for(i = 0; i < 3; i++) { status = _bios_disk (_DISK_READ, &di) >> 8; if(!status) break; } printf("\nПрочитано из нестандартного сектора:\n%s\n", diskbuf1); // Восстанавливаем старые значения в // таблице параметров дискеты dpt_ptr->sec_size = old_sec_size; dpt_ptr->fill_char = old_fill_char; dpt_ptr->eot = old_eot; return(0);} /*** get_dpt** Вычислить адрес таблицы параметров дискеты** Функция возвращает указатель на таблицу* параметров дискеты***/DPT far *get_dpt(void){ void far * far *ptr; ptr = (void far * far *)MK_FP(0x0, 0x78); return(DPT far*)(*ptr);}Программа FMT81TRK Другой пример - использование нестандартного номера дорожки. Программа FMT81TRK (листинг 5.2) форматирует дорожку (стандартным образом) с номером 81. Обычно считается, что дискеты могут содержать 40 или 80 дорожек, соответственно, с номерами 0...39 или 0...79, однако возможно использование и дорожек с большими номерами. Обычные программы копирования будут копировать только 40 или 80 дорожек, "не заметив" нашей лишней дорожки. Этим мы и воспользуемся, записав на 81 дорожку контрольную информацию. Для разнообразия в примере используем функции GENERIC IOCTL. Запись этой информации, а также ее чтение и отображение выполняется программой RW82TRK, описанной в следующем разделе. Листинг 5.2. Файл fmt81trk\fmt81trk.cpp #include <dos.h>#include <stdio.h>#include <conio.h>#include <malloc.h>#include <errno.h> typedef struct _EBPB_{ unsigned sectsize; char clustsize; unsigned ressecs; char fatcnt; unsigned rootsize; unsigned totsecs; char media; unsigned fatsize; unsigned seccnt; unsigned headcnt; unsigned hiddensec_low; unsigned hiddensec_hi; unsigned long drvsecs;} EBPB; typedef struct _TRK_LY_{ unsigned no; unsigned size;} TRK_LY; typedef struct _DPB_{ char spec; char devtype; unsigned devattr; unsigned numofcyl; char media_type; EBPB bpb; char reserved[6]; unsigned trkcnt; TRK_LY trk[100];} DPB; typedef struct _DPB_FORMAT_{ char spec; unsigned head; unsigned track;} DPB_FORMAT; int main(void){ union REGS reg; struct SREGS segreg; DPB far *dbp; DPB_FORMAT far *dbp_f; int sectors, i; printf("\nПрограмма уничтожит содержимое" "\n81-й дорожки диска А:." "\nЖелаете продолжить? (Y,N)\n"); i = getch(); if((i!= 'y') && (i!= 'Y')) return(-1); // Заказываем память для блока параметров устройства dbp = (DPB far*)farmalloc(sizeof(DPB)); // Заказываем память для блока параметров устройства, // который будет использован для форматирования dbp_f = (DPB_FORMAT far*) farmalloc(sizeof(DPB_FORMAT)); if(dbp == NULL || dbp_f == NULL) { printf("\nМало памяти"); return(-1); } // Получаем текущие параметры диска А: dbp->spec = 0; reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0860; reg.x.dx = FP_OFF(dbp); segreg.ds = FP_SEG(dbp); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка: %d", reg.x.ax); return(-1); } // Заполняем блок парметров для форматирования dbp->spec = 5; // Считываем из BPB количество секторов на дорожке sectors = dbp->bpb.seccnt; // Подготавливаем таблицу, описывающую формат дорожки // Записываем количество секторов на дорожке dbp->trkcnt = sectors; // Для каждого сектора на дорожке в таблицу // записываем его номер и размер. for(i = 0; i < sectors; i++) { dbp->trk[i].no = i+1; dbp->trk[i].size = 512; } // Устанавливаем новые параметры для диска А: reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0840; reg.x.dx = FP_OFF(dbp); segreg.ds = FP_SEG(dbp); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка: %d", reg.x.ax); return(-1); } // Готовим блок параметров устройства, // который будет использован при вызове // операции проверки возможности форматирования // дорожки dbp_f->spec = 1; dbp_f->head = 0; dbp_f->track = 81; reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0842; reg.x.dx = FP_OFF(dbp_f); segreg.ds = FP_SEG(dbp_f); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка: %d", reg.x.ax); return(-1); } // Если указанный формат дорожки поддерживается, // поле специальных функций будет содержать 0. // Проверяем это if(dbp_f->spec!= 0) { printf("\nФормат дорожки не поддерживается"); return(-1); } // Заполняем блок параметров для выполнения // операции форматирования dbp_f->spec = 0; dbp_f->head = 0; dbp_f->track = 81; // Форматируем дорожку с номером 81, головка 0 reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0842; reg.x.dx = FP_OFF(dbp_f); segreg.ds = FP_SEG(dbp_f); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка: %d", reg.x.ax); return(-1); } // Освобождаем память farfree(dbp); farfree(dbp_f); return(0);}Программа RW81TRK Для записи и последующего чтения информации на дополнительную дорожку, созданную предыдущей программой, можно использовать программу RW81TRK (листинг 5.3). Листинг 5.3. Файл fmt81trk\fmt81trk.cpp #include <dos.h>#include <stdio.h>#include <string.h>#include <malloc.h>#include <errno.h> typedef struct _DPB_WR_{ char spec; unsigned head; unsigned track; unsigned sector; unsigned sectcnt; void _far *buffer;} DPB_WR; char buf[1000];char buf1[80]; int main(void){ union REGS reg; struct SREGS segreg; DPB_WR far *dbp_wr; int sectors, i; // Заказываем память для блока параметров // устройства,который будет // использован для чтения и записи dbp_wr = (DPB_WR far*)farmalloc(sizeof(DPB_WR)); if(dbp_wr == NULL) { printf("\nМало памяти"); return(-1); } // Записываем информацию в нестандартный сектор printf("\nВведите строку для записи " "в нестандартный сектор," "\nдлина строки не должна превышать 80 байт" "\n->"); gets(buf1); strcpy(buf,buf1); // Заполняем блок параметров для выполнения // операции записи dbp_wr->spec = 0; dbp_wr->head = 0; dbp_wr->track = 81; dbp_wr->sector = 0; dbp_wr->sectcnt = 1; dbp_wr->buffer = buf; // Выполняем операцию записи reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0841; reg.x.dx = FP_OFF(dbp_wr); segreg.ds = FP_SEG(dbp_wr); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка при записи: %d", reg.x.ax); return(-1); } // Заполняем блок параметров для выполнения // операции чтения dbp_wr->spec = 0; dbp_wr->head = 0; dbp_wr->track = 81; dbp_wr->sector = 0; dbp_wr->sectcnt = 1; dbp_wr->buffer = buf; // Выполняем операцию чтения дорожки reg.x.ax = 0x440d; reg.h.bl = 1; reg.x.cx = 0x0861; reg.x.dx = FP_OFF(dbp_wr); segreg.ds = FP_SEG(dbp_wr); intdosx(®, ®, &segreg); if(reg.x.cflag!= 0) { printf("\nОшибка при чтении: %d",reg.x.ax); return(-1); } printf("\nПрочитано из нестандартного " "сектора:\n%s\n", buf); // Освобождаем память farfree(dbp_wr); return(0);}Программа FMTINTRL Более интересный способ защиты дискет от копирования связан с использованием при форматировании нестандартного чередования секторов на дорожке. В программе FMTINTRL (листинг 5.4) использовано "обратное" расположение секторов - вначале идет сектор с номером 15, затем 14 и т. д. Листинг 5.4. Файл fmtintrl\fmtintrl.cpp #include <stdio.h>#include <conio.h>#include <dos.h>#include <stdlib.h>#include <bios.h> // Номер форматируемой дорожки#define TRK 20 // Код размера сектора - 512 байт#define SEC_SIZE 2 typedef struct _DPT _{ unsigned char srt_hut; unsigned char dma_hlt; unsigned char motor_w; unsigned char sec_size; unsigned char eot; unsigned char gap_rw; unsigned char dtl; unsigned char gap_f; unsigned char fill_char; unsigned char hst; unsigned char mot_start;} DPT; DPT far *get_dpt(void); union REGS inregs, outregs;char diskbuf[512]; int main(void){ struct diskinfo_t di; unsigned status; unsigned char old_sec_size, old_fill_char, old_eot; int i, j; DPT far *dpt_ptr; printf("\nПрограмма уничтожит содержимое" "\n20-й дорожки диска А:." "\nЖелаете продолжить? (Y,N)\n"); i = getch(); if((i!= 'y') && (i!= 'Y')) return(-1); // Получаем адрес таблицы параметров дискеты dpt_ptr = get_dpt(); // Сохраняем старые значения из таблицы параметров old_sec_size = dpt_ptr->sec_size; old_fill_char = dpt_ptr->fill_char; old_eot = dpt_ptr->eot; // Устанавливаем в таблице параметров дискеты // код размера сектора, символ заполнения при // форматировании, количество секторов на дорожке dpt_ptr->sec_size = SEC_SIZE; dpt_ptr->fill_char = 0xf6; dpt_ptr->eot = 18; // Устанавливаем тип диска inregs.h.ah = 0x17; inregs.h.al = 3; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Устанавливаем среду для форматирования inregs.h.ah = 0x18; inregs.h.ch = TRK; inregs.h.cl = dpt_ptr->eot; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Подготавливаем параметры // для функции форматирования di.drive = 0; di.head = 0; di.track = TRK; di.sector = 1; di.nsectors = 18; di.buffer = diskbuf; // Подготавливаем буфер формата для 18 секторов // Используем обратный порядок расположения секторов // на дорожке for(i=0, j=18; j>0; i += 4, j--) { diskbuf[i] = TRK; diskbuf[i+1] = 0; diskbuf[i+2] = j; diskbuf[i+3] = SEC_SIZE; } // Вызываем функцию форматирования дорожки status = _bios_disk (_DISK_FORMAT, &di) >> 8; printf("\nФорматирование завершилось с кодом: %d", status); // Восстанавливаем старые значения в // таблице параметров дискеты dpt_ptr->sec_size = old_sec_size; dpt_ptr->fill_char = old_fill_char; dpt_ptr->eot = old_eot; return(0);} /*** get_dpt** Вычислить адрес таблицы параметров дискеты** Функция возвращает указатель на таблицу* параметров дискеты***/DPT far *get_dpt(void){ void far * far *ptr; ptr = (void far * far *)MK_FP(0x0, 0x78); return(DPT far*)(*ptr);}Программа CHKINTRL Для анализа используемого чередования секторов можно использовать программу CHKINTRL (листинг 5.5), которая пытается прочитать подряд два расположенных рядом сектора с номерами 1 и 2. Если используется стандартное чередование, то секторы с номерами 1 и 2 находятся рядом. Если же дорожка отформатирована приведенной выше программой, то эти секторы находятся на максимальном удалении друг от друга. Программа анализирует время, необходимое на то, чтобы 50 раз подряд прочитать эти два сектора на двадцатой дорожке. Вначале используется головка 0 - это нестандартная дорожка, подготовленная программой FMTINTRL, затем - головка 1, для которой раньше было выполнено стандартное форматирование. Листинг 5.5. Файл chkintrl\chkintrl.cpp #include <stdio.h>#include <conio.h>#include <bios.h>#include <dos.h>#include <stdlib.h>#include <time.h> char diskbuf[1024]; int main(void){ unsigned status = 0, i, j; struct diskinfo_t di; time_t start, end; float t1, t2; // Читаем первый сектор дорожки // для синхронизации таймера di.drive = 0; di.head = 0; di.track = 20; di.sector = 1; di.nsectors = 1; di.buffer = diskbuf; for(i = 0; i < 3; i++) { status = _bios_disk (_DISK_READ, &di) >> 8; if(!status) break; } // Отсчет времени начинаем сразу после чтения // сектора,это позволит компенсировать время, // необходимое на разгон мотора НГМД start = clock(); // Повторяем 50 раз чтение секторов с номерами 1 и 2 for(j=0; j<50; j++) { di.drive = 0; di.head = 0; di.track = 20; di.sector = 1; di.nsectors = 2; di.buffer = diskbuf; for(i = 0; i < 3; i++) { status = _bios_disk (_DISK_READ, &di) >> 8; if(!status) break; } } end = clock(); t1 = ((float)end - start) / CLK_TCK; printf("Время для головки 0: %5.1f\n",t1); // Выполняем аналогичную процедуру для дорожки, // которая была отформатирована обычным способом di.drive = 0; di.head = 1; di.track = 20; di.sector = 1; di.nsectors = 1; di.buffer = diskbuf; for(i = 0; i < 3; i++) { status = _bios_disk (_DISK_READ, &di) >> 8; if(!status) break; } start = clock(); for(j=0; j<50; j++) { di.drive = 0; di.head = 1; di.track = 20; di.sector = 1; di.nsectors = 2; di.buffer = diskbuf; for(i = 0; i < 3; i++) { status = _bios_disk (_DISK_READ, &di) >> 8; if(!status) break; } } end = clock(); t2 = ((float)end - start) / CLK_TCK; printf("Время для головки 1: %5.1f\n",t2); return 0;}
|
||||
Последнее изменение этой страницы: 2016-09-19; просмотров: 361; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.189.143.1 (0.012 с.) |