출처: http://sweeper.egloos.com/1792751


1. Static library

Dynamic (linking) library (흔히 얘기하는 DLL)을 설명하기 위해 간단하게 정리한다.

특정 기능의 라이브러리를 static 하게 제작한다는 것은 link 단계에서
라이브러리(*.lib 파일)를 실행 바이너리에 포함시킨다는 얘기이다.

즉, 라이브러리의 동작 코드가 이를 사용하는 실행 바이너리 속에
포함되기 때문에 별도의 추가 작업없이, 그리고 독립적으로(실행 바이너리만으로...)
라이브러리 함수들을 사용할 수 있다.

하지만, 정적 라이브러리를 사용하는 프로그램이 늘어나면 날수록
불필요하게 실행 파일들의 크기가 커지며,
라이브러리가 동시에 여러 실행 바이너리에 포함되어 실행되는 경우
메인 메모리의 공간 활용 효율이 떨어지는 등 multiple-caller가 존재하는 경우 그다지 바람직하지 않다.

정적 라이브러리를 사용하기 위해서는 프로젝트 설정의 Link 옵션에
라이브러리를 추가해 주거나 아래의 #pragma 지시자를 사용하면 된다.

#pragma comment(lib, "NAME.lib")


2. Dynamic (linking) library : DLL

말 그대로 "동적으로 링크하여 사용하는 라이브러리" 이다.

동적 라이브러리는 이를 사용하고자 하는 실행 바이너리에서
필요시 사용할 수 있도록 최소한의 정보만 포함하여 링크하거나,
아예 독립적으로 DLL을 로드/사용/해제할 수 있다.

1) Implicit linking

DLL을 구현하고 컴파일하고 나면 static library와는 다르게  output file이 2개 생성된다.
하나는 *.lib 파일이고 하나는 *.dll 파일이다.
여기서 *.lib 파일은 static library의 *.lib 파일과는 전혀 다르다.

Static library의 *.lib 파일은 라이브러리 전체 코드를 포함하는 바이너리이며,
DLL의 *.lib 파일은 DLL이 제공하고자 하는 함수 정보(함수명)을 가지는 정보 파일이다.

DLL의 *.lib 파일을 이용하여 링킹하는 것을 암시적 링킹(implicit linking)이라고 한다.
실행 바이너리를 링크 단계에서 실행 바이너리의 *.obj 파일들과 DLL의 *.lib 파일을
함께 링크하여 이 정보를 토대로 runtime에 DLL의 함수 코드를 참조하게 되는 것이다.
(한 줄로 요약하면 *.lib 파일은 링크시 필요하고, *.dll 파일은 실행시 필요하다)

정적 라이브러리를 사용할 때와 같이 프로젝트 설정의 Link 옵션에
라이브러리를 추가해 주거나 아래의 #pragma 지시자를 사용하면 된다.

#pragma comment(lib, "NAME.lib")

2) Explicit linking

명시적 링킹에서는 *.lib 파일이 필요하지 않다.
실행 바이너리 링크 단계에서 DLL의 함수 정보가 필요하지 않기 때문이다.

명시적 링킹에서 사용되는 세 가지 함수와 역할은 다음과 같다.

1. LoadLibrary : 필요한 DLL을 프로세스 가상 메모리에 맵핑한다.
2. GetProcAddress : DLL 함수의 포인터를 획득한다.
3. FreeLibrary : 프로세스 가상 메모리에서 DLL을 반환한다.

프로세스는 내부적으로 DLL의 레퍼런스 카운트를 계산한다.
LoadLibrary 호출시 DLL의 (프로세스) 레퍼런스 카운트는 1씩 증가하고,
FreeLibrary 호출시 레퍼런스 카운트가 1씩 감소한다.
레퍼런스 카운트가 0이 될 때 해당 DLL은 프로세스 가상 메모리에서 해제된다.

여기서 주의할 점이 물리 메모리가 아닌 가상 메모리에서의 반환(해제)라는 것이다.
레퍼런스 카운트는 각 프로세스 내부의 호출 회수이지,
전체 프로세스 간의 호출 회수가 아니라는 것이다.

이러한 레퍼런스 카운트를 두는 이유는 프로그램 실행 중에
DLL을 가상 메모리에 할당, 해제할 수 있도록 하기 위함이다.
(Implicit linking 방식에서는 이러한 장점을 얻을 수 없다.)

정리해서 명시적 링킹의 장점을 세 가지 정도 정리해 보면...

1. DLL이 필요한 시점에서 로딩하고, 불필요해지면 반환하기 때문에 메모리가 절약된다.
2. 프로그램 실행 중에 DLL 교체 및 선택이 가능하다.
3. 암시적 링킹은 프로그램 실행 전에 필요한 모든 DLL을 메모리에 로딩한다.
때문에 실행까지 걸리는 시간이 길어질 수 있다. 반면에 명시적 링킹은 필요한 순간에
하나씩 DLL을 로딩할 수 있기 때문에 그만큼 실행까지 걸리는 시간이 짧고,
DLL 로딩에 걸리는 시간을 분산시킬 수 있다.

뭐 위와 같이 명확한 장점들이 있음에도 불구하고 암시적 링킹이 더 선호되는 경우가 있는데,
이는 사용하기 쉽기 때문이다. 코드가 간결해 진다는 것, 사용하기 쉽다는 것은
대부분의 경우에 있어서의 성능보다도 더 큰 장점을 지니는 것이 아닌가 생각해 본다.

AND

출처: http://mores.tistory.com/210

출처: http://www.tipssoft.com

Windows 프로그램을 하다 보면 Z order라는 말을 종종 접한다. 하지만, 그 의미가 무엇인지를 정확하게 아는 사람이 별로 없는 것 같아서 이렇게 소개한다.

"Z Order"는 어떤 창들이 다른 창들 뒤에 가려져야 하는지를 결정하는 방법이다. 좀더 자세하게 이야기하면 "A 윈도우의 Z Order"는 겹쳐서 쌓아 올려진 윈도우들 중에서 A 윈도우의 위치라고 할 수 있다.

사용자 삽입 이미지

우리가 보는 화면은 2차원적이다. 따라서 X축과 Y축으로 모든 것을 표현한다. 하지만 개념적으로 볼 때, 겹쳐진 윈도우들은 3차원적인 의미를 가지고 있다. 따라서 가상의 축(Imaginary Axis)을 하나 더 생각해야 한다. 이 측을 Z축이라고 하면 아래와 같이 표현될 것이다.

사용자 삽입 이미지

위 그림을 보면 알 수 있듯이 Z 축의 값이 겹쳐진 순서의 위치 임을 알 수 있다. 이것을 보면 왜 Z Order라는 용어를 사용하는 그 이유를 알 수 있을 것이다.

Windows는 기본적으로 Single List를 이용하여 Z Order를 관리한다. 그리고 Windows는 이 윈도우들이 topmost(top-level) 윈도우인지 또는 child 윈도우인지를 고려한 Z Order를 추가적으로 관리한다.

Topmost 윈도우들은 모든 non-topmost 윈도우들보다 더 위쪽에 출력된다. 이때, non-topmost 윈도우가 활성화되어 있다든지 가장 앞쪽에 있다는 것과 같은 상황은 무시된다. 이런 Topmost 윈도우들은 자신의 확장속성에 WS_EX_TOPMOST라는 속성을 가지고 있다. 그리고 child 윈도우들은 그것의 Parent 윈도우의 Z Order에 의해서 그룹 지어진다.

응용 프로그램에서 새로운 윈도우를 하나 생성시키면 Windows 시스템은 동일한 형태(topmost이든지 non-topmost)의 윈도우들이 가지는 Z Order에서 가장 위쪽의 값을 부여한다. 그리고 동일한 형태의 윈도우들간에 Z Order를 가장 높이고 싶다면 BringWindowToTop이라는 함수를 이용하면 된다.

SetWindowPos 와 DeferWindowPos 함수를 이용하여 윈도우의 Z Order를 재정렬 할 수도 있다.

AND

출처: http://www.debuglab.com/knowledge/volatile.html

Volatile


1. 요약

Volatile은 ‘휘발성의’ 라는 뜻을 가지고 있습니다.

Volatile 키워드를 사용해서 정의한 변수는 그것을 사용하는 문장(statement)외에 다른 것에 의해서 변경될 수 있다는 의미를 갖습니다.

다른 것이란 운영체제, 하드웨어 혹은 다른 스레드가 될 수 있습니다. 그러므로 Volatile 키워드를 사용해서 정의한 변수는 눈에 보이는 문장만을 상대로 함부로 최적화 시키지 말아야 함을 의미합니다.

이 글에서는 간단한 사용법과 Volatile 키워드의 유무에 따라서 컴파일러가 생산해내는 코드가 어떻게 달라지는지 알아보겠습니다.


2. 본문

(1) 사용법

사용법은 간단합니다.

volatile int k; 
이제 k는 컴파일러가 함부로 최적화 시키지 않습니다.

(2) Loop를 돌며 일하는 Worker Thread

프로세스가 생성되면서 함께 생성되는 메인 스레드가 아니라면, 대부분의 경우는 메인스레드가 신호를 보내줄 때까지 루프를 돌면서 반복작업을 합니다.

다음과 같은 스레드 입구(Entry)함수가 있다고 합시다.

void ThreadEntry(void* pParm) 

{ 

    bool* pbExit = static_cast<bool*>(pParm); 

    int i = 0; 

    

    while( !*pbExit) 

    { 

        i++; 

    } 

    

    printf("i = %d\n" ,i); 

} 


메인 스레드가 넘겨준 bool 변수가 true값을 가질 때까지 계속해서 i의 값을 1씩 더하는 루틴입니다.
*pbExit가 true가 되는 순간에 while문을 빠져 나오고 이 워커 스레드( 이렇게 부르기로 합시다)는 종료하게 됩니다.

물론 Debug 모드로 컴파일 하신다면 위의 시나리오대로 잘 작동할 겁니다.
하지만 Release 모드로 컴파일 하신다면 아마도 워커 스레드는 정상으로 종료할 수 없을 겁니다.

그 이유는 Release 모드에서는 컴파일러가 최적화를 하기 때문입니다. 위의 코드를 다시 보신다면, 함수 내에서 *pbExit 의 값을 변경시키는 부분( 읽는 부분만 있죠)은 없다는 것을 알 수 있습니다.

그 결과 컴파일러는 굳이 *pbExit의 값을 매번 비교할 필요가 없다고 생각하고는 *pbExit가 true인지 비교하는 코드를 제거해버린 것입니다.

해결책은 다음과 같습니다.

volatile bool* pbExit = static_cast<volatile bool*>(pParm); 

이제 컴파일러는 섣불리 최적화하지 않을 것이고, Release 모드에서 정상 종료하는 좋은 코드가 되었습니다.
volatile의 유무에 따라 컴파일러가 생산하는 코드가 3. 예제 코드에 있으니 참조하시기 바랍니다.

Release 모드에서 어셈블된 코드를 보시려면 컴파일러 옵션에서 /FAcs를 추가하시면 됩니다. 그러면 *.cod라는 이름의 파일이 생성됩니다.


3. 예제 코드

(1) Volatile없는 경우

; 12   : bool* pbExit = static_cast<bool*>(pParm); 

; 13   : int i = 0; 

; 14   : 

; 15   : while( !*pbExit) 



  00000 8b 4c 24 04 mov ecx, DWORD PTR _pParm$[esp-4] 

  00004 33 c0 xor eax, eax 

  00006 80 39 00 cmp BYTE PTR [ecx], 0 

  00009 75 03 jne SHORT $L42424 

$L42423: 



; 16   : { 

; 17   : i++; 



  0000b 40 inc eax 



; 12   : bool* pbExit = static_cast<bool*>(pParm); 

; 13   : int i = 0; 

; 14   : 

; 15   : while( !*pbExit) 

////////////////////////////////////////////////////////// 

// 이 부분 보이시죠? 비교도 안하고 무조건 점프하는 모습!! 

  0000c eb fd jmp SHORT $L42423 -> 

$L42424: 



; 18   : } 


(2) Volatile있는 경우

