Media Log

VSColorOutput은 비주얼 스튜디오 2010 플러그인이다.

출력창에 나타나는 문자열들을 분석해서 예쁜 색깔로 구분지어 보여준다. 기본 필터 기능에 더해 사용자가 자신만의 필터를 등록할 수 있도록 정규 표현식을 추가할 수 있는 인터페이스도 갖추고 있다.


예쁘지 아니한가.

Visual Studio 이전 버전들도 모두 훌륭하다고 생각하지만 Visual Studio 2010은 좀 더 특별하다. 이런 좋은 확장 기능들이 많이 있는데다가 무엇보다 C++11을 사용할 수 있기 때문에.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit
코드잡이라는 사이트가 생겼다.
스택오버플로우의 시스템을 거의 본따서 만들었는데, 아직 디테일한 부분에서는 부족해보이지만 많은 사람들이 사용을 해서 멋진 개발자들의 놀이터가 될 수 있었으면 좋겠다.

스택오버플로우와 완전히 똑같지는 않고 페이스북 같은 소셜 기능도 넣었는데, 이는 참신해 보이기도 하지만 커뮤니티의 전체적인 분위기가 약간 가볍게 흘러가지는 않을까 걱정이 되기도 한다. 하지만 어떻게 될지는 지켜봐야 알 일이다.
부디 양질의 질문/답변들이 많이 쌓여서 많은 개발자들에게 도움이 되는 사이트가 되었으면 한다.
저작자 표시 비영리 동일 조건 변경 허락
신고
  1. Favicon of http://talkprogram.tistory.com BlogIcon 로로님 at 2012.01.19 20:40 신고 [edit/del]

    우와! 한국에도 이런게 생겼네요.ㅎㅎ (원래있엇나/..)

    Reply
  2. Favicon of http://blog.naver.com/empty_wagon BlogIcon 주의사신 at 2012.05.14 09:11 신고 [edit/del]

    저도 하나 만들고 있었고 내일(5월 15일) 공개할 예정이었는데, 경쟁자(?)가 있었군요...

    3달 만든 것이라 별 기능이 없어서 대대적으로 홍보할 상황이 못 됩니다만...

    Reply
    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2012.05.14 10:07 신고 [edit/del]

      헉 그런가요? 기대가 됩니다.
      참, 저는 몇 일전에 알았는데 http://askbot.org 라는 곳에서 어떤 친구들이 스택오버플로 클론을 오픈소스로 만들고 있더라구요. 리치 텍스트에디터가 스택오버플로만큼 깔끔하게 돌아가지는 않지만 그럭 저럭 쓸만은 한 것 같아요. 이미 알고 계셨나요?
      커뮤니티가 잘 운영되기를 진심으로 바랍니다.

    • Favicon of http://blog.naver.com/empty_wagon BlogIcon 주의사신 at 2012.05.15 09:59 신고 [edit/del]

      최후의 버그들 몇 개 잡고 오늘 오픈했습니다. 질문의 수정, 삭제도 안 되는 매우 서글픈 상태의 프로그램입니다만, 하나씩 계속 꾸준히 추가해 나갈 예정입니다.

      http://nullpointr.com/

      더 좋은 사이트가 될 수 있도록 많은 도움 부탁 드립니다.

      http://www.facebook.com/nullpointrcom

    • Favicon of http://www.benjaminlog.com BlogIcon 김재호 at 2012.05.15 10:33 신고 [edit/del]

      네에 지금 가서 구경하고 오는 길입니다. 깔끔하게 잘 만드셨네요. 가입절차도 간편해서 좋고요. 중요한 몇몇 기능들이 조금 더 추가되어 좋은 커뮤니티가 되었으면 합니다.

