Именованный канал по сети без логина и пароля

289
27 февраля 2017, 12:35

Как создать именованный канал в Windows, чтобы можно было читать из него и записывать данные в него без каких-либо логинов и паролей с компьютеров в локальной сети? Изъяны в безопасности при использовании такого канала меня не волнуют, так как это учебная программа. Хотелось бы обойтись без сложных настроек в ОС. Нужно, чтобы работало хотя бы в Windows XP и 7.

Вот пример, который работает на одном компьютере, но не на нескольких. Код сервера:

#include <windows.h>
#include <iostream>
char msg1[]="Message1";
char msg2[]="Message2";
int main(){ 
    std::string c;
    SECURITY_ATTRIBUTES sa={0};
    SECURITY_DESCRIPTOR sd={0};
    InitializeSecurityDescriptor( 
     &sd,
     SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl( 
     &sd, 
     TRUE, 
     NULL, 
     FALSE);
    sa.bInheritHandle=false;
    sa.lpSecurityDescriptor=&sd;
    sa.nLength=sizeof(sa);
    HANDLE ch1=CreateNamedPipe (
        "\\\\.\\pipe\\testpipe", 
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE| PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES,
        sizeof msg1, 4, 0, &sa
    );
    if(ch1==INVALID_HANDLE_VALUE){
        std::cout<<"ch1 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    HANDLE ch2=CreateNamedPipe(
        "\\\\.\\pipe\\testpipe", 
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE| PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES,
        sizeof msg1, 4, 0, &sa
    );
    if(ch2==INVALID_HANDLE_VALUE){
        std::cout<<"ch2 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    ConnectNamedPipe(ch1, 0);
    ConnectNamedPipe(ch2, 0);
    unsigned long foo;
    if(TransactNamedPipe(ch1, msg1, sizeof msg1, &foo, sizeof foo, &foo, 0)==0){
        std::cout<<"transact1 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    if(TransactNamedPipe(ch2, msg2, sizeof msg2, &foo, sizeof foo, &foo, 0)==0){
        std::cout<<"transact2 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    std::cout<<"Finished\n";
    std::getline(std::cin, c);
    return 0;
}

Код клиента:

#include <windows.h>
#include <iostream>
char msg1[]="Message1\n";
char msg2[]="Message2\n";
int main(){ 
    std::string c;
    std::cout<<"Server name:\n";
    std::string sname;
    std::cin>>sname;
    std::cin.ignore();
    NETRESOURCE nr={0};
    if(sname!="."){
        std::string sname2=std::string("\\\\")+sname;
        nr.dwType = RESOURCETYPE_ANY;
            nr.lpRemoteName = &sname2[0];
        DWORD ret=WNetAddConnection2( &nr, "", "", 0);
        if(ret!=NO_ERROR){
            std::cout<<"WNetAddConnection2 "<<GetLastError()<<"\n";
            std::getline(std::cin, c);
            return 1;
        }
    }
    std::string pname=std::string("\\\\")+sname+std::string("\\pipe\\testpipe");
    HANDLE phandle1=CreateFile (
        pname.c_str(), 
        GENERIC_READ|GENERIC_WRITE, 
        0, 0, OPEN_EXISTING, 0,0
    );
    if(phandle1==INVALID_HANDLE_VALUE){
        std::cout<<"CreateFile1 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    HANDLE phandle2=CreateFile (
        pname.c_str(), 
        GENERIC_READ|GENERIC_WRITE, 
        0, 0, OPEN_EXISTING, 0,0
    );
    if(phandle2==INVALID_HANDLE_VALUE){
        std::cout<<"CreateFile2 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    char msg[sizeof(msg1)];
    unsigned long s;
    unsigned long foo=0;
    if(ReadFile(phandle1, &msg, sizeof msg1, &s, 0)==0){
        std::cout<<"ReadFile1 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    std::cout<<msg<<"\n";
    if(WriteFile (phandle1, &foo, sizeof foo, &foo, 0)==0){
        std::cout<<"WriteFile1 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    if(ReadFile(phandle2, &msg, sizeof msg1, &s, 0)==0){
        std::cout<<"ReadFile2 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    std::cout<<msg<<"\n";
    if(WriteFile (phandle2, &foo, sizeof foo, &foo, 0)==0){
        std::cout<<"WriteFile2 "<<GetLastError()<<"\n";
        std::getline(std::cin, c);
        return 1;
    }
    std::cout<<"Finished\n";
    std::getline(std::cin, c);
    return 0;
}

Конкретная ошибка: 5 (ERROR_ACCESS_DENIED) при первом вызове CreateFile в клиентской программе.

READ ALSO
Балансировка дерева и приведение его к АВЛ сбалансированному дереву

Балансировка дерева и приведение его к АВЛ сбалансированному дереву

В файле записаны числа, нужно их считать, построить дерево поискаПосле этого сбалансировать дерево, выполнив RR поворот

258
end() vs cend()

end() vs cend()

Всегда ли это предложение возвращает true для стандартных контейнеров?

266
Выборка данных с группировкой по дате

Выборка данных с группировкой по дате

Две таблицы, связь один ко многимКак выбрать присутствующих сотрудников, за день

851
SQL выборочный UPDATE

SQL выборочный UPDATE

Есть таблица, T1, в ней нужно установить значение поля V2 в 'A3', но только в том случае, если это поле было равно 'A2'Сделать это нужно для всех записей,...

280