Named pipes 枚举Windows中的命名管道
连接到命名管道(在本例中为快速cgi命名管道)时遇到问题 根据MSDN,我应该使用CreateFile()或CallNamedPipe() (平面C API,同步-无重叠I/O) 然而,我得到的是无效的\u句柄\u值,当我得到lastError()时,它是零 我还想知道是否可以用一个。调用某种类型的函数,然后解析出我要查找的函数: “\。\pipe\FastCGI\” 是否有人对这些评论有经验:Named pipes 枚举Windows中的命名管道,named-pipes,Named Pipes,连接到命名管道(在本例中为快速cgi命名管道)时遇到问题 根据MSDN,我应该使用CreateFile()或CallNamedPipe() (平面C API,同步-无重叠I/O) 然而,我得到的是无效的\u句柄\u值,当我得到lastError()时,它是零 我还想知道是否可以用一个。调用某种类型的函数,然后解析出我要查找的函数: “\。\pipe\FastCGI\” 是否有人对这些评论有经验: 是否正确转义管道名称?它应该是这样的:\\.\\pipe\\FastCGI 有关更多信息,请参阅。
是否正确转义管道名称?它应该是这样的:
\\.\\pipe\\FastCGI
有关更多信息,请参阅。使用未记录的功能: //NtQueryDirectoryFile(
//在HANDLE FileHandle中,//文件的句柄
//在句柄EventHandle可选中,
//在PIO_APC_例程APC例程可选中,
//在PVOID环境中,可选,
//输出PIO\U状态块IoStatusBlock,
//OUT PVOID Buffer,//指向接收结果的缓冲区的指针
//在ULONG BufferLength中,//缓冲区的长度
//在文件\u INFORMATION\u CLASS InformationClass中,//信息类型
//在布尔ReturnByOne中,//每个调用只返回一个文件的信息
//在PUNICODE_STRING FileTemplate OPTIONAL中,//用于搜索的模板
//在布尔重置//重新启动搜索中
// ); 问题在于:
TmpInfo = DirInfo;
while(1)
{
if(TmpInfo->NextEntryOffset==0)
break;
TmpInfo->FileDirectoryInformationClass.FileName[TmpInfo->FileNameLength/sizeof(WCHAR)] = NULL;
wprintf(L"%s (%d, %d)\n",TmpInfo->FileDirectoryInformationClass.FileName,
TmpInfo->EndOfFile.LowPart,
TmpInfo->AllocationSize.LowPart );
TmpInfo = (PFILE_QUERY_DIRECTORY)((DWORD)TmpInfo+TmpInfo->NextEntryOffset);
}
在“while(1)”之后,检查NextEntryOffset==0
这意味着不会报告最后一个条目,将“if(…)break;”移动到“wprintf(…)”调用之后,您应该能够枚举所有管道。编辑
对于那些想要完整源代码(不需要DDK)的人,这里就是。请不要告诉我这不是我的代码,已经找到了。此代码与原始代码之间的唯一变化是上面详述的错误修复。
编辑v2.0
在下面的代码中发现另一个bug。当它去打印关于它正在迭代的当前项的信息时,它会在名称的末尾放置一个空字符。此空字符实际上覆盖了下一个条目的前2个字节,这恰好覆盖了该条目中“NextEntryOffset”变量的2个最低有效字节(通常使其等于0),因此每个“NtQueryDirectoryFile”调用仅枚举前2个项。
我在下面的代码中添加了一个修复程序,可以解决这个问题(存储正在清除的WCHAR,然后在打印后将其还原。有点麻烦,但这只是一些示例代码,为了正确实现,要么避免使用wprintf打印名称,要么将其复制到另一个缓冲区,这样您就可以安全地将其结尾置空)。
//pipelist.cpp(Windows NT/2000)
//
//此示例将演示如何枚举所有命名管道
//在系统上处于活动状态。
//
//(c)2000年Ashot Oganesyan K,智能线路公司
//邮寄地址:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com
#包括
#包括
#定义文件目录信息1
#定义状态\u无\u更多\u文件0x8000006L
类型定义结构
{
USHORT长度;
USHORT最大长度;
PWSTR缓冲区;
}UNICODE_字符串,*PUNICODE_字符串;
类型定义结构
{
长期状态;
乌龙信息;
}IO_状态_块,*PIO_状态_块;
类型定义结构{
ULONG NextEntryOffset;
乌龙文件索引;
大整数创建时间;
大整数时间;
大整数LastWriteTime;
大整数转换时间;
大整数内ffile;
大整数分配;
ULONG文件属性;
ULONG文件名长度;
联合{
结构{
WCHAR文件名[1];
}FileDirectoryInformationClass;
结构{
德沃德·杜克诺夫1;
WCHAR文件名[1];
}FileFullDirectoryInformationClass;
结构{
德沃德·杜克诺温2;
USHORT AltFileNameLen;
WCHAR AltFileName[12];
WCHAR文件名[1];
}FileBothDirectoryInformationClass;
};
}文件查询目录,*PFILE查询目录;
//ntdll!NtQueryDirectoryFile(特定于NT!)
//
//该函数用于在目录中搜索其名称和属性为的文件
//与函数调用中指定的匹配。
//
//NTSYSAPI
//NTSTATUS
//恩塔皮
//NtQueryDirectoryFile(
//在HANDLE FileHandle中,//文件的句柄
//在HANDLE EventHandle OPTIONAL中,
//在PIO_APC_例程APC_可选中,
//在PVOID上下文中,可选,
//输出PIO_状态块IoStatusBlock,
//OUT PVOID Buffer,//指向接收结果的缓冲区的指针
//在ULONG BufferLength中,//缓冲区的长度
//在文件\u INFORMATION\u CLASS InformationClass中,//信息类型
//在布尔ReturnByOne中,//每个调用只返回一个文件的信息
//在PUNICODE_STRING FileTemplate OPTIONAL中,//用于搜索的模板
//在布尔重置//重新启动搜索中
// );
typedef LONG(WINAPI*PROCNTQDF)(句柄、句柄、PVOID、PVOID、PIO_状态块、PVOID、ULONG、,
UINT,BOOL,PUNICODE_字符串,BOOL);
PROCNTQDF NtQueryDirectoryFile;
真空总管(真空)
{
长期状态;
IO_状态_块IoStatus;
处理高压管道;
BOOL-bReset=TRUE;
PFILE_QUERY_目录DirInfo,
TmpInfo;
NtQueryDirectoryFile=(PROCNTQDF)GetProcAddress(
GetModuleHandle(“ntdll”),
“NtQueryDirectoryFile”
// pipelist.cpp (Windows NT/2000)
//
// This example will show how you can enumerate all named pipes
// active on a system.
//
// (c)2000 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com
#include <windows.h>
#include <stdio.h>
#define FileDirectoryInformation 1
#define STATUS_NO_MORE_FILES 0x80000006L
typedef struct
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct
{
LONG Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
union {
struct {
WCHAR FileName[1];
} FileDirectoryInformationClass;
struct {
DWORD dwUknown1;
WCHAR FileName[1];
} FileFullDirectoryInformationClass;
struct {
DWORD dwUknown2;
USHORT AltFileNameLen;
WCHAR AltFileName[12];
WCHAR FileName[1];
} FileBothDirectoryInformationClass;
};
} FILE_QUERY_DIRECTORY, *PFILE_QUERY_DIRECTORY;
// ntdll!NtQueryDirectoryFile (NT specific!)
//
// The function searches a directory for a file whose name and attributes
// match those specified in the function call.
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQueryDirectoryFile(
// IN HANDLE FileHandle, // handle to the file
// IN HANDLE EventHandle OPTIONAL,
// IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
// IN PVOID ApcContext OPTIONAL,
// OUT PIO_STATUS_BLOCK IoStatusBlock,
// OUT PVOID Buffer, // pointer to the buffer to receive the result
// IN ULONG BufferLength, // length of Buffer
// IN FILE_INFORMATION_CLASS InformationClass,// information type
// IN BOOLEAN ReturnByOne, // each call returns info for only one file
// IN PUNICODE_STRING FileTemplate OPTIONAL, // template for search
// IN BOOLEAN Reset // restart search
// );
typedef LONG (WINAPI *PROCNTQDF)( HANDLE,HANDLE,PVOID,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,
UINT,BOOL,PUNICODE_STRING,BOOL );
PROCNTQDF NtQueryDirectoryFile;
void main(void)
{
LONG ntStatus;
IO_STATUS_BLOCK IoStatus;
HANDLE hPipe;
BOOL bReset = TRUE;
PFILE_QUERY_DIRECTORY DirInfo,
TmpInfo;
NtQueryDirectoryFile = (PROCNTQDF)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQueryDirectoryFile"
);
if (!NtQueryDirectoryFile)
return;
hPipe = CreateFile("\\\\.\\Pipe\\",GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,OPEN_EXISTING,0,NULL);
if(hPipe == INVALID_HANDLE_VALUE)
return;
DirInfo = (PFILE_QUERY_DIRECTORY) new BYTE[1024];
printf("Pipe name (Number of instances, Maximum instances)\n\n");
while(1)
{
ntStatus = NtQueryDirectoryFile(hPipe,NULL,NULL,NULL,&IoStatus,DirInfo,1024,
FileDirectoryInformation,FALSE,NULL,bReset);
if (ntStatus!=NO_ERROR)
{
if (ntStatus == STATUS_NO_MORE_FILES)
break;
return;
}
TmpInfo = DirInfo;
while(1)
{
// Store old values before we mangle the buffer
const int endStringAt = TmpInfo->FileNameLength/sizeof(WCHAR);
const WCHAR oldValue = TmpInfo->FileDirectoryInformationClass.FileName[endStringAt];
// Place a null character at the end of the string so wprintf doesn't read past the end
TmpInfo->FileDirectoryInformationClass.FileName[endStringAt] = NULL;
wprintf(L"%s (%d, %d)\n",TmpInfo->FileDirectoryInformationClass.FileName,
TmpInfo->EndOfFile.LowPart,
TmpInfo->AllocationSize.LowPart );
// Restore the buffer to its correct state
TmpInfo->FileDirectoryInformationClass.FileName[endStringAt] = oldValue;
if(TmpInfo->NextEntryOffset==0)
break;
TmpInfo = (PFILE_QUERY_DIRECTORY)((DWORD)TmpInfo+TmpInfo->NextEntryOffset);
}
bReset = FALSE;
}
delete DirInfo;
CloseHandle(hPipe);
}
\\.\pipe\test
\\.\pipe\test
Pipe_Name = "\\.\pipe\test"
MaxInstances = 1
OutBufferSize = 1024
InBufferSize = 1024
hPipe = CreateNamedPipe(_
Pipe_Name, _ ' Name of the Pipe
PIPE_ACCESS_DUPLEX, _ ' Specifies the pipe access/overlapped/write-through/security access modes
PIPE_TYPE_MESSAGE OR PIPE_READMODE_MESSAGE, _ ' Specifies the type, read, and wait modes of the pipe handle
MaxInstances, _ ' Specifies the maximum number of instances that can be created for this pipe
OutBufferSize, _ ' Specifies the number of bytes to reserve for the output buffer
InBufferSize, _ ' Specifies the number of bytes to reserve for the input buffer
0, _ ' Specifies the default time-out value, in milliseconds
Security_Declaration) ' Pointer to a SECURITY_ATTRIBUTES structure