Разработка драйверов под Windows

Автор работы: Пользователь скрыл имя, 28 Апреля 2013 в 23:02, курсовая работа

Краткое описание

Драйвер (от англ. driver) - это компьютерная программа, с помощью которой другая программа (обычно, операционная система) получает доступ к аппаратному обеспечению стандартным образом.

Содержание работы

1. Теоретические сведения 4
1.1. Разработка драйверов ядра Windows 4
1.2. Драйверы виртуальных устройств Windows. 11
1.3. Доступ к существующим драйверам из приложений пользовательского режима 21
2. Выполнение курсовой работы 27
2.1. Шаг 1 27
Листинг Kurs_test.cpp 27
Листинг beeper.sys 28
2.2. Шаг 2 30
Листинг shablon.c 30
Листинг курсовая2.cpp 32
2.3. Шаг 3 34
Листинг курсовая.cpp 34
2.4. Шаг 4 35
3. Работа приложения 38

Содержимое работы - 1 файл

КР_СПО_ЕрмаковNew.doc

— 388.73 Кб (Скачать файл)

указатель на структуру OVERLAPPED, которая используется для асинхронного вызова функции.

После возврата управления, в случае успешного завершения функции, в структуре PARTITION_INFORMATION_EX хранится информация о разделе.

// 4th part

Производится анализ и  вывод информации. Перед возвращением управления операционной системе можно  закрыть открытые дескрипторы. Это  позволяет сделать функция CloseHandle(__in HANDLE). Если дескрипторы не закрыть, то это сделает операционная система за Вас.

 

  1. Выполнение  курсовой работы

    1. Шаг 1

Задание: 1. Разработать драйвер ядра с доступом к портам, выполняющий действия согласно варианту и осуществляющий вывод информации в окно Debug View (по варианту), а также приложение, запускающее драйвер.

 

     7

Воспроизвести 7 сигналов одинаковой длительности с постоянной частотой звучания.


Листинг Kurs_test.cpp

 

#include "stdafx.h"

#include "windows.h"

#include "stdlib.h"

 

int _tmain(int argc, _TCHAR* argv[]){

SC_HANDLE hSCManager;

SC_HANDLE hService;

char acDriverPath[256]; 

 

hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);

if (hSCManager!=0){

GetFullPathName("beeper.sys",sizeof acDriverPath,acDriverPath,NULL);

// регистрация проигрывателя в таблице диспетчера SCManager

hService=CreateService(hSCManager,"beeper11","Nice Melody Beeper11",

SERVICE_START+DELETE,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,

SERVICE_ERROR_IGNORE,acDriverPath,NULL,NULL,NULL,NULL,NULL);

if (hService!=0){

StartService(hService, 0, NULL);

 

// Удаляем запись о драйвере

DeleteService(hService);

CloseServiceHandle(hService);

}else MessageBox(NULL,"Can't register driver",NULL,MB_ICONSTOP);

CloseServiceHandle(hSCManager);

}else MessageBox(NULL,"Can't connect to SCManager",NULL, MB_ICONSTOP);

return 0;

}

Листинг beeper.sys

#include <ndis.h>

 

#define TIMER_FREQUENCY  1193167   // 1,193,167 Hz

#define PITCH_C   523    //  523,25 Hz

#define PITCH_Cs   554    //  554,37 Hz

#define PITCH_D   587    //  587,33 Hz

#define PITCH_Ds   622    //  622,25 Hz

#define PITCH_E   659    //  659,25 Hz

#define PITCH_F   698    //  698,46 Hz

#define PITCH_Fs   740    //  739,99 Hz

#define PITCH_G   784    //  783,99 Hz

#define PITCH_Gs   831    //  830,61 Hz

#define PITCH_A   880    //  880,00 Hz

#define PITCH_As   988    //  987,77 Hz

 

void DO_DELAY(int time){

long i,j;

for (i=0; i<=time*0xfffff; i++) {}

}

 

void DO_BIG_DELAY(int time){

DO_DELAY(2*time);

}

 