; 12   : volatile bool* pbExit = static_cast<volatile bool*>(pParm); 

; 13   : int i = 0; 

; 14   : 

; 15   : while( !*pbExit) 



  00000 8b 4c 24 04 mov ecx, DWORD PTR _pParm$[esp-4] 

  00004 33 c0 xor eax, eax 

  00006 80 39 00 cmp BYTE PTR [ecx], 0 

  00009 75 07 jne SHORT $L42424 

$L42423: 



; 16   : { 

; 17   : i++; 



0000b 40 inc eax 

//////////////////////////////////////////////// 

// 이 부분 보이시죠?? 비교해서 분기하는 모습!! 

  0000c 8a 11 mov dl, BYTE PTR [ecx] 

  0000e 84 d2 test dl, dl 

  00010 74 f9 je SHORT $L42423 

$L42424: 



; 18   : } 



- 2001.08.06 Smile Seo -

AND

출처: http://www.winapi.co.kr/clec/cpp2/15-1-4.htm

15-1-라.volatile

volatile 키워드는 const와 함께 변수의 성질을 바꾸는 역할을 하는데 이 둘을 묶어 cv 지정자(Qualifier:제한자라고 번역하기도 한다)라고 한다. const에 비해 상대적으로 사용 빈도가 지극히 낮으며 이 키워드가 꼭 필요한 경우는 무척 드물다. 어떤 경우에 volatile이 필요한지 다음 코드를 보자.

 

int i;

double j;

 

for (i=0;i<100;i++) {

     j=sqrt(2.8)+log(3.5)+56;

     // do something

}

 

이 코드는 루프를 100번 실행하면서 어떤 작업을 하는데 루프 내부에서 j에 복잡한 연산 결과를 대입하고 있다. j값을 계산하는 식이 조금 복잡하지만 제어 변수 i값을 참조하지 않기 때문에 i 루프가 실행되는동안 j의 값은 상수나 마찬가지이며 절대로 변경되지 않는다. 루프 실행중에는 상수이므로 이 값을 매 루프마다 다시 계산하는 것은 시간 낭비이다. 그래서 제대로 된 컴파일러는 이 루프를 다음과 같이 수정하여 컴파일한다.

 

j=sqrt(2.8)+log(3.5)+56;

for (i=0;i<100;i++) {

     // do something

}

 

j의 값을 계산하는 식을 루프 이전으로 옮겨서 미리 계산해 놓고 루프 내부에서는 j값을 사용하기만 했다. 어차피 루프 내부에서 j값이 바뀌는 것이 아니므로 이렇게 코드를 수정해도 원래 코드와 완전히 동일한 동작을 할 것이다. 똑똑한 컴파일러는 프로그래머가 코드를 대충 짜 놓아도 속도를 높이기 위해 자동으로 최적화를 하는 기능을 가지고 있으며 이런 암묵적인 최적화 기능에 의해 프로그램의 성능이 향상된다.

그렇다면 위 두 코드가 정말로 완전히 동일할까 의심을 가져 보자. j는 분명히 루프 내부에서 상수이므로 미리 계산해 놓아도 아무 문제가 없음이 확실하다. 그러나 아주 특수한 경우 최적화된 코드가 원래 코드와 다른 동작을 할 경우가 있다. 어떤 경우인가 하면 프로그램이 아닌 외부에서 j의 값을 변경할 때이다.

도스 환경에서는 인터럽트라는 것이 있고 유닉스 환경에서는 데몬, 윈도우즈 환경에서는 서비스 등의 백그라운드 프로세스가 항상 실행된다. 이런 백그라운드 프로세스가 메모리의 어떤 상황이나 전역변수를 변경할 수 있으며 같은 프로세스 내에서도 스레드가 여러 개라면 다른 스레드가 j의 값을 언제든지 변경할 가능성이 있다. 또한 하드웨어에 의해 전역 환경이 바뀔 수도 있다.

예를 들어 위 코드를 실행하는 프로세스가 두 개의 스레드를 가지고 있고 다른 스레드에서 어떤 조건에 의해 전역변수 j값(또는 j에 영향을 미치는 다른 값)을 갑자기 바꿀 수도 있다고 하자. 이런 경우 루프 내부에서 매번 j값을 다시 계산하는 것과 루프에 들어가기 전에 미리 계산해 놓는 것이 다른 결과를 가져올 수 있다. i루프가 50회째 실행중에 다른 스레드가 j를 바꾸어 버릴 수도 있는 것이다.

이런 경우에 쓰는 것이 바로 volatile이다. 이 키워드를 변수 선언문 앞에 붙이면 컴파일러는 이 변수에 대해서는 어떠한 최적화 처리도 하지 않는다. 컴파일러가 보기에 코드가 비효율적이건 어쨌건 개발자가 작성한 코드 그대로 컴파일한다. 즉 volatile 키워드는 "잘난척 하지 말고 시키는 대로 해"라는 뜻이다. 어떤 변수를 다른 프로세스나 스레드가 바꿀 수도 있다는 것을 컴파일러는 알 수 없기 때문에 전역 환경을 참조하는 변수에 대해서는 개발자가 volatile 선언을 해야 한다. 위 코드에서 j 선언문 앞에 volatile만 붙이면 문제가 해결된다.

 

volatile double j;

 

이 키워드가 반드시 필요한 상황에 대한 예제를 만들어 보이는 것은 굉장히 어렵다. 왜냐하면 외부에서 값을 바꿀 가능성이 있는 변수에 대해서만 이 키워드가 필요한데 그런 예제는 보통 크기가 아니기 때문이다. 잘 사용되지 않는 키워드이므로 여기서는 개념만 익혀 두도록 하자.

 

AND

출처: http://www.edm2.com/0201/hooks.html

Utilizing Hooks for Added Capabilities

Written by Larry Salomon, Jr.

 

Introduction

Beginning with the MVS operating system, user exits have existed in order to give those with a bit of programming skill the opportunity to change the default behavior for a particular event. Since then, these have evolved into system hooks, which provide the same ability; unfortunately, whether known as user exits or system hooks, there has been a lack of documentation on how to utilize these provisions from with OS/2 applications.

This article will discuss what hooks are, what the different types of hooks are, and the uses of some of the various types of hooks. Finally, we will look at a (new) version of Life Saver, which uses one of the hooks to implement a screen saver.

Going Fishing?

What is a hook? In the sport of fishing, a hook attaches the fishing line) to the fish so that the line follows the movement of the fish. In programming, the concept is similar - you use a hook to attach your application to an event so that your application knows whenever the event occurs. Why is this useful? Consider an application that needs to know when the system is rebooting, or needs to know whenever the PrintScreen key was pressed (regardless of who has the focus). These types of things can only be done with hooks.

OS/2 defines 17 types of hooks that can be set.

Send message event (HK_SENDMSG)
The hook is invoked whenever WinSendMsg() is called.
Input event (HK_INPUT)
The hook is invoked whenever WinPostMsg() is called, including - and especially - for all mouse and keyboard input.
Message filter (HK_MSGFILTER)
The hook is invoked during any Win function which enters a message loop, e.g. WinDlgBox(), WinMessageBox(), etc.
Journal record (HK_JOURNALRECORD)
The hook is invoked to record (journal) a message.
Journal playback (HK_JOURNALPLAYBACK)
The hook is invoked to play back a journaled message.
Help event (HK_HELP)
The hook is invoked whenever help is requested by the user or an application.
Library and procedure event (HK_LOADER)
The hook is invoked whenever WinLoadLibrary() or WinLoadProcedure() is called.
User message registration event (HK_REGISTERUSERMSG)
The hook is invoked whenever WinRegisterUserMsg() is called.
Message control event (HK_MSGCONTROL)
The hook is invoked whenever any of the following four functions are called: WinSetClassMsgInterest(), WinSetMsgInterest(), WinSetMsgMode(), and WinSetSynchroMode().
Find word event (HK_FINDWORD)
The hook is invoked whenever a word to be drawn by the WinDrawText() function is too long to fit within the bounding rectangle.
Code page change event (HK_CODEPAGECHANGED)
The hook is invoked whenever a message queue's code page changes.
Device context association event (HK_WINDOWDC)
The hook is invoked whenever a device context is associated with a window.
Window destroy event (HK_DESTROYWINDOW)
The hook is invoked whenever a window is destroyed.
Message filter event (HK_CHECKMSGFILTER)
The hook is invoked whenever WinGetMsg() or WinPeekMsg() is called.
Input insertion (HK_MSGINPUT)
The hook is used to insert mouse or keyboard messages similar to the journal playback hook.
System lockup event (HK_LOCKUP)
The hook is invoked whenever WinLockupSystem() is called.
System shutdown event (HK_FLUSHBUF)
The hook is invoked whenever the Ctrl-Alt-Del key sequence is pressed.
The user message registration event is generated by a function that is no longer documented. The WinRegisterUserMessage() function existed in the 1.3 Toolkit documentation but does no longer.

Two other hooks - HK_PLIST_ENTRY and HK_PLIST_EXIT - are also defined in pmwin.h but they do not exist within the system (as far as I know).

Hook Contexts

Some hooks can be defined as application-wide or system-wide; the difference is that an application-wide hook will be called whenever the event occurs within the application, while a system-wide hook will be called whenever the event occurs anywhere within the system. Because of this property of system-wide hooks, the corresponding hook procedure must reside within a DLL. This has other interesting connotations which we will see later.

Some hooks must be application-wide, while others must be system-wide. Such hooks do not have a choice.

Chaining Hooks

In reality, a hook is nothing more than a function that accepts one or more arguments. The function is called by the system, meaning that the function must be exportable and use the _System calling convention. Additionally, the system must be made aware of the hook's existance; it is registered via the function WinSetHook(). Similarly, when the hook is to be removed, the function WinReleaseHook() is called.

hook1.gif
Figure 1) Before and after calling WinSetHook().

BOOL WinSetHook(HAB habAnchor,
                HMQ hmqQueue,
                LONG lHookType,
                PFN pfnHook,
                HMODULE hmModule);
BOOL WinReleaseHook(HAB habAnchor,
                    HMQ hmqQueue,
                    LONG lHookType,
                    PFN pfnHook,
                    HMODULE hmModule);
Both function take the following parameters:
habAnchor
Anchor block of the calling thread.
hmqQueue
Handle of the message queue to install the hook on. This can also be HMQ_CURRENT to specify the message queue of the calling thread, or NULLHANDLE if this is to be a system-wide queue.
lHookType
One of the HK_* constants (see the first section).
pfnHook
Pointer to the hook procedure.
hmModule
Handle to the DLL containing the hook procedure. This must be specified if hmqQueue is NULLHANDLE.
Functions for the various hook types are chained together, which allows for multiple hook functions to be installed for a particular hook type. The WinSetHook() call installs the hook function at the head of the chain.
hook2.gif
Figure 2) Multiple hooks of the same type. The hook on top was installed last using WinSetHook().

This is important because some Win functions install hooks themselves, such as the WinCreateHelpInstance() function. Since the help hook installed by this function indicates to the system that no other hooks after it should be called, any help hooks you install before calling this function will never see any help events.

Two Examples

A Small Example

Consider the application provided as hooks.zip. It is nothing more than a dialog box with two hooks attached - the associate window HDC hook, and the destroy window hook. Whenever either hook is invoked, they beep if the window provided is a frame window.


BOOL EXPENTRY assocWindowHook(HAB habAnchor,
                              HDC hdcContext,
                              HWND hwndAssoc,
                              BOOL bAssoc)
//-------------------------------------------------------------------------
// This hook is invoked whenever an HDC is associated or disassociated with
// a window.
//
// Input:  habAnchor - anchor block of the thread in whose context the
//                     event occurred.
//         hdcContext - handle of the device context.
//         hwndAssoc - handle of the window associated/disassociated.
//         bAssoc - TRUE if hwndAssoc is associated with hdcContext.  FALSE
//                  otherwise.
// Returns:  TRUE if successful processing, FALSE otherwise.
//-------------------------------------------------------------------------
{
   CHAR achClass[256];

   WinQueryClassName(hwndAssoc,sizeof(achClass),achClass);

   if ((WinFindAtom(WinQuerySystemAtomTable(),
                    achClass)==LOUSHORT(WC_FRAME)) && bAssoc) {
      WinAlarm(HWND_DESKTOP,WA_NOTE);
   } /* endif */

   return TRUE;
}

