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 :: 이 글에는 트랙백을 보낼 수 없습니다


MSDN Magazine blog...
2007/01/12 09:19
RSS 구독을 하고 있는데...
2007년 2월 MSDN 이 온라인상으로 발매...
링크를 따라 가봤더니 한글로도...

http://blogs.msdn.com/msdnmagazine/archive/2007/01/11/1451594.aspx



2007/01/12 09:19 2007/01/12 09:19
TAG ,
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • TWEETY 2007/01/15 08:38  댓글주소  수정/삭제  댓글쓰기
    링크를 따라 가봤더니 영언데? -.-;

  • 프로그램의 시간(성능)측정
    2006/12/29 14:31

    C 표준함수 clock() 을 이용

    (Language : c)
    1. #include <stdio.h>
    2. #include <time.h>
    3.  
    4. void main()
    5. {
    6.      clock_t t1,t2;
    7.      int count=0;
    8.  
    9.      t1=clock();
    10.      for (;;) {
    11.           printf("기다리십시오. %d\n",count++);
    12.           t2=clock();
    13.           if (t2-t1 > 3*CLOCKS_PER_SEC) {
    14.               break;
    15.           }
    16.      }
    17.      printf("끝났습니다.\n");
    18. }

    Windows Mutimedia timer 의 timeGetTime() 함수 이용

    (Language : c)
    1. DWORD dwStartTime = timeGetTime();
    2. // 중간코드생략
    3. DWORD dwEndTime = timeGetTime();
    4. printf("%d ms", dwEndTime-dwStartTime);

    Windows Management 의
    QueryPerformanceFrequency/QueryPerformanceCounter() 함수이용


    (Language : c)
    1. #define CHECK_TIME_START  __int64 freq, start, end; if (QueryPerformanceFrequency((_LARGE_INTEGER*)&freq))  {QueryPerformanceCounter((_LARGE_INTEGER*)&start);
    2.  
    3. #define CHECK_TIME_END(a,b) QueryPerformanceCounter((_LARGE_INTEGER*)&end);  a=(float)((double)(end - start)/freq*1000); b=TRUE;                        } else b=FALSE;
    4.  
    5. ...
    6.  
    7. CHECK_TIME_START;
    8. // 중간코드 생략
    9. CHECK_TIME_END(Time, err);
    10.  
    11. printf("printf() 걸린 시간은.. %8.6f미리세컨입니다.",Time);

     

    VC++6 의 Profile 사용
    Project Setting 에서 Link 의 Enable profiling을 체크

    사용자 삽입 이미지

    Build의 Profile 선택
    사용자 삽입 이미지

    Profile 대화상자에서 원하는 Profile Type 선택 - 시간측정은 Function timing
    Function converage와 Line Coverage 의 분석을 통해 함수의 점유율을 알수 있다.
    점유율에 대한 이해는 아래 링크를...
    http://www.debuglab.com/knowledge/coverage.html

    사용자 삽입 이미지

    그러면 아래와 같은 profile 탭에 결과가 나온다.

    사용자 삽입 이미지


    VS.NET 의 Profile 사용(PGO)

    프로젝트 속성에서 C/C++ 탭에서 프로그램 데이타 베이스를 /Zi 이하로 설정
    /ZI 일경우 /GL 옵션과 충돌

    사용자 삽입 이미지

    최적화 옵션에서 최적화를 /O[x] 중 원하는 것 선택
    전체 프로그램 최적화에서 /GL 옵션 선택


    사용자 삽입 이미지

    코드생성 탭에서 기본 런타임 검사를 기본값으로 설정

    사용자 삽입 이미지

    링커탭에서 일반에 보면 증분링크 사용 안함(/INCREMENTAL:NO)

    사용자 삽입 이미지

    그러면 설정은 다 끝났다.
    이제 빌드를 해야하는데 PGO를 위한 빌드는 빌드창에 프로필 기반 최적화라는 항목이 보인다.
    이 항목중에 계측, 업데이트, 최적화, 계측된/최적화된 응용 프로그램 실행 이 있는데 이중 먼저 계측을 선택하여 PGD 파일을 생성한다.
    다음 계측된/최적화된 응용 프로그램 실행을 눌러 실제 프로그램을 테스트/연습을 수행한다.
    원하는 만큼 수행하여도 된다 이때 수행한 만큼 PGC 파일이 생성된다.
    다음 최적화를 눌러 생성된 PGC 파일을 통해 최종 PGD 파일이 생성된다.


    사용자 삽입 이미지

    최종적으로 pgomrg.exe test.pgd /summary 를 실행해보면 요약된 정보를 얻을수 있다.
    도스커맨드 창은 도구에 VisualStudio 2005 command Prompt를 이용하면 별도로 경로명을 지정하지 않아도 편리하게 이용할수 있다.

    사용자 삽입 이미지


    @CLK
    이 방법은 디버깅시 Watch 창에 @CLK 를 입력하여 측정하는 방법이다.
    간단하지만 요긴하게 써먹을수 있다.
    아래 그림처럼 측정하고자 하는 구간의 첫번째 브레이크 포인터에
    @CLK/1000,d 를 하면 초단위로 값을 볼수 있다.
    그리고 마지막 브레이크 포인터에 @CLK=0 을 입력한다.
    아래 그림을 보면 for문 수행하는 시간이 대략 548초 걸렸다.
    디버깅 모드이므로 참고 정도로만 사용할것.
    사용자 삽입 이미지




    2006/12/29 14:31 2006/12/29 14:31
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

    1. Subject: 수행시간 측정

      Tracked from 냇가의 흐르는 물처럼... 2007/02/06 18:07  삭제

      1. clock() 이용 // 시작clock_t beginTime;clock_t endTime;beginTime = clock(); // 수행endTime = clock();수행 시간 = (double)(endTime - beginTime) / CLOCKS_PER_SEC 2. timeGetTime() 또는 GetTickCount()해더 파일 : mmsystem.h라이브러리 :..

  • seyool 2009/07/16 14:06  댓글주소  수정/삭제  댓글쓰기
    좋은 정보 감사합니다..
    pgomrg.exe가 오타인거 같네요..
    이거때문에 왜 2008에는 없는걸까 좌절했는데, pgomgr.exe였군요 ㅎㅎ
  • 비밀방문자 2010/03/27 16:50  댓글주소  수정/삭제  댓글쓰기
    관리자만 볼 수 있는 댓글입니다.

  • 비주얼스튜디오에서 DDK build를...
    2006/12/22 10:24

    DriverStudio를 설치해서 VC6에서 DDK 빌드를 한다.
    비주얼스튜디오 IDE를 사용해서 편하긴 한데 웬지 모를 존재의 무거움(?)이랄까?
    매번 드라이버스튜디오를 설치해야하고 환경설정해야하고...
    가장 중요한건 돈주고 사야한다는거...

    googling 하다가 알아낸 것들...

    1. http://www.osronline.com/article.cfm?article=43 에서 DDKBUILD를 다운받아 비주얼스튜디오 또는 프로젝트 폴더에 복사해 넣은다음
    2. VC6 또는 VS.NET에서 New Project를 Makefile project로 프로젝트 생성하고 - build command line에는 ddkbuild -WNET checked . -ceZ 이정도로 적당히 설정/
    3. SOURCE, MAKE 파일 및 소스파일등을 생성하고 빌드를 수행하면 된다.

    VS.NET에서 New Project를 Makefile로 생성해서 DDK를 빌드하는 방법에 대해 자세하게 나와있다.
    http://www.hollistech.com/Resources/ddkbuild/ddkbuild.htm
    영어 알레리기가 있는분은 somma님 블러그를 보시길...
    (http://somma.egloos.com/2710282)

    사용자 삽입 이미지

    CodeProject에 있는 위저드를 통한 DDK 빌드 환경
    http://www.codeproject.com/tools/driverwizard.asp
    project wizard를 만드는게 일이 되겠지만 한번 만들어 놓으면 좋을듯한데...

    사용자 삽입 이미지

    그외에...
    http://www.codeproject.com/macro/ddkwizard.asp


    DDK 빌드하다가
    regmlib.lib(reglib.obj) : error LNK2026: module unsafe for SAFESEH image.
    위와 같은 에러가 발생하면 set NO_SAFESEH=1 와 같이 ddkbuild.bat 또는 ddkbuild.cmd에 설정하도록 한다.

    2003 DDK를 설치했다면
    XP를 위한 빌드는
    ddkbuild -WNETXP [checked/free] . -ceZ
    2K를 위한 빌드는
    ddkbuild -WNET2K [checked/free] . -ceZ

    XP DDK를 설치했다면 각각 아래와 같다.
    ddkbuild -WXP [checked/free] . -ceZ
    ddkbuild -WXP2K [checked/free] . -ceZ

    2006/12/22 10:24 2006/12/22 10:24
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

    1. Subject: DDK버전 과 Windows 버전 그리고 환경설정

      Tracked from 홍가일보 2007/03/20 13:55  삭제

      Windows 버전 Windows VistaWindows Server 2003 with Service Pack 1 (SP1)Windows XP with Service Pack 2 (SP2)Windows Server 2003 Windows XP Professional x64 EditionWindows XP with Service Pack 1 (SP1)Windows XP Windows 2000 DDK 버전 Windows Longhorn, ..

    2. Subject: DDKBUILD.CMD로 DDK빌드시 SOURCES 옵션

      Tracked from 홍가일보 2007/06/21 09:40  삭제

      지난 포스팅에 DDKBUILD.CMD를 통해 비주얼 스튜디오에서 드라이버 빌드를 하고 있는데...사용하다 불편한게 있어서 몇가지 알아내 SOURCES의 옵셥설정.MAP파일 생성하고 싶을때SOURCES 파일에 아래 ..


    리모트 디버깅
    2006/12/08 13:17

    가끔 고객의 PC에서만 발생되는 버그를 Debugging 하기 위해서 고객을 방문해서 디버깅을 해야할때가 있다. 하지만 고객의 PC에 비주얼스튜디오를 설치 할수도 없고 설치한다고 한들 각종 환경설정은 어떻게 할것이냐 라는 문제에 봉착한다.
    그나마 VC++6 이면 설치하는데 별문제가 없겠지만 NET 2005의 경우라면 아예 설치할 생각을 말아야 한다.
    해서 리모트 디버깅을 해야 하는데 비주얼 스튜디오 버전에 따라 현지 사정에 따라 디버깅을 방법을 달리 해야 되는 경우가 많다.

    리모트디버깅은 위에서 말한것처럼 꼭 고객의 PC 뿐 아니라 개발환경이 설치되지 않은 clean 한 상태에서 테스트용 디버깅과 UI로 local 디버깅의 불편함도 해소 한다는 점에서 많은 이점이 있다.

    또한 이러한 방법들도 중요하지만 보다 중요한 것은 표준적인 디버깅환경이다. 같은 회사내에서도 다른 디버깅을 방법을 사용한다던가 개발자마다 다른 버전의 개발툴, 환경에서 오는 혼동도 무시 못한다. 먼저 이러한 부분에 있어서의 표준화가 먼저 되어야겠다.

    디버깅을 하기 전에 아래 링크에서 리모트디버깅을 위한 서버설정을 위한 파일들을 다운받도록 한다.
    http://hongyver.pe.kr/project/remotedbg.zip
    위의 파일들은 VC6~2005, WinDBG용 서버용 파일들이 있다. 원하는 파일을 고객 또는 디버깅 해야할 PC로 복사하여 사용한다.

    유저모드, 응용프로그램류를 디버깅할때
    VC++6에서 디버깅
    디버깅할 PC, 즉 고객의 PC에서 위에서 다운받은 파일중 msvcmon.exe(msvcmon.exe는 NET용이다.주의할것)를 실행시키면 아래와 같은 화면이 나온다.

    Visual C++ Debug Monitor에서 Setting을 눌러 Target machine name or address에 개발자 PC의 IP 또는 컴퓨터 이름을 입력한다.
    OK를 누르고 Connect를 누르면 Disconnecting 이라는 메세지가 나오면서 연결대기 상태가 된다. 이것으로 서버의 설정은 끝났다.
    그럼 다음으로 개발자 PC에서는 Project의 Setting을 눌러 Debug 란 탭을 눌러 아래의 화면처럼 설정한다.
    맨 아래의 Remote executable path and file name 란에 고객PC 또는 디버깅할 PC에 있는 디버깅할 파일명을 적는다. 상단의 Executable for debug session과 같은 파일명이다.
    그리고 나서 F5를 눌러 디버깅을 눌러 실행하면 고객PC에서는 프로그램이 실행되고 개발자의 PC에서는 디버깅이 가능하다.

    VS.NET 2005에서의 디버깅
    서 디버깅할 PC, 즉 고객의 PC에서 위에서 다운받은 파일중 msvsmon.exe(vc8이란 디렉토리에 있다.)를 실행시키면 아래와 같은 화면이 나온다.
    도구 -> 옵션을 눌러 위의 그림처럼 인증안함으로 설정하고 확인을 누르면 서버(고객PC 또는 디버깅할 PC)의 설정은 끝났다.

    다음으로 개발자 PC에서 비주얼스튜디어2005를 실행시켜 소스를 읽어들인다음  도구->프로세스연결 을 눌러 아래화면으로 띄운다.
    전송은 원격(네이티브 전용, 인증안함)으로 설정하고 한정자는 고객PC 또는 디버깅할 PC의 IP 번호 또는 컴퓨터이름을 입력하면 사용 가능한 프로세스 에 현재 고객PC 또는 디버깅할 PC의 프로세스들이 보인다. 이중 디버깅을 하고자 하는 프로세스를 클릭하고 연결을 누르면 디버깅이 가능하다. 그래서 원격지 PC에서 먼저 프로세스를 실행시켜야 두어야 한다.

    WinDBG
    고객PC 또는 디버깅할 PC에서 windbg.exe -server tcp:port=9090 (예시 포트번호) 로 수행한다.(바로가기를 만들어 속성에 추가해도 된다)
    개발자PC에서는 windbg.exe -remote tcp:Port=9090,Server=vmxp 로 서버에 접속할수 있다.
    아니면 아래의 그림처럼 메뉴의 File -> Connect to Remote Session 를 선택하여 Browse를 선택.
    Machine에 컴퓨터 이름 또는 IP번호를 입력하고 refresh를 누르면 Servers에 서버가 뜬다.
    서버를 클릭하여 접속한다.

    여기까지 해서 WinDBG로 고객PC와 개발자PC가 접속이 되었다면 실제로 디버깅을 수행하기 위해서는 고객PC 또는 디버깅할 PC에서 File -> Attach to a Process 를 선택하여 디버깅할 프로세스를 선택하여야 한다.
    비주얼 스튜디오에 비해 다소 불편하지만 보다 많은 정보와 폭 넓은 디버깅을 지원한다. 뿐만 아니라 꼭 TCP/IP 가 아닌 1394 나 시리얼을 통해서 디버깅이 가능하다.

    커널모드, 디바이스드라이버류
    SoftICE
    설치후 CTRL+D 로 디버깅이 가능하다.
    물론 Symblo Loader 라는 프로그램으로 디버깅하고자 하는 파일(EXE, DLL, SYS, DRV등등)을 File -> Open 한후  Module -> Load 를 수행하면 소스코드를 찾는데 이때 올바른 폴더를 지정해주면 CTRL+D 이후 디버깅에서 소스레벨의 디버깅이 가능하다.

    WinDBG
    설정방법은 아래 링크를 참조.
    단 WinDBG의 커널 디버깅에서는 SoftICE와는 달리 EXE 또는 DLL 디버깅을 할수 없고 커널관련 모듈(SYS)만 가능하다.
    역시 심볼설정을 통해 소스레벨의 디버깅이 가능하다.
    http://www.debuglab.com/board_detail.aspx?id=98&table=lecture&pagenum=10

    2006/12/08 13:17 2006/12/08 13:17
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • 우스 2007/02/01 00:18  댓글주소  수정/삭제  댓글쓰기
    안녕하세요^^;; 정말 좋은 정보인 것 같아서 담아가려구요^^;;
  • sunny 2007/06/25 11:53  댓글주소  수정/삭제  댓글쓰기
    넬름 퍼갔습니다. ;
  • 우왕... 2009/08/25 11:15  댓글주소  수정/삭제  댓글쓰기
    안녕하세요. 너무 좋은 내용이라 댓글 남기고 갑니다..잘 봤습니다.!!!!
    그런데 VS6.0 에서는 바로 F5 가 아니라 Build -> Debugger Remote Connection... 에서 Network (TCP/IP) -> Setting...부분에서 Target PC 의 IP를 입력해야 하는거 아닌가요? ^^;
    좋은 내용이라..제 블로그에 참조 했습니다 ^^;;

  • 정적링크와 동적링크 라이브러리 - lib 파일과 dll 파일
    2006/11/27 12:53

    Static Linked Library, 정적 링크 라이브러리

    컴파일시 실행파일에 라이브러리의 함수코드가 추가되어 작성되기 때문에 실행파일이 커지는 단점이 있으나 별도의 DLL이 필요없다.

    VC++6에서는 New Projects에 Win32 Static Library로 작성하고 2005에서는 Win32 콘솔 응용프로그램에서 정적라이브러리(미리 컴파일된 헤더 해제)를 선택하여 작성한다.
    명령줄에서 작성하려면 cl.exe /c /EHsc 파일명.cpp(/c 옵션은 링크없이 컴파일) 로 컴파일 하여 obj 파일 생성후 lib.exe ~.obj 으로 ~.lib 파일을 생성한다.

    만들어진 LIB(~.lib파일)과 ~.h(header파일)을 작성하고자 하는 Project 생성후라이브러리는 Project->Setting->Library modules에서 ~.lib를 추가하고 헤더는 원하는 코드에 추가하여 빌드한다.

    Dynamic Linked Libarary(DLL), 동적 링크 라이브러리

    우리가 흔히 말하는 DLLs 이다. 컴파일시 실행파일에 라이브러리의 함수코드를 넣지 않고 DLL 이라는 파일에 따로 두어 모듈화를 통해 관리와 테스트가 용이하며 공유를 통해 코드의 낭비를 줄이고 다국어버전등의 리소스교체를 용이하게 한다.

    New Projects에서 Win32 Dynamic-link library로 작성한다. 2005에서는 win32 응용프로그램작성에서 DLL 을 선택하면 된다.

    Header파일을 공통적으로 사용하기 위한 예시

    #ifdef _USRDLL
    #define DLLFunction  __declspec(dllexport)
    #elseif
    #define DLLFunction  __declspec(dllimport)
    #endif

    #ifdef __cplusplus
    extern “C” {
    #endif

    DLLFunction void somefunc();
    #ifdef __cplusplus
    }
    #endif


    ~.DEF 파일 
    예전에는 ~.def 파일을 통해 dll을 export 하였지만 VC++에서는 __declspec(dllexport)를 통해서 dll 의 함수들을 export한다. 반대로 import시에는 __declspec(dllimport)를 사용한다.

    LIBRARY              "TESTDLL.DLL"
    DESCRIPTION 'SIMPLEDLL Windows Dynamic Link Library'

    EXPORTS
      somefunc   @1


    Implicit Linkage, 암시적 링크
    LoadLibrary를 사용하지 않는다. 따라서 프로그램이 실행될때 dll이 로드된다.
    그러기 위해서는 Static Library와 같이 ~.lib파일과 ~.h 파일이 필요하고 실행시는 같은 폴더 또는 시스템폴더(dll을 찾는 정책에 따라)에 dll 파일이 존재하여야 한다. 없을시 찾을수 없다면 에러가 발생한다.
    dll을 생성하고 나면 생성된 폴더에 lib 파일도 같이 생성되는데 Static Library와는 달리 함수의 코드가 없다. 다만 함수형이 정의되어 있을뿐이다. 실행파일의 implict section에서 실행시 로드되어야 할 dll을 추가하여 나중에 프로그램이 실행되면 dll이 로드된다.

    Explicit Linkage,  명시적 링크
      LoadLibrary로 명시적으로 dll을 로드한다. GetProcAddress로 사용하고자 하는 함수의 주소를 얻어서 사용한다. dll이 load되는 시점은 프로그램이 실행되는 순간이 아니고 LoadLibrary가 호출되는 시점이다.

    Delay Linkage, 지연 링크
    빌드시 옵션에 /delayload:dllname 으로 작성한다.
    로드되는 시점은 프로그램 실행시가 아니라 함수가 사용되는 시점이 된다.
    /delay 옵션도 참고할것

    확장DLL
    MFC 클래스에서 파생된 재사용 가능한 클래스를 구현한 DLL. 따라서 MFC로 만든 응용 프로그램에서만 확장 DLL이 사용되어 질수 있다.
    이 DLL로부터 익스포트할 클래스에 대해서 여러분이 해줄일은 클래스 선언문에 AFX_EXT_CLASS란 매크로만 붙여준다.

    예시

    Class AFX_EXT_CLASS CDllDialog : public CDialog
    {
    ...
    }
    2006/11/27 12:53 2006/11/27 12:53
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다


    WinDBG에서 USB2.0 디버깅
    2006/11/01 09:59

    무지 편리할것 같아서...
    구글링을 해봤더니...

    일단 전용선이 필요한데다 국내 제작업체는 보이지 않는듯하고...
    제작하는 외국 업체도 Vista 만 지원한다니...

    결국 1394나 NullModem(COM1)으로 할수밖에 없구나...

    http://www.plxtech.com/products/NET2000/NET20DC/default.asp

    2006/11/01 09:59 2006/11/01 09:59
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다


    초기화 그리고 delete...
    2006/10/24 14:00

    다른 동료가 코딩한 프로그램에 코드 몇줄 추가하고 실행했더니...
    CodeProject에 있는 소스코드란다...
    이상하게 자꾸 메모리쪽에 ASSERT 에러가 발생하길래...(전혀 메모리쪽은 건들지도 않았는데...)
    Debugging을 해봤더니...
    이런 경우도...

    1. class CBabo
    2. {
    3. public:
    4.   CBabo();
    5.   CBabo(int i);
    6.   ~CBabo();
    7. private:
    8.   char*    m_babo;
    9. }
    10. CBabo::CBabo()
    11. {
    12.   m_babo= NULL;
    13. }
    14. CBabo::CBabo(int i)
    15. {
    16.   if(i==1)
    17.        some_function(); // m_babo에게 new pointer 할당...
    18.   else
    19.        m_babo= NULL;
    20. }
    21. CBabo::~CBabo()
    22. {
    23.   if (m_babo != NULL)
    24.   {
    25.        delete m_babo;
    26.       m_babo= NULL;
    27.   }
    28. }

    some_function()에서 당연히 멤버변수 m_babo가 new 로 point를 할당하는데...
    어쩌다 할당하지 못하는 경우가 드물게 발생...
    그럴경우 m_babo는 초기화 되지 못하고 쓰레기값이 들어가 있는 상태에서 소멸자에서 m_babo 는 NULL 이 아니므로 할당되지 못한 메모리를 delete 함으로 에러 발생...

    가장 좋은 초기화 방법으로는...
    CBabo::CBabo() : m_babo(NULL)
    참고서적으로는 이펙티브 C++...

    오전 반나절을 시간낭비 했지만...
    초기화 우습게 볼게 못되는군...

    2006/10/24 14:00 2006/10/24 14:00
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • TWEETY 2006/10/25 08:26  댓글주소  수정/삭제  댓글쓰기
    m_pVersionInfo = NULL;

    //<- 이것도 에러. ㅋㅋ
  • duck 2006/10/25 16:04  댓글주소  수정/삭제  댓글쓰기
    저는 프로그램은 모르지만..

    babo... 만 눈에 들어와요~ ㅋㅋㅋ
  • duck 2006/10/26 00:10  댓글주소  수정/삭제  댓글쓰기
    ㅡㅡ;;

  • 유닉스용 타임스탬프를 엑셀의 날짜로 변환...
    2006/09/26 15:37

    TRAC에서 report view를 통해 생성된 text 파일을 엑셀에서 읽고 보니...
    날짜가 이상하게 나온다.
    조사해 보니 TRAC에서 사용하는 DB(SQLite)가 날짜를 유닉스용 타임스탬프를 사용하기 때문...

    결과적으로...
    아래와 같이 변환하여 사용하면 된다.
    =유닉스타임스탬프/86400 + 365*70 + 17 + 9/24

    유닉스 타임스탬프는 1970년 1월 1일부터의 초이고 엑셀 시간은 1900년 1월 1일부터의 일을 의미.
    17은 70년동안 윤년이 17번 있었다는 의미이고 마지막 9/24는 대한민국이 UTC+9 시간대에 있기 때문...

    예제)
    1155946467 / 86400 + 365*70 + 17 + 9/24 = 25567.375
    25567.375의 셀서식을 날짜로 변경하면 2006-08-17 과 같은 날짜를 얻을수 있다.

    2006/09/26 15:37 2006/09/26 15:37
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

    1. Subject: 유닉스(Unix time)을 엑셀에서 바꿔보자!

      Tracked from The Cathedral and the Bazaar 2006/11/03 20:30  삭제

      PHP로 만들어진 게시판에서 노가다로 내용을 다른 곳으로 옮기려고 하는데, 갑자기 시간이 1155946467 이라고 적혀있더군요. 헉 난갑했습니다. 그러나 우리에게는 구글이 있었습니다. 찾아보니 ..


    x64 primer
    2006/09/22 09:15

    64bit는 64bit에만 설치가 가능하고(32bit 응용프로그램의 사용은 가능하다) Intel의 Itanium™과 32bit 및 64bit 시스템에 설치가 가능한 (당연히 32bit, 64bit 프로그램 실행이 가능하다) x64라고 알려진 Intel의 EM64T, AMD의 AMD64 이 있다.

    PE헤더 구조의 변화
    Win64의 포맷은 PE32+로 불린다. 두드러진 가장 큰 변화는  기존 예외처리 방식이 예외처리 정보를 스택에 추가되었다면 Win64는 테이블 기반의 예외 처리(exception handling)이다. 단점은 함수테이블 찾는것이 링크드 리스트보다 시간이 걸리는 것이고 장점은 매번 스택에 예외처리 블럭을 생성하는 오버헤드가 없다는 점이다.

    데이터 실행 보호(Data Execution Protection - DEP) 기능 추가
    고의적인든 아니든
    버퍼 오버런(buffer overrun)이 원래는 데이터 저장을 목적으로 했던 메모리 블락을 CPU에서 명령어로 인식하고 실행해 버리는 결과가 발생하곤 했었습니다. 이 DEP의 도움으로, 운영체제는, 의도한 코드 영역의 경계를 명료하게 설정할 수 있고, 이 의도된 경계를 벗어나는 코드 실행에 대해서는 CPU가 일종의 덫을 놓을 수 있게 되었습니다. 이 기능은 윈도우를 악의적인 공격에 덜 취약하게 만드는데 큰 도움을 줄 수 있다.
    윈도우 XP sp2 부터 기능이 추가되었고 시스템등록정보->고급->성능에서 볼수 있다. 보다 자세한 내용은 아래 링크 참조.
    http://www.microsoft.com/technet/prodtechnol/winxppro/ko/maintain/sp2mempr.mspx

    PatchGuard기술 추가
    syscall 테이블이나 인터럽트 디스패치 테이블(interrupt dispatch table-IDT)를 변경하는 사용자 프로그램이나 드라이버들은 보안상의 문제와 잠재적인 안정성의 문제를 일으켜 왔는데 x64의 내부에서는, 그러한 방식으로 커널의 메모리를 지원되지 않는 방식으로 바꾸는 방식이 허용되지 않습니다. 이러한 것을 강화시키는 기술이 PatchGuard 입니다. 이 기술은 중요한 커널 메모리의 위치가 바뀌는 것은 커널 모드의 쓰레드에서 항상 감시합니다. 그리고 메모리가 바뀌면, 시스템은 버그체크를 통하여 멈춰 버립니다.

    함수 호출 방식(Calling Convention)의 변경
    Win64의 경우는 하나의 함수 호출 방식이 존재합니다. fastcall 과 유사한 방식인데 처음의 4개의 인자는 특별히 디자인된 레지스터(RCX: 1 번째 정수 인자 RDX: 2 번째 정수 인자 R8: 3번째 정수 인자 R9: 4번째 정수 인자)에 전달되고 나머지는 스택으로 전달됩니다.  게다가 x64 코드 생성기는 (파라미터의 입장에서 보면) 얼마든지 큰 대상 함수에서도 쓸 수 있을 만큼 충분한 스택을 예약해 웬만한 경우가 아니면 RSP를 조작하는 경우가 없을겁니다.
    리턴값은 Win32에서와 마찬가지로 RAX에 저장됩니다.

    그외에 사항으로는

    링커의 기본주소 변경 4G 이상으로 설정
    64비트 포인터는 8바이트 이지만 int,long, DWORD는 4바이트
    레지스트터 이름 변경 RAX, RBX등으로, 기존 EAX, AX등 사용가능



    Visual Studio® 2005 에서 x64 어플리케이션의 개발
    추가중...


    참조
    Matt Pietrek의 x64 primer 원본(
    Matt Pietrek의 x64 primer 번역본)
    64비트 윈도우 개괄

    2006/09/22 09:15 2006/09/22 09:15
    TAG , ,
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다