submit
파일을 열 때 파일 포인터는 0으로 셋팅된다. 이후 해당 파일에 ReadFile이나 WriteFile등의 함수를 통해서 I/O를 하게 되면 파일 포인터가 자동으로 증가하게 된다. 물론 윈도우는 사용자가 직접 오프셋을 조정할 수 있는 인터페이스도 제공해주는데 SetFilePointer 함수가 바로 파일 포인터를 이동 시키는 인터페이스이다.
파일 포인터는 각 핸들별로 따로 관리된다. 즉 같은 파일이라 할지라도 2번을 열어서 핸들을 2개 가지고 있다면 각 핸들에 연결된 파일 포인터는 각각 독립적으로 움직인다.

이 SetFilePointer는 너무 복잡하게 만들어진 함수이다. 그래서 제대로 사용하기가 어렵다. 지금까지 내가 SetFilePointer 함수를 사용하는 코드를 보았던 곳에서는 제대로 작성된 코드가 거의 없었던 것 같다. 그렇다면 어떤 부분이 그렇게 SetFilePointer의 사용을 힘들게 만드는 것일까?

SetFilePointer 함수는 다음과 같이 생겼다. 32비트와 64비트를 동시에 지원하기 위해 2번째 인수와 3번째 인수를 통해 각 4바이트씩 총 64비트 만큼의 오프셋 정보를 전달할 수 있도록 만들어졌다.

DWORD WINAPI SetFilePointer(

  __in         HANDLE hFile,

  __in         LONG lDistanceToMove,

  __inout_opt  PLONG lpDistanceToMoveHigh,

  __in         DWORD dwMoveMethod

);

첫번째로 많이 하는 실수는 오프셋이 32비트 크기를 넘어갈 수 있는 경우에도 항상 lpDistanceToMoveHigh 에 NULL을 넣고 있는 경우이다. 4기가보다 큰 파일에 대해서 제대로 지원하지 못하는 경우인데 오래 전에 작성된 코드에서 흔히 볼 수 있다.
두번째. SetFilePointer의 리턴값은 변경된 오프셋 값이며 함수가 실패할 경우에는 INVALID_SET_FILE_POINTER 를 돌려주게 된다. INVALID_SET_FILE_POINTER의 값은 -1로 정의되어 있고, 이 값은 DWORD로 받아지기 때문에 0xFFFFFFFF가 된다. 그런데 만약 내가 변경하고 싶었던 위치가 0xFFFFFFFF(4기가) 였다면? 사용자는 0xFFFFFFFF위치로 오프셋을 옮겨줄 것을 요청했고 함수는 사용자가 원한 동작을 제대로 수행한 뒤 0xFFFFFFFF를 리턴했다. 이제 이 값이 에러인지 정상적인 오프셋 값인지 어떻게 구분해야할까? 사용자는 이를 확인해보기 위해서 반드시 GetLastError를 호출해야 한다. 만일 함수가 성공했고 제대로된 오프셋이라면 LastError가 ERROR_SUCCESS로 셋팅되어 있을 것이다. 지난 번에 윈도의 LastError값은 오직 함수가 실패할 때만 셋팅된다고 했었는데, SetFilePointer와 같은 몇몇 특별한 함수에서는 성공시에도 값을 0으로 만들어 준다. 물론 그렇게 하는 이유는 위처럼 리턴값만으로는 모든 정보를 전달해줄 수가 없기 때문이다.

따라서 SetFilePointer를 사용하는 곳에서는 다음 표에 있는 것처럼 리턴값을 확인해야 한다.

  If lpDistanceToMoveHigh == NULL If lpDistanceToMoveHigh != NULL
If success retVal != INVALID_SET_FILE_POINTER retVal != INVALID_SET_FILE_POINTER || GetLastError() == ERROR_SUCCESS 
If failed retVal == INVALID_SET_FILE_POINTER retVal == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS
많은 사람들이 틀리게 사용할 만도 하다.