BOOL EXPENTRY destroyWindowHook(HAB habAnchor,
                                HWND hwndDestroy,
                                ULONG ulReserved)
//-------------------------------------------------------------------------
// This hook is invoked whenever a window is destroyed.
//
// Input:  habAnchor - anchor block of the thread in whose context the
//                     event occurred.
//         hwndDestroy - handle of the window being destroyed.
//         ulReserved - reserved.
// Returns:  TRUE if successful processing, FALSE otherwise.
//-------------------------------------------------------------------------
{
   CHAR achClass[256];

   WinQueryClassName(hwndDestroy,sizeof(achClass),achClass);

   if (WinFindAtom(WinQuerySystemAtomTable(),achClass)==LOUSHORT(WC_FRAME))
{

      WinAlarm(HWND_DESKTOP,WA_ERROR);
   } /* endif */

   return TRUE;
}
Figure 3) Two simple hook procedures.

The hooks are installed, as we noted, using the WinSetHook() call and are released using the WinReleaseHook() call.


WinSetHook(habAnchor,
           HMQ_CURRENT,
           HK_WINDOWDC,
           (PFN)assocWindowHook,
           NULLHANDLE);
WinSetHook(habAnchor,
           HMQ_CURRENT,
           HK_DESTROYWINDOW,
           (PFN)destroyWindowHook,
           NULLHANDLE);
  :
  :
WinReleaseHook(habAnchor,
               HMQ_CURRENT,
               HK_WINDOWDC,
               (PFN)assocWindowHook,
               NULLHANDLE);
WinReleaseHook(habAnchor,
               HMQ_CURRENT,
               HK_DESTROYWINDOW,
               (PFN)destroyWindowHook,
               NULLHANDLE);
Figure 4) WinSetHook() and WinReleaseHook() calls.

Note that the hooks are local to the message queue for the thread. Also, note how the hook procedures are cast to the generic type PFN to avoid warnings/errors by the compiler.

A Large Example

Now, look at the application provided in life.zip. This is a screen saver which utilizes the input hook to determine when a period of inactivity elapses; actually, the word should be "expires" since the input hook is invoked when there is no inactivity. The strategy for the application is to start a timer using WinStartTimer() to count the number of seconds of inactivity. Whenever the input hook is invoked, it tells the application to reset this counter. Should the threshold be reached, the screen saver goes into effect.

There are a couple of interesting points to be made:

  1. The hook is a system-wide hook. Since this means it can be invoked from within the context of any process, it must reside in a DLL.
  2. Since the hook and the application need to share data but the DLL needs to access it from within any process' context, the data must be declared in the DLL and a pointer to it is kept by the application. Additionally, the DLL has the attributes DATA SHARED SINGLE specified in the .DEF file to indicate that all processes share the same copy of the DLL's data segment.

Summary

Hooks provide a way to code certain types of logic into your application, which could not be done (easily) in other ways. While they are very useful, care must be taken because, in the case of system-wide hooks, what you do affects the entire system. For example, in a send message hook, you wouldn't use WinSendMsg() to notify your application, or else you would have an endless loop. For all development involving hooks, one must be sure that the design is completely worked out, or you could spend fruitless hours debugging your hook...and these are not easy beasts to debug, either.

Probably the worst detriment during development is the lack of good documentation. Many of the hooks are scantily documented in pmwin.h at best, while others have incorrect parameters listed, making things even more difficult. If you have access to CompuServe, the best help you can get is from the IBMers that reside there, since they have been using many of these hooks since their first appearance.

AND

출처: http://www.presenter5.com/OpenSourceBuild.htm

Open Source Build Instructions


DISCLAIMER

HCL DOES NOT PROVIDE ANY WARRANTY OF THE OPEN SOURCE SOFTWARE(S) AND HCL HEREBY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED INCLUDING WARRANTY MERCHANTABILITY, NON-INFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO OPEN SOURCE SOFTWARE(S) TO DOWNLOAD.

HCL SHALL HAVE NO LIABILITY DIRECT OR INDIRECT, WITH RESPECT TO YOUR LICENSE YOU MAY AGREE TO THEIR TERMS AND CONDITIONS OF THE RESPECTIVE OPEN SOURCE SOFTWARE(S).

HIGHLIGHTS


Firefox 1.5.0.2 (Required for Web Browser Widget)

URL

http://releases.mozilla.org/pub/mozilla.org/firefox/releases/1.5.0.2/source/

SIZE

34 MB

BUILD STEPS

Windows

VC6/ VC7

The Firefox-1.5.0.2 build on Windows platform requires the build of Mozilla source code. The build process involves the following steps:

  1. Download Firefox-1.5.0.2 source code

Software

Download URL

File Name

Firefox-1.5.0.2 https://sourceforge.net/project/showfiles.php?group_id=152554&package_id=187307  firefox-1.5.0.2-source.tar.bz2  
  1. Unzip the Firefox-1.5.0.2-source.tar.bz2  to any drive on your machine.

           NOTE: In Firefox build we are considering the E:\ drive for building the source. You can build this source in any of the drives.

E:\cygwin\bin

Software Requirements

The following software needs to be installed for a standard Windows build.

  • GNU Tools for Microsoft Windows (Cygwin)

Cygwin is a UNIX-like environment for Windows. Firefox uses a developer set of cygwin packages, which must be installed.

You can download the cygwin from the following link http://www.cygwin.com/

These include gawk, make and zip utilities.

Install these utilities into E:\cygwin\. Remember to choose Unix as "Default Text File Type". Besides the default modules, install the following modules.

  • cvs

  • cygutils

  • make

  • patch

  • patchutils

  • perl

  • unzip

  • zip

  • libiconv

By default following modules should be installed.

  • ash

  • diffutils

  • fileutils

  • findutils

  • gawk

  • grep

  • sed

  • sh-utils

  • textutils

Download the make.exe 3.80 version from the following link   http://developer.mozilla.org/en/docs/Windows_build_prerequisites_using_cygwin

Copy the downloaded make.exe in the E:\cygwin\bin

  • Netscape wintools

Netscape's wintools.zip contains pre-built libraries and tools which are required to build Mozilla.

Download the Netscape's wintools.zip from the following link http://www.mozilla.org/build/win32-nmake.html

 

Extract the zip file into a temporary directory. Open a command prompt, and set the system variable MOZ_TOOLS to the directory where you have installed the MOZ tools. For example,

set MOZ_TOOLS=E:\mozilla\mozilla\moztools

The MOZ_TOOLS directory should neither be inside the cygwin installation directory nor in any of the sub-directories of  cygwin. If it is existed in any of the above mentioned locations, the build will be failed.

Run the wintools script. This batch script will install the files into %MOZ_TOOLS%/bin.

Finally, run the following commands.

cd moztools\buildtools\windows

install.bat

  • Compiler and linker

Microsoft Visual Studio 6.0

Use MSVC command line tools, such as CL for C/C++ compiler.