void Xylophone(int nPitch){

int nTone = TIMER_FREQUENCY/nPitch

_asm {

mov al, 10110110b ;//запись управляющего слова в 43h

out 43h, al       ;//Канал управления звуком - логическая схема, использующая тональный сигнал таймера и программно-управляемые биты системного порта

 

mov eax, nTone    ;//запись пересчитанной частоты в 42

out 42h, al       ;//старшая часть

 

mov al, ah        ;//младшая часть

out 42h, al

         

in al, 61h        ;//изменение управляющей последовательности - преобразование последних битов в единицы

                  ;//бит 0 - разрешение использования спикера

  ;//бит 1 - разрешение подключения таймер-2 к спикеру

or  al, 00000011b    ; speaker ON

out 61h, al      

}

DO_DELAY(0x7f);

_asm {

in al, 61h

and al, 11111100b ; speaker OFF

out 61h, al

}

 

int DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pusRegistryPath ){

Xylophone(PITCH_C);

Xylophone(PITCH_С);

Xylophone(PITCH_С);

Xylophone(PITCH_С);

Xylophone(PITCH_С);

Xylophone(PITCH_С);

Xylophone(PITCH_С); 

 

return STATUS_DEVICE_CONFIGURATION_ERROR;

}

 

    1. Шаг 2

Разработать драйвер виртуального устройства, позволяющий выполнять  действия, доступные только на нулевом  уровне привилегий (в соответствии с вариантом), а затем передавать результаты в приложение на 3 уровень  привилегий для вывода их на экран.

В приложении выводим результат  в стандартное окно Windows.

 

Задание

7

Определить наличие и тип дисковода  А: и вывести в стандартное  окно, есть ли он и какого типа, в  виде текста.

Указание. Драйвер передает в вызывающую программу значение из CMOS, а именно из байта по смещению 10h – наличие и тип дисководов A: (старшая 16-ричная цифра) и B: (младшая). Значения:

0 – нет дисковода, 4 - на 1.44Мб


Листинг shablon.c

#include <ntddk.h>          // various NT definitions

#include <ndis.h>

 

#define IOCTL_GET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)

 

UNICODE_STRING g_usDeviceName;

UNICODE_STRING g_usSymbolicLinkName;

 

void DriverUnload(IN PDRIVER_OBJECT pDriverObject){

IoDeleteSymbolicLink(&g_usSymbolicLinkName);

IoDeleteDevice(pDriverObject->DeviceObject);

}

 

NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp){//обработка MJ_CREATE MJ_CLOSE

pIrp->IoStatus.Status = STATUS_SUCCESS;

pIrp->IoStatus.Information = 0;

IoCompleteRequest(pIrp,IO_NO_INCREMENT);

return STATUS_SUCCESS;

}

 

NTSTATUS DispatchControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp){//обработка IRP_MJ_DEVICECONTROL

NTSTATUS status;

int regEsi;

// берем указатель на IO_STACK_LOCATION, в нем на IoControlCode

if (pIrp->Tail.Overlay.CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode ==IOCTL_GET){

//Сравниваем код  действия и если это таки  наш клиент, то:

_asm{

mov eax,0

mov al,10h

out 70h,al

in al,71h

cbw

cwde

mov regEsi,eax

}

// это наша функциональность - берем содержимое регистра esi

// записываем его  в системный буфер 

*((int*)pIrp->AssociatedIrp.SystemBuffer) = regEsi;

pIrp->IoStatus.Information = 4;    //  и задаем размер результат

status = STATUS_SUCCESS;

} else status = STATUS_INVALID_DEVICE_REQUEST;

pIrp->IoStatus.Status = status; 

IoCompleteRequest(pIrp, IO_NO_INCREMENT);

return(status);

}

 

int DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pusRegistryPath){

NTSTATUS Status;

PDEVICE_OBJECT pDeviceObject;

 

// инициализируем Unicode-строки

RtlInitUnicodeString(&g_usDeviceName, L"\\Device\\DevGet");

RtlInitUnicodeString(&g_usSymbolicLinkName, L"\\??\\sldevGet");

 

// заполняем объект  драйвера - доходчиво объясняем драйвера  какая функция что обрабатывает

pDriverObject->DriverUnload = &DriverUnload;

pDriverObject->MajorFunction[IRP_MJ_CREATE]         = &DispatchCreateClose;

pDriverObject->MajorFunction[IRP_MJ_CLOSE]          = &DispatchCreateClose;

pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DispatchControl;

 

// создаем логический объект виртуального устройства

Status = IoCreateDevice(pDriverObject, 0, &g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);

if( !NT_SUCCESS(Status) ){return Status;}

//создаем символьную ссылку на устройство

Status = IoCreateSymbolicLink(&g_usSymbolicLinkName, &g_usDeviceName);

if( !NT_SUCCESS(Status) ){

IoDeleteDevice(pDeviceObject);

return Status;

}

return Status;

}

