Сторона режима пользователя: Есть несколько способов.
1) Наиболее распространенный / гибкий способ - использовать DeviceIOControl
для связи между режимом пользователя и режимом ядра, включая передачу памяти.
Прошло много времени (шесть лет? Срок XP) с тех пор, как я написал свой последний драйвер ядра, так что это обзор процесса, а не точный код. Однако ваша программа пользовательского режима должна иметь возможность получить дескриптор вашего «устройства» или открытого экземпляра вашего драйвера, работающего над чем-либо, используя CreateFile
и указав его имя, например, \\.\YourNameHere
. Используйте этот дескриптор для связи с ним (первый параметр DeviceIOControl
.)
Вам будут интересны четыре параметра:
__in_opt LPVOID lpInBuffer,
__in DWORD nInBufferSize,
__out_opt LPVOID lpOutBuffer,
__in DWORD nOutBufferSize,
__out_opt LPDWORD lpBytesReturned,
Используя их, вы можете передавать данные драйверу (через указатель lpInBuffer
и параметр nInBufferSize
, указывающий, насколько он велик - что это за данные или как их интерпретировать до вашего драйвера) и ядру. Слой режима может возвращать данные через lpOutBuffer
(указатель на память, которую вы в пользовательском режиме уже выделили - это не указатель, который устанавливает драйвер!), его размер в байтах в nOutBufferSize
(опять же, вы это знаете , поскольку вы в пользовательском режиме выделяете этот буфер), а затем драйвер сообщит вам, сколько из этого буфера фактически заполнено lpBytesReturned
.
Эта статья в Википедии описывает общую концепцию функций ioctl , примером которой является DeviceIOControl.
Примечание: Вы сказали "Я пытаюсь разделить память между пользовательским пространством и пространством ядра в Windows" . Это не точно разделяемая память - это не память, к которой пользовательский режим и режим ядра, например, считывают или записывают в одно и то же время. Это память, где во время вызова функции DeviceIOControl
режим ядра имеет доступ к вашей памяти, выделенной пользовательскому режиму, для которой вы передаете указатели (хотя из памяти это немного сложнее, чем это, но это эффект). Т.е. он только «общий», пока вы вызываете этот метод.
2) Другой альтернативой является использование ReadFile
и WriteFile
, если вам нужна только простая передача данных и драйвер ядра принимает ее. Он не позволяет вам иметь двустороннюю связь, в отличие от DeviceIOControl
(где вы предоставляете данные драйвера и он возвращает вам что-то с кодом ошибки), но это просто, и вы, вероятно, уже знакомы с этими API.
Сторона режима ядра: Вы тоже пишете драйвер ядра? Если это так, эта статья содержит информацию о реализации стороны IOCTL в режиме ядра. В этой серии статей также описано, как пользовательский режим может использовать ReadFile
и WriteFile
для связи, если вы выберете этот метод.