To build the Firefox you need to install Visual Studio Service Pack 5 and Visual C++ Processor Pack(http://msdn2.microsoft.com/en-us/vstudio/aa718349.aspx)

Run the vcvars32.bat on the command prompt.

Configuring Environment

Creating mozconfig.txt

  • Create a file, mozconfig.txt in E:\mozilla\.

  • To build Firefox, put the following code in mozconfig.txt.

mk_add_options BUILD_OFFICIAL=1

mk_add_options MOZ_OFFICIAL=1

mk_add_options MOZ_CO_PROJECT=browser

mk_add_options MOZ_OBJDIR="@TOPSRCDIR@/../obj-win32"

ac_add_options --disable-debug

ac_add_options --enable-application=browser

ac_add_options --disable-tests

ac_add_options --disable-static

ac_add_options --disable-strip

ac_add_options --disable-accessibility

ac_add_options --disable-updater

@echo off

set MOZ_TOOLS=E:\mozilla\mozilla\moztools
(Set to the place where you want Netscape's wintools.zip to install its binaries.)

set HOME=E:\mozilla

set PATH=%PATH%;E:\cygwin\bin;%MOZ_TOOLS%\bin
(Include both the Netscape wintools and the cygwin UNIX-like tools in your command search path.)

set LIB=%LIB%;%MOZ_TOOLS%\bin

set MOZCONFIG=E:\mozilla\mozilla\mozconfig.txt (Set path to mozconfig.txt)

  • Run mozset.bat on the command prompt.

Now build the Firefox using the following command.

cd E:\Mozilla\mozilla
make -f client.mk build_all

GCC

 The Firefox-1.5.0.2 build on Windows GCC platform requires the build of Mozilla source code. The build involves the following steps:

  1.  Download Firefox-1.5.0.2 source code

Software

Download URL

File Name

Firefox-1.5.0.2 https://sourceforge.net/project/showfiles.php?group_id=152554&package_id=187307  firefox-1.5.0.2-source.tar.bz2

Software Requirements

    The following software needs to be installed for a standard GCC build.

  1. binutils-2.16.91-20060119-1.tar.gz

  2. gcc-core-3.4.5-20060117-1.tar.gz

  3. gcc-g++-3.4.5-20060117-1.tar.gz

  4. mingw32-make-3.80.0-3.exe

  5. mingw-runtime-3.9.tar.gz

  6. w32api-3.6.tar.gz

Extract/Install all the above packages in the same folder, e.g. c:\mingw

NOTE: In Firefox build we are considering the c:\ drive for building the source. You can build this source in any of the drives.

  • GNU Tools for Microsoft Windows (Cygwin)

Cygwin is a UNIX-like environment for Windows. A developer set of cygwin package is required to be installed to build Firefox.

Download the cygwin from the following link http://www.cygwin.com/

Install Cygwin into a folder, such as c:\cygwin. Remember to choose Unix as "Default Text File Type". Besides the default modules, install the following modules:

  • cvs

  • cygutils

  • make

  • patch

  • patchutils

  • perl

  • unzip

  • zip

  • libiconv

To perform this, press the View button in the Select Packages part of the installer.

By default the following modules should be installed.

  • ash

  • diffutils

  • fileutils

  • findutils

  • gawk

  • grep

  • sed

  • sh-utils

  • textutils

Download the make.exe 3.80 version from the following link  

http://developer.mozilla.org/en/docs/Windows_build_prerequisites_using_cygwin

Copy the downloaded make.exe in the c:\cygwin\bin

  • Netscape wintools

Netscape's wintools.zip contains pre-built libraries and tools which are required to build Mozilla.

You can easily download the Netscape's wintools.zip from the following link

 http://ftp.mozilla.org/pub/mozilla.org/mozilla/source/wintools.zip

Create a folder moztools and put the wintools in it.

Untar mozilla source to any drive on your machine (say c: drive), name the source folder as Mozilla.

Configuring Environment

Creating mozconfig.txt

  • Create a file called mozconfig.txt in $(HOME)\mozilla\. 
To build Firefox, put the following code in mozconfig.txt. 

CC=gcc CXX=g++ CPP=cpp AS=as LD=ld

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-opt

mk_add_options BUILD_OFFICIAL=1

mk_add_options MOZILLA_INTERNAL_API=1

mk_add_options MOZ_CO_PROJECT=browser

ac_add_options --enable-extensions

ac_add_options --disable-debug

ac_add_options --enable-application=browser

ac_add_options --enable-official-branding

ac_add_options --enable-canvas

ac_add_options --disable-tests

ac_add_options --disable-installer

ac_add_options --enable-svg

ac_add_options --enable-crypto

ac_add_options --enable-shared

ac_add_options --disable-static

ac_add_options --disable-strip

ac_add_options --disable-accessibility

ac_add_options --disable-activex

ac_add_options --disable-updater

ac_add_options --disable-activex-scripting

  • Create a batch file called mozset.bat in $(HOME)\mozilla directory containing the following code.

set HOME=c:\mozilla

set MOZ_TOOLS=$(HOME)\mozilla\moztools

set path=c:\mingwbin;c:\cygwin\bin;%MOZ_TOOLS%\bin;%path%

set HOME=$(HOME)\mozilla

set CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot

set MOZCONFIG=$(HOME)\mozilla\mozconfig.txt

Now perform the following steps.
  1. Open command prompt and go the $(HOME)\mozilla directory

  2. Run mozset.bat

  3. Now compile the source using make –f client.mk build_all

  4. After compilation gets completed, go to the $(HOME)\mozilla\obj-opt\dist\bin and type firefox to run the binary.

UNIX

To integrate Firefox browser with Presenter on Unix platform few lines in the file available at mozilla/widget/src/xlib/nsAppShell.cpp is required to be changed. This patch automatically changes the original code with the changed code.

To do the same, perform the following steps.

  1. Click the link Mozilla changes for  Presenter integration to download the tar file.

  2. Untar this file using the following command at the command prompt.

          tar -xvf mozilla_changes_script.tar

          When the respective file gets untarred a directory by the name of script is created in the current working directory.

  1. Go to the respective directory and run the patch.csh script.

LINUX (Red Hat Linux 9.0)

  1. Download Firefox-1.5.0.2 source code.

Software

Download URL

File Name

Firefox-1.5.0.2 https://sourceforge.net/project/showfiles.php?group_id=152554&package_id=187307  firefox-1.5.0.2-source.tar.bz2
  1. Open a Linux Bash-shell and enter the following commands in a Bash-shell to extract the Firefox source code:

bunzip2 firefox-1.5.0.2-source.tar.bz2

tar  –xvf firefox-1.5.0.2-source.tar

This will create a directory named “mozilla”.

Software Requirements

The following softwares should be installed before starting the Firefox build.

  • Compiler used gcc-3.3.2

  • glibc 2.2 (only)
  • Perl  version 5.8. (You can check the Perl version using the command Perl -v.)
  • GTK2 not to be used.
  • XFT not to be used.
  • FreeType2 not to be used.

Links to download required software.

Configuring Environment
  1. Create the .mozconfig file in the mozilla directory with the following configuration options.

mk_add_options MOZ_PHOENIX=1

ac_add_options --disable-accessibility

ac_add_options --disable-calendar

ac_add_options --disable-composer

ac_add_options --disable-debug

ac_add_options --disable-installer

ac_add_options --disable-jsd

ac_add_options --disable-ldap

ac_add_options --disable-mailnews

ac_add_options --disable-tests

ac_add_options --enable-strip

ac_add_options --enable-strip-libs

ac_add_options --disable-shared

ac_add_options --enable-static

ac_add_options --enable-optimize="-O2 -march=i686 -finline-functions -fforce-addr -fno-strict-aliasing"

ac_add_options --enable-extensions="help,cookie,xml-rpc,xmlextras,p3p,pref,transformiix,universalchardet,typeaheadfind,webservices"

ac_add_options --enable-old-abi-compat-wrappers

ac_add_options --disable-toolkit-gtk2

ac_add_options --enable-default-toolkit=xlib

ac_add_options --disable-toolkit-gtk

ac_add_options --disable-toolkit-qt

ac_add_options --enable-toolkit-xlib

ac_add_options --disable-xft

ac_add_options --enable-mathml

ac_add_options --enable-xsl

ac_add_options --enable-crypto

ac_add_options --enable-ipv6

ac_add_options --without-system-nspr

ac_add_options --enable-nspr-autoconf

ac_add_options --enable-xterm-updates

ac_add_options --enable-elf-dynstr-gc

ac_add_options --disable-pedantic

ac_add_options --disable-freetype2

  1. Set the following environment variables.
export MOZ_PHOENIX=1
export MOZILLA_OFFICIAL=1
export BUILD_OFFICIAL=1
  1. Set the required path using the following command.
export PATH=/USR/X11R6/lib:$PATH
  1. Ensure that gmake and zip commands are in the current path and start the Firefox build.
 Starting Firefox build
  • Enter the following command in the “mozilla” directory to start the Firefox build.

gmake –f client.mk build

Checking Firefox build for successful completion
  • Go to the directory mozilla/obj-opt/dist/bin and execute the following command.
./run-mozilla.sh ./firefox

SOLARIS

  1. Download Firefox-1.5.0.2 source code

Software

Download URL

File Name

Firefox-1.5.0.2 https://sourceforge.net/project/showfiles.php?group_id=152554&package_id=187307  firefox-1.5.0.2-source.tar.bz2
  1. Open a Solaris shell and enter the following commands in a C-shell to extract the Firefox source code.

bunzip2 firefox-1.5.0.2-source.tar.bz2

tar –xvf firefox-1.5.0.2-source.tar

This will create a directory named “mozilla”.

Software Requirements

The following software’s should be installed before starting the Firefox build:

  • libIDL 0.6.8. If libIDL is installed at /usr/local/ directory, then one can check the libIDL version by using “libIDL-config –version” command. Otherwise, find the directory at which libIDL is installed, append it in the PATH environment variable.

  • perl 5.0 or higher. (To determine the Perl version, use perl –v command.)

  • GNU make 3.74 or higher, except 3.77. (To determine the GNU make version use, gmake –v command.)

  • Zip 2.32. (It is a compression and file packaging utility.)

Links to download required softwares:

 To build libIDl 0.6.8

  1. tar –xvf <libIDL-source>.tar
  2. ./configure
  3. vi Makefile and on line 126 comment as here
  4. libIDL_la_LDFLAGS = #-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
  5. -release $(LT_RELEASE)
  6. make
  7. Enter super user mode using “su” command and do “make install” to install the libIDL in appropriate directories.

 Set the required environment variables using the following commands.

  1. setenv CFLAGS="-xlibmil"
  2. setenv CXXFLAGS="-xlibmil -xlibmopt -features=tmplife -norunpath"
  3. setenv ORIGIN
  4. setenv LDFLAGS='-R$ORIGIN -R/usr/sfw/lib -R/opt/sfw/lib -R/usr/local/lib'
  5. setenv MOZ_PHOENIX 1
  6. setenv MOZ_XUL_APP 1
  7. setenv MOZ_APP_NAME firefox
  8. setenv CC cc
  9. setenv CXX CC
  10. setenv CCC CC
Configuring Environment

Create the .mozconfig file in the mozilla directory with the following configuration options:

mk_add_options MOZ_CO_PROJECT=browser

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-opt

mk_add_options MOZ_PHOENIX=1

ac_add_options --enable-optimize="-xO3"

ac_add_options --disable-ldap

ac_add_options --disable-mailnews

ac_add_options --enable-extensions="cookie,xml-rpc,xmlextras,pref,transformiix,universalchardet,webservices,inspector,p3p,gnomevfs"

ac_add_options --enable-crypto

ac_add_options --disable-composer

ac_add_options --disable-debug

ac_add_options --disable-tests

ac_add_options --disable-static

ac_add_options --enable-shared

ac_add_options --enable-single-profile

ac_add_options --disable-profilesharing

ac_add_options --with-xprint

ac_add_options --enable-xinerama

ac_add_options --enable-x11-shm

ac_add_options --enable-ctl

ac_add_options --enable-default-toolkit=xlib

ac_add_options --disable-freetype2

ac_add_options --disable-xft

#ac_add_options --without-system-nspr

ac_add_options --without-system-zlib

ac_add_options --without-system-jpeg

ac_add_options --without-system-png

ac_add_options --without-system-mng

ac_add_options --x-includes=/usr/openwin/include

ac_add_options --x-libraries=/usr/openwin/lib

mk_add_options BUILD_OFFICIAL=1

mk_add_options MOZILLA_OFFICIAL=1

 
Set the required paths using the following commands.
  1. setenv PATH $PATH:/usr/local/bin:/opt/sfw/bin:/opt/SUNWspro/bin:/usr/bin::/usr/dt/bin:/usr/openwin/bin:/bin:/usr/ccs/bin:/usr/ucb:/usr/sfw/bin
  2. setenv LD_LIBRARY_PATH /usr/openwin/lib:/usr/local/lib:/usr/sfw/lib:/opt/sfw/lib

Ensure that gmake and zip commands are in the current path and start the Firefox build.

Starting Firefox build
  1. Enter the following command in the “mozilla” directory to start the Firefox build.

gmake –f client.mk build_all

Checking Firefox build for successful completion

  1. Go to the directory mozilla/obj-opt/dist/bin and execute the following command:
./run-mozilla.sh ./firefox

HPUX

  1. Download Firefox-1.5.0.2 source code.

Software

Download URL

File Name

Firefox-1.0

http://releases.mozilla.org/pub/mozilla.org/firefox/releases/1.0/source/

Direct download link: http://releases.mozilla.org/pub/mozilla.org/firefox/releases/1.0/source/firefox-1.0-source.tar.bz2 

firefox-1.0-source.tar.bz2
  1.  Untar the Firefox source code. It will create a “mozilla” directory.

Software Requirements

The following softwares should be installed before starting the Firefox build:

  • libIDL 0.6.8. If libIDL is installed at /usr/local/ directory, then one can check the libIDL version by using “libIDL-config –version” command. Otherwise, find the directory at which libIDL is installed, append it in the PATH environment variable.

  • perl 5.0 or higher.(To determine the Perl version, use perl –v command.)

  • GNU make 3.74 or higher, except 3.77. (To determine the GNU make version use, gmake –v command.)

  • Zip 2.32. (It is a compression and file packaging utility.)

Links to download required softwares.

Setting up the environment variable and compiler flag
Setting up the path for libIDL and HPUX native compiler aCC.
 
setenv PATH /opt/libIDL/bin:/usr/bin:/opt/aCC/bin:$PATH
 
Setting up the library path for libIDL:
 
setenv SHLIB_PATH /opt/libIDL/lib
setenv LIBIDL_CONFIG /opt/libIDL/bin/libIDL-config
 
Setting up the aCC compiler Flags:
 
setenv CC 'cc -Ae +DA1.1 +DS2.0'
setenv CXX 'aCC -ext +p +DA1.1 +DS2.0'
setenv CFLAGS '-DHPUX11 -Dhpux'
setenv CXXFLAGS '-DHPUX11 -Dhpux'

Code addition in Firefox

NSPR provides platform independence for non-GUI operating system facilities. These facilities include threads, thread synchronization, normal file and network I/O, interval timing and calendar time, basic memory management (malloc and free) and shared library linking.

In HPUX 11i, the system header file netdb.h does not define the addressinfo structure that provides hints about the type of socket the caller supports, which is used by the getaddrinfo function that provides protocol-independent translation from host name to address. To resolve this, we have created a header file called hpsock.h that defines addressinfo structure and the necessary macros needed by getaddrinfo function.

To update the Mozilla changes for HPUX in firefox source code please refer to the Unix section

Configuring Environment

Create the .mozconfig file in the mozilla directory with the following configuration options.

. $topsrcdir/browser/config/mozconfig

mk_add_options MOZ_PHOENIX=1

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-opt

ac_add_options --disable-auto-deps

mk_add_options MOZ_CO_PROJECT=browser

ac_add_options --enable-application=browser

 

ac_add_options --disable-accessibility

ac_add_options --disable-calendar

ac_add_options --disable-composer

ac_add_options --disable-debug

ac_add_options --disable-installer

ac_add_options --disable-jsd

ac_add_options --disable-ldap

ac_add_options --disable-mailnews

ac_add_options --disable-tests

ac_add_options --enable-strip

ac_add_options --enable-strip-libs

ac_add_options --enable-shared

ac_add_options --enable-extensions="help,cookie,xml-rpc,xmlextras,p3p,pref,transformiix,universalchardet,typeaheadfind,webservices"

ac_add_options --disable-toolkit-gtk2

ac_add_options --enable-default-toolkit=xlib

ac_add_options --disable-toolkit-gtk

ac_add_options --disable-toolkit-qt

ac_add_options --enable-toolkit-xlib

ac_add_options --disable-xft

ac_add_options --enable-mathml

ac_add_options --enable-xsl

ac_add_options --enable-crypto

ac_add_options --enable-xterm-updates

ac_add_options --disable-pedantic

ac_add_options --disable-freetype2
  
Starting Firefox Build
  • Give the following command in the “mozilla” directory to start the Firefox build:

gmake –f client.mk build_all

Resolving Build Errors

You may come across thread related linking error “Unsatisfied symbols: pthread_join” in the module <xxx>/mozilla/toolkit/mozapps/update/src/updater. 
To resolve this error use the option “-lcma” during linking.

Checking Firefox build for successful completion

  1. Go to the following directory. 
mozilla/obj-opt/dist/bin 
  1. Execute the following command.

./run-mozilla.sh ./firefox

Integration with Presenter

For all Windows Platforms

    Copy all the files from obj-win32\dist\bin folder to 3rdparty\dll folder.

For all UNIX Platforms

    Copy all the files from dist/bin folder to 3rdparty/dll folder.


gSOAP 2.7.6e (Required for Web Services)

URL

http://sourceforge.net/project/showfiles.php?group_id=52781&package_id=68161

For gSOAP, OpenSSL is also required. Please visit website http://www.openssl.org/

SIZE

5.7 MB.

BUILD STEPS

Windows (VC 6/ VC 7/ Gcc)

  1.  Download gSOAP 2.7.6e and OpenSSL sources from the following websites.

Software

Download URL

File Name

gSOAP http://sourceforge.net/project/showfiles.php?group_id=52781&package_id=68161&release_id=394790 gsoap_win32_2.7.6e.zip
OpenSSL http://www.slproweb.com/products/Win32OpenSSL.html Win32OpenSSL-0_9_8e.exe
  1. Unzip the contents of gsoap_win32_2.7.6e.zip to a temporary folder. For e.g., c:\gsoap

  2. Install Win32OpenSSL-0_9_8e.exe to a temporary folder. For e.g., c:\openssl

  3. Change to the gSoap directory:

cd c:\gsoap

  1. Create an empty file named “env.h” in the current gsoap directory.

  2. Set up the Visual C++ environment using vcvars32.bat

  3. Copy libeay32MD.lib and ssleay32MD.lib from C:\openssl\lib\VC to C:\gsoap folder and rename the  libraries using the following commands.

copy c:\openssl\lib\VC\libeay32MD.lib c:\gsoap\libeay32.lib

copy c:\openssl\lib\VC\ssleay32MD.lib c:\gsoap\ssleay32.lib

  1. Create a makefile named mkdll_gsoap.mak with the following contents.

# NMAKE for gsoap DLL

 

#Use VC++ compiler

CC = cl.exe

 

#Use gSOAP's "soapcpp2" precompiler.

PRECOMP = soapcpp2.exe -c

 

#Use input env file

envINfile = env.h

 

#Base (stdsoap2.dll) DLL source

BDLLSRC = stdsoap2.c envC.c

 

#DLL flag for BaseDLL Output

BDLLFLG = /LD  /DWITH_NONAMESPACES -DWITH_OPENSSL –I*path-to-openssl-include-folder /DSOAP_FMAC1=__declspec(dllexport) /DSOAP_FMAC3=__declspec(dllexport)

 

#DLL flag for final Output

DLLFLG = /LD  /DWITH_NONAMESPACES -DWITH_OPENSSL *path-to-openssl-include-folder /DSOAP_FMAC5=__declspec(dllexport) /DSOAP_CMAC=__declspec(dllexport)

 

#External Linking flag

LINK32_FLG= /link wsock32.lib stdsoap2.lib

 

# top-level rule, to compile everything.

all: dllsoap  basedll

 

#SOAP Header and Fault serializers without namespace

dllsoap:$(envINfile)

           $(PRECOMP) -penv $(envINfile)

 

#Create BaseDLL(stdsoap2.dll)

basedll:

           $(CC) $(BDLLFLG) $(BDLLSRC) /link wsock32.lib libeay32.lib ssleay32.lib

 

#Clean up

clean:

           -@erase "*.pc"

 *path-to-openssl-include-folder: Provide the path to openssl/include folder here.

  1. Build gSOAP using the following command

nmake /f mkdll_gsoap.mak

This command would create the required stdsoap2.dll in the current directory.

Linux

  1.     Download gSOAP 2.7.6e and OpenSSL sources from the following websites.

Software

Download URL

File Name

gSOAP http://sourceforge.net/project/showfiles.php?group_id=52781&package_id=68161&release_id=394790 gsoap_2.7.6e.tar.gz
OpenSSL http://www.openssl.org/source openssl-0.9.8e.tar.gz
  1.  Untar gSOAP and OpenSSL sources using the following commands.

gunzip gsoap_2.7.6e.tar.gz

tar –xvf gsoap_2.7.6e.tar

NOTE: This would create a directory named gsoap-2.7 

gunzip openssl-0.9.8e.tar.gz

tar –xvf openssl-0.9.8e.tar

 NOTE: This would create a directory named openssl-0.9.8e

  1. Change the directory to the gSoap directory.

cd gsoap-2.7

  1. Run the configure script to create the required makefiles.

./configure

  1. Compile the gSoap sources.

make

  1. Change the directory to the soapcpp2 directory

cd soapcpp2

  1. Run the following commands:

touch env.h

./src/soapcpp2 -penv env.h

g++ -c envC.cpp

  1. Copy libcrypto.so and libssl.so from the Presenter 5.3 base kit to the soapcpp2 folder.

  2. Compile and link the gSoap libraries using the following commands:

gcc -DWITH_NONAMESPACES -DWITH_OPENSSL -I/*path-to-openssl-include-folder –cs stdsoap2.c

gcc -shared -o libstdsoap2.so envC.o stdsoap2.o -L. -lcrypto -lssl

         *path-to-openssl-include-folder: Provide the path to openssl/include folder here.

Solaris

  1. Download gSoap 2.7.6e and Openssl sources from the following websites.

Software

Download URL

File Name

gSOAP http://sourceforge.net/project/showfiles.php?group_id=52781&package_id=68161&release_id=394790 gsoap_2.7.6e.tar.gz
OpenSSL http://www.openssl.org/source/ openssl-0.9.8e.tar.gz
  1. Untar gSoap and openssl sources using the following commands:

gunzip gsoap_2.7.6e.tar.gz

tar –xvf gsoap_2.7.6e.tar

Note: This would create a directory named gsoap-2.7

gunzip openssl-0.9.8e.tar.gz

tar –xvf openssl-0.9.8e.tar

            NOTE: This would create a directory named openssl-0.9.8e

  1. Change the directory to the gSoap directory

cd gsoap-2.7

  1. The following file needs to be modified for the gSoap build

soapcpp/src/soapcpp2_yacc.y

         NOTE: For details, please refer to the Modifications details given below.

  1. Set the required environment variables using the following variables

setenv CC cc

setenv CXX CC

  1. Run the configure script to create the required makefiles.

./configure

  1. Compile the gSoap sources

make

  1. Change the directory to the soapcpp2 directory

cd soapcpp2

  1. Run the following commands

touch env.h

./src/soapcpp2 -penv env.h

CC -c envC.cpp

  1. Copy libcrypto.so and libssl.so from the Presenter base kit to the soapcpp2 folder.

  2. Compile and link the gSoap libraries using the following commands

cc -DWITH_NONAMESPACES -DWITH_OPENSSL -I/*path-to-openssl-include-folder– c stdsoap2.c 

cc -b -G -o libstdsoap2.so envC.o stdsoap2.o -L. -lcrypto -lssl

 *path-to-openssl-include-folder: Provide the path to Openssl/include folder here.

 Modification details for gSOAP Solaris Build

 soapcpp/src/soapcpp2_yacc.y

Modified Line no: 115

Original Code

%expect 1

Modified Code

/*%expect 1*/

HPUX

  1. Download gSOAP 2.7.6e and OpenSSL sources from the following websites.

Software

Download URL

File Name

gSOAP http://sourceforge.net/project/showfiles.php?group_id=52781&package_id=68161&release_id=394790 gsoap_2.7.6e.tar.gz
OpenSSL http://www.openssl.org/source/ openssl-0.9.8e.tar.gz
  1. Untar gSoap and openssl sources using the following commands.

gunzip gsoap_2.7.6e.tar.gz

tar –xvf gsoap_2.7.6e.tar

NOTE: This would create a directory named gsoap-2.7

gunzip openssl-0.9.8e.tar.gz

tar –xvf openssl-0.9.8e.tar

NOTE: This would create a directory named openssl-0.9.8e

  1. Change the directory to the gSoap directory

cd gsoap-2.7

  1. The following files need to be modified for the gSOAP build:

soapcpp/src/soapcpp2_yacc.y

soapcpp2/stdsoap2.cpp

soapcpp2/stdsoap2.h

     NOTE: For details, please refer to the Modifications details given below.

  1. Run the configure script to create the required makefiles

 ./configure

  1. Compile the gSoap sources

 make

  1. Change the directory to the soapcpp2 directory.

 cd soapcpp2

  1. Run the following commands

touch env.h

./src/soapcpp2 -penv env.h

aCC -c -z +Z envC.cpp

  1. Copy libcrypto.so and libssl.so from the Presenter base kit to the soapcpp2 folder.

  2. Compile and link the gSoap libraries using the following commands.

cc -z +Z -DWITH_NONAMESPACES -DWITH_OPENSSL -I/*path-to-openssl-include-folder -c stdsoap2.c

aCC -b -o libstdsoap2.sl envC.o stdsoap2.o -L. -lcrypto -lssl

 *path-to-openssl-include-folder: Provide the path to Openssl/include folder here.

 Modification Details for gSOAP HPUX Build

  1.  soapcpp/src/soapcpp2_yacc.y

Modified Line no: 115

Original Code

%expect 1

Modified Code

/*%expect 1*/

  1. soapcpp2/stdsoap2.cpp

Replace all instances of the following code in stdsoap2.cpp.

Original Code

__cplusplus

Modified Code

__cplusplus1

For example: Consider the following code.

Original Code

#ifdef __cplusplus

Modified Code

#ifdef __cplusplus1

  1. soapcpp2/stdsoap2.h

  1. Replace all instances of the following code in stdsoap2.h:

Original Code

__cplusplus

Modified Code

__cplusplus1

For example: Consider the following code.

Original Code

#ifdef __cplusplus

Modified Code

#ifdef __cplusplus1 

  1. Modified Line no: 1714

Original Code:

SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*);

Modified Code:

#ifdef __cplusplus

extern "C" {

#endif

SOAP_FMAC1 void SOAP_FMAC2 soap_fault(struct soap*);

  1. Modified Line no: 1944

Original Code

SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*);

Modified Code

 

SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap*);

