이전 포스트에서 얘기했듯이, Notepad2-mod엔 묘한 버그가 하나 있다.

32비트 어플리케이션에서 64비트 Notepad2-mod로 드래그앤드롭을 하면 오류가 발생한다는 것이다.


½h 라는 파일을 대체 누가 만들라고 한 게냐?


이 문제는 사실 몇 가지 조건이 만족되는 경우에만 발생한다.


1. Windows 8.1에서만 발생함 (Win7은 발생하지 않고, Win8은 확인하지 못함)

2. 32비트 Shell에서만 발생함 (Total Commander, XYplorer 등)

3. Visual Studio, ICL 로 컴파일할 때만 발생함 (WDK에선 발생하지 않음)


무엇이 문제인지 분석하기 위해 드래그앤드롭을 처리하는 부분의 소스를 찾아봤다.


    case WM_DROPFILES:

      {

        HDROP hDrop = (HDROP)wParam;

        WORD wPathnameSize;

        WCHAR *szBuf;


        if (IsIconic(hwnd))

          ShowWindow(hwnd,SW_RESTORE);


        wPathnameSize = DragQueryFile(hDrop,0,NULL,0)+1;

        szBuf = (WCHAR*)malloc(sizeof(WCHAR)*wPathnameSize);

        DragQueryFile(hDrop,0,szBuf,wPathnameSize);


        if (PathIsDirectory(szBuf)) {

          WCHAR tchFile[MAX_PATH];

          if (OpenFileDlg(hwndMain,tchFile,COUNTOF(tchFile),szBuf))

            FileLoad(FALSE,FALSE,FALSE,FALSE,tchFile);

        }


        else

          FileLoad(FALSE,FALSE,FALSE,FALSE,szBuf);

        free(szBuf);

        

        if (DragQueryFile(hDrop,(UINT)(-1),NULL,0) > 1)

          MsgBox(MBWARN,IDS_ERR_DROP);


        DragFinish(hDrop);

      }

      break;


문제가 되는 부분은 10행, 12행이다.

DragQueryFile() 함수는 드롭한 파일의 갯수를 읽거나 파일명 자체 및 파일명의 길이를 읽는 함수다.

파라미터를 위와 같이 지정하면 파일명의 길이를 읽어들이는데, 이게 위의 조건에선 0을 리턴한다.


그러니, 이후부터 들어있는 malloc() 등에선 뻘짓만을 할 뿐이다.


MSDN이나 구글 등에서 Windows 8.1의 드래그앤드롭 문제를 찾아봐도 이 부분에 대한 얘긴 없다.

죄다 권한 상승에 대한 얘기만 나오는데, 권한 문제가 생기면 아예 WM_DROPFILES 메시지가 발생하지 않는다.


이 경우는 WM_DROPFILES 메시지는 발생하지만, 파일명이 읽어지지 않으니, 전혀 다른 문제다.

물론, Shell과 Notepad2-mod 모두를 관리자 권한으로 실행시켜도 같은 문제는 계속 발생한다.



내가 이해가 가지 않는 건 아래와 같다.


1. 왜 Windows 7에선 발생하지 않던 문제가 Windows 8.1에선 발생했을까? 즉, OS의 버그일까?

2. 왜 같은 소스를 WDK로 컴파일했을 땐 문제가 없을까? 즉, 컴파일러들의 버그일까?

3. 왜 이 문제는 보고가 된 곳이 없을까?



혹시 이 문제에 대한 해결책을 아시는 분이나 실마리를 주실 수 있는 분이 계시면 답글 부탁드립니다.

꼭 해결하고 싶습니다!



신고
  1. 無名 2016.08.07 15:32 신고

    눈으로 봐선 UINT가 WORD로 변환되지 않는 거 같은데...
    죄송합니다. 64비트 컴파일 할 줄 몰라서리..여기까지만..

    unsigned short WORD;
    unsigned int UINT;

    UINT DragQueryFile(
    _In_ HDROP hDrop,
    _In_ UINT iFile,
    _Out_ LPTSTR lpszFile,
    UINT cch
    );

  2. 無名 2016.10.29 17:54 신고

    다음 링크를 발견.....
    https://github.com/notepad-plus-plus/notepad-plus-plus/issues/2487
    따라가 보니...
    http://stackoverflow.com/questions/39612616/drag-and-drop-from-32-to-64-bit/39664759#39664759
    정확하게 이거 같은데...
    잘 모르겠음.

+ Recent posts