9월, 2015의 게시물 표시

Windows Vista 이상의 환경에서 Service에서 interactive process 실행하기.

Windows Vista 이상의 환경에서 LocalSystem account context에서 돌아가는 Service에서 interactive process를 실행하는 방법에 대해 포스팅해보도록 하겠다. 이것 저것 많은 자료를 보면서 이해했다 ㅠㅠ 일단 Windows에서의 세션, 스테이션, 데스크탑에 대해서 이해해야한다. http://www.brianbondy.com/blog/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops  (원본) http://www.benjaminlog.com/160  (번역본) 위 링크를 일단 읽으면 세션, 스테이션, 데스크탑이 뭔지에 대해서 알 수 있다. 그리고  http://cappleblog.co.kr/m/post/241  이 것도 보면 좋을 것 같다. access token 에 대해서도 알아야한다. http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx 그리고 위 링크에서 내가 오늘 포스팅하려는 내용에 대해 설명하고 있다. 좀 더 친절하게 정리해서 내가 써보려고한다. 1. 현재 로그인하고 있는 다른 유저와 상호작용하는 process를 실행하고 싶은 경우   우선 로그인하는 있는 다른 유저가 로컬이라고 가정을 해보겠다. 서비스는 세션0에서 동작하고 있다. 그렇기 때문에 직접적으로 현재 로컬에서 로그인하고 있는 다른 유저의 세션에 접근할 수는 없다.  그래서 일단   WTSGetActiveConsoleSessionId   () 를 통해서 로컬에서 로그인되 '활성화' 되어 있는 유저의 세션id를 얻어야한다.  그리고  WTSQueryUserToken  () 를 통해서 세션id

도메인에 자신이 만든 네임서버를 연결시킬 때 네임서버등록과 호스트등록이 둘 다 필요한 이유

이미지
나는 taeguk.me 라는 도메인을 보유하고 있는데 이 도메인에 내가 만든 네임서버를 등록하려는데 자꾸 호스트가 등록되지 않았다는 메시지가 뜨면서 실패하였다. 알고보니 도메인업체 사이트에서 호스트등록 메뉴에서 네임서버를 등록해야했다. 결국 ns.taeguk.me를 호스트등록함으로서 문제를 해결했다. 근데 왜 네임서버 등록은 왜 아이피주소가 아닌 ns.taeguk.me 와 같은 식으로 해야하고, 굳히 호스트 등록을 해야하는지 의문이 들었다. 이에 대한 해답은 nameserver 설정파일을 통해 답을 내릴 수 있었다.   위를 보면 .(루트)의 서브도메인에 대한 NS를 A,ROOT-SERVERS.NET. 과 같은 식으로 지정해주고 있는 것을 알 수 있다. 그리고  A,ROOT-SERVERS.NET. 의 Address를 198.41.0.4와 같은 식으로 지정하고 있다. 이때 NS를 지정하는 것은 도메인업체 사이트에서 "네임서버 설정" 에 해당하는 부분이고, NS에 대한 ip address를 A레코드를 이용해 지정하는 것은 도메인업체 사이트에서 "호스트 등록"에 해당하는 부분이다. 즉 taeguk.me. 도메인에 대해서 네임서버를 ns.taeguk.me.로 설정한다면 taeguk.me. IN NS ns.taeguk.me. 라는 세팅이 me. 도메인의 네임서버에 추가될 것이다. (아마?) 그리고 ns.taeguk.me. 에 대해 호스트등록을 한다면 ns.taeguk.me. IN A 123.123.123.123 라는 세팅이 me. 도메인의 네임서버에 추가될 것이다. (아마?) 그러면 왜 네임서버 등록에서 아이피주소로 등록할 수 없는 지에 대한 해답이 나온다. ip address는 A레코드에서만 설정할 수 있기 때문이다. 따라서 무조건 글루레코드를 이용해야만 하는 것이다. 그러면 만약 taeguk.me. 에 대한 네임서버가 ns.hello.com. 이라

Overlapped IO 할 때 주의해야 할 점.

이미지
Overlapped IO 를 할 때는 무조건 OVERLAPPED 구조체의 Offset, OffsetHigh 에 file offset을 넣어줘야한다.   1번째는 여러개의 IO가 동시에 진행되니까 당연히 OVERLAPPED 구조체의 Offset을 통해 IO가 진행될 file offset을 당연히 지정해줘야만 하다고 생각하였다. 하지만 2번째의 경우에는 각각의 IO가 동시에 1개씩 밖에 실행이 안된다. 즉 비동기 IO가 동기화되어있는 셈이다. 따라서 그냥 Offset에 0을 넣어도 상관없을거 같기도하고 아닌거 같기도 하고 해서 직접 실험을 해보았다. 실험 결과 2번째도 1번째랑 똑같은 결과가 나왔다. 즉 OVERLAPPED구조체의 Offset은 말그대로 파일 오프셋을 의미하는 것이였다. 나는 가장 최근의 비동기IO가 완료된 시점의 파일 오프셋을 Base로 했을 때의 Offset을 의미하는 게 아닐까 생각했었는데 아니였다. 그냥 파일 오프셋 자체였다. 정리하자면  Overlapped IO 를 할 때는 무조건 OVERLAPPED 구조체의 Offset, OffsetHigh 에 file  offset을 넣어줘야한다.

