int ESvnBase::ContinuePipe () { char RealCommand[2048]; size_t space; if (!OnFilesPos) { // At the end of all files, terminate ClosePipe (); return 0; } else if (Running) { // Already running, close the pipe and continue ReturnCode=gui->ClosePipe (PipeId); } else { // Not running -> set to Running mode Running=1; } // Make real command with some files from OnFiles, update OnFilesPos strcat (strcpy (RealCommand,Command)," "); space=sizeof (RealCommand)-strlen (RealCommand)-1; if (space>=strlen (OnFilesPos)) { strcat (RealCommand,OnFilesPos); OnFilesPos=NULL; } else { char c=OnFilesPos[space]; OnFilesPos[space]=0; char *s=strrchr (OnFilesPos,' '); OnFilesPos[space]=c; if (!s) { ClosePipe (); return 0; } *s=0; strcat (RealCommand,OnFilesPos); OnFilesPos=s+1; while (*OnFilesPos==' ') OnFilesPos++; if (!*OnFilesPos) OnFilesPos=NULL; } BufLen=BufPos=0; { char s[sizeof (RealCommand)+32]; sprintf (s,"[continuing: '%s']",RealCommand); AddLine (0,-1,s); } PipeId=gui->OpenPipe (RealCommand,this); return 0; }
void Pipe::ConnectToPipe(const String &PipeName) { ClosePipe(); bool Done = false; while(!Done) { _Handle = CreateFile( PipeName.CString(), // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe 0, // default attributes NULL); // no template file if(_Handle != INVALID_HANDLE_VALUE) { Done = true; } Sleep(100); } DWORD Mode = PIPE_READMODE_MESSAGE; BOOL Success = SetNamedPipeHandleState( _Handle, // pipe handle &Mode, // new pipe mode NULL, // don't set maximum bytes NULL); // don't set maximum time Assert(Success != FALSE, "SetNamedPipeHandleState failed in Pipe::ConnectToPipe"); }
/*********************************************************************************** ** Execute a file chooser dialog ** NB: this will fork ** ** KDEOpFileChooser::Execute ***********************************************************************************/ OP_STATUS KDEOpFileChooser::Execute(OpWindow* parent, DesktopFileChooserListener* listener, const DesktopFileChooserRequest& request) { // Don't call twice if (m_childpid) return OpStatus::ERR; m_listener = listener; // Prepare communication pipe if (pipe(m_pipe_descriptor) != 0) return OpStatus::ERR; // fork() and check for error m_childpid = fork(); if (m_childpid == 0) { // Child ClosePipe(PipeRead); dup2(m_pipe_descriptor[PipeWrite], fileno(stdout)); if (OpStatus::IsError(OpenDialog(request))) exit(1); } else if (m_childpid > 0) { // Parent ClosePipe(PipeWrite); g_main_message_handler->SetCallBack(this, MSG_FILE_CHOOSER_SHOW, reinterpret_cast<MH_PARAM_1>(this)); g_main_message_handler->PostMessage(MSG_FILE_CHOOSER_SHOW, reinterpret_cast<MH_PARAM_1>(this), 0, 100); } else { // Error occured m_childpid = 0; return OpStatus::ERR; } return OpStatus::OK; }
static BOOL ProcessDetach() { lf("memtrace.dll: ProcessDetach()"); TerminateSendingThread(); ClosePipe(); DeleteCriticalSection(&gMemMutex); CloseHandle(gSendThreadEvent); FreeAllBlocks(); lf("memtrace.dll: allocated total %d blocks", gBlocksAllocated); HeapDestroy(gHeap); return TRUE; }
static bool WriteToPipe(const byte *s, size_t len) { DWORD written; if (!gPipe) return false; DWORD toWrite = (DWORD)len; BOOL ok = WriteFile(gPipe, s, toWrite, &written, NULL); if (!ok) { lf("memtrace.dll: WriteToPipe() failed"); LogLastError(); ClosePipe(); return false; } if (written != toWrite) { lf("memtrace.dll: only wrote %d out of %d", (int)written, (int)toWrite); ClosePipe(); return false; } return true; }
void std_logger_Close(std_logger *sys) { if (sys->stop_pipe[1] != -1) { write(sys->stop_pipe[1], '\0', 1); close(sys->stop_pipe[1]); sys->stop_pipe[1] = -1; pthread_join(sys->thread, NULL); } ClosePipe(sys->stop_pipe); ClosePipe(sys->stdout_pipe); ClosePipe(sys->stderr_pipe); if (sys->old_stdout != -1 && sys->old_stderr != -1) { dup2(sys->old_stdout, STDOUT_FILENO); dup2(sys->old_stderr, STDERR_FILENO); close(sys->old_stdout); close(sys->old_stderr); sys->old_stdout = sys->old_stderr = -1; } free(sys); }
std_logger * std_logger_Open(const char *TAG) { std_logger *sys = NULL; sys = (std_logger *)calloc(1, sizeof (std_logger)); if (!sys) return NULL; sys->TAG = TAG; sys->stop_pipe[0] = sys->stop_pipe[1] = sys->stdout_pipe[0] = sys->stdout_pipe[1] = sys->old_stdout = sys->old_stderr = -1; /* save the old stdout/stderr fd to restore it when logged is closed */ sys->old_stdout = dup(STDOUT_FILENO); sys->old_stderr = dup(STDERR_FILENO); if (sys->old_stdout == -1 || sys->old_stderr == -1) goto bailout; /* duplicate stdout */ if (pipe(sys->stdout_pipe) == -1) goto bailout; if (dup2(sys->stdout_pipe[1], STDOUT_FILENO) == -1) goto bailout; /* duplicate stderr */ if (pipe(sys->stderr_pipe) == -1) goto bailout; if (dup2(sys->stderr_pipe[1], STDERR_FILENO) == -1) goto bailout; /* pipe to signal the thread to stop */ if (pipe(sys->stop_pipe) == -1) goto bailout; if (pthread_create(&sys->thread, NULL, std_logger_Thread, sys)) { ClosePipe(sys->stop_pipe); goto bailout; } return sys; bailout: std_logger_Close(sys); return NULL; }
bool CRemoteCacheLink::EnsurePipeOpen() { AutoLocker lock(m_critSec); if (InternalEnsurePipeOpen (m_hPipe, GetCachePipeName())) { // create an unnamed (=local) manual reset event for use in the overlapped structure if (m_hEvent) return true; m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (m_hEvent) return true; CTraceToOutputDebugString::Instance()(__FUNCTION__ ": CreateEvent failed"); ClosePipe(); } return false; }
int ESvnBase::ExecCommand(int Command, ExState &State) { switch (Command) { case ExChildClose: if (Running == 0 || PipeId == -1) break; ClosePipe (); { char s[30]; sprintf(s, "[aborted, status=%d]", ReturnCode); AddLine(0, -1, s); } return ErOK; case ExActivateInOtherWindow: ShowLine(View->Next, Row); return ErOK; } return EList::ExecCommand(Command, State); }
int ProcessExternalCommand (struct data * d, struct comand * c) { int status = COMMAND_OK; pid_t pid; int s = 0; pid = fork(); if (pid == -1) { perror ("Crytical error: fork did not work"); return RUN_ERROR; } if (pid == 0) ChildProcess (d, c); else { if (ClosePipe (&(d->in), &(d->out))) status = COMMAND_FAIL; } if (!d->bg) { if (d->pp) { ++ d->i; AddToPipeList (pid, &(d->plist)); } else { waitpid (pid, &s, 0); if (WIFEXITED (s)) { if (WEXITSTATUS (s) != COMMAND_OK) status = COMMAND_FAIL; } } } return status; }
bool CCacheDlg::GetStatusFromRemoteCache(const CTGitPath& Path, bool bRecursive) { if(!EnsurePipeOpen()) { STARTUPINFO startup = { 0 }; PROCESS_INFORMATION process = { 0 }; startup.cb = sizeof(startup); CString sCachePath = L"TGitCache.exe"; if (CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength() + 1), L"", nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process) == 0) { // It's not appropriate to do a message box here, because there may be hundreds of calls sCachePath.ReleaseBuffer(); ATLTRACE("Failed to start cache\n"); return false; } sCachePath.ReleaseBuffer(); // Wait for the cache to open ULONGLONG endTime = GetTickCount64()+1000; while(!EnsurePipeOpen()) { if((GetTickCount64() - endTime) > 0) { return false; } } } DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, Path.GetWinPath(), MAX_PATH); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might loose // valuable data. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 5 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. TGITCacheResponse ReturnedStatus; BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), &ReturnedStatus, sizeof(ReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, INFINITE); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); return TRUE; } else fSuccess = FALSE; } ClosePipe(); return false; }
bool CCacheDlg::EnsurePipeOpen() { if(m_hPipe != INVALID_HANDLE_VALUE) { return true; } m_hPipe = CreateFile( GetCachePipeName(), // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing nullptr, // default security attributes OPEN_EXISTING, // opens existing pipe FILE_FLAG_OVERLAPPED, // default attributes nullptr); // no template file if (m_hPipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) { // TSVNCache is running but is busy connecting a different client. // Do not give up immediately but wait for a few milliseconds until // the server has created the next pipe instance if (WaitNamedPipe(GetCachePipeName(), 50)) { m_hPipe = CreateFile( GetCachePipeName(), // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing nullptr, // default security attributes OPEN_EXISTING, // opens existing pipe FILE_FLAG_OVERLAPPED, // default attributes nullptr); // no template file } } if (m_hPipe != INVALID_HANDLE_VALUE) { // The pipe connected; change to message-read mode. DWORD dwMode; dwMode = PIPE_READMODE_MESSAGE; if(!SetNamedPipeHandleState( m_hPipe, // pipe handle &dwMode, // new pipe mode nullptr, // don't set maximum bytes nullptr)) // don't set maximum time { ATLTRACE("SetNamedPipeHandleState failed"); CloseHandle(m_hPipe); m_hPipe = INVALID_HANDLE_VALUE; return false; } // create an unnamed (=local) manual reset event for use in the overlapped structure m_hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (m_hEvent) return true; ATLTRACE("CreateEvent failed"); ClosePipe(); return false; } return false; }
CRemoteCacheLink::~CRemoteCacheLink(void) { ClosePipe(); CloseCommandPipe(); m_critSec.Term(); }
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive) { if(!EnsurePipeOpen()) { // We've failed to open the pipe - try and start the cache // but only if the last try to start the cache was a certain time // ago. If we just try over and over again without a small pause // in between, the explorer is rendered unusable! // Failing to start the cache can have different reasons: missing exe, // missing registry key, corrupt exe, ... if (((long)GetTickCount() - m_lastTimeout) < 0) return false; // if we're in protected mode, don't try to start the cache: since we're // here, we know we can't access it anyway and starting a new process will // trigger a warning dialog in IE7+ on Vista - we don't want that. if (GetProcessIntegrityLevel() < SECURITY_MANDATORY_MEDIUM_RID) return false; if (!RunTGitCacheProcess()) return false; // Wait for the cache to open long endTime = (long)GetTickCount()+1000; while(!EnsurePipeOpen()) { if(((long)GetTickCount() - endTime) > 0) { m_lastTimeout = (long)GetTickCount()+10000; return false; } } m_lastTimeout = (long)GetTickCount()+10000; } AutoLocker lock(m_critSec); DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, Path.GetWinPath(), _countof(request.path) - 1); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might loose // valuable data. // One particular situation where the shell could hang is when // the cache crashes and our crash report dialog comes up. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 10 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), pReturnedStatus, sizeof(*pReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { //OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n"); ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, 10000); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); } else { // the cache didn't respond! fSuccess = FALSE; } } if (fSuccess) { return true; } ClosePipe(); return false; }
Pipe::~Pipe() { ClosePipe(); }
bool CRemoteCacheLink::GetStatusFromRemoteCache(const CTGitPath& Path, TGITCacheResponse* pReturnedStatus, bool bRecursive) { if(!EnsurePipeOpen()) { // We've failed to open the pipe - try and start the cache // but only if the last try to start the cache was a certain time // ago. If we just try over and over again without a small pause // in between, the explorer is rendered unusable! // Failing to start the cache can have different reasons: missing exe, // missing registry key, corrupt exe, ... if (((long)GetTickCount() - m_lastTimeout) < 0) return false; STARTUPINFO startup; PROCESS_INFORMATION process; memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); memset(&process, 0, sizeof(process)); CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe"); #ifndef _WIN64 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process; fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); if (NULL != fnIsWow64Process) { BOOL bIsWow64 = false; if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { bIsWow64 = false; } if (bIsWow64) { CRegString tgitinstalled64 = CRegString(_T("Software\\TortoiseGit\\CachePath"), _T(""), false, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY); if (!CString(tgitinstalled64).IsEmpty()) sCachePath = tgitinstalled64; } } if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { ATLTRACE("Failed to start x64 cache\n"); CString sCachePath = CPathUtils::GetAppDirectory(g_hmodThisDll) + _T("TGitCache.exe"); if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { // It's not appropriate to do a message box here, because there may be hundreds of calls ATLTRACE("Failed to start cache\n"); return false; } } #else if (!CCreateProcessHelper::CreateProcessDetached(sCachePath, NULL)) { // It's not appropriate to do a message box here, because there may be hundreds of calls ATLTRACE("Failed to start cache\n"); return false; } #endif CloseHandle(process.hThread); CloseHandle(process.hProcess); sCachePath.ReleaseBuffer(); // Wait for the cache to open long endTime = (long)GetTickCount()+1000; while(!EnsurePipeOpen()) { if(((long)GetTickCount() - endTime) > 0) { m_lastTimeout = (long)GetTickCount()+10000; return false; } } } AutoLocker lock(m_critSec); DWORD nBytesRead; TGITCacheRequest request; request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS; if(bRecursive) { request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS; } wcsncpy_s(request.path, MAX_PATH+1, Path.GetWinPath(), MAX_PATH); SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED)); m_Overlapped.hEvent = m_hEvent; // Do the transaction in overlapped mode. // That way, if anything happens which might block this call // we still can get out of it. We NEVER MUST BLOCK THE SHELL! // A blocked shell is a very bad user impression, because users // who don't know why it's blocked might find the only solution // to such a problem is a reboot and therefore they might lose // valuable data. // One particular situation where the shell could hang is when // the cache crashes and our crash report dialog comes up. // Sure, it would be better to have no situations where the shell // even can get blocked, but the timeout of 10 seconds is long enough // so that users still recognize that something might be wrong and // report back to us so we can investigate further. BOOL fSuccess = TransactNamedPipe(m_hPipe, &request, sizeof(request), pReturnedStatus, sizeof(*pReturnedStatus), &nBytesRead, &m_Overlapped); if (!fSuccess) { if (GetLastError()!=ERROR_IO_PENDING) { //OutputDebugStringA("TortoiseShell: TransactNamedPipe failed\n"); ClosePipe(); return false; } // TransactNamedPipe is working in an overlapped operation. // Wait for it to finish DWORD dwWait = WaitForSingleObject(m_hEvent, 10000); if (dwWait == WAIT_OBJECT_0) { fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE); } else { // the cache didn't respond! fSuccess = FALSE; } } if (fSuccess) { return true; } ClosePipe(); return false; }
bool WhmShellProcess::run(WhmShellContext *sc) { WhmShellCommand *c = command; bool result = true; Token_t token = NULL; #ifndef HTTP_PROXY if (runAsUser) { //创建运行身份令牌 if (sc->vh==NULL) { sc->last_error = 128; return false; } token = sc->vh->createToken(result); if(!result){ sc->last_error = 129; return false; } } #endif //the commands stdout pipe PIPE_T big_stdout_pipe[2]; if (!KPipeStream::create(big_stdout_pipe)) { if (token) { KVirtualHost::closeToken(token); } return false; } //the commands stdin pipe PIPE_T big_stdin_pipe[2]; bool big_stdin_pipe_created = false; //init the std file PIPE_T hstdin = get_stdin(sc); if (hstdin==INVALIDE_PIPE && sc->in_buffer.getLen()>0) { //如果没有输入文件并且输入有数据。就要创建输入管道 if (!KPipeStream::create(big_stdin_pipe)) { //关闭打开的big_stdout_pipe ClosePipe(big_stdout_pipe[0]); ClosePipe(big_stdout_pipe[1]); if (token) { KVirtualHost::closeToken(token); } return false; } big_stdin_pipe_created = true; hstdin = big_stdin_pipe[READ_PIPE]; } PIPE_T hstdout = get_stdout(sc); PIPE_T hstderr = get_stderr(sc); PIPE_T in,out,err; err = hstderr; if (err==INVALIDE_PIPE) { err = big_stdout_pipe[WRITE_PIPE]; } PIPE_T pp[2]; for(int i=0;i<2;i++){ pp[i] = INVALIDE_PIPE; } while (c) { char **arg = c->makeArgs(sc); KCmdEnv *env = c->makeEnv(sc); pid_t pid; kfinit(pid); //set in if (c==command) { in = hstdin; } else { assert(pp[READ_PIPE]!=INVALIDE_PIPE); in = pp[READ_PIPE]; pp[READ_PIPE] = INVALIDE_PIPE; assert(pp[WRITE_PIPE]!=INVALIDE_PIPE); //close the out pipe ClosePipe(pp[WRITE_PIPE]); pp[WRITE_PIPE] = INVALIDE_PIPE; } //set out if (c->next) { //create a new pipe if (!KPipeStream::create(pp)) { if (c!=command) { ClosePipe(in); } break; } out = pp[WRITE_PIPE]; } else { //if the command is last. //then set the out to big_pipe out = hstdout; if (out==INVALIDE_PIPE) { out = big_stdout_pipe[WRITE_PIPE]; } } char *curdir2 = NULL; if (curdir) { curdir2 = sc->parseString(curdir); } result = createProcess(token,arg,env,curdir2,in,out,err,pid); if (curdir2) { free(curdir2); } if (c!=command) { //close the in pipe ClosePipe(in); } //free args for (int i=0;;i++) { if(arg[i]==NULL){ break; } free(arg[i]); } delete[] arg; if (env) { delete env; } sc->setLastPid(pid); if (!result) { sc->last_error = 127; break; } c = c->next; } //关闭输入,输出父进程无用的管道端 if (kflike(hstdin)) { ClosePipe(hstdin); } ClosePipe(big_stdout_pipe[WRITE_PIPE]); //处理输入 if (big_stdin_pipe_created) { if (result) { //创建成功才写入数据 buff *buf = sc->in_buffer.getHead(); while (buf && buf->data) { if (write_pipe(big_stdin_pipe[WRITE_PIPE],buf->data,buf->used)!=buf->used) { break; } buf = buf->next; } } //清理输入数据和管道资源 sc->in_buffer.destroy(); ClosePipe(big_stdin_pipe[WRITE_PIPE]); } //处理输出 if (result && (hstdout==INVALIDE_PIPE || hstderr==INVALIDE_PIPE)) { for (;;) { char buf[512]; int len = read_pipe(big_stdout_pipe[READ_PIPE],buf,512); if (len<=0) { break; } sc->lock.Lock(); if (sc->out_buffer.getLen() > 1048576) { //the out msg is too large.drop it. sc->lock.Unlock(); fwrite(buf,1,len,stdout); } else { sc->out_buffer.write_all(buf,len); sc->lock.Unlock(); } //fwrite(buf,1,len,stdout); } } if (kflike(hstdout)) { ClosePipe(hstdout); } if (kflike(hstderr)) { ClosePipe(hstderr); } ClosePipe(big_stdout_pipe[READ_PIPE]); if (token) { KVirtualHost::closeToken(token); } #ifdef _WIN32 if (kflike(sc->last_pid)) { WaitForSingleObject(sc->last_pid,INFINITE); } #endif return result; }
void Pipe::CreatePipe(const String &PipeName) { ClosePipe(); const UINT PipeBufferSize = 100000; DWORD dwRes; PSID pEveryoneSID = NULL, pAdminSID = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea[1]; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; SECURITY_ATTRIBUTES Attributes; HKEY hkSub = NULL; // Create a well-known SID for the Everyone group. BOOL Success = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID); Assert(Success != FALSE, "AllocateAndInitializeSid failed in Pipe::CreatePipe"); // Initialize an EXPLICIT_ACCESS structure for an ACE. // The ACE will allow Everyone read access to the key. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea[0].grfAccessPermissions = FILE_ALL_ACCESS; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance= NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID; // Create a new ACL that contains the new ACEs. dwRes = SetEntriesInAcl(1, ea, NULL, &pACL); Assert(dwRes == ERROR_SUCCESS, "SetEntriesInAcl failed in Pipe::CreatePipe"); // Initialize a security descriptor. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); Assert(pSD != NULL, "LocalAlloc failed in Pipe::CreatePipe"); Success = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); Assert(Success != FALSE, "InitializeSecurityDescriptor failed in Pipe::CreatePipe"); // Add the ACL to the security descriptor. Success = SetSecurityDescriptorDacl(pSD, TRUE, // bDaclPresent flag pACL, FALSE); Assert(Success != FALSE, "SetSecurityDescriptorDacl failed in Pipe::CreatePipe"); // Initialize a security attributes structure. Attributes.nLength = sizeof(SECURITY_ATTRIBUTES); Attributes.lpSecurityDescriptor = pSD; Attributes.bInheritHandle = FALSE; String FullPipeName = String("\\\\.\\pipe\\") + PipeName; _Handle = CreateNamedPipe( FullPipeName.CString(), // pipe name PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances PipeBufferSize, // output buffer size PipeBufferSize, // input buffer size NMPWAIT_USE_DEFAULT_WAIT, // client time-out &Attributes); // default security attribute Assert(_Handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed in Pipe::CreatePipe"); // // Block until a connection comes in // BOOL Connected = (ConnectNamedPipe(_Handle, NULL) != 0); Assert(Connected != FALSE, "ConnectNamedPipe failed in Pipe::CreatePipe"); }