Media Log

  1. win32API공부학생 at 2013.12.31 20:56 [edit/del]

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

    Reply
  2. Kim at 2021.01.26 10:50 [edit/del]

    도움이 되엇습니다. 감사합니다.

    Reply

submit

submit
윈도의 레지스트리에 무엇인가를 기록하면 항상 영구적으로 저장된다고 생각하는 사람들이 많이 있는 것 같다.
윈도는 일회용으로 레지스트리에 정보를 기록할 수 있는 방법 또한 제공한다.

RegCreateKeyEx 함수를 통해 레지스트리의 키를 생성할 때 REG_OPTION_VOLATILE 옵션을 주면 데이터를 일회용으로 저장할 수 있다.

컴퓨터가 켜져있는 동안 일회성으로 정보를 기록하고 나중에 종료될 때 지워야 할 경우를 종종 맞닥드리게 되는데, 이럴 때 해당 옵션을 사용하면 편리하다. 마치 CreateFile의 DeleteOnClose 옵션과 비슷하다고도 할 수 있겠다. 이런 옵션을 사용하지 않으면 응용이 종료될 때에 직접 데이터를 정확히 지워줘야 하며, 응용이 비정상 종료된다거나 하면 더욱 골치 아파지고 에러 처리를 하기 위해서 쓸데없는 로직을 집어 넣게 된다.

submit
MoveFileEx 함수는 파일 이름 변경이나 삭제를 컴퓨터가 재시작할 때 까지 지연시킬 수 있는 상당히 유용한 옵션이 있는데 꽤 많은 사람들이 잘 모르고 있는 것 같다.
이 옵션은 스마트 업데이터 같은 프로그램이 DLL을 교체 시켜야 한다거나 언인스톨러시 파일을 삭제해야 하는데 다른 곳에서 이미 파일이 사용중이어서 삭제할 수 없는 경우에 유용하게 쓸 수 있다.

MoveFile 함수는 내부적으로 CreateFile 함수를 통해 파일을 오픈하는데 이 때 DesiredAccess로 DELETE을 사용한다. 파일이 잘 열렸다면 RenameInformation IRP를 날린 후 핸들을 닫고 성공으로 반환하지만, 이미 다른 위치에서 파일이 열려있었다면 먼저 파일을 연쪽에서 FILE_SHARE_DELETE를 함께 주지 않았었을 경우 파일 열기가 ERROR_SHARING_VIOLATION 으로 실패하게 되어 MoveFile 함수 또한 실패로 리턴해버리게 되는 것이다.

재부팅 시에라도 dll 등을 교체시켜주거나 깨끗하게 삭제하기를 원한다면 MoveFileEx함수를 호출 할 때 세번째 파라메터로 MOVEFILE_DELAY_UNTIL_REBOOT 옵션을 주면 되는데, 이렇게 하면 MoveFileEx함수는 레지스트리의 HKLM\System\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations 위치에 어떤 오퍼레이션이었는지 정보를 적어 놓기만 하고 리턴한다. 시스템이 재부팅 되고 나서 응용프로그램들이 실행되기 전 운영체제에서 레지스트리를 확인해 보고 해당 동작을(이름변경 혹은 삭제) 수행해 주기 때문에 어떤 파일이던지 삭제가 가능하다. HKLM 위치에 써야 하기 때문에 관리자 권한은 필요하다.

