/// <summary> /// 보안 특성 구하기 /// </summary> /// <returns>보안 특성</returns> private static SECURITY_ATTRIBUTE GetSecurityAttribute() { RawSecurityDescriptor descriptor = new RawSecurityDescriptor(ControlFlags.DiscretionaryAclPresent, null, null, null, null); SECURITY_ATTRIBUTE securityAttribute = new SECURITY_ATTRIBUTE(); securityAttribute.Length = (uint)Marshal.SizeOf(typeof(SECURITY_ATTRIBUTE)); securityAttribute.InheritHandle = false; byte[] byteArray = new byte[descriptor.BinaryLength]; descriptor.GetBinaryForm(byteArray, 0); securityAttribute.SecurityDescriptor = Marshal.AllocHGlobal(byteArray.Length); Marshal.Copy(byteArray, 0, securityAttribute.SecurityDescriptor, byteArray.Length); return(securityAttribute); }
private static extern SafeFileHandle CreateNamedPipe(string pipeName, uint openMode, uint pipeMode, uint maximumInstanceCount, uint outBufferSize, uint inBufferSize, uint defaultTimeOut, ref SECURITY_ATTRIBUTE securityAttribute);
////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Public #region 연결 대기하기 - WaitForConnection() /// <summary> /// 연결 대기하기 /// </summary> /// <returns>자식 파이프</returns> public NamedPipe WaitForConnection() { if (string.IsNullOrEmpty(this.pipeName) == true || this.exitEventHandle == null) { Trace.WriteLine("파이프 서비스 종료"); return(null); } NamedPipe clientPipe = new NamedPipe(); clientPipe.pipeName = this.pipeName; clientPipe.pipeDirection = this.pipeDirection; SECURITY_ATTRIBUTE securityAttribute = GetSecurityAttribute(); clientPipe.pipeHandle = CreateNamedPipe ( clientPipe.pipeName, (uint)(this.pipeDirection | PipeDirection.FILE_FLAG_OVERLAPPED), PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 255, BUFFER_SIZE, BUFFER_SIZE, 0, ref securityAttribute ); Marshal.FreeHGlobal(securityAttribute.SecurityDescriptor); if (clientPipe.pipeHandle.IsInvalid) { Trace.WriteLine("무효한 파이프 연결"); clientPipe.Dispose(); return(null); } NativeOverlapped nativeOverlapped = new NativeOverlapped(); SecurityIdentifier securityIdentifier = new SecurityIdentifier(WellKnownSidType.WorldSid, null); EventWaitHandleSecurity eventHandleSecurity = new EventWaitHandleSecurity(); bool created; eventHandleSecurity.AddAccessRule(new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.FullControl, AccessControlType.Allow)); eventHandleSecurity.AddAccessRule(new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.ChangePermissions, AccessControlType.Deny)); using (EventWaitHandle eventHandle = new EventWaitHandle(false, EventResetMode.ManualReset, null, out created, eventHandleSecurity)) { nativeOverlapped.EventHandle = eventHandle.SafeWaitHandle.DangerousGetHandle(); ConnectNamedPipe(clientPipe.pipeHandle, ref nativeOverlapped); int lastError = Marshal.GetLastWin32Error(); if (lastError == 997) { int completeCode = 0; IntPtr[] waitHandleArray = new IntPtr[] { eventHandle.SafeWaitHandle.DangerousGetHandle(), this.exitEventHandle.SafeWaitHandle.DangerousGetHandle() }; completeCode = WaitForMultipleObjects(waitHandleArray.Length, waitHandleArray, false, -1); if (completeCode == 0) { } else if (completeCode == 1) { Trace.WriteLine("파이프 서비스 종료 (리소스 해제)"); clientPipe.Dispose(); return(null); } } else if (lastError != 535) { Trace.WriteLine("파이프 연결 에러 : " + lastError); clientPipe.Dispose(); return(null); } else { Debug.WriteLine("연결되었습니다."); } } clientPipe.needToDisconnect = true; FileAccess fileAccess = GetFileAccess(clientPipe.pipeDirection); clientPipe.pipeStream = new FileStream(clientPipe.pipeHandle, fileAccess, (int)BUFFER_SIZE, true); if (clientPipe.pipeStream == null) { Trace.WriteLine("파이프 파일 스트림이 null 입니다."); clientPipe.Dispose(); return(null); } return(clientPipe); }