#ifdef __cplusplus

}

#endif

Integration with Presenter

  1. Copy all the files from gsoap/dll folder to 3rdparty/dll folder of the kit.

  2. Copy all the files from gsoap/bin folder to 3rdparty/bin folder of the kit.

  3. Copy all the files/folders from gsoap/include folder to 3rdparty/include folder of the kit.


Xerces 2.7 (Required for XML Parser)

 URL

http://archive.apache.org/dist/xml/xerces-c/source/ 

 SIZE

7.4 MB

BUILD STEPS

Windows

VC6/VC7

The XML build on Windows platform requires the build of Xerces source code. The build involves the following steps.

  1. Download Xerces source code.

Software

Download URL

File Name

Xerces http://archive.apache.org/dist/xml/xerces-c/source/  xerces-c-src_2_7_0.tar.gz  
  1. Unzip the xerces-c-src_2_7_0.tar.gz to any drive on your machine.

           NOTE: In Firefox build we are considering the D:\ drive for building the source. You can build this source in any of the drives.

D:\xerces-c-src_2_7_0

  1. Go to the following location

D:\xerces-c-src_2_7_0\Projects\Win32\VC6\xerces-all\XercesLib

  1.  Open the VC++ 6 Workspace XercesLib (XercesLib .dsw) with Microsoft Visual studio Version 6.

  2.  Go to Build menu option and select “Set Active Configuration…”

  3.  Select the Xerces-Lib Win32 Debug option in the “Set Active Project Configuration    window”.

  4.  To build xerces-c_2_7D.dll press either function key F7 or go to Build menu option and select “Build xerces-c_2_7D.dll”

  5.  The required xerces-c_2_7D.dll will be created at following location

 D:\xerces-c-src_2_7_0\Build\Win32\VC6\Debug

