Пишу первый драйвер (на c), не запускается :(

Тема в разделе "WASM.NT.KERNEL", создана пользователем alexey_k, 10 авг 2010.

  1. alexey_k

    alexey_k New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2006
    Сообщения:
    24
    Доброго!

    Вобщем пишу свой первый драйвер. Для начала собрал утилиту instdrv.exe (у меня - starter.exe):
    Код (Text):
    1. /*++
    2.  
    3. Copyright (c) 1993  Microsoft Corporation
    4.  
    5. Module Name:
    6.  
    7. Instdrv.c
    8.  
    9. Abstract:
    10.  
    11. A simple Win32 app that installs a device driver
    12.  
    13. Environment:
    14.  
    15. user mode only
    16.  
    17. Notes:
    18.  
    19. See readme.txt
    20.  
    21. Revision History:
    22.  
    23. 06-25-93 : created
    24. --*/
    25.  
    26.  
    27.  
    28. #include <windows.h>
    29. #include <stdio.h>
    30. #include <stdlib.h>
    31. #include <string.h>
    32.  
    33.  
    34.  
    35. BOOL
    36. InstallDriver(
    37.     IN SC_HANDLE  SchSCManager,
    38.     IN LPCTSTR    DriverName,
    39.     IN LPCTSTR    ServiceExe
    40.     );
    41.  
    42. BOOL
    43. RemoveDriver(
    44.     IN SC_HANDLE  SchSCManager,
    45.     IN LPCTSTR    DriverName
    46.     );
    47.  
    48. BOOL
    49. StartDriver(
    50.     IN SC_HANDLE  SchSCManager,
    51.     IN LPCTSTR    DriverName
    52.     );
    53.  
    54. BOOL
    55. StopDriver(
    56.     IN SC_HANDLE  SchSCManager,
    57.     IN LPCTSTR    DriverName
    58.     );
    59.  
    60. BOOL
    61. OpenDevice(
    62.     IN LPCTSTR    DriverName
    63.     );
    64.  
    65.  
    66.  
    67. VOID
    68. __cdecl
    69. main(
    70.     IN int   argc,
    71.     IN char *argv[]
    72.     )
    73. /*++
    74.  
    75. Routine Description:
    76.  
    77. Arguments:
    78.  
    79. Return Value:
    80.  
    81. --*/
    82. {
    83.   SC_HANDLE   schSCManager;
    84.  
    85.   if (argc != 3)
    86.   {
    87.     char currentDirectory[128];
    88.  
    89.     printf ("usage: instdrv <driver name> <.sys location>\n");
    90.     printf ("           to install a kernel-mode device driver, or:\n");
    91.     printf ("       instdrv <driver name> remove\n");
    92.     printf ("           to remove a kernel-mode device driver\n\n");
    93.  
    94.     GetCurrentDirectory (128,
    95.         currentDirectory
    96.         );
    97.  
    98.     printf ("       Example: instdrv simpldrv %s\\obj\\i386\\simpldrv.sys\n",
    99.         currentDirectory
    100.         );
    101.  
    102.     exit (1);
    103.   }
    104.  
    105.   schSCManager = OpenSCManager (NULL,                 // machine (NULL == local)
    106.       NULL,                 // database (NULL == default)
    107.       SC_MANAGER_ALL_ACCESS // access required
    108.       );
    109.  
    110.   if (!_stricmp (argv[2],
    111.             "remove"
    112.           ))
    113.   {
    114.     StopDriver (schSCManager,
    115.         argv[1]
    116.         );
    117.  
    118.     RemoveDriver (schSCManager,
    119.         argv[1]
    120.         );
    121.   }
    122.   else
    123.   {
    124.     InstallDriver (schSCManager,
    125.         argv[1],
    126.         argv[2]
    127.         );
    128.  
    129.     StartDriver (schSCManager,
    130.         argv[1]
    131.         );
    132.  
    133.     OpenDevice (argv[1]);
    134.  
    135.   }
    136.  
    137.   CloseServiceHandle (schSCManager);
    138. }
    139.  
    140.  
    141.  
    142. BOOL
    143. InstallDriver(
    144.     IN SC_HANDLE  SchSCManager,
    145.     IN LPCTSTR    DriverName,
    146.     IN LPCTSTR    ServiceExe
    147.     )
    148. /*++
    149.  
    150. Routine Description:
    151.  
    152. Arguments:
    153.  
    154. Return Value:
    155.  
    156. --*/
    157. {
    158.   SC_HANDLE  schService;
    159.   DWORD      err;
    160.  
    161.  
    162.  
    163.   //
    164.   // NOTE: This creates an entry for a standalone driver. If this
    165.   //       is modified for use with a driver that requires a Tag,
    166.   //       Group, and/or Dependencies, it may be necessary to
    167.   //       query the registry for existing driver information
    168.   //       (in order to determine a unique Tag, etc.).
    169.   //
    170.  
    171.   schService = CreateService (SchSCManager,          // SCManager database
    172.       DriverName,           // name of service
    173.       DriverName,           // name to display
    174.       SERVICE_ALL_ACCESS,    // desired access
    175.       SERVICE_KERNEL_DRIVER, // service type
    176.       SERVICE_DEMAND_START,  // start type
    177.       SERVICE_ERROR_NORMAL,  // error control type
    178.       ServiceExe,            // service's binary
    179.       NULL,                  // no load ordering group
    180.       NULL,                  // no tag identifier
    181.       NULL,                  // no dependencies
    182.       NULL,                  // LocalSystem account
    183.       NULL                   // no password
    184.       );
    185.  
    186.   if (schService == NULL)
    187.   {
    188.     err = GetLastError();
    189.  
    190.     if (err == ERROR_SERVICE_EXISTS)
    191.     {
    192.       //
    193.       // A common cause of failure (easier to read than an error code)
    194.       //
    195.  
    196.       printf ("failure: CreateService, ERROR_SERVICE_EXISTS\n");
    197.     }
    198.     else
    199.     {
    200.       printf ("failure: CreateService (0x%02x)\n",
    201.           err
    202.           );
    203.     }
    204.  
    205.     return FALSE;
    206.   }
    207.   else
    208.   {
    209.     printf ("CreateService SUCCESS\n");
    210.   }
    211.  
    212.   CloseServiceHandle (schService);
    213.  
    214.   return TRUE;
    215. }
    216.  
    217.  
    218.  
    219. BOOL
    220. RemoveDriver(
    221.     IN SC_HANDLE  SchSCManager,
    222.     IN LPCTSTR    DriverName
    223.     )
    224. /*++
    225.  
    226. Routine Description:
    227.  
    228. Arguments:
    229.  
    230. Return Value:
    231.  
    232. --*/
    233. {
    234.   SC_HANDLE  schService;
    235.   BOOL       ret;
    236.  
    237.   schService = OpenService (SchSCManager,
    238.       DriverName,
    239.       SERVICE_ALL_ACCESS
    240.       );
    241.  
    242.   if (schService == NULL)
    243.   {
    244.     printf ("failure: OpenService (0x%02x)\n", GetLastError());
    245.     return FALSE;
    246.   }
    247.  
    248.   ret = DeleteService (schService);
    249.  
    250.   if (ret)
    251.   {
    252.     printf ("DeleteService SUCCESS\n");
    253.   }
    254.   else
    255.   {
    256.     printf ("failure: DeleteService (0x%02x)\n",
    257.         GetLastError()
    258.         );
    259.   }
    260.  
    261.   CloseServiceHandle (schService);
    262.  
    263.   return ret;
    264. }
    265.  
    266.  
    267.  
    268. BOOL
    269. StartDriver(
    270.     IN SC_HANDLE  SchSCManager,
    271.     IN LPCTSTR    DriverName
    272.     )
    273. {
    274.   SC_HANDLE  schService;
    275.   BOOL       ret;
    276.   DWORD      err;
    277.  
    278.   schService = OpenService (SchSCManager,
    279.       DriverName,
    280.       SERVICE_ALL_ACCESS
    281.       );
    282.  
    283.   if (schService == NULL)
    284.   {
    285.     printf ("failure: OpenService (0x%02x)\n", GetLastError());
    286.     return FALSE;
    287.   }
    288.  
    289.   ret = StartService (schService,    // service identifier
    290.       0,             // number of arguments
    291.       NULL           // pointer to arguments
    292.       );
    293.   if (ret)
    294.   {
    295.     printf ("StartService SUCCESS\n");
    296.   }
    297.   else
    298.   {
    299.     err = GetLastError();
    300.  
    301.     if (err == ERROR_SERVICE_ALREADY_RUNNING)
    302.     {
    303.       //
    304.       // A common cause of failure (easier to read than an error code)
    305.       //
    306.  
    307.       printf ("failure: StartService, ERROR_SERVICE_ALREADY_RUNNING\n");
    308.     }
    309.     else
    310.     {
    311.       printf ("failure: StartService (0x%02x)\n",
    312.           err
    313.           );
    314.     }
    315.   }
    316.  
    317.   CloseServiceHandle (schService);
    318.  
    319.   return ret;
    320. }
    321.  
    322.  
    323.  
    324. BOOL
    325. StopDriver(
    326.     IN SC_HANDLE  SchSCManager,
    327.     IN LPCTSTR    DriverName
    328.     )
    329. {
    330.   SC_HANDLE       schService;
    331.   BOOL            ret;
    332.   SERVICE_STATUS  serviceStatus;
    333.  
    334.   schService = OpenService (SchSCManager,
    335.       DriverName,
    336.       SERVICE_ALL_ACCESS
    337.       );
    338.  
    339.   if (schService == NULL)
    340.   {
    341.     printf ("failure: OpenService (0x%02x)\n", GetLastError());
    342.     return FALSE;
    343.   }
    344.  
    345.   ret = ControlService (schService,
    346.       SERVICE_CONTROL_STOP,
    347.       &serviceStatus
    348.       );
    349.   if (ret)
    350.   {
    351.     printf ("ControlService SUCCESS\n");
    352.   }
    353.   else
    354.   {
    355.     printf ("failure: ControlService (0x%02x)\n",
    356.         GetLastError()
    357.         );
    358.   }
    359.  
    360.   CloseServiceHandle (schService);
    361.  
    362.   return ret;
    363. }
    364.  
    365.  
    366.  
    367. BOOL
    368. OpenDevice(
    369.     IN LPCTSTR    DriverName
    370.     )
    371. {
    372.   char     completeDeviceName[64] = "";
    373.   LPCTSTR  dosDeviceName = DriverName;
    374.   HANDLE   hDevice;
    375.   BOOL     ret;
    376.  
    377.  
    378.  
    379.   //
    380.   // Create a \\.\XXX device name that CreateFile can use
    381.   //
    382.   // NOTE: We're making an assumption here that the driver
    383.   //       has created a symbolic link using it's own name
    384.   //       (i.e. if the driver has the name "XXX" we assume
    385.   //       that it used IoCreateSymbolicLink to create a
    386.   //       symbolic link "\DosDevices\XXX". Usually, there
    387.   //       is this understanding between related apps/drivers.
    388.   //
    389.   //       An application might also peruse the DEVICEMAP
    390.   //       section of the registry, or use the QueryDosDevice
    391.   //       API to enumerate the existing symbolic links in the
    392.   //       system.
    393.   //
    394.  
    395.   strcat (completeDeviceName,
    396.       "\\\\.\\"
    397.       );
    398.  
    399.   strcat (completeDeviceName,
    400.       dosDeviceName
    401.       );
    402.  
    403.   hDevice = CreateFile (completeDeviceName,
    404.       GENERIC_READ | GENERIC_WRITE,
    405.       0,
    406.       NULL,
    407.       OPEN_EXISTING,
    408.       FILE_ATTRIBUTE_NORMAL,
    409.       NULL
    410.       );
    411.  
    412.   if (hDevice == ((HANDLE)-1))
    413.   {
    414.     printf ("Can't get a handle to %s\n",
    415.         completeDeviceName
    416.         );
    417.  
    418.     ret = FALSE;
    419.   }
    420.   else
    421.   {
    422.     printf ("CreateFile SUCCESS\n");
    423.  
    424.     CloseHandle (hDevice);
    425.  
    426.     ret = TRUE;
    427.   }
    428.  
    429.   return ret;
    430. }
    Далее вот код самого драйвера:
    Код (Text):
    1. #include <ntddk.h>
    2.  
    3. typedef struct _DEVICE_EXTENSION
    4. {
    5.     PDEVICE_OBJECT pdo;
    6.     UNICODE_STRING ustrSymLinkName;
    7. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    8.  
    9. VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
    10. {
    11.     PDEVICE_OBJECT pNextDevObj;
    12.     int i;
    13.     DbgPrint("OnUnload");
    14.     pNextDevObj = pDriverObject->DeviceObject;
    15.     for(i=0; pNextDevObj!=NULL; i++)
    16.     {
    17.         PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    18.         UNICODE_STRING *pLinkName = &(dx->ustrSymLinkName);
    19.         pNextDevObj = pNextDevObj->NextDevice;
    20.         DbgPrint("OnUnload Deleting device (%d): pointer to PDO = %X.", i, dx->pdo);
    21.         DbgPrint("OnUnload Deleting symlink = %ws.", pLinkName->Buffer);
    22.         IoDeleteSymbolicLink(pLinkName);
    23.         IoDeleteDevice(dx->pdo);
    24.     }
    25. }
    26.  
    27.  
    28. NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    29. {
    30.     NTSTATUS status = STATUS_SUCCESS;
    31.     PDEVICE_OBJECT  pdo;
    32.     UNICODE_STRING  devName;
    33.     UNICODE_STRING  symLinkName;
    34.     PDEVICE_EXTENSION   dx;
    35.     DbgPrint("Entering DriverEntry");
    36.     DbgPrint("RegistryPath = %ws.", pRegistryPath->Buffer);
    37.     RtlInitUnicodeString(&devName, L"\\Device\\MyDevice");
    38.     RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\MyDevice");
    39.     pDriverObject->DriverUnload = OnUnload;
    40.     status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pdo);
    41.     if(!NT_SUCCESS(status))
    42.     {
    43.         DbgPrint("DriverEntry IoCreateDevice error!");
    44.         return status;
    45.     }
    46.     dx = (PDEVICE_EXTENSION)pdo->DeviceExtension;
    47.     dx->pdo = pdo;
    48.     dx->ustrSymLinkName = symLinkName;
    49.     status = IoCreateSymbolicLink(&symLinkName, &devName);
    50.     if(!NT_SUCCESS(status))
    51.     {
    52.         IoDeleteDevice(pdo);
    53.         return status;
    54.     }
    55.     DbgPrint("DriverEntry successfully completed.");
    56.     return status;
    57. }
    Всё компилируется нормально, но когда я пытаюсь запустить драйвер:
    Код (Text):
    1. C:\CPP\objchk_wxp_x86\i386>starter MyDevice MyDevice.sys
    2. CreateService SUCCESS
    3. failure: StartService (0x02)
    4. Can't get a handle to \\.\MyDevice
    Пример набирал с книги, а исходник утилиты скачал с сети.. Подскажите, пожалуйста, где ошибка и почему не стартует сервис?

    зы
    и еще в DebugView вобще - пусто :dntknw: Хотя должны были сообщения DbgPrint показываться...
     
  2. IceCrashLdr

    IceCrashLdr New Member

    Публикаций:
    0
    Регистрация:
    29 июн 2010
    Сообщения:
    193
    ОСь какая?
    Запусти под vmware с WinDbg и поставь __asm int 3 в DriverEntry(), если поймаеш значит драйвер грузится а DbgView не работает(Может просто не включен kernel capture, или прав не хватило).
     
  3. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    DebugView -> Capture -> Capture Kernel стоит?

    У меня все выводится.


    Ай, не увидел что IceCrashLdr уже подсказал на счет Capture Kernel :dntknw:


    DebugView выводит

    Код (Text):
    1. Entering DriverEntry
    2. RegistryPath = \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Driver.
    3. DriverEntry successfully completed.
     
  4. alexey_k

    alexey_k New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2006
    Сообщения:
    24
    :dntknw:
    оказывается дело не в драйвере самом, а в установщике. Скачал InstDrv с rootkit.com. Отлично запускается и устанавливается мой драйвер. DBGView тоже пишет :)

    JCronuz
    а вы компилировали мой пример установщика? или свой у вас?
    может быть нужно студию более новую?

    у меня:
    Windows XP SP3
    VisualStudio 6 SP6
     
  5. IceCrashLdr

    IceCrashLdr New Member

    Публикаций:
    0
    Регистрация:
    29 июн 2010
    Сообщения:
    193
    Компилятор здесь не причем, все дело в логике ... :)
     
  6. alexey_k

    alexey_k New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2006
    Сообщения:
    24
    в какой логике? вы о чем?
     
  7. JCronuz

    JCronuz New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2007
    Сообщения:
    1.240
    Адрес:
    Russia
    Да KmdLoader использовал для загрузки, тоже когда-то пробовал Instdrv.c использовать, потом решил создать свой, что и вам советую, за одно и разбиретесь с SCM. KmdLoader кстати с открытым кодом.
     
  8. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    OpenDevice не работает в том лоадыре как и в Kmd. Наверно потому что нет IRP_MJ_CONTROL обработчика?
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    punxer
    Для открытия девайса нужен IRP_MJ_CREATE обработчик. А IRP_MJ_DEVICE_CONTROL для DeviceIoControl() нужен
     
  10. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Командная строка:
    C:\CPP\objchk_wxp_x86\i386>starter MyDevice MyDevice.sys

    Функции InstallDriver (schSCManager,argv[1],argv[2]) вы передаете в качестве argv[2] - MyDevice.sys, это будет параметр ServiceExe в функции CreateService, а ей нужно передать полный путь к файлу MyDevice.sys в этом параметре. Значит драйвер не загрузится.

    Что бы открыть хендл драйвера функцией OpenService ей нужно передать полное имя драйвера - с расширением, т.е. "MyDevice.sys" - а у вас функции StartDriver(schSCManager,argv[1]) передаётся аргумент argv[1] равный "MyDevice". А это значит что вы не откроете хендл драйвера который должен быть уже загружен.

    На первый взгляд кажется всё.
     
  11. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Great

    то есть для управления дровом через DeviceIoControl() нужно реализовать оба обработчега. Ведь для DeviceIoControl() нужен хэндл CreateFile()? так? Обработчик IOCTL я представляю, есть ли что то что обязательно делать в IRP_MJ_CREATE ?
     
  12. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    Да, для CreateFile() нужно в обработчике IRP_MJ_CREATE и не только, просто вернуть Irp->IoStatus.Status = STATUS_SUCCESS;

    К стати я тоже сегодня сделал свой первый драйвер, у меня это так реализовано:
    Код из DriverEntry -
    Код (Text):
    1. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
    2.         DriverObject->MajorFunction[i] = DriverDefaultHandler;
    3.  
    4.     //===========
    5.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
    6.     DriverObject->DriverUnload = DriverUnload;
    7.  
    8.         pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    9.  
    10.     return STATUS_SUCCESS;
    А вот обработчик IRP_MJ_CREATE:

    Код (Text):
    1. NTSTATUS DriverDefaultHandler(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)
    2. {
    3.     PIO_STACK_LOCATION pSL = IoGetCurrentIrpStackLocation (Irp) ;
    4.    
    5.     switch (pSL->MajorFunction)
    6.     {
    7.         case IRP_MJ_CREATE :
    8.         case IRP_MJ_CLOSE :
    9.         case IRP_MJ_CLEANUP :
    10.             {
    11.                 Irp->IoStatus.Status = STATUS_SUCCESS;
    12.                 break;
    13.             }
    14.         default:
    15.                 { Irp->IoStatus.Status = STATUS_NOT_SUPPORTED ; }
    16.     }
    17.  
    18.     Irp->IoStatus.Information = 0;
    19.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    20.     return Irp->IoStatus.Status;
    21. }
     
  13. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    Charlief
    Небольшое замечание: лучше заменить STATUS_NOT_SUPPORTED на STATUS_INVALID_DEVICE_REQUEST
     
  14. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. #define _X86_
    2.  
    3. #include <ntddk.h>
    4.  
    5.  
    6.  
    7. typedef struct _DEVICE_EXTENSION
    8. {
    9.     PDEVICE_OBJECT pdo;
    10.     UNICODE_STRING ustrSymLinkName;
    11. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    12.  
    13. NTSTATUS
    14. MJ_DispatchIoctl(
    15.     IN  PDEVICE_OBJECT  DeviceObject,
    16.     IN  PIRP            Irp
    17.     )
    18.  
    19. {
    20.     PIO_STACK_LOCATION      irpStack;
    21.     NTSTATUS                status= STATUS_SUCCESS;
    22.  
    23.     irpStack = IoGetCurrentIrpStackLocation (Irp);
    24.     switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
    25.     {
    26.     case 1:
    27.         DbgPrint("IOCTL CODE PASSED");
    28.         break;
    29.     default:
    30.         break;
    31.    
    32.     };
    33.     Irp->IoStatus.Status = status;
    34.     IoCompleteRequest (Irp, IO_NO_INCREMENT);
    35.  
    36.     return status;
    37. }
    38. NTSTATUS
    39. MJ_Create (
    40.     IN PDEVICE_OBJECT DeviceObject,
    41.     IN PIRP Irp
    42.     )
    43.  
    44.  
    45. {  
    46.     NTSTATUS                status = STATUS_SUCCESS;
    47.     PIO_STACK_LOCATION      irpStack;
    48.  
    49.     irpStack = IoGetCurrentIrpStackLocation (Irp);
    50.    
    51.  
    52.  
    53.     Irp->IoStatus.Information = 0; // fill in the correct length
    54.     Irp->IoStatus.Status = status;
    55.     IoCompleteRequest (Irp, IO_NO_INCREMENT);
    56.     return status;
    57.  
    58.  
    59.  
    60. }
    61. NTSTATUS DriverDefaultHandler(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)
    62. {
    63.     PIO_STACK_LOCATION pSL = IoGetCurrentIrpStackLocation (Irp) ;
    64.    
    65.     switch (pSL->MajorFunction)
    66.     {
    67.         case IRP_MJ_CREATE :
    68.         case IRP_MJ_CLOSE :
    69.         case IRP_MJ_CLEANUP :
    70.             {
    71.                 Irp->IoStatus.Status = STATUS_SUCCESS;
    72.                 break;
    73.             }
    74.         default:
    75.             Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST ;
    76.     }
    77.  
    78.     Irp->IoStatus.Information = 0;
    79.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    80.     return Irp->IoStatus.Status;
    81. }
    82.  
    83. VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
    84. {
    85.     PDEVICE_OBJECT pNextDevObj;
    86.     int i;
    87.     DbgPrint("OnUnload");
    88.     pNextDevObj = pDriverObject->DeviceObject;
    89.     for(i=0; pNextDevObj!=NULL; i++)
    90.     {
    91.         PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    92.         UNICODE_STRING *pLinkName = &(dx->ustrSymLinkName);
    93.         pNextDevObj = pNextDevObj->NextDevice;
    94.  
    95.         IoDeleteSymbolicLink(pLinkName);
    96.         IoDeleteDevice(dx->pdo);
    97.     }
    98. }
    99.  
    100.  
    101. NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    102. {
    103.     NTSTATUS status = STATUS_SUCCESS;
    104.     PDEVICE_OBJECT    pdo;
    105.     UNICODE_STRING    devName;
    106.     UNICODE_STRING    symLinkName;
    107.     PDEVICE_EXTENSION    dx;
    108.     int i;
    109.     RtlInitUnicodeString(&devName, L"\\Device\\MyDevice");
    110.     RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\MyDevice");
    111.     pDriverObject->DriverUnload = OnUnload;
    112.    
    113.     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
    114.         pDriverObject->MajorFunction[i] = DriverDefaultHandler;
    115.  
    116.     pDriverObject->Flags &= ~DO_DEVICE_INITIALIZING;
    117.     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MJ_DispatchIoctl;
    118.    
    119.    
    120.     status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pdo);
    121.     if(!NT_SUCCESS(status))
    122.     {
    123.         DbgPrint("DriverEntry IoCreateDevice error!");
    124.         return status;
    125.     }
    126.     dx = (PDEVICE_EXTENSION)pdo->DeviceExtension;
    127.     dx->pdo = pdo;
    128.     dx->ustrSymLinkName = symLinkName;
    129.     status = IoCreateSymbolicLink(&symLinkName, &devName);
    130.     if(!NT_SUCCESS(status))
    131.     {
    132.         IoDeleteDevice(pdo);
    133.         return status;
    134.     }
    135.     DbgPrint("DriverEntry successfully completed.");
    136.     return status;
    137. }
    Вот и я накатал)
    нашел пример тостера
    Вопрос: почему KmdManger не может послать IOCTL_CODE? Наверное потому что не знает имя девайса созданного драйвером, но тогда зачем это реализовано в нем. Решение: писатьсвой загрузчик свой можно взять исходник но открывать именно мой девайс и уже после CreateFile вызывать DeviceIoControl?
    может для KmdManger имя файла драйвера должно быть идентично имени устройства?
    Да, именно так и есть.
     
  15. Charlief

    Charlief New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    129
    punxer
    И что, работает ?

    irpStack->Parameters.DeviceIoControl.IoControlCode врядли будет равным 1. Его можно сформировать в программе вызывающей DeviceIoControl() с помощью макроса:
    Код (Text):
    1. #define CTL_CODE( DeviceType, Function, Method, Access ) (                 \
    2.     ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
    А в дрйвере можно извлечь поле Function и вызвать соотвествующий обработчик.

    Флаг pDriverObject->Flags &= ~DO_DEVICE_INITIALIZING; сбрасывается только после полной инициализации объекта устройства см. http://www.microsoft.com/whdc/driver/tips/devinit.mspx , а в драйвере WDM в функции AddDevice.

    А зачем нужна функция MJ_Create которая нигде не используется ?
     
  16. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Charlief работает
    я просто ради примера передаю 1 через KmdMan, про макрос знаю/
    забыл убрать
    думал сделать ввод/вывод через Write/ReadFile, но потом понял что обойдусь IOCTL
    да и макрос мне незачем, мне нужно просто эмулировать клаву через порты некоторые кнопки их немного
    так что нужны просто разные коды для разных клавиш передавать
    понял спасибо