이제 내가 하고 싶었던 말을 정리하면,
  • SetFilePointer 함수를 사용한 곳을 보게 되면 위 내용을 유심히 살펴보는 것도 재미있다. 그리고 코드가 틀렸다면 바르게 고쳐라.
  • 위 표에 나온대로 고치려고 하지말고, SetFilePointerEx를 사용해서 고치는 것이 좋다.
  • GetFileSize 함수도 역시 비슷한 문제가 있다. GetFileSizeEx만 사용해라

다음은 프로그래밍 센스를 확인해 볼 수 있는 간단한 퀴즈이다.
윈도에는 SetFilePointer와 SetFilePointerEx라는 함수는 존재하지만 GetFilePointer라는 함수는 존재하지 않는다. 그렇다면 윈도에서 현재 가지고 있는 핸들의 파일 포인터의 오프셋은 어떻게 구할 수 있을까?

저작자 표시 비영리 동일 조건 변경 허락
신고
  1. win32API공부학생 at 2013.12.31 20:56 신고 [edit/del]

    SetFilePointer함수의 리턴값을 잘못사용하고 있었네요ㅠㅜ 좋은정보감사합니다!

    Reply

submit
시작하세요! 맥 OS X 라이언 - 8점
로빈 윌리엄스 & 존 톨렛 지음, 이대엽 옮김, 김태영 감수/위키북스
맥북 에어가 한 대 생겨서 좀 써보려고 하는데 도대체 뭘 어떻게 쓰는건지 알 수가 있어야지. 그래서 책을 보고 공부하기로 했다. 나는 아직까지 인터넷보다는 책으로 공부하는 것을 선호한다. 맥 라이언 책들이 수두룩하게 있었는데 이 책이 가장 좋아보이고 역자 이름이 눈에 익어서 이걸로 선택을 했다.

응용 프로그램들에 대한 설명은 대충대충 보고 넘어가고, 맥 OS X 전체적인 공통 인터페이스나 파인더 셋팅, 미션컨트롤과 같은 부분들은 하나씩 따라하면서 꼼꼼히 읽어보았다. 그림들이 컬러로 되어있고 폰트들이 아주 맘에 들어서 좋았다.
한 달여 동안 집에서 쿠분투를 꺼놓고 맥북만을 사용했는데 덕분에 이제는 꽤 익숙한 사용자가 되었다.

나는 애플 Hater라고 말할 수 있다. 지금까지 애플 제품을 한번도 사서 써본 적이 없었는데, 다른 이유는 없고 그냥 그네들이 돈을 너무 비싸게 받아먹기 때문이었다. 주위에서 애플 제품이 끝내주게 좋다고 말하는 사람들이 너무나도 많아져서 얼마나 좋은지 나도 한번 써보고 싶었다. 한번 써보면 윈도우로 다시 돌아가지 못한다나 어쩐다나. 멀티 터치 같은 트랙패드 기능들은 정말 훌륭해서 매번 감탄하고 있다. 세 손가락 드래깅으로 창을 이동시키는 것이 너무 익숙해져서 다른 노트북을 만질 때마다 몹시 불편함을 느낀다. 하지만 사람들이 말한 정도로 맥 OS X가 끝내준다고 생각되지는 않는다. 처음 보는 사람들도 한눈에 직관적으로 사용법을 알 수 있다고 하는데, 아니, 옵션키를 눌러야 메뉴에 새로운 아이템이 추가되는 것을 누가 설명서도 안 읽어보고 알아챌 수 있겠는가.
무엇보다 쓸만한 응용들이 윈도우즈에 비해 턱 없이 부족하다. 그래도 우분투보다는 낫지만.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit

윈도우즈를 잘 이해하기 위해서는 레지스트리와 친해져야 한다. - Jeffery RichterWindows via C/C++ 중에서