IIS에서 FTP열기 문제 (cuz passive mode, FTP 방화벽 지원)

IIS에서 ftp세팅을 하고나서 외부에서 연결을 하려고 하니 접속이 안됐다. 깜박하고 IIS에서 FTP방화벽 지원을 안한 것이다 ㅠㅠ IIS에서 FTP passive mode를 지원하기 위해서는 FTP 방화벽 지원에서 사용할 포트 범위를 설정하고, 인바운드 방화벽에서 그 포트범위에 대해서 허용규칙을 추가한다. http://livegs.tistory.com/33

[Windows Via C/C++][1장 에러 핸들링] FormatMessage가 format message를 얻는데 실패하는 경우

ErrorShow 예제 어플리케이션 코드를 보면 FormatMessage가 format message를 얻는데 실패했을 경우에 대한 처리가 있다. 실패할 수 있는 이유는 FORMAT_MESSAGE_FROM_SYSTEM 일때, 모든 error code에 대한 error message를 얻을 수 있는게 아니기 때문이다.  2번째 링크에서 알 수 있다시피 FORMAT_MESSAGE_FROM_SYSTEM에서 얻을 수 있는 것은 System Error Messages 뿐이다.  winerror.h에 모든 error code가 존재하지는 않는 것처럼 system message table에 모든 error message string이 존재하지는 않는다. 예를 들어 network error에 대한 error code는 lmerr.h에 정의되어있고 이에 대한 message table는 netmsg.dll에 있다. 따라서 책의 예제 코드에서  FORMAT_MESSAGE_FROM_SYSTEM  에서 실패 했을 경우에 netmsg.dll 의 모듈핸들을 얻어서 이를 이용해서 format message 획득을 시도해보는 것이다. 물론 책에 있는 예제도 완벽한 것은 아니다. 책의 예제프로그램에서는 netmsg.dll에도 없는 error message에 대해서는 출력해주지 못한다. http://blogs.msdn.com/b/oldnewthing/archive/2008/09/01/8914664.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa370285(v=vs.85).aspx https://www.rpi.edu/dept/cis/software/g77-mingw32/include/lmerr.h

Windows Asynchronous Notification IO Model

Asynchronous Notification IO Model 이란 IO의 notification이 비동기로 이루어지는 것. 즉 IO이벤트 발생을 비동기적으로 확인하는 모델이다. 즉 IO이벤트 관찰 함수를 호출하는 시점과 IO이벤트 확인의 시점이 다른 비동기적인 모델이다. (내 생각에)  리눅스의 epoll과 거의 흡사하다. (코드도) 근데 사용하기는 epoll이 더 편하지 않나 싶다. select는 Synchronous Notification IO Model 이다. 근데 중요한 게 select를 Asynchronous Notification IO Model로 착각하면 안된다. 물론 select의 timeout을 0으로 둬서 비동기방식으로 사용할 수는 있지만 이는 select자체를 생각해볼 때 옳지 않은 방법이다. select는 매 함수 호출마다 file descriptor들의 event를 등록해야하는데 만약 비동기방식처럼 사용하려면 매우 비효율적이기 때문이다. (IO event가 발생하지 않았을 경우 다시 file descriptor들의 event를 등록해야하기 때문) 따라서 select는 asynchronous방식처럼 사용할 수는 있지만 비효율적이고, 애초에 생겨먹은(?)게 Synchronous이다. 그에 반에 epoll과 윈도우의 WSAEventSelect/WSAAsyncSelect같은 경우는 비동기 notification IO model 이다. select와 달리 관찰할 file descriptor 혹은 handle을 한번만 등록해 놓고 다른 일을 하다가 IO notification을 확인 할 수 있기 때문이다. 즉 epoll과  윈도우의 WSAEventSelect/WSAAsyncSelect 는 IO notification의 관찰을 비동기로 명령해놓고, 다른 일을 하다가 IO event의 확인을 해볼 수 있기 때문에 Asynchronous Notification IO Model이고, select는 함수 호

The reason why using non-blocking fd in edge triggered epoll

오랜만에 다시 epoll보니까 헷갈려가지고 정리해봅니다. level triggered 방식에서 read할 경우에는 buffer에서 전부 read하지 않아도 다음 epoll_wait에서 또 이벤트가 등록되기 때문에 다시 read할 기회를 얻을 수 있다. 그러나 edge triggered 방식에서는 input buffer에 data가 수신됬을 때만 read할 기회를 갖기 때문에 EAGAIN일때까지 계속 반복해서 수신을 해줘야한다. 이 때 만약 file descriptor가 blocking mode라고 했을 때, read할 data가 buffer에 없으면 read는 blocking 상태에 빠지기 때문에 문제가 된다. 따라서 edge triggered 방식에서는 반드시 file descriptor가 non-blocking mode 여야만 한다. 그래야지만 read가 위의 상태에서도 blocking상태에 빠지지않고  EAGAIN을 errno에 넣어주면서  바로 반환되어서 수신이 끝났다는 것을 알아차릴 수 있다. 이러한 edge triggered 방식의 특징때문에 edge triggered 방식의 epoll에서는 반드시 file descriptor가 non-blocking mode이여야만한다.