이와 관련된 몇 가지 알아두면 좋을 지식들이 있다.
  • 다른 곳에서 파일을 열고 있다고 이름 변경을 못하는 것은 아니다. 먼저 파일을 연쪽에서 어떤 공유 모드로 파일을 열었는지가 중요하다. 파일을 먼저 오픈 하는 쪽에서 FILE_SHARE_DELETE옵션을 주어서 CreateFile을 하면 다른 위치에서 해당 파일의 이름을 변경 할 수 있다. 심지어는 삭제도 가능한데(DeleteFile을 호출하면 성공한다) 이때는 파일이 삭제 상태로만 마킹 되며 파일 시스템 드라이버는 해당 파일을 열어 놓은 모든 핸들이 닫힐 때 실제로 삭제를 수행한다. 이렇게 삭제 상태로 마킹되어 있는 동안에는 또 다른 곳에서 파일 오픈 시도가 생겼을 때 ERROR_ACCESS_DENIED 에러가 발생하게 된다. 파일 핸들을 닫기 전까지는 이런 DELETE_PENDING 상태의 파일을 삭제되지 않은 상태의 파일로 다시 돌리는 것 또한 가능하다.
  • 다른 한 쪽에서 파일 삭제를 허용하지 않고 먼저 파일을 열어두었을 시에, MoveFileEx에 MOVEFILE_DELAY_UNTIL_REBOOT 옵션을 주어 함수를 호출하더라도 파일 열기시 ERROR_SHARING_VIOLATION에러를 받게 되지만 이 때는 MoveFileEx 함수가 실패로 리턴하지 않고 레지스트리에 기록을 해주기 때문에, 어떤 파일이던지 간에 이름 변경이나 삭제를 할 수가 있는 것이다.
  • 함수 모양을 봤을 때 MoveFileEx나 DeleteFile처럼 HANDLE을 인자로 전달받지 않고 파일 경로를 전달 받는 함수는 모두 내부적으로 파일을 오픈한다.
  • SetFileInformationByHandle 함수를 사용하면 추가적으로 파일을 다시 열지 않고 Rename, Delete등의 작업을 할 수 있다. 이 함수는 파일 시스템 드라이버에 전달되는 IRP와 거의 비슷하게 매핑되는 아주 강력한 함수이다. 파일 속성에 대한 모든 조작은 이 함수를 통해서 할 수 있다.
    하지만 워낙 저수준의 함수이기 때문에 사용법이 조금 어렵게 느껴질 수도 있다.
    아래 글에 해당 함수를 사용하여 이름 변경을 하는 코드에 대한 설명이 있다.
    하위 디렉터리의 파일이 변경 되었는지 감지하는 법
     

submit
  1. 재호님 팬 at 2010.12.29 12:11 [edit/del]

    재호님~ 소스코드 폰트색상이 굉장히 예쁘네요
    폰트 rgb 값좀 알려주시면 안되나요?

    Reply
  2. 오곡 at 2012.12.05 00:57 [edit/del]

    정말 좋은 내용 잘보고 갑니다 ㅠㅠ

    Reply
  3. at 2013.07.21 21:49 [edit/del]

    저기 비동기식으로 감시한다는게 무슨 뜻인가요?

    Reply
  4. Mr.K at 2014.06.26 11:37 [edit/del]

    감사합니다. 파일과 관련된 처리 하다가 찾았습니다. 유용할거 같네요

    Reply
  5. BlogIcon builder at 2017.05.12 10:51 [edit/del]

    안녕하세요. 궁금한 게 있어 덧글 남깁니다ㅠ
    cbBuffer = 1048576 초기화 이유가 따로 있나용?

    Reply

submit

submit
  1. 관우 at 2011.01.05 23:15 [edit/del]

    너무 궁금했는데 이렇게 간단할 줄은 몰랐네요. ㅎㅎ 잘 배워 갑니다.

    Reply

submit
오늘 일을 하는데 윈도우즈 세션이 종료될 때 애플리케이션들에게 보내지는 윈도우 메세지가 뭐였는지 기억이 나질 않는 것이다. 옛날에 김상형씨의 winapi 사이트에서 공부할 때 봤던 것 같은 생각이 언뜻 들어 오랜만에 winapi.co.kr을 찾았다.

들어가자마자 메인 페이지에 구인 광고가 있길래 찬찬히 읽어보다가 '예쁜 여성분 우대' 에서 뿜어버리고 말았다.


winapi의 공지사항들도 한번 읽어보면 더욱 즐거워 질 것이다.

유머 감각이 있는 사람들은 아름답다.
훌륭한 해커를 가졌고, 예쁜여자까지 선호하는 저런 바람직한 회사에 많은 인재들이 지원해보기를 바란다.

아참, 궁금했던 그 메세지는 WM_QUERYENDSESSION 이었다.

'에세이' 카테고리의 다른 글

자판기 동전 교환의 비밀  (7) 2010.08.19
예스24에서 중고책 팔기  (2) 2010.05.27
김상형씨의 구인 광고  (2) 2010.05.13
인터넷 서점에서 중고책 사고 팔기  (0) 2010.05.04
제 5회 알라딘 리뷰 대회  (3) 2009.11.01
임요환의 아름다운 열정  (4) 2009.07.14
  1. 락의전사 at 2010.05.18 18:15 [edit/del]

    왜 주소가 바낐찌?
    먼가 구린게 있나보군요...
    구려 구린내가 나...

    Reply

submit