我使用IOCTL_TCP_QUERY_INFORMATION_EX
控制代码调用NtDeviceIoControlFile
,但在执行实际调用之前,我需要获取输出缓冲区的大小,以便为其分配适当的大小。
这是我的代码:
TCP_REQUEST_QUERY_INFORMATION_EX TcpRequestQuery; IO_STATUS_BLOCK StatusBlock; DWORD BufferSize = sizeof(TDIENTITYID) * 4096; memset(&TcpRequestQuery, 0, sizeof(TcpRequestQuery)); TcpRequestQuery.ID.toi_class = 0x100; TcpRequestQuery.ID.toi_type = 0x100; TcpRequestQuery.ID.toi_id = 0; TcpRequestQuery.ID.toi_entity.tei_entity = 0; TcpRequestQuery.ID.toi_entity.tei_instance = 0; *EntityList = (TDIENTITYID *) GlobalAlloc (GMEM_ZEROINIT, BufferSize); NTSTATUS Status = NtDeviceIoControlFile( TcpFile, NULL, NULL, NULL, &IOBlock, IOCTL_TCP_QUERY_INFORMATION_EX, &TcpQueryInfo, sizeof(TcpQueryInfo), *EntityList, BufferSize); if (!NT_SUCCESS(Status)) return Status; BufferSize = StatusBlock.uInformation;
问题是第一次调用NtDeviceIoControlFile
返回ERROR_INVALID_PARAMETER (87)
。 正在使用SYNCHRONIZE
标志设置打开TCP设备对象的句柄。
问题是为什么,在哪里?
#include #include NTSTATUS QueryTcp() { NTSTATUS status; #ifndef _WIN64 struct TCP_REQUEST_QUERY_INFORMATION_EX_WOW { TDIObjectID ID; // object ID to query. ULONG pad; // ! for wow64 only - Context must be aligned on 8 byte in 64bit windows uchar Context[CONTEXT_SIZE]; // multi-request context. Zeroed }; PVOID Wow; status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &Wow, sizeof(Wow), 0); if (0 > status) { return status; } #endif static const UNICODE_STRING ObjectName = RTL_CONSTANT_STRING(L"\device\tcp"); static const OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, const_cast(&ObjectName), OBJ_CASE_INSENSITIVE }; HANDLE hFile; IO_STATUS_BLOCK iosb; status = NtOpenFile(&hFile, SYNCHRONIZE, const_cast(&oa), &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT); if (0 <= status) { PVOID InputBuffer; ULONG InputBufferLength; #ifndef _WIN64 if (Wow) { TCP_REQUEST_QUERY_INFORMATION_EX_WOW req = { { { GENERIC_ENTITY }, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID } }; InputBuffer = &req, InputBufferLength = sizeof(req); } else #endif { TCP_REQUEST_QUERY_INFORMATION_EX req = { { { GENERIC_ENTITY }, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID } }; InputBuffer = &req, InputBufferLength = sizeof(req); } union { PVOID buf; TDIEntityID* pEntity; }; volatile static UCHAR guz; PVOID stack = alloca(guz); ULONG cbAllocated = 0, cbNeed = 8 * sizeof(TDIEntityID); do { if (cbAllocated < cbNeed) { cbAllocated = RtlPointerToOffset(buf = alloca(cbNeed - cbAllocated), stack); } if (0 <= (status = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb, IOCTL_TCP_QUERY_INFORMATION_EX, InputBuffer, InputBufferLength, buf, cbAllocated))) { if (ULONG n = (ULONG)iosb.Information / sizeof(TDIEntityID)) { do { DbgPrint("{ %08x, %08x }n", pEntity->tei_entity, pEntity->tei_instance); } while (pEntity++, --n); } } cbNeed += 8 * sizeof(TDIEntityID); } while (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL); NtClose(hFile); } return status; }
和输出
{ 00000400, 00000000 } { 00000401, 00000000 } { 00000301, 00000000 } { 00000301, 00000001 } { 00000380, 00000000 } { 00000380, 00000001 } { 00000200, 00000015 } { 00000200, 00000014 } { 00000200, 00000013 } { 00000200, 00000012 } { 00000200, 00000011 } { 00000200, 00000010 } { 00000200, 0000000f } { 00000200, 0000000e } { 00000200, 0000000d }
然后我们可以从输出数组中获取具体的TDIEntityID
,将其复制到TCP_REQUEST_QUERY_INFORMATION_EX
并在此实体上发出详细请求,如下所述 –
以上就是c/c++开发分享NtDeviceIoControlFile – 获取缓冲区的大小相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522467.html