прежде всего нужно понять - что такое анонимные каналы и что, существует разница между анонимными и именованными каналами вообще ,
на самом деле существует только один тип канала (реализовано npfs.sys ). нет никакой разницы, кроме имени, между именованными и анонимными каналами вообще. оба это только трубы.
так называемые анонимные каналы - это специальные / случайные именованные каналы до win7, а настоящие безымянные каналы начинаются с win7.
когда msdn пишет, что "анонимный канал - односторонний канал" - это ложь . как любая труба, она может быть односторонней или дуплексной. когда msdn пишет, что «Асинхронные (перекрывающиеся) операции чтения и записи не поддерживаются анонимными каналами.» - это ложь . Конечно, трубы поддерживают асинхронный IO. На имя трубы это никак не влияет.
до win7 действительно безымянные каналы даже вообще не существовали. Функция CreatePipe
использует формат Win32Pipes.%08x.%08x
для создания имени "Анонимный канал".
static LONG PipeSerialNumber;
WCHAR name[64];
swprintf(name, L"\\Device\\NamedPipe\\Win32Pipes.%08x.%08x",
GetCurrentProcessId(), InterlockedIncrement(&PipeSerialNumber));
начинайте с win7 CreatePipe
используйте другой метод (относительное открытие файла) для создания пары каналов - теперь это действительно анонимно.
например, код с созданием пары каналов, где один канал асинхронный и не наследуется. и другой канал является синхронным и наследуемым. обе трубы дуплексные (поддерживают чтение и запись)
ULONG CreatePipeAnonymousPair7(PHANDLE phServerPipe, PHANDLE phClientPipe)
{
HANDLE hNamedPipe;
IO_STATUS_BLOCK iosb;
static UNICODE_STRING NamedPipe = RTL_CONSTANT_STRING(L"\\Device\\NamedPipe\\");
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, const_cast<PUNICODE_STRING>(&NamedPipe), OBJ_CASE_INSENSITIVE };
NTSTATUS status;
if (0 <= (status = NtOpenFile(&hNamedPipe, SYNCHRONIZE, &oa, &iosb, FILE_SHARE_VALID_FLAGS, 0)))
{
oa.RootDirectory = hNamedPipe;
static LARGE_INTEGER timeout = { 0, MINLONG };
static UNICODE_STRING empty = {};
oa.ObjectName = ∅
if (0 <= (status = ZwCreateNamedPipeFile(phServerPipe,
FILE_READ_ATTRIBUTES|FILE_READ_DATA|
FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA|
FILE_CREATE_PIPE_INSTANCE,
&oa, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_CREATE, 0, FILE_PIPE_BYTE_STREAM_TYPE, FILE_PIPE_BYTE_STREAM_MODE,
FILE_PIPE_QUEUE_OPERATION, 1, 0, 0, &timeout)))
{
oa.RootDirectory = *phServerPipe;
oa.Attributes = OBJ_CASE_INSENSITIVE|OBJ_INHERIT;
if (0 > (status = NtOpenFile(phClientPipe, SYNCHRONIZE|FILE_READ_ATTRIBUTES|FILE_READ_DATA|
FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA, &oa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT)))
{
NtClose(oa.RootDirectory);
}
}
NtClose(hNamedPipe);
}
return RtlNtStatusToDosError(status);
}
ULONG CreatePipeAnonymousPair(PHANDLE phServerPipe, PHANDLE phClientPipe)
{
static char flag_supported = -1;
if (flag_supported < 0)
{
ULONG dwMajorVersion, dwMinorVersion;
RtlGetNtVersionNumbers(&dwMajorVersion, &dwMinorVersion, 0);
flag_supported = _WIN32_WINNT_WIN7 <= ((dwMajorVersion << 8)| dwMinorVersion);
}
if (flag_supported)
{
return CreatePipeAnonymousPair7(phServerPipe, phClientPipe);
}
static LONG PipeSerialNumber;
WCHAR name[64];
swprintf(name, L"\\\\?\\pipe\\Win32Pipes.%08x.%08x", GetCurrentProcessId(), InterlockedIncrement(&PipeSerialNumber));
HANDLE hClient, hServer = CreateNamedPipeW(name,
PIPE_ACCESS_DUPLEX|FILE_READ_DATA|FILE_WRITE_DATA|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 1, 0, 0, 0, 0);
if (hServer != INVALID_HANDLE_VALUE)
{
static SECURITY_ATTRIBUTES sa = { sizeof(sa), 0, TRUE };
hClient = CreateFileW(name, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0);
if (hClient != INVALID_HANDLE_VALUE)
{
*phServerPipe = hServer, *phClientPipe = hClient;
return NOERROR;
}
CloseHandle(hServer);
}
return GetLastError();
}