我需要检查Windows中进程创建事件中的某些行为,我需要实现一个规则,该规则检查传递给createprocess api调用的startupinfo结构并提取std输入/ std输出处理所创建进程的值。 然后,我必须检查此句柄是否属于tcp套接字。 是否有任何api函数可以帮助我获取有关我拥有的句柄编号的任何信息(无论是文件句柄还是套接字句柄)?
答案 0 :(得分:0)
使用GetFileType()
功能
检索指定文件的文件类型。
语法
DWORD WINAPI GetFileType( _In_ HANDLE hFile );
参数
hFile [[in]
文件的句柄。
返回值
该函数返回以下值之一。
FILE_TYPE_CHAR
指定的文件是字符文件,通常是LPT设备或控制台。
FILE_TYPE_DISK
指定的文件是磁盘文件。
FILE_TYPE_PIPE
指定的文件是套接字,命名管道或匿名管道。
FILE_TYPE_REMOTE
未使用。
FILE_TYPE_UNKNOWN
指定文件的类型未知,或者函数失败
答案 1 :(得分:0)
以@RemyLebeau的答案为基础,我想我是否可以找到一种可靠的方法来将套接字与管道区分开来(GetFileType()
无法做到),于是我想到了以下内容:工作,没有明显的缺点。
要点是getsockopt()
如果传递的不是套接字,将返回WSAENOTSOCK
(= 10038)。因此,此测试本身就足够了,只要传递给它的任何句柄是SOCKET或文件或管道句柄。不要仅仅将其传递给任何旧的HANDLE(有各种各样的句柄),否则可能会根据@HansPassant在下面的第一条评论而感到困惑。
示例代码:
#include <winsock2.h> // * before* windows.h (!)
#include <windows.h>
#include <assert.h>
#include <iostream>
int main ()
{
WSADATA wsa_data;
int err = WSAStartup (2, &wsa_data);
assert (err == 0);
// Pipe
HANDLE hReadPipe, hWritePipe;
BOOL ok = CreatePipe (&hReadPipe, &hWritePipe, NULL, 2048);
assert (ok);
int opt;
int optlen = sizeof (opt);
err = getsockopt ((SOCKET) hReadPipe, IPPROTO_TCP, TCP_NODELAY, (char *) &opt, &optlen);
if (err)
{
DWORD dwErr = GetLastError ();
std::cout << "Pipe: " << dwErr << std::endl;
}
else
std::cout << "Pipe: OK" << std::endl;
CloseHandle (hReadPipe);
CloseHandle (hWritePipe);
// Socket
SOCKET skt = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
assert (skt != INVALID_SOCKET);
optlen = sizeof (opt);
err = getsockopt (skt, IPPROTO_TCP, TCP_NODELAY, (char *) &opt, &optlen);
if (err)
{
DWORD dwErr = GetLastError ();
std::cout << "Socket: " << dwErr << std::endl;
}
else
std::cout << "Socket: OK" << std::endl;
closesocket (skt);
return 0;
}
输出:
Pipe: 10038
Socket: OK
编辑:如果您阅读下面的评论,您会发现已经有人在讨论是否可以使该代码相信文件或管道的HANDLE实际上是一个SOCKET。好吧,那不可能。我们之所以知道这一点,是因为ReadFile()
和WriteFile()
之类的功能在文件/管道HANDLE和SOCKET上均能很好地工作,并且如果有可能将两者误用,那就行不通了。>
因此,此代码在所有情况下(包括重定向的输出,Remy的代码都将其视为套接字)在所有情况下(a)安全,(b)简单且(c)有效。因此,我推荐它。只要确保先致电WSAStartup()
,然后再执行其他操作即可。
感谢@HansPassant和@eryksun为这篇文章做出了重要贡献。
答案 2 :(得分:0)
使用GetNamedPipeInfo(s,NULL,NULL,NULL,NULL)来区分管道和套接字。
127.0.0.1 - - [15/Feb/2013 10:52:22] "GET /index.html HTTP/1.1" 200