Как создать именованный канал в 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
в клиентской программе.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В файле записаны числа, нужно их считать, построить дерево поискаПосле этого сбалансировать дерево, выполнив RR поворот
Две таблицы, связь один ко многимКак выбрать присутствующих сотрудников, за день
Есть таблица, T1, в ней нужно установить значение поля V2 в 'A3', но только в том случае, если это поле было равно 'A2'Сделать это нужно для всех записей,...