ERROR_ACCESS_DENIED и Com port

Тема в разделе "WASM.NT.KERNEL", создана пользователем rttgedt, 6 авг 2011.

  1. rttgedt

    rttgedt Антон

    Публикаций:
    0
    Регистрация:
    12 окт 2010
    Сообщения:
    85
    Пытаюсь написать фильтр для ком порта, присоеденился к стеку, пытаюсь перехватывать IRP. При изменении режима питания - все нормально, IRP монторятся, но когда пытаюсь открыть ком-порт, CreateFile возвращает ERROR_ACCESS_DENIED. Подскажите, пожалуйста, как мне пристроится в стек ком-порта не в "монопольном" режиме?

    Вот исходник фильтра:
    Код (Text):
    1. #include "ComFltr.h"
    2.  
    3. #pragma PAGEDCODE
    4. NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING UnicodeString)
    5. {
    6.     NTSTATUS Status = STATUS_SUCCESS;
    7.     PDEVICE_EXTENSION pdx;
    8.     PDEVICE_OBJECT FiDO;
    9.     PDEVICE_OBJECT fdo;
    10.     PDEVICE_OBJECT LowObject;
    11.     PFILE_OBJECT fLowObject;
    12.     UNICODE_STRING sLowObject;
    13.     int i;
    14. #ifdef DBG
    15.     DbgPrint(DRIVERNAME ": Enter to DriverEntry, DriverObject: %x; UnicodeString: %ws \n", DriverObject, UnicodeString);
    16. #endif
    17.  
    18.     for (i = 0; i < ARRAYSIZE(DriverObject->MajorFunction); ++i)
    19.         DriverObject->MajorFunction[i] = DispatchAny;
    20.    
    21.     DriverObject->DriverUnload = DriverUnload;
    22.     DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
    23.     DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
    24.  
    25.     Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_PARALLEL_PORT, 0, FALSE, &FiDO);
    26.  
    27.     if (!NT_SUCCESS(Status))
    28.     {
    29.         DbgPrint(DRIVERNAME ": IoCreateDevice failed with status %x\n", Status);
    30.         return Status;
    31.     }
    32.     RtlInitUnicodeString(&sLowObject, L"\\Device\\Serial1");
    33.     Status = IoGetDeviceObjectPointer(&sLowObject, FILE_ALL_ACCESS, &fLowObject, &LowObject);
    34.  
    35.     if (!NT_SUCCESS(Status))
    36.     {
    37.         DbgPrint(DRIVERNAME ": IoGetDeviceObjectPointer failed with status %x\n", Status);
    38.         return Status;
    39.     }
    40.  
    41.     pdx = (PDEVICE_EXTENSION) FiDO->DeviceExtension;
    42.     do
    43.     {
    44.         IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
    45.         pdx->DeviceObject = FiDO;
    46.         pdx->PDO = LowObject;
    47.  
    48.         fdo = IoAttachDeviceToDeviceStack(FiDO, LowObject);
    49.         if (!fdo)
    50.         {
    51.             DbgPrint(DRIVERNAME ": IoAttachDeviceToDeviceStack failed \n");
    52.             Status = STATUS_DEVICE_REMOVED;
    53.             break;
    54.         }
    55.         pdx->LowerDeviceObject = fdo;
    56.        
    57.         FiDO->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
    58.         FiDO->Flags &= ~DO_DEVICE_INITIALIZING;
    59.     }while(FALSE);
    60.  
    61.     if (!NT_SUCCESS(Status))
    62.     {
    63.         if (pdx->LowerDeviceObject)
    64.             IoDetachDevice(pdx->LowerDeviceObject);
    65.         IoDeleteDevice(FiDO);
    66.     }
    67.  
    68. #ifdef DBG
    69.     DbgPrint(DRIVERNAME ": DriverEntry completed with status %x\n", Status);
    70. #endif
    71.     return Status;
    72. }
    73.  
    74. void DriverUnload(PDRIVER_OBJECT FiDO)
    75. {
    76.     PDEVICE_EXTENSION pdx = FiDO->DriverExtension;
    77. #ifdef DBG
    78.     DbgPrint(DRIVERNAME ": Entering to DriverUnload with FiDO %x", FiDO);
    79. #endif
    80.     ObDereferenceObject(pdx->LowerDeviceObject);
    81. }
    82.  
    83. #pragma LOCKEDCODE
    84. NTSTATUS CompleteRequest(PIRP Irp, NTSTATUS Status, ULONG_PTR Info)
    85. {
    86.     Irp->IoStatus.Status = Status;
    87.     Irp->IoStatus.Information = Info;
    88.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    89.     return Status;
    90. }
    91.  
    92. #pragma LOCKEDCODE
    93. NTSTATUS DispatchAny(PDEVICE_OBJECT FiDO, PIRP Irp)
    94. {
    95.     PDEVICE_EXTENSION pdx = FiDO->DeviceExtension;
    96.     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    97.     NTSTATUS Status;
    98.  
    99. #if DBG
    100.     static char* irpname[] = {
    101.         "IRP_MJ_CREATE",
    102.         "IRP_MJ_CREATE_NAMED_PIPE",
    103.         "IRP_MJ_CLOSE",
    104.         "IRP_MJ_READ",
    105.         "IRP_MJ_WRITE",
    106.         "IRP_MJ_QUERY_INFORMATION",
    107.         "IRP_MJ_SET_INFORMATION",
    108.         "IRP_MJ_QUERY_EA",
    109.         "IRP_MJ_SET_EA",
    110.         "IRP_MJ_FLUSH_BUFFERS",
    111.         "IRP_MJ_QUERY_VOLUME_INFORMATION",
    112.         "IRP_MJ_SET_VOLUME_INFORMATION",
    113.         "IRP_MJ_DIRECTORY_CONTROL",
    114.         "IRP_MJ_FILE_SYSTEM_CONTROL",
    115.         "IRP_MJ_DEVICE_CONTROL",
    116.         "IRP_MJ_INTERNAL_DEVICE_CONTROL",
    117.         "IRP_MJ_SHUTDOWN",
    118.         "IRP_MJ_LOCK_CONTROL",
    119.         "IRP_MJ_CLEANUP",
    120.         "IRP_MJ_CREATE_MAILSLOT",
    121.         "IRP_MJ_QUERY_SECURITY",
    122.         "IRP_MJ_SET_SECURITY",
    123.         "IRP_MJ_POWER",
    124.         "IRP_MJ_SYSTEM_CONTROL",
    125.         "IRP_MJ_DEVICE_CHANGE",
    126.         "IRP_MJ_QUERY_QUOTA",
    127.         "IRP_MJ_SET_QUOTA",
    128.         "IRP_MJ_PNP",
    129.         };
    130.     UCHAR Type = stack->MajorFunction;
    131.     DbgPrint(DRIVERNAME ": Entering to DispatchAny (FiDO = %x; Irp = %x)\n", FiDO, Irp);
    132.  
    133.     if (Type >= ARRAYSIZE(irpname))
    134.         DbgPrint(DRIVERNAME ": Unknown IRP major type %x\n", Type);
    135.     else
    136.         DbgPrint(DRIVERNAME ": - %s name\n", irpname[Type]);
    137. #endif
    138.  
    139.     Status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
    140.     if (!NT_SUCCESS(Status))
    141.         return CompleteRequest(Irp, Status, 0);
    142.  
    143.     IoSkipCurrentIrpStackLocation(Irp);
    144.     Status = IoCallDriver(pdx->LowerDeviceObject, Irp);
    145.     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    146. #ifdef DBG
    147.     DbgPrint(DRIVERNAME ": DispatchAny completed with Status %x\n", Status);
    148. #endif
    149.  
    150.     return Status;
    151. }
    152.  
    153. NTSTATUS DispatchPower(PDEVICE_OBJECT FiDO, PIRP Irp)
    154. {
    155.     NTSTATUS Status;
    156.     PDEVICE_EXTENSION pdx;
    157. #ifdef DBG
    158.     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    159.     ULONG fcn = stack->MinorFunction;
    160.  
    161.     static char* fcnname[] = {
    162.         "IRP_MN_WAIT_WAKE",
    163.         "IRP_MN_POWER_SEQUENCE",
    164.         "IRP_MN_SET_POWER",
    165.         "IRP_MN_QUERY_POWER",
    166.         };
    167.     DbgPrint(DRIVERNAME ": Entering to DispatchPower (FiDO = %x; Irp = %x)\n", FiDO, Irp);
    168.     if (fcn == IRP_MN_SET_POWER || fcn == IRP_MN_QUERY_POWER)
    169.     {
    170.         static char* sysstate[] = {
    171.             "PowerSystemUnspecified",
    172.             "PowerSystemWorking",
    173.             "PowerSystemSleeping1",
    174.             "PowerSystemSleeping2",
    175.             "PowerSystemSleeping3",
    176.             "PowerSystemHibernate",
    177.             "PowerSystemShutdown",
    178.             "PowerSystemMaximum",
    179.             };
    180.  
    181.         static char* devstate[] = {
    182.             "PowerDeviceUnspecified",
    183.             "PowerDeviceD0",
    184.             "PowerDeviceD1",
    185.             "PowerDeviceD2",
    186.             "PowerDeviceD3",
    187.             "PowerDeviceMaximum",
    188.             };
    189.         ULONG Context = stack->Parameters.Power.SystemContext;
    190.         POWER_STATE_TYPE Type = stack->Parameters.Power.Type;
    191.        
    192.         DbgPrint(DRIVERNAME ": IRP_MJ_POWER (%s)\n", fcnname[fcn]);
    193.         if (Type == SystemPowerState)
    194.             DbgPrint(DRIVERNAME ": SystemPowerState = %s\n", sysstate[stack->Parameters.Power.State.SystemState]);
    195.         else DbgPrint(DRIVERNAME ": DevicePowerState = %s\n", devstate[stack->Parameters.Power.State.DeviceState]);
    196.     }
    197.     else if (fcn < ARRAYSIZE(fcnname))
    198.         DbgPrint(DRIVERNAME ": IRP_MJ_POWER (%s)\n", fcnname[fcn]);
    199.     else DbgPrint(DRIVERNAME ": IRP_MJ_POWER (%x)\n", fcn);
    200. #endif
    201.  
    202.     pdx = (PDEVICE_EXTENSION) FiDO->DeviceExtension;
    203.     PoStartNextPowerIrp(Irp);
    204.     Status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
    205.     if (!NT_SUCCESS(Status))
    206.         return CompleteRequest(Irp, Status, 0);
    207.     IoSkipCurrentIrpStackLocation(Irp);
    208.     Status = PoCallDriver(pdx->LowerDeviceObject, Irp);
    209.     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    210.  
    211. #ifdef DBG
    212.     DbgPrint(DRIVERNAME ": DispatchPower completed with status %x\n", Status);
    213. #endif
    214.  
    215.     return Status;
    216. }
    217.  
    218. NTSTATUS DispatchPnp(PDEVICE_OBJECT FiDO, PIRP Irp)
    219. {
    220.     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    221.     ULONG fcn = stack->MinorFunction;
    222.     NTSTATUS Status;
    223.     PDEVICE_EXTENSION pdx = FiDO->DeviceExtension;
    224.  
    225. #ifdef DBG
    226.     static char* pnpname[] = {
    227.         "IRP_MN_START_DEVICE",
    228.         "IRP_MN_QUERY_REMOVE_DEVICE",
    229.         "IRP_MN_REMOVE_DEVICE",
    230.         "IRP_MN_CANCEL_REMOVE_DEVICE",
    231.         "IRP_MN_STOP_DEVICE",
    232.         "IRP_MN_QUERY_STOP_DEVICE",
    233.         "IRP_MN_CANCEL_STOP_DEVICE",
    234.         "IRP_MN_QUERY_DEVICE_RELATIONS",
    235.         "IRP_MN_QUERY_INTERFACE",
    236.         "IRP_MN_QUERY_CAPABILITIES",
    237.         "IRP_MN_QUERY_RESOURCES",
    238.         "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
    239.         "IRP_MN_QUERY_DEVICE_TEXT",
    240.         "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
    241.         "",
    242.         "IRP_MN_READ_CONFIG",
    243.         "IRP_MN_WRITE_CONFIG",
    244.         "IRP_MN_EJECT",
    245.         "IRP_MN_SET_LOCK",
    246.         "IRP_MN_QUERY_ID",
    247.         "IRP_MN_QUERY_PNP_DEVICE_STATE",
    248.         "IRP_MN_QUERY_BUS_INFORMATION",
    249.         "IRP_MN_DEVICE_USAGE_NOTIFICATION",
    250.         "IRP_MN_SURPRISE_REMOVAL",
    251.         "IRP_MN_QUERY_LEGACY_BUS_INFORMATION",
    252.         };
    253.     if (fcn < ARRAYSIZE(pnpname))
    254.         DbgPrint(DRIVERNAME ": IRP_MJ_PNP (%s)\n", pnpname[fcn]);
    255.     else DbgPrint(DRIVERNAME ": IRP_MJ_PNP (%x)\n", fcn);
    256. #endif
    257.  
    258. #ifdef DBG
    259.     DbgPrint(DRIVERNAME ": Entering to DispatchPnp (FiDO = %x; Irp = %x)\n", FiDO, Irp);
    260. #endif
    261.  
    262.     Status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
    263.     if (!NT_SUCCESS(Status))
    264.         return CompleteRequest(Irp, Status, 0);
    265.  
    266.     if (fcn == IRP_MN_DEVICE_USAGE_NOTIFICATION)
    267.     {
    268.         if (!FiDO->AttachedDevice || (FiDO->AttachedDevice->Flags & DO_POWER_PAGABLE))
    269.             FiDO->Flags |= DO_POWER_PAGABLE;
    270.         IoCopyCurrentIrpStackLocationToNext(Irp);
    271.         IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) UsageNotificationCompletionRoutine,
    272.                                 (PVOID) pdx, TRUE, TRUE, TRUE);
    273.         return IoCallDriver(pdx->LowerDeviceObject, Irp);
    274.     }
    275.     if (fcn == IRP_MN_START_DEVICE)
    276.     {
    277.         IoCopyCurrentIrpStackLocationToNext(Irp);
    278.         IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) StartDeviceCompletionRoutine,
    279.                                 (PVOID) pdx, TRUE, TRUE, TRUE);
    280.         return IoCallDriver(pdx->LowerDeviceObject, Irp);
    281.     }
    282.     if (fcn == IRP_MN_REMOVE_DEVICE)
    283.     {
    284.         IoSkipCurrentIrpStackLocation(Irp);
    285.         Status = IoCallDriver(pdx->LowerDeviceObject, Irp);
    286.         IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
    287.         RemoveDevice(FiDO);
    288.         return Status;
    289.     }
    290.     IoSkipCurrentIrpStackLocation(Irp);
    291.     Status = IoCallDriver(pdx->LowerDeviceObject, Irp);
    292.     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    293.     return Status;
    294. }
    295.  
    296. #pragma PAGEDCODE
    297. VOID RemoveDevice(PDEVICE_OBJECT FiDO)
    298. {
    299.     PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) FiDO->DeviceExtension;
    300.     NTSTATUS Status;
    301.  
    302.     if (pdx->LowerDeviceObject)
    303.         IoDetachDevice(pdx->LowerDeviceObject);
    304.     IoDeleteDevice(FiDO);
    305. }
    306.  
    307. #pragma LOCKEDCODE
    308. NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT FiDO, PIRP Irp, PDEVICE_EXTENSION pdx)
    309. {
    310.     if (Irp->PendingReturned)
    311.         IoMarkIrpPending(Irp);
    312.     if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
    313.         FiDO->Characteristics |= FILE_REMOVABLE_MEDIA;
    314.     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    315.     return STATUS_SUCCESS;
    316. }
    317.  
    318. #pragma LOCKEDCODE
    319. NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT FiDO, PIRP Irp, PDEVICE_EXTENSION pdx)
    320. {
    321.     if (Irp->PendingReturned)
    322.         IoMarkIrpPending(Irp);
    323.     if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
    324.         FiDO->Flags &= ~DO_POWER_PAGABLE;
    325.     IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
    326.     return STATUS_SUCCESS;
    327. }
    328. #pragma LOCKEDCODE
     
  2. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    rttgedt
    Вероятно, не те параметры передаёте в CreateFile.
     
  3. rttgedt

    rttgedt Антон

    Публикаций:
    0
    Регистрация:
    12 окт 2010
    Сообщения:
    85
    Без фильтра все передается нормально, тестирую вот таким простеньким кодом:
    Код (Text):
    1. #include <windows.h>
    2. #include <stdio.h>
    3.  
    4. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    5. {
    6.     CHAR *Buf = "1234";
    7.     DWORD Written;
    8.     HANDLE hFile = CreateFileW(L"\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, 0, NULL);
    9.     if (hFile == INVALID_HANDLE_VALUE)
    10.     {
    11.         int Err = GetLastError();
    12.         CHAR buf[100];
    13.         sprintf(buf, "CreateFileW failed with error: %d", Err);
    14.         MessageBoxA(0, buf, "Error", MB_OK|MB_ICONERROR);
    15.         return 0;
    16.     }
    17.     if (!WriteFile(hFile, Buf, 5, &Written, NULL))
    18.     {
    19.         int Err = GetLastError();
    20.         CHAR buf[100];
    21.         sprintf(buf, "WriteFile failed with error: %d", Err);
    22.         MessageBoxA(0, buf, "Error", MB_OK|MB_ICONERROR);
    23.     }
    24.     return 0;
    25. }
     
  4. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    rttgedt
    В драйверах я не силён, точнее говоря не имею о них никакого представления. Но, поскольку других предположений нет, попробую угадать. Возможно Вы в драйвере открываете порт с эксклюзивным доступом и не закрываете, соответственно никто другой его уже открыть не может.
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    rttgedt
    А если поставить точку останова на IRP_MJ_CREATE, что происходит? Приходит ли управление, что возвращает низлежащее устройство?
     
  6. rttgedt

    rttgedt Антон

    Публикаций:
    0
    Регистрация:
    12 окт 2010
    Сообщения:
    85
    Я цепляюсь в вершину стека, когда система уже загружена, а открыть порт после этого уже не могу. Поэтому IRP_MJ_CREATE не приходит вообще.
     
  7. rttgedt

    rttgedt Антон

    Публикаций:
    0
    Регистрация:
    12 окт 2010
    Сообщения:
    85
    Разобрался! )))
    После получения указателя на низлежащее устройство через IoGetDeviceObjectPointer, нужно обязательно отдереференсить файловый объект, как показано в ДДК:
    Код (Text):
    1. RtlInitUnicodeString(&nameString, L"\\Device\\RawDisk");
    2. status = IoGetDeviceObjectPointer(
    3.             &nameString,                    //ObjectName
    4.             FILE_READ_ATTRIBUTES,           //DesiredAccess
    5.             &fileObject,                    //FileObject
    6.             &rawDeviceObject);              //DeviceObject
    7. if (NT_SUCCESS(status)) {
    8.             ObDereferenceObject(fileObject);
    9. }
    Всем большое спасибо за участие!