Gurudatt 8032986 Ответов: 1

Мне нужна помощь в подключении к удаленным именованным каналам...


У меня есть служба, работающая в сеансе 0 на одном компьютере, скажем A, которая создает именованный канал и ждет соединения. На другом компьютере, скажем B, у меня есть другая служба, которая действует как клиент канала и пытается подключиться к именованному каналу на компьютере A, но получает GLE=5.

Я пробовал использовать одни и те же две службы, работающие на одном компьютере, и связь по именованному каналу была абсолютно гладкой.

Может ли кто-нибудь указать, не пропустил ли я что-нибудь при создании именованного канала?
Нужно ли мне делать какие-либо настройки на обоих серверах, чтобы это работало ?

Я работаю над этим уже давно, и мне нужно, чтобы это сработало..

Спасибо.

Что я уже пробовал:

Я использовал VC6.0 для кода именованного канала.

При создании имя канала, я пробовал с:
1. Атрибуты безопасности=нуль,
2. инициализированный SA со значениями по умолчанию и
3. Режим трубу Ored с PIPE_ACCEPT_REMOTE_CLIENTS.

Все эти методы не дали успеха.

Richard MacCutchan

Пожалуйста, обновите вопрос и покажите код для обоих процессов, которые открывают канал и проверяют возвращаемое значение.

1 Ответов

Рейтинг:
2

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

Один момент, который я хотел бы упомянуть, заключается в том, что на этих двух серверах не настроена аутентификация без пароля. Службы приложения работают на двух серверах в контексте пользователя, созданного самим приложением (при его установке).