VC6 에서 VS2005로 옮기기
2007/02/13 12:54

Vista도 그렇고 새로나온 SDK 때문에도 그렇고...
딱히 VC6에서 개발 못할 것도 없지만서도 개발환경을 VS2005로 전부 converting 하여야 겠다고 마음먹고 작업을 하려고 보니...
이것저것 쓰경쓰이는게 한두가지가 아니다.
일단 VC6 프로젝트를 VS2005에서 자동으로 변환하지 않고...
일일이 수작업으로 복사해서 붙여넣고 빌드했다...하는김에 /Wp64 옵션을 켜놓았더니 포인터에 대한 문제도 발생...
나름대로 정리하자면...

1. Secure Function
수많은 warning C4996 : deprecated 경고
일부 CRT 함수들이 보안이 강화된 함수(Secure Function)를 기존 함수를 대신하여 사용하라는 경고 문구...
간단하게 _s 만을 붙이면 될듯하지만 그게 그렇지 않다.
복사할 영역의 크기도 지정해주어야 하는데 이게 그렇게 간단하게 생각할 문제가 아니다.
보다 자세한 내용은 아래 링크 참조하자.
김명신님의 Secure Function에 관한 글 보러가기

굳이 Secure Function을 사용하고 싶지 않다면 _CRT_SECURE_NO_DEPRECATE 옵션을 사용하여 빌드하면 된다. (명령줄에 /D _CRT_SECURE_NO_DEPRECATE 를 추가하면 된다)
차후에 Secrue Function만을 지원할지 모르니 권장하지는 않는다. 그냥 VS2005로 변환후 빌드가 제대로 되는지 확인하는 차원에서만 사용하는게 좋을듯한다.

2. 형변환 문제
size_t를 DWORD로 형변환을 할때는 SizeTToDword와 같은 함수(intsafe.h, conversion 함수)를 사용하여 리턴값을 에러가 발생(64bit를 32bit로 변환함으로)하는것을 검사해서 별도의 에러처리를 수행하여야 한다.
[code]
DWORD dwRegLen;
HRESULT hrErr = SizeTToDWord((_tcslen(temp)+1)*sizeof(TCHAR),&dwRegLen);
if(hrErr==INTSAFE_E_ARITHMETIC_OVERFLOW)
{
  // 오버플로우 발생에 대한 에러 처리
}
[/code]

3. 메모리 할당
malloc와 같은 메모리 할당 함수는 char *로 메모리를 할당하기 때문에 유니코드 사용할때는 sizeof(TCHAR)의 크기를 곱해서 계산하여 한다.
그래서 문제가 되는게 _tcscpy_s 와 같은 secure function은 strDst의 크기도 지정을 해주어야 하는데 유니코드로 계산된 크기보다 char * 계산된 문자열(_tcslen)의 크기가 크기 때문에 사실은 nLen/sizeof(TCHAR)를 해주어야 한다.

(Language : c)
  1. size_t nLen = _tcslen(HubName)*sizeof(TCHAR) + sizeof(_T("test"));
  2. strDst= (LPTSTR)malloc(nLen);
  3. ...
  4. _tcscpy_s(strDst, nLen, _T("test"));
  5. _tcscpy_s(strDst+ _tcslen(_T("test")) , nLen, strSrc);




4. DWORD_PTR, UINT_PTR
timeSetEvent() 등 일부 함수에서 함수 포인터 인자를 이전 SDK에서는 DWORD 였으나 새로운 SDK에서는 DWORD_PTR로 변경.
AppendMenu()과 같은 함수는 UINT에서 UINT_PTR로 변경되었다.


바꾸어놓고 아직 테스트도 안해봤는데...
심히 노가다에 가깝구나...
 