Листинг курсовая2.cpp

#include "stdafx.h"

#include "windows.h"

#include "stdlib.h"

 

#define IOCTL_GET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)

 

int _tmain(int argc, _TCHAR* argv[]){

HANDLE hDevice;

BOOL   DevControl;

DWORD  dwBytesReturned;

LPVOID adwInBuffer, adwOutBuffer;

char   stroka[7];

 

    hDevice = CreateFile("\\\\.\\sldevGet",GENERIC_READ+GENERIC_WRITE,0, NULL,OPEN_EXISTING, 0, NULL);

/*

Параметры:

lpFileName Адрес нульзаканчивающейся  строки, которая определяет имя  объекта для его создания или  открытия.

 

dwDesiredAccess Тип досупа  к объекту. Данный параметр  может принимать любую комбинацию  из следующих значений:

Значение:     Описание:

0             Определяет запрос о доступности  объекта на указанном устройстве. Приложение может запросить атрибуты  устройства, без доступа к нему.

GENERIC_READ  Определяет  доступ на чтение из объекта.  Данные могут быть прочитаны  из файла и файловый указатель  может быть перемещен. Комбинируйте  с GENERIC_WRITE для доступа к чтению-записи.

GENERIC_WRITE Определяет  доступ на запись в объект. Данные могут быть записаны  в файл и файловый указатель  может быть перемещен. Комбинируйте  с GENERIC_READ для доступа к чтению-записи.

 

dwShareMode Режим разделяемого  доступа к объекту. При нулевом  значеним объект не может быть  использован совместно несколькими  программами. Все последующие  операции открытия объекта будут  терпеть неудачу, пока дескриптор  объекта не будет закрыт. Для  совместного использования объекта  используйте комбинацию следующих  значений:

Значение:         Описание:

FILE_SHARE_DELETE Допускает  последовательность операций открытия  объекта для запроса доступа  на удаление.

FILE_SHARE_READ   Допускает  последовательность операций открытия  объекта для запроса доступа  на чтение.

FILE_SHARE_WRITE  Допускает  последовательность операций открытия  объекта для запроса доступа  на запись

 

lpSecurityAttributes Адрес  структуры SECURITY_ATTRIBUTES, которая определяет  может или нет возвращаемый  функцией дескриптор быть унаследован  дочерним процессом.

Если lpSecurityAttributes равен NULL, то дескриптор не может быть унаследован.

 

dwCreationDisposition

Значение: Описание:

CREATE_ALWAYS     Создает новый файл, всегда.

                  Если файл существует, функция  перезаписывает файл.

CREATE_NEW        Создает новый файл. Функция завершится  с ошибкой если файл существует.

OPEN_ALWAYS       Открыть файл, всегда. Если файл  не существует, функция создает  его так же, если dwCreationDisposition был  бы CREATE_NEW.

OPEN_EXISTING     Открывает файл. Функция завершится  с ошибкой если файл не существует.

TRUNCATE_EXISTING Открывает  файл и обрезает его до нулевого  размера. Функция завершится с  ошибкой если файл не существует.

 

dwFlagsAndAttributes Флаги  и атрибуты файла.

 

Когда открывается  существующий файл, то CreateFile игнорирует файл-шаблон.

 

Возвращаемые значения:

Если функция  успешна, возвращается открытый дескриптор указанного файла. Если указанный файл существует до вызова функции и параметр dwCreationDisposition равен CREATE_ALWAYS или OPEN_ALWAYS, вызов GetLastError вернет ERROR_ALREADY_EXISTS, даже если функция  успешна. Если файл не существует перед  вызовом, GetLastError вернет 0 (ноль).

 

При ошибке, функция  вернет INVALID_HANDLE_VALUE. Для получения  дополнительной информации об ошибке, вызывайте GetLastError.

*/

if (hDevice != 0){

        DevControl = DeviceIoControl(hDevice,IOCTL_GET,&adwInBuffer, sizeof(adwInBuffer),&adwOutBuffer,sizeof(adwOutBuffer), &dwBytesReturned,NULL);

/*

hDevice         - это хэндл, возвpащенный CreateFile'ом.

dwIocontrolCode - это значение, котоpое указывает опеpацию, котоpую  должен выполнить.

lpInBuffer      - это адpес буфеpа, котоpый содеpжит  данные, необходимые для выполнения  опеpации, указанные в dwIoControlCode. Если  опеpация не тpебует данных, вы  можете пеpедать NULL.

nInBufferSize   - это  pазмеp в байтах данных в буфеpе,  на котоpый указывает lpInBuffer.

lpOutBuffer     - это адpес буфеpа, котоpый заполнится  выходными данными, когда опеpация  будет успешно пpоизведена. Если  опеpация не пpедполагает выходных  данных, это поле должно pавняться NULL'у. 

nOutBufferSiz   - это  pазмеp в байтах буфеpа, на котоpый  указывает lpOutbuffer.

lpBytesReturned - адpес пеpеменной  типа dword, котоpая получит pазмеp данных, вписанных в lpOutBuffer.

lpOverlapped    - это  адpес стpуктуpы OVERLAPPED, если вы  хотите, чтобы опеpация была асинхpонной.  Если вы хотите подождать, пока  опеpация будет выполнена, поместите  NULL в это поле.

*/

if ((DevControl != 0)&&(dwBytesReturned != 0)){

wsprintf((LPSTR) stroka, "%X", adwOutBuffer);//запись строки в буфер (adwOutBuffer --> stroka)

if (stroka =="00000100") MessageBox(NULL,"Found 1.44 Mb","Yermakov FDD scaner",MB_OK);

else  MessageBox(NULL,"Not found","Yermakov FDD scaner",MB_OK);

}else MessageBox(NULL,"Can't send control code",NULL,MB_OK);

CloseHandle(hDevice);

}else MessageBox(NULL, "Dev is not present", NULL, MB_ICONSTOP);

return 0;

}

 

    1. Шаг 3