Gcc

  1. Execute the MSys shell.

  2. Unzip the Xerces source

  3. $ export XERCESCROOT=/e/xerces-c-current/xerces-c-src_2_7_0

  4. $ cd xerces-c-src_2_7_0

  5. Apply the mingw-msys patch for xerces.

  6. $ patch –p1 < xerces-c-src_2_6_0.patch

  7. $ cd xerces-c-src_2_7_0/src/xercesc

  8. $ ./runConfigure -p mingw-msys -c gcc -x g++ -z -mms-bitfields

  9. $ make: This will produce the required Xerces Dlls.

Linux

 The XML build on Linux platform requires the build of Xerces (source code) The build involves the following steps:

  1. Open a new terminal and do not enter into the c shell.

  2. Type the following command.

export XERCESCROOT= <path name>

where <path name> is the path before the ‘src’ folder where Xerces source code has been put.

  1. Now, type the command :  cd $XERCESCROOT/src  This command goes in the src folder of the XERCES source code.

  2. Go to xerces folder in src.

  3. type autoconf.

This command creates a script runConfigure which is needed to proceed with the build procedure.

  1. Run the runConfigure script by typing the command:

./runConfigure –p<OS>  –c<C compiler>  –x<C++ compiler> -minmem  -nfileonly  –tnative

Where OS: linux

C compiler: gcc.

C++ compiler: g++.

  1. The above command creates the Makefiles. To start the build of Xerces source code, we need these makefiles. Run the gmake command to start the actual build of the source code.

  2. The gmake command creates the necessary files which are needed during the build of XML.

 Solaris

  1. Download xerces source code

Software

Download URL

File Name

xerces

http://archive.apache.org/dist/xml/xerces-c/source/ 

xerces-c-src_2_7_0.tar.gz

  1. Untar XERCES using the following commands

gunzip xerces-c-src_2_7_0.tar.gz

tar –xvf  xerces-c-src_2_7_0.tar

NOTE: This would create a directory named xerces-c-src_2_7_0

  1. Open a new terminal and do not enter into the C shell

  2. Type the command

XERCESCROOT=<path name>

export XERCESCROOT

where <path name> is the path before the ‘src’ folder where Xerces source code has been put.

  1.  Now, type the command:  cd $XERCESCROOT/src. This command goes in the src folder of the XERCES source code.

  2. Go to xercesc folder in src.

  3. Type autoconf.

This command creates a script runConfigure which is needed to proceed with the build procedure.  

  1. Run the runConfigure script by typing the following command.

   ./runConfigure –p<OS>  –c<C compiler>  –x<C++ compiler>  -minmem  -nfileonly  –tnative

    Where OS: solaris

                C compiler: CC

                C++ compiler: CC

  1. The above command creates the Makefiles. To start the build of Xerces source code, we need these makefiles. Run the gmake command to start the actual build of the source code.

  2.  The gmake command creates the necessary files which are required during the build of XML.

 HPUX

The XML build on HPUX platform requires the build of Xerces (source code); the build involves the following steps:

  1. Download xerces source code

Software

Download URL

File Name

xerces

http://archive.apache.org/dist/xml/xerces-c/source/ 

xerces-c-src_2_7_0.tar.gz

  1. Untar xerces using the following command.

 tar –zxvf  xerces-c-src_2_7_0.tar.gz

  Note: This would create a directory named xerces-c-src_2_7_0

  1. Open a new terminal and do not enter into the C shell.

  2. Type the following command.

export XERCESCROOT= <path name>

Where <path name> is the path before the ‘src’ folder where Xerces source code has been put.

  1. Now, type the command: cd $XERCESCROOT/srcThis command goes in the src folder of the xerces source code.

  2. Go to xerces folder in src.

  3. Run the runConfigure script by typing the command:

./runConfigure –p<OS>  –c<C compiler>  -x<C++ compiler>  -minmem  -nfileonly  –tnative

Where OS: hp-11.

            C compiler is cc.

            C++ compiler is aCC.

  1. The above command creates the Makefiles. To start the build of xerces source code, we need these makefiles. Run the gmake command to start the actual build of the source code.

       The gmake command creates the necessary files which are needed during the build of XML.  

Integration with Presenter

  • Copy all the files from xerces-c-src_2_7_0/lib folder to 3rdparty/dll folder. 


Ghostscript 8.54 (Required for PDF Writer)

 URL

Ghostscript 8.54   http://www.cs.wisc.edu/~ghost/ 

Ghostscript fonts ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/AFPL/gs854/ghostscript-fonts-std-8.11.tar.gz

                                                            Or

                                  http://sourceforge.net/project/showfiles.php?group_id=3498

SIZE

   12 MB 

BUILD STEPS

Extract the Ghostscript source code to a folder and follow the following build instructions:

 Windows

 cd ghostscript-8.54

VC 6/ VC 7

For VC 6.0

nmake -f src\msvc32.mak MSVC_VERSION=6 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio"

For VC 7.0:

nmake -f src\msvc32.mak MSVC_VERSION=7 DEVSTUDIO="C:\Program Files\Microsoft Visual Studio .NET"

Linux

 Instead of running configure script; just create a link to “unix-gcc.mak” makefile already provided for gcc compiler on Linux:

% cd ghostscript-*

% ln –s src/unix-gcc.mak Makefile

% make so

 Solaris

Do the following steps

% setenv CC cc

% cd ghostscript-*

% ./configure

Make the following changes to ./Makefile

Line 207

Original Code

 CFLAGS_SO=-fPIC

Modified Code

  CFLAGS_SO=-KPIC

Make the following changes to src/unix-dll.mak file:

Line 77

Original Code

 SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\

Changed Code

 SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -G'\

         make so

HPUX

 Perform the following steps.

% setenv CC cc

% cd ghostscript-*

% ./configure

Make the following changes to ./Makefile

Line 207

Original Code

 CFLAGS_SO=-fPIC

Changed Code

 CFLAGS_SO=+z

Make the following changes to src/unix-dll.mak file:

Line 48

Original Code

 GS_SONAME=lib$(GS).so

Changed Code

 GS_SONAME=lib$(GS).sl

Line 77

Original Code

 SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\

Changed Code

 SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -b'\

        make so

 AIX

 Perform the following steps

% setenv CC xlc

% cd ghostscript-*

% ./configure

 Make the following changes to ./Makefile

Line 207

Original Code

CFLAGS_SO=-fPIC

Changed Code

CFLAGS_SO=

Make the following changes to src/unix-dll.mak file:

 Line 73

Original Code

$(GLCC) -g -o $(GSSOC_XE) $(GLSRC)dxmainc.c -L$(BINDIR) -l

$(GS)

Changed Code

$(GLCC) -brtl -g -o $(GSSOC_XE) $(GLSRC)dxmainc.c -L$(BINDIR) -l

$(GS)

 Line 77

Original Code

SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\

Changed Code

SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -qmkshrobj'\

make so

 IRIX

 Perform the following steps:

% setenv CC cc

% cd ghostscript-*

% ./configure

 Make the following changes to ./Makefile

Line 207

Original Code:

CFLAGS_SO=-fPIC

Changed Code:

CFLAGS_SO=-KPIC

Make the following changes to src/unix-dll.mak file:

Line 77

Original Code:

SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared -Wl,-soname=$(GS_SONAME_MAJOR)'\

Changed Code:

SODEFS=LDFLAGS='$(LDFLAGS) $(CFLAGS_SO) -shared'\

      make so

Integration with Presenter

 Copy all the files of the following ghostscript folders to the corresponding 3rdparty folders in the Presenter kit:

  1. bin

  2. fonts

  3. lib

  4. Resource


 

AND

출처: http://www.enjoydev.com/blog/107

제    목  : [Vista] Admin 권한으로 실행되는 프로그램 만들기 (VB6)
작 성 일  : 2007년 03월 14일
작 성 자  : 제용재 (182cm@korea.com)
개발환경  : Visual Basic 6.0
분    류  : Development -> Visual Basic
키 워 드  : Visual Basic, Vista, UAC, rc.exe, mt.exe
요    약  : Admin 계정으로 로그인했더라도 프로그램을 실행시키면 일반 사용자 권한으로 프로그램이 실행된다.
            Admin 권한으로 실행 시키기 위해서는 "관리자 권한으로 실행"을 이용하거나 권한 관련 속성 정보를 변경해야만 한다.



Vista에서는 UAC(User Account Control, 사용자 계정 관리) 기능을 통해 프로그램 실행에 대한 권한을 강화했는데, 일반 사용자 권한으로 실행되는 프로그램에서는 시스템 폴더, Program Files 폴더, 레지스트리 제어 등에 있어 많은 제약이 따르게된다.

UAC 기능을 고려하지 않은 프로그램을 Admin 권한으로 실행하는 방법은 다음과 같다.

    1. Vista 제어판을 통해 UAC 기능을 중지 시킨다. (비추)
        - UAC 기능이 불편함을 초래할 수는 있으나, 사용자 모르게 임의로 실행되는 악성
          프로그램 등으로부터 보호하는 기능을 가지고 있으므로 가급적 사용을 권장한다.
    2. 실행 파일에서 오른쪽 버튼 클릭 후 "관리자 권한으로 실행" 메뉴 선택
        - 경우에 따라 Admin 권한을 부여하기 위한 일회성 방법이다.
        - "사용자 계정 컨트롤"의 권한 상승 화면을 거쳐야 한다.
    3. 실행 파일의 속성->호환성 탭에서 "관리자 권한으로 이 프로그램 실행" 체크
        - 속성 변경 후에는 자동으로 Admin 권한으로 실행된다.
        - "사용자 계정 컨트롤"의 권한 상승 화면을 거쳐야 한다.
        - 파일명을 변경하거나 위치(폴더)를 이동하는 경우, "권한 수준" 내용을 초기화 된다.

 
Vista에서 Admin 권한으로 실행되는 프로그램을 만들기 위해서는 manifest 파일을 리소스에 포함시키면 되는데 VB6의 리소스 편집기에서는 manifest 리소스 관리를 지원하지 않으므로 [1]VS6의 rc.exe 프로그램을 이용해서 리소스 파일을 만들고 이 리소스 파일을 포함해서 컴파일한다. 또는 [2]VS2005의 mt.exe를 이용해서 이미 컴파일 된 프로그램에 manifest 정보를 추가한다.

[1] manifest 리소스 정보를 포함해서 컴파일하는 방법

1) manifest 파일 만들기
    - 다음의 내용을 텍스트 파일로 저장한다. (파일명 : "app_name.exe.manifest")
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0"
     processorArchitecture="X86"
     name="AdminApp"
     type="win32"/>

  <description>Description of your application</description>
  <!-- Identify the application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>

        </requestedPrivileges>
       </security>
  </trustInfo>
</assembly>


2) ResourceScript 파일 만들기
    - 다음의 내용을 텍스트 파일로 저장한다. (파일명 : ResourceScript.rc)
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST                     24
CREATEPROCESS_MANIFEST_RESOURCE_ID   RT_MANIFEST    "app_name.exe.manifest"


3) rc.exe 를 이용한 리소스 파일 만들기
    - 도스창에서 다음의 명령을 입력해서 리소스 파일을 만든다.
    - "c:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\" 폴더에 있다.
"RC.EXE" /r /fo app_name.res ResourceScript.rc


4) VB 프로젝트에 리소스 파일 추가
   - VB에서 프로젝트->파일 추가 메뉴를 통해 3)에서 만든 리소스 파일(app_name.res)을 프로젝트 리소스 파일로 등록한다.

5) 프로젝트 컴파일

6) Vista의 UAC 사용 환경에서 테스트


[2] VS 2005의 mt.exe를 이용하는 방법

1) Admin 권한 부여를 위한 프로그램(EXE) 준비

2) manifest 파일 만들기 ([1]과 동일)

3) 실행 파일에 manifest 정보 추가하기

mt -manifest app_name.exe.manifest -outputresource:app_name.exe;#1


