Не совсем ясно почему m$ не устраивает следующий код: Код (Text): ExAcquireFastMutex(...); if (RtlCompareUnicodeString(...) == 0) { ... } Фаст мютекс повышает IRQL до APC_LEVEL, следовательно paged и non-paged доступны. Однако согласно документации (и SAL анотации в SDK) Rtl*UnicodeString ф-и работают только на PASSIVE_LEVEL. При этом в дебажной версии ядра для RtlCompareUnicodeString указан ASSERT который чекает только на выход в DPC_LEVEL и выше: Код (C): if ( KeGetCurrentIrql() > 1u ) { v5 = KeGetCurrentIrql(); DbgPrint("EX: Pageable code called at IRQL %d\n", v5); NT_ASSERT("0"); } Есть у кого идеи в чем смысл ограничения?
JKornev, Эта строковая функа ничего не вызывает, тока к памяти обращается. Следовательно нет описанных вами ограничений. И в этом случае никакого требования по IRQL не может быть.
Да, но требование к PASSIVE_LEVEL есть в документации к ф-ям на MSDN, хочеться понять есть ли в этом хоть капля смысла или же это косяк m$
JKornev, Может это автоматика писала, разбили на группы и потом выдали лог, кто знает. Это сомнительный источник инфы. К коду, который ничего не вызывает, к чему есть требования по IRQL - нет требований по IRQL соответственно.
Это не совсем так, многие функции позволяют и больше чем PASSIVE_LEVEL. RtlInitUnicodeString А некоторые такие как RtlCopyUnicodeString в общем все зависит от типа выделенной памяти. Что же до функции RtlCompareUnicodeString - то MS скорее всего накосячили (может даже перестраховались, от возможных задержек на APC_LEVEL, когда и сам код исполняется на APC_LEVEL, при подкачке страниц, во время сравнения строк). В вашем случае, я бы просто сделал свою реализацию. Она простая, и не нужно будет дергать то, что имеет странное ограничение.
Мне кажется не все так просто (возможно ошибаюсь), поскольку даже для сравнения без учета регистра придется иметь таблицу для всех групп символов юникода по которой определять соотношение между LowerCase и UpperCase. Также существуют ньюансы в сравнении отдельных символов и знаков. Для примера флаги функции ComapreStringEx.
Посмотрите исходник оригинальной RtlCopyUnicodeString в ядре. Там ничего такого не делается, из того, что вы написали. Там все тупо сравнение. По этому я и написал - сделать свой аналог. Конечно если делать настоящее сравнение юникода - это настоящая головная боль, с кучей нюансов и тп.
TermoSINteZ, Рипнуть можно, если расположение кода не нравится. Да и вообще это примитивная апи, она копирует хидер и саму строку. Копирование строки выполняется общей процедурой с оптимизацией. Посему не ясно зачем такое нужно. Сравнение сложнее есно.
Thetrik, Indy_, пардон - не то написал. Я имел ввиду конечно RtlCompareUnicodeString та реализация, что в ядре она простая - переводится в UpperCase и сравнивается символ с символом. Без всяких проверок кодировок на сколько я помню из того, что было в ядре.
Да немножко поправлюсь, когда нужно CaseInSensitive = то оно тогда да, проверяет кодировку по таблице, NlsMbCodePageTag и после преобразования к одному регистру, сравнивает. Иначе как я и сказал - просто сравнение.