bool TAnonPipeServer::createAnonPipe() { SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; // security information for pipes InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, true, NULL, false); sa.lpSecurityDescriptor = &sd; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; // allow passing handle to child HANDLE ClientAnonReadH, PipeW_H, ClientAnonWriteH, Pipe_H; if (!CreatePipe(&ClientAnonReadH, &PipeW_H, &sa, 0)) // create stdin pipe { GlobalOutput.perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); return false; } if (!CreatePipe(&Pipe_H, &ClientAnonWriteH, &sa, 0)) // create stdout pipe { GlobalOutput.perror("TPipeServer CreatePipe (anon) failed, GLE=", GetLastError()); CloseHandle(ClientAnonReadH); CloseHandle(PipeW_H); return false; } ClientAnonRead_.reset(ClientAnonReadH); ClientAnonWrite_.reset(ClientAnonWriteH); PipeR_.reset(Pipe_H); PipeW_.reset(PipeW_H); return true; }
void TPipe::open() { if (isOpen()) return; TAutoHandle hPipe; do { DWORD flags = FILE_FLAG_OVERLAPPED; // async mode, so we can do reads at the same time as writes hPipe.reset(CreateFile(pipename_.c_str(), GENERIC_READ | GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe flags, NULL)); // no template file if (hPipe.h != INVALID_HANDLE_VALUE) break; // success! if (::GetLastError() != ERROR_PIPE_BUSY) { GlobalOutput.perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } } while (::WaitNamedPipe(pipename_.c_str(), TimeoutSeconds_ * 1000)); if (hPipe.h == INVALID_HANDLE_VALUE) { GlobalOutput.perror("TPipe::open ::CreateFile errored GLE=", ::GetLastError()); throw TTransportException(TTransportException::NOT_OPEN, "Unable to open pipe"); } impl_.reset(new TNamedPipeImpl(hPipe.h)); hPipe.release(); }
bool TNamedPipeServer::createNamedPipe(const TAutoCrit & /*lockProof*/) { // Windows - set security to allow non-elevated apps // to access pipes created by elevated apps. SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; PSID everyone_sid = NULL; AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid); EXPLICIT_ACCESS ea; ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = static_cast<LPTSTR>(everyone_sid); PACL acl = NULL; SetEntriesInAcl(1, &ea, NULL, &acl); PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = sd; sa.bInheritHandle = FALSE; // Create an instance of the named pipe TAutoHandle hPipe(CreateNamedPipeA(pipename_.c_str(), // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, // async mode PIPE_TYPE_BYTE | // byte type pipe PIPE_READMODE_BYTE, // byte read mode maxconns_, // max. instances bufsize_, // output buffer size bufsize_, // input buffer size 0, // client time-out &sa)); // security attributes DWORD lastError = GetLastError(); LocalFree(sd); LocalFree(acl); FreeSid(everyone_sid); if (hPipe.h == INVALID_HANDLE_VALUE) { Pipe_.reset(); GlobalOutput.perror("TPipeServer::TCreateNamedPipe() GLE=", lastError); throw TTransportException(TTransportException::NOT_OPEN, "TCreateNamedPipe() failed", lastError); return false; } Pipe_.reset(hPipe.release()); return true; }