Вариант

Задание

7

Вывести номер одного из разделов жесткого диска (IOCTL_DISK_GET_PARTITION_INFO_EX)


Листинг курсовая.cpp

#include <windows.h>

#include <winioctl.h>

#include <stdio.h>

 

BOOL GetPartitionNumber(PARTITION_INFORMATION_EX  *pex)

{

HANDLE hDevice;               // дескриптор проверяемого устройства

BOOL   bResult;               // флажок результата

DWORD  junk;                  

 

hDevice = CreateFile(TEXT("\\\\.\\c:"),          // открываемое устройство

GENERIC_READ | GENERIC_WRITE, // доступ к устройству

FILE_SHARE_READ |FILE_SHARE_WRITE,   // режим совместного использования

NULL,                                // атрибуты безопасности по умолчанию

OPEN_EXISTING,                       // расположение

0,                                   // атрибуты файла

NULL);                               // не копировать атрибуты файла

if (hDevice == INVALID_HANDLE_VALUE){             // невозможно открыть устройство

printf("CreateFile() failed!\n");

return (FALSE);

}

bResult = DeviceIoControl(hDevice,                   // запрошенное устройство

           IOCTL_DISK_GET_PARTITION_INFO_EX,  // выполняемая операция

                        NULL,                              // указатель на входной буфер

    0,                                // размер входного буфера

                       pex, sizeof(*pex),               // выходной буфер

                        &junk,                             // количество возвращаемых байтов

                       (LPOVERLAPPED) NULL);               // синхронизация ввода/вывода (I/O)

CloseHandle(hDevice);

return (bResult);

}

 

int main(int argc, char *argv[])

{

PARTITION_INFORMATION_EX  pex;            // структура устройства

/*

typedef struct {

PARTITION_STYLE PartitionStyle;  // формат раздела

LARGE_INTEGER   StartingOffset;  // смещение начала раздела

LARGE_INTEGER   PartitionLength;  // размер раздела

DWORD           PartitionNumber;  // номер раздела

BOOLEAN         RewritePartition;  // если раздел перезаписываемый то TRUE

union {

PARTITION_INFORMATION_MBR Mbr;  // дополнительная информация MBR Style раздела

PARTITION_INFORMATION_GPT Gpt;  // дополнительная информация GPT Style раздела

} ;

} PARTITION_INFORMATION_EX;

*/

BOOL bResult;                           

 

bResult = GetPartitionNumber (&pex);

if (bResult){ printf("PartitionNumber = %d\n", pex.PartitionNumber );

}else{ printf ("GetPartitionNumber() failed. Error %d.\n", GetLastError());}

system("PAUSE");

Информация о работе Разработка драйверов под Windows