한 때 이 글을 읽고 레지스트리를 다루는 책을 도서관에서 몽땅 빌려서 읽었던 적이 있다. 어느 정도 숙달이 되어 레지스트리 에디터를 열면 빛의 속도로 트리를 탐색해 나갈 수 있었는데, 작년에 회사를 그만두고 2달여를 집에서 쉬다가 다시 새로운 회사에 들어갔을 때 나의 이 능력이 마법처럼 사라져 버렸다는 것을 깨닫게 되었다. 아쉬운 일이다.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit
GetLastError는 윈도 Api를 호출 한 뒤 해당 함수의 Win32 에러 코드를 받아오기 위한 함수이다. 이 오류 정보는 쓰레드별로 하나만 저장되기 때문에 함수가 실패한 후 다른 함수를 실행하기 전에 에러 값을 읽어와야 한다. 다른 함수들이 호출된 이후에는 에러 값이 덮어 씌워져 버릴 수 있다.

보통은 아래와 같이 사용한다.
HANDLE h = CreateFile(...);
if (h == INVALID_HANDLE_VALUE)
{
  DWORD dw = GetLastError();
  ... Do something
}

경험이 많지 않거나 주의 깊지 않은 프로그래머들은 프로그램을 유지보수 하면서 이미 잘 만들어져있던 위와 같은 코드를 별 생각 없이 아래처럼 바꾸기도 한다.
HANDLE h = CreateFile(...);
if (h == INVALID_HANDLE_VALUE)
{
  DoSomethingElse(); // 뭔가 예외를 처리하기 위해 추가적인 코드를 여기에 쑤셔넣는다. 아니, 왜 하필 여기에.
  DWORD dw = GetLastError();
  ... Do something
}
처음에 말했듯이 DoSomethingElse()안에서 윈도 Api를 사용한다면 쓰레드 저장소에 있던 LastError 코드가 다른 값으로 바뀌어버릴 수 있다는 것을 예상할 수 있다. 항상 코드를 읽으면서 GetLastError를 호출하는 부분이 에러값을 확인하려고 했던 함수의 바로 아래에 붙어있지 않다면 섬뜩함을 느껴야 한다. 하지만 잘 모르고 있으면 보이지 않는 법.

HANDLE h = CreateXXX(...);
DWORD dw = GetLastError();
if (dw == ERROR_SUCCESS)
{
  ... 핸들을 가지고 다른 무엇인가를 한다.
}
else
{
  ... 함수의 실패처리를 한다.
}
이번에는 한 Api를 호출 한 뒤에 바로 GetLastError를 호출해서 에러값을 얻어왔다. 얼핏보면 맞는 것도 같지만 역시 틀린 코드이다. 함수의 성공 실패 여부는 함수의 스펙에 따라 리턴 값 등으로 확인해야지 GetLastError 값으로 확인해서는 안된다. 왜냐하면 Win32에서 제공되는 대부분의 Api들이 함수가 성공했을 때는 LastError 값을 건드리지 않기 때문이다. 위 코드에서는 함수가 성공할 때는 에러 값도 0(ERROR_SUCCESS)으로 셋팅시켜 줄 것이라 굳게 믿고 있다. 실상은 그렇지 않다. GetLastError는 오직 함수가 실패했을 때만(그 바로 직후에) 호출해야 한다.

대부분의 함수들은 그 성공 여부를 리턴값으로 가르쳐준다. 리턴 값으로 성공과 실패 여부를 호출자에게 전달해주기로 했다면 뭐하러 또 SetLastError(ERROR_SUCCESS) 와 같은 추가적인 코드를 호출하겠는가.
하지만 어떤 함수들은 성공시에도 SetLastError(ERROR_SUCCESS)를 정확히 호출해주기도 하는데, 이것에 대한 이야기는 다음 포스트에서 해보려고 한다.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit
Sparse 파일을 만드는 것은 Win32 Api로서 제공되지는 않으며, 파일 시스템이 인터페이스를 제공한다.
콘트롤 코드를 파일 시스템 장치에 직접 보냄으로써 Sparse 파일을 만들어 낼 수 있다.

