이전 포스트에서 얘기했듯이, 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. 왜 이 문제는 보고가 된 곳이 없을까?
혹시 이 문제에 대한 해결책을 아시는 분이나 실마리를 주실 수 있는 분이 계시면 답글 부탁드립니다.
꼭 해결하고 싶습니다!