4) Vista의 UAC 사용 환경에서 테스트


※ manifest 적용 후에는 다음 그림처럼 방패 모양이 추가되는 것을 볼 수 있다. (Vista에서 확인 가능)
사용자 삽입 이미지 사용자 삽입 이미지


※ manifest 적용 및 테스트를 위한 예제 프로젝트





☞ 본문 출처 : http://www.enjoydev.com/blog/107(새 창으로 열기)

☞ 본인의 글 입니다. 이 글을 다른 곳에 게재하는 경우 본문 출처를 밝혀주시기 바랍니다.

☞ 위 내용은 정식 문서 번역이 아닌, 실무 적용에 따른 경험을 바탕으로 어느정도 자의적인 설명이 포함되어있습니다.
   잘못된 내용이 있는 경우 지적 바랍니다.
AND

출처: http://himskim.egloos.com/1524155

Vista Note -3 권한상승을 위해 실행파일에 manifest 추가

Administrators 권한이 있는 경우에만 정상적으로 수행될 수 있는 어플리케이션을 만들기 위해서는 manifest를 이용하여 '이 프로그램을 수행하기 위해서는 반드시 권한상승이 필요하다'는 정보를 실행파일에 포함시킬 필요가 있습니다.

물론, 오른마우스를 클릭해서 "관리자 권한으로 실행" 으로 어플리케이션을 수행하거나, '속성'에서 '관리자 권한으로 이 프로그램 실행'을 선택할 수도 있겠지만, 사용자에게 이렇게 어플리케이션을 수행할 것을 강요하는 것은 매우 어려운 일이기 때문에, 실행파일 자체에 '이 어플리케이션은 반드시 Administrators permission이 필요하다' 라는 정보를 추가하여, 자동적으로 권한상승 창이 뜰 수 있도록 하는 것은 매우 중요합니다. 그런데 Visual Studio 2005 조차도 이러한 정보를 단숨에 실행파일에 추가하는 손쉬운 방법을 제공하지는 않습니다. (1. 아래 내용을 보면 아시겠지만 그렇다고 매우 복잡한것도 아닙니다. 2. 한편으로 보면 이는 매우 당연합니다. Visual Studio 2005가 Vista보다 미리 출시되었을 뿐더러 이러한 manifest를 추가하는 것은 단순히 특수한 type의 resource를 추가하는 것 이상의 동작이 아니기 때문입니다.) 게다가 managed code를 개발하느냐 혹은 C/C++와 같이 native code를 개발하느냐에 따라 그 방법이 서로 상이하기 때문에 조금은 혼돈스러울 수 있습니다.

앞서 말한 이러한 제약사항(본 어플리케이션은 반드시 Administrators 권한이 필요하다와 같은)은 manifest 라는 파일에 기록되게 되며, manifest 파일들은 실행파일에 추가(embedding)될 수 있습니다. manifest 파일의 일반적인 구조는 다음과 같습니다. 이 파일은 '실행파일명.exe.manifest' 라는 파일로 저장하는 것이 좋습니다. 'MyApp.exe'가 실행파일명이라면 'MyApp.exe.manifest'로 저장하시면 됩니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0"
processorArchitecture="X86"
name="IsUserAdmin"
type="win32"/>

<description>Description of your application</description>
<!-- Identify the application security requirements. -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

(indentation을 못해서 죄송합니다. 어떻게 하는지를 모르겠어요 ^^;)


이제 실질적인 3가지 절차를 알아 봅시다.  


1. 'Step by Step' 방법


먼저 '실행파일명.rc' 라는 이름의 빈파일을 만듭니다. 'MyApp.rc'와 같이 만들면 됩니다. 아래와 같은 내용을 적습니다.

#define RT_MANIFEST 24
#define APP_MANIFEST 1

APP_MANIFEST RT_MANIFEST MyApp.exe.manifest