HANDLE h = CreateFileW(
    L”D:\\MySparseFile.TXT”,
    GENERIC_WRITE,
    FILE_SHARE_DELETE,
    0,
    CREATE_NEW,
    0,
    0
);

if(!DeviceIoControl(
    h,
    FSCTL_SET_SPARSE,
    NULL,
    0,
    NULL,
    0,
    &dwWritten,
    NULL))
{
    dwError = GetLastError();
    return dwError;
}

Sparse파일을 만들게 되면, 파일 포인터를 충분히 크게 이동하고 SetEndOfFile을 호출해도 실제로 데이터를 기록하지 않으며(그러므로 SetEndOfFile이 금방 반환된다) 나중에 파일의 해당 부분을 읽을 때 파일 시스템이 해당 부분의 데이터는 0으로 돌려주게 된다. WriteFile 같은 함수를 통해 실제로 데이터를 쓰는 경우에만 디스크의 용량을 차지하게 되는 이점이 있는데, 버추얼 박스나 VMware에서 생성하는 커다란 동적 하드 디스크를 구현 할 때 이런 방법을 사용하면 된다. -처음에 가상 디스크의 용량을 크게 잡아둬도 실제 하드 디스크 용량을 차지하지 않다가, 사용하면 할수록 하드 디스크의 사용량이 늘어나는 것을 본 적이 있을 것이다.

윈도에 인스톨 될 수 있는 모든 파일 시스템이 Sparse 파일을 지원한다고 가정해서는 안된다. FAT이나 다른 벤더에서 만든 인스톨러블 파일 시스템은 Sparse 기능을 지원하지 않을 수도 있다. Sparse 기능이 지원되는지 알아보기 위해서는 GetVolumeInformation 함수를 사용한다.
FAT 파일 시스템도 Sparse파일을 지원하지 않는데, 그러므로 NTFS상의 Sparse 파일을 FAT 볼륨으로 복사하게 되면 FAT볼륨에서는 더 이상 공간이 절약되지 않는다. (실제로 0을 디스크에 써버릴 것이다.)
Sparse 파일에서 실제로 디스크에 저장된 용량을 알고 싶을 때는 GetCompressedFileSize 함수를 사용하면 된다.

저작자 표시 비영리 동일 조건 변경 허락
신고
  1. Favicon of http://blog.spowner.com BlogIcon spowner at 2012.01.06 13:29 신고 [edit/del]

    유용한 정보 감사합니다

    Reply
  2. gcd at 2012.02.22 06:52 신고 [edit/del]

    계속해서 좋은 글 감사합니다. 재미있게 읽고 있습니다.
    다른 포스트까지 읽으면서 느낀 점이지만, 구조체 정렬까지 고려해서 reserved 인수를 때려박는 MS가, 어째서 GetCompressedFileSize() 인터페이스를 왜 GetFileSize()처럼 해놨을까요? -_-;
    Ex 붙은 버전도 넣어주든가(..)

    Reply

submit
위대한 해커이자 이제는 소설가(?)이기도한 윈도의 대가 마크 러시노비치의 처녀작이다.
책이 처음 나왔을 때부터 재미는 있으려나, 기술적으로 배울만한 것도 있을까 관심을 가지고 있었는데, 영어로 읽기는 싫으니 번역되는 날만을 기다렸다. 그런데 오늘 드디어 떴구나! 새해 선물인가.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit
NTFS에서 만들 수 있는 단일 파일의 가장 큰 크기는? 16테라. 빙고.
그럼 NTFS 상에서 16 테라 바이트의 파일을 만들기 위해서는 얼마나 시간이 걸릴까?

답은 여기에 있다.

16TB 라는 숫자의 이미지가 머리 속에 잘 안그려져서 내 추정보다 훨씬 큰 기간이 나와버렸는데, 가만히 계산해보니 그렇게 놀라운 숫자도 아니다. 16TB라는 숫자를 너무 얕봤나보다.
저작자 표시 비영리 동일 조건 변경 허락
신고

submit