Здраствуйте! Вопрос: Как создать в системе новый COM-порт? COM-порт должен создаваться из драйвера. Т.е. задача заключается в создании драйвера устройства, который создает COM-порт в своей процедуре DriverEntry. Если пользовательское устройство записывает данные по этому порту, то в зависимости от этих данных что-то происходит. Т.е. драйвер работает от сообщений поступаемых на COM-порт. Например, посылаем команду KILL на этот COM-порт, а дровина убивает например какое-нибудь приложение. --------------------------------------------------------- По моим предположениям это будет драйвер фильтр для serial.sys драйвера. Но как это сделать или может концепция совсем другая. --------------------------------------------------------- Вопрос для Four-F, т.к. он специалист по драйверам. Но если ктонибудь знает ответ на этот вопрос помогите пожалуйста.
Bill_TPOC, о каком порте речь идёт? Может быть ты имел в виду виртуальное устройство? Если пользовательское устройство записывает данные по этому порту если и меются в виду порты ввода-вывода(in/out) то писать в них так просто из r-3 нельзя. Создать порт ввода-вывода(не виртуальный) можно разве-что паяльником... Может опишешь ситуацию по конкретней?
Bill_TPOC чёт я не понял Идешь в ддк, берешь готовый исходник драйвера, меняешь начинку и наслаждаешься... чего тут сложного, кроме того примеров на сайте было насколько я помню и ответов до 屁股 .....
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS st; PCWSTR dDeviceName = L"\\Device\\VirtualCom"; PCWSTR dSymbolicLinkName = L"\\DosDevices\\COM3"; PDRIVER_DISPATCH *ppdd; RtlInitUnicodeString(&DeviceName, dDeviceName); RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName); st = IoCreateDevice(DriverObject, // указатель на DriverObject 256, // максимальный размер принимаемых данных &DeviceName, // имя создаваемого устройства FILE_DEVICE_NULL,// тип создаваемого устройства METHOD_NEITHER, // метод буфферизации FALSE, // "эксклюзивное" устройство &deviceObject); // указатель на обьект устройства if (st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки &DeviceName); // имя устройства ppdd = DriverObject->MajorFunction; // обьявляю процедуры обработки ввода-вывода ppdd [IRP_MJ_CREATE] = ppdd [IRP_MJ_WRITE ] = DriverDispatcher; DriverObject->DriverUnload = DriverUnload; return st; }
Короче, надо создать устройство, и ассоциировать с ним символическую ссылку COM3, назначить процедуры обработки IRP и будет работать. Ну а чтоб в перечислении портов был еще и виртуальный порт, надо его в системе зарегистрировать (вроде в ддк на эту тему были примеры).
создание символик линка - это еще не всё... данные о порте надо прописать в реджистри HKLM\Hardware\DEVICEMAP\SERIALCOMM вот код ф-ии, создающей виртуальный сериальный порт: Код (Text): ULONG Card_CreateSerialPort(PDEVICE_OBJECT fdo) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ComNameStr, ComNameStr1, ComNumStr; OBJECT_ATTRIBUTES objectAttributes; HANDLE hKeySection; DEVICE_EXTENSION *ext = (PDEVICE_EXTENSION) fdo->DeviceExtension; WCHAR wszComName[100] = L"COM"; WCHAR wszComName1[100] = L"\\\\.\\COM"; static WCHAR wszSymName[100] = L"\\DosDevices\\"; // make COM name swprintf(wszComName, L"COM%i", ext->ComXSer.Number); swprintf(wszComName1, L"\\??\\COM%i", ext->ComXSer.Number); // make symbolic name swprintf(wszSymName, L"\\DosDevices\\%s", wszComName); // Initislaize the unicode strings RtlInitUnicodeString(&ComNameStr, wszComName); RtlInitUnicodeString(&ComNameStr1, wszComName1); RtlInitUnicodeString(&ext->ComXSer.ComSymbLink, wszSymName); // Is this COM port exist? PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; status = IoGetDeviceObjectPointer(&ComNameStr1, FILE_ALL_ACCESS, &FileObject, &DeviceObject ); if (NT_SUCCESS(status)) { ObDereferenceObject(FileObject); ext->lastError = Err_CreateSerialPort; return ext->lastError; } status = IoCreateSymbolicLink(&ext->ComXSer.ComSymbLink, &g_nameString); if (!NT_SUCCESS(status)) { ext->lastError = Err_CreateSerialPort; return ext->lastError; } // write SERIALCOM\\xxx registry key status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM", g_nameString.Buffer, REG_SZ, ComNameStr.Buffer, ComNameStr.Length + sizeof(WCHAR)); if(NT_SUCCESS(status)) { ext->ComXSer.isEnabled = TRUE; } else { ext->lastError = Err_CreateSerialPort; } return ext->lastError; }
Огромное спасибо за помощь. Но вот продолжение - если я создал COM-порт, то как мне связать его с модемом. Т.е. как заставить программы типа HyperTerminal посылать команды на данный COM-порт. Например, программа посылает команду ATDT 12346789, адровина смотрит на эту команду и убивает процесс вызовом ZwTerminateProcess. С Kernel Mode второй день, так что не смейтесь.