Depois que um serviço/driver (.sys) é iniciado, normalmente a comunicação acontece por meio de um arquivo (pseudocódigo do cliente):
HANDLE gHandle = CreateFileA("\\\\.\\DriverFile",
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
...
DeviceIoControl(gHandle, MY_MSG_ID, NULL, 0, &refCount,
sizeof(refCount), &length, NULL);
...
CloseHandle(gHandle);
Existe uma maneira de saber quantos clientes têm conexão aberta com o arquivo do driver? Uma maneira de implementar isso é manipular IRP_MJ_CREATE / IRP_MJ_CLOSE no lado do driver e manter a contagem de ref manualmente; então usar alguma mensagem para o código do cliente do driver pode recuperar a contagem. Existe uma maneira de fazer isso sem envolver alterações no lado do driver?
você não precisa de nenhuma contagem de referência (o sistema já faz isso para você) e não precisa esperar pelos clientes. Se você quiser descarregar/excluir o driver, basta fazer isso. Se ainda houver arquivos abertos no driver (mais exatamente em algum dispositivo de TI), o sistema descarrega o driver e quando o último arquivo for fechado.
vamos fazer uma demonstração com o driver Null.sys . tente pará-lo/descarregar até que existam arquivos abertos no dispositivo (
\Device\Null
).para verificar se o driver está na memória, podemos usar a próxima função
no caso de Null.sys o
\Driver\Null
objeto estará, até que o driver esteja na memória. podemos tentar abrir este objeto comNtOpenFile
. falharemos em qualquer caso (impossível abrir o objeto do driver no modo de usuário e com esta API). mas o código de erro será diferente.STATUS_OBJECT_TYPE_MISMATCH
- significa que\Driver\Null
existe eSTATUS_OBJECT_NAME_NOT_FOUND
- significa que\Driver\Null
não existepara simular o cliente durante a parada do motorista, podemos usar o seguinte código
então primeiro iniciamos o cliente e esperamos até que ele abra o dispositivo em Null.sys (
L"\\\\?\\NUL"
) e então tentamos parar o driver -StopDriver(L"Null", L"\\Driver\\Null");
porque estamos esperando aqui pela demonstração - ficaremos girando em loop, até que a caixa de mensagemClientThread
não seja fechada. no código real - normalmente você não precisa chamarDoesDriverObjectExist
e esperar por outro valor além deSTATUS_OBJECT_TYPE_MISMATCH
- você pode simplesmente excluir o serviço ou não se importar. todo esse código - para demonstração e melhor entendimento de tudo.e função util