위 의미는 RT_MANIFEST 형 resource로 APP_MANIFEST 라는 이름의 identifier를 "MyApp.exe.manifest" 라는 내용을 정의한다라는 의미입니다.(manifest 형 resource 구분자의 값은 항상 1로 정의하는 것이 좋습니다.

(참고적으로 파일내에 RT_MANIFEST 를 정의하는 대신 #include <winuser.h> 를 포함시키는 것도 좋은 방법입니다. 하지만 이 경우 winuser.h 파일의 위치를 정의하기 위하여 추가적인 명령들을 설정해야할 수 있습니다. 또한 MyApp.exe.manifest 파일을 rc 파일과 분리된 파일로 두지 않고 rc 파일내에 쓸 수도 있습니다.)

이제 rc 파일을 컴파일하여 res 파일을 만듭니다. 컴파일 하는 방법은 다음과 같은 두가지 방법 중 한가지를 사용하면 됩니다.

  • command line prompt 에서 rc.exe /r MyApp.rc 를 입력합니다.
  • Visual Studio 2005 내에서 project properties를 선택하고 Build Event Tab의 Pre-Build event에 다음을 입력합니다.

"$(DevEnvDir)..\..\SDK\v2.0\bin\rc.exe" /r "$(ProjectDir)$(TargetName).rc"

(rc.exe 파일의 위치는 적절히 수정되어야할 수 있습니다.)

이제 컴파일된 resource를 실행파일에 추가하기 위한 절차를 수행합니다. 다음과 같은 2가지 방법이 있을 수 있습니다.

  • Visual Studio 2005나 MsBuild를 이용하는 방법

MyApp.csproj 파일을 열어서 볼드체로 표시된 내용을 다음과 같이 추가합니다.

<PropertyGroup>

...
<Win32Resource>MyApp.res</Win32Resource>

...
</PropertyGroup>

  • command line을 이용하여 컴파일 하는 방법

csc /win32res:MyApp.res MyApp.cs
vjc /win32res:MyApp.res MyApp.jsl
vbc /win32resource:MyApp.res MyApp.vb


2. mt.exe를 활용하는 방법


mt.exe 를 이용하면 이미 생성된 실행파일에 manifest 파일을 embedding할 수 있습니다. mt.exe를 활용하는 방법에도 2가지 방법이 있을 수 있습니다.

  • command prompt를 이용하여 다음과 같이 입력합니다.

mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1

여기서 #1 은 manfest 파일에 대한 resource identifier를 1로 정의한다는 의미입니다.

  • Visual Studio 2005 내에서 project properties를 선택하고 Build Event Tab의 Post-Build event에 다음을 입력합니다.

"$(DevEnvDir)..\..\VC\bin\mt.exe" -manifest "$(ProjectDir)$(TargetName).exe.manifest"  –outputresource:"$(TargetDir)$(TargetFileName)";#1


3. Manifest Tool을 이용하는 방법


Visual Studio 2005를 이용하여 C++ 어플리케이션을 개발하고 있다면, 좀 더 손쉽게 manifest 파일을 embedding할 수 있습니다.

project properties를 선택하고 Configuration Properties->Manifest Tool을 선택한 후, Input and Output을 선택합니다. Additional Manifest Files 에 'MyApp.exe.manifest' 와 같이 manifest 파일명을 입력하면 됩니다.


결론

이러한 3가지 방법중에 각각 선호하는 방법을 선택하면 되겠습니다만, 2번 방법을 이용하는 것이 가장 간단하면서도, managed/native의 구분없이 사용할 수 있으므로 가장 적절하지 않을까 생각됩니다.


다음 Link를 참고하십시오.

Developer Best Practices and Guidelines for Applications in a Least Privileged Environment

.Net Security Blog : Adding a UAC Manifest to Managed Code

The Moth: Vista: User Account Control

How To: Tell Vista's UAC What Privelege Level Your App Requires

by 김명신 | 2007/03/09 15:29 | 복잡한컴퓨터이야기 | 트랙백(1) | 덧글(1)
트랙백 주소 : http://himskim.egloos.com/tb/1524155
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from 잡식에 잡식의 잡식의 .. at 2007/12/30 17:04 #

제목 : 권한상승을 위해 실행파일에 manifest 추가
Vista Note -3 권한상승을 위해 실행파일에 manifest 추가그냥 추가만 시키는게 아니라 조금 더 알고싶다면 클릭...more

Commented by 오즈 at 2007/07/26 14:53 # x
좋은 정보 감사합니다. 참고 좀 해갈께요.

AND

출처: http://blog.naver.com/jmj1130?Redirect=Log&logNo=100042140754

열나게 맞고 한대 더 맞는 느낌으로...유니코드 대책 Vc,C++,Tip모음

2007/09/17 19:04

복사 http://blog.naver.com/jmj1130/100042140754

http://i-sac.co.kr/blog/archives/2005/08/index.html


----------------------------------------------------------------------
형 변환
//UNICODE->ANSI
int nAsciiLen = WideCharToMultiByte( CP_ACP, 0, buffer, -1, NULL, 0, NULL, NULL);
char *szXMLFilePath = new char[nAsciiLen+1];
WideCharToMultiByte( CP_ACP, 0, buffer, -1, szXMLFilePath, nAsciiLen+1, NULL, NULL );


//ANSI->UNICODE
char appName[256];
char logFolder[MAX_PATH];
char logFileName[128];

m_clsResourceProvider->GetParameter("LogFolder",logFolder);
m_clsResourceProvider->GetParameter("LogFileName",logFileName);
m_clsResourceProvider->GetParameter("AppName",appName);

m_clsLogger = new CLog(appName);

/*
 MultiByteToWideChar( CP_ACP, 0, UserName,
        strlen(UserName)+1, wszUserName,  
     sizeof(wszUserName)/sizeof(wszUserName[0]) );
*/
_TCHAR _appName[512];
_TCHAR _logFolder[MAX_PATH*2];
_TCHAR _logFileName[256];

MultiByteToWideChar( CP_ACP, 0, appName, strlen(appName)+1, _appName,sizeof(_appName)/sizeof(_appName[0]) );
MultiByteToWideChar( CP_ACP, 0, logFolder, strlen(logFolder)+1, _logFolder,sizeof(_logFolder)/sizeof(_logFolder[0]) );
MultiByteToWideChar( CP_ACP, 0, logFileName, strlen(logFileName)+1, _logFileName,sizeof(_logFileName)/sizeof(_logFileName[0]) );

wsprintf((LPWSTR)buffer ,_T( "%s\\%s") ,_logFolder,_logFileName);

CFileLogAppender * pFileLogAppender = new CFileLogAppender(nsCLog::mylog, (LPSTR)buffer);
if(false != m_clsLogger->addAppender(pFileLogAppender))
{
m_clsLogger->writeLog(nsCLog::warning, "CIVRLogHandlerApp | NULL |アプリケーションが起動されました | NULL |");
}


---------------------------------------------------------------
문자의 개수 : sizeof(szBuffer) / sizeof(TCHAR)

문자열의 길이 : sizeof(szBuffer) * sizeof(TCHAR)

적절한 매크로를 만들어 사용하면 고민에서 해방될까?

-------------------------------------------------------------------
TCHAR std::string 대책
// ok but not recommended
typedef basic_string  char_traits,
  allocator >
  tstring;

// better, recommended
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif


---------------------------------------------------------------------------------------
http://www.reiot.com/blogmeme/blog/index.php?blog_code=reiot&article_id=120

 
게임 서버에서 모든 문자열을 유니 코드(UTF-16)로 사용한다고 하면, 메모리를 2배나 사용할텐데 메모리나 성능에 문제가 생기면 어쩌냐는 질문을 많이 받는다. 그 정도는 괜찮다고 말하지만, 내심 걱정이 되는 것이 사실이다. (이전 프로젝트에서 서버 프로파일링을 해보니 실제로 std::string 이 차지하는 부하가 무지막지했다. 더군다나 이번엔 std::wstring... STL string 혐오론자가 보면 두려움에 치를 떨지도... -┌)

유니 코드를 쓰는 이유는 꽤나 많지만, 그 중에서도 가장 큰 이유를 꼽자면, i18n 그리고 l10n 이 필요해지는 시점에서 추가적인 작업을 최소화한다는 데 있다. 그런데, 실제로 저 작업을 처음부터 끝까지 겪어보지 못한 나로서는 웬지 지금 하고 있는 짓이 무의미하고 귀찮게만 느껴지기도 한다. 대충 나열해 보자면...

- strcpy() 의 친구들을 _tcscpy() 친구들로 교체
- 모든 문자열의 앞뒤로 _T( ) 를 붙임 <-- 이게 제일 귀찮다!! 그냥 regexp 로 글로벌 변경하는 게 짱이다.
- 모든 Win32 API 들의 유니코드 지원여부 체크. 가끔 LPCTSTR 이 아닌 char * 만을 받는 함수들을 만나면 좀 난감하다. 특히 winsock2의 주소 쿼리 함수들...
- 문자열 <-> 바이트배열 변환시 /sizeof(TCHAR) 또는 * sizeof(TCHAR) 꼭 해주기
- 문자 배열을 TCHAR []로, 바이트 배열은 BYTE []로, char * 는 LPCTSTR 로 변경하기
- 모든 텍스트 파일을 UTF-8 인코딩으로 저장해서 체크인 할 때마다, 소스세이프의 투덜거림을 달래기
- wstring 을 타이핑 할 때마다 '이렇게 하면 오히려 더 느려질텐데...' 라며 잠시 근심하기

사실, l10n 을 해야 할 때가 되었다는 것은 하늘의 축복이므로 기쁜 마음으로 하면 될텐데... 하고 한숨을 지어 본다. (성공한 개발자는 이 말의 의미를 잘 모를꺼다. 헹.) 그러고보니, 아직 더 알아봐야 하는 것들도 있다.

- 지역화 메시지 : 클라이언트 서버에 사용하는 다양한 다국적 출력 메시지들을 얼마나 아름답게 지역화하는가~
- DB에다가 유니코드 charset 을 사용하기 : 몇몇 고수들의 말로는 그냥 그나라 charset 을 사용하는 게 제일 좋다고 하더라만은... 아직은 와닿지 않는 이야기.


--------------------------------------------------------------------------------------
C++의 기본은 문자열 조작이라고 생각한다. 이참에 문자열을 비롯한 자료형을 정리하자..
1. C 자료형

    char (1) , short (2) , int (4) , long (4), float (4) , double (8) , bool  
    문자 : char
    char szName[20] = "kim";


2. WIN API 자료형

BYTE (1,unsigned char)  
WORD (2,unsigned short)
UNIT (4, unsigned int) , 
     DWORD (4,unsigned long)
LONG (4,long)
BOOL
    문자 : UCHAR (unsigned char)
    핸들 : 대상을 구분하는 4바이트 정수(HWND, HDC 등)

    MBCS문자(열)                 유니코드문자(열)           자동매크로문자(열)
    char                                     wchar_t                       TCHAR
    LPSTR(char*)                    LPWSTR(wchar_t*)         LPTSTR
    LPCSTR(const char*)      LPCWSTR                         LPCTSTR

    (참조1) 문자열에 대해 그냥 습관적으로 LPTSTR 또는 LPCTSTR 를 써라
    (참조2) 헝가리안명명법
                   w(WORD) , dw(DWORD) , i(int) , b(BOOL) , ch(문자) , sz(문자열) , h(핸들)
                   cb(바이트수) , a(배열)
(참조3) OLECHAR(wchar_t), LPOLESTR(LPWSTR), LPCOLESTR(LPCWSTR), OLESTR(x) = _T(x)


3. COM 스트링

    BSTR : 문자열길이를 시작전에 저장하고, 이어서 유니코드문자열을 저장하는 방식
                  1> LPCWSTR ->  BSTR : 생성안됨. 생성함수를 이용해야함
                      BSTR bstr = sysAllocString(L"Hi Bob"); // 메모리할당
                      sysFreeString(bstr); // 메모리제거
                  2> BSTR  ->  LPCWSTR : 형변환 가능

    VARIANT : 문자열이 들어올때  BSTR과 동일

4. CRT(c runtime library) 지원 스트링클래스

    _bstr_t : BSTR랩퍼클래스, 메모리할당/제거를 자동으로 수행
                  1> LPCSTR, LPCWSTR  -> _bstr_t
                               _bstr_t bs1 = "char string";  // 생성
                  2> _bstr_t  ->  LPCSTR, LPCWSTR
                               LPCSTR psz1 = (LPCSTR)bs1; // 형변환
                  3> _bstr_t  ->  BSTR : 형변환안됨. 함수이용
                               BSTR bstr = bs1.copy();
                               sysFreeString(bstr);  // BSTR은 사용후 메모리해제를 해야하는 불편이있음..

    _variant_t : VARIANT랩퍼클래스, 메모리할당/제거를 자동으로 수행
                  1> LPCSTR, LPCWSTR  -> _variant_t
                               _variant_t v1 = "char string"; // 생성
                  2> _variant_t  -> _bstr_t  ->  LPCSTR, LPCWSTR
                               LPCSTR psz1 = (LPCSTR)(_bstr_t)v1;  //형변환

5. ATL 지원 스트링클래스

    CComBSTR : BSTR랩퍼클래스, 메모리할당/제거를 자동으로 수행
                  1> LPCSTR, LPCWSTR  ->  CComBSTR
                               CComBSTR bs1 = "char string"; // 생성
                  2> CComBSTR  ->  BSTR   -> LPCWSTR
                               BSTR bstr = (BSTR)bs1;  // 형변환

                  (참조) BSTR -> CComBSTR  
                               CComBSTR bs2; bs2.Attach(W2BSTR(L"Bob"))
                               
    CComVariant : VARIANT랩퍼클래스, 메모리할당/제거를 자동으로 수행
                  1> LPCSTR, LPCWSTR  ->  CComVariant
                               CComVariant bs1 = "char string"; // 생성
                  2> CComVariant  ->  CComBSTR   ->  BSTR   -> LPCWSTR
                               CComBSTR bs2 = bs1.bstrVal;

6. STL 스트링

    string  
                  1> LPCSTR -> string
                                string  str = "char string"; //생성
                  2> string -> LPCSTR : 형변환 안됨. 함수이용
                                LPCSTR psz = str.c_str();
    wstring
                   1> LPCWSTR -> wstring
                                wstring  str = "wide char string"; //생성
                  2> wstring -> LPCWSTR : 형변환 안됨. 함수이용
                                LPCWSTR psz = str.c_str();

7. MFC 스트링

    CString
                  1> LPCSTR, LPCWSTR  ->  CString
                                CString  str = "char string"; //생성
                  2> CString  -> LPCTSTR : 
                                LPCTSTR  lpsz = (LPCTSTR)str; //형변환

                  (참고)  CString  -> LPTSTR :  함수이용

                               LPTSTR lptsz  = str.GetBuffer(0); str.ReleaseBuffer(); //  올바른 사용
                               LPTSTR lptsz  = (LPTSTR)(LPCTSTR)str  //  잘못된 사용
                               CString  -> BSTR  
                               BSTR bstr = str.AllocSysString(); sysFreeString(bstr)

8. VC7 스트링

    String : .NET에서 새로 정의한 스트링 클래스
                               String* s1 = S"this is nice"; // 생성
                               CString s2(s1); // 형변환

AND

출처: http://tong.nate.com/im_alies/43417018

How To Debug MFC Module and Thread State Problems

Article ID : 189485
Last Review : November 21, 2006
Revision : 2.2
This article was previously published under Q189485

SUMMARY

MFC maintains three different types of data: process specific data, module specific data, and thread specific data. Because there can be more than one MFC module or thread in a process, MFC maintains state variables to keep track of the current module and thread instance data.

Many ASSERTs can occur when objects are created in the context of one module or thread state, and used or destructed in another. Following are a few common ASSERTs in Visual C++, version 5.0, Service Pack 3:
   AFXWIN1.INL line 19,  ASSERT(afxCurrentInstanceHandle != NULL)
   AFXWIN1.INL line 22,  ASSERT(afxCurrentResourceHandle != NULL)
   WINCORE.CPP line 871, ASSERT(pMap != NULL)
   WINCORE.CPP line 874, ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL
                            || (p = pMap->LookupTemporary(m_hWnd)) != NULL)
   WINCORE.CPP line 876, ASSERT((CWnd*)p == this)

				

Back to the top

MORE INFORMATION

Each MFC module state is tied to an initialization of the shared MFC DLL. The application, as well as each regular MFC DLL and MFC ActiveX control, maintains a separate initialization of MFC. MFC extension DLLs use the module state of the calling application or DLL.

To correctly switch between module states, MFC requires that each entry point contain an AFX_MANAGE_STATE macro that sets and restores the current module state. If an entry point is missing this macro, the current module state can be corrupted. This can result in an ASSERT, general protection fault, or invalid resource being loaded from somewhere else in the process, including inside another MFC DLL.

While thread state is stored in Thread Local Storage (TLS) and is always correct for the running thread, it's still possible to see problems when MFC objects are passed between threads. MFC objects that use Windows or Graphics Device Interface (GDI) handles are stored in thread specific handle maps. When these objects are passed between threads, problems occur.

Below are two macros that you can use to find these problems. You can place them in the stdafx.h file, and use them anywhere in the application or DLL to compare module or thread states:
   #ifdef _DEBUG
   #define MODULE_TRACE()  TRACE("%s(%d) : Module State nInst = 0x%X\n", \ 
         __FILE__, __LINE__, AfxGetModuleState()->m_hCurrentInstanceHandle)
   #define THREAD_TRACE()  TRACE("%s(%d) : Thread State Address = 0x%X\n",\ 
         __FILE__, __LINE__, AfxGetThreadState())
   #else
   #define MODULE_TRACE()
   #define THREAD_TRACE()
   #endif  //_DEBUG
				
Each of these macros prints out a message in the output window, identifying the current module or thread state. Double-clicking on the message takes you to the source line where they appear.

NOTE: you may need to run the MFC Tracer utility from the DevStudio Tools menu, and turn off support for "Multiple application debugging," as this prepends the module name to the debug string sent to the output window.

MODULE_TRACE() is most useful when you place it in every CWinApp::InitInstance() in the process, as well as where the object that is causing the ASSERTs is being created and destroyed. THREAD_TRACE() works like MODULE_TRACE(), but you should also place it in the CWinThread::InitInstance() of secondary threads.

MODULE_TRACE() returns the same value in every function in the same DLL or .exe file. THREAD_TRACE() returns the same value in every method for a CWnd, or CGdiObject-derived class. If not, there is a problem. You can call the macros more often to help isolate the problem.

Once the problem has been isolated, see the following references on how to fix or resolve the problem.

Back to the top

REFERENCES

For more information on MFC Module State, please see:
Visual C++ Online Documentation: Microsoft Foundation Class Reference; MFC Technical Notes; TN058: MFC Module State Implementation.

For more information on MFC thread handle maps, please see:

Visual C++ Online Documentation: Visual C++ Programmer's Guide; Adding Program Functionality; Details; Multithreading Topics; click on:
Programming tips for MFC multithreaded programming
For more information on AFX_MANAGE_STATE, search on AFX_MANAGE_STATE in the VC++ 5.0 Online Documentation.

For additional information, please see the following articles in the Microsoft Knowledge Base:
127074 (http://support.microsoft.com/kb/127074/EN-US/) How to Use AFX_MANAGE_STATE in an OLE Control

140850 (http://support.microsoft.com/kb/140850/EN-US/) How To Converting DLLTRACE to Use MFC in Shared Library
(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Kelly Marie Ward, Microsoft Corporation.

Back to the top


APPLIES TO
Microsoft Foundation Class Library 4.2, when used with:
    Microsoft Visual C++ 4.0 Standard Edition
    Microsoft Visual C++ 4.1 Subscription
    Microsoft Visual C++ 4.2 Enterprise Edition
    Microsoft Visual C++ 4.2 Professional Edition
    Microsoft Visual C++ 5.0 Enterprise Edition
    Microsoft Visual C++ 5.0 Professional Edition

Back to the top

Keywords:
kbarchitecture kbbug kbdebug kbdll kbhowto kbthread KB189485

Back to the top

출처 : Tong - 미스터팬텀님의 프로그래밍 NoTE통

AND