2007/02/13 12:54 2007/02/13 12:54
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  1. Subject: timesetevent-으로 이어질 블로그링

    Tracked from blogring.org 2008/12/15 22:13  삭제

    timesetevent-에 관한블로그를 요약한 것입니다.

  • 크라이키스 2007/04/03 09:44  댓글주소  수정/삭제  댓글쓰기
    그나마 ATL 프로젝트는 변환하면 컴파일도 안된다는 비극이... ^^;;

  • 메니페스트(Manifest)와 어셈블리....
    2007/02/02 07:44

    Manifest는 응용 프로그램이나 어셈블리 안에 포함되거나 외부 XML 파일로 제공되는 XML 문서이다. Visual C++ 라이브러리의 헤더에는 어셈블리의 정보가 포함되어져 라이브러리를 응용 프로그램 코드에 포함하면 링커가 최종 이진 파일에 대한 매니페스트를 구성하는 데 이 어셈블리 정보가 사용된다.
    링커는 매니페스트 파일을 이진 파일 안에 포함하지 않으며 매니페스트를 외부 파일로만 생성할수도 있다.
    매니페스에는 버전정보나, 구성된 파일의 리스트등을 포함한다.

    그럼 어셈블리란?
    1. 어셈블리는 코드들의 논리적인 묶음이다.
    2. 어셈블리는 물리적으로 DLL또는 EXE로 존재한다.
    3. 한 개의 어셈블리는 한 개이상의 파일을 포함할 수 있다.
    4. 어셈블리안에는 어떤 형태의 파일도 포함될 수 있다(예: 텍스트 파일, 이미지파일등)
    5. 작성된 소스코드가 어셈블리로 묶여지지 않다면, 다른 어플리케이션에서는 이용할 수가 없다.
    6. 어셈블리파일엔 자체정보를 가지고 있는데 이를 어셈블리 메니페스트(Manifest)라 한다.

    프로그램의 언인스톨시 의존성있는 DLL 또는 다른 프로그램이 같이 사용하는 DLL의 의존성을 메타정보로 기록하여 그 의존성을 극복한다고 즉, DLL 지옥에서 벗어난다고는 하는데...
    뭐 더 복잡해진것도 같고...

    참고할만한 페이지
    http://msdn2.microsoft.com/ko-kr/library/1w45z383(VS.80).aspx
    http://www.hoonsbara.com/hoonsboard.aspx?table_name=cshaptip&board_idx=443278&page=5&keyword=&search=&boardmode=2

    2007/02/02 07:44 2007/02/02 07:44
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다


    Window Station과 Desktop 그리고 Session
    2007/01/29 08:25

    예전 프린터 드라이버를 개발하는 회사에서 일할때 잉크나 토너의 사용여부등을 알려주는 프린터 모니터 프로그램에서 대화상자를 올바르게 띄우지 못하는 버그가 발생했었다.
    윈도우 XP에 FastUserSwitching이란 기능이 있는데 이를 이용하여 두번째 logon 한 사용자는 프린터 모니터의 대화상자를 볼수없었다.
    디버깅을 해본 결과 FastUserSwitching은 터미널 서비스 세션을 이용하여 첫번째 logon 한 사람과 두번째 logon 사람의 Session이 각각 Session0과 Session1로 다르기 때문에 두번째 logon한 사람은 프린터 모니터의 대화상자를 볼수없고 엉뚱하게 첫번째 logon사람의 화면에 대화상자가 보여졌기 때문이다.
    오래되서 기억은 나지 않지만 꽤 번거로운 작업을 해서 해결했던 기억이...
    프린터 드라이버에서 모니터 프로그램을 CreateProcessAsUser로 실행했던가?!

    Window Station 과 Desktop

    윈도우는 User Interface, GDI 그리고 커널 메인 객체를 제공한다.
    커널은 안전하지만 UI, GDI는 그렇지 않기 때문에 추가적인 보안성을 제공하기 위해 윈도우는 stations와 desktops 을 사용한다.
    Station은 클립보드, desktop 등을 포함하는 프로세스와 관련이 있는 보안객체 이고 Desktop은 Station내에 존재하며 논리화면, 윈도우, 메뉴, 훅과 같은 User Interface를 포함하는 보안객체이다. 로그온 화면을 관리하는 winlogon desktop, 화면보호기를 담당하는 screen saver desktop, 평상시 윈도우 화면을 보여주는 interactive desktop의 3가지로 나눠진다.

    사용자가 logon을 하게 되면 WinSta0\Winlogon 에서  smss.exe(세션메니져), winlogon.exe, msgina.dll를 통해 일련의 logon 작업을 거쳐 최종적으로 Winsta0\default 라는 interacive window station을 생성한다.
    그러므로 사용자는 Winsta0 의 station에서만이 UI 및 키입력을 받을수 있다. (즉 서비스의 경우는 Service-0x0-3e7$\default 로 생성된다.)
    Winlogon 과 default desktop은 서로 메세지나 대화상자를 공유할수 없다. 자신의 desktop(winlogon, default)에서만 사용이 가능하다. 하지만 클립보드는 Station에서 관리되기 때문에 다른 desktop에서 사용이 가능하다.

    Service의 경우 LocalSystem 계정(administrator 계정보다 상위개념)으로 실행되어 Service-0x0-3e7$\default 와 같은 station을 생성하므로 UI 및 키입력을 받을수 없다. 그래서 서비스내에서 UI를 가진 프로그램을 실행시키기 위해서는 STARTUPINFO 구조체의 si.lpDesktop = "WinSta0\\Default"; 와 같이 설정하여 실행시켜야 한다. 서비스 프로그램중에서 mtask.exe와 같은 프로그램은 WinSta0을 사용한다.
    반면 서비스 프로그램을 UI 또는 키입력을 받기 위해서는 CreateService로 실행시 SERVICE_INTERACTIVE_PROCESS 옵션을 사용하거나 서비스 등록정보에서 로그온정보에 "데스크과 상호 작용" 을 설정하면 서비스도 UI 및 키입력을 받을수 있다.

    여기까지가 Station과 Desktop에 관한 이야기였고 맨위에서 말한바와 같이 우리가 알고 있어야 Session이라는 개념이 하나가 더있다.
    XP에서는 Session을 통해 사용자마다 다른 Session ID를 부여한다. 이러한 Session의 개념은 Teminal Service Session에서 이미 사용되어 졌다. (FastUserSwitching도 결국 Teminal Service Session을 이용한다.)
    결국 Session -> WindowStation -> Desktop 와 같은 구조를 이루는데 다른 Session에서는 같은 winsta0\default 를 가졌더라도 메세지 및 UI가 공유될수 없다. 즉 Session 1 에 logon 한 사용자가 실행시킨 프로그램에서 표시된 대화상자는 Session 2로 logon 사용자의 화면에는 나타나지 않는다는 이야기다. (당연한 이야기 아닌가?)

    단 XP에서는 첫번째 logon 사용자에게 Session 0 이 부여되는것(서비스도 마찬가지로 Session 0 이 주어진다.)과 달리 윈도우 Vista에서는 Session 0은 서비스에게만 주어지고 첫번째 logon 사용자는 Session 0 이외에 다른 Session ID가 부여되어진다.


    2007/01/29 08:25 2007/01/29 08:25
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다