我正在尝试与用于创建TUN接口(WinTun)的驱动程序进行接口连接,但是为了从它们发送和接收数据,我需要注册一个环形缓冲区。我正在使用的代码看起来像这样(我省略了使用SetupApi创建设备的部分,因为这似乎可以正常工作):
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#define REGISTER_RINGS_IOCTL CTL_CODE(51820U, 0x970U, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define BUF_CAPACITY 0x20000
#define BUF_TRAILING 0x10000
typedef struct {
volatile ULONG Head;
volatile ULONG Tail;
volatile LONG Alertable;
UCHAR Data[BUF_CAPACITY + BUF_TRAILING];
} TUN_RING;
typedef struct {
ULONG Size;
UCHAR Data;
} TUN_PACKET;
typedef struct {
struct {
ULONG RingSize;
TUN_RING *Ring;
HANDLE TailMoved;
} Send, Receive;
} TUN_REGISTER_RINGS;
int main() {
HANDLE device = CreateFileW(
L"\\\\?\\ROOT#NET#0006#{cac88484-7515-4c03-82e6-71a87abac361}",
// ^^ This comes from the omitted code ^^
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(device == INVALID_HANDLE_VALUE) {
printf("The device does not exist\n");
return -1;
}
TUN_RING Send, Receive = {0};
TUN_REGISTER_RINGS params = {
.Send.RingSize = sizeof(TUN_RING),
.Send.Ring = &Send,
.Send.TailMoved = CreateEventW(NULL, FALSE, FALSE, NULL),
.Receive.RingSize = sizeof(TUN_RING),
.Receive.Ring = &Receive,
.Receive.TailMoved = CreateEventW(NULL, FALSE, FALSE, NULL),
};
DWORD bytes;
BOOL ret = DeviceIoControl(
device,
REGISTER_RINGS_IOCTL,
¶ms,
sizeof(TUN_REGISTER_RINGS),
NULL,
0,
&bytes,
NULL
);
if(ret == 0) {
printf("Err: %d\n", GetLastError());
return -2;
}
return 0;
}
我的问题是此代码在DeviceIoControl
处失败,错误5,对应于ERROR_ACCESS_DENIED。
我不知道为什么会这样,因为程序已经以管理员权限运行并且设备句柄已使用推荐的属性(README file)打开。抱歉,缺少额外的信息,但是我在Windows驱动程序方面经验不足,也不知道如何进一步调试。
我认为问题可能与这个as you can see here有关,因为它似乎在检查输入缓冲区之前就停止了(当我在输入缓冲区中放入垃圾时,它应该重新启动INVALID_PARAMETER,但这不会发生)。
再次,抱歉,如果我误解了一些东西或错过了一些关键的东西,但是我正在学习所有这些东西,请预先感谢!
答案 0 :(得分:2)
找到了解决方案。如@RbMm所述,code that creates the security descriptor仅允许访问LocalSystem。这意味着它是唯一允许与驾驶员通话的帐户。