Rick York
Вы подключаетесь к каналу с именем вида : "\\ComputerName\pipe\PipeName", где ComputerName-это имя машины, на которой работает сервер каналов, а PipeName-это имя канала?
Открытый вызов должен быть примерно таким :
hpipe = CreateFile( pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
Вот один довольно сложный аспект кода, который я использовал :
////////////////////////////////////////////////////////////////
static BOOL EstablishNullSession( const char* computerName )
{
NETRESOURCE nr = { 0 };
char server[MAX_PATH+1] = { 0 };
DWORD ret;
if( streq( computerName, "." ) )
{
strcpy( server, computerName );
}
else
{
strcpy( server, "\\\\" );
strcat( server, computerName );
}
nr.dwType = RESOURCETYPE_ANY;
nr.lpRemoteName = server;
ret = WNetAddConnection2( &nr, "", "", 0 );
if( ret != ERROR_SUCCESS )
{
DisplayError( "WNetAddConnection2" );
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////
TPipe ConnectToPipe( const char * pipename, const char * nodename,
int retries, int waitsecs ) )
{
printf( "connecting to pipe '%s'\n", name );
TPipe hpipe = { 0 };
bool triedLogin = false;
DWORD tries = 0;
DWORD lastError = 0;
DWORD openType = GENERIC_READ | GENERIC_WRITE;
while( TRUE )
{
hpipe = CreateFile( name, openType, 0, NULL, OPEN_EXISTING, 0, NULL );
// check that the pipe's handle is valid
if( hpipe != INVALID_HANDLE_VALUE )
break; // succeeded
lastError = GetLastError();
// if server not present yet try again
if( lastError == ERROR_FILE_NOT_FOUND )
{
if( tries > retries )
{
DisplayError( "CreateFile" );
return 0;
}
++tries;
Sleep( 500 );
continue;
}
else if( ( lastError == ERROR_LOGON_FAILURE ) ||
( lastError == ERROR_ACCESS_DENIED ) ||
( lastError == ERROR_INVALID_PASSWORD ) )
{
if( triedLogon )
{
return 0;
}
else // this is the tricky part
{
if( EstablishNullSession( nodename ) )
{
printf( "established Null session.\n" );
}
else
{
return 0;
}
triedLogon = true;
continue;
}
}
else if( lastError == ERROR_PIPE_BUSY )
{
printf( "the pipe was busy - waiting" );
if( ! WaitNamedPipe( name, 1000 * waitsecs ) )
{
DisplayError( "WaitNamedPipe" );
return 0;
}
}
else // something else happened
{
DisplayError( "CreateFile" );
return 0;
}
}
mode = PIPE_READMODE_MESSAGE;
if( ! SetNamedPipeHandleState( hpipe, &mode, NULL, NULL ) )
{
DisplayError( "SetNamedPipeHandleState " );
return 0;
}
return (TPipe)hpipe;
}
Я думаю, что TPipe был определен как ULONG. Это довольно старый код, который я давно не пробовал, но в то время он работал довольно хорошо.
Желаю удачи с этим.
Rick York
Сложнее всего было установить нулевой сеанс, если он не сработал с первого раза. Очевидно, что это не требуется, когда сервер находится на одной машине.
Gurudatt 8032986
Спасибо тебе, Рич, за код. Я попробовал его в своей системе, и он терпит неудачу в EstablishNullSession, где после вызова API WNetAddConnection2 GLE = 5.
Gurudatt 8032986
Один момент, который я хотел бы упомянуть, заключается в том, что на этих двух серверах не настроена аутентификация без пароля. Службы приложения работают на двух серверах в контексте пользователя, созданного самим приложением (при его установке).