Цитата: "А марганец при горении выделяет кислород". Афтырь, ты в каком подземном переходе аттестат покупал? В школе преподают предмет под названием - химия. Иди учи двоечник.
Стоит внимания. Есть новизна и сюжет. Есть и ляпы. Ну например трудно потерять арбалет, еще трудней не пойти его поискать, тем более, что он весьма дорогой и удобный. Я слабо представляю, что четверо охотников уходят на охоту без дистанционного оружия и лишь по надобности его берут, тем более, что есть повозка и лошади. Слабо представляю, что охотники за своей жертвой и подранками бегаю с мечами. Имея 4 арбалета и видя волколака автор
подробнее ...
рассказывает нам как его они рассматривают и как он готовится к нападению, дожидаясь атаки. Лишь ГГ успевает нажать на спуск в догон и забыв о перезарядке несётся безоружный за целью, видимо высказать своё устное фи за грубое подталкивание. Ну и как всегда охотники на монстров не имеют элементарной защиты от таких нападений - рогатины и предпочитают служить "кеглями" и летать не имея крыльев. Стандарт вооружения для таких писателей - меч, взяв авторит - ведьмака А. Сапковского. Только у него ведьмаки были уже биомутантами и обучались с детства, имели невероятную реакцию, гибкость, скорость и кучу химии от отравлений и заживление ран от ближнего контакта с чудовищами. Наши простые предки справлялись копьями,луками, собаками, ядом и ловушками. Диванные писатели пишут глупые книги и ссылаясь друг на друга. Да нормальные охотники в лес без хороших как минимум двух обученных собак держать зверя на одном месте на хищника не пойдут, иначе сами станут дичью. Я действительно умных произведений, где хоть чему то можно научиться из реального опыта давно не читал. На фоне прочих авторов оценку ставлю - хорошо и рекомендую представлять в уме более реальные ситуации и не резать монстров ножичком, а сразу колоть зубочисткой.
Очень! очень приличная "боярка"! Прочёл все семь книг "запоем". Не уступает качеством сюжета ни Демченко Антону, ни Плотников Сергею, ни Ильину Владимиру. Lena Stol - респект за "открытие" талантливого автора!!!
Написано на уровне детсада. Великий перерожденец и врун. По мановению руки сотня людей поднимается в воздух, а может и тысячи. В кучу собран казачий уклад вольных и реестровых казаков, княжества и рабы. 16 летний князь командует атаманами казачьего войска. Отпускает за откуп врагов, убивших его родителей. ГГ у меня вызывает чувство гадливости. Автор с ГГ развлекает нас текстами казачьих песен. Одновременно обвиняя казаков
подробнее ...
обворовывание своего князя. Читать о всемогущем колдуне и его глупых выходках и рассуждениях просто не интересно.
received from NdisMRegisterDevice() )
// объявление буферизации для связывающих операций
deviceObject->Flags |= DO_BUFFERED_IO;
// все.
Тела функций, типа Filter, объявите сразу после тела функции DriverEntry и оставьте пока пустыми, добавив, только возвращение значения
return NDIS_STATUS_SUCCESS;
Как писать драйвера (часть 4)
В прошлый раз мы заготовили списки необходимых функций, зарегистрировали их, а сегодня рассмотрим их поподробнее.
Группа минипорт.
Функции этой группы занимаются обработкой потока данных и событий, происходящих в верхнем уровне драйвера, и вызываемых обращением к NDIS TCP/IP стека.
Если посмотреть на схемы из второй части, то видно, что в нижней части находятся функции протокола, а в верхней минипорта. Почему? Каждый драйвер выступает в двух ипостасях. Общаясь с верхним уровнем драйверов он становиться для него драйвером минипорта, а для нижнего уровня, драйвером протокола.
Список функций минипорт:
MPInitialize – инициализация группы.
MPSendMPSendPacketsMPTransferDataMPReturnPacket
Функции отвечающие за пересылку пакетов данных.
MPQueryInformationMPSetInformationMPQueryPNPCapbilitiesMPIsSendOIDMPProcessSetPowerOid
Функции работы с питанием состоянием системы и системой PlagNPlay. Сказать особенно нечего. Стандартное отслеживание внутренних событий системы прописанное Microsoft.
MPHalt – отработка выгрузки и де регистрации драйвера при аварийном.
MPReset – как написано у Microsoft – мы не должны ничего делать :)
Работа с системой – необходимость отрабатывать события важные для сервиса корректно.
MPSetMiniportSecondaryMPPromoteSecondaryMPBundleSearchAndSetSecondary
В системе может быть не один адаптер и соответственно не один драйвер к которому приходится обращаться. В случае такого используются эти функции.
В нашем случае основными функциями из этой группы – являются функции пересылки данных. Все остальные мы можем не рассматривать, их назначение – обслуживать правильно системные связи, вся основная часть которых написана Microsoft.
MPSend
Основная функция вызываемая всегда, при прохождении данных. По правилам работы с данными в NDIS необходимо написать (что в примере и сделано) re-wrap пакету.
Для этого сначала пакет надо захватить, перекопировать содержимое пакета в свою память и переслать его далее, после чего освободить пакет. Вот как будет это выглядеть в коде:
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
Контекст адаптера приходящий в качестве параметра. Присвоим его своему типизированному указателю.
NDIS_STATUS Status;
Возвращаемый статус.
PNDIS_PACKET MyPacket;
Наш пакет – пока только указатель.
PRSVD Rsvd;
Резервный указатель.
PVOID MediaSpecificInfo = NULL;
Тип адаптера с которым будем работать.
ULONG MediaSpecificInfoSize = 0;
Размер типа адаптера.
ASSERT (pAdapt->pSecondaryAdapt);
pAdapt = pAdapt->pSecondaryAdapt;
Проверка наличия второго сетевого адаптера. Вверху я говорил, что его наличие необходимо предусматривать.
if (IsIMDeviceStateOn (pAdapt) == FALSE) {
return NDIS_STATUS_FAILURE;
}
Проверка наличия и состояния.
NdisAllocatePacket(&Status, &MyPacket, pAdapt->SendPacketPoolHandle);
Выделение места под размер полученного пакета (Pool) данных.
if (Status == NDIS_STATUS_SUCCESS) {
PNDIS_PACKET_EXTENSION Old, New;
Rsvd = (PRSVD)(MyPacket->ProtocolReserved);
Rsvd->OriginalPkt = Packet;
MyPacket->Private.Flags = Flags;
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;
Собственно копирование всей служебной информации
NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);
Установка ее в наш внутренний буфер.
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket), NDIS_OOB_DATA_FROM_PACKET(Packet), sizeof(NDIS_PACKET_OOB_DATA));
Перенос данных в сам пакет.
NdisIMCopySendPerPacketInfo(MyPacket, Packet);
Копирование служебных данных по пересылке пакета.
Копирование данных о типе адаптера, куда пересылать данные.
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet, &MediaSpecificInfo, &MediaSpecificInfoSize);
if (MediaSpecificInfo || MediaSpecificInfoSize) {
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket, MediaSpecificInfo, MediaSpecificInfoSize);
}
Собственно пересылка имеющихся данных в NDIS, что вызовет нормальное прохождение пакета далее по цепочке драйверов.
NdisSend(&Status, pAdapt->BindingHandle, MyPacket);
if (Status != NDIS_STATUS_PENDING) {
NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
NdisFreePacket(MyPacket);
}
Если нет задержки на отсылке освободить пакет.
} else {
Это говорит об отсутствии пакета в системе – ничего не надо делать.
}
return(Status);
Возврат значения SUCCESS или код ошибки.
Стоит остановиться еще на одном моменте. Когда система ответила, что посылка данных закончена кодом задержки пакета – NDIS_STATUS_PENDING.
В этом случае мы пакет не освободим, блокировав таким образом всю систему NDIS по пересылке данных. Такое случается при посылке по медленной сети большого числа пакетов.
Как нам освободить пакет? Система предусматривает такое и при освобождении ресурса после освобождению пакета вызовет функцию из группы протокола PtSendComplete. Смена на протокольную группу вызвана тем, что система получит сообщение от низлежащего
Последние комментарии
15 часов 45 минут назад
15 часов 47 минут назад
16 часов 45 минут назад
17 часов 7 минут назад
1 день 11 часов назад
1 день 11 часов назад